Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tls_sec_prot.c Source File

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/tls_sec_prot/tls_sec_prot.h"
00037 #include "Security/protocols/tls_sec_prot/tls_sec_prot_lib.h"
00038 
00039 #ifdef HAVE_WS
00040 
00041 #define TRACE_GROUP "tlsp"
00042 
00043 typedef enum {
00044     TLS_STATE_INIT = SEC_STATE_INIT,
00045     TLS_STATE_CREATE_REQ = SEC_STATE_CREATE_REQ,
00046     TLS_STATE_CREATE_RESP = SEC_STATE_CREATE_RESP,
00047     TLS_STATE_CREATE_IND = SEC_STATE_CREATE_IND,
00048 
00049     TLS_STATE_CLIENT_HELLO = SEC_STATE_FIRST,
00050     TLS_STATE_CONFIGURE,
00051     TLS_STATE_PROCESS,
00052 
00053     TLS_STATE_FINISH = SEC_STATE_FINISH,
00054     TLS_STATE_FINISHED = SEC_STATE_FINISHED
00055 } eap_tls_sec_prot_state_e;
00056 
00057 typedef struct tls_sec_prot_lib_int_s tls_sec_prot_lib_int_t;
00058 
00059 typedef struct {
00060     sec_prot_common_t             common;            /**< Common data */
00061     uint8_t                       new_pmk[PMK_LEN];  /**< New Pair Wise Master Key */
00062     tls_data_t                    tls_send;          /**< TLS send buffer */
00063     tls_data_t                    tls_recv;          /**< TLS receive buffer */
00064     uint32_t                      int_timer;         /**< TLS intermediate timer timeout */
00065     uint32_t                      fin_timer;         /**< TLS final timer timeout */
00066     bool                          fin_timer_timeout; /**< TLS final timer has timeouted */
00067     bool                          timer_running : 1; /**< TLS timer running */
00068     bool                          finished : 1;      /**< TLS finished */
00069     bool                          calculating : 1;   /**< TLS is calculating */
00070     bool                          queued : 1;        /**< TLS is queued */
00071     bool                          library_init : 1;  /**< TLS library has been initialized */
00072     tls_sec_prot_lib_int_t        *tls_sec_inst;     /**< TLS security library storage, SHALL BE THE LAST FIELD */
00073 } tls_sec_prot_int_t;
00074 
00075 typedef struct {
00076     ns_list_link_t link;                             /**< Link */
00077     sec_prot_t *prot;                                /**< Protocol instance */
00078 } tls_sec_prot_queue_t;
00079 
00080 static uint16_t tls_sec_prot_size(void);
00081 static int8_t client_tls_sec_prot_init(sec_prot_t *prot);
00082 static int8_t server_tls_sec_prot_init(sec_prot_t *prot);
00083 
00084 static void tls_sec_prot_create_request(sec_prot_t *prot, sec_prot_keys_t *sec_keys);
00085 static void tls_sec_prot_create_response(sec_prot_t *prot, sec_prot_result_e result);
00086 static void tls_sec_prot_delete(sec_prot_t *prot);
00087 static int8_t tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t size);
00088 static void tls_sec_prot_finished_send(sec_prot_t *prot);
00089 
00090 static void client_tls_sec_prot_state_machine(sec_prot_t *prot);
00091 static void server_tls_sec_prot_state_machine(sec_prot_t *prot);
00092 
00093 static void tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks);
00094 
00095 static int16_t tls_sec_prot_tls_send(void *handle, const void *buf, size_t len);
00096 static int16_t tls_sec_prot_tls_receive(void *handle, unsigned char *buf, size_t len);
00097 static void tls_sec_prot_tls_export_keys(void *handle, const uint8_t *master_secret, const uint8_t *eap_tls_key_material);
00098 static void tls_sec_prot_tls_set_timer(void *handle, uint32_t inter, uint32_t fin);
00099 static int8_t tls_sec_prot_tls_get_timer(void *handle);
00100 
00101 static int8_t tls_sec_prot_tls_configure_and_connect(sec_prot_t *prot, bool is_server);
00102 
00103 static bool tls_sec_prot_queue_check(sec_prot_t *prot);
00104 static bool tls_sec_prot_queue_process(sec_prot_t *prot);
00105 static void tls_sec_prot_queue_remove(sec_prot_t *prot);
00106 
00107 static uint16_t tls_sec_prot_send_buffer_size_get(sec_prot_t *prot);
00108 
00109 #define tls_sec_prot_get(prot) (tls_sec_prot_int_t *) &prot->data
00110 
00111 static NS_LIST_DEFINE(tls_sec_prot_queue, tls_sec_prot_queue_t, link);
00112 
00113 int8_t client_tls_sec_prot_register(kmp_service_t *service)
00114 {
00115     if (!service) {
00116         return -1;
00117     }
00118 
00119     if (kmp_service_sec_protocol_register(service, TLS_PROT, tls_sec_prot_size, client_tls_sec_prot_init) < 0) {
00120         return -1;
00121     }
00122 
00123     return 0;
00124 }
00125 
00126 int8_t server_tls_sec_prot_register(kmp_service_t *service)
00127 {
00128     if (!service) {
00129         return -1;
00130     }
00131 
00132     if (kmp_service_sec_protocol_register(service, TLS_PROT, tls_sec_prot_size, server_tls_sec_prot_init) < 0) {
00133         return -1;
00134     }
00135 
00136     return 0;
00137 }
00138 
00139 static uint16_t tls_sec_prot_size(void)
00140 {
00141     return sizeof(tls_sec_prot_int_t) + tls_sec_prot_lib_size();
00142 }
00143 
00144 static int8_t client_tls_sec_prot_init(sec_prot_t *prot)
00145 {
00146     prot->create_req = tls_sec_prot_create_request;
00147     prot->create_resp = NULL;
00148     prot->receive = tls_sec_prot_receive;
00149     prot->delete = tls_sec_prot_delete;
00150     prot->state_machine = client_tls_sec_prot_state_machine;
00151     prot->timer_timeout = tls_sec_prot_timer_timeout;
00152     prot->finished_send = tls_sec_prot_finished_send;
00153 
00154     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00155 
00156     sec_prot_init(&data->common);
00157     sec_prot_state_set(prot, &data->common, TLS_STATE_INIT);
00158 
00159     memset(data->new_pmk, 0, PMK_LEN);
00160     data->finished = false;
00161     // Set from security parameters
00162     eap_tls_sec_prot_lib_message_init(&data->tls_recv);
00163     eap_tls_sec_prot_lib_message_init(&data->tls_send);
00164     data->int_timer = 0;
00165     data->fin_timer = 0;
00166     data->fin_timer_timeout = false;
00167     data->timer_running = false;
00168     data->calculating = false;
00169     data->queued = false;
00170     data->library_init = false;
00171     return 0;
00172 }
00173 
00174 static int8_t server_tls_sec_prot_init(sec_prot_t *prot)
00175 {
00176     prot->create_req = NULL;
00177     prot->create_resp = tls_sec_prot_create_response;
00178     prot->receive = tls_sec_prot_receive;
00179     prot->delete = tls_sec_prot_delete;
00180     prot->state_machine = server_tls_sec_prot_state_machine;
00181     prot->timer_timeout = tls_sec_prot_timer_timeout;
00182     prot->finished_send = tls_sec_prot_finished_send;
00183 
00184     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00185 
00186     sec_prot_init(&data->common);
00187     sec_prot_state_set(prot, &data->common, TLS_STATE_INIT);
00188 
00189     memset(data->new_pmk, 0, PMK_LEN);
00190     data->finished = false;
00191     // Set from security parameters
00192     eap_tls_sec_prot_lib_message_init(&data->tls_recv);
00193     eap_tls_sec_prot_lib_message_init(&data->tls_send);
00194     data->int_timer = 0;
00195     data->fin_timer = 0;
00196     data->fin_timer_timeout = false;
00197     data->timer_running = false;
00198     data->calculating = false;
00199     data->queued = false;
00200     data->library_init = false;
00201     return 0;
00202 }
00203 
00204 static void tls_sec_prot_delete(sec_prot_t *prot)
00205 {
00206     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00207     eap_tls_sec_prot_lib_message_free(&data->tls_send);
00208     eap_tls_sec_prot_lib_message_free(&data->tls_recv);
00209     if (data->library_init) {
00210         tr_info("TLS: free library");
00211         tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
00212     }
00213     tls_sec_prot_queue_remove(prot);
00214 }
00215 
00216 static void tls_sec_prot_create_request(sec_prot_t *prot, sec_prot_keys_t *sec_keys)
00217 {
00218     prot->sec_keys = sec_keys;
00219 
00220     // Call state machine
00221     prot->state_machine_call(prot);
00222 }
00223 
00224 static void tls_sec_prot_create_response(sec_prot_t *prot, sec_prot_result_e result)
00225 {
00226     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00227 
00228     // Call state machine
00229     sec_prot_result_set(&data->common, result);
00230     prot->state_machine_call(prot);
00231 }
00232 
00233 static int8_t tls_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t size)
00234 {
00235     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00236 
00237     // Discards old data
00238     eap_tls_sec_prot_lib_message_free(&data->tls_recv);
00239 
00240     data->tls_recv.data = pdu;
00241     data->tls_recv.total_len = size;
00242 
00243     prot->state_machine(prot);
00244 
00245     return 0;
00246 }
00247 
00248 static void tls_sec_prot_finished_send(sec_prot_t *prot)
00249 {
00250     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00251     prot->timer_start(prot);
00252     sec_prot_state_set(prot, &data->common, TLS_STATE_FINISHED);
00253 }
00254 
00255 static void tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
00256 {
00257     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00258 
00259     if (data->timer_running) {
00260         if (data->int_timer > ticks) {
00261             data->int_timer -= ticks;
00262         } else {
00263             data->int_timer = 0;
00264         }
00265 
00266         if (data->fin_timer > ticks) {
00267             data->fin_timer -= ticks;
00268         } else {
00269             if (data->fin_timer > 0) {
00270                 data->fin_timer_timeout = true;
00271                 data->fin_timer = 0;
00272             }
00273         }
00274     }
00275 
00276     /* Checks if TLS sessions queue is enabled, and if queue is enabled whether the
00277        session is first in the queue i.e. allowed to process */
00278     if (tls_sec_prot_queue_process(prot)) {
00279         if (data->fin_timer_timeout) {
00280             data->fin_timer_timeout = false;
00281             prot->state_machine(prot);
00282         } else if (data->calculating || data->queued) {
00283             prot->state_machine(prot);
00284         }
00285     }
00286 
00287     sec_prot_timer_timeout_handle(prot, &data->common, NULL, ticks);
00288 }
00289 
00290 static void client_tls_sec_prot_state_machine(sec_prot_t *prot)
00291 {
00292     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00293     int8_t result;
00294 
00295     switch (sec_prot_state_get(&data->common)) {
00296         case TLS_STATE_INIT:
00297             tr_debug("TLS: init");
00298             sec_prot_state_set(prot, &data->common, TLS_STATE_CREATE_REQ);
00299             prot->timer_start(prot);
00300             // Set default timeout for the total maximum length of the negotiation
00301             sec_prot_default_timeout_set(&data->common);
00302             break;
00303 
00304         // Wait KMP-CREATE.request
00305         case TLS_STATE_CREATE_REQ:
00306             tr_debug("TLS: start");
00307 
00308             prot->create_conf(prot, SEC_RESULT_OK);
00309 
00310             sec_prot_state_set(prot, &data->common, TLS_STATE_CONFIGURE);
00311 
00312             prot->state_machine_call(prot);
00313             break;
00314 
00315         case TLS_STATE_CONFIGURE:
00316             if (tls_sec_prot_tls_configure_and_connect(prot, false) < 0) {
00317                 sec_prot_result_set(&data->common, SEC_RESULT_CONF_ERROR);
00318                 sec_prot_state_set(prot, &data->common, TLS_STATE_FINISH);
00319                 return;
00320             }
00321             sec_prot_state_set(prot, &data->common, TLS_STATE_PROCESS);
00322             prot->state_machine(prot);
00323             break;
00324 
00325         case TLS_STATE_PROCESS:
00326             result = tls_sec_prot_lib_process((tls_security_t *) &data->tls_sec_inst);
00327 
00328             if (result == TLS_SEC_PROT_LIB_CALCULATING) {
00329                 data->calculating = true;
00330                 prot->state_machine_call(prot);
00331                 return;
00332             } else {
00333                 data->calculating = false;
00334             }
00335 
00336             if (data->tls_send.data) {
00337                 prot->send(prot, data->tls_send.data, data->tls_send.handled_len);
00338                 eap_tls_sec_prot_lib_message_init(&data->tls_send);
00339             }
00340 
00341             if (result != TLS_SEC_PROT_LIB_CONTINUE) {
00342                 if (result == TLS_SEC_PROT_LIB_ERROR) {
00343                     tr_error("TLS: error");
00344                     sec_prot_result_set(&data->common, SEC_RESULT_ERROR);
00345                 }
00346                 sec_prot_state_set(prot, &data->common, TLS_STATE_FINISH);
00347             }
00348             break;
00349 
00350         case TLS_STATE_FINISH:
00351             tr_debug("TLS: finish");
00352 
00353             data->calculating = false;
00354 
00355             if (sec_prot_result_ok_check(&data->common)) {
00356                 sec_prot_keys_pmk_write(prot->sec_keys, data->new_pmk);
00357             }
00358 
00359             // KMP-FINISHED.indication,
00360             prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
00361             sec_prot_state_set(prot, &data->common, TLS_STATE_FINISHED);
00362 
00363             tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
00364             data->library_init = false;
00365             break;
00366 
00367         case TLS_STATE_FINISHED:
00368             tr_debug("TLS: finished, free %s", data->library_init ? "T" : "F");
00369             if (data->library_init) {
00370                 tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
00371                 data->library_init = false;
00372             }
00373             prot->timer_stop(prot);
00374             prot->finished(prot);
00375             break;
00376 
00377         default:
00378             break;
00379     }
00380 }
00381 
00382 static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
00383 {
00384     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00385     int8_t result;
00386     bool client_hello = false;
00387 
00388     switch (sec_prot_state_get(&data->common)) {
00389         case TLS_STATE_INIT:
00390             tr_debug("TLS: init");
00391             sec_prot_state_set(prot, &data->common, TLS_STATE_CLIENT_HELLO);
00392             prot->timer_start(prot);
00393             // Set default timeout for the total maximum length of the negotiation
00394             sec_prot_default_timeout_set(&data->common);
00395             break;
00396 
00397         // Wait EAP request, Identity (starts handshake on supplicant)
00398         case TLS_STATE_CLIENT_HELLO:
00399             tr_debug("TLS: start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00400 
00401             client_hello = true;
00402 
00403             sec_prot_state_set(prot, &data->common, TLS_STATE_CREATE_RESP);
00404 
00405             // Send KMP-CREATE.indication
00406             prot->create_ind(prot);
00407             break;
00408 
00409         // Wait KMP-CREATE.response
00410         case TLS_STATE_CREATE_RESP:
00411             if (sec_prot_result_ok_check(&data->common)) {
00412                 sec_prot_state_set(prot, &data->common, TLS_STATE_CONFIGURE);
00413                 prot->state_machine_call(prot);
00414             } else {
00415                 // Ready to be deleted
00416                 sec_prot_state_set(prot, &data->common, TLS_STATE_FINISHED);
00417             }
00418             break;
00419 
00420         case TLS_STATE_CONFIGURE:
00421             if (tls_sec_prot_tls_configure_and_connect(prot, true) < 0) {
00422                 sec_prot_result_set(&data->common, SEC_RESULT_CONF_ERROR);
00423                 sec_prot_state_set(prot, &data->common, TLS_STATE_FINISH);
00424                 return;
00425             }
00426             sec_prot_state_set(prot, &data->common, TLS_STATE_PROCESS);
00427             prot->state_machine(prot);
00428             break;
00429 
00430         case TLS_STATE_PROCESS:
00431             // If not client hello, reserves slot on TLS queue
00432             if (!client_hello && !tls_sec_prot_queue_check(prot)) {
00433                 data->queued = true;
00434                 return;
00435             } else {
00436                 data->queued = false;
00437             }
00438 
00439             result = tls_sec_prot_lib_process((tls_security_t *) &data->tls_sec_inst);
00440 
00441             if (result == TLS_SEC_PROT_LIB_CALCULATING) {
00442                 data->calculating = true;
00443                 prot->state_machine_call(prot);
00444                 return;
00445             } else {
00446                 data->calculating = false;
00447             }
00448 
00449             if (data->tls_send.data) {
00450                 prot->send(prot, data->tls_send.data, data->tls_send.handled_len);
00451                 eap_tls_sec_prot_lib_message_init(&data->tls_send);
00452             }
00453 
00454             if (result != TLS_SEC_PROT_LIB_CONTINUE) {
00455                 if (result == TLS_SEC_PROT_LIB_ERROR) {
00456                     tr_error("TLS: error, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00457                     sec_prot_result_set(&data->common, SEC_RESULT_ERROR);
00458                 }
00459                 sec_prot_state_set(prot, &data->common, TLS_STATE_FINISH);
00460             }
00461             break;
00462 
00463         case TLS_STATE_FINISH:
00464             tr_debug("TLS: finish, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00465 
00466             data->calculating = false;
00467 
00468             if (sec_prot_result_ok_check(&data->common)) {
00469                 sec_prot_keys_pmk_write(prot->sec_keys, data->new_pmk);
00470             }
00471 
00472             // KMP-FINISHED.indication,
00473             prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
00474             sec_prot_state_set(prot, &data->common, TLS_STATE_FINISHED);
00475 
00476             tls_sec_prot_queue_remove(prot);
00477             tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
00478             data->library_init = false;
00479             break;
00480 
00481         case TLS_STATE_FINISHED: {
00482             uint8_t *remote_eui_64 = sec_prot_remote_eui_64_addr_get(prot);
00483             tr_debug("TLS: finished, eui-64: %s free %s", remote_eui_64 ? trace_array(sec_prot_remote_eui_64_addr_get(prot), 8) : "not set", data->library_init ? "T" : "F");
00484             if (data->library_init) {
00485                 tls_sec_prot_lib_free((tls_security_t *) &data->tls_sec_inst);
00486                 data->library_init = false;
00487             }
00488             prot->timer_stop(prot);
00489             prot->finished(prot);
00490             break;
00491         }
00492         default:
00493             break;
00494     }
00495 }
00496 
00497 static int16_t tls_sec_prot_tls_send(void *handle, const void *buf, size_t len)
00498 {
00499     sec_prot_t *prot = handle;
00500     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00501 
00502     if (!data->tls_send.data) {
00503         uint16_t buffer_len = tls_sec_prot_send_buffer_size_get(prot);
00504         eap_tls_sec_prot_lib_message_allocate(&data->tls_send, prot->header_size, buffer_len);
00505     }
00506     if (!data->tls_send.data) {
00507         return -1;
00508     }
00509 
00510     /* If send buffer is too small for the TLS payload, re-allocates */
00511     uint16_t new_len = prot->header_size + data->tls_send.handled_len + len;
00512     if (new_len > data->tls_send.total_len) {
00513         tr_error("TLS send buffer size too small: %i < %i, allocating new: %i", data->tls_send.total_len, new_len, data->tls_send.total_len + TLS_SEC_PROT_SEND_BUFFER_SIZE_INCREMENT);
00514         if (eap_tls_sec_prot_lib_message_realloc(&data->tls_send, prot->header_size,
00515                                                  data->tls_send.total_len + TLS_SEC_PROT_SEND_BUFFER_SIZE_INCREMENT) < 0) {
00516             return -1;
00517         }
00518     }
00519 
00520     memcpy(data->tls_send.data + prot->header_size + data->tls_send.handled_len, buf, len);
00521     data->tls_send.handled_len += len;
00522 
00523     return len;
00524 }
00525 
00526 static int16_t tls_sec_prot_tls_receive(void *handle, unsigned char *buf, size_t len)
00527 {
00528     sec_prot_t *prot = handle;
00529     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00530 
00531     if (data->tls_recv.data && len > 0) {
00532 
00533         uint16_t copy_len = len;
00534         bool all_copied = false;
00535 
00536         if ((uint16_t) copy_len >= data->tls_recv.total_len - data->tls_recv.handled_len) {
00537             copy_len = data->tls_recv.total_len - data->tls_recv.handled_len;
00538             all_copied = true;
00539         }
00540 
00541         memcpy(buf, data->tls_recv.data + data->tls_recv.handled_len, copy_len);
00542 
00543         data->tls_recv.handled_len += copy_len;
00544 
00545         if (all_copied) {
00546             eap_tls_sec_prot_lib_message_free(&data->tls_recv);
00547         }
00548 
00549         return copy_len;
00550     }
00551 
00552     return TLS_SEC_PROT_LIB_NO_DATA;
00553 }
00554 
00555 static void tls_sec_prot_tls_export_keys(void *handle, const uint8_t *master_secret, const uint8_t *eap_tls_key_material)
00556 {
00557     (void) master_secret;
00558 
00559     sec_prot_t *prot = handle;
00560     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00561 
00562     if (eap_tls_key_material) {
00563         memcpy(data->new_pmk, eap_tls_key_material, PMK_LEN);
00564     }
00565 
00566 #ifdef EXTRA_DEBUG_INFO
00567     const uint8_t *print_data = eap_tls_key_material;
00568     uint16_t print_data_len = 128;
00569     while (true) {
00570         tr_debug("EAP-TLS key material %s\n", trace_array(print_data, print_data_len > 32 ? 32 : print_data_len));
00571         if (print_data_len > 32) {
00572             print_data_len -= 32;
00573             print_data += 32;
00574         } else {
00575             break;
00576         }
00577     }
00578 #endif
00579 }
00580 
00581 static void tls_sec_prot_tls_set_timer(void *handle, uint32_t inter, uint32_t fin)
00582 {
00583     sec_prot_t *prot = handle;
00584     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00585 
00586     if (fin == 0) {
00587         data->timer_running = false;
00588         data->int_timer = 0;
00589         data->fin_timer = 0;
00590         return;
00591     }
00592 
00593     data->timer_running = true;
00594     data->int_timer = inter / 100;
00595     data->fin_timer = fin / 100;
00596 }
00597 
00598 static int8_t tls_sec_prot_tls_get_timer(void *handle)
00599 {
00600     sec_prot_t *prot = handle;
00601     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00602 
00603     if (!data->timer_running) {
00604         return TLS_SEC_PROT_LIB_TIMER_CANCELLED;
00605     } else if (data->fin_timer == 0) {
00606         return TLS_SEC_PROT_LIB_TIMER_FIN_EXPIRY;
00607     } else if (data->int_timer == 0) {
00608         return TLS_SEC_PROT_LIB_TIMER_INT_EXPIRY;
00609     }
00610 
00611     return TLS_SEC_PROT_LIB_TIMER_NO_EXPIRY;
00612 }
00613 
00614 static int8_t tls_sec_prot_tls_configure_and_connect(sec_prot_t *prot, bool is_server)
00615 {
00616     tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
00617 
00618     // Must be free if library initialize is done
00619     data->library_init = true;
00620     if (tls_sec_prot_lib_init((tls_security_t *)&data->tls_sec_inst) < 0) {
00621         tr_error("TLS: library init fail");
00622         return -1;
00623     }
00624 
00625     tls_sec_prot_lib_set_cb_register((tls_security_t *)&data->tls_sec_inst, prot,
00626                                      tls_sec_prot_tls_send, tls_sec_prot_tls_receive, tls_sec_prot_tls_export_keys,
00627                                      tls_sec_prot_tls_set_timer, tls_sec_prot_tls_get_timer);
00628 
00629     if (tls_sec_prot_lib_connect((tls_security_t *)&data->tls_sec_inst, is_server, prot->sec_keys->certs) < 0) {
00630         tr_error("TLS: library connect fail");
00631         return -1;
00632     }
00633 
00634     return 0;
00635 }
00636 
00637 static bool tls_sec_prot_queue_check(sec_prot_t *prot)
00638 {
00639     bool queue_add = true;
00640     bool queue_continue = false;
00641     uint8_t entry_index = 0;
00642 
00643     // Checks if TLS queue is empty or this instance is the first entry
00644     if (ns_list_is_empty(&tls_sec_prot_queue)) {
00645         queue_continue = true;
00646     } else {
00647         ns_list_foreach(tls_sec_prot_queue_t, entry, &tls_sec_prot_queue) {
00648             if (entry->prot == prot) {
00649                 queue_add = false;
00650                 if (entry_index < 3) {
00651                     queue_continue = true;
00652                     break;
00653                 } else {
00654                     queue_continue = false;
00655                 }
00656             }
00657             entry_index++;
00658         }
00659     }
00660 
00661     // Adds entry to queue if not there already
00662     if (queue_add) {
00663         tr_debug("TLS QUEUE add index: %i, eui-64: %s", entry_index, trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
00664         tls_sec_prot_queue_t *entry = ns_dyn_mem_temporary_alloc(sizeof(tls_sec_prot_queue_t));
00665         if (entry) {
00666             entry->prot = prot;
00667             ns_list_add_to_end(&tls_sec_prot_queue, entry);
00668         }
00669     }
00670 
00671     return queue_continue;
00672 }
00673 
00674 static bool tls_sec_prot_queue_process(sec_prot_t *prot)
00675 {
00676     if (ns_list_is_empty(&tls_sec_prot_queue)) {
00677         return true;
00678     }
00679 
00680     uint8_t entry_index = 0;
00681     ns_list_foreach(tls_sec_prot_queue_t, entry, &tls_sec_prot_queue) {
00682         if (entry->prot == prot) {
00683             return true;
00684         }
00685         if (entry_index > 2) {
00686             return false;
00687         }
00688         entry_index++;
00689     }
00690 
00691     return false;
00692 }
00693 
00694 static void tls_sec_prot_queue_remove(sec_prot_t *prot)
00695 {
00696     ns_list_foreach_safe(tls_sec_prot_queue_t, entry, &tls_sec_prot_queue) {
00697         if (entry->prot == prot) {
00698             ns_list_remove(&tls_sec_prot_queue, entry);
00699             ns_dyn_mem_free(entry);
00700             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));
00701         }
00702     }
00703 }
00704 
00705 static uint16_t tls_sec_prot_send_buffer_size_get(sec_prot_t *prot)
00706 {
00707     return TLS_SEC_PROT_SEND_BUFFER_SIZE + sec_prot_certs_own_cert_chain_len_get(prot->sec_keys->certs);
00708 }
00709 
00710 #endif /* HAVE_WS */