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