init
Embed:
(wiki syntax)
Show/hide line numbers
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 13:25:01 by
1.7.2