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.
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 Tue Jul 12 2022 12:22:16 by
