BA / Mbed OS BaBoRo1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pana_server.c Source File

pana_server.c

00001 /*
00002  * Copyright (c) 2017, 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 #include "nsconfig.h"
00018 
00019 #include "ns_types.h"
00020 #include "eventOS_event.h"
00021 #include "ns_trace.h"
00022 #include "string.h"
00023 #include "randLIB.h"
00024 #include "nsdynmemLIB.h"
00025 #include "Core/include/socket.h"
00026 #include "NWK_INTERFACE/Include/protocol.h"
00027 #include "ccmLIB.h"
00028 #include "shalib.h"
00029 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
00030 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h"
00031 #ifdef ECC
00032 #include "libX509_V3.h"
00033 #include "ecc.h"
00034 #endif
00035 #include "Security/TLS/tls_lib.h"
00036 #include "Security/Common/sec_lib.h"
00037 #include "net_nvm_api.h"
00038 #include "Security/PANA/pana.h"
00039 #include "Security/PANA/pana_internal_api.h"
00040 #include "6LoWPAN/MAC/mac_helper.h"
00041 #include "6LoWPAN/MAC/mac_data_poll.h"
00042 #include "6LoWPAN/ND/nd_router_object.h"
00043 #include "Common_Protocols/udp.h"
00044 
00045 #ifdef ECC
00046 #include    "ecc.h"
00047 #endif
00048 #include "common_functions.h"
00049 #include "Security/PANA/pana_nvm.h"
00050 #include "Security/PANA/pana_avp.h"
00051 #include "Security/PANA/pana_eap_header.h"
00052 #include "Security/PANA/pana_header.h"
00053 #include "Security/PANA/eap_protocol.h"
00054 #include "net_pana_parameters_api.h"
00055 #include "Service_Libs/mle_service/mle_service_api.h"
00056 #include "6LoWPAN/NVM/nwk_nvm.h"
00057 
00058 #ifdef PANA
00059 #ifdef PANA_SERVER_API
00060 
00061 #define TRACE_GROUP "PanS"
00062 static pana_server_base_t *NS_LARGE pana_server_base = NULL;
00063 static pana_server_update_cb *pana_nvm_storage_cb = NULL;
00064 static pana_server_session_get_cb *pana_server_nvm_get = NULL;
00065 static pana_server_session_get_by_id_cb *pana_server_nvm__session_get = NULL;
00066 static void (*pana_key_update_process_ready)(void) = 0;
00067 static uint8_t *pana_nvm_buffer = 0;
00068 
00069 static void pana_server_packet_handler(buffer_t *buf);
00070 static int8_t pana_server_init(int8_t nwk_id, const uint8_t *network_key_material, uint8_t supported_chipher_suites, uint32_t key_update_delay);
00071 static pana_server_base_t * pana_server_staructure_allocate(void);
00072 static pana_key_material_t *pana_server_key_get(bool primary);
00073 static void pana_server_set_random_key_value(uint8_t *network_key_material);
00074 static void pana_server_material_read(const uint8_t *ptr);
00075 static void pana_server_material_write(uint8_t *ptr);
00076 static void pana_server_client_save_to_nvm(sec_suite_t *suite, pana_nvm_update_process_t nvm_event);
00077 static uint8_t *pana_avp_zip_key_material(uint8_t *dptr, uint8_t *key_info, uint32_t message_seq, sec_suite_t *suite);
00078 static void pana_client_session_init(sec_suite_t *suite);
00079 
00080 static bool pana_auth_msg_validate(uint8_t *ptr, uint16_t length, uint8_t *key);
00081 static void pana_pna_response_build(buffer_t *buf, uint8_t operation, pana_header_t *header, sec_suite_t *suite);
00082 static void pana_client_authentication_fail(sec_suite_t *suite);
00083 static void pana_key_update_delivery_ready(void);
00084 static void pana_server_build_key_push(buffer_t *buf, sec_suite_t *suite);
00085 static void pana_success_server_build(buffer_t *buf, sec_suite_t *suite);
00086 static void pana_server_state_machine_func(sec_suite_t *suite);
00087 
00088 
00089 static uint8_t *pana_avp_zip_key_material(uint8_t *dptr, uint8_t *key_info, uint32_t message_seq, sec_suite_t *suite)
00090 {
00091     //SET AVP BASE
00092     dptr = pana_avp_base_write(AVP_ENCRYPT_ALGORITHM_CODE, 32, dptr, 0, 0);
00093     uint8_t *ptr = dptr;
00094     dptr = pana_avp_vendor_id_write_n_bytes(PANA_EAP_KEYWRAP_TYPE, 18, key_info, dptr, ZIGBEE_VENDOR_ID);
00095     //Crypt Key Info
00096     pana_ccm_data_crypt(ptr, 32, AES_CCM_ENCRYPT, message_seq, suite);
00097     return dptr;
00098 }
00099 
00100 static pana_server_base_t * pana_server_staructure_allocate(void)
00101 {
00102     pana_server_base_t *server = ns_dyn_mem_alloc(sizeof(pana_server_base_t));
00103     if (server) {
00104         memset(server, 0, sizeof(pana_server_base_t));
00105     }
00106     return server;
00107 }
00108 
00109 static pana_key_material_t *pana_server_key_get(bool primary)
00110 {
00111     if (primary) {
00112         return &pana_server_base->sec_key_material[pana_server_base->primary_material];
00113     }
00114 
00115     if (pana_server_base->primary_material) {
00116         return    &pana_server_base->sec_key_material[0];
00117     }
00118 
00119     return &pana_server_base->sec_key_material[1];
00120 }
00121 
00122 static void pana_server_set_random_key_value(uint8_t *network_key_material)
00123 {
00124     randLIB_get_n_bytes_random(network_key_material, 16);
00125 }
00126 
00127 static void pana_server_material_write(uint8_t *ptr)
00128 {
00129     pana_key_material_t *key_ptr;
00130     ptr = common_write_32_bit(pana_server_base->pana_key_id, ptr);
00131     ptr = common_write_32_bit(pana_server_base->session_lifetime, ptr);
00132     ptr = common_write_32_bit(pana_server_base->key_wrap, ptr);
00133     ptr = common_write_32_bit(pana_server_base->prf_algorythm, ptr);
00134     ptr = common_write_32_bit(pana_server_base->integrity_algorythm, ptr);
00135     ptr = common_write_32_bit(pana_server_base->next_session_id, ptr);
00136     ptr = common_write_32_bit(pana_server_base->key_update_delay, ptr);
00137     ptr = common_write_32_bit(pana_server_base->pana_key_update_delay_used, ptr); //32
00138     *ptr++ = pana_server_base->supported_chipher_suites;
00139     *ptr++ = pana_server_base->auth_cnt;
00140     *ptr++ = pana_server_base->primary_material;
00141     key_ptr = &pana_server_base->sec_key_material[0];
00142     *ptr++ = key_ptr->key_id;
00143     memcpy(ptr, key_ptr->key_material, 16);
00144     ptr += 16;//52
00145     key_ptr = &pana_server_base->sec_key_material[1];
00146     *ptr++ = key_ptr->key_id;
00147     memcpy(ptr, key_ptr->key_material, 16);
00148     ptr += 16;  //69
00149 
00150     if (pana_server_base->pana_key_update) {
00151         pana_key_update_t *pku = pana_server_base->pana_key_update;
00152         *ptr++ = 1;
00153         *ptr++ = pku->key_id;
00154         ptr = common_write_16_bit(pku->key_delivery_cnt, ptr); //73
00155         memcpy(ptr, pku->new_key_material, 16); // 89
00156     } else {
00157         *ptr = 0; //70
00158     }
00159 
00160 }
00161 
00162 static void pana_server_material_read(const uint8_t *ptr)
00163 {
00164     pana_key_material_t *key_ptr;
00165     //Set Stored setup
00166     pana_server_base->pana_key_id = common_read_32_bit(ptr);
00167     ptr += 4;
00168     pana_server_base->session_lifetime = common_read_32_bit(ptr);
00169     ptr += 4;
00170     pana_server_base->key_wrap = common_read_32_bit(ptr);
00171     ptr += 4;
00172     pana_server_base->prf_algorythm = common_read_32_bit(ptr);
00173     ptr += 4;
00174     pana_server_base->integrity_algorythm = common_read_32_bit(ptr);
00175     ptr += 4;
00176     pana_server_base->next_session_id = common_read_32_bit(ptr);
00177     ptr += 4;
00178     pana_server_base->key_update_delay = common_read_32_bit(ptr);
00179     ptr += 4;
00180     pana_server_base->pana_key_update_delay_used = common_read_32_bit(ptr);
00181     ptr += 4;
00182     pana_server_base->supported_chipher_suites = *ptr++;
00183     pana_server_base->auth_cnt = *ptr++;
00184     pana_server_base->primary_material = *ptr++;
00185 
00186     key_ptr = &pana_server_base->sec_key_material[0];
00187     key_ptr->key_id = *ptr++;
00188     memcpy(key_ptr->key_material, ptr, 16);
00189     tr_debug("KID0: %02x, %s", key_ptr->key_id, trace_array(ptr, 16));
00190     ptr += 16;
00191 
00192     key_ptr = &pana_server_base->sec_key_material[1];
00193     key_ptr->key_id = *ptr++;
00194     memcpy(key_ptr->key_material, ptr, 16);
00195     tr_debug("KID1: %02x, %s", key_ptr->key_id, trace_array(ptr, 16));
00196     ptr += 16;
00197 
00198     uint8_t key_update = *ptr++;
00199     if (key_update) {
00200         pana_key_update_t *pku = ns_dyn_mem_temporary_alloc(sizeof(pana_key_update_t));
00201         if (pku) {
00202             pku->key_id = *ptr++;
00203             pku->key_delivery_cnt = common_read_16_bit(ptr);
00204             ptr += 2;
00205             memcpy(pku->new_key_material, ptr, 16);
00206             pana_server_base->pana_key_update = pku;
00207             tr_debug("Key Update Process active");
00208         }
00209     }
00210 }
00211 
00212 
00213 static int8_t pana_server_init(int8_t nwk_id, const uint8_t *network_key_material, uint8_t supported_chipher_suites, uint32_t key_update_delay)
00214 {
00215     if (!pana_socket_init(pana_server_packet_handler, pana_server_state_machine_func, tls_server_up)) {
00216         return -1;
00217     }
00218 
00219     int8_t ret_val = -1;
00220     sec_suite_list_clean();
00221 
00222     //Allocate
00223     if (pana_server_base == 0) {
00224         pana_server_base = pana_server_staructure_allocate();
00225     } else {
00226         if (pana_server_base->network_interface_id != nwk_id) {
00227             tr_debug("UnKnow id");
00228             return -2;
00229         }
00230     }
00231     if (pana_server_base) {
00232 
00233         pana_server_base->primary_material = 0;
00234         pana_key_material_t *key_info = pana_server_key_get(false);
00235         key_info->key_id = 0;
00236         key_info = pana_server_key_get(true);
00237 
00238 
00239         key_info->key_id = 1;
00240         if (network_key_material) {
00241             memcpy(key_info->key_material, network_key_material, 16);
00242         } else {
00243             pana_server_set_random_key_value(key_info->key_material);
00244         }
00245         pana_server_base->auth_cnt = 0;
00246         pana_server_base->pana_key_id = 1;
00247         pana_server_base->session_lifetime = 0xffffffff;
00248         pana_server_base->key_wrap = 1;
00249         pana_server_base->prf_algorythm = 5;
00250         pana_server_base->integrity_algorythm = 0x0c;
00251         pana_server_base->next_session_id = 1;
00252         pana_server_base->key_update_delay = 0;
00253         pana_server_base->supported_chipher_suites = supported_chipher_suites;
00254         pana_server_base->pana_key_update = 0;
00255         pana_server_base->open_pana_authentication_cnt = 0;
00256         pana_server_base->network_interface_id = nwk_id;
00257         pana_server_base->pana_key_update_delay_used = key_update_delay;
00258         if (pana_nvm_storage_cb) {
00259             pana_server_material_write(pana_nvm_buffer);
00260             pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
00261         }
00262         ret_val = 0;
00263     }
00264     return ret_val;
00265 }
00266 
00267 void pana_key_update_delivery_ready(void)
00268 {
00269     if (pana_server_base && pana_server_base->pana_key_update) {
00270         if (pana_server_base->pana_key_update->key_delivery_cnt-- == 1) {
00271             if (pana_key_update_process_ready) {
00272                 pana_server_base->key_update_delay = 1;
00273             } else {
00274                 pana_server_base->key_update_delay = pana_server_base->pana_key_update_delay_used;
00275                 if (pana_server_base->key_update_delay == 0) {
00276                     tr_debug("Delivery Ready");
00277                     pana_server_base->key_update_delay = 1;
00278                 }
00279             }
00280             //NVM UPDAte for timer and key material
00281         }
00282         if (pana_nvm_storage_cb) {
00283             pana_server_material_write(pana_nvm_buffer);
00284             pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
00285         }
00286 
00287     }
00288 }
00289 
00290 /* Save and load stored settings to Pana server core */
00291 static void pana_server_client_save_to_nvm(sec_suite_t *suite, pana_nvm_update_process_t nvm_event)
00292 {
00293     uint8_t *ptr = pana_nvm_buffer;
00294     pana_session_t *p_session = &suite->pana_session;
00295     /* static Part of every session */
00296     ptr = common_write_16_bit(p_session->nvm_offset, ptr);
00297     memcpy(ptr, suite->session_address, 16);
00298     ptr += 16;
00299     ptr = common_write_16_bit(suite->session_port, ptr);
00300     ptr = common_write_32_bit(p_session->session_id, ptr);
00301     if (nvm_event == PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE) {
00302         tr_debug("Remove From NVM");
00303     } else {
00304         /* First Encrypted sector start */
00305         *ptr++ = suite->state;
00306         ptr = common_write_32_bit(suite->timer, ptr);
00307         uint8_t state = 0;
00308         if (p_session->key_warp) {
00309             state |= PANA_ST_KEY_WRAP;
00310         }
00311 
00312         if (p_session->session_ready) {
00313             state |= PANA_ST_READY;
00314         }
00315         *ptr++ = state; //6
00316         ptr = common_write_32_bit(p_session->req_seq, ptr);
00317         ptr = common_write_32_bit(p_session->res_seq, ptr);
00318         *ptr++ = p_session->address_status;
00319         memcpy(ptr, p_session->session_relay_address, 16);
00320         ptr += 16;
00321         ptr = common_write_16_bit(p_session->relay_port, ptr); //37 bytes sector
00322         *ptr++ = p_session->auth_cnt;
00323         *ptr++ = p_session->nwk_key_id;
00324         memcpy(ptr, p_session->pana_auth_key, 32);
00325         ptr += 32;
00326         memcpy(ptr, p_session->pana_PAA_enc_key, 16);
00327         ptr += 16;
00328         ptr = common_write_32_bit(p_session->pana_key_id, ptr);
00329         ptr = common_write_32_bit(p_session->session_lifetime, ptr);
00330         *ptr++ = p_session->eap_id_seq;
00331 
00332     }
00333 }
00334 
00335 static void pana_server_client_restore_from_nvm(sec_suite_t *suite, const uint8_t *ptr)
00336 {
00337 
00338     pana_session_t *p_session = &suite->pana_session;
00339     p_session->nvm_offset = common_read_16_bit(ptr);
00340     ptr += 2;
00341     memcpy(suite->session_address, ptr, 16);
00342     ptr += 16;
00343     suite->session_port = common_read_16_bit(ptr);
00344     ptr += 2;
00345     p_session->session_id = common_read_32_bit(ptr);
00346     ptr += 4; //24
00347 
00348     suite->state = (sec_state_machine_t) * ptr++;
00349     suite->timer = common_read_32_bit(ptr);
00350     ptr += 4;
00351     uint8_t state = *ptr++;
00352     p_session->user_server = true;
00353     if (state & PANA_ST_KEY_WRAP) {
00354         p_session->key_warp = true;
00355     } else {
00356         p_session->key_warp = false;
00357     }
00358 
00359     if (state & PANA_ST_READY) {
00360         p_session->session_ready = true;
00361     } else {
00362         p_session->session_ready = false;
00363     }
00364 
00365     p_session->req_seq = common_read_32_bit(ptr);
00366     ptr += 4;
00367     p_session->res_seq = common_read_32_bit(ptr);
00368     ptr += 4;
00369     p_session->address_status = *ptr++;
00370     memcpy(p_session->session_relay_address, ptr, 16);
00371     ptr += 16;
00372     p_session->relay_port = common_read_16_bit(ptr);
00373     ptr += 2;
00374     p_session->auth_cnt = *ptr++;
00375     p_session->nwk_key_id = *ptr++;
00376     memcpy(p_session->pana_auth_key, ptr, 32);
00377     ptr += 32;
00378     memcpy(p_session->pana_PAA_enc_key, ptr, 16);
00379     ptr += 16;
00380     p_session->pana_key_id = common_read_32_bit(ptr);
00381     ptr += 4;
00382     p_session->session_lifetime = common_read_32_bit(ptr);
00383     ptr += 4;
00384     p_session->eap_id_seq = *ptr++;
00385 }
00386 
00387 void pana_session_nvm_udate(sec_suite_t *suite, pana_nvm_update_process_t update_event)
00388 {
00389     if (pana_nvm_storage_cb) {
00390         if (pana_server_base) {
00391             pana_server_client_save_to_nvm(suite, update_event);
00392             suite->pana_session.nvm_offset = pana_nvm_storage_cb(update_event);
00393         }
00394     }
00395 }
00396 
00397 static void pana_client_session_init(sec_suite_t *suite)
00398 {
00399     suite->pana_session.session_ready = false;
00400     suite->pana_session.key_warp = true;
00401     suite->pana_session.user_server = true;
00402     suite->pana_session.session_id = pana_server_base->next_session_id; // Take Random Number
00403     pana_server_base->next_session_id++;
00404     suite->pana_session.req_seq = randLIB_get_32bit();
00405     suite->pana_session.res_seq = 0;
00406     suite->pana_session.eap_id_seq = randLIB_get_8bit();
00407     suite->pana_session.eap_id_seq &= 63;
00408     suite->pana_session.eap_id_seq++;
00409 
00410 
00411     suite->pana_session.prf_algorythm = pana_server_base->prf_algorythm;
00412     suite->pana_session.integrity_algorythm = pana_server_base->integrity_algorythm;
00413     suite->pana_session.key_wrap = pana_server_base->key_wrap;
00414 
00415     //init eap fragmentation
00416     suite->pana_session.pana_key_id = pana_server_base->pana_key_id;
00417     suite->pana_session.session_lifetime = pana_server_base->session_lifetime;
00418     suite->supported_chipher_suites = pana_server_base->supported_chipher_suites;
00419 
00420     //suite->setups &= ~TLS_HANSHAKE_HASH;
00421     suite->setups = TLS_SERVER_MODE;
00422     suite->timer = 1;
00423     suite->state = PANA_REQUEST_TX;
00424     suite->retry_counter = 0;
00425     eap_fragmentation_init(suite);
00426     suite->pana_session.pana_heap->handshake_len = 0;
00427     suite->pana_session.pana_heap->handshake_req_offset = 0;
00428     randLIB_get_n_bytes_random(suite->pana_session.pana_heap->agent_nonce, 16);
00429 
00430     if (pana_nvm_storage_cb) {
00431         pana_server_material_write(pana_nvm_buffer);
00432         pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
00433     }
00434 }
00435 
00436 
00437 
00438 static bool pana_auth_msg_validate(uint8_t *ptr, uint16_t length, uint8_t *key)
00439 {
00440     pana_avp_t authency;
00441     authency.code = AVP_AUTHENCY_CODE;
00442 
00443     if (!pana_avp_discover(ptr, length, &authency)) {
00444         return false;
00445     }
00446 
00447     if (!pana_auth_check(ptr, length, authency.avp_ptr, key)) {
00448         tr_debug("Auth Fail");
00449         return false;
00450     }
00451     return true;
00452 }
00453 
00454 static void pana_server_set_key_material(uint8_t *key_material, bool new_key, uint8_t auth_cnt)
00455 {
00456 
00457     if (new_key) {
00458         memcpy(key_material, pana_server_base->pana_key_update->new_key_material, 16);
00459         key_material += 16;
00460         *key_material++ = pana_server_base->pana_key_update->key_id;
00461 
00462     } else {
00463         pana_key_material_t *primary_key = pana_server_key_get(true);
00464         memcpy(key_material, primary_key->key_material, 16);
00465         key_material += 16;
00466         *key_material++ = primary_key->key_id;
00467     }
00468     *key_material = auth_cnt;
00469 }
00470 
00471 static void pana_pna_response_build(buffer_t *buf, uint8_t operation, pana_header_t *header, sec_suite_t *suite)
00472 {
00473     uint8_t *ptr;
00474 
00475     header->type = PANA_MSG_PNA;
00476     header->flags &= ~PANA_FLAGS_REQUEST;
00477 
00478     buf->buf_ptr  = PANA_HEADER_LENGTH;
00479     ptr = buffer_data_pointer(buf);
00480 
00481     if (operation == 4) {
00482         //Leave emtpy
00483     } else {
00484         uint8_t key_material[18];
00485         if (operation == 3) {
00486             pana_server_set_key_material(key_material, true, suite->pana_session.auth_cnt);
00487         } else {
00488             pana_server_set_key_material(key_material, false, suite->pana_session.auth_cnt);
00489         }
00490         ptr = pana_avp_zip_key_material(ptr, key_material, header->seq, suite);
00491     }
00492 
00493     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
00494 
00495     buffer_data_end_set(buf, ptr);
00496     buf = build_pana_base(buf, header, suite);
00497     if (!buf) {
00498         return;
00499     }
00500 
00501     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
00502 
00503     //Encode Pana Auth
00504     if (buf->src_sa .address [0] == 0xfe) {
00505         pana_set_agend_address(buf, false, suite);
00506     } else {
00507         //Check IF need Relay
00508         pana_set_agend_address(buf, true, suite);
00509     }
00510 
00511     if (suite->pana_session.address_status & 1) {
00512         buf = pana_relay_avp_build(buf, suite);
00513         if (buf) {
00514             header->flags = 0;
00515             header->type = PANA_MSG_RELAY;
00516             header->session_id = 0;
00517             header->seq = 0;
00518             buf = build_pana_base(buf, header, suite);
00519         }
00520     }
00521 
00522     protocol_push(buf);
00523 }
00524 
00525 
00526 static void pana_complete_msg_parse(buffer_t *buf, pana_header_t *header, sec_suite_t *suite)
00527 {
00528 
00529     uint16_t length = buffer_data_length(buf);
00530     uint8_t *ptr = buffer_data_pointer(buf);
00531 
00532     if (sec_check_suite_ptrs(suite) == 0) {
00533         buffer_free(buf);
00534         return;
00535     }
00536 
00537     if (header->flags & PANA_FLAGS_REQUEST) {
00538         buffer_free(buf);
00539         return;
00540     }
00541 
00542 
00543     uint32_t key_id = 0xffffffff;
00544 
00545     bool key_id_parsed = false;
00546     pana_avp_t avp_temp;
00547     //Read Key id if they are coming
00548 
00549 
00550     avp_temp.code = AVP_KEY_ID_CODE;
00551     if (pana_avp_discover(ptr, length, &avp_temp) &&  avp_temp.len == 4) {
00552         key_id= common_read_32_bit(avp_temp.avp_ptr);
00553         key_id_parsed = true;
00554     }
00555 
00556 
00557 
00558     if (key_id_parsed) {
00559 
00560         if (!pana_auth_msg_validate(ptr, length, suite->pana_session.pana_auth_key)) {
00561             goto pana_failure;
00562         }
00563 
00564         if (suite->pana_session.pana_key_id != key_id) {
00565             goto pana_failure;
00566         }
00567         tr_debug("Client AUTH_OK");
00568         sec_lib_state_machine_trig(suite, PANA_READY);
00569         if (pana_server_base) {
00570             if (pana_server_base->open_pana_authentication_cnt) {
00571                 pana_server_base->open_pana_authentication_cnt--;
00572             }
00573         }
00574     } else {
00575         sec_lib_state_machine_trig(suite, PANA_ERROR);
00576     }
00577 
00578     buffer_free(buf);
00579     return;
00580 
00581     pana_failure:
00582     tr_debug("Drop Key MSG");
00583     sec_lib_state_machine_trig(suite, PANA_FAILURE); //shuold be calc
00584     buffer_free(buf);
00585     return;
00586 }
00587 
00588 static void pana_server_finnish_error_build(buffer_t *buf, sec_suite_t *suite)
00589 {
00590     buf->buf_ptr  = PANA_HEADER_LENGTH;
00591     uint8_t *ptr = buffer_data_pointer(buf);
00592     //tr_debug("End Pana and EAP");
00593     uint8_t eap_status[4];
00594     eap_header_build(eap_status, 4,EAP_FAILURE, suite->pana_session.eap_id_seq, 0);
00595 
00596     ptr = pana_avp_32_bit_write(AVP_RESULT_CODE, 2, ptr);
00597     ptr = pana_avp_write_n_bytes(AVP_EAP_PAYLOAD_CODE, 4, eap_status, ptr);
00598     buffer_data_end_set(buf, ptr);
00599 }
00600 
00601 static void sec_auth_ready(sec_suite_t *suite) {
00602     suite->timer = 0;
00603     tr_debug("Pana:OK");
00604     suite->pana_session.session_ready = true;
00605     if (suite->state == PANA_READY) {
00606         pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE);
00607     }
00608 
00609     //Reset pointer
00610     suite->pana_session.auth_info = NULL;
00611     pana_free_dynamic_ram(suite);
00612     sec_suite_tls_free(suite, true);
00613 
00614 }
00615 #ifdef ECC
00616 static uint32_t tls_backoff_random_timer_start(void)
00617 {
00618     return randLIB_get_random_in_range(2, 16);
00619 }
00620 #endif
00621 
00622 static void pana_server_pana_error_handler(sec_suite_t *suite)
00623 {
00624     sec_lib_state_machine_lock(suite, PANA_ERROR);
00625     pana_client_authentication_fail(suite);
00626     seclib_session_clean(suite);
00627 }
00628 
00629 
00630 static void pana_server_state_machine_func(sec_suite_t *suite)
00631 {
00632     if (!suite) {
00633         return;
00634     }
00635     uint8_t general_tx = 0;
00636     switch (suite->state) {
00637         case PANA_ERROR:
00638             pana_server_pana_error_handler(suite);
00639             return;
00640 
00641         case PANA_READY:
00642         case PANA_RE_VALID:
00643         case PANA_PULL_DONE:
00644             sec_auth_ready(suite);
00645             break;
00646 
00647         case PRF_CALC:
00648         case PRF_CALC2:
00649         case TLS_ECC_CERTIFICATE_VERIFY_SIGNATURE:
00650         case TLS_ECC_MESSAGE_VERIFY:
00651         case TLS_ECC_CERTIFICATE_SIGNATURE_CHECK:
00652         case TLS_ECC_GENERATE_PUBLIC_KEY:
00653         case TLS_ECC_GENERATE_PREMASTER_SECRET:
00654         case TLS_ECC_SIGNATURE_MESSAGE:
00655             break;
00656         case TLS_HELLO_RX:
00657         case TLS_SERVER_KEY_EXCHANGE_RX:
00658         case TLS_SERVER_WAIT_CHANGE_CHIPHERSUITE:
00659         case TLS_CLIENT_KEY_EXCHANGE_RX:
00660         case TLS_CHANGE_CHIPHER:
00661             tr_debug("%02x", suite->state);
00662             tr_debug("Timeout");
00663             sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00664             general_tx = 1;
00665             break;
00666 
00667 #ifdef ECC
00668         case TLS_ECC_GENERATE_PUBLIC_KEY_START:
00669             sec_ecc_gen_public_key_start(suite);
00670             break;
00671 
00672         case TLS_ECC_MESSAGE_SERVER_VERIFY_START:
00673         case TLS_ECC_MESSAGE_VERIFY_START:
00674             if (suite->tls_session) {
00675                 if (suite->tls_session->tls_heap) {
00676                     int start = 0;
00677                     tls_heap_t *theap = suite->tls_session->tls_heap;
00678 
00679                     if (theap->cert_temp_buf) {
00680                         if (suite->state == TLS_ECC_MESSAGE_SERVER_VERIFY_START) {
00681                             if (theap->signature_temp_buf == 0) {
00682                                 start = 1;
00683                             }
00684                         }
00685                     } else {
00686                         start = 1;
00687                     }
00688                     if (start) {
00689                         tls_server_finnish_handle_start(suite);
00690                     } else {
00691                         tr_debug("Start Certi Check");
00692                         tls_certificate_signature_verify(suite);
00693                     }
00694                 }
00695             }
00696             break;
00697         case TLS_ECC_MESSAGE_VERIFY_START2:
00698             tls_ecc_verfify_start(suite);
00699             break;
00700 
00701         case TLS_SERVER_ECC_PUB_KEY_GEN:
00702             if (sec_auth_re_check(suite)) {
00703                 if (tls_server_certi_hash_copy(suite) == 0) {
00704                     suite->timer = tls_backoff_random_timer_start();
00705                 } else {
00706 
00707                     suite->setups &= ~TLS_HANSHAKE_HASH;
00708                     //PUBLIC key cal
00709                     sec_lib_state_machine_trig(suite, TLS_ECC_GENERATE_PUBLIC_KEY_START);
00710                 }
00711             } else {
00712                 tr_debug("TLS_SERVER_ECC_PUB_KEY_GEN timeout");
00713                 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00714                 general_tx = 1;
00715                 //Alert Shuold send Here
00716             }
00717             break;
00718 
00719         case TLS_ECC_CLIENT_SIGNATURE_START:
00720             sec_ecc_client_signature_start(suite);
00721             break;
00722 #endif
00723         case TLS_UPDATE_HAS_WITH_CERTIFICATE:
00724 #ifdef ECC
00725             if (sec_auth_re_check(suite)) {
00726                 if (tls_certi_hash_copy(suite) == 0) {
00727                     tr_warn("Server Certficate Alloc fail");
00728                     suite->timer = 4;
00729                 } else {
00730                     sec_lib_state_machine_trig(suite, TLS_ECC_CLIENT_SIGNATURE_START);
00731                 }
00732             } else
00733 #endif
00734             {
00735                 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00736                 general_tx = 1;
00737             }
00738             break;
00739 
00740         case TLS_TX_SERVER_KEY_EXCHANGE:
00741 #ifdef ECC
00742             if (sec_auth_re_check(suite)) {
00743                 bool tx_start_OK = false;
00744                 if (suite->pana_session.assy_length || suite->pana_session.frag_length || suite->pana_session.packet_delivered) {
00745                     //Build next EAP Packet
00746                     //tr_debug("TX same again fragment piece");
00747                     tx_start_OK = pana_eap_frag_re_tx(suite);
00748 
00749                 } else {
00750                     if (tls_pana_server_exchange_build(suite)) {
00751                         suite->pana_session.packet_delivered = false;
00752                         tx_start_OK = true;
00753                     }
00754 
00755                 }
00756                 if (tx_start_OK) {
00757                     pana_timeout_timer_set(suite, suite->state);
00758                 } else {
00759                     suite->timer = tls_backoff_random_timer_start();
00760                 }
00761             } else
00762 #endif
00763             {
00764                 if (suite->pana_session.assy_length) {
00765                     buffer_free(suite->pana_session.eap_assy_buf);
00766                     suite->pana_session.eap_assy_buf = 0;
00767                     suite->pana_session.assy_length = 0;
00768                     suite->pana_session.assy_off_set = 0;
00769                 }
00770                 tr_debug("TLS_TX_SERVER_KEY_EXCHANGE timeout");
00771                 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00772                 general_tx = 1;
00773             }
00774             break;
00775 
00776 
00777         default:
00778             general_tx = 1;
00779             break;
00780     }
00781 
00782     if (general_tx) {
00783         if (sec_auth_re_check(suite)) {
00784             buffer_t *buf = buffer_get(140);
00785             if (buf) {
00786                 buf->interface  = suite->interface;
00787                 suite->timer = 600;
00788                 switch (suite->state) {
00789                     case PANA_REQUEST_TX:
00790                         pana_start_message_build(buf, suite);
00791                         break;
00792 
00793                     case EAP_IDENTITY_REQ:
00794                         pana_eap_identity_build(buf, suite);
00795                         break;
00796 
00797                     case TLS_START:
00798                         pana_eap_tls_start_build(buf, suite);
00799                         break;
00800 
00801                     case TLS_SERVER_TX_SERVER_HELLO:
00802                         tls_server_hello_build(buf, suite);
00803                         pana_eap_down(buf, suite);
00804                         break;
00805 
00806                     case TLS_KEY_CHANGE:
00807                         //Print Handshake message
00808                         tls_prepare_change_chipher_spec(suite);
00809 
00810                         tls_build_client_change_chipher_suite_finnish(buf, suite);
00811                         tls_nonce_update(suite->tls_session->tls_nonce_explit);
00812                         tr_debug("Set Keys");
00813                         pana_eap_down(buf, suite);
00814 
00815                         break;
00816 
00817                     case TLS_EAP_END_PANA_VERIFY:
00818                         pana_success_server_build(buf, suite);
00819                         break;
00820 
00821 
00822                     case PANA_KEY_UPDATE:
00823                         pana_server_build_key_push(buf, suite);
00824                         break;
00825 
00826                     case PANA_FAILURE:
00827                         pana_server_finnish_error_build(buf, suite);
00828                         pana_down(buf, suite);
00829 
00830                         break;
00831 
00832                     case TLS_FINISH:
00833                     case TLS_ALERT:
00834                         eap_fragmentation_init(suite);
00835                         pana_eap_tls_finnish_build(buf, suite);
00836                         break;
00837 
00838 
00839                     case TLS_ALERT_CLOSE_FATAL:
00840                     case TLS_ALERT_INTERNAL:
00841                     case TLS_ALERT_CHIPHER_SUITE:
00842                     case TLS_ALERT_DECRYPT:
00843                     case TLS_ALERT_BAD_CERTIFICATE:
00844 
00845                         eap_fragmentation_init(suite);
00846 
00847                         suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY);
00848 #ifdef ECC
00849                         {
00850                             tls_heap_t *tls_heap = suite->tls_session->tls_heap;
00851                             if (tls_heap) {
00852                                 tls_ecc_heap_free(tls_heap);
00853                             }
00854                         }
00855 #endif
00856                         if (suite->state == TLS_ALERT_DECRYPT) {
00857                             tls_alert_build(buf, ALERT_BAD_RECORD);
00858                         } else if (suite->state == TLS_ALERT_CLOSE_FATAL) {
00859                             tls_alert_build(buf, ALERT_INTERNAL_ERR);
00860                         } else if (suite->state == TLS_ALERT_BAD_CERTIFICATE) {
00861 
00862                             tls_alert_build(buf, ALERT_BAD_CERTIFICATE);
00863                         } else {
00864                             tls_alert_build(buf, ALERT_INTERNAL_ERR);
00865 
00866                         }
00867                         pana_eap_down(buf, suite);
00868                         break;
00869 
00870 
00871                     default:
00872                         tr_debug("Unknown Packet. State: %x", suite->state);
00873                         buf = buffer_free(buf);
00874                         break;
00875                 }
00876 
00877             } else {
00878                 suite->timer = 2;
00879             }
00880         } else {
00881             tr_debug("Tls Auth Re TX limit Reached. State: %x", suite->state);
00882 
00883             switch (suite->state) {
00884                 case TLS_SERVER_TX_SERVER_HELLO:
00885                 case TLS_KEY_CHANGE:
00886                     sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00887                     break;
00888 
00889                 default:
00890                     if (suite->state == PANA_KEY_UPDATE) {
00891                         tr_warn("Key Delivery Fail");
00892                         pana_key_update_delivery_ready();
00893                     }
00894                     pana_server_pana_error_handler(suite);
00895                     break;
00896             }
00897         }
00898     }
00899 }
00900 
00901 static void pana_server_tls_session_init(sec_suite_t *suite)
00902 {
00903     //Generate TLS SESSION
00904     tls_session_id_genrate(suite->tls_session->tls_session_id, 4);
00905     suite->tls_session->id_length = 4;
00906     memset(suite->tls_session->tls_nonce_explit, 0, 8);
00907 }
00908 
00909 static void pana_server_session_address_set_for_relay(sec_suite_t *suite, buffer_t *buf)
00910 {
00911     memcpy(suite->session_address, buf->dst_sa .address , 16);
00912     suite->session_port = buf->dst_sa .port ;
00913     suite->pana_session.address_status = 1;
00914     //Copy Relay Address
00915     memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16);
00916     suite->pana_session.relay_port = buf->src_sa .port ;
00917     memcpy(&(buf->src_sa ), &(buf->dst_sa ), sizeof(sockaddr_t));
00918 
00919 }
00920 
00921 static sec_suite_t *pana_server_session_restore(uint8_t *nvm_data, protocol_interface_info_entry_t *interface)
00922 {
00923     sec_suite_t *suite = sec_lib_security_session_allocate(false);
00924     if (!suite) {
00925         return NULL;
00926     }
00927     //Restore
00928     pana_server_client_restore_from_nvm(suite, nvm_data);
00929     //Init Satic Information At ZIP
00930     suite->setups = TLS_SERVER_MODE;
00931     suite->interface = interface;
00932     suite->pana_session.key_wrap = pana_server_base->key_wrap;
00933     suite->pana_session.prf_algorythm = pana_server_base->prf_algorythm;
00934     suite->pana_session.integrity_algorythm = pana_server_base->integrity_algorythm;
00935     return suite;
00936 }
00937 
00938 
00939 static sec_suite_t * pana_server_get_session_by_session_id(uint32_t session_id, protocol_interface_info_entry_t *interface)
00940 {
00941     sec_suite_t *suite = sec_suite_selected_pana_session(session_id);
00942     if (!suite && pana_server_nvm__session_get) {
00943         if (!pana_server_nvm__session_get(session_id)) {
00944             return NULL;
00945         }
00946         suite = pana_server_session_restore(pana_nvm_buffer, interface);
00947     }
00948 
00949     return suite;
00950 }
00951 
00952 static sec_suite_t *pana_server_get_session_by_address(uint8_t *ll_address, protocol_interface_info_entry_t *interface)
00953 {
00954     sec_suite_t *suite =  sec_suite_selected_address(ll_address);
00955 
00956     if (!suite && pana_server_nvm_get) {
00957         if (!pana_server_nvm_get(ll_address)) {
00958             return NULL;
00959         }
00960         suite = pana_server_session_restore(pana_nvm_buffer, interface);
00961     }
00962 
00963     return suite;
00964 }
00965 
00966 
00967 static void pana_server_packet_handler(buffer_t *buf)
00968 {
00969     bool relay_pack = false;
00970     sec_suite_t *suite =  NULL;
00971     pana_header_t header;
00972     if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) {
00973         buffer_free(buf);
00974         return;
00975     }
00976     buffer_data_strip_header(buf, PANA_HEADER_LENGTH);
00977 
00978 
00979     if (header.type == PANA_MSG_RELAY) {
00980         /** Parse Relay */
00981         buf = pana_relay_parse(buf);
00982         if (buf) {
00983             /** Parse Relayed Packet */
00984             if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) {
00985                 buffer_free(buf);
00986                 return;
00987             }
00988             buffer_data_strip_header(buf, PANA_HEADER_LENGTH);
00989             relay_pack = true;
00990         }
00991         if (buf == 0) {
00992             tr_debug("Drop Pana Relay Pack");
00993             return;
00994         }
00995     }
00996 
00997     //Server will use address and session when address is LL and GP use only ID
00998     //SERVER: if type is relay parse relay address and save
00999     if (header.type == PANA_MSG_PNA) {
01000         //tr_debug("PNA");
01001         suite = pana_server_get_session_by_session_id(header.session_id, buf->interface );
01002         if (!suite || !(header.flags & PANA_FLAGS_PING)) {
01003             buffer_free(buf);
01004             return;
01005         }
01006         if (!pana_auth_msg_validate(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key)) {
01007             buffer_free(buf);
01008             return;
01009         }
01010 
01011         if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) {
01012             if (suite->pana_session.req_seq != header.seq) {
01013                 tr_debug("PNA RES:Drop Old seq");
01014                 buffer_free(buf);
01015                 return;
01016             }
01017 
01018             suite->pana_session.req_seq++;
01019 
01020             if (suite->pana_session.session_ready ) {
01021 
01022                 tr_debug("Key push OK");
01023                 if (suite->state == PANA_KEY_UPDATE) {
01024                     sec_lib_state_machine_lock(suite, PANA_READY);
01025                     tr_debug("Key Delivery OK");
01026                     //Call SEC KEY UPDATE
01027                     //tr_debug("NVM SEQ Update by Key Pull Ready");
01028                     pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE);
01029                     pana_key_update_delivery_ready();
01030                 }
01031             }
01032             buffer_free(buf);
01033             return;
01034         } else {
01035             if (suite->pana_session.res_seq == 0) {
01036                 suite->pana_session.res_seq = header.seq;
01037             } else {
01038                 if ((suite->pana_session.res_seq + 1) == header.seq) {
01039                     suite->pana_session.res_seq = header.seq;
01040                 } else if (suite->pana_session.res_seq != header.seq) {
01041                     tr_debug("PNA REQ:Drop unknow Request");
01042                     buffer_free(buf);
01043                     return;
01044                 }
01045             }
01046         }
01047 
01048         if (relay_pack) {
01049             pana_server_session_address_set_for_relay(suite, buf);
01050 
01051         } else {
01052             if ((buf->src_sa .address [0] != 0xfe)) {
01053                 //tr_debug("SET GP & SEQ");
01054                 suite->pana_session.address_status = 0;
01055                 memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16);
01056                 suite->pana_session.relay_port = buf->src_sa .port ;
01057                 suite->session_port = buf->src_sa .port ;
01058 
01059             } else {
01060                 if (memcmp(suite->session_address, buf->src_sa .address , 16) != 0) {
01061                     tr_debug("PNA REQ:Drop By Address");
01062                     buffer_free(buf);
01063                     return;
01064                 }
01065 
01066                 //Shuold Update Relay Information
01067                 suite->pana_session.address_status = 2;
01068                 suite->session_port = buf->src_sa .port ;
01069                 lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address );
01070             }
01071         }
01072 
01073         if (!suite->pana_session.session_ready) {
01074             buffer_free(buf);
01075             return;
01076         }
01077 
01078         //KEY PULL
01079         pana_avp_t avp_temp;
01080         //Read Resul and Key id if they are coming
01081         avp_temp.code = PANA_EAP_KEYREQ_TYPE;
01082         avp_temp.len = 0;
01083         uint8_t key_delivery;
01084         if (!pana_avp_discover(buffer_data_pointer(buf), buffer_data_length(buf), &avp_temp)) {
01085             key_delivery = 2;
01086             avp_temp.avp_ptr = NULL;
01087         } else {
01088             if (avp_temp.len != 2) {
01089                 buffer_free(buf);
01090                 return;
01091             }
01092             uint8_t *ptr = avp_temp.avp_ptr;
01093             pana_key_material_t *primary_key = pana_server_key_get(true);
01094             tr_debug("Network KEY Request: %s", trace_array(ptr, 2));
01095             if (*ptr++ & 1) {
01096                 tr_debug("REQ bit, 1");
01097                 //if(*ptr == pana_server_base->network_key_id)
01098                 if (*ptr == primary_key->key_id) {
01099                     if (pana_server_base->pana_key_update) {
01100                         key_delivery = 3;
01101                     } else {
01102                         key_delivery = 4;
01103                     }
01104                 } else {
01105                     key_delivery = 2;
01106                 }
01107 
01108             } else {
01109             //if(*ptr == pana_server_base->network_key_id)
01110                 if (*ptr == primary_key->key_id) {
01111                     key_delivery = 2;
01112                 } else {
01113                     key_delivery = 4;
01114                 }
01115             }
01116         }
01117 
01118         tr_debug("NVM  SEQ update BY Client key Pull");
01119         pana_pna_response_build(buf, key_delivery, &header, suite);
01120         pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE);
01121         return;
01122     } else if (header.type == PANA_MSG_PCI) {
01123         if (relay_pack) {
01124             suite =  pana_server_get_session_by_address(buf->dst_sa .address , buf->interface );
01125         } else {
01126             suite =  pana_server_get_session_by_address(buf->src_sa .address , buf->interface );
01127         }
01128         if (suite) {
01129             //Check State
01130             //if state ready create new session
01131             if (!suite->pana_session.session_ready ) {
01132                 tr_debug("PCI received; Discard unfinished session and start a new one");
01133                 if (pana_server_base->open_pana_authentication_cnt) {
01134                     pana_server_base->open_pana_authentication_cnt--;
01135                 }
01136                 sec_suite_remove(suite);
01137                 suite = 0;
01138             } else {
01139                 tr_debug("Accept new session");
01140             }
01141         }
01142 
01143         if (suite) {
01144             if (suite->pana_session.pana_heap == NULL) {
01145                 suite->pana_session.pana_heap = pana_heap_structure_allocate();
01146             }
01147             if (suite->tls_session == NULL) {
01148                 suite->tls_session = amr_tls_session_allocate();
01149                 if (suite->tls_session == NULL) {
01150                     if (suite->pana_session.pana_heap) {
01151                         ns_dyn_mem_free(suite->pana_session.pana_heap);
01152                         suite->pana_session.pana_heap = NULL;
01153                     }
01154                 }
01155             }
01156             if (suite->pana_session.pana_heap) {
01157 
01158                 arm_tls_session_clear(suite->tls_session);
01159                 suite->tls_session->tls_heap = tls_heap_allocate();
01160                 if (suite->tls_session->tls_heap) {
01161                     //Generate TLS SESSION
01162                     pana_server_tls_session_init(suite);
01163                     pana_client_session_init(suite);
01164                     tr_debug("UPdate Auth Counter");
01165                     if (relay_pack) {
01166                         pana_server_session_address_set_for_relay(suite, buf);
01167                     } else {
01168                         suite->pana_session.address_status = 2;
01169                         memcpy(suite->session_address, buf->src_sa .address , 16);
01170                         suite->session_port = buf->src_sa .port ;
01171                     }
01172                     pana_server_base->open_pana_authentication_cnt++;
01173                 } else {
01174                     tr_debug("TLS heap allocate");
01175                 }
01176             }
01177 
01178         } else {
01179             //Generate session
01180             suite = sec_suite_create();
01181             if (suite) {
01182                 tr_debug("Create new Pana Session");
01183                 pana_server_tls_session_init(suite);
01184                 pana_server_base->open_pana_authentication_cnt++;
01185                 pana_client_session_init(suite);
01186                 suite->interface = buf->interface ;
01187                 if (relay_pack) {
01188                     pana_server_session_address_set_for_relay(suite, buf);
01189                 } else {
01190                     suite->pana_session.address_status = 2;
01191                     memcpy(suite->session_address, buf->src_sa .address , 16);
01192                     suite->session_port = buf->src_sa .port ;
01193                 }
01194             }
01195         }
01196         buffer_free(buf);
01197         return;
01198     } else if (header.type == PANA_MSG_PA) {
01199 
01200         if (buf->src_sa .address [0] == 0xfe || relay_pack) {
01201             //accept only now session
01202             suite = sec_suite_selected_pana_session(header.session_id);
01203             if (!suite) {
01204                 tr_debug("Drop Packet by session ID");
01205                 buffer_free(buf);
01206                 return;
01207             }
01208 
01209 
01210             if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) {
01211                 if (suite->pana_session.req_seq == header.seq) {
01212                     suite->pana_session.req_seq++;
01213                     //ADD Check for EAP fragmentation!!!!!!!!!!!!!!!
01214                     if ((header.flags & PANA_FLAGS_COMPLETE) == PANA_FLAGS_COMPLETE) {
01215                         if (suite->state != TLS_EAP_END_PANA_VERIFY && suite->state != PANA_READY) {
01216                             if (pana_server_base->open_pana_authentication_cnt) {
01217                                 pana_server_base->open_pana_authentication_cnt--;
01218                             }
01219                             tr_debug("Remove Current session by 'Comp bit'");
01220                             sec_suite_remove(suite);
01221                             buffer_free(buf);
01222                             return;
01223                         }
01224                     }
01225                 } else {
01226                     tr_debug("Pana RES:Drop Old seq");
01227                     buffer_free(buf);
01228                     return;
01229                 }
01230             } else {
01231                 suite->pana_session.res_seq = header.seq;
01232             }
01233 
01234             if (relay_pack) {
01235                 buf->src_sa  = buf->dst_sa ;
01236             }
01237 
01238             if (header.flags & PANA_FLAGS_START) {
01239                 pana_session_startms_parse(buf, &header, suite);
01240             } else if (header.flags & PANA_FLAGS_COMPLETE) {
01241                 pana_complete_msg_parse(buf, &header, suite);
01242             } else {
01243 
01244                 buf = pana_auth_message_handler(buf, &header, suite);
01245 
01246                 if (buf) {
01247                     pana_eap_tls_up(buf, suite);
01248                 }
01249             }
01250             return;
01251         }
01252         buffer_free(buf);
01253     } else {
01254         buffer_free(buf);
01255     }
01256 }
01257 
01258 
01259 int8_t pana_server_interface_init(int8_t interface_id, net_tls_cipher_e cipher_mode, const uint8_t *key_material, uint32_t time_period_before_activate_key)
01260 {
01261     int8_t ret_val;
01262     uint8_t supported_chipher_suites;
01263     protocol_interface_info_entry_t *cur;
01264     cur = protocol_stack_interface_info_get_by_id(interface_id);
01265     if (!cur) {
01266         return -1;
01267     }
01268 
01269     if (!cur->if_lowpan_security_params) {
01270         return -1;
01271     }
01272 
01273     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
01274         return -4;
01275     } else if (cur->if_lowpan_security_params->pana_params == 0) {
01276         return -3;
01277     } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) {
01278         return -5;
01279     }
01280 
01281     switch (cipher_mode) {
01282         case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */
01283             supported_chipher_suites = SEC_CIPHERSUITE_PSK;
01284             break;
01285 
01286         case NET_TLS_ECC_CIPHER:        /**< Network Authentication support only ECC */
01287         case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */
01288 #ifdef ECC
01289             //Verify Certficate
01290             if (sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) {
01291                 return -1;
01292             }
01293             if (cipher_mode == NET_TLS_PSK_AND_ECC_CIPHER) {
01294                 supported_chipher_suites = (SEC_CIPHERSUITE_PSK | SEC_CIPHERSUITE_ECC);
01295             } else {
01296                 supported_chipher_suites = SEC_CIPHERSUITE_ECC;
01297             }
01298             break;
01299 #endif // if ECC is not supported, flow into default => nothing is supported.
01300         default:
01301             supported_chipher_suites = 0;
01302             break;
01303     }
01304 
01305 
01306     ret_val = pana_server_init(interface_id, key_material, supported_chipher_suites, time_period_before_activate_key);
01307     if (ret_val == 0) {
01308         cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode;
01309         cur->if_lowpan_security_params->pana_params->psk_key_id = 0;
01310         cur->if_lowpan_security_params->pana_params->pana_client = 0;
01311         cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION);
01312         cur->configure_flags |= INTERFACE_SECURITY_DEFINED;
01313     }
01314 
01315     return ret_val;
01316 }
01317 
01318 int8_t pana_server_key_update(int8_t interface_id, const uint8_t *network_key_material)
01319 {
01320 
01321     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
01322     if (!cur) {
01323         return -1;
01324     }
01325 
01326     if (!pana_server_base || pana_server_base->network_interface_id != interface_id || pana_server_base->pana_key_update) {
01327         return -2;
01328     }
01329 
01330     if (!cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) {
01331         return -3;
01332     }
01333 
01334     if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) {
01335         return -4;
01336     } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) {
01337         return -5;
01338     }
01339 
01340 
01341 
01342     pana_server_base->pana_key_update = ns_dyn_mem_temporary_alloc(sizeof(pana_key_update_t));
01343     if (!pana_server_base->pana_key_update) {
01344         return -3;
01345     }
01346 
01347     pana_key_material_t *primary_key = pana_server_key_get(true);
01348 
01349     if (network_key_material) {
01350         memcpy(pana_server_base->pana_key_update->new_key_material, network_key_material, 16);
01351     } else {
01352         pana_server_set_random_key_value(pana_server_base->pana_key_update->new_key_material);
01353         network_key_material = pana_server_base->pana_key_update->new_key_material;
01354     }
01355 
01356     pana_lib_parameters_s *parameters = pana_parameters_get();
01357 
01358     /*  Update Key ID */
01359     pana_server_base->pana_key_update->key_id = primary_key->key_id;
01360     if (pana_server_base->pana_key_update->key_id == parameters->KEY_ID_MAX_VALUE) {
01361         /*  Start Lollipop Sechema from 1 again */
01362         pana_server_base->pana_key_update->key_id = 0;
01363     }
01364     pana_server_base->pana_key_update->key_id++;
01365 
01366 
01367     //Set New Key to secondary key
01368     primary_key = pana_server_key_get(false);
01369     primary_key->key_id = pana_server_base->pana_key_update->key_id;
01370     memcpy(primary_key->key_material, pana_server_base->pana_key_update->new_key_material, 16);
01371     //TRIG Timers
01372     pana_server_base->pana_key_update->key_delivery_cnt = sec_pana_key_update_trig(parameters->KEY_UPDATE_THRESHOLD);
01373     uint8_t *key_ptr = pana_key_get(network_key_material);
01374     if (key_ptr) {
01375         //pana_server_base->auth_cnt++;
01376         tr_debug("SET Secondary Key ready");
01377         mac_helper_security_next_key_set(cur, (key_ptr + 16), pana_server_base->pana_key_update->key_id, MAC_KEY_ID_MODE_IDX);
01378         mle_service_security_set_security_key(cur->id, key_ptr, pana_server_base->pana_key_update->key_id, false);
01379     }
01380     tr_debug("KEY Delivery CNT: %02x", pana_server_base->pana_key_update->key_delivery_cnt);
01381     if (pana_server_base->pana_key_update->key_delivery_cnt == 0) {
01382         tr_debug("TRIG NEW Key");
01383         pana_server_base->pana_key_update->key_delivery_cnt = 1;
01384         pana_key_update_delivery_ready();
01385     }
01386     if (pana_nvm_storage_cb) {
01387         pana_server_material_write(pana_nvm_buffer);
01388         pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
01389     }
01390     return 0;
01391 }
01392 
01393 void pana_key_update_delay_timer(void)
01394 {
01395     if (pana_server_base && pana_server_base->key_update_delay) {
01396         if (pana_server_base->key_update_delay <= 100) {
01397             protocol_interface_info_entry_t *cur;
01398             pana_server_base->key_update_delay = 0;
01399             cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id);
01400 
01401             //SWAP new KEY
01402             if (cur) {
01403                 tr_debug("Trig New Key ID");
01404                 uint8_t keyId = mle_service_security_next_key_id_get(cur->id);
01405                 mac_helper_security_key_swap_next_to_default(cur);
01406                 mle_service_security_key_trig(cur->id, keyId);
01407                 if (cur->nwk_wpan_nvm_api) {
01408                     cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01409                 }
01410                 if (pana_key_update_process_ready) {
01411                     pana_key_update_process_ready();
01412                 }
01413             }
01414             if (pana_server_base->primary_material) {
01415                 pana_server_base->primary_material = 0;
01416             } else {
01417                 pana_server_base->primary_material = 1;
01418             }
01419 
01420             pana_key_material_t *primary_key = pana_server_key_get(true);
01421             primary_key->key_id = pana_server_base->pana_key_update->key_id;
01422             memcpy(primary_key->key_material , pana_server_base->pana_key_update->new_key_material, 16);
01423 
01424             if (pana_server_base->pana_key_update) {
01425                 ns_dyn_mem_free(pana_server_base->pana_key_update);
01426                 pana_server_base->pana_key_update = 0;
01427             }
01428             if (pana_nvm_storage_cb) {
01429                 tr_debug("PS:NVM Cover");
01430                 pana_server_material_write(pana_nvm_buffer);
01431                 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
01432             }
01433 
01434         } else {
01435             pana_server_base->key_update_delay -= 100;
01436         }
01437     }
01438 
01439 }
01440 
01441 int8_t pana_server_nvm_callback_set(pana_server_update_cb *update_cb, pana_server_session_get_cb *nvm_get, pana_server_session_get_by_id_cb *nvm_session_get, uint8_t *nvm_static_buffer)
01442 {
01443     if (!update_cb || !nvm_static_buffer || !nvm_get || !nvm_session_get) {
01444         return -1;
01445     }
01446     pana_nvm_storage_cb = update_cb;
01447     pana_server_nvm_get = nvm_get;
01448     pana_server_nvm__session_get = nvm_session_get;
01449     pana_nvm_buffer = nvm_static_buffer;
01450     return 0;
01451 }
01452 
01453 int8_t pana_server_process_ready_cb_set(void (*cb_fptr)(void))
01454 {
01455     if (cb_fptr) {
01456         pana_key_update_process_ready = cb_fptr;
01457         return 0;
01458     }
01459     return -1;
01460 }
01461 
01462 /* Pana Client session load from NVM API */
01463 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer)
01464 {
01465 
01466     if (!pana_server_base) {
01467         return -1;
01468     }
01469     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id);
01470     if (!cur) {
01471         return -1;
01472     }
01473 
01474     if (pana_socket_id_get() == -1) {
01475         return -2;
01476     }
01477 
01478     if (pana_server_session_restore(nvm_pointer, cur)) {
01479         return -3;
01480     }
01481     return 0;
01482 }
01483 
01484 static void pana_success_server_build(buffer_t *buf, sec_suite_t *suite)
01485 {
01486     uint8_t *ptr;
01487     pana_header_t header;
01488     header.type = PANA_MSG_PA;
01489     header.flags = PANA_FLAGS_COMPLETE | PANA_FLAGS_REQUEST;
01490     //REQUEST
01491     header.seq = suite->pana_session.req_seq;
01492     header.session_id = suite->pana_session.session_id;
01493 
01494     buf->buf_ptr  = PANA_HEADER_LENGTH;
01495     ptr = buffer_data_pointer(buf);
01496 
01497     uint8_t eap_status[4];
01498     eap_header_build(eap_status, 4,EAP_SUCCESS, suite->pana_session.eap_id_seq, 0);
01499 
01500     ptr = pana_avp_32_bit_write(AVP_RESULT_CODE, 0, ptr);
01501     ptr = pana_avp_write_n_bytes(AVP_EAP_PAYLOAD_CODE, 4, eap_status, ptr);
01502     ptr = pana_avp_32_bit_write(AVP_KEY_ID_CODE, suite->pana_session.pana_key_id, ptr);
01503     ptr = pana_avp_32_bit_write(AVP_SESSION_LIFETIME_CODE, suite->pana_session.session_lifetime, ptr);
01504     //ENC
01505     uint8_t key_material[18];
01506     pana_server_set_key_material(key_material, false, suite->pana_session.auth_cnt);
01507     ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite);
01508     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
01509     buffer_data_end_set(buf, ptr);
01510     buf = build_pana_base(buf, &header, suite);
01511     if (!buf) {
01512         return;
01513     }
01514 
01515     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
01516 
01517     //Encode Pana Auth
01518     pana_set_agend_address(buf, false, suite);
01519     if (suite->pana_session.address_status & 1) {
01520         buf = pana_relay_avp_build(buf, suite);
01521         if (buf) {
01522             header.flags = 0;
01523             header.type = PANA_MSG_RELAY;
01524             header.session_id = 0;
01525             header.seq = 0;
01526             buf = build_pana_base(buf, &header, suite);
01527         }
01528     }
01529 
01530     protocol_push(buf);
01531 }
01532 
01533 
01534 
01535 static void pana_server_build_key_push(buffer_t *buf, sec_suite_t *suite)
01536 {
01537     uint8_t *ptr;
01538     pana_header_t header;
01539     header.type = PANA_MSG_PNA;
01540     header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING;
01541     //REQUEST
01542     header.seq = suite->pana_session.req_seq;
01543     header.session_id = suite->pana_session.session_id;
01544 
01545 
01546     buf->buf_ptr  = PANA_HEADER_LENGTH;
01547     ptr = buffer_data_pointer(buf);
01548     //ENC
01549     uint8_t key_material[18];
01550     pana_server_set_key_material(key_material, true, suite->pana_session.auth_cnt);
01551     ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite);
01552     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
01553 
01554     buffer_data_end_set(buf, ptr);
01555     buf = build_pana_base(buf, &header, suite);
01556     if (!buf) {
01557         return;
01558     }
01559 
01560     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
01561     pana_set_agend_address(buf, true, suite);
01562 
01563     protocol_push(buf);
01564 }
01565 
01566 int8_t pana_network_key_get(int8_t interface_id, ns_keys_t *key)
01567 {
01568     (void)interface_id;
01569 
01570     if (pana_server_base && key) {
01571         pana_key_material_t *primary_key = pana_server_key_get(true);
01572         pana_key_material_t *prev_key = pana_server_key_get(false);
01573         if (prev_key->key_id == 0) {
01574             prev_key = 0;
01575         }
01576         key->current_active_key_index = primary_key->key_id;
01577         memcpy(key->current_active_network_key , primary_key->key_material, 16);
01578         if (prev_key) {
01579             key->previous_active_key_index = prev_key->key_id;
01580             memcpy(key->previous_active_network_key , prev_key->key_material, 16);
01581         } else {
01582             memset(key->previous_active_network_key, 0, 16);
01583         }
01584         return 0;
01585     }
01586     return -1;
01587 }
01588 
01589 int8_t pana_server_trig_new_key(int8_t interface_id)
01590 {
01591 
01592     if (!pana_server_base) {
01593         return -1;
01594     }
01595     if (pana_server_base->network_interface_id != interface_id) {
01596         return -2;
01597     }
01598     if (pana_server_base->key_update_delay) {
01599         tr_debug("TRIG faster");
01600         pana_server_base->key_update_delay = 1;
01601         return  0;
01602     }
01603     return -1;
01604 
01605 }
01606 
01607 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id)
01608 {
01609     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
01610     if (!cur) {
01611      return -1;
01612     }
01613 
01614     if (!pana_socket_init(pana_server_packet_handler, pana_server_state_machine_func, tls_server_up)) {
01615         return -1;
01616     }
01617 
01618     sec_suite_list_clean();
01619 
01620     //Allocate
01621     if (pana_server_base == 0) {
01622         pana_server_base = pana_server_staructure_allocate();
01623     }
01624     if (!pana_server_base || !cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) {
01625         return -1;
01626     }
01627 
01628     net_tls_cipher_e cipher_mode;
01629     pana_server_base->open_pana_authentication_cnt = 0;
01630     pana_server_base->network_interface_id = interface_id;
01631     pana_server_base->pana_key_update = 0;
01632     pana_server_base->key_update_delay = 0;
01633     pana_server_material_read(nvm_data);
01634     if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_PSK) {
01635         cipher_mode = NET_TLS_PSK_CIPHER;
01636     } else if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_ECC) {
01637         cipher_mode = NET_TLS_ECC_CIPHER;
01638     } else {
01639         cipher_mode = NET_TLS_PSK_AND_ECC_CIPHER;
01640     }
01641 
01642     cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode;
01643     cur->if_lowpan_security_params->pana_params->psk_key_id = 0;//TODO?????
01644             cur->if_lowpan_security_params->pana_params->pana_client = 0;
01645     cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION);
01646     cur->configure_flags |= INTERFACE_SECURITY_DEFINED;
01647 
01648     return 0;
01649 }
01650 
01651 int8_t pana_server_key_material_load(int8_t interface_id)
01652 {
01653     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
01654     if (!cur) {
01655         return -1;
01656     } else if (!pana_server_base) {
01657         return -1;
01658     }
01659     uint8_t *key_ptr;
01660     pana_key_material_t *key_mat;
01661     if (pana_server_base->pana_key_update) {
01662 
01663         pana_server_base->auth_cnt++;
01664         //Load First Primary to master
01665         key_mat = pana_server_key_get(true);
01666         key_ptr = pana_key_get(key_mat->key_material);
01667         mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01668         mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true);
01669         if (cur->nwk_wpan_nvm_api) {
01670             cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01671         }
01672         //Set Secondary to coming key
01673         key_mat = pana_server_key_get(false);
01674         key_ptr = pana_key_get(key_mat->key_material);
01675         mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01676         mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false);
01677     } else {
01678         bool secondary_active = false;
01679         //Load first Secondary and then Primary
01680         key_mat = pana_server_key_get(false);
01681         if (key_mat->key_id) {
01682             key_ptr = pana_key_get(key_mat->key_material);
01683             secondary_active = true;
01684             mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01685             mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true);
01686             if (cur->nwk_wpan_nvm_api) {
01687                 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01688             }
01689         }
01690         key_mat = pana_server_key_get(true);
01691         key_ptr = pana_key_get(key_mat->key_material);
01692         if (secondary_active) {
01693             mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01694             mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false);
01695             mac_helper_security_key_swap_next_to_default(cur);
01696             mle_service_security_key_trig(cur->id, key_mat->key_id);
01697         } else {
01698             mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01699             mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true);
01700         }
01701         if (cur->nwk_wpan_nvm_api) {
01702             cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01703         }
01704     }
01705     return 0;
01706 }
01707 
01708 static void pana_client_authentication_fail(sec_suite_t *suite)
01709 {
01710     if (suite->pana_session.nvm_offset) {
01711         //tr_debug("NVM Session Remove");
01712         pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE);
01713     }
01714     if (pana_server_base && pana_server_base->open_pana_authentication_cnt) {
01715         pana_server_base->open_pana_authentication_cnt--;
01716     }
01717 }
01718 
01719 #else
01720 int8_t pana_server_nvm_callback_set(pana_server_update_cb *update_cb, pana_server_session_get_cb *nvm_get, pana_server_session_get_by_id_cb *nvm_session_get, uint8_t *nvm_static_buffer)
01721 {
01722     (void)update_cb;
01723     (void)nvm_static_buffer;
01724     return -1;
01725 }
01726 
01727 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer)
01728 {
01729     (void) nvm_pointer;
01730     return -1;
01731 }
01732 
01733 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id)
01734 {
01735     (void) nvm_data;
01736     (void)interface_id;
01737     return -1;
01738 }
01739 #endif
01740 #else
01741 int8_t pana_server_nvm_callback_set(pana_server_update_cb *update_cb, pana_server_session_get_cb *nvm_get, pana_server_session_get_by_id_cb *nvm_session_get, uint8_t *nvm_static_buffer)
01742 {
01743     (void)update_cb;
01744     (void)nvm_static_buffer;
01745     return -1;
01746 }
01747 
01748 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer)
01749 {
01750     (void) nvm_pointer;
01751     return -1;
01752 }
01753 
01754 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id)
01755 {
01756     (void) nvm_data;
01757     (void)interface_id;
01758     return -1;
01759 }
01760 #endif