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.c
00001 /* 00002 * Copyright (c) 2013-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 #include "nsconfig.h" 00018 00019 #include "ns_types.h" 00020 #include "eventOS_event.h" 00021 #include "ns_trace.h" 00022 #include "string.h" 00023 #include "randLIB.h" 00024 #include "nsdynmemLIB.h" 00025 #include "Core/include/ns_socket.h" 00026 #include "NWK_INTERFACE/Include/protocol.h" 00027 #include "ccmLIB.h" 00028 #include "shalib.h" 00029 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00030 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00031 #ifdef ECC 00032 #include "libX509_V3.h" 00033 #include "ecc.h" 00034 #endif 00035 #include "Security/TLS/tls_lib.h" 00036 #include "Security/Common/sec_lib.h" 00037 #include "net_nvm_api.h" 00038 #include "Security/PANA/pana.h" 00039 #include "Security/PANA/pana_internal_api.h" 00040 #include "6LoWPAN/MAC/mac_helper.h" 00041 #include "6LoWPAN/MAC/mac_data_poll.h" 00042 #include "6LoWPAN/ND/nd_router_object.h" 00043 #include "Common_Protocols/udp.h" 00044 00045 #ifdef ECC 00046 #include "ecc.h" 00047 #endif 00048 #include "common_functions.h" 00049 #include "Security/PANA/pana_nvm.h" 00050 #include "Security/PANA/pana_avp.h" 00051 #include "Security/PANA/pana_eap_header.h" 00052 #include "Security/PANA/pana_header.h" 00053 #include "Security/PANA/eap_protocol.h" 00054 #include "net_pana_parameters_api.h" 00055 #include "Service_Libs/mle_service/mle_service_api.h" 00056 #include "socket_api.h" 00057 00058 #ifdef PANA 00059 00060 #define TRACE_GROUP "pana" 00061 00062 typedef enum { 00063 ARM_PANA_INIT = 0, 00064 ARM_PANA_TLS_CB = 1, 00065 } arm_pana_event_id_e; 00066 00067 //Pana Relay Constant 00068 const uint8_t PANA_AUTH_STRING[9] = {'I', 'E', 'T', 'F', ' ', 'P', 'A', 'N', 'A'}; 00069 const uint8_t PANA_PAA_ENC_KEY_STRING[18] = {'I', 'E', 'T', 'F', ' ', 'P', 'A', 'N', 'A', ' ', 'P', 'A', 'A', ' ', 'E', 'n', 'c', 'r'}; 00070 const uint8_t PANA_PAC_ENC_KEY_STRING[18] = {'I', 'E', 'T', 'F', ' ', 'P', 'A', 'N', 'A', ' ', 'P', 'a', 'C', ' ', 'E', 'n', 'c', 'r'}; 00071 00072 static void pana_key_calc(bool enc_key, sec_suite_t *suite); 00073 static void pana_handshake_copy(uint8_t *ptr, uint16_t len, bool request, sec_suite_t *suite); 00074 00075 //TLS message parse support 00076 00077 NS_LARGE int8_t pana_socket = -1; /*socket variable*/ 00078 static int8_t pana_tasklet_id = -1; 00079 static pana_socket_packet_handler_cb *pana_socket_packet_handler = NULL; 00080 static pana_state_machine_step *pana_state_machine_step_cb = NULL; 00081 static pana_eap_tls_up_cb *pana_tls_handler_cb = NULL; 00082 00083 static NS_LARGE uint8_t pana_key_material[32]; 00084 00085 /** Pana Protocol Dynamic Parameters */ 00086 static pana_lib_parameters_s pana_library_params = { 00087 .PCI_IRT = 10, 00088 .PCI_MRT = 60, 00089 .PCI_MRC = 5, 00090 .REQ_IRT = 20, 00091 .REQ_MRT = 60, 00092 .REQ_MRC = 4, 00093 .AUTHENTICATION_TIMEOUT = 120, 00094 .KEY_UPDATE_THRESHOLD = 10, 00095 .KEY_ID_MAX_VALUE = 0xff, 00096 .EAP_FRAGMENT_SIZE = EAP_MTU_FRAG_SIZE, 00097 .AUTH_COUNTER_MAX = 0xff 00098 }; 00099 00100 pana_lib_parameters_s *pana_parameters_get(void) 00101 { 00102 return &pana_library_params; 00103 } 00104 00105 int8_t pana_socket_id_get(void) 00106 { 00107 return pana_socket; 00108 } 00109 00110 void pana_common_state_machine(sec_suite_t *suite) 00111 { 00112 if (pana_state_machine_step_cb) { 00113 pana_state_machine_step_cb(suite); 00114 } 00115 } 00116 00117 pana_session_t *pana_session_allocate(void) 00118 { 00119 pana_session_t *p_session = ns_dyn_mem_alloc(sizeof(pana_session_t)); 00120 if (p_session) { 00121 memset(p_session, 0, sizeof(pana_session_t)); 00122 p_session->session_ready = false; 00123 p_session->key_warp = false; 00124 p_session->user_server = false; 00125 p_session->eap_id_seq = randLIB_get_8bit(); //Take Random EAP ID 00126 } 00127 return p_session; 00128 } 00129 00130 void pana_session_base_init(pana_session_t *p_session) 00131 { 00132 00133 memset(p_session, 0, sizeof(pana_session_t)); 00134 p_session->session_ready = false; 00135 p_session->key_warp = false; 00136 p_session->user_server = false; 00137 p_session->eap_id_seq = randLIB_get_8bit(); //Take Random EAP ID 00138 00139 } 00140 00141 00142 void pana_session_state_init(pana_session_t *p_session) 00143 { 00144 p_session->key_warp = false; 00145 p_session->address_status = 0; 00146 } 00147 00148 pana_heap_t *pana_heap_structure_allocate(void) 00149 { 00150 pana_heap_t *heap = ns_dyn_mem_temporary_alloc(sizeof(pana_heap_t)); 00151 if (heap) { 00152 heap->handshake_len = 0; 00153 heap->handshake_req_offset = 0; 00154 randLIB_get_n_bytes_random(heap->client_nonce, 16); 00155 } 00156 return heap; 00157 } 00158 00159 static buffer_t *pana_eap_payload_to_avp(buffer_t *buf) 00160 { 00161 uint8_t *ptr; 00162 00163 uint16_t eap_len, padding; 00164 eap_len = buffer_data_length(buf); 00165 padding = eap_len; 00166 if ((buf = buffer_headroom(buf, 8)) == 0) { 00167 return NULL; 00168 } 00169 00170 buffer_data_reserve_header(buf, 8); 00171 //tr_debug("EAP AVP LEN: %02x", eap_len); 00172 ptr = buffer_data_pointer(buf); 00173 ptr = pana_avp_base_write(AVP_EAP_PAYLOAD_CODE, eap_len, ptr, 0, 0); 00174 00175 //Check Padding 00176 padding %= 4; 00177 if (padding) { 00178 padding = 4 - padding; 00179 //tr_debug("Add Pad: %02x", padding); 00180 if ((buf = buffer_headroom(buf, padding)) != 0) { 00181 uint8_t *ptr2; 00182 buffer_data_reserve_header(buf, padding); 00183 ptr = buffer_data_pointer(buf); 00184 ptr2 = ptr; 00185 ptr += padding; 00186 memmove(ptr2, ptr, eap_len + 8); 00187 } else { 00188 return NULL; 00189 } 00190 } 00191 00192 return buf; 00193 } 00194 00195 int8_t pana_get_params(pana_lib_parameters_s *params) 00196 { 00197 if (params) { 00198 *params = pana_library_params; 00199 return 0; 00200 } 00201 return -1; 00202 } 00203 00204 int8_t pana_set_params(const pana_lib_parameters_s *params) 00205 { 00206 int8_t ret_val = -1; 00207 if (!params) { 00208 00209 } else if (params->PCI_IRT == 0 || params->PCI_MRT == 0 || params->PCI_MRC == 0) { 00210 00211 } else if (params->REQ_IRT == 0 || params->REQ_MRT == 0 || params->REQ_MRC == 0) { 00212 00213 } else if (params->KEY_UPDATE_THRESHOLD == 0 || params->KEY_ID_MAX_VALUE < 3) { 00214 00215 } else if (params->EAP_FRAGMENT_SIZE < 64 || params->EAP_FRAGMENT_SIZE >= 920) { 00216 00217 } else if ((params->PCI_IRT > params->PCI_MRT) || (params->REQ_IRT > params->REQ_MRT)) { 00218 00219 } else { 00220 ret_val = 0; 00221 pana_library_params = *params; 00222 } 00223 return ret_val; 00224 00225 } 00226 00227 const pana_lib_parameters_s *pana_get_params_ptr(void) 00228 { 00229 return &pana_library_params; 00230 } 00231 00232 void pana_timeout_timer_set(sec_suite_t *suite, sec_state_machine_t cur_state) 00233 { 00234 uint32_t timer; 00235 uint32_t timer_inc; 00236 uint32_t timer_max; 00237 uint8_t retry; 00238 retry = suite->retry_counter; 00239 if (cur_state == PANA_PCI_TX) { 00240 timer_inc = (pana_library_params.PCI_IRT * 10); 00241 timer_max = (pana_library_params.PCI_MRT * 10); 00242 } else { 00243 timer_inc = (pana_library_params.REQ_IRT * 10); 00244 timer_max = (pana_library_params.REQ_MRT * 10); 00245 } 00246 timer = timer_inc; 00247 while (retry > 1) { 00248 timer += timer_inc; 00249 if (timer > timer_max) { 00250 timer = timer_max; 00251 retry = 0; 00252 } else { 00253 retry--; 00254 } 00255 } 00256 //Set State 00257 suite->state = cur_state; 00258 suite->timer = timer; 00259 00260 } 00261 uint8_t pana_retry_req_max_get(void) 00262 { 00263 return pana_library_params.REQ_MRC; 00264 } 00265 00266 uint32_t pana_handshake_timeout(void) 00267 { 00268 uint32_t ret_val = (pana_library_params.AUTHENTICATION_TIMEOUT * 10); 00269 return ret_val; 00270 } 00271 00272 int pana_retry_check(uint8_t counter, sec_state_machine_t cur_state) 00273 { 00274 int ret_val = -1; 00275 if (cur_state == PANA_PCI_TX) { 00276 if (counter < pana_library_params.PCI_MRC) { 00277 ret_val = 0; 00278 } 00279 } else { 00280 if (counter < pana_library_params.REQ_MRC) { 00281 ret_val = 0; 00282 } 00283 } 00284 return ret_val; 00285 } 00286 00287 uint8_t *pana_key_get(const uint8_t *key) 00288 { 00289 static uint8_t key_seed[8] = {'Z', 'i', 'g', 'B', 'e', 'e', 'I', 'P'}; 00290 SHALIB_init_HMAC(key, 16); 00291 SHALIB_push_data_HMAC(key_seed, 8); 00292 SHALIB_finish_HMAC(pana_key_material, 8); 00293 return pana_key_material; 00294 } 00295 00296 //static void pana_key_pair_data_generate(sec_suite_t *suite) 00297 //{ 00298 // uint8_t *pac, *paa; 00299 // if (suite->setups & TLS_SERVER_MODE) { 00300 // //Server 00301 // paa = suite->interface->iid_eui64; 00302 // pac = &suite->session_address[8]; 00303 // } else { 00304 // pac = suite->interface->iid_eui64; 00305 // paa = &suite->session_address[8]; 00306 // 00307 // } 00308 // SHALIB_push_data_HMAC(paa, 8); 00309 // SHALIB_push_data_HMAC(pac, 8); 00310 //} 00311 ///* Define Pair wise Key*/ 00312 //static uint8_t pana_hmac_temp_key[64]; 00313 //static uint8_t *pana_generate_key_pair_key(sec_suite_t *suite, uint8_t *common_key, uint8_t *key_ptr) 00314 //{ 00315 // static uint8_t key_seed[8] = {'K', 'e', 'y', 'P', 'a', 'i', 'r', '?'}; 00316 // memcpy(pana_hmac_temp_key, suite->pana_session.pana_auth_key, 32); 00317 // memcpy(&pana_hmac_temp_key[32], common_key, 16); 00318 // 00319 // SHALIB_init_HMAC(pana_hmac_temp_key, 48); 00320 // 00321 // SHALIB_push_data_HMAC(key_seed, 8); 00322 // pana_key_pair_data_generate(suite); 00323 // SHALIB_push_data_HMAC(&suite->pana_session.auth_cnt, 1); 00324 // SHALIB_finish_HMAC(common_key, 4); 00325 // return common_key; 00326 //} 00327 00328 void pana_session_init_by_session_ptr(sec_suite_t *suite, auth_info_t *auth_ptr) 00329 { 00330 if (suite) { 00331 suite->setups = 0; 00332 pana_session_state_init(&suite->pana_session); 00333 suite->pana_session.auth_info = auth_ptr; 00334 00335 eap_fragmentation_init(suite); 00336 if (suite->pana_session.session_ready) { 00337 tr_debug("Ping Notify"); 00338 suite->state = PANA_PING_REQ; 00339 suite->timer = 1; 00340 suite->retry_counter = 0; 00341 } else { 00342 if (sec_pana_protocol_init(suite) == 0) { 00343 sec_lib_state_machine_trig(suite, PANA_ERROR); 00344 } 00345 } 00346 } 00347 } 00348 00349 void pana_authentication_ready(uint8_t status, protocol_interface_info_entry_t *cur_interface) 00350 { 00351 if (status) { 00352 nwk_6lowpan_bootsrap_pana_authentication_cb(true, cur_interface); 00353 } else { 00354 nwk_6lowpan_bootsrap_pana_authentication_cb(false, cur_interface); 00355 } 00356 } 00357 00358 #ifdef ECC 00359 extern void sec_ecc_state_free(sec_suite_t *suite); 00360 #endif 00361 00362 void pana_reset_values(uint16_t pana_id) 00363 { 00364 sec_suite_t *suite = 0; 00365 00366 suite = sec_suite_selected_py_pan_id(pana_id); 00367 if (suite) { 00368 suite->timer = 0; 00369 sec_suite_tls_free(suite, true); 00370 pana_free_dynamic_ram(suite); 00371 #ifdef ECC 00372 sec_ecc_state_free(suite); 00373 #endif 00374 } 00375 00376 } 00377 00378 static void pana_socket_callback(void *cb) 00379 { 00380 socket_buffer_callback_t *cb_buf = cb; 00381 if (cb_buf->event_type == SOCKET_DATA) { 00382 buffer_t *buf = cb_buf->buf ; 00383 if (buf) { 00384 00385 //Find or create session //Do CB HERE 00386 buf->socket = socket_dereference(buf->socket ); 00387 buf->session_ptr = NULL; 00388 pana_socket_packet_handler(buf); 00389 } 00390 } else { 00391 00392 sec_suite_socket_event(cb_buf->event_type, cb_buf->session_ptr); 00393 } 00394 } 00395 00396 void pana_event_handler(arm_event_s *event) 00397 { 00398 switch (event->event_type) { 00399 case ARM_PANA_INIT: 00400 tr_debug("Pana Tasklet Init"); 00401 break; 00402 00403 case ARM_PANA_TLS_CB: 00404 if (event->data_ptr) { 00405 buffer_t *buf = event->data_ptr; 00406 sec_suite_t *tls_suite = buf->session_ptr; 00407 buf->session_ptr = NULL; 00408 00409 tls_suite = sec_suite_verify(tls_suite); 00410 00411 if (tls_suite && pana_tls_handler_cb) { 00412 buf = pana_tls_handler_cb(buf, tls_suite); 00413 } else { 00414 tr_warn("Pana/TLS er"); 00415 } 00416 00417 if (buf) { 00418 buffer_free(buf); 00419 } 00420 } 00421 break; 00422 default: 00423 break; 00424 } 00425 } 00426 00427 bool pana_socket_init(pana_socket_packet_handler_cb *socket_handler, pana_state_machine_step *state_machine_stepper, pana_eap_tls_up_cb *tls_handler_cb) 00428 { 00429 tr_debug("Pana sub-layer init"); 00430 if (pana_socket == -1) { 00431 if (socket_create(SOCKET_FAMILY_IPV6, SOCKET_TYPE_DGRAM, 0, &pana_socket, UDP_PORT_PANA, pana_socket_callback, true) != eOK) { 00432 return false; 00433 } 00434 //GENERATE TASKLET if not created before 00435 if (pana_tasklet_id == -1) { 00436 pana_tasklet_id = eventOS_event_handler_create(&pana_event_handler, ARM_PANA_INIT); 00437 if (pana_tasklet_id < 0) { 00438 socket_close(pana_socket); 00439 pana_socket = -1; 00440 return false; 00441 } 00442 } 00443 } 00444 tr_debug("Pana socket Id %i", pana_socket); 00445 00446 pana_socket_packet_handler = socket_handler; 00447 pana_state_machine_step_cb = state_machine_stepper; 00448 pana_tls_handler_cb = tls_handler_cb; 00449 return true; 00450 } 00451 00452 void pana_set_agend_address(buffer_t *buf, bool relay, sec_suite_t *suite) 00453 { 00454 uint8_t *ptr = 0; 00455 buf->interface = suite->interface; 00456 protocol_interface_info_entry_t *cur = buf->interface ; 00457 if (cur) { 00458 00459 if (suite->pana_session.user_server) { 00460 if (relay) { 00461 ptr = protocol_6lowpan_nd_border_router_address_get(buf->interface ->nwk_id); 00462 if (ptr) { 00463 memcpy(buf->src_sa .address , ptr, 16); 00464 ptr = suite->pana_session.session_relay_address; 00465 memcpy(buf->dst_sa .address , ptr, 16); 00466 } 00467 // 00468 buf->options .ll_security_bypass_tx = false; 00469 } else { 00470 //Default 00471 addr_interface_get_ll_address(cur, buf->src_sa .address , 2); 00472 ptr = suite->session_address; 00473 memcpy(buf->dst_sa .address , ptr, 16); 00474 buf->options .ll_security_bypass_tx = true; 00475 } 00476 } else { 00477 if (relay) { 00478 ptr = protocol_6lowpan_nd_border_router_address_get(buf->interface ->nwk_id); 00479 if (ptr) { 00480 memcpy(buf->dst_sa .address , ptr, 16); 00481 memcpy(suite->pana_session.session_relay_address, ptr, 16); 00482 //Select source by Dst address 00483 (void) addr_interface_select_source(cur, buf->src_sa .address , buf->dst_sa .address , 0); 00484 } 00485 buf->options .ll_security_bypass_tx = false; 00486 } else { 00487 00488 00489 //tr_debug("LL Agent"); 00490 nd_router_t *object = nd_get_pana_address(); 00491 if (object) { 00492 icmp_nd_set_nd_def_router_address(buf->dst_sa .address , object); 00493 tr_debug("MD Router adr: %s", trace_ipv6(buf->dst_sa .address )); 00494 } else { 00495 //tr_debug("Use Mac Coordinator"); 00496 protocol_6lowpan_interface_get_link_local_cordinator_address(cur, buf->dst_sa .address ); 00497 } 00498 ptr = suite->session_address; 00499 memcpy(ptr, buf->dst_sa .address , 16); 00500 00501 addr_interface_get_ll_address(cur, buf->src_sa .address , 1); 00502 buf->options .ll_security_bypass_tx = true; 00503 } 00504 } 00505 } 00506 tr_debug("DST %s src %s", trace_ipv6(buf->dst_sa .address ), trace_ipv6(buf->src_sa .address )); 00507 buf->src_sa .addr_type = ADDR_IPV6 ; 00508 buf->dst_sa .addr_type = ADDR_IPV6 ; 00509 00510 } 00511 00512 00513 buffer_t *build_pana_base(buffer_t *buf, pana_header_t *header, sec_suite_t *suite) 00514 { 00515 uint8_t *ptr; 00516 buf->session_ptr = NULL; 00517 buf = buffer_headroom(buf, PANA_HEADER_LENGTH); 00518 if (!buf) { 00519 return NULL; 00520 } 00521 00522 buf = buffer_turnaround(buf); // In case we're reusing a buffer 00523 ptr = buffer_data_reserve_header(buf, PANA_HEADER_LENGTH); 00524 header->payload_len = buffer_data_length(buf); 00525 pana_header_write(ptr, header); 00526 00527 buf->src_sa .port = UDP_PORT_PANA; 00528 buf->dst_sa .port = suite->session_port; 00529 buf->info = (buffer_info_t)(B_DIR_DOWN + B_FROM_APP + B_TO_UDP); 00530 if (header->type != PANA_MSG_RELAY || suite->pana_session.user_server) { 00531 buffer_socket_set(buf, socket_pointer_get(pana_socket)); 00532 buf->session_ptr = suite; 00533 } else { 00534 buf->socket = socket_dereference(buf->socket ); 00535 buf->session_ptr = NULL; 00536 } 00537 //tr_debug("From Pana-> Core"); 00538 buf->interface = suite->interface; 00539 tr_debug("PANA len: %d", header->payload_len); 00540 return buf; 00541 } 00542 00543 void pana_eap_tls_up(buffer_t *buf, sec_suite_t *suite) 00544 { 00545 buf = eap_up(buf, suite); 00546 if (!buf) { 00547 return; 00548 } 00549 pana_eap_down(buf, suite); 00550 } 00551 00552 void pana_eap_down(buffer_t *buf, sec_suite_t *suite) 00553 { 00554 buf = eap_down(buf, suite); 00555 if (!buf) { 00556 return; 00557 } 00558 //Set EAP Payload 00559 pana_eap_payload_down(buf, NULL, suite); 00560 } 00561 00562 void pana_eap_payload_down(buffer_t *buf, const uint8_t *nonce, sec_suite_t *suite) 00563 { 00564 buf = pana_eap_payload_to_avp(buf); 00565 00566 if (!buf) { 00567 return; 00568 } 00569 00570 if (nonce) { 00571 if ((buf = buffer_headroom(buf, 24)) == 0) { 00572 return; 00573 } 00574 buffer_data_reserve_header(buf, 24); 00575 uint8_t *ptr = buffer_data_pointer(buf); 00576 ptr = pana_avp_write_n_bytes(AVP_NONCE_CODE, 16, nonce, ptr); 00577 } 00578 00579 pana_down(buf, suite); 00580 } 00581 00582 00583 void pana_handshake_copy(uint8_t *ptr, uint16_t len, bool request, sec_suite_t *suite) 00584 { 00585 if (suite->pana_session.pana_heap) { 00586 uint8_t *dptr = 0; 00587 pana_heap_t *pheap = suite->pana_session.pana_heap; 00588 00589 dptr = pheap->pana_handshake; 00590 if (!request) { 00591 dptr += pheap->handshake_req_offset; 00592 pheap->handshake_len = len + pheap->handshake_req_offset; 00593 } else { 00594 pheap->handshake_req_offset = len; 00595 pheap->handshake_len = len; 00596 } 00597 memcpy(dptr, ptr, len); 00598 } 00599 } 00600 00601 00602 void pana_down(buffer_t *buf, sec_suite_t *suite) 00603 { 00604 //Check Request Or Response 00605 pana_header_t header; 00606 header.type = PANA_MSG_PA; 00607 if (suite->pana_session.user_server) { 00608 if (suite->state == PANA_REQUEST_TX) { 00609 header.flags = PANA_FLAGS_START | PANA_FLAGS_REQUEST; 00610 } else if (suite->state == EAP_PANA_FINISH || suite->state == PANA_FAILURE) { 00611 header.flags = (PANA_FLAGS_REQUEST | PANA_FLAGS_COMPLETE); 00612 } else if (suite->state == PANA_FAILURE_RESPONSE) { 00613 header.flags = (PANA_FLAGS_RESPONSE | PANA_FLAGS_COMPLETE); 00614 } else { 00615 header.flags = PANA_FLAGS_REQUEST; 00616 } 00617 } else { 00618 00619 if (suite->state == PANA_FAILURE) { 00620 header.flags = PANA_FLAGS_COMPLETE; 00621 } else if (suite->state == PANA_START_RESPONSE) { 00622 header.flags = PANA_FLAGS_START; 00623 } else { 00624 header.flags = 0; 00625 } 00626 } 00627 00628 if (header.flags & PANA_FLAGS_REQUEST) { 00629 header.seq = suite->pana_session.req_seq; 00630 } else { 00631 header.seq = suite->pana_session.res_seq; 00632 } 00633 header.session_id = suite->pana_session.session_id; 00634 pana_set_agend_address(buf, false, suite); 00635 buf = build_pana_base(buf, &header, suite); 00636 if (buf) { 00637 /** 00638 * Copy Authentication start message 00639 */ 00640 if (header.flags & PANA_FLAGS_START) { 00641 uint16_t len = buffer_data_length(buf); 00642 uint8_t *ptr = buffer_data_pointer(buf); 00643 00644 if (header.flags & PANA_FLAGS_REQUEST) { 00645 pana_handshake_copy(ptr, len, true, suite); 00646 } else { 00647 pana_handshake_copy(ptr, len, false, suite); 00648 } 00649 } 00650 00651 if (suite->pana_session.address_status & 1) { 00652 tr_debug("Build Relay"); 00653 buf = pana_relay_avp_build(buf, suite); 00654 if (buf) { 00655 header.flags = 0; 00656 header.type = PANA_MSG_RELAY; 00657 header.session_id = 0; 00658 header.seq = 0; 00659 buf = build_pana_base(buf, &header, suite); 00660 } 00661 } 00662 00663 protocol_push(buf); 00664 } 00665 00666 00667 } 00668 00669 00670 buffer_t *pana_relay_avp_build(buffer_t *buf, sec_suite_t *suite) 00671 { 00672 uint8_t *ptr, *adr_ptr; 00673 uint16_t relay_len, padding; 00674 relay_len = buffer_data_length(buf); 00675 padding = relay_len; 00676 buf->socket = socket_dereference(buf->socket ); 00677 buf->session_ptr = NULL; 00678 if ((buf = buffer_headroom(buf, 36)) == 0) { 00679 return buf; 00680 } else { 00681 buffer_data_reserve_header(buf, 36); 00682 ptr = buffer_data_pointer(buf); 00683 ptr = pana_avp_base_write(AVP_PAC_INFO_CODE, 18, ptr, 0, 0); 00684 //SET Relay IPV6 address 00685 if (suite->pana_session.user_server) { 00686 memcpy(ptr, suite->session_address, 16); 00687 ptr += 16; 00688 ptr = common_write_16_bit(suite->session_port, ptr); 00689 00690 adr_ptr = protocol_6lowpan_nd_border_router_address_get(buf->interface ->nwk_id); 00691 if (adr_ptr) { 00692 memcpy(buf->src_sa .address , adr_ptr, 16); 00693 memcpy(buf->dst_sa .address , suite->pana_session.session_relay_address, 16); 00694 buf->dst_sa .port = suite->pana_session.relay_port; 00695 } 00696 } else { 00697 memcpy(ptr, buf->src_sa .address , 16); 00698 ptr += 16; 00699 ptr = common_write_16_bit(buf->src_sa .port , ptr); 00700 } 00701 //PADDING for PAC 00702 ptr = common_write_16_bit(0, ptr); 00703 //PANA Relay AVP header Write data is already there 00704 ptr = pana_avp_base_write(AVP_RELAY_MSG_CODE, relay_len, ptr, 0, 0); 00705 } 00706 //Enable security for relay allways by Default 00707 buf->options .ll_security_bypass_tx = false; 00708 padding %= 4; 00709 if (padding) { 00710 padding = 4 - padding; 00711 //tr_debug("Add Pad: %02x", padding); 00712 if ((buf = buffer_headroom(buf, padding)) != 0) { 00713 uint8_t *ptr2; 00714 buffer_data_reserve_header(buf, padding); 00715 ptr = buffer_data_pointer(buf); 00716 ptr2 = ptr; 00717 ptr += padding; 00718 memmove(ptr2, ptr, relay_len + 36); 00719 } 00720 } 00721 return buf; 00722 } 00723 00724 bool pana_auth_check(uint8_t *ptr, uint16_t length, uint8_t *authency, uint8_t *key) 00725 { 00726 if (!authency) { 00727 return false; 00728 } 00729 uint8_t hasn_buf_temp[16]; 00730 uint8_t compare_hash_temp[16]; 00731 00732 //tr_debug("AV SUCCESS. Hash RX: %s", trace_array(ptr, 16)); 00733 memcpy(compare_hash_temp, authency, 16); 00734 memset(authency, 0, 16); 00735 length += 16; 00736 ptr -= 16;//Shift Pana Headers back 00737 //tr_debug("Calc: %s", trace_array(key, 32) ); 00738 SHALIB_init_HMAC(key, 32); 00739 SHALIB_push_data_HMAC(ptr, length); 00740 //tr_debug("%s", trace_array(ptr,length)); 00741 SHALIB_finish_HMAC(hasn_buf_temp, 4); 00742 00743 if (memcmp(hasn_buf_temp, compare_hash_temp, 16) != 0) { 00744 tr_debug("HASH AUTH Fail. RX: %s", trace_array(compare_hash_temp, 16)); 00745 tr_debug("Cal: %s", trace_array(hasn_buf_temp, 16)); 00746 return false; 00747 } 00748 return true; 00749 } 00750 00751 int8_t pana_ccm_data_crypt(uint8_t *ptr, uint16_t len, uint8_t operation_type, uint32_t message_seq, sec_suite_t *suite) 00752 { 00753 uint8_t *explict_ptr; 00754 uint8_t *key_ptr = 0; 00755 ccm_globals_t ccm_ptr; 00756 key_ptr = suite->pana_session.pana_PAA_enc_key; 00757 00758 //Here Comes AES Decrypt 00759 if (!ccm_sec_init(&ccm_ptr, AES_SECURITY_LEVEL_ENC, key_ptr, operation_type, 3)) { 00760 return -1; 00761 } 00762 00763 explict_ptr = ccm_ptr.exp_nonce; 00764 //Set IV 00765 explict_ptr = common_write_32_bit(suite->pana_session.pana_key_id, explict_ptr); 00766 //SET EXP 4 octest Session ID, 4 Octet Pana SQN number 00767 explict_ptr = common_write_32_bit(suite->pana_session.session_id, explict_ptr); 00768 explict_ptr = common_write_32_bit(message_seq, explict_ptr); 00769 ccm_ptr.data_len = len; 00770 ccm_ptr.data_ptr = ptr; 00771 return ccm_process_run(&ccm_ptr); 00772 } 00773 00774 buffer_t *pana_relay_parse(buffer_t *buf) 00775 { 00776 uint8_t *ptr; 00777 buf->options .ll_security_bypass_tx = true; 00778 //tr_debug("Relay RX"); 00779 ptr = buffer_data_pointer(buf); 00780 uint16_t length = buffer_data_length(buf); 00781 00782 pana_avp_t pac_info; 00783 pac_info.code = AVP_PAC_INFO_CODE; 00784 00785 if (!pana_avp_discover(ptr, length, &pac_info) || pac_info.len != 18) { 00786 tr_debug("No Pac info"); 00787 return buffer_free(buf); 00788 } 00789 00790 pana_avp_t relay_msg; 00791 relay_msg.code = AVP_RELAY_MSG_CODE; 00792 00793 if (!pana_avp_discover(ptr, length, &relay_msg)) { 00794 tr_debug("No Relay MSG"); 00795 return buffer_free(buf); 00796 } 00797 //Set Message data to relay msg 00798 buffer_data_pointer_set(buf, relay_msg.avp_ptr); 00799 buffer_data_length_set(buf, relay_msg.len); 00800 //Set Destination to Pac Info 00801 ptr = pac_info.avp_ptr; 00802 memcpy(buf->dst_sa .address , ptr, 16); 00803 //buf->dst_sa.addr_type = ADDR_IPV6; 00804 ptr += 16; 00805 buf->dst_sa .port = common_read_16_bit(ptr); 00806 ptr += 2; 00807 //tr_debug("%s", trace_array(buf->dst_sa.address, 16) ); 00808 return buf; 00809 } 00810 00811 void pana_session_startms_parse(buffer_t *buf, pana_header_t *header, sec_suite_t *suite) 00812 { 00813 uint32_t prf_algorythm = 0; 00814 uint32_t integrity_algorythm = 12; 00815 uint32_t key_wrap = 0; 00816 bool key_wrap_parsed = false; 00817 uint16_t len = buffer_data_length(buf); 00818 uint8_t *ptr = buffer_data_pointer(buf); 00819 00820 pana_avp_t avp_temp; 00821 //Read Resul and Key id if they are coming 00822 avp_temp.code = AVP_PRF_ALGORYTHM_CODE; 00823 avp_temp.len = 0; 00824 if (pana_avp_discover(ptr, len, &avp_temp) && avp_temp.len == 4) { 00825 prf_algorythm = common_read_32_bit(avp_temp.avp_ptr); 00826 } 00827 00828 avp_temp.code = AVP_INTEGRIRTY_ALGORYTHM_CODE; 00829 avp_temp.len = 0; 00830 if (pana_avp_discover(ptr, len, &avp_temp) && avp_temp.len == 4) { 00831 integrity_algorythm = common_read_32_bit(avp_temp.avp_ptr); 00832 } 00833 00834 avp_temp.code = AVP_KEY_WRAP_ALG_CODE; 00835 avp_temp.len = 0; 00836 if (pana_avp_discover(ptr, len, &avp_temp) && avp_temp.len == 4) { 00837 key_wrap = common_read_32_bit(avp_temp.avp_ptr); 00838 key_wrap_parsed = true; 00839 } 00840 00841 bool drop_message = false; 00842 if ((header->flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00843 if (prf_algorythm != suite->pana_session.prf_algorythm) { 00844 tr_debug("PRF!!"); 00845 drop_message = true; 00846 } else if (integrity_algorythm != suite->pana_session.integrity_algorythm) { 00847 tr_debug("int!!"); 00848 drop_message = true; 00849 } 00850 if (key_wrap_parsed && key_wrap != suite->pana_session.key_wrap) { 00851 tr_debug("key!!"); 00852 drop_message = true; 00853 } 00854 00855 } else { 00856 if (prf_algorythm != 5) { 00857 drop_message = true; 00858 } else if (integrity_algorythm != 12) { 00859 drop_message = true; 00860 } 00861 } 00862 00863 if (!drop_message) { 00864 if (key_wrap_parsed) { 00865 suite->pana_session.key_warp = true; 00866 suite->pana_session.key_wrap = key_wrap; 00867 } 00868 len += 16; 00869 ptr -= 16; //Shift Pana Headers back 00870 if ((header->flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00871 sec_lib_state_machine_trig(suite, EAP_IDENTITY_REQ); 00872 pana_handshake_copy(ptr, len, false, suite); 00873 } else { 00874 suite->pana_session.integrity_algorythm = integrity_algorythm; 00875 suite->pana_session.prf_algorythm = prf_algorythm; 00876 sec_lib_state_machine_trig(suite, PANA_START_RESPONSE); 00877 pana_handshake_copy(ptr, len, true, suite); 00878 } 00879 suite->retry_counter = 0; 00880 00881 } 00882 00883 buffer_free(buf); 00884 } 00885 00886 buffer_t *pana_auth_message_handler(buffer_t *buf, pana_header_t *header, sec_suite_t *suite) 00887 { 00888 if (!buf) { 00889 return NULL; 00890 } 00891 protocol_interface_info_entry_t *cur = buf->interface ; 00892 if (!cur) { 00893 return buffer_free(buf); 00894 } 00895 00896 uint16_t length = buffer_data_length(buf); 00897 uint8_t *ptr = buffer_data_pointer(buf); 00898 pana_avp_t avp_temp; 00899 00900 if (suite->pana_session.session_ready) { 00901 return buffer_free(buf); 00902 } 00903 00904 if (sec_check_suite_ptrs(suite) == 0) { 00905 tr_warn("SEC Lib Fail"); 00906 return buffer_free(buf); 00907 } 00908 00909 avp_temp.code = AVP_NONCE_CODE; 00910 if (pana_avp_discover(ptr, length, &avp_temp)) { 00911 if (avp_temp.len == 16) { 00912 if ((header->flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00913 memcpy(suite->pana_session.pana_heap->client_nonce, avp_temp.avp_ptr, 16); 00914 } else { 00915 memcpy(suite->pana_session.pana_heap->agent_nonce, avp_temp.avp_ptr, 16); 00916 } 00917 //tr_debug("Pana:A_NONCE OK"); 00918 00919 } else { 00920 tr_debug("A_NONCE length fail, Len: %x", avp_temp.len); 00921 } 00922 } 00923 00924 avp_temp.code = AVP_EAP_PAYLOAD_CODE; 00925 if (pana_avp_discover(ptr, length, &avp_temp)) { 00926 ptr = avp_temp.avp_ptr; 00927 if (avp_temp.len > 4) { 00928 buf->buf_ptr = 0; 00929 buf->buf_end = avp_temp.len; 00930 memmove(buf->buf , ptr, avp_temp.len); 00931 return buf; 00932 } 00933 } 00934 00935 return buffer_free(buf); 00936 } 00937 00938 void pana_start_message_build(buffer_t *buf, sec_suite_t *suite) 00939 { 00940 uint8_t *ptr; 00941 //tr_debug("TX Pana Start Response"); 00942 buf->buf_ptr = PANA_HEADER_LENGTH; 00943 ptr = buffer_data_pointer(buf); 00944 ptr = pana_avp_32_bit_write(AVP_PRF_ALGORYTHM_CODE, suite->pana_session.prf_algorythm, ptr); 00945 ptr = pana_avp_32_bit_write(AVP_INTEGRIRTY_ALGORYTHM_CODE, suite->pana_session.integrity_algorythm, ptr); 00946 if (suite->pana_session.key_warp) { 00947 ptr = pana_avp_32_bit_write(AVP_KEY_WRAP_ALG_CODE, suite->pana_session.key_wrap, ptr); 00948 } 00949 buffer_data_end_set(buf, ptr); 00950 pana_down(buf, suite); 00951 } 00952 00953 00954 00955 void eap_tls_payload_push(buffer_t *buf) 00956 { 00957 arm_event_s event = { 00958 .receiver = pana_tasklet_id, 00959 .sender = 0, 00960 .data_ptr = buf, 00961 .event_type = ARM_PANA_TLS_CB, 00962 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00963 }; 00964 if (eventOS_event_send(&event) != 0) { 00965 tr_warn("Free Buffer if fail"); 00966 buf->session_ptr = NULL; 00967 buffer_free(buf); 00968 } 00969 } 00970 00971 void pana_free_dynamic_ram(sec_suite_t *suite) 00972 { 00973 if (suite->pana_session.pana_heap) { 00974 tr_debug("Free Pana Heap"); 00975 ns_dyn_mem_free(suite->pana_session.pana_heap); 00976 suite->pana_session.pana_heap = NULL; 00977 } 00978 eap_fragmentation_init(suite); 00979 } 00980 00981 static void pana_key_calc(bool enc_key, sec_suite_t *suite) 00982 { 00983 pana_heap_t *pheap = suite->pana_session.pana_heap; 00984 00985 //tr_debug("Pana Auth verify. MSK: %s", trace_array(suite->pana_session.MSK, 64) ); 00986 SHALIB_init_HMAC(pheap->MSK, 64); 00987 if (enc_key) { 00988 //tr_debug("Cal Pana En Key start"); 00989 SHALIB_push_data_HMAC(PANA_PAA_ENC_KEY_STRING, 18); 00990 } else { 00991 SHALIB_push_data_HMAC(PANA_AUTH_STRING, 9); 00992 } 00993 00994 //tr_debug("Handshake data: %s", trace_array(pheap->pana_handshake, pheap->handshake_len)); 00995 SHALIB_push_data_HMAC(pheap->pana_handshake, pheap->handshake_len); 00996 // tr_debug("Handshake data"); 00997 // tr_debug("C Nonce: %s", trace_array(pheap->client_nonce, 16) ); 00998 SHALIB_push_data_HMAC(pheap->client_nonce, 16); 00999 // tr_debug("A Nonce: %s", trace_array(pheap->agent_nonce, 16) ); 01000 SHALIB_push_data_HMAC(pheap->agent_nonce, 16); 01001 uint8_t temp32_buf[4]; 01002 // tr_debug("Key ID: %s", trace_array(temp32_buf, 4) ); 01003 common_write_32_bit(suite->pana_session.pana_key_id, temp32_buf); 01004 SHALIB_push_data_HMAC(temp32_buf, 4); 01005 SHALIB_push_data_HMAC(&(const uint8_t) { 01006 1 01007 }, 1); 01008 if (enc_key) { 01009 uint8_t *key_ptr = suite->pana_session.pana_PAA_enc_key; 01010 01011 SHALIB_finish_HMAC(key_ptr, 4); 01012 } else { 01013 SHALIB_finish_HMAC(suite->pana_session.pana_auth_key, 8); 01014 } 01015 } 01016 01017 void pana_key_calculation(sec_suite_t *suite) 01018 { 01019 pana_key_calc(false, suite); 01020 pana_key_calc(true, suite); 01021 } 01022 01023 void pana_auth_hash_calc(uint8_t *data_ptr, uint16_t data_length, uint8_t *key) 01024 { 01025 SHALIB_init_HMAC(key, 32); 01026 SHALIB_push_data_HMAC(data_ptr, data_length); 01027 data_ptr += (data_length - 16); 01028 SHALIB_finish_HMAC(data_ptr, 4); 01029 } 01030 01031 #ifdef ECC 01032 static void certificate_copy_block(const arm_certificate_chain_entry_s *rx_chain_info, certificate_chain_internal_t *cert) 01033 { 01034 uint8_t i; 01035 cert->chain_length = rx_chain_info->chain_length; 01036 for (i = 0; i < cert->chain_length; i++) { 01037 //Copy Certi 01038 cert->certi_chain[i] = rx_chain_info->cert_chain[i]; 01039 cert->certi_len[i] = rx_chain_info->cert_len[i]; 01040 //Copy Cur Key 01041 cert->key_chain[i] = rx_chain_info->key_chain[i]; 01042 } 01043 } 01044 #endif 01045 01046 int8_t pana_interface_certificate_chain_set(const arm_certificate_chain_entry_s *chain_info) 01047 { 01048 #ifdef ECC 01049 if (!chain_info) { 01050 return -1; 01051 } 01052 certificate_chain_internal_t temp_certi; 01053 certificate_copy_block(chain_info, &temp_certi); 01054 return x509_cetificate_chain_push(SEC_NWK_AUTHENTICATION_CERTI_CHAIN, &temp_certi); 01055 #else 01056 (void) chain_info; 01057 return -1; 01058 #endif 01059 } 01060 01061 #endif /*PANA*/ 01062 //************************ECC Certificates end 01063 01064 /* end of file */
Generated on Tue Jul 12 2022 13:54:40 by
1.7.2