Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
pana_client.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 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/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 suite->timer = 0; 00382 tr_debug("Pana:OK"); 00383 suite->pana_session.session_ready = true; 00384 if (suite->state == PANA_READY) { 00385 pana_client_session_nvm_udate(suite); 00386 } 00387 //Kick ICMP-State Machine to ND / RPL 00388 if (suite->state != PANA_PULL_DONE) { 00389 pana_authentication_ready(1, suite->interface); 00390 } 00391 00392 //Reset pointer 00393 suite->pana_session.auth_info = NULL; 00394 pana_free_dynamic_ram(suite); 00395 sec_suite_tls_free(suite, true); 00396 00397 } 00398 00399 static void pana_pci_build(sec_suite_t *suite) 00400 { 00401 00402 buffer_t *buf = buffer_get(127); 00403 00404 if (!buf) { 00405 tr_debug("Pana Init Fail"); 00406 return; 00407 } 00408 tr_debug("BUILD PCI"); 00409 pana_header_t header; 00410 header.type = PANA_MSG_PCI; 00411 header.flags = 0; 00412 header.seq = 0; 00413 header.session_id = 0; 00414 buf->interface = suite->interface; 00415 pana_set_agend_address(buf, false, suite); 00416 suite->session_port = UDP_PORT_PANA; 00417 buf = build_pana_base(buf, &header, suite); 00418 protocol_push(buf); 00419 } 00420 00421 static void pana_client_pana_error_handler(sec_suite_t *suite) 00422 { 00423 sec_lib_state_machine_lock(suite, PANA_ERROR); 00424 pana_authentication_ready(0, suite->interface); 00425 seclib_session_clean(suite); 00426 } 00427 00428 static void pana_client_state_machine_func(sec_suite_t *suite) 00429 { 00430 if (!suite) { 00431 return; 00432 } 00433 uint8_t general_tx = 0; 00434 00435 00436 switch (suite->state) { 00437 case PANA_ERROR: 00438 pana_client_pana_error_handler(suite); 00439 return; 00440 case PANA_PCI_TX: 00441 if (sec_auth_re_check(suite)) { 00442 pana_pci_build(suite); 00443 pana_timeout_timer_set(suite, suite->state); 00444 } else { 00445 pana_client_pana_error_handler(suite); 00446 } 00447 return; 00448 case PANA_KEY_PULL: 00449 case PANA_PING_REQ: 00450 if (sec_auth_re_check(suite)) { 00451 if (suite->state == PANA_PING_REQ) { 00452 pana_ping_notify_msg_generate(0, suite); 00453 } else { 00454 pana_ping_notify_msg_generate(1, suite); 00455 } 00456 00457 } else { 00458 //Do Pana 00459 if (suite->state == PANA_PING_REQ) { 00460 tr_error("pana nvm failed"); 00461 } 00462 tr_debug("Reset Pana"); 00463 suite->pana_session.session_ready = false; 00464 pana_session_init_by_session_ptr(suite, suite->pana_session.auth_info); 00465 } 00466 break; 00467 00468 case PANA_READY: 00469 case PANA_RE_VALID: 00470 case PANA_PULL_DONE: 00471 sec_auth_ready(suite); 00472 break; 00473 00474 case PRF_CALC: 00475 case PRF_CALC2: 00476 case TLS_ECC_CERTIFICATE_VERIFY_SIGNATURE: 00477 case TLS_ECC_MESSAGE_VERIFY: 00478 case TLS_ECC_CERTIFICATE_SIGNATURE_CHECK: 00479 case TLS_ECC_GENERATE_PUBLIC_KEY: 00480 case TLS_ECC_GENERATE_PREMASTER_SECRET: 00481 case TLS_ECC_SIGNATURE_MESSAGE: 00482 break; 00483 case TLS_HELLO_RX: 00484 case TLS_SERVER_KEY_EXCHANGE_RX: 00485 case TLS_SERVER_WAIT_CHANGE_CHIPHERSUITE: 00486 case TLS_CLIENT_KEY_EXCHANGE_RX: 00487 case TLS_CHANGE_CHIPHER: 00488 tr_debug("%02x", suite->state); 00489 tr_debug("Timeout"); 00490 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00491 general_tx = 1; 00492 break; 00493 00494 #ifdef ECC 00495 case TLS_ECC_GENERATE_PUBLIC_KEY_START: 00496 sec_ecc_gen_public_key_start(suite); 00497 break; 00498 00499 case TLS_ECC_MESSAGE_SERVER_VERIFY_START: 00500 case TLS_ECC_MESSAGE_VERIFY_START: 00501 if (suite->tls_session) { 00502 if (suite->tls_session->tls_heap) { 00503 int start = 0; 00504 tls_heap_t *theap = suite->tls_session->tls_heap; 00505 00506 if (theap->cert_temp_buf) { 00507 if (suite->state == TLS_ECC_MESSAGE_SERVER_VERIFY_START) { 00508 if (theap->signature_temp_buf == 0) { 00509 start = 1; 00510 } 00511 } 00512 } else { 00513 start = 1; 00514 } 00515 if (start) { 00516 tls_server_finnish_handle_start(suite); 00517 } else { 00518 tr_debug("Start Certi Check"); 00519 tls_certificate_signature_verify(suite); 00520 } 00521 } 00522 } 00523 break; 00524 case TLS_ECC_MESSAGE_VERIFY_START2: 00525 tls_ecc_verfify_start(suite); 00526 break; 00527 00528 case TLS_ECC_CLIENT_SIGNATURE_START: 00529 sec_ecc_client_signature_start(suite); 00530 break; 00531 #endif 00532 case TLS_UPDATE_HAS_WITH_CERTIFICATE: 00533 #ifdef ECC 00534 if (sec_auth_re_check(suite)) { 00535 if (tls_certi_hash_copy(suite) == 0) { 00536 tr_warn("Server Certficate Alloc fail"); 00537 suite->timer = 4; 00538 } else { 00539 sec_lib_state_machine_trig(suite, TLS_ECC_CLIENT_SIGNATURE_START); 00540 } 00541 } else 00542 #endif 00543 { 00544 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00545 general_tx = 1; 00546 } 00547 break; 00548 00549 case TLS_CLIENT_TX_CERTIFICATE_VERIFY: 00550 #ifdef ECC 00551 if (sec_auth_re_check(suite)) { 00552 if (tls_certificate_build(suite) == 0) { 00553 tr_warn("Client Certi Verify Alloc fail"); 00554 suite->timer = 4; 00555 } else { 00556 sec_set_auth_timeout(suite, TLS_CLIENT_TX_CERTIFICATE_VERIFY); 00557 } 00558 } else 00559 #endif 00560 { 00561 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00562 general_tx = 1; 00563 } 00564 break; 00565 00566 default: 00567 general_tx = 1; 00568 break; 00569 } 00570 00571 if (general_tx) { 00572 if (sec_auth_re_check(suite)) { 00573 buffer_t *buf = buffer_get(140); 00574 if (buf) { 00575 buf->interface = suite->interface; 00576 suite->timer = 600; 00577 switch (suite->state) { 00578 case PANA_START_RESPONSE: 00579 pana_start_message_build(buf, suite); 00580 break; 00581 00582 case EAP_IDENTITY_RES: 00583 pana_eap_identity_build(buf, suite); 00584 break; 00585 00586 case TLS_INIT: 00587 buf = tls_client_hello_build(buf, suite); 00588 if (buf) { 00589 pana_eap_down(buf, suite); 00590 } 00591 sec_set_auth_timeout(suite, TLS_INIT); 00592 break; 00593 00594 case TLS_KEY_CHANGE: 00595 //Print Handshake message 00596 tls_prepare_change_chipher_spec(suite); 00597 tls_build_client_change_chipher_suite_finnish(buf, suite); 00598 pana_eap_down(buf, suite); 00599 break; 00600 00601 case PANA_FAILURE: 00602 buf->buf_ptr = PANA_HEADER_LENGTH; 00603 buf->buf_end = PANA_HEADER_LENGTH; 00604 pana_down(buf, suite); 00605 break; 00606 00607 case TLS_FINISH: 00608 case TLS_ALERT: 00609 eap_fragmentation_init(suite); 00610 pana_eap_tls_finnish_build(buf, suite); 00611 break; 00612 00613 00614 case TLS_ALERT_CLOSE_FATAL: 00615 case TLS_ALERT_INTERNAL: 00616 case TLS_ALERT_CHIPHER_SUITE: 00617 case TLS_ALERT_DECRYPT: 00618 case TLS_ALERT_BAD_CERTIFICATE: 00619 00620 eap_fragmentation_init(suite); 00621 00622 suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY); 00623 #ifdef ECC 00624 { 00625 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00626 if (tls_heap) { 00627 tls_ecc_heap_free(tls_heap); 00628 } 00629 } 00630 #endif 00631 if (suite->state == TLS_ALERT_DECRYPT) { 00632 tls_alert_build(buf, ALERT_BAD_RECORD); 00633 } else if (suite->state == TLS_ALERT_CLOSE_FATAL) { 00634 tls_alert_build(buf, ALERT_INTERNAL_ERR); 00635 } else if (suite->state == TLS_ALERT_BAD_CERTIFICATE) { 00636 00637 tls_alert_build(buf, ALERT_BAD_CERTIFICATE); 00638 } else { 00639 tls_alert_build(buf, ALERT_INTERNAL_ERR); 00640 00641 } 00642 pana_eap_down(buf, suite); 00643 break; 00644 00645 00646 default: 00647 tr_debug("Unknown Packet. State: %x", suite->state); 00648 buf = buffer_free(buf); 00649 break; 00650 } 00651 00652 } else { 00653 suite->timer = 2; 00654 } 00655 } else { 00656 tr_debug("Tls Auth Re TX limit Reached. State: %x", suite->state); 00657 00658 switch (suite->state) { 00659 case TLS_KEY_CHANGE: 00660 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00661 break; 00662 case TLS_INIT: //Trig pana failure if not get any response from server 00663 sec_lib_state_machine_trig(suite, PANA_FAILURE); 00664 break; 00665 00666 default: 00667 pana_client_pana_error_handler(suite); 00668 break; 00669 } 00670 } 00671 } 00672 } 00673 00674 static void pana_client_packet_handler(buffer_t *buf) 00675 { 00676 pana_header_t header; 00677 if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) { 00678 buffer_free(buf); 00679 return; 00680 } 00681 buffer_data_strip_header(buf, PANA_HEADER_LENGTH); 00682 00683 sec_suite_t *suite = sec_suite_selected_py_pan_id(buf->link_specific.ieee802_15_4.srcPanId); 00684 if (!suite) { 00685 buffer_free(buf); 00686 return; 00687 } 00688 00689 header.agent_retry = false; 00690 //Handle Relay 00691 if (header.type == PANA_MSG_RELAY) { 00692 if (suite->pana_session.session_ready ) { 00693 buf = pana_relay_parse(buf); 00694 } 00695 if (buf) { 00696 protocol_interface_info_entry_t *cur_interface = buf->interface ; 00697 addr_interface_get_ll_address(cur_interface, buf->src_sa .address , 0); 00698 buf->src_sa .addr_type = ADDR_IPV6 ; 00699 buf->src_sa .port = UDP_PORT_PANA; 00700 buf = buffer_turnaround(buf); 00701 buf->info = (buffer_info_t)(B_DIR_DOWN + B_FROM_APP + B_TO_UDP); 00702 protocol_push(buf); 00703 buf = NULL; 00704 } 00705 return; 00706 } 00707 00708 bool my_session = false; 00709 if (header.type != PANA_MSG_PCI) { 00710 if ((header.flags & PANA_FLAG_START_REQ_MASK) == (PANA_FLAG_START_REQ_MASK)) { 00711 if (memcmp(suite->session_address, buf->src_sa .address , 16) == 0) { 00712 my_session = true; 00713 } 00714 } else { 00715 //Check Session 00716 if (suite->pana_session.session_id == header.session_id) { 00717 //Validate Session 00718 if ((memcmp(suite->session_address, buf->src_sa .address , 16) == 0)) { 00719 my_session = true; 00720 } else if (memcmp(suite->pana_session.session_relay_address, buf->src_sa .address , 16) == 0) { 00721 my_session = true; 00722 } 00723 00724 } 00725 00726 if (!my_session) { 00727 if (buf->src_sa .address [0] != 0xfe) { 00728 tr_debug("Not relay src"); 00729 buffer_free(buf); 00730 return; 00731 } 00732 } 00733 } 00734 } 00735 00736 if (my_session) { 00737 if ((header.flags & PANA_FLAG_START_REQ_MASK) == (PANA_FLAG_START_REQ_MASK)) { 00738 tr_debug("Take session & Sequency"); 00739 suite->pana_session.session_id = header.session_id; 00740 suite->pana_session.res_seq = header.seq; 00741 pana_session_startms_parse(buf, &header, suite); 00742 return; 00743 } 00744 00745 if (suite->pana_session.pana_heap) { 00746 pana_heap_t *pheap = suite->pana_session.pana_heap; 00747 if (pheap->handshake_len == 0 || pheap->handshake_req_offset == pheap->handshake_len) { 00748 tr_debug("Pana REQ dropped because Handshake is not full started"); 00749 buffer_free(buf); 00750 return; 00751 } 00752 } 00753 00754 if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00755 if (suite->pana_session.req_seq == header.seq) { 00756 suite->pana_session.req_seq++; 00757 } else { 00758 tr_debug("Pana RES:Drop Packet by seq num. Res: %02"PRIu32", RX: %02"PRIu32, suite->pana_session.req_seq >> 8, header.seq); 00759 buffer_free(buf); 00760 return; 00761 } 00762 } else { 00763 if ((suite->pana_session.res_seq + 1) == header.seq) { 00764 suite->pana_session.res_seq = header.seq; 00765 00766 } else { 00767 if (suite->pana_session.res_seq != header.seq) { 00768 tr_debug("PANA REQ:Drop Packet by seq num. Res: %02"PRIu32" , RX: %02"PRIu32, suite->pana_session.res_seq >> 8, header.seq); 00769 buffer_free(buf); 00770 return; 00771 } else { 00772 header.agent_retry = true; 00773 } 00774 } 00775 } 00776 if (header.flags & PANA_FLAGS_COMPLETE) { 00777 pana_complete_msg_parse(buf, &header, suite); 00778 00779 } else { 00780 00781 if (header.type == PANA_MSG_PNA) { 00782 pana_client_pna_handler(buf, &header, suite); 00783 return; 00784 } 00785 00786 if (header.type != PANA_MSG_PA) { 00787 return; 00788 } 00789 00790 buf = pana_auth_message_handler(buf, &header, suite); 00791 00792 if (buf) { 00793 pana_eap_tls_up(buf, suite); 00794 } 00795 } 00796 return; 00797 00798 } 00799 00800 //Relay 00801 00802 if ((suite->pana_session.session_ready) && pana_check_address(buf)) { 00803 00804 if (header.type == PANA_MSG_PNA || header.type == PANA_MSG_PCI) { 00805 //Remove old data 00806 if (lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address ) ) { 00807 uint8_t ll_adr[16]; 00808 memcpy(ll_adr, buf->src_sa .address , 16); 00809 buffer_free(buf); 00810 tr_debug("Parent rejoin --> send unsecured Link Reject"); 00811 mle_service_reject_message_build(suite->interface->id, ll_adr, true); 00812 return; 00813 } 00814 } 00815 00816 buffer_data_reserve_header(buf, 16); 00817 buf = pana_relay_avp_build(buf, suite); 00818 if (buf) { 00819 //Set Pana Headers Like Draft say 00820 tr_debug("Pana Relay"); 00821 header.flags = 0; 00822 header.type = PANA_MSG_RELAY; 00823 header.session_id = 0; 00824 header.seq = 0; 00825 pana_set_agend_address(buf, true, suite); 00826 buf = build_pana_base(buf, &header, suite); 00827 protocol_push(buf); 00828 buf = NULL; 00829 } else { 00830 tr_debug("Relay AVP Build Fail"); 00831 } 00832 } 00833 00834 00835 if (buf) { 00836 buffer_free(buf); 00837 } 00838 return; 00839 } 00840 00841 sec_suite_t *pana_client_init(auth_info_t *auth_ptr, uint8_t *session_address_ptr, pana_tls_setup_s *setup) 00842 { 00843 sec_suite_t *suite = sec_suite_selected_py_pan_id(setup->pan_id); 00844 00845 if (!suite) { 00846 00847 bool loaded_setup = false; 00848 if (pana_client_nvm_storage_cb) { 00849 loaded_setup = pana_client_session_get(setup->pan_id); 00850 if (loaded_setup) { 00851 tr_debug("load pana nvm for PAN ID %2.2x", setup->pan_id); 00852 suite = sec_lib_security_session_allocate(false); 00853 } else { 00854 tr_debug("nvm pana load fail for PAN ID %2.2x", setup->pan_id); 00855 suite = sec_lib_security_session_allocate(true); 00856 } 00857 } else { 00858 suite = sec_lib_security_session_allocate(true); 00859 } 00860 if (!suite) { 00861 return NULL; 00862 } 00863 if (loaded_setup) { 00864 pana_session_data_load_to_session(pana_client_nvm_buffer + 16, suite); 00865 } 00866 suite->pan_id = setup->pan_id; 00867 00868 tr_debug("Create Entry"); 00869 memcpy(suite->session_address, session_address_ptr, 16); 00870 tr_debug("Session adr: %s", tr_ipv6(suite->session_address)); 00871 } 00872 00873 if (suite) { 00874 pana_session_init_by_session_ptr(suite, auth_ptr); 00875 suite->supported_chipher_suites = setup->security_support; 00876 suite->psk_key_id = setup->psk_key_id; 00877 } 00878 return suite; 00879 } 00880 00881 void pana_reset_client_session(void) 00882 { 00883 sec_suite_list_clean(); 00884 } 00885 00886 int8_t pana_client_interface_init(int8_t interface_id, net_tls_cipher_e cipher_mode, uint32_t psk_key_id) 00887 { 00888 protocol_interface_info_entry_t *cur = 0; 00889 cur = protocol_stack_interface_info_get_by_id(interface_id); 00890 if (!cur) { 00891 return -1; 00892 } 00893 00894 if (!cur->if_lowpan_security_params) { 00895 return -1; 00896 } else if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00897 return -4; 00898 } else if (cur->if_lowpan_security_params->pana_params == 0) { 00899 return -3; 00900 } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) { 00901 return -5; 00902 } 00903 00904 if (!pana_socket_init(pana_client_packet_handler, pana_client_state_machine_func, tls_client_up)) { 00905 return -1; 00906 } 00907 00908 switch (cipher_mode) { 00909 00910 case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */ 00911 //Verify PSK KEY ID 00912 if (arm_tls_check_key(psk_key_id) != 0) { 00913 return -7; 00914 } 00915 break; 00916 00917 case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */ 00918 //Verify PSK KEY ID 00919 if (arm_tls_check_key(psk_key_id) != 0) { 00920 return -7; 00921 } 00922 /* fall through */ 00923 case NET_TLS_ECC_CIPHER: /**< Network Authentication support only ECC */ 00924 00925 #ifdef ECC 00926 //Verify Certficate 00927 if(sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) { 00928 return -6; 00929 } 00930 #endif 00931 break; 00932 } 00933 00934 cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode; 00935 cur->if_lowpan_security_params->pana_params->psk_key_id = psk_key_id; 00936 cur->if_lowpan_security_params->pana_params->pana_client = 1; 00937 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 00938 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 00939 00940 return 0; 00941 } 00942 00943 nwk_pana_params_s * pana_client_parameter_allocate(void) 00944 { 00945 nwk_pana_params_s *pana_params = ns_dyn_mem_alloc((sizeof(nwk_pana_params_s))); 00946 if (pana_params) { 00947 00948 #ifdef ECC 00949 pana_params->nwk_chipher_mode = NET_TLS_ECC_CIPHER; 00950 #else 00951 pana_params->nwk_chipher_mode = NET_TLS_PSK_CIPHER; 00952 #endif 00953 pana_params->client_session_mode = NET_PANA_SINGLE_SESSION; 00954 pana_params->psk_key_id = 0; 00955 pana_params->pana_client = 1; 00956 } 00957 return pana_params; 00958 } 00959 00960 int8_t pana_client_key_pull(int8_t interface_id) 00961 { 00962 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00963 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 00964 return -1; 00965 } 00966 00967 sec_suite_t *suite = sec_suite_selected_py_pan_id(cur->mac_parameters->pan_id); 00968 if (!suite || suite->pana_session.user_server || !suite->pana_session.session_ready || suite->state == PANA_KEY_PULL) { 00969 return -1; 00970 } 00971 00972 mac_data_poll_enable_check(cur); 00973 sec_lib_state_machine_trig(suite, PANA_KEY_PULL); 00974 return 0; 00975 } 00976 00977 uint8_t pana_ping_notify_msg_tx(uint16_t pan_id) 00978 { 00979 sec_suite_t *suite = sec_suite_selected_py_pan_id(pan_id); 00980 if (!suite) { 00981 return 0; 00982 } 00983 00984 sec_lib_state_machine_trig(suite, PANA_KEY_PULL); 00985 return 1; 00986 } 00987 00988 static uint8_t pana_ping_notify_msg_generate(uint8_t key_req, sec_suite_t *suite) 00989 { 00990 00991 if (suite->pana_session.user_server) { 00992 return 0; 00993 } 00994 protocol_interface_info_entry_t *cur = suite->interface; 00995 if (!cur) { 00996 return 0; 00997 } 00998 buffer_t *buf = buffer_get(127); 00999 01000 if (!buf) { 01001 return 0; 01002 } 01003 uint8_t *ptr; 01004 pana_header_t header; 01005 header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING; 01006 header.type = PANA_MSG_PNA; 01007 header.seq = suite->pana_session.req_seq; 01008 header.session_id = suite->pana_session.session_id; 01009 buf->buf_ptr = PANA_HEADER_LENGTH; 01010 ptr = buffer_data_pointer(buf); 01011 if (key_req) { 01012 //Add Key Request 01013 tr_debug("Key Request"); 01014 ptr = pana_avp_zip_key_req(ptr, cur); 01015 } 01016 01017 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 01018 01019 buffer_data_end_set(buf, ptr); 01020 buf = build_pana_base(buf, &header, suite); 01021 if (!buf) { 01022 return 0; 01023 } 01024 01025 //Calc 01026 //tr_debug("Calc"); 01027 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 01028 01029 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01030 if (suite->state == PANA_PING_REQ) { 01031 pana_set_agend_address(buf, false, suite); 01032 } else { 01033 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) { 01034 pana_set_agend_address(buf, true, suite); 01035 } else { 01036 pana_set_agend_address(buf, false, suite); 01037 } 01038 } 01039 } else { 01040 pana_set_agend_address(buf, false, suite); 01041 } 01042 01043 01044 // tr_debug("Hash Cal: %s", trace_array(ptr,16)); 01045 if (key_req) { 01046 pana_timeout_timer_set(suite, PANA_KEY_PULL); 01047 tr_debug("Pull Key by Req"); 01048 } else { 01049 tr_debug("TX Ping notify"); 01050 pana_timeout_timer_set(suite, PANA_PING_REQ); 01051 } 01052 protocol_push(buf); 01053 return 1; 01054 01055 } 01056 01057 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) 01058 { 01059 if (!nvm_update || !nvm_static_buffer || !nvm_get) { 01060 return -1; 01061 } 01062 pana_client_nvm_storage_cb = nvm_update; 01063 pana_client_session_get = nvm_get; 01064 pana_client_nvm_buffer = nvm_static_buffer; 01065 return 0; 01066 01067 } 01068 01069 static void pana_client_session_nvm_udate(sec_suite_t *suite) 01070 { 01071 if (pana_client_nvm_storage_cb) { 01072 uint8_t *data_buf = pana_client_nvm_buffer; 01073 memcpy(data_buf, suite->session_address, 16); 01074 data_buf += 16; 01075 *data_buf++ = suite->pana_session.auth_cnt; 01076 *data_buf++ = suite->pana_session.nwk_key_id; 01077 memcpy(data_buf, suite->pana_session.pana_auth_key, 32); 01078 data_buf += 32; 01079 memcpy(data_buf, suite->pana_session.pana_PAA_enc_key, 16); 01080 data_buf += 16; 01081 data_buf = common_write_32_bit(suite->pana_session.pana_key_id, data_buf); 01082 data_buf = common_write_32_bit(suite->pana_session.session_id, data_buf); 01083 data_buf = common_write_32_bit(suite->pana_session.req_seq, data_buf); 01084 data_buf = common_write_32_bit(suite->pana_session.res_seq, data_buf); 01085 data_buf = common_write_32_bit(suite->pana_session.session_lifetime, data_buf); 01086 pana_client_nvm_storage_cb(suite->pan_id, PANA_CLIENT_SESSION_UPDATE); 01087 } 01088 } 01089 01090 static void pana_session_data_load_to_session(uint8_t *data_buf, sec_suite_t *suite) 01091 { 01092 suite->timer = 0; 01093 suite->supported_chipher_suites = SEC_DEFAULT_SUPPORTED_CHIPHER_SUITES; 01094 suite->setups = 0; 01095 01096 pana_session_state_init(&suite->pana_session); 01097 01098 //Check Is pana Raedy 01099 suite->pana_session.session_ready = true; 01100 //Start Copy 01101 //tr_debug("Set Status"); 01102 suite->pana_session.auth_cnt = *data_buf++; 01103 suite->pana_session.nwk_key_id = *data_buf++; 01104 memcpy(suite->pana_session.pana_auth_key, data_buf, 32); 01105 data_buf += 32; 01106 memcpy(suite->pana_session.pana_PAA_enc_key, data_buf, 16); 01107 data_buf += 16; 01108 01109 suite->pana_session.pana_key_id = common_read_32_bit(data_buf); 01110 data_buf += 4; 01111 01112 suite->pana_session.session_id = common_read_32_bit(data_buf); 01113 data_buf += 4; 01114 01115 suite->pana_session.req_seq = common_read_32_bit(data_buf); 01116 data_buf += 4; 01117 suite->pana_session.res_seq = common_read_32_bit(data_buf); 01118 data_buf += 4; 01119 suite->pana_session.session_lifetime = common_read_32_bit(data_buf); 01120 } 01121 01122 01123 #else 01124 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) 01125 { 01126 (void)nvm_update; 01127 (void)nvm_get; 01128 (void)nvm_static_buffer; 01129 return -1; 01130 } 01131 01132 #endif 01133
Generated on Fri Jul 22 2022 04:53:58 by
1.7.2
