EL4121 Embedded System / mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

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) {
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                         tx_start_OK = true;
00752                     }
00753 
00754                 }
00755                 if (tx_start_OK) {
00756                     pana_timeout_timer_set(suite, suite->state);
00757                 } else {
00758                     suite->timer = tls_backoff_random_timer_start();
00759                 }
00760             } else
00761 #endif
00762             {
00763                 if (suite->pana_session.assy_length) {
00764                     buffer_free(suite->pana_session.eap_assy_buf);
00765                     suite->pana_session.eap_assy_buf = 0;
00766                     suite->pana_session.assy_length = 0;
00767                     suite->pana_session.assy_off_set = 0;
00768                 }
00769                 tr_debug("TLS_TX_SERVER_KEY_EXCHANGE timeout");
00770                 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00771                 general_tx = 1;
00772             }
00773             break;
00774 
00775 
00776         default:
00777             general_tx = 1;
00778             break;
00779     }
00780 
00781     if (general_tx) {
00782         if (sec_auth_re_check(suite)) {
00783             buffer_t *buf = buffer_get(140);
00784             if (buf) {
00785                 buf->interface  = suite->interface;
00786                 suite->timer = 600;
00787                 switch (suite->state) {
00788                     case PANA_REQUEST_TX:
00789                         pana_start_message_build(buf, suite);
00790                         break;
00791 
00792                     case EAP_IDENTITY_REQ:
00793                         pana_eap_identity_build(buf, suite);
00794                         break;
00795 
00796                     case TLS_START:
00797                         pana_eap_tls_start_build(buf, suite);
00798                         break;
00799 
00800                     case TLS_SERVER_TX_SERVER_HELLO:
00801                         tls_server_hello_build(buf, suite);
00802                         pana_eap_down(buf, suite);
00803                         break;
00804 
00805                     case TLS_KEY_CHANGE:
00806                         //Print Handshake message
00807                         tls_prepare_change_chipher_spec(suite);
00808 
00809                         tls_build_client_change_chipher_suite_finnish(buf, suite);
00810                         tls_nonce_update(suite->tls_session->tls_nonce_explit);
00811                         tr_debug("Set Keys");
00812                         pana_eap_down(buf, suite);
00813 
00814                         break;
00815 
00816                     case TLS_EAP_END_PANA_VERIFY:
00817                         pana_success_server_build(buf, suite);
00818                         break;
00819 
00820 
00821                     case PANA_KEY_UPDATE:
00822                         pana_server_build_key_push(buf, suite);
00823                         break;
00824 
00825                     case PANA_FAILURE:
00826                         pana_server_finnish_error_build(buf, suite);
00827                         pana_down(buf, suite);
00828 
00829                         break;
00830 
00831                     case TLS_FINISH:
00832                     case TLS_ALERT:
00833                         eap_fragmentation_init(suite);
00834                         pana_eap_tls_finnish_build(buf, suite);
00835                         break;
00836 
00837 
00838                     case TLS_ALERT_CLOSE_FATAL:
00839                     case TLS_ALERT_INTERNAL:
00840                     case TLS_ALERT_CHIPHER_SUITE:
00841                     case TLS_ALERT_DECRYPT:
00842                     case TLS_ALERT_BAD_CERTIFICATE:
00843 
00844                         eap_fragmentation_init(suite);
00845 
00846                         suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY);
00847 #ifdef ECC
00848                         {
00849                             tls_heap_t *tls_heap = suite->tls_session->tls_heap;
00850                             if (tls_heap) {
00851                                 tls_ecc_heap_free(tls_heap);
00852                             }
00853                         }
00854 #endif
00855                         if (suite->state == TLS_ALERT_DECRYPT) {
00856                             tls_alert_build(buf, ALERT_BAD_RECORD);
00857                         } else if (suite->state == TLS_ALERT_CLOSE_FATAL) {
00858                             tls_alert_build(buf, ALERT_INTERNAL_ERR);
00859                         } else if (suite->state == TLS_ALERT_BAD_CERTIFICATE) {
00860 
00861                             tls_alert_build(buf, ALERT_BAD_CERTIFICATE);
00862                         } else {
00863                             tls_alert_build(buf, ALERT_INTERNAL_ERR);
00864 
00865                         }
00866                         pana_eap_down(buf, suite);
00867                         break;
00868 
00869 
00870                     default:
00871                         tr_debug("Unknown Packet. State: %x", suite->state);
00872                         buf = buffer_free(buf);
00873                         break;
00874                 }
00875 
00876             } else {
00877                 suite->timer = 2;
00878             }
00879         } else {
00880             tr_debug("Tls Auth Re TX limit Reached. State: %x", suite->state);
00881 
00882             switch (suite->state) {
00883                 case TLS_SERVER_TX_SERVER_HELLO:
00884                 case TLS_KEY_CHANGE:
00885                     sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00886                     break;
00887 
00888                 default:
00889                     if (suite->state == PANA_KEY_UPDATE) {
00890                         tr_warn("Key Delivery Fail");
00891                         pana_key_update_delivery_ready();
00892                     }
00893                     pana_server_pana_error_handler(suite);
00894                     break;
00895             }
00896         }
00897     }
00898 }
00899 
00900 static void pana_server_tls_session_init(sec_suite_t *suite)
00901 {
00902     //Generate TLS SESSION
00903     tls_session_id_genrate(suite->tls_session->tls_session_id, 4);
00904     suite->tls_session->id_length = 4;
00905     memset(suite->tls_session->tls_nonce_explit, 0, 8);
00906 }
00907 
00908 static void pana_server_session_address_set_for_relay(sec_suite_t *suite, buffer_t *buf)
00909 {
00910     memcpy(suite->session_address, buf->dst_sa .address , 16);
00911     suite->session_port = buf->dst_sa .port ;
00912     suite->pana_session.address_status = 1;
00913     //Copy Relay Address
00914     memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16);
00915     suite->pana_session.relay_port = buf->src_sa .port ;
00916     memcpy(&(buf->src_sa ), &(buf->dst_sa ), sizeof(sockaddr_t));
00917 
00918 }
00919 
00920 static sec_suite_t *pana_server_session_restore(uint8_t *nvm_data, protocol_interface_info_entry_t *interface)
00921 {
00922     sec_suite_t *suite = sec_lib_security_session_allocate(false);
00923     if (!suite) {
00924         return NULL;
00925     }
00926     //Restore
00927     pana_server_client_restore_from_nvm(suite, nvm_data);
00928     //Init Satic Information At ZIP
00929     suite->setups = TLS_SERVER_MODE;
00930     suite->interface = interface;
00931     suite->pana_session.key_wrap = pana_server_base->key_wrap;
00932     suite->pana_session.prf_algorythm = pana_server_base->prf_algorythm;
00933     suite->pana_session.integrity_algorythm = pana_server_base->integrity_algorythm;
00934     return suite;
00935 }
00936 
00937 
00938 static sec_suite_t * pana_server_get_session_by_session_id(uint32_t session_id, protocol_interface_info_entry_t *interface)
00939 {
00940     sec_suite_t *suite = sec_suite_selected_pana_session(session_id);
00941     if (!suite && pana_server_nvm__session_get) {
00942         if (!pana_server_nvm__session_get(session_id)) {
00943             return NULL;
00944         }
00945         suite = pana_server_session_restore(pana_nvm_buffer, interface);
00946     }
00947 
00948     return suite;
00949 }
00950 
00951 static sec_suite_t *pana_server_get_session_by_address(uint8_t *ll_address, protocol_interface_info_entry_t *interface)
00952 {
00953     sec_suite_t *suite =  sec_suite_selected_address(ll_address);
00954 
00955     if (!suite && pana_server_nvm_get) {
00956         if (!pana_server_nvm_get(ll_address)) {
00957             return NULL;
00958         }
00959         suite = pana_server_session_restore(pana_nvm_buffer, interface);
00960     }
00961 
00962     return suite;
00963 }
00964 
00965 
00966 static void pana_server_packet_handler(buffer_t *buf)
00967 {
00968     bool relay_pack = false;
00969     sec_suite_t *suite =  NULL;
00970     pana_header_t header;
00971     if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) {
00972         buffer_free(buf);
00973         return;
00974     }
00975     buffer_data_strip_header(buf, PANA_HEADER_LENGTH);
00976 
00977 
00978     if (header.type == PANA_MSG_RELAY) {
00979         /** Parse Relay */
00980         buf = pana_relay_parse(buf);
00981         if (buf) {
00982             /** Parse Relayed Packet */
00983             if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) {
00984                 buffer_free(buf);
00985                 return;
00986             }
00987             buffer_data_strip_header(buf, PANA_HEADER_LENGTH);
00988             relay_pack = true;
00989         }
00990         if (buf == 0) {
00991             tr_debug("Drop Pana Relay Pack");
00992             return;
00993         }
00994     }
00995 
00996     //Server will use address and session when address is LL and GP use only ID
00997     //SERVER: if type is relay parse relay address and save
00998     if (header.type == PANA_MSG_PNA) {
00999         //tr_debug("PNA");
01000         suite = pana_server_get_session_by_session_id(header.session_id, buf->interface );
01001         if (!suite || !(header.flags & PANA_FLAGS_PING)) {
01002             buffer_free(buf);
01003             return;
01004         }
01005         if (!pana_auth_msg_validate(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key)) {
01006             buffer_free(buf);
01007             return;
01008         }
01009 
01010         if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) {
01011             if (suite->pana_session.req_seq != header.seq) {
01012                 tr_debug("PNA RES:Drop Old seq");
01013                 buffer_free(buf);
01014                 return;
01015             }
01016 
01017             suite->pana_session.req_seq++;
01018 
01019             if (suite->pana_session.session_ready ) {
01020 
01021                 tr_debug("Key push OK");
01022                 if (suite->state == PANA_KEY_UPDATE) {
01023                     sec_lib_state_machine_lock(suite, PANA_READY);
01024                     tr_debug("Key Delivery OK");
01025                     //Call SEC KEY UPDATE
01026                     //tr_debug("NVM SEQ Update by Key Pull Ready");
01027                     pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE);
01028                     pana_key_update_delivery_ready();
01029                 }
01030             }
01031             buffer_free(buf);
01032             return;
01033         } else {
01034             if (suite->pana_session.res_seq == 0) {
01035                 suite->pana_session.res_seq = header.seq;
01036             } else {
01037                 if ((suite->pana_session.res_seq + 1) == header.seq) {
01038                     suite->pana_session.res_seq = header.seq;
01039                 } else if (suite->pana_session.res_seq != header.seq) {
01040                     tr_debug("PNA REQ:Drop unknow Request");
01041                     buffer_free(buf);
01042                     return;
01043                 }
01044             }
01045         }
01046 
01047         if (relay_pack) {
01048             pana_server_session_address_set_for_relay(suite, buf);
01049 
01050         } else {
01051             if ((buf->src_sa .address [0] != 0xfe)) {
01052                 //tr_debug("SET GP & SEQ");
01053                 suite->pana_session.address_status = 0;
01054                 memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16);
01055                 suite->pana_session.relay_port = buf->src_sa .port ;
01056                 suite->session_port = buf->src_sa .port ;
01057 
01058             } else {
01059                 if (memcmp(suite->session_address, buf->src_sa .address , 16) != 0) {
01060                     tr_debug("PNA REQ:Drop By Address");
01061                     buffer_free(buf);
01062                     return;
01063                 }
01064 
01065                 //Shuold Update Relay Information
01066                 suite->pana_session.address_status = 2;
01067                 suite->session_port = buf->src_sa .port ;
01068                 lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address );
01069             }
01070         }
01071 
01072         if (!suite->pana_session.session_ready) {
01073             buffer_free(buf);
01074             return;
01075         }
01076 
01077         //KEY PULL
01078         pana_avp_t avp_temp;
01079         //Read Resul and Key id if they are coming
01080         avp_temp.code = PANA_EAP_KEYREQ_TYPE;
01081         avp_temp.len = 0;
01082         uint8_t key_delivery;
01083         if (!pana_avp_discover(buffer_data_pointer(buf), buffer_data_length(buf), &avp_temp)) {
01084             key_delivery = 2;
01085             avp_temp.avp_ptr = NULL;
01086         } else {
01087             if (avp_temp.len != 2) {
01088                 buffer_free(buf);
01089                 return;
01090             }
01091             uint8_t *ptr = avp_temp.avp_ptr;
01092             pana_key_material_t *primary_key = pana_server_key_get(true);
01093             tr_debug("Network KEY Request: %s", trace_array(ptr, 2));
01094             if (*ptr++ & 1) {
01095                 tr_debug("REQ bit, 1");
01096                 //if(*ptr == pana_server_base->network_key_id)
01097                 if (*ptr == primary_key->key_id) {
01098                     if (pana_server_base->pana_key_update) {
01099                         key_delivery = 3;
01100                     } else {
01101                         key_delivery = 4;
01102                     }
01103                 } else {
01104                     key_delivery = 2;
01105                 }
01106 
01107             } else {
01108             //if(*ptr == pana_server_base->network_key_id)
01109                 if (*ptr == primary_key->key_id) {
01110                     key_delivery = 2;
01111                 } else {
01112                     key_delivery = 4;
01113                 }
01114             }
01115         }
01116 
01117         tr_debug("NVM  SEQ update BY Client key Pull");
01118         pana_pna_response_build(buf, key_delivery, &header, suite);
01119         pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE);
01120         return;
01121     } else if (header.type == PANA_MSG_PCI) {
01122         if (relay_pack) {
01123             suite =  pana_server_get_session_by_address(buf->dst_sa .address , buf->interface );
01124         } else {
01125             suite =  pana_server_get_session_by_address(buf->src_sa .address , buf->interface );
01126         }
01127         if (suite) {
01128             //Check State
01129             //if state ready create new session
01130             if (!suite->pana_session.session_ready ) {
01131                 tr_debug("PCI received; Discard unfinished session and start a new one");
01132                 if (pana_server_base->open_pana_authentication_cnt) {
01133                     pana_server_base->open_pana_authentication_cnt--;
01134                 }
01135                 sec_suite_remove(suite);
01136                 suite = 0;
01137             } else {
01138                 tr_debug("Accept new session");
01139             }
01140         }
01141 
01142         if (suite) {
01143             if (suite->pana_session.pana_heap == NULL) {
01144                 suite->pana_session.pana_heap = pana_heap_structure_allocate();
01145             }
01146             if (suite->tls_session == NULL) {
01147                 suite->tls_session = amr_tls_session_allocate();
01148                 if (suite->tls_session == NULL) {
01149                     if (suite->pana_session.pana_heap) {
01150                         ns_dyn_mem_free(suite->pana_session.pana_heap);
01151                         suite->pana_session.pana_heap = NULL;
01152                     }
01153                 }
01154             }
01155             if (suite->pana_session.pana_heap) {
01156 
01157                 arm_tls_session_clear(suite->tls_session);
01158                 suite->tls_session->tls_heap = tls_heap_allocate();
01159                 if (suite->tls_session->tls_heap) {
01160                     //Generate TLS SESSION
01161                     pana_server_tls_session_init(suite);
01162                     pana_client_session_init(suite);
01163                     tr_debug("UPdate Auth Counter");
01164                     if (relay_pack) {
01165                         pana_server_session_address_set_for_relay(suite, buf);
01166                     } else {
01167                         suite->pana_session.address_status = 2;
01168                         memcpy(suite->session_address, buf->src_sa .address , 16);
01169                         suite->session_port = buf->src_sa .port ;
01170                     }
01171                     pana_server_base->open_pana_authentication_cnt++;
01172                 } else {
01173                     tr_debug("TLS heap allocate");
01174                 }
01175             }
01176 
01177         } else {
01178             //Generate session
01179             suite = sec_suite_create();
01180             if (suite) {
01181                 tr_debug("Create new Pana Session");
01182                 pana_server_tls_session_init(suite);
01183                 pana_server_base->open_pana_authentication_cnt++;
01184                 pana_client_session_init(suite);
01185                 suite->interface = buf->interface ;
01186                 if (relay_pack) {
01187                     pana_server_session_address_set_for_relay(suite, buf);
01188                 } else {
01189                     suite->pana_session.address_status = 2;
01190                     memcpy(suite->session_address, buf->src_sa .address , 16);
01191                     suite->session_port = buf->src_sa .port ;
01192                 }
01193             }
01194         }
01195         buffer_free(buf);
01196         return;
01197     } else if (header.type == PANA_MSG_PA) {
01198 
01199         if (buf->src_sa .address [0] == 0xfe || relay_pack) {
01200             //accept only now session
01201             suite = sec_suite_selected_pana_session(header.session_id);
01202             if (!suite) {
01203                 tr_debug("Drop Packet by session ID");
01204                 buffer_free(buf);
01205                 return;
01206             }
01207 
01208 
01209             if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) {
01210                 if (suite->pana_session.req_seq == header.seq) {
01211                     suite->pana_session.req_seq++;
01212                     //ADD Check for EAP fragmentation!!!!!!!!!!!!!!!
01213                     if ((header.flags & PANA_FLAGS_COMPLETE) == PANA_FLAGS_COMPLETE) {
01214                         if (suite->state != TLS_EAP_END_PANA_VERIFY && suite->state != PANA_READY) {
01215                             if (pana_server_base->open_pana_authentication_cnt) {
01216                                 pana_server_base->open_pana_authentication_cnt--;
01217                             }
01218                             tr_debug("Remove Current session by 'Comp bit'");
01219                             sec_suite_remove(suite);
01220                             buffer_free(buf);
01221                             return;
01222                         }
01223                     }
01224                 } else {
01225                     tr_debug("Pana RES:Drop Old seq");
01226                     buffer_free(buf);
01227                     return;
01228                 }
01229             } else {
01230                 suite->pana_session.res_seq = header.seq;
01231             }
01232 
01233             if (relay_pack) {
01234                 buf->src_sa  = buf->dst_sa ;
01235             }
01236 
01237             if (header.flags & PANA_FLAGS_START) {
01238                 pana_session_startms_parse(buf, &header, suite);
01239             } else if (header.flags & PANA_FLAGS_COMPLETE) {
01240                 pana_complete_msg_parse(buf, &header, suite);
01241             } else {
01242 
01243                 buf = pana_auth_message_handler(buf, &header, suite);
01244 
01245                 if (buf) {
01246                     pana_eap_tls_up(buf, suite);
01247                 }
01248             }
01249             return;
01250         }
01251         buffer_free(buf);
01252     } else {
01253         buffer_free(buf);
01254     }
01255 }
01256 
01257 
01258 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)
01259 {
01260     int8_t ret_val;
01261     uint8_t supported_chipher_suites;
01262     protocol_interface_info_entry_t *cur;
01263     cur = protocol_stack_interface_info_get_by_id(interface_id);
01264     if (!cur) {
01265         return -1;
01266     }
01267 
01268     if (!cur->if_lowpan_security_params) {
01269         return -1;
01270     }
01271 
01272     if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
01273         return -4;
01274     } else if (cur->if_lowpan_security_params->pana_params == 0) {
01275         return -3;
01276     } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) {
01277         return -5;
01278     }
01279 
01280     switch (cipher_mode) {
01281         case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */
01282             supported_chipher_suites = SEC_CIPHERSUITE_PSK;
01283             break;
01284 
01285         case NET_TLS_ECC_CIPHER:        /**< Network Authentication support only ECC */
01286         case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */
01287 #ifdef ECC
01288             //Verify Certficate
01289             if (sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) {
01290                 return -1;
01291             }
01292             if (cipher_mode == NET_TLS_PSK_AND_ECC_CIPHER) {
01293                 supported_chipher_suites = (SEC_CIPHERSUITE_PSK | SEC_CIPHERSUITE_ECC);
01294             } else {
01295                 supported_chipher_suites = SEC_CIPHERSUITE_ECC;
01296             }
01297             break;
01298 #endif // if ECC is not supported, flow into default => nothing is supported.
01299         default:
01300             supported_chipher_suites = 0;
01301             break;
01302     }
01303 
01304 
01305     ret_val = pana_server_init(interface_id, key_material, supported_chipher_suites, time_period_before_activate_key);
01306     if (ret_val == 0) {
01307         cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode;
01308         cur->if_lowpan_security_params->pana_params->psk_key_id = 0;
01309         cur->if_lowpan_security_params->pana_params->pana_client = 0;
01310         cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION);
01311         cur->configure_flags |= INTERFACE_SECURITY_DEFINED;
01312     }
01313 
01314     return ret_val;
01315 }
01316 
01317 int8_t pana_server_key_update(int8_t interface_id, const uint8_t *network_key_material)
01318 {
01319 
01320     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
01321     if (!cur) {
01322         return -1;
01323     }
01324 
01325     if (!pana_server_base || pana_server_base->network_interface_id != interface_id || pana_server_base->pana_key_update) {
01326         return -2;
01327     }
01328 
01329     if (!cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) {
01330         return -3;
01331     }
01332 
01333     if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) {
01334         return -4;
01335     } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) {
01336         return -5;
01337     }
01338 
01339 
01340 
01341     pana_server_base->pana_key_update = ns_dyn_mem_temporary_alloc(sizeof(pana_key_update_t));
01342     if (!pana_server_base->pana_key_update) {
01343         return -3;
01344     }
01345 
01346     pana_key_material_t *primary_key = pana_server_key_get(true);
01347 
01348     if (network_key_material) {
01349         memcpy(pana_server_base->pana_key_update->new_key_material, network_key_material, 16);
01350     } else {
01351         pana_server_set_random_key_value(pana_server_base->pana_key_update->new_key_material);
01352         network_key_material = pana_server_base->pana_key_update->new_key_material;
01353     }
01354 
01355     pana_lib_parameters_s *parameters = pana_parameters_get();
01356 
01357     /*  Update Key ID */
01358     pana_server_base->pana_key_update->key_id = primary_key->key_id;
01359     if (pana_server_base->pana_key_update->key_id == parameters->KEY_ID_MAX_VALUE) {
01360         /*  Start Lollipop Sechema from 1 again */
01361         pana_server_base->pana_key_update->key_id = 0;
01362     }
01363     pana_server_base->pana_key_update->key_id++;
01364 
01365 
01366     //Set New Key to secondary key
01367     primary_key = pana_server_key_get(false);
01368     primary_key->key_id = pana_server_base->pana_key_update->key_id;
01369     memcpy(primary_key->key_material, pana_server_base->pana_key_update->new_key_material, 16);
01370     //TRIG Timers
01371     pana_server_base->pana_key_update->key_delivery_cnt = sec_pana_key_update_trig(parameters->KEY_UPDATE_THRESHOLD);
01372     uint8_t *key_ptr = pana_key_get(network_key_material);
01373     if (key_ptr) {
01374         //pana_server_base->auth_cnt++;
01375         tr_debug("SET Secondary Key ready");
01376         mac_helper_security_next_key_set(cur, (key_ptr + 16), pana_server_base->pana_key_update->key_id, MAC_KEY_ID_MODE_IDX);
01377         mle_service_security_set_security_key(cur->id, key_ptr, pana_server_base->pana_key_update->key_id, false);
01378     }
01379     tr_debug("KEY Delivery CNT: %02x", pana_server_base->pana_key_update->key_delivery_cnt);
01380     if (pana_server_base->pana_key_update->key_delivery_cnt == 0) {
01381         tr_debug("TRIG NEW Key");
01382         pana_server_base->pana_key_update->key_delivery_cnt = 1;
01383         pana_key_update_delivery_ready();
01384     }
01385     if (pana_nvm_storage_cb) {
01386         pana_server_material_write(pana_nvm_buffer);
01387         pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
01388     }
01389     return 0;
01390 }
01391 
01392 void pana_key_update_delay_timer(void)
01393 {
01394     if (pana_server_base && pana_server_base->key_update_delay) {
01395         if (pana_server_base->key_update_delay <= 100) {
01396             protocol_interface_info_entry_t *cur;
01397             pana_server_base->key_update_delay = 0;
01398             cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id);
01399 
01400             //SWAP new KEY
01401             if (cur) {
01402                 tr_debug("Trig New Key ID");
01403                 uint8_t keyId = mle_service_security_next_key_id_get(cur->id);
01404                 mac_helper_security_key_swap_next_to_default(cur);
01405                 mle_service_security_key_trig(cur->id, keyId);
01406                 if (cur->nwk_wpan_nvm_api) {
01407                     cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01408                 }
01409                 if (pana_key_update_process_ready) {
01410                     pana_key_update_process_ready();
01411                 }
01412             }
01413             if (pana_server_base->primary_material) {
01414                 pana_server_base->primary_material = 0;
01415             } else {
01416                 pana_server_base->primary_material = 1;
01417             }
01418 
01419             pana_key_material_t *primary_key = pana_server_key_get(true);
01420             primary_key->key_id = pana_server_base->pana_key_update->key_id;
01421             memcpy(primary_key->key_material , pana_server_base->pana_key_update->new_key_material, 16);
01422 
01423             if (pana_server_base->pana_key_update) {
01424                 ns_dyn_mem_free(pana_server_base->pana_key_update);
01425                 pana_server_base->pana_key_update = 0;
01426             }
01427             if (pana_nvm_storage_cb) {
01428                 tr_debug("PS:NVM Cover");
01429                 pana_server_material_write(pana_nvm_buffer);
01430                 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE);
01431             }
01432 
01433         } else {
01434             pana_server_base->key_update_delay -= 100;
01435         }
01436     }
01437 
01438 }
01439 
01440 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)
01441 {
01442     if (!update_cb || !nvm_static_buffer || !nvm_get || !nvm_session_get) {
01443         return -1;
01444     }
01445     pana_nvm_storage_cb = update_cb;
01446     pana_server_nvm_get = nvm_get;
01447     pana_server_nvm__session_get = nvm_session_get;
01448     pana_nvm_buffer = nvm_static_buffer;
01449     return 0;
01450 }
01451 
01452 int8_t pana_server_process_ready_cb_set(void (*cb_fptr)(void))
01453 {
01454     if (cb_fptr) {
01455         pana_key_update_process_ready = cb_fptr;
01456         return 0;
01457     }
01458     return -1;
01459 }
01460 
01461 /* Pana Client session load from NVM API */
01462 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer)
01463 {
01464 
01465     if (!pana_server_base) {
01466         return -1;
01467     }
01468     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id);
01469     if (!cur) {
01470         return -1;
01471     }
01472 
01473     if (pana_socket_id_get() == -1) {
01474         return -2;
01475     }
01476 
01477     if (pana_server_session_restore(nvm_pointer, cur)) {
01478         return -3;
01479     }
01480     return 0;
01481 }
01482 
01483 static void pana_success_server_build(buffer_t *buf, sec_suite_t *suite)
01484 {
01485     uint8_t *ptr;
01486     pana_header_t header;
01487     header.type = PANA_MSG_PA;
01488     header.flags = PANA_FLAGS_COMPLETE | PANA_FLAGS_REQUEST;
01489     //REQUEST
01490     header.seq = suite->pana_session.req_seq;
01491     header.session_id = suite->pana_session.session_id;
01492 
01493     buf->buf_ptr  = PANA_HEADER_LENGTH;
01494     ptr = buffer_data_pointer(buf);
01495 
01496     uint8_t eap_status[4];
01497     eap_header_build(eap_status, 4,EAP_SUCCESS, suite->pana_session.eap_id_seq, 0);
01498 
01499     ptr = pana_avp_32_bit_write(AVP_RESULT_CODE, 0, ptr);
01500     ptr = pana_avp_write_n_bytes(AVP_EAP_PAYLOAD_CODE, 4, eap_status, ptr);
01501     ptr = pana_avp_32_bit_write(AVP_KEY_ID_CODE, suite->pana_session.pana_key_id, ptr);
01502     ptr = pana_avp_32_bit_write(AVP_SESSION_LIFETIME_CODE, suite->pana_session.session_lifetime, ptr);
01503     //ENC
01504     uint8_t key_material[18];
01505     pana_server_set_key_material(key_material, false, suite->pana_session.auth_cnt);
01506     ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite);
01507     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
01508     buffer_data_end_set(buf, ptr);
01509     buf = build_pana_base(buf, &header, suite);
01510     if (!buf) {
01511         return;
01512     }
01513 
01514     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
01515 
01516     //Encode Pana Auth
01517     pana_set_agend_address(buf, false, suite);
01518     if (suite->pana_session.address_status & 1) {
01519         buf = pana_relay_avp_build(buf, suite);
01520         if (buf) {
01521             header.flags = 0;
01522             header.type = PANA_MSG_RELAY;
01523             header.session_id = 0;
01524             header.seq = 0;
01525             buf = build_pana_base(buf, &header, suite);
01526         }
01527     }
01528 
01529     protocol_push(buf);
01530 }
01531 
01532 
01533 
01534 static void pana_server_build_key_push(buffer_t *buf, sec_suite_t *suite)
01535 {
01536     uint8_t *ptr;
01537     pana_header_t header;
01538     header.type = PANA_MSG_PNA;
01539     header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING;
01540     //REQUEST
01541     header.seq = suite->pana_session.req_seq;
01542     header.session_id = suite->pana_session.session_id;
01543 
01544 
01545     buf->buf_ptr  = PANA_HEADER_LENGTH;
01546     ptr = buffer_data_pointer(buf);
01547     //ENC
01548     uint8_t key_material[18];
01549     pana_server_set_key_material(key_material, true, suite->pana_session.auth_cnt);
01550     ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite);
01551     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
01552 
01553     buffer_data_end_set(buf, ptr);
01554     buf = build_pana_base(buf, &header, suite);
01555     if (!buf) {
01556         return;
01557     }
01558 
01559     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
01560     pana_set_agend_address(buf, true, suite);
01561 
01562     protocol_push(buf);
01563 }
01564 
01565 int8_t pana_network_key_get(int8_t interface_id, ns_keys_t *key)
01566 {
01567     (void)interface_id;
01568 
01569     if (pana_server_base && key) {
01570         pana_key_material_t *primary_key = pana_server_key_get(true);
01571         pana_key_material_t *prev_key = pana_server_key_get(false);
01572         if (prev_key->key_id == 0) {
01573             prev_key = 0;
01574         }
01575         key->current_active_key_index = primary_key->key_id;
01576         memcpy(key->current_active_network_key , primary_key->key_material, 16);
01577         if (prev_key) {
01578             key->previous_active_key_index = prev_key->key_id;
01579             memcpy(key->previous_active_network_key , prev_key->key_material, 16);
01580         } else {
01581             memset(key->previous_active_network_key, 0, 16);
01582         }
01583         return 0;
01584     }
01585     return -1;
01586 }
01587 
01588 int8_t pana_server_trig_new_key(int8_t interface_id)
01589 {
01590 
01591     if (!pana_server_base) {
01592         return -1;
01593     }
01594     if (pana_server_base->network_interface_id != interface_id) {
01595         return -2;
01596     }
01597     if (pana_server_base->key_update_delay) {
01598         tr_debug("TRIG faster");
01599         pana_server_base->key_update_delay = 1;
01600         return  0;
01601     }
01602     return -1;
01603 
01604 }
01605 
01606 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id)
01607 {
01608     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
01609     if (!cur) {
01610      return -1;
01611     }
01612 
01613     if (!pana_socket_init(pana_server_packet_handler, pana_server_state_machine_func, tls_server_up)) {
01614         return -1;
01615     }
01616 
01617     sec_suite_list_clean();
01618 
01619     //Allocate
01620     if (pana_server_base == 0) {
01621         pana_server_base = pana_server_staructure_allocate();
01622     }
01623     if (!pana_server_base || !cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) {
01624         return -1;
01625     }
01626 
01627     net_tls_cipher_e cipher_mode;
01628     pana_server_base->open_pana_authentication_cnt = 0;
01629     pana_server_base->network_interface_id = interface_id;
01630     pana_server_base->pana_key_update = 0;
01631     pana_server_base->key_update_delay = 0;
01632     pana_server_material_read(nvm_data);
01633     if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_PSK) {
01634         cipher_mode = NET_TLS_PSK_CIPHER;
01635     } else if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_ECC) {
01636         cipher_mode = NET_TLS_ECC_CIPHER;
01637     } else {
01638         cipher_mode = NET_TLS_PSK_AND_ECC_CIPHER;
01639     }
01640 
01641     cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode;
01642     cur->if_lowpan_security_params->pana_params->psk_key_id = 0;//TODO?????
01643             cur->if_lowpan_security_params->pana_params->pana_client = 0;
01644     cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION);
01645     cur->configure_flags |= INTERFACE_SECURITY_DEFINED;
01646 
01647     return 0;
01648 }
01649 
01650 int8_t pana_server_key_material_load(int8_t interface_id)
01651 {
01652     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
01653     if (!cur) {
01654         return -1;
01655     } else if (!pana_server_base) {
01656         return -1;
01657     }
01658     uint8_t *key_ptr;
01659     pana_key_material_t *key_mat;
01660     if (pana_server_base->pana_key_update) {
01661 
01662         pana_server_base->auth_cnt++;
01663         //Load First Primary to master
01664         key_mat = pana_server_key_get(true);
01665         key_ptr = pana_key_get(key_mat->key_material);
01666         mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01667         mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true);
01668         if (cur->nwk_wpan_nvm_api) {
01669             cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01670         }
01671         //Set Secondary to coming key
01672         key_mat = pana_server_key_get(false);
01673         key_ptr = pana_key_get(key_mat->key_material);
01674         mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01675         mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false);
01676     } else {
01677         bool secondary_active = false;
01678         //Load first Secondary and then Primary
01679         key_mat = pana_server_key_get(false);
01680         if (key_mat->key_id) {
01681             key_ptr = pana_key_get(key_mat->key_material);
01682             secondary_active = true;
01683             mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01684             mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true);
01685             if (cur->nwk_wpan_nvm_api) {
01686                 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01687             }
01688         }
01689         key_mat = pana_server_key_get(true);
01690         key_ptr = pana_key_get(key_mat->key_material);
01691         if (secondary_active) {
01692             mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01693             mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false);
01694             mac_helper_security_key_swap_next_to_default(cur);
01695             mle_service_security_key_trig(cur->id, key_mat->key_id);
01696         } else {
01697             mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX);
01698             mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true);
01699         }
01700         if (cur->nwk_wpan_nvm_api) {
01701             cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true);
01702         }
01703     }
01704     return 0;
01705 }
01706 
01707 static void pana_client_authentication_fail(sec_suite_t *suite)
01708 {
01709     if (suite->pana_session.nvm_offset) {
01710         //tr_debug("NVM Session Remove");
01711         pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE);
01712     }
01713     if (pana_server_base && pana_server_base->open_pana_authentication_cnt) {
01714         pana_server_base->open_pana_authentication_cnt--;
01715     }
01716 }
01717 
01718 #else
01719 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)
01720 {
01721     (void)update_cb;
01722     (void)nvm_static_buffer;
01723     return -1;
01724 }
01725 
01726 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer)
01727 {
01728     (void) nvm_pointer;
01729     return -1;
01730 }
01731 
01732 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id)
01733 {
01734     (void) nvm_data;
01735     (void)interface_id;
01736     return -1;
01737 }
01738 #endif
01739 #else
01740 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)
01741 {
01742     (void)update_cb;
01743     (void)nvm_static_buffer;
01744     return -1;
01745 }
01746 
01747 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer)
01748 {
01749     (void) nvm_pointer;
01750     return -1;
01751 }
01752 
01753 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id)
01754 {
01755     (void) nvm_data;
01756     (void)interface_id;
01757     return -1;
01758 }
01759 #endif