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.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
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 case TLS_INIT: 00661 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00662 break; 00663 00664 default: 00665 pana_client_pana_error_handler(suite); 00666 break; 00667 } 00668 } 00669 } 00670 } 00671 00672 static void pana_client_packet_handler(buffer_t *buf) 00673 { 00674 pana_header_t header; 00675 if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) { 00676 buffer_free(buf); 00677 return; 00678 } 00679 buffer_data_strip_header(buf, PANA_HEADER_LENGTH); 00680 00681 sec_suite_t *suite = sec_suite_selected_py_pan_id(buf->link_specific.ieee802_15_4.srcPanId); 00682 if (!suite) { 00683 buffer_free(buf); 00684 return; 00685 } 00686 00687 header.agent_retry = false; 00688 //Handle Relay 00689 if (header.type == PANA_MSG_RELAY) { 00690 if (suite->pana_session.session_ready ) { 00691 buf = pana_relay_parse(buf); 00692 } 00693 if (buf) { 00694 protocol_interface_info_entry_t *cur_interface = buf->interface ; 00695 addr_interface_get_ll_address(cur_interface, buf->src_sa .address , 0); 00696 buf->src_sa .addr_type = ADDR_IPV6 ; 00697 buf->src_sa .port = UDP_PORT_PANA; 00698 buf = buffer_turnaround(buf); 00699 buf->info = (buffer_info_t)(B_DIR_DOWN + B_FROM_APP + B_TO_UDP); 00700 protocol_push(buf); 00701 buf = NULL; 00702 } 00703 return; 00704 } 00705 00706 bool my_session = false; 00707 if (header.type != PANA_MSG_PCI) { 00708 if ((header.flags & PANA_FLAG_START_REQ_MASK) == (PANA_FLAG_START_REQ_MASK)) { 00709 if (memcmp(suite->session_address, buf->src_sa .address , 16) == 0) { 00710 my_session = true; 00711 } 00712 } else { 00713 //Check Session 00714 if (suite->pana_session.session_id == header.session_id) { 00715 //Validate Session 00716 if ((memcmp(suite->session_address, buf->src_sa .address , 16) == 0)) { 00717 my_session = true; 00718 } else if (memcmp(suite->pana_session.session_relay_address, buf->src_sa .address , 16) == 0) { 00719 my_session = true; 00720 } 00721 00722 } 00723 00724 if (!my_session) { 00725 if (buf->src_sa .address [0] != 0xfe) { 00726 tr_debug("Not relay src"); 00727 buffer_free(buf); 00728 return; 00729 } 00730 } 00731 } 00732 } 00733 00734 if (my_session) { 00735 if ((header.flags & PANA_FLAG_START_REQ_MASK) == (PANA_FLAG_START_REQ_MASK)) { 00736 tr_debug("Take session & Sequency"); 00737 suite->pana_session.session_id = header.session_id; 00738 suite->pana_session.res_seq = header.seq; 00739 pana_session_startms_parse(buf, &header, suite); 00740 return; 00741 } 00742 00743 if (suite->pana_session.pana_heap) { 00744 pana_heap_t *pheap = suite->pana_session.pana_heap; 00745 if (pheap->handshake_len == 0 || pheap->handshake_req_offset == pheap->handshake_len) { 00746 tr_debug("Pana REQ dropped because Handshake is not full started"); 00747 buffer_free(buf); 00748 return; 00749 } 00750 } 00751 00752 if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00753 if (suite->pana_session.req_seq == header.seq) { 00754 suite->pana_session.req_seq++; 00755 } else { 00756 tr_debug("Pana RES:Drop Packet by seq num. Res: %02"PRIu32", RX: %02"PRIu32, suite->pana_session.req_seq >> 8, header.seq); 00757 buffer_free(buf); 00758 return; 00759 } 00760 } else { 00761 if ((suite->pana_session.res_seq + 1) == header.seq) { 00762 suite->pana_session.res_seq = header.seq; 00763 00764 } else { 00765 if (suite->pana_session.res_seq != header.seq) { 00766 tr_debug("PANA REQ:Drop Packet by seq num. Res: %02"PRIu32" , RX: %02"PRIu32, suite->pana_session.res_seq >> 8, header.seq); 00767 buffer_free(buf); 00768 return; 00769 } else { 00770 header.agent_retry = true; 00771 } 00772 } 00773 } 00774 if (header.flags & PANA_FLAGS_COMPLETE) { 00775 pana_complete_msg_parse(buf, &header, suite); 00776 00777 } else { 00778 00779 if (header.type == PANA_MSG_PNA) { 00780 pana_client_pna_handler(buf, &header, suite); 00781 return; 00782 } 00783 00784 if (header.type != PANA_MSG_PA) { 00785 return; 00786 } 00787 00788 buf = pana_auth_message_handler(buf, &header, suite); 00789 00790 if (buf) { 00791 pana_eap_tls_up(buf, suite); 00792 } 00793 } 00794 return; 00795 00796 } 00797 00798 //Relay 00799 00800 if ((suite->pana_session.session_ready) && pana_check_address(buf)) { 00801 00802 if (header.type == PANA_MSG_PNA || header.type == PANA_MSG_PCI) { 00803 //Remove old data 00804 if (lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address ) ) { 00805 uint8_t ll_adr[16]; 00806 memcpy(ll_adr, buf->src_sa .address , 16); 00807 buffer_free(buf); 00808 tr_debug("Parent rejoin --> send unsecured Link Reject"); 00809 mle_service_reject_message_build(suite->interface->id, ll_adr, true); 00810 return; 00811 } 00812 } 00813 00814 buffer_data_reserve_header(buf, 16); 00815 buf = pana_relay_avp_build(buf, suite); 00816 if (buf) { 00817 //Set Pana Headers Like Draft say 00818 tr_debug("Pana Relay"); 00819 header.flags = 0; 00820 header.type = PANA_MSG_RELAY; 00821 header.session_id = 0; 00822 header.seq = 0; 00823 pana_set_agend_address(buf, true, suite); 00824 buf = build_pana_base(buf, &header, suite); 00825 protocol_push(buf); 00826 buf = NULL; 00827 } else { 00828 tr_debug("Relay AVP Build Fail"); 00829 } 00830 } 00831 00832 00833 if (buf) { 00834 buffer_free(buf); 00835 } 00836 return; 00837 } 00838 00839 sec_suite_t *pana_client_init(auth_info_t *auth_ptr, uint8_t *session_address_ptr, pana_tls_setup_s *setup) 00840 { 00841 sec_suite_t *suite = sec_suite_selected_py_pan_id(setup->pan_id); 00842 00843 if (!suite) { 00844 00845 bool loaded_setup = false; 00846 if (pana_client_nvm_storage_cb) { 00847 loaded_setup = pana_client_session_get(setup->pan_id); 00848 if (loaded_setup) { 00849 tr_debug("load pana nvm for PAN ID %2.2x", setup->pan_id); 00850 suite = sec_lib_security_session_allocate(false); 00851 } else { 00852 tr_debug("nvm pana load fail for PAN ID %2.2x", setup->pan_id); 00853 suite = sec_lib_security_session_allocate(true); 00854 } 00855 } else { 00856 suite = sec_lib_security_session_allocate(true); 00857 } 00858 if (!suite) { 00859 return NULL; 00860 } 00861 if (loaded_setup) { 00862 pana_session_data_load_to_session(pana_client_nvm_buffer + 16, suite); 00863 } 00864 suite->pan_id = setup->pan_id; 00865 00866 tr_debug("Create Entry"); 00867 memcpy(suite->session_address, session_address_ptr, 16); 00868 tr_debug("Session adr: %s", tr_ipv6(suite->session_address)); 00869 } 00870 00871 if (suite) { 00872 pana_session_init_by_session_ptr(suite, auth_ptr); 00873 suite->supported_chipher_suites = setup->security_support; 00874 suite->psk_key_id = setup->psk_key_id; 00875 } 00876 return suite; 00877 } 00878 00879 void pana_reset_client_session(void) 00880 { 00881 sec_suite_list_clean(); 00882 } 00883 00884 int8_t pana_client_interface_init(int8_t interface_id, net_tls_cipher_e cipher_mode, uint32_t psk_key_id) 00885 { 00886 protocol_interface_info_entry_t *cur = 0; 00887 cur = protocol_stack_interface_info_get_by_id(interface_id); 00888 if (!cur) { 00889 return -1; 00890 } 00891 00892 if (!cur->if_lowpan_security_params) { 00893 return -1; 00894 } else if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 00895 return -4; 00896 } else if (cur->if_lowpan_security_params->pana_params == 0) { 00897 return -3; 00898 } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) { 00899 return -5; 00900 } 00901 00902 if (!pana_socket_init(pana_client_packet_handler, pana_client_state_machine_func, tls_client_up)) { 00903 return -1; 00904 } 00905 00906 switch (cipher_mode) { 00907 00908 case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */ 00909 //Verify PSK KEY ID 00910 if (arm_tls_check_key(psk_key_id) != 0) { 00911 return -7; 00912 } 00913 break; 00914 00915 case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */ 00916 //Verify PSK KEY ID 00917 if (arm_tls_check_key(psk_key_id) != 0) { 00918 return -7; 00919 } 00920 /* fall through */ 00921 case NET_TLS_ECC_CIPHER: /**< Network Authentication support only ECC */ 00922 00923 #ifdef ECC 00924 //Verify Certficate 00925 if(sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) { 00926 return -6; 00927 } 00928 #endif 00929 break; 00930 } 00931 00932 cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode; 00933 cur->if_lowpan_security_params->pana_params->psk_key_id = psk_key_id; 00934 cur->if_lowpan_security_params->pana_params->pana_client = 1; 00935 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 00936 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 00937 00938 return 0; 00939 } 00940 00941 nwk_pana_params_s * pana_client_parameter_allocate(void) 00942 { 00943 nwk_pana_params_s *pana_params = ns_dyn_mem_alloc((sizeof(nwk_pana_params_s))); 00944 if (pana_params) { 00945 00946 #ifdef ECC 00947 pana_params->nwk_chipher_mode = NET_TLS_ECC_CIPHER; 00948 #else 00949 pana_params->nwk_chipher_mode = NET_TLS_PSK_CIPHER; 00950 #endif 00951 pana_params->client_session_mode = NET_PANA_SINGLE_SESSION; 00952 pana_params->psk_key_id = 0; 00953 pana_params->pana_client = 1; 00954 } 00955 return pana_params; 00956 } 00957 00958 int8_t pana_client_key_pull(int8_t interface_id) 00959 { 00960 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 00961 if (!cur || !(cur->lowpan_info & INTERFACE_NWK_ACTIVE)) { 00962 return -1; 00963 } 00964 00965 sec_suite_t *suite = sec_suite_selected_py_pan_id(cur->mac_parameters->pan_id); 00966 if (!suite || suite->pana_session.user_server || !suite->pana_session.session_ready || suite->state == PANA_KEY_PULL) { 00967 return -1; 00968 } 00969 00970 mac_data_poll_enable_check(cur); 00971 sec_lib_state_machine_trig(suite, PANA_KEY_PULL); 00972 return 0; 00973 } 00974 00975 uint8_t pana_ping_notify_msg_tx(uint16_t pan_id) 00976 { 00977 sec_suite_t *suite = sec_suite_selected_py_pan_id(pan_id); 00978 if (!suite) { 00979 return 0; 00980 } 00981 00982 sec_lib_state_machine_trig(suite, PANA_KEY_PULL); 00983 return 1; 00984 } 00985 00986 static uint8_t pana_ping_notify_msg_generate(uint8_t key_req, sec_suite_t *suite) 00987 { 00988 00989 if (suite->pana_session.user_server) { 00990 return 0; 00991 } 00992 protocol_interface_info_entry_t *cur = suite->interface; 00993 if (!cur) { 00994 return 0; 00995 } 00996 buffer_t *buf = buffer_get(127); 00997 00998 if (!buf) { 00999 return 0; 01000 } 01001 uint8_t *ptr; 01002 pana_header_t header; 01003 header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING; 01004 header.type = PANA_MSG_PNA; 01005 header.seq = suite->pana_session.req_seq; 01006 header.session_id = suite->pana_session.session_id; 01007 buf->buf_ptr = PANA_HEADER_LENGTH; 01008 ptr = buffer_data_pointer(buf); 01009 if (key_req) { 01010 //Add Key Request 01011 tr_debug("Key Request"); 01012 ptr = pana_avp_zip_key_req(ptr, cur); 01013 } 01014 01015 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 01016 01017 buffer_data_end_set(buf, ptr); 01018 buf = build_pana_base(buf, &header, suite); 01019 if (!buf) { 01020 return 0; 01021 } 01022 01023 //Calc 01024 //tr_debug("Calc"); 01025 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 01026 01027 if (cur->lowpan_info & INTERFACE_NWK_ROUTER_DEVICE) { 01028 if (suite->state == PANA_PING_REQ) { 01029 pana_set_agend_address(buf, false, suite); 01030 } else { 01031 if ((cur->lowpan_info & INTERFACE_NWK_BOOTSRAP_ADDRESS_REGISTER_READY)) { 01032 pana_set_agend_address(buf, true, suite); 01033 } else { 01034 pana_set_agend_address(buf, false, suite); 01035 } 01036 } 01037 } else { 01038 pana_set_agend_address(buf, false, suite); 01039 } 01040 01041 01042 // tr_debug("Hash Cal: %s", trace_array(ptr,16)); 01043 if (key_req) { 01044 pana_timeout_timer_set(suite, PANA_KEY_PULL); 01045 tr_debug("Pull Key by Req"); 01046 } else { 01047 tr_debug("TX Ping notify"); 01048 pana_timeout_timer_set(suite, PANA_PING_REQ); 01049 } 01050 protocol_push(buf); 01051 return 1; 01052 01053 } 01054 01055 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) 01056 { 01057 if (!nvm_update || !nvm_static_buffer || !nvm_get) { 01058 return -1; 01059 } 01060 pana_client_nvm_storage_cb = nvm_update; 01061 pana_client_session_get = nvm_get; 01062 pana_client_nvm_buffer = nvm_static_buffer; 01063 return 0; 01064 01065 } 01066 01067 static void pana_client_session_nvm_udate(sec_suite_t *suite) 01068 { 01069 if (pana_client_nvm_storage_cb) { 01070 uint8_t *data_buf = pana_client_nvm_buffer; 01071 memcpy(data_buf, suite->session_address, 16); 01072 data_buf += 16; 01073 *data_buf++ = suite->pana_session.auth_cnt; 01074 *data_buf++ = suite->pana_session.nwk_key_id; 01075 memcpy(data_buf, suite->pana_session.pana_auth_key, 32); 01076 data_buf += 32; 01077 memcpy(data_buf, suite->pana_session.pana_PAA_enc_key, 16); 01078 data_buf += 16; 01079 data_buf = common_write_32_bit(suite->pana_session.pana_key_id, data_buf); 01080 data_buf = common_write_32_bit(suite->pana_session.session_id, data_buf); 01081 data_buf = common_write_32_bit(suite->pana_session.req_seq, data_buf); 01082 data_buf = common_write_32_bit(suite->pana_session.res_seq, data_buf); 01083 data_buf = common_write_32_bit(suite->pana_session.session_lifetime, data_buf); 01084 pana_client_nvm_storage_cb(suite->pan_id, PANA_CLIENT_SESSION_UPDATE); 01085 } 01086 } 01087 01088 static void pana_session_data_load_to_session(uint8_t *data_buf, sec_suite_t *suite) 01089 { 01090 suite->timer = 0; 01091 suite->supported_chipher_suites = SEC_DEFAULT_SUPPORTED_CHIPHER_SUITES; 01092 suite->setups = 0; 01093 01094 pana_session_state_init(&suite->pana_session); 01095 01096 //Check Is pana Raedy 01097 suite->pana_session.session_ready = true; 01098 //Start Copy 01099 //tr_debug("Set Status"); 01100 suite->pana_session.auth_cnt = *data_buf++; 01101 suite->pana_session.nwk_key_id = *data_buf++; 01102 memcpy(suite->pana_session.pana_auth_key, data_buf, 32); 01103 data_buf += 32; 01104 memcpy(suite->pana_session.pana_PAA_enc_key, data_buf, 16); 01105 data_buf += 16; 01106 01107 suite->pana_session.pana_key_id = common_read_32_bit(data_buf); 01108 data_buf += 4; 01109 01110 suite->pana_session.session_id = common_read_32_bit(data_buf); 01111 data_buf += 4; 01112 01113 suite->pana_session.req_seq = common_read_32_bit(data_buf); 01114 data_buf += 4; 01115 suite->pana_session.res_seq = common_read_32_bit(data_buf); 01116 data_buf += 4; 01117 suite->pana_session.session_lifetime = common_read_32_bit(data_buf); 01118 } 01119 01120 01121 #else 01122 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) 01123 { 01124 (void)nvm_update; 01125 (void)nvm_get; 01126 (void)nvm_static_buffer; 01127 return -1; 01128 } 01129 01130 #endif 01131
Generated on Tue Jul 12 2022 13:03:08 by
