Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers auth_eap_tls_sec_prot.c Source File

auth_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/auth_eap_tls_sec_prot.h"
00037 
00038 #ifdef HAVE_WS
00039 
00040 #define TRACE_GROUP "eapa"
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_RESPONSE_ID = SEC_STATE_FIRST,
00049     EAP_TLS_STATE_RESPONSE_START,
00050     EAP_TLS_STATE_RESPONSE,
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 typedef struct {
00057     sec_prot_common_t             common;           /**< Common data */
00058     sec_prot_t                    *tls_prot;        /**< TLS security protocol */
00059     eapol_pdu_t                   recv_eapol_pdu;   /**< Received EAPOL PDU */
00060     tls_data_t                    tls_send;         /**< EAP-TLS send buffer */
00061     tls_data_t                    tls_recv;         /**< EAP-TLS receive buffer */
00062     uint8_t                       eap_id_seq;       /**< EAP sequence */
00063     uint8_t                       recv_eap_id_seq;  /**< Last received EAP sequence */
00064     uint8_t                       eap_code;         /**< Received EAP code */
00065     uint8_t                       eap_type;         /**< Received EAP type */
00066     int8_t                        tls_result;       /**< Result of TLS operation */
00067     bool                          wait_tls: 1;      /**< Wait TLS (ECC calculation) before sending EAP-TLS message */
00068     bool                          tls_ongoing: 1;   /**< TLS handshake is ongoing */
00069     bool                          send_pending: 1;  /**< TLS data is not yet send to network */
00070 } eap_tls_sec_prot_int_t;
00071 
00072 /*Small network setup*/
00073 #define EAP_TLS_SMALL_IMIN 300 // retries done in 30 seconds
00074 #define EAP_TLS_SMALL_IMAX 900 // Largest value 90 seconds
00075 
00076 /* Large network setup*/
00077 #define EAP_TLS_LARGE_IMIN 600 // retries done in 60 seconds
00078 #define EAP_TLS_LARGE_IMAX 2400 // Largest value 240 seconds
00079 
00080 
00081 static trickle_params_t eap_tls_trickle_params = {
00082     .Imin = EAP_TLS_SMALL_IMIN,           /* ticks are 100ms */
00083     .Imax = EAP_TLS_SMALL_IMAX,           /* ticks are 100ms */
00084     .k = 0,                /* infinity - no consistency checking */
00085     .TimerExpirations = 2
00086 };
00087 
00088 static uint16_t auth_eap_tls_sec_prot_size(void);
00089 static int8_t auth_eap_tls_sec_prot_init(sec_prot_t *prot);
00090 
00091 static void auth_eap_tls_sec_prot_create_request(sec_prot_t *prot, sec_prot_keys_t *sec_keys);
00092 static void auth_eap_tls_sec_prot_delete(sec_prot_t *prot);
00093 static int8_t auth_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t size);
00094 
00095 static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot);
00096 
00097 static int8_t auth_eap_tls_sec_prot_message_handle(sec_prot_t *prot);
00098 static int8_t auth_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_code, uint8_t eap_type, uint8_t tls_state);
00099 
00100 static void auth_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks);
00101 static int8_t auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot);
00102 static void auth_eap_tls_sec_prot_delete_tls(sec_prot_t *prot);
00103 
00104 static void auth_eap_tls_sec_prot_seq_id_update(sec_prot_t *prot);
00105 
00106 #define eap_tls_sec_prot_get(prot) (eap_tls_sec_prot_int_t *) &prot->data
00107 
00108 int8_t auth_eap_tls_sec_prot_register(kmp_service_t *service)
00109 {
00110     if (!service) {
00111         return -1;
00112     }
00113 
00114     if (kmp_service_sec_protocol_register(service, IEEE_802_1X_MKA, auth_eap_tls_sec_prot_size, auth_eap_tls_sec_prot_init) < 0) {
00115         return -1;
00116     }
00117 
00118     return 0;
00119 }
00120 
00121 int8_t auth_eap_tls_sec_prot_timing_adjust(uint8_t timing)
00122 {
00123 
00124     if (timing < 16) {
00125         eap_tls_trickle_params.Imin = EAP_TLS_SMALL_IMIN;
00126         eap_tls_trickle_params.Imax = EAP_TLS_SMALL_IMAX;
00127     } else {
00128         eap_tls_trickle_params.Imin = EAP_TLS_LARGE_IMIN;
00129         eap_tls_trickle_params.Imax = EAP_TLS_LARGE_IMAX;
00130     }
00131     return 0;
00132 }
00133 
00134 static uint16_t auth_eap_tls_sec_prot_size(void)
00135 {
00136     return sizeof(eap_tls_sec_prot_int_t);
00137 }
00138 
00139 static int8_t auth_eap_tls_sec_prot_init(sec_prot_t *prot)
00140 {
00141     prot->create_req = auth_eap_tls_sec_prot_create_request;
00142     prot->create_resp = 0;
00143     prot->receive = auth_eap_tls_sec_prot_receive;
00144     prot->delete = auth_eap_tls_sec_prot_delete;
00145     prot->state_machine = auth_eap_tls_sec_prot_state_machine;
00146     prot->timer_timeout = auth_eap_tls_sec_prot_timer_timeout;
00147 
00148     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00149 
00150     sec_prot_init(&data->common);
00151     sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_INIT);
00152 
00153     data->tls_prot = NULL;
00154     data->eap_id_seq = 0;
00155     data->recv_eap_id_seq = 0;
00156     data->eap_code = 0;
00157     data->eap_type = 0;
00158     eap_tls_sec_prot_lib_message_init(&data->tls_recv);
00159     eap_tls_sec_prot_lib_message_init(&data->tls_send);
00160     data->tls_result =  EAP_TLS_RESULT_ERROR;
00161     data->wait_tls = false;
00162     data->tls_ongoing = false;
00163     data->send_pending = false;
00164     return 0;
00165 }
00166 
00167 static void auth_eap_tls_sec_prot_delete(sec_prot_t *prot)
00168 {
00169     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00170     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00171     eap_tls_sec_prot_lib_message_free(&data->tls_recv);
00172 }
00173 
00174 static void auth_eap_tls_sec_prot_create_request(sec_prot_t *prot, sec_prot_keys_t *sec_keys)
00175 {
00176     prot->sec_keys = sec_keys;
00177 
00178     // Call state machine
00179     prot->state_machine_call(prot);
00180 }
00181 
00182 static int8_t auth_eap_tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t size)
00183 {
00184     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00185     int8_t ret_val = -1;
00186 
00187     // Decoding is successful
00188     if (eapol_parse_pdu_header(pdu, size, &data->recv_eapol_pdu)) {
00189         // Handle only EAP messages (ignore initial EAPOL-key retransmissions)
00190         if (data->recv_eapol_pdu.packet_type == EAPOL_EAP_TYPE) {
00191             data->eap_code = data->recv_eapol_pdu.msg.eap.eap_code;
00192             data->eap_type = data->recv_eapol_pdu.msg.eap.type;
00193 
00194             // Call state machine
00195             prot->state_machine(prot);
00196         }
00197         ret_val = 0;
00198     }
00199 
00200     memset(&data->recv_eapol_pdu, 0, sizeof(eapol_pdu_t));
00201     data->eap_code = 0;
00202     data->eap_type = 0;
00203 
00204     return ret_val;
00205 }
00206 
00207 static int8_t auth_eap_tls_sec_prot_message_handle(sec_prot_t *prot)
00208 {
00209     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00210 
00211     uint8_t *data_ptr = data->recv_eapol_pdu.msg.eap.data_ptr;
00212     uint16_t length = data->recv_eapol_pdu.msg.eap.length;
00213 
00214     bool new_seq_id = false;
00215     bool old_seq_id = false;
00216 
00217     // Already received sequence ID is received again, ignore
00218     if (data->recv_eapol_pdu.msg.eap.id_seq < data->eap_id_seq) {
00219         old_seq_id = true;
00220     } else if (data->recv_eapol_pdu.msg.eap.id_seq == data->eap_id_seq) {
00221         // Confirmation that supplicant has received the message, proceed with protocol
00222         data->recv_eap_id_seq = data->recv_eapol_pdu.msg.eap.id_seq;
00223         data->eap_id_seq++;
00224         new_seq_id = true;
00225     }
00226 
00227     tr_info("EAP-TLS: recv %s type %s id %i flags %x len %i, eui-64 %s", eap_msg_trace[data->eap_code - 1],
00228             data->eap_type == EAP_IDENTITY ? "IDENTITY" : "TLS", data->recv_eapol_pdu.msg.eap.id_seq,
00229             length >= 6 ? data_ptr[0] : 0, length, trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00230 
00231     if (old_seq_id) {
00232         return EAP_TLS_MSG_DECODE_ERROR;
00233     }
00234 
00235     if (data->eap_type == EAP_IDENTITY) {
00236         return EAP_TLS_MSG_IDENTITY;
00237     }
00238 
00239     if (!data_ptr || length < 6) {
00240         tr_error("EAP-TLS: decode error");
00241         return EAP_TLS_MSG_DECODE_ERROR;
00242     }
00243 
00244     length -= 5; // EAP fields: code, id, length, type
00245 
00246     return eap_tls_sec_prot_lib_message_handle(data_ptr, length, new_seq_id, &data->tls_send, &data->tls_recv);
00247 }
00248 
00249 static int8_t auth_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_code, uint8_t eap_type, uint8_t tls_state)
00250 {
00251     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00252 
00253     uint8_t flags = 0xff;
00254     // EAP-TLS flags field is always present during TLS exchange
00255     if (tls_state == EAP_TLS_EXCHANGE_ONGOING) {
00256         flags = 0x00;
00257     }
00258 
00259     if (eap_code == EAP_REQ) {
00260         if (eap_type == EAP_TLS && tls_state == EAP_TLS_EXCHANGE_START) {
00261             eap_tls_sec_prot_lib_message_allocate(&data->tls_send, TLS_HEAD_LEN, 0);
00262             flags = EAP_TLS_START;
00263         }
00264     } else if (eap_code == EAP_SUCCESS || eap_code == EAP_FAILURE) {
00265         // Send Success and Failure with same identifier as received in EAP Response
00266         data->eap_id_seq = data->recv_eap_id_seq;
00267     } else {
00268         return -1;
00269     }
00270 
00271     uint16_t eapol_pdu_size;
00272     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);
00273     if (!eapol_decoded_data) {
00274         return -1;
00275     }
00276 
00277     tr_info("EAP-TLS: send %s type %s id %i flags %x len %i, eui-64: %s", eap_msg_trace[eap_code - 1],
00278             eap_type == EAP_IDENTITY ? "IDENTITY" : "TLS", data->eap_id_seq, flags, eapol_pdu_size,
00279             trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00280 
00281     if (prot->send(prot, eapol_decoded_data, eapol_pdu_size + prot->header_size) < 0) {
00282         return -1;
00283     }
00284 
00285     return 0;
00286 }
00287 
00288 static void auth_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
00289 {
00290     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00291     sec_prot_timer_timeout_handle(prot, &data->common, &eap_tls_trickle_params, ticks);
00292 }
00293 
00294 static void auth_eap_tls_sec_prot_tls_create_indication(sec_prot_t *tls_prot)
00295 {
00296     tls_prot->create_resp(tls_prot, SEC_RESULT_OK);
00297 }
00298 
00299 static void auth_eap_tls_sec_prot_tls_finished_indication(sec_prot_t *tls_prot, sec_prot_result_e result, sec_prot_keys_t *sec_keys)
00300 {
00301     (void) sec_keys;
00302 
00303     sec_prot_t *prot = tls_prot->type_get(tls_prot, SEC_PROT_TYPE_EAP_TLS);
00304     if (!prot) {
00305         return;
00306     }
00307 
00308     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00309 
00310     if (result == SEC_RESULT_OK) {
00311         data->tls_result = EAP_TLS_RESULT_HANDSHAKE_OVER;
00312         tr_info("EAP-TLS: handshake success");
00313     } else if (result == SEC_RESULT_CONF_ERROR) {
00314         data->tls_result = EAP_TLS_RESULT_HANDSHAKE_FATAL_ERROR;
00315         tr_error("EAP-TLS: handshake fatal error");
00316     } else {
00317         data->tls_result = EAP_TLS_RESULT_HANDSHAKE_FAILED;
00318         tr_error("EAP-TLS: handshake failed");
00319     }
00320 
00321     data->tls_ongoing = false;
00322 
00323     if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_FATAL_ERROR) {
00324         // On fatal error terminate right away
00325         prot->state_machine_call(prot);
00326     }
00327 }
00328 
00329 static int8_t auth_eap_tls_sec_prot_tls_send(sec_prot_t *tls_prot, void *pdu, uint16_t size)
00330 {
00331     sec_prot_t *prot = tls_prot->type_get(tls_prot, SEC_PROT_TYPE_EAP_TLS);
00332     if (!prot) {
00333         return -1;
00334     }
00335 
00336     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00337 
00338     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00339 
00340     data->tls_send.data = pdu;
00341     data->tls_send.total_len = size;
00342     data->tls_send.handled_len = 0;
00343 
00344     data->send_pending = true;
00345 
00346     prot->state_machine_call(prot);
00347 
00348     return 0;
00349 }
00350 
00351 static int8_t auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
00352 {
00353     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00354     if (data->tls_prot) {
00355         return 0;
00356     }
00357 
00358     data->tls_prot = prot->type_get(prot, SEC_PROT_TYPE_TLS);
00359     if (!data->tls_prot) {
00360         return -1;
00361     }
00362 
00363     data->tls_prot->header_size = TLS_HEAD_LEN;
00364     data->tls_prot->sec_keys = prot->sec_keys;
00365 
00366     data->tls_prot->create_conf = NULL;
00367     data->tls_prot->create_ind = auth_eap_tls_sec_prot_tls_create_indication;
00368     data->tls_prot->finished_ind = auth_eap_tls_sec_prot_tls_finished_indication;
00369     data->tls_prot->send = auth_eap_tls_sec_prot_tls_send;
00370 
00371     data->tls_ongoing = true;
00372 
00373     return 0;
00374 }
00375 
00376 static void auth_eap_tls_sec_prot_delete_tls(sec_prot_t *prot)
00377 {
00378     // Triggers TLS to terminate if it is not already terminating by its own
00379     sec_prot_t *tls_prot = prot->type_get(prot, SEC_PROT_TYPE_TLS);
00380     if (tls_prot) {
00381         tls_prot->finished_send(tls_prot);
00382     }
00383 }
00384 
00385 static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
00386 {
00387     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00388     int8_t result = EAP_TLS_MSG_CONTINUE;
00389 
00390     // EAP-TLS authenticator state machine
00391     switch (sec_prot_state_get(&data->common)) {
00392         case EAP_TLS_STATE_INIT:
00393             tr_info("EAP-TLS init");
00394             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_CREATE_REQ);
00395             prot->timer_start(prot);
00396             break;
00397 
00398         // Wait KMP-CREATE.request
00399         case EAP_TLS_STATE_CREATE_REQ:
00400             tr_info("EAP-TLS start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00401 
00402             // Set default timeout for the total maximum length of the negotiation
00403             sec_prot_default_timeout_set(&data->common);
00404 
00405             // KMP-CREATE.confirm
00406             prot->create_conf(prot, SEC_RESULT_OK);
00407 
00408             // Increment sequence ID
00409             auth_eap_tls_sec_prot_seq_id_update(prot);
00410 
00411             // Sends EAP request, Identity
00412             auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE);
00413 
00414             // Start trickle timer to re-send if no response
00415             sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
00416 
00417             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE_ID);
00418             break;
00419 
00420         // Wait EAP response, Identity
00421         case EAP_TLS_STATE_RESPONSE_ID:
00422 
00423             // On timeout
00424             if (sec_prot_result_timeout_check(&data->common)) {
00425                 // Re-sends EAP request, Identity
00426                 auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_IDENTITY, EAP_TLS_EXCHANGE_NONE);
00427                 return;
00428             }
00429 
00430             // Handle EAP response (expected Identity)
00431             if (auth_eap_tls_sec_prot_message_handle(prot) != EAP_TLS_MSG_IDENTITY) {
00432                 return;
00433             }
00434 
00435             // Sends EAP request, TLS EAP start
00436             auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_START);
00437 
00438             // Start trickle timer to re-send if no response
00439             sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
00440 
00441             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE_START);
00442             break;
00443 
00444         // Wait EAP response, TLS handshake
00445         case EAP_TLS_STATE_RESPONSE_START:
00446         case EAP_TLS_STATE_RESPONSE:
00447 
00448             // On timeout
00449             if (sec_prot_result_timeout_check(&data->common)) {
00450                 if (sec_prot_state_get(&data->common) == EAP_TLS_STATE_RESPONSE_START) {
00451                     // Re-sends EAP request, TLS EAP start
00452                     auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_START);
00453                 } else {
00454                     // Re-sends EAP request, TLS EAP
00455                     auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_ONGOING);
00456                 }
00457                 return;
00458             }
00459 
00460             // EAP response
00461             if (data->eap_code == EAP_RESPONSE) {
00462                 // Handle EAP response, TLS EAP
00463                 result = auth_eap_tls_sec_prot_message_handle(prot);
00464                 if (result == EAP_TLS_MSG_DECODE_ERROR) {
00465                     return;
00466                 }
00467                 if (result == EAP_TLS_MSG_IDENTITY) {
00468                     // If received EAP response, Identity: re-sends EAP request, TLS EAP start
00469                     auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_START);
00470                     return;
00471                 }
00472 
00473                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_RESPONSE);
00474 
00475                 // All fragments received for a message
00476                 if (result == EAP_TLS_MSG_RECEIVE_DONE) {
00477                     // Initialize TLS protocol
00478                     if (auth_eap_tls_sec_prot_init_tls(prot) < 0) {
00479                         tr_error("TLS init failed");
00480                         return;
00481                     }
00482                     if (data->tls_ongoing) {
00483                         // Call TLS
00484                         data->tls_prot->receive(data->tls_prot, data->tls_recv.data, data->tls_recv.total_len);
00485                         eap_tls_sec_prot_lib_message_init(&data->tls_recv);
00486                         sec_prot_timer_trickle_stop(&data->common);
00487                         if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_FAILED && !data->send_pending) {
00488                             // In case has received alert and aborted can fail already here
00489                             eap_tls_sec_prot_lib_message_free(&data->tls_send);
00490                         } else {
00491                             data->wait_tls = true;
00492                         }
00493                     }
00494                 } else if (result == EAP_TLS_MSG_SEND_DONE) {
00495                     // All fragments send for a message, no new fragment received
00496                     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00497                 }
00498                 // Wait TLS to process the received message
00499                 if (data->wait_tls) {
00500                     return;
00501                 }
00502             } else {
00503                 // Call from TLS
00504                 if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_FATAL_ERROR) {
00505                     // Send failure
00506                     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00507                 }
00508 
00509                 // Call from TLS
00510                 data->wait_tls = false;
00511             }
00512 
00513             // TLS EAP message to be send
00514             if (data->tls_send.total_len > 0 || result == EAP_TLS_MSG_MORE_FRAG) {
00515                 data->send_pending = false;
00516 
00517                 // Sends EAP request, TLS EAP, TLS exchange
00518                 auth_eap_tls_sec_prot_message_send(prot, EAP_REQ, EAP_TLS, EAP_TLS_EXCHANGE_ONGOING);
00519 
00520                 // Start trickle timer to re-send if no response
00521                 sec_prot_timer_trickle_start(&data->common, &eap_tls_trickle_params);
00522             } else {
00523                 // TLS done, indicate success to peer
00524                 if (data->tls_result == EAP_TLS_RESULT_HANDSHAKE_OVER) {
00525                     // Supplicant PMK is now valid
00526                     sec_prot_keys_pmk_mismatch_reset(prot->sec_keys);
00527                     // Sends EAP success
00528                     auth_eap_tls_sec_prot_message_send(prot, EAP_SUCCESS, 0, EAP_TLS_EXCHANGE_NONE);
00529                 } else {
00530                     // Sends EAP failure
00531                     auth_eap_tls_sec_prot_message_send(prot, EAP_FAILURE, 0, EAP_TLS_EXCHANGE_NONE);
00532                     sec_prot_result_set(&data->common, SEC_RESULT_ERROR);
00533                 }
00534 
00535                 // Done
00536                 sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISH);
00537             }
00538             break;
00539 
00540         case EAP_TLS_STATE_FINISH:
00541             tr_info("EAP-TLS finish, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00542 
00543             // KMP-FINISHED.indication,
00544             prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
00545 
00546             sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISHED);
00547             break;
00548 
00549         case EAP_TLS_STATE_FINISHED: {
00550             uint8_t *remote_eui_64 = sec_prot_remote_eui_64_addr_get(prot);
00551             tr_info("EAP-TLS finished, eui-64: %s", remote_eui_64 ? trace_array(sec_prot_remote_eui_64_addr_get(prot), 8) : "not set");
00552             auth_eap_tls_sec_prot_delete_tls(prot);
00553             prot->timer_stop(prot);
00554             prot->finished(prot);
00555             break;
00556         }
00557         default:
00558             break;
00559     }
00560 }
00561 
00562 static void auth_eap_tls_sec_prot_seq_id_update(sec_prot_t *prot)
00563 {
00564     eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
00565     data->eap_id_seq++;
00566 }
00567 
00568 #endif /* HAVE_WS */
00569