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-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 #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 = 0; 00754 key_ptr = suite->pana_session.pana_PAA_enc_key; 00755 00756 //Here Comes AES Decrypt 00757 ccm_ptr = ccm_sec_init(AES_SECURITY_LEVEL_ENC, key_ptr, operation_type , 3); 00758 if (!ccm_ptr) { 00759 return -1; 00760 } 00761 00762 explict_ptr = ccm_ptr->exp_nonce; 00763 //Set IV 00764 explict_ptr = common_write_32_bit(suite->pana_session.pana_key_id, explict_ptr); 00765 //SET EXP 4 octest Session ID, 4 Octet Pana SQN number 00766 explict_ptr = common_write_32_bit(suite->pana_session.session_id, explict_ptr); 00767 explict_ptr = common_write_32_bit(message_seq, explict_ptr); 00768 ccm_ptr->data_len = len; 00769 ccm_ptr->data_ptr = ptr; 00770 return ccm_process_run(ccm_ptr); 00771 } 00772 00773 buffer_t *pana_relay_parse(buffer_t *buf) 00774 { 00775 uint8_t *ptr; 00776 buf->options .ll_security_bypass_tx = true; 00777 //tr_debug("Relay RX"); 00778 ptr = buffer_data_pointer(buf); 00779 uint16_t length = buffer_data_length(buf); 00780 00781 pana_avp_t pac_info; 00782 pac_info.code = AVP_PAC_INFO_CODE; 00783 00784 if (!pana_avp_discover(ptr, length, &pac_info) || pac_info.len != 18) { 00785 tr_debug("No Pac info"); 00786 return buffer_free(buf); 00787 } 00788 00789 pana_avp_t relay_msg; 00790 relay_msg.code = AVP_RELAY_MSG_CODE; 00791 00792 if (!pana_avp_discover(ptr, length, &relay_msg)) { 00793 tr_debug("No Relay MSG"); 00794 return buffer_free(buf); 00795 } 00796 //Set Message data to relay msg 00797 buffer_data_pointer_set(buf, relay_msg.avp_ptr); 00798 buffer_data_length_set(buf, relay_msg.len); 00799 //Set Destination to Pac Info 00800 ptr = pac_info.avp_ptr; 00801 memcpy(buf->dst_sa .address , ptr, 16); 00802 //buf->dst_sa.addr_type = ADDR_IPV6; 00803 ptr += 16; 00804 buf->dst_sa .port = common_read_16_bit(ptr); 00805 ptr += 2; 00806 //tr_debug("%s", trace_array(buf->dst_sa.address, 16) ); 00807 return buf; 00808 } 00809 00810 void pana_session_startms_parse(buffer_t *buf, pana_header_t *header, sec_suite_t *suite) 00811 { 00812 uint32_t prf_algorythm = 0; 00813 uint32_t integrity_algorythm = 12; 00814 uint32_t key_wrap = 0; 00815 bool key_wrap_parsed = false; 00816 uint16_t len = buffer_data_length(buf); 00817 uint8_t *ptr = buffer_data_pointer(buf); 00818 00819 pana_avp_t avp_temp; 00820 //Read Resul and Key id if they are coming 00821 avp_temp.code = AVP_PRF_ALGORYTHM_CODE; 00822 avp_temp.len = 0; 00823 if (pana_avp_discover(ptr, len, &avp_temp) && avp_temp.len == 4) { 00824 prf_algorythm = common_read_32_bit(avp_temp.avp_ptr); 00825 } 00826 00827 avp_temp.code = AVP_INTEGRIRTY_ALGORYTHM_CODE; 00828 avp_temp.len = 0; 00829 if (pana_avp_discover(ptr, len, &avp_temp) && avp_temp.len == 4) { 00830 integrity_algorythm = common_read_32_bit(avp_temp.avp_ptr); 00831 } 00832 00833 avp_temp.code = AVP_KEY_WRAP_ALG_CODE; 00834 avp_temp.len = 0; 00835 if (pana_avp_discover(ptr, len, &avp_temp) && avp_temp.len == 4) { 00836 key_wrap = common_read_32_bit(avp_temp.avp_ptr); 00837 key_wrap_parsed = true; 00838 } 00839 00840 bool drop_message = false; 00841 if ((header->flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00842 if (prf_algorythm != suite->pana_session.prf_algorythm) { 00843 tr_debug("PRF!!"); 00844 drop_message = true; 00845 } else if (integrity_algorythm != suite->pana_session.integrity_algorythm) { 00846 tr_debug("int!!"); 00847 drop_message = true; 00848 } 00849 if (key_wrap_parsed && key_wrap != suite->pana_session.key_wrap) { 00850 tr_debug("key!!"); 00851 drop_message = true; 00852 } 00853 00854 } else { 00855 if (prf_algorythm != 5) { 00856 drop_message = true; 00857 } else if (integrity_algorythm != 12) { 00858 drop_message = true; 00859 } 00860 } 00861 00862 if (!drop_message) { 00863 if (key_wrap_parsed) { 00864 suite->pana_session.key_warp = true; 00865 suite->pana_session.key_wrap = key_wrap; 00866 } 00867 len += 16; 00868 ptr -= 16; //Shift Pana Headers back 00869 if ((header->flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00870 sec_lib_state_machine_trig(suite, EAP_IDENTITY_REQ); 00871 pana_handshake_copy(ptr, len, false, suite); 00872 } else { 00873 suite->pana_session.integrity_algorythm = integrity_algorythm; 00874 suite->pana_session.prf_algorythm = prf_algorythm; 00875 sec_lib_state_machine_trig(suite, PANA_START_RESPONSE); 00876 pana_handshake_copy(ptr, len, true, suite); 00877 } 00878 suite->retry_counter = 0; 00879 00880 } 00881 00882 buffer_free(buf); 00883 } 00884 00885 buffer_t *pana_auth_message_handler(buffer_t *buf, pana_header_t *header, sec_suite_t *suite) 00886 { 00887 if (!buf) { 00888 return NULL; 00889 } 00890 protocol_interface_info_entry_t *cur = buf->interface ; 00891 if (!cur) { 00892 return buffer_free(buf); 00893 } 00894 00895 uint16_t length = buffer_data_length(buf); 00896 uint8_t *ptr = buffer_data_pointer(buf); 00897 pana_avp_t avp_temp; 00898 00899 if (suite->pana_session.session_ready) { 00900 return buffer_free(buf); 00901 } 00902 00903 if (sec_check_suite_ptrs(suite) == 0) { 00904 tr_warn("SEC Lib Fail"); 00905 return buffer_free(buf); 00906 } 00907 00908 avp_temp.code = AVP_NONCE_CODE; 00909 if (pana_avp_discover(ptr, length, &avp_temp)) { 00910 if (avp_temp.len == 16) { 00911 if ((header->flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 00912 memcpy(suite->pana_session.pana_heap->client_nonce, avp_temp.avp_ptr, 16); 00913 } else { 00914 memcpy(suite->pana_session.pana_heap->agent_nonce, avp_temp.avp_ptr, 16); 00915 } 00916 //tr_debug("Pana:A_NONCE OK"); 00917 00918 } else { 00919 tr_debug("A_NONCE length fail, Len: %x", avp_temp.len); 00920 } 00921 } 00922 00923 avp_temp.code = AVP_EAP_PAYLOAD_CODE; 00924 if (pana_avp_discover(ptr, length, &avp_temp)) { 00925 ptr = avp_temp.avp_ptr; 00926 if (avp_temp.len > 4) { 00927 buf->buf_ptr = 0; 00928 buf->buf_end = avp_temp.len; 00929 memmove(buf->buf , ptr, avp_temp.len); 00930 return buf; 00931 } 00932 } 00933 00934 return buffer_free(buf); 00935 } 00936 00937 void pana_start_message_build(buffer_t *buf, sec_suite_t *suite) 00938 { 00939 uint8_t *ptr; 00940 //tr_debug("TX Pana Start Response"); 00941 buf->buf_ptr = PANA_HEADER_LENGTH; 00942 ptr = buffer_data_pointer(buf); 00943 ptr = pana_avp_32_bit_write(AVP_PRF_ALGORYTHM_CODE, suite->pana_session.prf_algorythm, ptr); 00944 ptr = pana_avp_32_bit_write(AVP_INTEGRIRTY_ALGORYTHM_CODE, suite->pana_session.integrity_algorythm, ptr); 00945 if (suite->pana_session.key_warp) { 00946 ptr = pana_avp_32_bit_write(AVP_KEY_WRAP_ALG_CODE, suite->pana_session.key_wrap, ptr); 00947 } 00948 buffer_data_end_set(buf, ptr); 00949 pana_down(buf, suite); 00950 } 00951 00952 00953 00954 void eap_tls_payload_push(buffer_t *buf) 00955 { 00956 arm_event_s event = { 00957 .receiver = pana_tasklet_id, 00958 .sender = 0, 00959 .data_ptr = buf, 00960 .event_type = ARM_PANA_TLS_CB, 00961 .priority = ARM_LIB_HIGH_PRIORITY_EVENT, 00962 }; 00963 if (eventOS_event_send(&event) != 0) { 00964 tr_warn("Free Buffer if fail"); 00965 buf->session_ptr = NULL; 00966 buffer_free(buf); 00967 } 00968 } 00969 00970 void pana_free_dynamic_ram(sec_suite_t *suite) 00971 { 00972 if (suite->pana_session.pana_heap) { 00973 tr_debug("Free Pana Heap"); 00974 ns_dyn_mem_free(suite->pana_session.pana_heap); 00975 suite->pana_session.pana_heap = NULL; 00976 } 00977 eap_fragmentation_init(suite); 00978 } 00979 00980 static void pana_key_calc(bool enc_key, sec_suite_t *suite) 00981 { 00982 pana_heap_t *pheap = suite->pana_session.pana_heap; 00983 00984 //tr_debug("Pana Auth verify. MSK: %s", trace_array(suite->pana_session.MSK, 64) ); 00985 SHALIB_init_HMAC(pheap->MSK, 64); 00986 if (enc_key) { 00987 //tr_debug("Cal Pana En Key start"); 00988 SHALIB_push_data_HMAC(PANA_PAA_ENC_KEY_STRING, 18); 00989 } else { 00990 SHALIB_push_data_HMAC(PANA_AUTH_STRING, 9); 00991 } 00992 00993 //tr_debug("Handshake data: %s", trace_array(pheap->pana_handshake, pheap->handshake_len)); 00994 SHALIB_push_data_HMAC(pheap->pana_handshake, pheap->handshake_len); 00995 // tr_debug("Handshake data"); 00996 // tr_debug("C Nonce: %s", trace_array(pheap->client_nonce, 16) ); 00997 SHALIB_push_data_HMAC(pheap->client_nonce, 16); 00998 // tr_debug("A Nonce: %s", trace_array(pheap->agent_nonce, 16) ); 00999 SHALIB_push_data_HMAC(pheap->agent_nonce, 16); 01000 uint8_t temp32_buf[4]; 01001 // tr_debug("Key ID: %s", trace_array(temp32_buf, 4) ); 01002 common_write_32_bit(suite->pana_session.pana_key_id, temp32_buf); 01003 SHALIB_push_data_HMAC(temp32_buf, 4); 01004 SHALIB_push_data_HMAC(&(const uint8_t) { 1 }, 1); 01005 if (enc_key) { 01006 uint8_t *key_ptr = suite->pana_session.pana_PAA_enc_key; 01007 01008 SHALIB_finish_HMAC(key_ptr, 4); 01009 } else { 01010 SHALIB_finish_HMAC(suite->pana_session.pana_auth_key, 8); 01011 } 01012 } 01013 01014 void pana_key_calculation(sec_suite_t *suite) 01015 { 01016 pana_key_calc(false, suite); 01017 pana_key_calc(true, suite); 01018 } 01019 01020 void pana_auth_hash_calc(uint8_t *data_ptr, uint16_t data_length, uint8_t *key) 01021 { 01022 SHALIB_init_HMAC(key, 32); 01023 SHALIB_push_data_HMAC(data_ptr, data_length); 01024 data_ptr += (data_length -16); 01025 SHALIB_finish_HMAC(data_ptr, 4); 01026 } 01027 01028 #ifdef ECC 01029 static void certificate_copy_block(const arm_certificate_chain_entry_s *rx_chain_info, certificate_chain_internal_t *cert) 01030 { 01031 uint8_t i; 01032 cert->chain_length = rx_chain_info->chain_length; 01033 for (i = 0; i < cert->chain_length; i++) { 01034 //Copy Certi 01035 cert->certi_chain[i] = rx_chain_info->cert_chain[i]; 01036 cert->certi_len[i] = rx_chain_info->cert_len[i]; 01037 //Copy Cur Key 01038 cert->key_chain[i] = rx_chain_info->key_chain[i]; 01039 } 01040 } 01041 #endif 01042 01043 int8_t pana_interface_certificate_chain_set(const arm_certificate_chain_entry_s *chain_info) 01044 { 01045 #ifdef ECC 01046 if (!chain_info) { 01047 return -1; 01048 } 01049 certificate_chain_internal_t temp_certi; 01050 certificate_copy_block(chain_info, &temp_certi); 01051 return x509_cetificate_chain_push(SEC_NWK_AUTHENTICATION_CERTI_CHAIN, &temp_certi); 01052 #else 01053 (void) chain_info; 01054 return -1; 01055 #endif 01056 } 01057 01058 #endif /*PANA*/ 01059 //************************ECC Certificates end 01060 01061 /* end of file */
Generated on Tue Jul 12 2022 18:18:46 by
