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.
Dependencies: nRF51_Vdd TextLCD BME280
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 Jul 12 2022 15:15:55 by
