Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pana_client.c Source File

pana_client.c

00001 /*
00002  * Copyright (c) 2017-2019, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "nsconfig.h"
00019 
00020 #include "ns_types.h"
00021 #include "eventOS_event.h"
00022 #include "ns_trace.h"
00023 #include "string.h"
00024 #include "randLIB.h"
00025 #include "nsdynmemLIB.h"
00026 #include "Core/include/ns_socket.h"
00027 #include "NWK_INTERFACE/Include/protocol.h"
00028 #include "ccmLIB.h"
00029 #include "shalib.h"
00030 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h"
00031 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h"
00032 #ifdef ECC
00033 #include "libX509_V3.h"
00034 #include "ecc.h"
00035 #endif
00036 #include "Security/TLS/tls_lib.h"
00037 #include "Security/Common/sec_lib.h"
00038 #include "net_nvm_api.h"
00039 #include "Security/PANA/pana.h"
00040 #include "Security/PANA/pana_internal_api.h"
00041 #include "6LoWPAN/MAC/mac_helper.h"
00042 #include "6LoWPAN/MAC/mac_data_poll.h"
00043 #include "6LoWPAN/ND/nd_router_object.h"
00044 #include "Common_Protocols/udp.h"
00045 
00046 #ifdef ECC
00047 #include    "ecc.h"
00048 #endif
00049 #include "common_functions.h"
00050 #include "Security/PANA/pana_nvm.h"
00051 #include "Security/PANA/pana_avp.h"
00052 #include "Security/PANA/pana_eap_header.h"
00053 #include "Security/PANA/pana_header.h"
00054 #include "Security/PANA/eap_protocol.h"
00055 #include "net_pana_parameters_api.h"
00056 #include "Service_Libs/mle_service/mle_service_api.h"
00057 #include "6LoWPAN/NVM/nwk_nvm.h"
00058 
00059 #ifdef PANA
00060 #define TRACE_GROUP "PanC"
00061 
00062 static pana_client_session_update_cb *pana_client_nvm_storage_cb = NULL;
00063 static pana_client_session_get_cb *pana_client_session_get = NULL;
00064 static uint8_t *pana_client_nvm_buffer = 0;
00065 
00066 static void pana_complete_msg_parse(buffer_t *buf, pana_header_t *header, sec_suite_t *suite);
00067 static void pana_client_packet_handler(buffer_t *buf);
00068 static buffer_t *pana_auth_msg_build(buffer_t *buf, pana_header_t *header, sec_suite_t *suite);
00069 static void pana_client_pna_handler(buffer_t *buf, pana_header_t *header, sec_suite_t *suite);
00070 static bool pana_check_address(buffer_t *buf);
00071 static uint8_t *pana_avp_zip_key_req(uint8_t *dptr, protocol_interface_info_entry_t *cur);
00072 static void pana_client_session_nvm_udate(sec_suite_t *suite);
00073 static void pana_session_data_load_to_session(uint8_t *data_buf, sec_suite_t *suite);
00074 static uint8_t pana_ping_notify_msg_generate(uint8_t key_req, sec_suite_t *suite);
00075 
00076 static uint8_t *pana_avp_zip_key_req(uint8_t *dptr, protocol_interface_info_entry_t *cur)
00077 {
00078     uint8_t key_req[2];
00079     key_req[0] = 1;
00080     key_req[1] = mac_helper_default_key_index_get(cur);
00081     return pana_avp_vendor_id_write_n_bytes(PANA_EAP_KEYREQ_TYPE, 2, key_req, dptr, ZIGBEE_VENDOR_ID);
00082 }
00083 
00084 bool pana_check_address(buffer_t *buf)
00085 {
00086     if (buf->src_sa .address [0] == 0xfe && buf->dst_sa .address [0] == 0xfe) {
00087         return true;
00088     }
00089     return false;
00090 }
00091 
00092 static buffer_t *pana_auth_msg_build(buffer_t *buf, pana_header_t *header, sec_suite_t *suite)
00093 {
00094     uint8_t *ptr;
00095     buf->buf_ptr  = PANA_HEADER_LENGTH;
00096     ptr = buffer_data_pointer(buf);
00097     ptr = pana_avp_32_bit_write(AVP_KEY_ID_CODE, suite->pana_session.pana_key_id, ptr);
00098     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
00099     buffer_data_end_set(buf, ptr);
00100     header->flags = PANA_FLAGS_COMPLETE;
00101     return build_pana_base(buf, header, suite);
00102 
00103 }
00104 
00105 static uint8_t *pana_client_keywrap_parse(uint8_t *ptr, uint16_t len, sec_suite_t *suite)
00106 {
00107     suite->pana_session.key_warp = true;
00108     pana_avp_t avp_data;
00109     avp_data.code = PANA_EAP_KEYWRAP_TYPE;
00110     if (!pana_avp_discover(ptr, len, &avp_data) || avp_data.len != 18) {
00111         return NULL;
00112     }
00113 
00114     if (avp_data.flags & PANA_EAP_VENDOR_FLAG) {
00115         if (avp_data.vendor_id != ZIGBEE_VENDOR_ID) {
00116             tr_debug("Vendor not ZIP: %02"PRIu32, avp_data.vendor_id);
00117             return NULL;
00118         }
00119     }
00120 
00121     tr_debug("Network Key id: %02x, Ctr: %02x", avp_data.avp_ptr[16], avp_data.avp_ptr[17]);
00122     return avp_data.avp_ptr;
00123 }
00124 
00125 static bool pana_message_authency_validate(uint8_t *ptr, uint16_t length, uint8_t *auth_key)
00126 {
00127     pana_avp_t avp_temp;
00128     avp_temp.code = AVP_AUTHENCY_CODE;
00129     if (!pana_avp_discover(ptr, length, &avp_temp)) {
00130         return false;
00131     }
00132 
00133     return pana_auth_check(ptr, length, avp_temp.avp_ptr, auth_key);
00134 }
00135 
00136 static void pana_complete_msg_parse(buffer_t *buf, pana_header_t *header, sec_suite_t *suite)
00137 {
00138     uint16_t length = buffer_data_length(buf);
00139     uint8_t *ptr = buffer_data_pointer(buf);
00140 
00141     if (sec_check_suite_ptrs(suite) == 0) {
00142         buffer_free(buf);
00143         return;
00144     }
00145 
00146     if (!(header->flags & PANA_FLAGS_REQUEST)) {
00147         buffer_free(buf);
00148         return;
00149     }
00150 
00151     uint32_t key_id = 0xffffffff;
00152 
00153     bool key_id_parsed = false;
00154     uint32_t result = 0; //Default if not sended
00155     pana_avp_t avp_temp;
00156     //Read Resul and Key id if they are coming
00157     avp_temp.code = AVP_RESULT_CODE;
00158     if (pana_avp_discover(ptr, length, &avp_temp) &&  avp_temp.len == 4) {
00159         result = common_read_32_bit(avp_temp.avp_ptr);
00160     }
00161 
00162     avp_temp.code = AVP_KEY_ID_CODE;
00163     if (pana_avp_discover(ptr, length, &avp_temp) &&  avp_temp.len == 4) {
00164         key_id = common_read_32_bit(avp_temp.avp_ptr);
00165         key_id_parsed = true;
00166     }
00167 
00168 
00169     uint32_t lifetime = 0xffffffff;
00170     tr_debug("Handle Compelete request");
00171 
00172     if ((header->agent_retry) && suite->state == PANA_READY) {
00173 
00174         if (!pana_message_authency_validate(ptr, length, suite->pana_session.pana_auth_key)) {
00175             buffer_free(buf);
00176             return;
00177         }
00178 
00179         tr_debug("RE TX response for Pana Complete");
00180         goto build_response;
00181     }
00182 
00183     bool eap_status = true;
00184     avp_temp.code = AVP_EAP_PAYLOAD_CODE;
00185     if (pana_avp_discover(ptr, length, &avp_temp)) {
00186         eap_header_t eap_header;
00187         if (eap_header_parse(avp_temp.avp_ptr, avp_temp.len, &eap_header)) {
00188             if (eap_header.eap_code == EAP_SUCCESS) {
00189                 tr_debug("EAP success");
00190             } else if (eap_header.eap_code == EAP_FAILURE) {
00191                 tr_debug("EAP Failure");
00192                 eap_status = false;
00193             }
00194         }
00195     }
00196 
00197 
00198     //Validate Result
00199     if (result || !eap_status) {
00200         tr_debug("PANA / EAP Failure Result");
00201         //Check State
00202         if (suite->state != PANA_PING_REQ) {
00203             goto pana_failure;
00204         }
00205 
00206         tr_debug("Reset Pana for new session");
00207         suite->pana_session.key_warp = false;
00208         suite->pana_session.session_ready = false;
00209         pana_session_init_by_session_ptr(suite, suite->pana_session.auth_info);
00210         buffer_free(buf);
00211         return;
00212 
00213     }
00214 
00215     avp_temp.code = AVP_SESSION_LIFETIME_CODE;
00216     if (pana_avp_discover(ptr, length, &avp_temp) &&  avp_temp.len == 4) {
00217         lifetime = common_read_32_bit(avp_temp.avp_ptr);
00218     }
00219 
00220     if (!key_id_parsed) {
00221         goto pana_failure;
00222     }
00223 
00224     suite->pana_session.pana_key_id = key_id;
00225     suite->pana_session.session_lifetime = lifetime;
00226     if (suite->state != PANA_READY) {
00227         pana_key_calculation(suite);
00228     }
00229 
00230     if (!pana_message_authency_validate(ptr, length, suite->pana_session.pana_auth_key)) {
00231         goto pana_failure;
00232     }
00233 
00234 
00235     avp_temp.code = AVP_ENCRYPT_ALGORITHM_CODE;
00236     if (pana_avp_discover(ptr, length, &avp_temp)) {
00237         tr_debug("Key Delivery");
00238         if (pana_ccm_data_crypt(avp_temp.avp_ptr, avp_temp.len, AES_CCM_DECRYPT, header->seq, suite) != 0) {
00239             goto pana_failure;
00240         }
00241         uint8_t *key_material = pana_client_keywrap_parse(avp_temp.avp_ptr, avp_temp.len, suite);
00242         if (!key_material) {
00243             goto pana_failure;
00244         }
00245         if (!suite->pana_session.auth_info) {
00246             goto pana_failure;
00247         }
00248 
00249         tr_debug("Valid");
00250         suite->pana_session.nwk_key_id = key_material[16];
00251         suite->pana_session.auth_cnt = key_material[17];
00252         auth_info_t *pana_auth_info_temp = suite->pana_session.auth_info;
00253         memcpy(pana_auth_info_temp->network_key, key_material, 16);
00254         pana_auth_info_temp->key_id = key_material[16];
00255     }
00256     tr_debug("Server AUTH_OK");
00257     suite->state = PANA_READY;
00258     suite->timer = 95;
00259 
00260 build_response:
00261     buf = pana_auth_msg_build(buf, header, suite);
00262     if (!buf) {
00263         return;
00264     }
00265 
00266     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
00267     pana_set_agend_address(buf, false, suite);
00268     protocol_push(buf);
00269     return;
00270 
00271 
00272 pana_failure:
00273     tr_debug("Drop Key MSG");
00274     sec_lib_state_machine_trig(suite, PANA_FAILURE); //shuold be calc
00275     buffer_free(buf);
00276     return;
00277 }
00278 
00279 static void pana_client_pna_handler(buffer_t *buf, pana_header_t *header, sec_suite_t *suite)
00280 {
00281 
00282     protocol_interface_info_entry_t *cur = buf->interface ;
00283     if (!cur) {
00284         goto end_of_function;
00285     }
00286 
00287     if (!suite->pana_session.session_ready) {
00288         goto end_of_function;
00289     }
00290 
00291     uint16_t length = buffer_data_length(buf);
00292     uint8_t *ptr = buffer_data_pointer(buf);
00293     tr_debug("Parse Ping Auth Notify");
00294 
00295     if (!pana_message_authency_validate(ptr, length, suite->pana_session.pana_auth_key)) {
00296         tr_warn("Auth Fail");
00297         goto end_of_function;
00298     }
00299 
00300     pana_avp_t avp_temp;
00301     avp_temp.code = AVP_ENCRYPT_ALGORITHM_CODE;
00302 
00303     if (pana_avp_discover(ptr, length, &avp_temp)) {
00304         tr_debug("ZIP Key");
00305         //Calc key
00306         if (pana_ccm_data_crypt(avp_temp.avp_ptr, avp_temp.len, AES_CCM_DECRYPT, header->seq, suite) != 0) {
00307             tr_debug("Drop Key MSG");
00308             goto end_of_function;
00309         }
00310 
00311         uint8_t *key_delivery = pana_client_keywrap_parse(avp_temp.avp_ptr, avp_temp.len, suite);
00312         if (!key_delivery) {
00313             tr_debug("Drop Key MSG");
00314             goto end_of_function;
00315         }
00316         //tr_debug("Valid");
00317         suite->pana_session.nwk_key_id = key_delivery[16];
00318         suite->pana_session.auth_cnt = key_delivery[17];
00319         if (suite->state == PANA_PING_REQ) {
00320             tr_debug("Save Key to auth Info");
00321 
00322             if (suite->pana_session.auth_info) {
00323                 tr_debug("Save Key to auth Info");
00324                 auth_info_t *pana_auth_info_temp = suite->pana_session.auth_info;
00325                 //Save keys to Auth Info structure
00326                 memcpy(pana_auth_info_temp->network_key, key_delivery, 16);
00327                 pana_auth_info_temp->key_id = key_delivery[16];
00328             }
00329         } else {
00330             //Calc keys
00331             tr_debug("Calc keys");
00332             uint8_t *key_ptr = pana_key_get(key_delivery);
00333             mac_helper_security_next_key_set(cur, (key_ptr + 16), key_delivery[16], MAC_KEY_ID_MODE_IDX);
00334             mle_service_security_set_security_key(cur->id, key_ptr, key_delivery[16], false);
00335         }
00336     }
00337 
00338 
00339     if (header->flags & PANA_FLAGS_REQUEST) {
00340         //tr_debug("Build Response");
00341         //SET Original packet First
00342         if ((header->flags & (PANA_FLAGS_PING | PANA_FLAGS_REQUEST)) == (PANA_FLAGS_PING | PANA_FLAGS_REQUEST)) {
00343             pana_client_session_nvm_udate(suite);
00344         }
00345         header->flags &= ~PANA_FLAGS_REQUEST;
00346         buf->buf_ptr  = PANA_HEADER_LENGTH;
00347         ptr = buffer_data_pointer(buf);
00348         ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
00349         buffer_data_end_set(buf, ptr);
00350         buf = build_pana_base(buf, header, suite);
00351         if (buf) {
00352             pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
00353             //memcpy(buf->dst_sa.address, buf->src_sa.address, 16);
00354             //buf->src_sa.addr_type = ADDR_NONE;
00355             if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) {
00356                 pana_set_agend_address(buf, true, suite);
00357             } else {
00358                 pana_set_agend_address(buf, false, suite);
00359             }
00360             protocol_push(buf);
00361         }
00362         return;
00363     }
00364     //tr_debug("GET KEY");
00365     if (suite->state == PANA_PING_REQ) {
00366         //tr_debug("RE Valid Ready");
00367         tr_debug("pana nvm ok");
00368         sec_lib_state_machine_trig(suite, PANA_RE_VALID);
00369     } else if (suite->state == PANA_KEY_PULL) {
00370         mac_data_poll_protocol_poll_mode_disable(cur);
00371         sec_lib_state_machine_trig(suite, PANA_PULL_DONE);
00372     }
00373     pana_client_session_nvm_udate(suite);
00374 
00375 
00376 end_of_function:
00377     buffer_free(buf);
00378 }
00379 
00380 static void sec_auth_ready(sec_suite_t *suite)
00381 {
00382     suite->timer = 0;
00383     tr_debug("Pana:OK");
00384     suite->pana_session.session_ready = true;
00385     if (suite->state == PANA_READY) {
00386         pana_client_session_nvm_udate(suite);
00387     }
00388     //Kick ICMP-State Machine to ND / RPL
00389     if (suite->state != PANA_PULL_DONE) {
00390         pana_authentication_ready(1, suite->interface);
00391     }
00392 
00393     //Reset pointer
00394     suite->pana_session.auth_info = NULL;
00395     pana_free_dynamic_ram(suite);
00396     sec_suite_tls_free(suite, true);
00397 
00398 }
00399 
00400 static void pana_pci_build(sec_suite_t *suite)
00401 {
00402 
00403     buffer_t *buf = buffer_get(127);
00404 
00405     if (!buf) {
00406         tr_debug("Pana Init Fail");
00407         return;
00408     }
00409     tr_debug("BUILD PCI");
00410     pana_header_t header;
00411     header.type = PANA_MSG_PCI;
00412     header.flags = 0;
00413     header.seq = 0;
00414     header.session_id = 0;
00415     buf->interface  = suite->interface;
00416     pana_set_agend_address(buf, false, suite);
00417     suite->session_port = UDP_PORT_PANA;
00418     buf = build_pana_base(buf, &header, suite);
00419     protocol_push(buf);
00420 }
00421 
00422 static void pana_client_pana_error_handler(sec_suite_t *suite)
00423 {
00424     sec_lib_state_machine_lock(suite, PANA_ERROR);
00425     pana_authentication_ready(0, suite->interface);
00426     seclib_session_clean(suite);
00427 }
00428 
00429 static void pana_client_state_machine_func(sec_suite_t *suite)
00430 {
00431     if (!suite) {
00432         return;
00433     }
00434     uint8_t general_tx = 0;
00435 
00436 
00437     switch (suite->state) {
00438         case PANA_ERROR:
00439             pana_client_pana_error_handler(suite);
00440             return;
00441         case PANA_PCI_TX:
00442             if (sec_auth_re_check(suite)) {
00443                 pana_pci_build(suite);
00444                 pana_timeout_timer_set(suite, suite->state);
00445             } else {
00446                 pana_client_pana_error_handler(suite);
00447             }
00448             return;
00449         case PANA_KEY_PULL:
00450         case PANA_PING_REQ:
00451             if (sec_auth_re_check(suite)) {
00452                 if (suite->state == PANA_PING_REQ) {
00453                     pana_ping_notify_msg_generate(0, suite);
00454                 } else {
00455                     pana_ping_notify_msg_generate(1, suite);
00456                 }
00457 
00458             } else {
00459                 //Do Pana
00460                 if (suite->state == PANA_PING_REQ) {
00461                     tr_error("pana nvm failed");
00462                 }
00463                 tr_debug("Reset Pana");
00464                 suite->pana_session.session_ready = false;
00465                 pana_session_init_by_session_ptr(suite, suite->pana_session.auth_info);
00466             }
00467             break;
00468 
00469         case PANA_READY:
00470         case PANA_RE_VALID:
00471         case PANA_PULL_DONE:
00472             sec_auth_ready(suite);
00473             break;
00474 
00475         case PRF_CALC:
00476         case PRF_CALC2:
00477         case TLS_ECC_CERTIFICATE_VERIFY_SIGNATURE:
00478         case TLS_ECC_MESSAGE_VERIFY:
00479         case TLS_ECC_CERTIFICATE_SIGNATURE_CHECK:
00480         case TLS_ECC_GENERATE_PUBLIC_KEY:
00481         case TLS_ECC_GENERATE_PREMASTER_SECRET:
00482         case TLS_ECC_SIGNATURE_MESSAGE:
00483             break;
00484         case TLS_HELLO_RX:
00485         case TLS_SERVER_KEY_EXCHANGE_RX:
00486         case TLS_SERVER_WAIT_CHANGE_CHIPHERSUITE:
00487         case TLS_CLIENT_KEY_EXCHANGE_RX:
00488         case TLS_CHANGE_CHIPHER:
00489             tr_debug("%02x", suite->state);
00490             tr_debug("Timeout");
00491             sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00492             general_tx = 1;
00493             break;
00494 
00495 #ifdef ECC
00496         case TLS_ECC_GENERATE_PUBLIC_KEY_START:
00497             sec_ecc_gen_public_key_start(suite);
00498             break;
00499 
00500         case TLS_ECC_MESSAGE_SERVER_VERIFY_START:
00501         case TLS_ECC_MESSAGE_VERIFY_START:
00502             if (suite->tls_session) {
00503                 if (suite->tls_session->tls_heap) {
00504                     int start = 0;
00505                     tls_heap_t *theap = suite->tls_session->tls_heap;
00506 
00507                     if (theap->cert_temp_buf) {
00508                         if (suite->state == TLS_ECC_MESSAGE_SERVER_VERIFY_START) {
00509                             if (theap->signature_temp_buf == 0) {
00510                                 start = 1;
00511                             }
00512                         }
00513                     } else {
00514                         start = 1;
00515                     }
00516                     if (start) {
00517                         tls_server_finnish_handle_start(suite);
00518                     } else {
00519                         tr_debug("Start Certi Check");
00520                         tls_certificate_signature_verify(suite);
00521                     }
00522                 }
00523             }
00524             break;
00525         case TLS_ECC_MESSAGE_VERIFY_START2:
00526             tls_ecc_verfify_start(suite);
00527             break;
00528 
00529         case TLS_ECC_CLIENT_SIGNATURE_START:
00530             sec_ecc_client_signature_start(suite);
00531             break;
00532 #endif
00533         case TLS_UPDATE_HAS_WITH_CERTIFICATE:
00534 #ifdef ECC
00535             if (sec_auth_re_check(suite)) {
00536                 if (tls_certi_hash_copy(suite) == 0) {
00537                     tr_warn("Server Certficate Alloc fail");
00538                     suite->timer = 4;
00539                 } else {
00540                     sec_lib_state_machine_trig(suite, TLS_ECC_CLIENT_SIGNATURE_START);
00541                 }
00542             } else
00543 #endif
00544             {
00545                 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00546                 general_tx = 1;
00547             }
00548             break;
00549 
00550         case TLS_CLIENT_TX_CERTIFICATE_VERIFY:
00551 #ifdef ECC
00552             if (sec_auth_re_check(suite)) {
00553                 if (tls_certificate_build(suite) == 0) {
00554                     tr_warn("Client Certi Verify Alloc fail");
00555                     suite->timer = 4;
00556                 } else {
00557                     sec_set_auth_timeout(suite, TLS_CLIENT_TX_CERTIFICATE_VERIFY);
00558                 }
00559             } else
00560 #endif
00561             {
00562                 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00563                 general_tx = 1;
00564             }
00565             break;
00566 
00567         default:
00568             general_tx = 1;
00569             break;
00570     }
00571 
00572     if (general_tx) {
00573         if (sec_auth_re_check(suite)) {
00574             buffer_t *buf = buffer_get(140);
00575             if (buf) {
00576                 buf->interface  = suite->interface;
00577                 suite->timer = 600;
00578                 switch (suite->state) {
00579                     case PANA_START_RESPONSE:
00580                         pana_start_message_build(buf, suite);
00581                         break;
00582 
00583                     case EAP_IDENTITY_RES:
00584                         pana_eap_identity_build(buf, suite);
00585                         break;
00586 
00587                     case TLS_INIT:
00588                         buf = tls_client_hello_build(buf, suite);
00589                         if (buf) {
00590                             pana_eap_down(buf, suite);
00591                         }
00592                         sec_set_auth_timeout(suite, TLS_INIT);
00593                         break;
00594 
00595                     case TLS_KEY_CHANGE:
00596                         //Print Handshake message
00597                         tls_prepare_change_chipher_spec(suite);
00598                         tls_build_client_change_chipher_suite_finnish(buf, suite);
00599                         pana_eap_down(buf, suite);
00600                         break;
00601 
00602                     case PANA_FAILURE:
00603                         buf->buf_ptr  = PANA_HEADER_LENGTH;
00604                         buf->buf_end  = PANA_HEADER_LENGTH;
00605                         pana_down(buf, suite);
00606                         break;
00607 
00608                     case TLS_FINISH:
00609                     case TLS_ALERT:
00610                         eap_fragmentation_init(suite);
00611                         pana_eap_tls_finnish_build(buf, suite);
00612                         break;
00613 
00614 
00615                     case TLS_ALERT_CLOSE_FATAL:
00616                     case TLS_ALERT_INTERNAL:
00617                     case TLS_ALERT_CHIPHER_SUITE:
00618                     case TLS_ALERT_DECRYPT:
00619                     case TLS_ALERT_BAD_CERTIFICATE:
00620 
00621                         eap_fragmentation_init(suite);
00622 
00623                         suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY);
00624 #ifdef ECC
00625                         {
00626                             tls_heap_t *tls_heap = suite->tls_session->tls_heap;
00627                             if (tls_heap) {
00628                                 tls_ecc_heap_free(tls_heap);
00629                             }
00630                         }
00631 #endif
00632                         if (suite->state == TLS_ALERT_DECRYPT) {
00633                             tls_alert_build(buf, ALERT_BAD_RECORD);
00634                         } else if (suite->state == TLS_ALERT_CLOSE_FATAL) {
00635                             tls_alert_build(buf, ALERT_INTERNAL_ERR);
00636                         } else if (suite->state == TLS_ALERT_BAD_CERTIFICATE) {
00637 
00638                             tls_alert_build(buf, ALERT_BAD_CERTIFICATE);
00639                         } else {
00640                             tls_alert_build(buf, ALERT_INTERNAL_ERR);
00641 
00642                         }
00643                         pana_eap_down(buf, suite);
00644                         break;
00645 
00646 
00647                     default:
00648                         tr_debug("Unknown Packet. State: %x", suite->state);
00649                         buf = buffer_free(buf);
00650                         break;
00651                 }
00652 
00653             } else {
00654                 suite->timer = 2;
00655             }
00656         } else {
00657             tr_debug("Tls Auth Re TX limit Reached. State: %x", suite->state);
00658 
00659             switch (suite->state) {
00660                 case TLS_KEY_CHANGE:
00661                     sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL);
00662                     break;
00663                 case TLS_INIT: //Trig pana failure if not get any response from server
00664                     sec_lib_state_machine_trig(suite, PANA_FAILURE);
00665                     break;
00666 
00667                 default:
00668                     pana_client_pana_error_handler(suite);
00669                     break;
00670             }
00671         }
00672     }
00673 }
00674 
00675 static void pana_client_packet_handler(buffer_t *buf)
00676 {
00677     pana_header_t header;
00678     if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) {
00679         buffer_free(buf);
00680         return;
00681     }
00682     buffer_data_strip_header(buf, PANA_HEADER_LENGTH);
00683 
00684     sec_suite_t *suite =  sec_suite_selected_py_pan_id(buf->link_specific.ieee802_15_4.srcPanId);
00685     if (!suite) {
00686         buffer_free(buf);
00687         return;
00688     }
00689 
00690     header.agent_retry = false;
00691     //Handle Relay
00692     if (header.type == PANA_MSG_RELAY) {
00693         if (suite->pana_session.session_ready) {
00694             buf = pana_relay_parse(buf);
00695         }
00696         if (buf) {
00697             protocol_interface_info_entry_t *cur_interface = buf->interface ;
00698             addr_interface_get_ll_address(cur_interface, buf->src_sa .address , 0);
00699             buf->src_sa .addr_type  = ADDR_IPV6 ;
00700             buf->src_sa .port  = UDP_PORT_PANA;
00701             buf = buffer_turnaround(buf);
00702             buf->info  = (buffer_info_t)(B_DIR_DOWN + B_FROM_APP + B_TO_UDP);
00703             protocol_push(buf);
00704             buf = NULL;
00705         }
00706         return;
00707     }
00708 
00709     bool my_session = false;
00710     if (header.type != PANA_MSG_PCI) {
00711         if ((header.flags & PANA_FLAG_START_REQ_MASK)  == (PANA_FLAG_START_REQ_MASK)) {
00712             if (memcmp(suite->session_address, buf->src_sa .address , 16) == 0) {
00713                 my_session = true;
00714             }
00715         } else {
00716             //Check Session
00717             if (suite->pana_session.session_id == header.session_id) {
00718                 //Validate Session
00719                 if ((memcmp(suite->session_address, buf->src_sa .address , 16) == 0)) {
00720                     my_session = true;
00721                 } else if (memcmp(suite->pana_session.session_relay_address, buf->src_sa .address , 16) == 0) {
00722                     my_session = true;
00723                 }
00724 
00725             }
00726 
00727             if (!my_session) {
00728                 if (buf->src_sa .address [0] != 0xfe) {
00729                     tr_debug("Not relay src");
00730                     buffer_free(buf);
00731                     return;
00732                 }
00733             }
00734         }
00735     }
00736 
00737     if (my_session) {
00738         if ((header.flags & PANA_FLAG_START_REQ_MASK)  == (PANA_FLAG_START_REQ_MASK)) {
00739             tr_debug("Take session & Sequency");
00740             suite->pana_session.session_id = header.session_id;
00741             suite->pana_session.res_seq = header.seq;
00742             pana_session_startms_parse(buf, &header, suite);
00743             return;
00744         }
00745 
00746         if (suite->pana_session.pana_heap) {
00747             pana_heap_t *pheap = suite->pana_session.pana_heap;
00748             if (pheap->handshake_len == 0 || pheap->handshake_req_offset == pheap->handshake_len) {
00749                 tr_debug("Pana REQ dropped because Handshake is not full started");
00750                 buffer_free(buf);
00751                 return;
00752             }
00753         }
00754 
00755         if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) {
00756             if (suite->pana_session.req_seq == header.seq) {
00757                 suite->pana_session.req_seq++;
00758             } else {
00759                 tr_debug("Pana RES:Drop Packet by seq num. Res: %02"PRIu32", RX: %02"PRIu32, suite->pana_session.req_seq >> 8, header.seq);
00760                 buffer_free(buf);
00761                 return;
00762             }
00763         } else {
00764             if ((suite->pana_session.res_seq + 1) == header.seq) {
00765                 suite->pana_session.res_seq = header.seq;
00766 
00767             } else {
00768                 if (suite->pana_session.res_seq != header.seq) {
00769                     tr_debug("PANA REQ:Drop Packet by seq num. Res: %02"PRIu32" , RX: %02"PRIu32, suite->pana_session.res_seq >> 8, header.seq);
00770                     buffer_free(buf);
00771                     return;
00772                 } else {
00773                     header.agent_retry = true;
00774                 }
00775             }
00776         }
00777         if (header.flags & PANA_FLAGS_COMPLETE) {
00778             pana_complete_msg_parse(buf, &header, suite);
00779 
00780         } else {
00781 
00782             if (header.type == PANA_MSG_PNA) {
00783                 pana_client_pna_handler(buf, &header, suite);
00784                 return;
00785             }
00786 
00787             if (header.type != PANA_MSG_PA) {
00788                 return;
00789             }
00790 
00791             buf = pana_auth_message_handler(buf, &header, suite);
00792 
00793             if (buf) {
00794                 pana_eap_tls_up(buf, suite);
00795             }
00796         }
00797         return;
00798 
00799     }
00800 
00801     //Relay
00802 
00803     if ((suite->pana_session.session_ready) && pana_check_address(buf)) {
00804 
00805         if (header.type == PANA_MSG_PNA || header.type == PANA_MSG_PCI) {
00806             //Remove old data
00807             if (lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address )) {
00808                 uint8_t ll_adr[16];
00809                 memcpy(ll_adr, buf->src_sa .address , 16);
00810                 buffer_free(buf);
00811                 tr_debug("Parent rejoin --> send unsecured Link Reject");
00812                 mle_service_reject_message_build(suite->interface->id, ll_adr, true);
00813                 return;
00814             }
00815         }
00816 
00817         buffer_data_reserve_header(buf, 16);
00818         buf = pana_relay_avp_build(buf, suite);
00819         if (buf) {
00820             //Set Pana Headers Like Draft say
00821             tr_debug("Pana Relay");
00822             header.flags = 0;
00823             header.type = PANA_MSG_RELAY;
00824             header.session_id = 0;
00825             header.seq = 0;
00826             pana_set_agend_address(buf, true, suite);
00827             buf = build_pana_base(buf, &header, suite);
00828             protocol_push(buf);
00829             buf = NULL;
00830         } else {
00831             tr_debug("Relay AVP Build Fail");
00832         }
00833     }
00834 
00835 
00836     if (buf) {
00837         buffer_free(buf);
00838     }
00839     return;
00840 }
00841 
00842 sec_suite_t *pana_client_init(auth_info_t *auth_ptr, uint8_t *session_address_ptr, pana_tls_setup_s *setup)
00843 {
00844     sec_suite_t *suite = sec_suite_selected_py_pan_id(setup->pan_id);
00845 
00846     if (!suite) {
00847 
00848         bool loaded_setup = false;
00849         if (pana_client_nvm_storage_cb) {
00850             loaded_setup = pana_client_session_get(setup->pan_id);
00851             if (loaded_setup) {
00852                 tr_debug("load pana nvm for PAN ID %2.2x", setup->pan_id);
00853                 suite = sec_lib_security_session_allocate(false);
00854             } else {
00855                 tr_debug("nvm pana load fail for PAN ID %2.2x", setup->pan_id);
00856                 suite = sec_lib_security_session_allocate(true);
00857             }
00858         } else {
00859             suite = sec_lib_security_session_allocate(true);
00860         }
00861         if (!suite) {
00862             return NULL;
00863         }
00864         if (loaded_setup) {
00865             pana_session_data_load_to_session(pana_client_nvm_buffer + 16, suite);
00866         }
00867         suite->pan_id = setup->pan_id;
00868 
00869         tr_debug("Create Entry");
00870         memcpy(suite->session_address, session_address_ptr, 16);
00871         tr_debug("Session adr: %s", tr_ipv6(suite->session_address));
00872     }
00873 
00874     if (suite) {
00875         pana_session_init_by_session_ptr(suite, auth_ptr);
00876         suite->supported_chipher_suites =  setup->security_support;
00877         suite->psk_key_id = setup->psk_key_id;
00878     }
00879     return suite;
00880 }
00881 
00882 void pana_reset_client_session(void)
00883 {
00884     sec_suite_list_clean();
00885 }
00886 
00887 int8_t pana_client_interface_init(int8_t interface_id, net_tls_cipher_e cipher_mode, uint32_t psk_key_id)
00888 {
00889     protocol_interface_info_entry_t *cur = 0;
00890     cur = protocol_stack_interface_info_get_by_id(interface_id);
00891     if (!cur) {
00892         return -1;
00893     }
00894 
00895     if (!cur->if_lowpan_security_params) {
00896         return -1;
00897     } else if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) {
00898         return -4;
00899     } else if (cur->if_lowpan_security_params->pana_params == 0) {
00900         return -3;
00901     } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) {
00902         return -5;
00903     }
00904 
00905     if (!pana_socket_init(pana_client_packet_handler, pana_client_state_machine_func, tls_client_up)) {
00906         return -1;
00907     }
00908 
00909     switch (cipher_mode) {
00910 
00911         case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */
00912             //Verify PSK KEY ID
00913             if (arm_tls_check_key(psk_key_id) != 0) {
00914                 return -7;
00915             }
00916             break;
00917 
00918         case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */
00919             //Verify PSK KEY ID
00920             if (arm_tls_check_key(psk_key_id) != 0) {
00921                 return -7;
00922             }
00923         /* fall through */
00924         case NET_TLS_ECC_CIPHER:        /**< Network Authentication support only ECC */
00925 
00926 #ifdef ECC
00927             //Verify Certficate
00928             if (sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) {
00929                 return -6;
00930             }
00931 #endif
00932             break;
00933     }
00934 
00935     cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode;
00936     cur->if_lowpan_security_params->pana_params->psk_key_id = psk_key_id;
00937     cur->if_lowpan_security_params->pana_params->pana_client = 1;
00938     cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION);
00939     cur->configure_flags |= INTERFACE_SECURITY_DEFINED;
00940 
00941     return 0;
00942 }
00943 
00944 nwk_pana_params_s *pana_client_parameter_allocate(void)
00945 {
00946     nwk_pana_params_s *pana_params = ns_dyn_mem_alloc((sizeof(nwk_pana_params_s)));
00947     if (pana_params) {
00948 
00949 #ifdef ECC
00950         pana_params->nwk_chipher_mode = NET_TLS_ECC_CIPHER;
00951 #else
00952         pana_params->nwk_chipher_mode = NET_TLS_PSK_CIPHER;
00953 #endif
00954         pana_params->client_session_mode = NET_PANA_SINGLE_SESSION;
00955         pana_params->psk_key_id = 0;
00956         pana_params->pana_client = 1;
00957     }
00958     return pana_params;
00959 }
00960 
00961 int8_t pana_client_key_pull(int8_t interface_id)
00962 {
00963     protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id);
00964     if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) {
00965         return -1;
00966     }
00967 
00968     sec_suite_t *suite =  sec_suite_selected_py_pan_id(cur->mac_parameters->pan_id);
00969     if (!suite || suite->pana_session.user_server || !suite->pana_session.session_ready || suite->state == PANA_KEY_PULL) {
00970         return -1;
00971     }
00972 
00973     mac_data_poll_enable_check(cur);
00974     sec_lib_state_machine_trig(suite, PANA_KEY_PULL);
00975     return 0;
00976 }
00977 
00978 uint8_t pana_ping_notify_msg_tx(uint16_t pan_id)
00979 {
00980     sec_suite_t *suite =  sec_suite_selected_py_pan_id(pan_id);
00981     if (!suite) {
00982         return 0;
00983     }
00984 
00985     sec_lib_state_machine_trig(suite, PANA_KEY_PULL);
00986     return 1;
00987 }
00988 
00989 static uint8_t pana_ping_notify_msg_generate(uint8_t key_req, sec_suite_t *suite)
00990 {
00991 
00992     if (suite->pana_session.user_server) {
00993         return 0;
00994     }
00995     protocol_interface_info_entry_t *cur = suite->interface;
00996     if (!cur) {
00997         return 0;
00998     }
00999     buffer_t *buf = buffer_get(127);
01000 
01001     if (!buf) {
01002         return 0;
01003     }
01004     uint8_t *ptr;
01005     pana_header_t header;
01006     header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING;
01007     header.type = PANA_MSG_PNA;
01008     header.seq = suite->pana_session.req_seq;
01009     header.session_id = suite->pana_session.session_id;
01010     buf->buf_ptr  = PANA_HEADER_LENGTH;
01011     ptr = buffer_data_pointer(buf);
01012     if (key_req) {
01013         //Add Key Request
01014         tr_debug("Key Request");
01015         ptr = pana_avp_zip_key_req(ptr, cur);
01016     }
01017 
01018     ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr);
01019 
01020     buffer_data_end_set(buf, ptr);
01021     buf = build_pana_base(buf, &header, suite);
01022     if (!buf) {
01023         return 0;
01024     }
01025 
01026     //Calc
01027     //tr_debug("Calc");
01028     pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key);
01029 
01030     if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) {
01031         if (suite->state == PANA_PING_REQ) {
01032             pana_set_agend_address(buf, false, suite);
01033         } else {
01034             if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) {
01035                 pana_set_agend_address(buf, true, suite);
01036             } else {
01037                 pana_set_agend_address(buf, false, suite);
01038             }
01039         }
01040     } else {
01041         pana_set_agend_address(buf, false, suite);
01042     }
01043 
01044 
01045     //                  tr_debug("Hash Cal: %s", trace_array(ptr,16));
01046     if (key_req) {
01047         pana_timeout_timer_set(suite, PANA_KEY_PULL);
01048         tr_debug("Pull Key by Req");
01049     } else {
01050         tr_debug("TX Ping notify");
01051         pana_timeout_timer_set(suite, PANA_PING_REQ);
01052     }
01053     protocol_push(buf);
01054     return 1;
01055 
01056 }
01057 
01058 int8_t pana_client_nvm_callback_set(pana_client_session_update_cb *nvm_update, pana_client_session_get_cb *nvm_get, uint8_t *nvm_static_buffer)
01059 {
01060     if (!nvm_update || !nvm_static_buffer || !nvm_get) {
01061         return -1;
01062     }
01063     pana_client_nvm_storage_cb = nvm_update;
01064     pana_client_session_get = nvm_get;
01065     pana_client_nvm_buffer = nvm_static_buffer;
01066     return 0;
01067 
01068 }
01069 
01070 static void pana_client_session_nvm_udate(sec_suite_t *suite)
01071 {
01072     if (pana_client_nvm_storage_cb) {
01073         uint8_t *data_buf = pana_client_nvm_buffer;
01074         memcpy(data_buf, suite->session_address, 16);
01075         data_buf += 16;
01076         *data_buf++ = suite->pana_session.auth_cnt;
01077         *data_buf++ = suite->pana_session.nwk_key_id;
01078         memcpy(data_buf, suite->pana_session.pana_auth_key, 32);
01079         data_buf += 32;
01080         memcpy(data_buf, suite->pana_session.pana_PAA_enc_key, 16);
01081         data_buf += 16;
01082         data_buf = common_write_32_bit(suite->pana_session.pana_key_id, data_buf);
01083         data_buf = common_write_32_bit(suite->pana_session.session_id, data_buf);
01084         data_buf = common_write_32_bit(suite->pana_session.req_seq, data_buf);
01085         data_buf = common_write_32_bit(suite->pana_session.res_seq, data_buf);
01086         data_buf = common_write_32_bit(suite->pana_session.session_lifetime, data_buf);
01087         pana_client_nvm_storage_cb(suite->pan_id, PANA_CLIENT_SESSION_UPDATE);
01088     }
01089 }
01090 
01091 static void pana_session_data_load_to_session(uint8_t *data_buf, sec_suite_t *suite)
01092 {
01093     suite->timer = 0;
01094     suite->supported_chipher_suites = SEC_DEFAULT_SUPPORTED_CHIPHER_SUITES;
01095     suite->setups = 0;
01096 
01097     pana_session_state_init(&suite->pana_session);
01098 
01099     //Check Is pana Raedy
01100     suite->pana_session.session_ready = true;
01101     //Start Copy
01102     //tr_debug("Set Status");
01103     suite->pana_session.auth_cnt = *data_buf++;
01104     suite->pana_session.nwk_key_id = *data_buf++;
01105     memcpy(suite->pana_session.pana_auth_key, data_buf, 32);
01106     data_buf += 32;
01107     memcpy(suite->pana_session.pana_PAA_enc_key, data_buf, 16);
01108     data_buf += 16;
01109 
01110     suite->pana_session.pana_key_id = common_read_32_bit(data_buf);
01111     data_buf += 4;
01112 
01113     suite->pana_session.session_id = common_read_32_bit(data_buf);
01114     data_buf += 4;
01115 
01116     suite->pana_session.req_seq = common_read_32_bit(data_buf);
01117     data_buf += 4;
01118     suite->pana_session.res_seq = common_read_32_bit(data_buf);
01119     data_buf += 4;
01120     suite->pana_session.session_lifetime = common_read_32_bit(data_buf);
01121 }
01122 
01123 
01124 #else
01125 int8_t pana_client_nvm_callback_set(pana_client_session_update_cb *nvm_update, pana_client_session_get_cb *nvm_get, uint8_t *nvm_static_buffer)
01126 {
01127     (void)nvm_update;
01128     (void)nvm_get;
01129     (void)nvm_static_buffer;
01130     return -1;
01131 }
01132 
01133 #endif
01134