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