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.
Fork of OmniWheels by
pana_server.c
00001 /* 00002 * Copyright (c) 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 "6LoWPAN/NVM/nwk_nvm.h" 00057 00058 #ifdef PANA 00059 #ifdef PANA_SERVER_API 00060 00061 #define TRACE_GROUP "PanS" 00062 static pana_server_base_t *NS_LARGE pana_server_base = NULL; 00063 static pana_server_update_cb *pana_nvm_storage_cb = NULL; 00064 static pana_server_session_get_cb *pana_server_nvm_get = NULL; 00065 static pana_server_session_get_by_id_cb *pana_server_nvm__session_get = NULL; 00066 static void (*pana_key_update_process_ready)(void) = 0; 00067 static uint8_t *pana_nvm_buffer = 0; 00068 00069 static void pana_server_packet_handler(buffer_t *buf); 00070 static int8_t pana_server_init(int8_t nwk_id, const uint8_t *network_key_material, uint8_t supported_chipher_suites, uint32_t key_update_delay); 00071 static pana_server_base_t * pana_server_staructure_allocate(void); 00072 static pana_key_material_t *pana_server_key_get(bool primary); 00073 static void pana_server_set_random_key_value(uint8_t *network_key_material); 00074 static void pana_server_material_read(const uint8_t *ptr); 00075 static void pana_server_material_write(uint8_t *ptr); 00076 static void pana_server_client_save_to_nvm(sec_suite_t *suite, pana_nvm_update_process_t nvm_event); 00077 static uint8_t *pana_avp_zip_key_material(uint8_t *dptr, uint8_t *key_info, uint32_t message_seq, sec_suite_t *suite); 00078 static void pana_client_session_init(sec_suite_t *suite); 00079 00080 static bool pana_auth_msg_validate(uint8_t *ptr, uint16_t length, uint8_t *key); 00081 static void pana_pna_response_build(buffer_t *buf, uint8_t operation, pana_header_t *header, sec_suite_t *suite); 00082 static void pana_client_authentication_fail(sec_suite_t *suite); 00083 static void pana_key_update_delivery_ready(void); 00084 static void pana_server_build_key_push(buffer_t *buf, sec_suite_t *suite); 00085 static void pana_success_server_build(buffer_t *buf, sec_suite_t *suite); 00086 static void pana_server_state_machine_func(sec_suite_t *suite); 00087 00088 00089 static uint8_t *pana_avp_zip_key_material(uint8_t *dptr, uint8_t *key_info, uint32_t message_seq, sec_suite_t *suite) 00090 { 00091 //SET AVP BASE 00092 dptr = pana_avp_base_write(AVP_ENCRYPT_ALGORITHM_CODE, 32, dptr, 0, 0); 00093 uint8_t *ptr = dptr; 00094 dptr = pana_avp_vendor_id_write_n_bytes(PANA_EAP_KEYWRAP_TYPE, 18, key_info, dptr, ZIGBEE_VENDOR_ID); 00095 //Crypt Key Info 00096 pana_ccm_data_crypt(ptr, 32, AES_CCM_ENCRYPT, message_seq, suite); 00097 return dptr; 00098 } 00099 00100 static pana_server_base_t * pana_server_staructure_allocate(void) 00101 { 00102 pana_server_base_t *server = ns_dyn_mem_alloc(sizeof(pana_server_base_t)); 00103 if (server) { 00104 memset(server, 0, sizeof(pana_server_base_t)); 00105 } 00106 return server; 00107 } 00108 00109 static pana_key_material_t *pana_server_key_get(bool primary) 00110 { 00111 if (primary) { 00112 return &pana_server_base->sec_key_material[pana_server_base->primary_material]; 00113 } 00114 00115 if (pana_server_base->primary_material) { 00116 return &pana_server_base->sec_key_material[0]; 00117 } 00118 00119 return &pana_server_base->sec_key_material[1]; 00120 } 00121 00122 static void pana_server_set_random_key_value(uint8_t *network_key_material) 00123 { 00124 randLIB_get_n_bytes_random(network_key_material, 16); 00125 } 00126 00127 static void pana_server_material_write(uint8_t *ptr) 00128 { 00129 pana_key_material_t *key_ptr; 00130 ptr = common_write_32_bit(pana_server_base->pana_key_id, ptr); 00131 ptr = common_write_32_bit(pana_server_base->session_lifetime, ptr); 00132 ptr = common_write_32_bit(pana_server_base->key_wrap, ptr); 00133 ptr = common_write_32_bit(pana_server_base->prf_algorythm, ptr); 00134 ptr = common_write_32_bit(pana_server_base->integrity_algorythm, ptr); 00135 ptr = common_write_32_bit(pana_server_base->next_session_id, ptr); 00136 ptr = common_write_32_bit(pana_server_base->key_update_delay, ptr); 00137 ptr = common_write_32_bit(pana_server_base->pana_key_update_delay_used, ptr); //32 00138 *ptr++ = pana_server_base->supported_chipher_suites; 00139 *ptr++ = pana_server_base->auth_cnt; 00140 *ptr++ = pana_server_base->primary_material; 00141 key_ptr = &pana_server_base->sec_key_material[0]; 00142 *ptr++ = key_ptr->key_id; 00143 memcpy(ptr, key_ptr->key_material, 16); 00144 ptr += 16;//52 00145 key_ptr = &pana_server_base->sec_key_material[1]; 00146 *ptr++ = key_ptr->key_id; 00147 memcpy(ptr, key_ptr->key_material, 16); 00148 ptr += 16; //69 00149 00150 if (pana_server_base->pana_key_update) { 00151 pana_key_update_t *pku = pana_server_base->pana_key_update; 00152 *ptr++ = 1; 00153 *ptr++ = pku->key_id; 00154 ptr = common_write_16_bit(pku->key_delivery_cnt, ptr); //73 00155 memcpy(ptr, pku->new_key_material, 16); // 89 00156 } else { 00157 *ptr = 0; //70 00158 } 00159 00160 } 00161 00162 static void pana_server_material_read(const uint8_t *ptr) 00163 { 00164 pana_key_material_t *key_ptr; 00165 //Set Stored setup 00166 pana_server_base->pana_key_id = common_read_32_bit(ptr); 00167 ptr += 4; 00168 pana_server_base->session_lifetime = common_read_32_bit(ptr); 00169 ptr += 4; 00170 pana_server_base->key_wrap = common_read_32_bit(ptr); 00171 ptr += 4; 00172 pana_server_base->prf_algorythm = common_read_32_bit(ptr); 00173 ptr += 4; 00174 pana_server_base->integrity_algorythm = common_read_32_bit(ptr); 00175 ptr += 4; 00176 pana_server_base->next_session_id = common_read_32_bit(ptr); 00177 ptr += 4; 00178 pana_server_base->key_update_delay = common_read_32_bit(ptr); 00179 ptr += 4; 00180 pana_server_base->pana_key_update_delay_used = common_read_32_bit(ptr); 00181 ptr += 4; 00182 pana_server_base->supported_chipher_suites = *ptr++; 00183 pana_server_base->auth_cnt = *ptr++; 00184 pana_server_base->primary_material = *ptr++; 00185 00186 key_ptr = &pana_server_base->sec_key_material[0]; 00187 key_ptr->key_id = *ptr++; 00188 memcpy(key_ptr->key_material, ptr, 16); 00189 tr_debug("KID0: %02x, %s", key_ptr->key_id, trace_array(ptr, 16)); 00190 ptr += 16; 00191 00192 key_ptr = &pana_server_base->sec_key_material[1]; 00193 key_ptr->key_id = *ptr++; 00194 memcpy(key_ptr->key_material, ptr, 16); 00195 tr_debug("KID1: %02x, %s", key_ptr->key_id, trace_array(ptr, 16)); 00196 ptr += 16; 00197 00198 uint8_t key_update = *ptr++; 00199 if (key_update) { 00200 pana_key_update_t *pku = ns_dyn_mem_temporary_alloc(sizeof(pana_key_update_t)); 00201 if (pku) { 00202 pku->key_id = *ptr++; 00203 pku->key_delivery_cnt = common_read_16_bit(ptr); 00204 ptr += 2; 00205 memcpy(pku->new_key_material, ptr, 16); 00206 pana_server_base->pana_key_update = pku; 00207 tr_debug("Key Update Process active"); 00208 } 00209 } 00210 } 00211 00212 00213 static int8_t pana_server_init(int8_t nwk_id, const uint8_t *network_key_material, uint8_t supported_chipher_suites, uint32_t key_update_delay) 00214 { 00215 if (!pana_socket_init(pana_server_packet_handler, pana_server_state_machine_func, tls_server_up)) { 00216 return -1; 00217 } 00218 00219 int8_t ret_val = -1; 00220 sec_suite_list_clean(); 00221 00222 //Allocate 00223 if (pana_server_base == 0) { 00224 pana_server_base = pana_server_staructure_allocate(); 00225 } else { 00226 if (pana_server_base->network_interface_id != nwk_id) { 00227 tr_debug("UnKnow id"); 00228 return -2; 00229 } 00230 } 00231 if (pana_server_base) { 00232 00233 pana_server_base->primary_material = 0; 00234 pana_key_material_t *key_info = pana_server_key_get(false); 00235 key_info->key_id = 0; 00236 key_info = pana_server_key_get(true); 00237 00238 00239 key_info->key_id = 1; 00240 if (network_key_material) { 00241 memcpy(key_info->key_material, network_key_material, 16); 00242 } else { 00243 pana_server_set_random_key_value(key_info->key_material); 00244 } 00245 pana_server_base->auth_cnt = 0; 00246 pana_server_base->pana_key_id = 1; 00247 pana_server_base->session_lifetime = 0xffffffff; 00248 pana_server_base->key_wrap = 1; 00249 pana_server_base->prf_algorythm = 5; 00250 pana_server_base->integrity_algorythm = 0x0c; 00251 pana_server_base->next_session_id = 1; 00252 pana_server_base->key_update_delay = 0; 00253 pana_server_base->supported_chipher_suites = supported_chipher_suites; 00254 pana_server_base->pana_key_update = 0; 00255 pana_server_base->open_pana_authentication_cnt = 0; 00256 pana_server_base->network_interface_id = nwk_id; 00257 pana_server_base->pana_key_update_delay_used = key_update_delay; 00258 if (pana_nvm_storage_cb) { 00259 pana_server_material_write(pana_nvm_buffer); 00260 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 00261 } 00262 ret_val = 0; 00263 } 00264 return ret_val; 00265 } 00266 00267 void pana_key_update_delivery_ready(void) 00268 { 00269 if (pana_server_base && pana_server_base->pana_key_update) { 00270 if (pana_server_base->pana_key_update->key_delivery_cnt-- == 1) { 00271 if (pana_key_update_process_ready) { 00272 pana_server_base->key_update_delay = 1; 00273 } else { 00274 pana_server_base->key_update_delay = pana_server_base->pana_key_update_delay_used; 00275 if (pana_server_base->key_update_delay == 0) { 00276 tr_debug("Delivery Ready"); 00277 pana_server_base->key_update_delay = 1; 00278 } 00279 } 00280 //NVM UPDAte for timer and key material 00281 } 00282 if (pana_nvm_storage_cb) { 00283 pana_server_material_write(pana_nvm_buffer); 00284 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 00285 } 00286 00287 } 00288 } 00289 00290 /* Save and load stored settings to Pana server core */ 00291 static void pana_server_client_save_to_nvm(sec_suite_t *suite, pana_nvm_update_process_t nvm_event) 00292 { 00293 uint8_t *ptr = pana_nvm_buffer; 00294 pana_session_t *p_session = &suite->pana_session; 00295 /* static Part of every session */ 00296 ptr = common_write_16_bit(p_session->nvm_offset, ptr); 00297 memcpy(ptr, suite->session_address, 16); 00298 ptr += 16; 00299 ptr = common_write_16_bit(suite->session_port, ptr); 00300 ptr = common_write_32_bit(p_session->session_id, ptr); 00301 if (nvm_event == PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE) { 00302 tr_debug("Remove From NVM"); 00303 } else { 00304 /* First Encrypted sector start */ 00305 *ptr++ = suite->state; 00306 ptr = common_write_32_bit(suite->timer, ptr); 00307 uint8_t state = 0; 00308 if (p_session->key_warp) { 00309 state |= PANA_ST_KEY_WRAP; 00310 } 00311 00312 if (p_session->session_ready) { 00313 state |= PANA_ST_READY; 00314 } 00315 *ptr++ = state; //6 00316 ptr = common_write_32_bit(p_session->req_seq, ptr); 00317 ptr = common_write_32_bit(p_session->res_seq, ptr); 00318 *ptr++ = p_session->address_status; 00319 memcpy(ptr, p_session->session_relay_address, 16); 00320 ptr += 16; 00321 ptr = common_write_16_bit(p_session->relay_port, ptr); //37 bytes sector 00322 *ptr++ = p_session->auth_cnt; 00323 *ptr++ = p_session->nwk_key_id; 00324 memcpy(ptr, p_session->pana_auth_key, 32); 00325 ptr += 32; 00326 memcpy(ptr, p_session->pana_PAA_enc_key, 16); 00327 ptr += 16; 00328 ptr = common_write_32_bit(p_session->pana_key_id, ptr); 00329 ptr = common_write_32_bit(p_session->session_lifetime, ptr); 00330 *ptr++ = p_session->eap_id_seq; 00331 00332 } 00333 } 00334 00335 static void pana_server_client_restore_from_nvm(sec_suite_t *suite, const uint8_t *ptr) 00336 { 00337 00338 pana_session_t *p_session = &suite->pana_session; 00339 p_session->nvm_offset = common_read_16_bit(ptr); 00340 ptr += 2; 00341 memcpy(suite->session_address, ptr, 16); 00342 ptr += 16; 00343 suite->session_port = common_read_16_bit(ptr); 00344 ptr += 2; 00345 p_session->session_id = common_read_32_bit(ptr); 00346 ptr += 4; //24 00347 00348 suite->state = (sec_state_machine_t) * ptr++; 00349 suite->timer = common_read_32_bit(ptr); 00350 ptr += 4; 00351 uint8_t state = *ptr++; 00352 p_session->user_server = true; 00353 if (state & PANA_ST_KEY_WRAP) { 00354 p_session->key_warp = true; 00355 } else { 00356 p_session->key_warp = false; 00357 } 00358 00359 if (state & PANA_ST_READY) { 00360 p_session->session_ready = true; 00361 } else { 00362 p_session->session_ready = false; 00363 } 00364 00365 p_session->req_seq = common_read_32_bit(ptr); 00366 ptr += 4; 00367 p_session->res_seq = common_read_32_bit(ptr); 00368 ptr += 4; 00369 p_session->address_status = *ptr++; 00370 memcpy(p_session->session_relay_address, ptr, 16); 00371 ptr += 16; 00372 p_session->relay_port = common_read_16_bit(ptr); 00373 ptr += 2; 00374 p_session->auth_cnt = *ptr++; 00375 p_session->nwk_key_id = *ptr++; 00376 memcpy(p_session->pana_auth_key, ptr, 32); 00377 ptr += 32; 00378 memcpy(p_session->pana_PAA_enc_key, ptr, 16); 00379 ptr += 16; 00380 p_session->pana_key_id = common_read_32_bit(ptr); 00381 ptr += 4; 00382 p_session->session_lifetime = common_read_32_bit(ptr); 00383 ptr += 4; 00384 p_session->eap_id_seq = *ptr++; 00385 } 00386 00387 void pana_session_nvm_udate(sec_suite_t *suite, pana_nvm_update_process_t update_event) 00388 { 00389 if (pana_nvm_storage_cb) { 00390 if (pana_server_base) { 00391 pana_server_client_save_to_nvm(suite, update_event); 00392 suite->pana_session.nvm_offset = pana_nvm_storage_cb(update_event); 00393 } 00394 } 00395 } 00396 00397 static void pana_client_session_init(sec_suite_t *suite) 00398 { 00399 suite->pana_session.session_ready = false; 00400 suite->pana_session.key_warp = true; 00401 suite->pana_session.user_server = true; 00402 suite->pana_session.session_id = pana_server_base->next_session_id; // Take Random Number 00403 pana_server_base->next_session_id++; 00404 suite->pana_session.req_seq = randLIB_get_32bit(); 00405 suite->pana_session.res_seq = 0; 00406 suite->pana_session.eap_id_seq = randLIB_get_8bit(); 00407 suite->pana_session.eap_id_seq &= 63; 00408 suite->pana_session.eap_id_seq++; 00409 00410 00411 suite->pana_session.prf_algorythm = pana_server_base->prf_algorythm; 00412 suite->pana_session.integrity_algorythm = pana_server_base->integrity_algorythm; 00413 suite->pana_session.key_wrap = pana_server_base->key_wrap; 00414 00415 //init eap fragmentation 00416 suite->pana_session.pana_key_id = pana_server_base->pana_key_id; 00417 suite->pana_session.session_lifetime = pana_server_base->session_lifetime; 00418 suite->supported_chipher_suites = pana_server_base->supported_chipher_suites; 00419 00420 //suite->setups &= ~TLS_HANSHAKE_HASH; 00421 suite->setups = TLS_SERVER_MODE; 00422 suite->timer = 1; 00423 suite->state = PANA_REQUEST_TX; 00424 suite->retry_counter = 0; 00425 eap_fragmentation_init(suite); 00426 suite->pana_session.pana_heap->handshake_len = 0; 00427 suite->pana_session.pana_heap->handshake_req_offset = 0; 00428 randLIB_get_n_bytes_random(suite->pana_session.pana_heap->agent_nonce, 16); 00429 00430 if (pana_nvm_storage_cb) { 00431 pana_server_material_write(pana_nvm_buffer); 00432 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 00433 } 00434 } 00435 00436 00437 00438 static bool pana_auth_msg_validate(uint8_t *ptr, uint16_t length, uint8_t *key) 00439 { 00440 pana_avp_t authency; 00441 authency.code = AVP_AUTHENCY_CODE; 00442 00443 if (!pana_avp_discover(ptr, length, &authency)) { 00444 return false; 00445 } 00446 00447 if (!pana_auth_check(ptr, length, authency.avp_ptr, key)) { 00448 tr_debug("Auth Fail"); 00449 return false; 00450 } 00451 return true; 00452 } 00453 00454 static void pana_server_set_key_material(uint8_t *key_material, bool new_key, uint8_t auth_cnt) 00455 { 00456 00457 if (new_key) { 00458 memcpy(key_material, pana_server_base->pana_key_update->new_key_material, 16); 00459 key_material += 16; 00460 *key_material++ = pana_server_base->pana_key_update->key_id; 00461 00462 } else { 00463 pana_key_material_t *primary_key = pana_server_key_get(true); 00464 memcpy(key_material, primary_key->key_material, 16); 00465 key_material += 16; 00466 *key_material++ = primary_key->key_id; 00467 } 00468 *key_material = auth_cnt; 00469 } 00470 00471 static void pana_pna_response_build(buffer_t *buf, uint8_t operation, pana_header_t *header, sec_suite_t *suite) 00472 { 00473 uint8_t *ptr; 00474 00475 header->type = PANA_MSG_PNA; 00476 header->flags &= ~PANA_FLAGS_REQUEST; 00477 00478 buf->buf_ptr = PANA_HEADER_LENGTH; 00479 ptr = buffer_data_pointer(buf); 00480 00481 if (operation == 4) { 00482 //Leave emtpy 00483 } else { 00484 uint8_t key_material[18]; 00485 if (operation == 3) { 00486 pana_server_set_key_material(key_material, true, suite->pana_session.auth_cnt); 00487 } else { 00488 pana_server_set_key_material(key_material, false, suite->pana_session.auth_cnt); 00489 } 00490 ptr = pana_avp_zip_key_material(ptr, key_material, header->seq, suite); 00491 } 00492 00493 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 00494 00495 buffer_data_end_set(buf, ptr); 00496 buf = build_pana_base(buf, header, suite); 00497 if (!buf) { 00498 return; 00499 } 00500 00501 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 00502 00503 //Encode Pana Auth 00504 if (buf->src_sa .address [0] == 0xfe) { 00505 pana_set_agend_address(buf, false, suite); 00506 } else { 00507 //Check IF need Relay 00508 pana_set_agend_address(buf, true, suite); 00509 } 00510 00511 if (suite->pana_session.address_status & 1) { 00512 buf = pana_relay_avp_build(buf, suite); 00513 if (buf) { 00514 header->flags = 0; 00515 header->type = PANA_MSG_RELAY; 00516 header->session_id = 0; 00517 header->seq = 0; 00518 buf = build_pana_base(buf, header, suite); 00519 } 00520 } 00521 00522 protocol_push(buf); 00523 } 00524 00525 00526 static void pana_complete_msg_parse(buffer_t *buf, pana_header_t *header, sec_suite_t *suite) 00527 { 00528 00529 uint16_t length = buffer_data_length(buf); 00530 uint8_t *ptr = buffer_data_pointer(buf); 00531 00532 if (sec_check_suite_ptrs(suite) == 0) { 00533 buffer_free(buf); 00534 return; 00535 } 00536 00537 if (header->flags & PANA_FLAGS_REQUEST) { 00538 buffer_free(buf); 00539 return; 00540 } 00541 00542 00543 uint32_t key_id = 0xffffffff; 00544 00545 bool key_id_parsed = false; 00546 pana_avp_t avp_temp; 00547 //Read Key id if they are coming 00548 00549 00550 avp_temp.code = AVP_KEY_ID_CODE; 00551 if (pana_avp_discover(ptr, length, &avp_temp) && avp_temp.len == 4) { 00552 key_id= common_read_32_bit(avp_temp.avp_ptr); 00553 key_id_parsed = true; 00554 } 00555 00556 00557 00558 if (key_id_parsed) { 00559 00560 if (!pana_auth_msg_validate(ptr, length, suite->pana_session.pana_auth_key)) { 00561 goto pana_failure; 00562 } 00563 00564 if (suite->pana_session.pana_key_id != key_id) { 00565 goto pana_failure; 00566 } 00567 tr_debug("Client AUTH_OK"); 00568 sec_lib_state_machine_trig(suite, PANA_READY); 00569 if (pana_server_base) { 00570 if (pana_server_base->open_pana_authentication_cnt) { 00571 pana_server_base->open_pana_authentication_cnt--; 00572 } 00573 } 00574 } else { 00575 sec_lib_state_machine_trig(suite, PANA_ERROR); 00576 } 00577 00578 buffer_free(buf); 00579 return; 00580 00581 pana_failure: 00582 tr_debug("Drop Key MSG"); 00583 sec_lib_state_machine_trig(suite, PANA_FAILURE); //shuold be calc 00584 buffer_free(buf); 00585 return; 00586 } 00587 00588 static void pana_server_finnish_error_build(buffer_t *buf, sec_suite_t *suite) 00589 { 00590 buf->buf_ptr = PANA_HEADER_LENGTH; 00591 uint8_t *ptr = buffer_data_pointer(buf); 00592 //tr_debug("End Pana and EAP"); 00593 uint8_t eap_status[4]; 00594 eap_header_build(eap_status, 4,EAP_FAILURE, suite->pana_session.eap_id_seq, 0); 00595 00596 ptr = pana_avp_32_bit_write(AVP_RESULT_CODE, 2, ptr); 00597 ptr = pana_avp_write_n_bytes(AVP_EAP_PAYLOAD_CODE, 4, eap_status, ptr); 00598 buffer_data_end_set(buf, ptr); 00599 } 00600 00601 static void sec_auth_ready(sec_suite_t *suite) { 00602 suite->timer = 0; 00603 tr_debug("Pana:OK"); 00604 suite->pana_session.session_ready = true; 00605 if (suite->state == PANA_READY) { 00606 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE); 00607 } 00608 00609 //Reset pointer 00610 suite->pana_session.auth_info = NULL; 00611 pana_free_dynamic_ram(suite); 00612 sec_suite_tls_free(suite, true); 00613 00614 } 00615 #ifdef ECC 00616 static uint32_t tls_backoff_random_timer_start(void) 00617 { 00618 return randLIB_get_random_in_range(2, 16); 00619 } 00620 #endif 00621 00622 static void pana_server_pana_error_handler(sec_suite_t *suite) 00623 { 00624 sec_lib_state_machine_lock(suite, PANA_ERROR); 00625 pana_client_authentication_fail(suite); 00626 seclib_session_clean(suite); 00627 } 00628 00629 00630 static void pana_server_state_machine_func(sec_suite_t *suite) 00631 { 00632 if (!suite) { 00633 return; 00634 } 00635 uint8_t general_tx = 0; 00636 switch (suite->state) { 00637 case PANA_ERROR: 00638 pana_server_pana_error_handler(suite); 00639 return; 00640 00641 case PANA_READY: 00642 case PANA_RE_VALID: 00643 case PANA_PULL_DONE: 00644 sec_auth_ready(suite); 00645 break; 00646 00647 case PRF_CALC: 00648 case PRF_CALC2: 00649 case TLS_ECC_CERTIFICATE_VERIFY_SIGNATURE: 00650 case TLS_ECC_MESSAGE_VERIFY: 00651 case TLS_ECC_CERTIFICATE_SIGNATURE_CHECK: 00652 case TLS_ECC_GENERATE_PUBLIC_KEY: 00653 case TLS_ECC_GENERATE_PREMASTER_SECRET: 00654 case TLS_ECC_SIGNATURE_MESSAGE: 00655 break; 00656 case TLS_HELLO_RX: 00657 case TLS_SERVER_KEY_EXCHANGE_RX: 00658 case TLS_SERVER_WAIT_CHANGE_CHIPHERSUITE: 00659 case TLS_CLIENT_KEY_EXCHANGE_RX: 00660 case TLS_CHANGE_CHIPHER: 00661 tr_debug("%02x", suite->state); 00662 tr_debug("Timeout"); 00663 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00664 general_tx = 1; 00665 break; 00666 00667 #ifdef ECC 00668 case TLS_ECC_GENERATE_PUBLIC_KEY_START: 00669 sec_ecc_gen_public_key_start(suite); 00670 break; 00671 00672 case TLS_ECC_MESSAGE_SERVER_VERIFY_START: 00673 case TLS_ECC_MESSAGE_VERIFY_START: 00674 if (suite->tls_session) { 00675 if (suite->tls_session->tls_heap) { 00676 int start = 0; 00677 tls_heap_t *theap = suite->tls_session->tls_heap; 00678 00679 if (theap->cert_temp_buf) { 00680 if (suite->state == TLS_ECC_MESSAGE_SERVER_VERIFY_START) { 00681 if (theap->signature_temp_buf == 0) { 00682 start = 1; 00683 } 00684 } 00685 } else { 00686 start = 1; 00687 } 00688 if (start) { 00689 tls_server_finnish_handle_start(suite); 00690 } else { 00691 tr_debug("Start Certi Check"); 00692 tls_certificate_signature_verify(suite); 00693 } 00694 } 00695 } 00696 break; 00697 case TLS_ECC_MESSAGE_VERIFY_START2: 00698 tls_ecc_verfify_start(suite); 00699 break; 00700 00701 case TLS_SERVER_ECC_PUB_KEY_GEN: 00702 if (sec_auth_re_check(suite)) { 00703 if (tls_server_certi_hash_copy(suite) == 0) { 00704 suite->timer = tls_backoff_random_timer_start(); 00705 } else { 00706 00707 suite->setups &= ~TLS_HANSHAKE_HASH; 00708 //PUBLIC key cal 00709 sec_lib_state_machine_trig(suite, TLS_ECC_GENERATE_PUBLIC_KEY_START); 00710 } 00711 } else { 00712 tr_debug("TLS_SERVER_ECC_PUB_KEY_GEN timeout"); 00713 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00714 general_tx = 1; 00715 //Alert Shuold send Here 00716 } 00717 break; 00718 00719 case TLS_ECC_CLIENT_SIGNATURE_START: 00720 sec_ecc_client_signature_start(suite); 00721 break; 00722 #endif 00723 case TLS_UPDATE_HAS_WITH_CERTIFICATE: 00724 #ifdef ECC 00725 if (sec_auth_re_check(suite)) { 00726 if (tls_certi_hash_copy(suite) == 0) { 00727 tr_warn("Server Certficate Alloc fail"); 00728 suite->timer = 4; 00729 } else { 00730 sec_lib_state_machine_trig(suite, TLS_ECC_CLIENT_SIGNATURE_START); 00731 } 00732 } else 00733 #endif 00734 { 00735 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00736 general_tx = 1; 00737 } 00738 break; 00739 00740 case TLS_TX_SERVER_KEY_EXCHANGE: 00741 #ifdef ECC 00742 if (sec_auth_re_check(suite)) { 00743 bool tx_start_OK = false; 00744 if (suite->pana_session.assy_length || suite->pana_session.frag_length || suite->pana_session.packet_delivered) { 00745 //Build next EAP Packet 00746 //tr_debug("TX same again fragment piece"); 00747 tx_start_OK = pana_eap_frag_re_tx(suite); 00748 00749 } else { 00750 if (tls_pana_server_exchange_build(suite)) { 00751 suite->pana_session.packet_delivered = false; 00752 tx_start_OK = true; 00753 } 00754 00755 } 00756 if (tx_start_OK) { 00757 pana_timeout_timer_set(suite, suite->state); 00758 } else { 00759 suite->timer = tls_backoff_random_timer_start(); 00760 } 00761 } else 00762 #endif 00763 { 00764 if (suite->pana_session.assy_length) { 00765 buffer_free(suite->pana_session.eap_assy_buf); 00766 suite->pana_session.eap_assy_buf = 0; 00767 suite->pana_session.assy_length = 0; 00768 suite->pana_session.assy_off_set = 0; 00769 } 00770 tr_debug("TLS_TX_SERVER_KEY_EXCHANGE timeout"); 00771 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00772 general_tx = 1; 00773 } 00774 break; 00775 00776 00777 default: 00778 general_tx = 1; 00779 break; 00780 } 00781 00782 if (general_tx) { 00783 if (sec_auth_re_check(suite)) { 00784 buffer_t *buf = buffer_get(140); 00785 if (buf) { 00786 buf->interface = suite->interface; 00787 suite->timer = 600; 00788 switch (suite->state) { 00789 case PANA_REQUEST_TX: 00790 pana_start_message_build(buf, suite); 00791 break; 00792 00793 case EAP_IDENTITY_REQ: 00794 pana_eap_identity_build(buf, suite); 00795 break; 00796 00797 case TLS_START: 00798 pana_eap_tls_start_build(buf, suite); 00799 break; 00800 00801 case TLS_SERVER_TX_SERVER_HELLO: 00802 tls_server_hello_build(buf, suite); 00803 pana_eap_down(buf, suite); 00804 break; 00805 00806 case TLS_KEY_CHANGE: 00807 //Print Handshake message 00808 tls_prepare_change_chipher_spec(suite); 00809 00810 tls_build_client_change_chipher_suite_finnish(buf, suite); 00811 tls_nonce_update(suite->tls_session->tls_nonce_explit); 00812 tr_debug("Set Keys"); 00813 pana_eap_down(buf, suite); 00814 00815 break; 00816 00817 case TLS_EAP_END_PANA_VERIFY: 00818 pana_success_server_build(buf, suite); 00819 break; 00820 00821 00822 case PANA_KEY_UPDATE: 00823 pana_server_build_key_push(buf, suite); 00824 break; 00825 00826 case PANA_FAILURE: 00827 pana_server_finnish_error_build(buf, suite); 00828 pana_down(buf, suite); 00829 00830 break; 00831 00832 case TLS_FINISH: 00833 case TLS_ALERT: 00834 eap_fragmentation_init(suite); 00835 pana_eap_tls_finnish_build(buf, suite); 00836 break; 00837 00838 00839 case TLS_ALERT_CLOSE_FATAL: 00840 case TLS_ALERT_INTERNAL: 00841 case TLS_ALERT_CHIPHER_SUITE: 00842 case TLS_ALERT_DECRYPT: 00843 case TLS_ALERT_BAD_CERTIFICATE: 00844 00845 eap_fragmentation_init(suite); 00846 00847 suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY); 00848 #ifdef ECC 00849 { 00850 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00851 if (tls_heap) { 00852 tls_ecc_heap_free(tls_heap); 00853 } 00854 } 00855 #endif 00856 if (suite->state == TLS_ALERT_DECRYPT) { 00857 tls_alert_build(buf, ALERT_BAD_RECORD); 00858 } else if (suite->state == TLS_ALERT_CLOSE_FATAL) { 00859 tls_alert_build(buf, ALERT_INTERNAL_ERR); 00860 } else if (suite->state == TLS_ALERT_BAD_CERTIFICATE) { 00861 00862 tls_alert_build(buf, ALERT_BAD_CERTIFICATE); 00863 } else { 00864 tls_alert_build(buf, ALERT_INTERNAL_ERR); 00865 00866 } 00867 pana_eap_down(buf, suite); 00868 break; 00869 00870 00871 default: 00872 tr_debug("Unknown Packet. State: %x", suite->state); 00873 buf = buffer_free(buf); 00874 break; 00875 } 00876 00877 } else { 00878 suite->timer = 2; 00879 } 00880 } else { 00881 tr_debug("Tls Auth Re TX limit Reached. State: %x", suite->state); 00882 00883 switch (suite->state) { 00884 case TLS_SERVER_TX_SERVER_HELLO: 00885 case TLS_KEY_CHANGE: 00886 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00887 break; 00888 00889 default: 00890 if (suite->state == PANA_KEY_UPDATE) { 00891 tr_warn("Key Delivery Fail"); 00892 pana_key_update_delivery_ready(); 00893 } 00894 pana_server_pana_error_handler(suite); 00895 break; 00896 } 00897 } 00898 } 00899 } 00900 00901 static void pana_server_tls_session_init(sec_suite_t *suite) 00902 { 00903 //Generate TLS SESSION 00904 tls_session_id_genrate(suite->tls_session->tls_session_id, 4); 00905 suite->tls_session->id_length = 4; 00906 memset(suite->tls_session->tls_nonce_explit, 0, 8); 00907 } 00908 00909 static void pana_server_session_address_set_for_relay(sec_suite_t *suite, buffer_t *buf) 00910 { 00911 memcpy(suite->session_address, buf->dst_sa .address , 16); 00912 suite->session_port = buf->dst_sa .port ; 00913 suite->pana_session.address_status = 1; 00914 //Copy Relay Address 00915 memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16); 00916 suite->pana_session.relay_port = buf->src_sa .port ; 00917 memcpy(&(buf->src_sa ), &(buf->dst_sa ), sizeof(sockaddr_t)); 00918 00919 } 00920 00921 static sec_suite_t *pana_server_session_restore(uint8_t *nvm_data, protocol_interface_info_entry_t *interface) 00922 { 00923 sec_suite_t *suite = sec_lib_security_session_allocate(false); 00924 if (!suite) { 00925 return NULL; 00926 } 00927 //Restore 00928 pana_server_client_restore_from_nvm(suite, nvm_data); 00929 //Init Satic Information At ZIP 00930 suite->setups = TLS_SERVER_MODE; 00931 suite->interface = interface; 00932 suite->pana_session.key_wrap = pana_server_base->key_wrap; 00933 suite->pana_session.prf_algorythm = pana_server_base->prf_algorythm; 00934 suite->pana_session.integrity_algorythm = pana_server_base->integrity_algorythm; 00935 return suite; 00936 } 00937 00938 00939 static sec_suite_t * pana_server_get_session_by_session_id(uint32_t session_id, protocol_interface_info_entry_t *interface) 00940 { 00941 sec_suite_t *suite = sec_suite_selected_pana_session(session_id); 00942 if (!suite && pana_server_nvm__session_get) { 00943 if (!pana_server_nvm__session_get(session_id)) { 00944 return NULL; 00945 } 00946 suite = pana_server_session_restore(pana_nvm_buffer, interface); 00947 } 00948 00949 return suite; 00950 } 00951 00952 static sec_suite_t *pana_server_get_session_by_address(uint8_t *ll_address, protocol_interface_info_entry_t *interface) 00953 { 00954 sec_suite_t *suite = sec_suite_selected_address(ll_address); 00955 00956 if (!suite && pana_server_nvm_get) { 00957 if (!pana_server_nvm_get(ll_address)) { 00958 return NULL; 00959 } 00960 suite = pana_server_session_restore(pana_nvm_buffer, interface); 00961 } 00962 00963 return suite; 00964 } 00965 00966 00967 static void pana_server_packet_handler(buffer_t *buf) 00968 { 00969 bool relay_pack = false; 00970 sec_suite_t *suite = NULL; 00971 pana_header_t header; 00972 if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) { 00973 buffer_free(buf); 00974 return; 00975 } 00976 buffer_data_strip_header(buf, PANA_HEADER_LENGTH); 00977 00978 00979 if (header.type == PANA_MSG_RELAY) { 00980 /** Parse Relay */ 00981 buf = pana_relay_parse(buf); 00982 if (buf) { 00983 /** Parse Relayed Packet */ 00984 if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) { 00985 buffer_free(buf); 00986 return; 00987 } 00988 buffer_data_strip_header(buf, PANA_HEADER_LENGTH); 00989 relay_pack = true; 00990 } 00991 if (buf == 0) { 00992 tr_debug("Drop Pana Relay Pack"); 00993 return; 00994 } 00995 } 00996 00997 //Server will use address and session when address is LL and GP use only ID 00998 //SERVER: if type is relay parse relay address and save 00999 if (header.type == PANA_MSG_PNA) { 01000 //tr_debug("PNA"); 01001 suite = pana_server_get_session_by_session_id(header.session_id, buf->interface ); 01002 if (!suite || !(header.flags & PANA_FLAGS_PING)) { 01003 buffer_free(buf); 01004 return; 01005 } 01006 if (!pana_auth_msg_validate(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key)) { 01007 buffer_free(buf); 01008 return; 01009 } 01010 01011 if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 01012 if (suite->pana_session.req_seq != header.seq) { 01013 tr_debug("PNA RES:Drop Old seq"); 01014 buffer_free(buf); 01015 return; 01016 } 01017 01018 suite->pana_session.req_seq++; 01019 01020 if (suite->pana_session.session_ready ) { 01021 01022 tr_debug("Key push OK"); 01023 if (suite->state == PANA_KEY_UPDATE) { 01024 sec_lib_state_machine_lock(suite, PANA_READY); 01025 tr_debug("Key Delivery OK"); 01026 //Call SEC KEY UPDATE 01027 //tr_debug("NVM SEQ Update by Key Pull Ready"); 01028 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE); 01029 pana_key_update_delivery_ready(); 01030 } 01031 } 01032 buffer_free(buf); 01033 return; 01034 } else { 01035 if (suite->pana_session.res_seq == 0) { 01036 suite->pana_session.res_seq = header.seq; 01037 } else { 01038 if ((suite->pana_session.res_seq + 1) == header.seq) { 01039 suite->pana_session.res_seq = header.seq; 01040 } else if (suite->pana_session.res_seq != header.seq) { 01041 tr_debug("PNA REQ:Drop unknow Request"); 01042 buffer_free(buf); 01043 return; 01044 } 01045 } 01046 } 01047 01048 if (relay_pack) { 01049 pana_server_session_address_set_for_relay(suite, buf); 01050 01051 } else { 01052 if ((buf->src_sa .address [0] != 0xfe)) { 01053 //tr_debug("SET GP & SEQ"); 01054 suite->pana_session.address_status = 0; 01055 memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16); 01056 suite->pana_session.relay_port = buf->src_sa .port ; 01057 suite->session_port = buf->src_sa .port ; 01058 01059 } else { 01060 if (memcmp(suite->session_address, buf->src_sa .address , 16) != 0) { 01061 tr_debug("PNA REQ:Drop By Address"); 01062 buffer_free(buf); 01063 return; 01064 } 01065 01066 //Shuold Update Relay Information 01067 suite->pana_session.address_status = 2; 01068 suite->session_port = buf->src_sa .port ; 01069 lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address ); 01070 } 01071 } 01072 01073 if (!suite->pana_session.session_ready) { 01074 buffer_free(buf); 01075 return; 01076 } 01077 01078 //KEY PULL 01079 pana_avp_t avp_temp; 01080 //Read Resul and Key id if they are coming 01081 avp_temp.code = PANA_EAP_KEYREQ_TYPE; 01082 avp_temp.len = 0; 01083 uint8_t key_delivery; 01084 if (!pana_avp_discover(buffer_data_pointer(buf), buffer_data_length(buf), &avp_temp)) { 01085 key_delivery = 2; 01086 avp_temp.avp_ptr = NULL; 01087 } else { 01088 if (avp_temp.len != 2) { 01089 buffer_free(buf); 01090 return; 01091 } 01092 uint8_t *ptr = avp_temp.avp_ptr; 01093 pana_key_material_t *primary_key = pana_server_key_get(true); 01094 tr_debug("Network KEY Request: %s", trace_array(ptr, 2)); 01095 if (*ptr++ & 1) { 01096 tr_debug("REQ bit, 1"); 01097 //if(*ptr == pana_server_base->network_key_id) 01098 if (*ptr == primary_key->key_id) { 01099 if (pana_server_base->pana_key_update) { 01100 key_delivery = 3; 01101 } else { 01102 key_delivery = 4; 01103 } 01104 } else { 01105 key_delivery = 2; 01106 } 01107 01108 } else { 01109 //if(*ptr == pana_server_base->network_key_id) 01110 if (*ptr == primary_key->key_id) { 01111 key_delivery = 2; 01112 } else { 01113 key_delivery = 4; 01114 } 01115 } 01116 } 01117 01118 tr_debug("NVM SEQ update BY Client key Pull"); 01119 pana_pna_response_build(buf, key_delivery, &header, suite); 01120 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE); 01121 return; 01122 } else if (header.type == PANA_MSG_PCI) { 01123 if (relay_pack) { 01124 suite = pana_server_get_session_by_address(buf->dst_sa .address , buf->interface ); 01125 } else { 01126 suite = pana_server_get_session_by_address(buf->src_sa .address , buf->interface ); 01127 } 01128 if (suite) { 01129 //Check State 01130 //if state ready create new session 01131 if (!suite->pana_session.session_ready ) { 01132 tr_debug("PCI received; Discard unfinished session and start a new one"); 01133 if (pana_server_base->open_pana_authentication_cnt) { 01134 pana_server_base->open_pana_authentication_cnt--; 01135 } 01136 sec_suite_remove(suite); 01137 suite = 0; 01138 } else { 01139 tr_debug("Accept new session"); 01140 } 01141 } 01142 01143 if (suite) { 01144 if (suite->pana_session.pana_heap == NULL) { 01145 suite->pana_session.pana_heap = pana_heap_structure_allocate(); 01146 } 01147 if (suite->tls_session == NULL) { 01148 suite->tls_session = amr_tls_session_allocate(); 01149 if (suite->tls_session == NULL) { 01150 if (suite->pana_session.pana_heap) { 01151 ns_dyn_mem_free(suite->pana_session.pana_heap); 01152 suite->pana_session.pana_heap = NULL; 01153 } 01154 } 01155 } 01156 if (suite->pana_session.pana_heap) { 01157 01158 arm_tls_session_clear(suite->tls_session); 01159 suite->tls_session->tls_heap = tls_heap_allocate(); 01160 if (suite->tls_session->tls_heap) { 01161 //Generate TLS SESSION 01162 pana_server_tls_session_init(suite); 01163 pana_client_session_init(suite); 01164 tr_debug("UPdate Auth Counter"); 01165 if (relay_pack) { 01166 pana_server_session_address_set_for_relay(suite, buf); 01167 } else { 01168 suite->pana_session.address_status = 2; 01169 memcpy(suite->session_address, buf->src_sa .address , 16); 01170 suite->session_port = buf->src_sa .port ; 01171 } 01172 pana_server_base->open_pana_authentication_cnt++; 01173 } else { 01174 tr_debug("TLS heap allocate"); 01175 } 01176 } 01177 01178 } else { 01179 //Generate session 01180 suite = sec_suite_create(); 01181 if (suite) { 01182 tr_debug("Create new Pana Session"); 01183 pana_server_tls_session_init(suite); 01184 pana_server_base->open_pana_authentication_cnt++; 01185 pana_client_session_init(suite); 01186 suite->interface = buf->interface ; 01187 if (relay_pack) { 01188 pana_server_session_address_set_for_relay(suite, buf); 01189 } else { 01190 suite->pana_session.address_status = 2; 01191 memcpy(suite->session_address, buf->src_sa .address , 16); 01192 suite->session_port = buf->src_sa .port ; 01193 } 01194 } 01195 } 01196 buffer_free(buf); 01197 return; 01198 } else if (header.type == PANA_MSG_PA) { 01199 01200 if (buf->src_sa .address [0] == 0xfe || relay_pack) { 01201 //accept only now session 01202 suite = sec_suite_selected_pana_session(header.session_id); 01203 if (!suite) { 01204 tr_debug("Drop Packet by session ID"); 01205 buffer_free(buf); 01206 return; 01207 } 01208 01209 01210 if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 01211 if (suite->pana_session.req_seq == header.seq) { 01212 suite->pana_session.req_seq++; 01213 //ADD Check for EAP fragmentation!!!!!!!!!!!!!!! 01214 if ((header.flags & PANA_FLAGS_COMPLETE) == PANA_FLAGS_COMPLETE) { 01215 if (suite->state != TLS_EAP_END_PANA_VERIFY && suite->state != PANA_READY) { 01216 if (pana_server_base->open_pana_authentication_cnt) { 01217 pana_server_base->open_pana_authentication_cnt--; 01218 } 01219 tr_debug("Remove Current session by 'Comp bit'"); 01220 sec_suite_remove(suite); 01221 buffer_free(buf); 01222 return; 01223 } 01224 } 01225 } else { 01226 tr_debug("Pana RES:Drop Old seq"); 01227 buffer_free(buf); 01228 return; 01229 } 01230 } else { 01231 suite->pana_session.res_seq = header.seq; 01232 } 01233 01234 if (relay_pack) { 01235 buf->src_sa = buf->dst_sa ; 01236 } 01237 01238 if (header.flags & PANA_FLAGS_START) { 01239 pana_session_startms_parse(buf, &header, suite); 01240 } else if (header.flags & PANA_FLAGS_COMPLETE) { 01241 pana_complete_msg_parse(buf, &header, suite); 01242 } else { 01243 01244 buf = pana_auth_message_handler(buf, &header, suite); 01245 01246 if (buf) { 01247 pana_eap_tls_up(buf, suite); 01248 } 01249 } 01250 return; 01251 } 01252 buffer_free(buf); 01253 } else { 01254 buffer_free(buf); 01255 } 01256 } 01257 01258 01259 int8_t pana_server_interface_init(int8_t interface_id, net_tls_cipher_e cipher_mode, const uint8_t *key_material, uint32_t time_period_before_activate_key) 01260 { 01261 int8_t ret_val; 01262 uint8_t supported_chipher_suites; 01263 protocol_interface_info_entry_t *cur; 01264 cur = protocol_stack_interface_info_get_by_id(interface_id); 01265 if (!cur) { 01266 return -1; 01267 } 01268 01269 if (!cur->if_lowpan_security_params) { 01270 return -1; 01271 } 01272 01273 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01274 return -4; 01275 } else if (cur->if_lowpan_security_params->pana_params == 0) { 01276 return -3; 01277 } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) { 01278 return -5; 01279 } 01280 01281 switch (cipher_mode) { 01282 case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */ 01283 supported_chipher_suites = SEC_CIPHERSUITE_PSK; 01284 break; 01285 01286 case NET_TLS_ECC_CIPHER: /**< Network Authentication support only ECC */ 01287 case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */ 01288 #ifdef ECC 01289 //Verify Certficate 01290 if (sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) { 01291 return -1; 01292 } 01293 if (cipher_mode == NET_TLS_PSK_AND_ECC_CIPHER) { 01294 supported_chipher_suites = (SEC_CIPHERSUITE_PSK | SEC_CIPHERSUITE_ECC); 01295 } else { 01296 supported_chipher_suites = SEC_CIPHERSUITE_ECC; 01297 } 01298 break; 01299 #endif // if ECC is not supported, flow into default => nothing is supported. 01300 default: 01301 supported_chipher_suites = 0; 01302 break; 01303 } 01304 01305 01306 ret_val = pana_server_init(interface_id, key_material, supported_chipher_suites, time_period_before_activate_key); 01307 if (ret_val == 0) { 01308 cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode; 01309 cur->if_lowpan_security_params->pana_params->psk_key_id = 0; 01310 cur->if_lowpan_security_params->pana_params->pana_client = 0; 01311 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 01312 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 01313 } 01314 01315 return ret_val; 01316 } 01317 01318 int8_t pana_server_key_update(int8_t interface_id, const uint8_t *network_key_material) 01319 { 01320 01321 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01322 if (!cur) { 01323 return -1; 01324 } 01325 01326 if (!pana_server_base || pana_server_base->network_interface_id != interface_id || pana_server_base->pana_key_update) { 01327 return -2; 01328 } 01329 01330 if (!cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) { 01331 return -3; 01332 } 01333 01334 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 01335 return -4; 01336 } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) { 01337 return -5; 01338 } 01339 01340 01341 01342 pana_server_base->pana_key_update = ns_dyn_mem_temporary_alloc(sizeof(pana_key_update_t)); 01343 if (!pana_server_base->pana_key_update) { 01344 return -3; 01345 } 01346 01347 pana_key_material_t *primary_key = pana_server_key_get(true); 01348 01349 if (network_key_material) { 01350 memcpy(pana_server_base->pana_key_update->new_key_material, network_key_material, 16); 01351 } else { 01352 pana_server_set_random_key_value(pana_server_base->pana_key_update->new_key_material); 01353 network_key_material = pana_server_base->pana_key_update->new_key_material; 01354 } 01355 01356 pana_lib_parameters_s *parameters = pana_parameters_get(); 01357 01358 /* Update Key ID */ 01359 pana_server_base->pana_key_update->key_id = primary_key->key_id; 01360 if (pana_server_base->pana_key_update->key_id == parameters->KEY_ID_MAX_VALUE) { 01361 /* Start Lollipop Sechema from 1 again */ 01362 pana_server_base->pana_key_update->key_id = 0; 01363 } 01364 pana_server_base->pana_key_update->key_id++; 01365 01366 01367 //Set New Key to secondary key 01368 primary_key = pana_server_key_get(false); 01369 primary_key->key_id = pana_server_base->pana_key_update->key_id; 01370 memcpy(primary_key->key_material, pana_server_base->pana_key_update->new_key_material, 16); 01371 //TRIG Timers 01372 pana_server_base->pana_key_update->key_delivery_cnt = sec_pana_key_update_trig(parameters->KEY_UPDATE_THRESHOLD); 01373 uint8_t *key_ptr = pana_key_get(network_key_material); 01374 if (key_ptr) { 01375 //pana_server_base->auth_cnt++; 01376 tr_debug("SET Secondary Key ready"); 01377 mac_helper_security_next_key_set(cur, (key_ptr + 16), pana_server_base->pana_key_update->key_id, MAC_KEY_ID_MODE_IDX); 01378 mle_service_security_set_security_key(cur->id, key_ptr, pana_server_base->pana_key_update->key_id, false); 01379 } 01380 tr_debug("KEY Delivery CNT: %02x", pana_server_base->pana_key_update->key_delivery_cnt); 01381 if (pana_server_base->pana_key_update->key_delivery_cnt == 0) { 01382 tr_debug("TRIG NEW Key"); 01383 pana_server_base->pana_key_update->key_delivery_cnt = 1; 01384 pana_key_update_delivery_ready(); 01385 } 01386 if (pana_nvm_storage_cb) { 01387 pana_server_material_write(pana_nvm_buffer); 01388 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 01389 } 01390 return 0; 01391 } 01392 01393 void pana_key_update_delay_timer(void) 01394 { 01395 if (pana_server_base && pana_server_base->key_update_delay) { 01396 if (pana_server_base->key_update_delay <= 100) { 01397 protocol_interface_info_entry_t *cur; 01398 pana_server_base->key_update_delay = 0; 01399 cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id); 01400 01401 //SWAP new KEY 01402 if (cur) { 01403 tr_debug("Trig New Key ID"); 01404 uint8_t keyId = mle_service_security_next_key_id_get(cur->id); 01405 mac_helper_security_key_swap_next_to_default(cur); 01406 mle_service_security_key_trig(cur->id, keyId); 01407 if (cur->nwk_wpan_nvm_api) { 01408 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01409 } 01410 if (pana_key_update_process_ready) { 01411 pana_key_update_process_ready(); 01412 } 01413 } 01414 if (pana_server_base->primary_material) { 01415 pana_server_base->primary_material = 0; 01416 } else { 01417 pana_server_base->primary_material = 1; 01418 } 01419 01420 pana_key_material_t *primary_key = pana_server_key_get(true); 01421 primary_key->key_id = pana_server_base->pana_key_update->key_id; 01422 memcpy(primary_key->key_material , pana_server_base->pana_key_update->new_key_material, 16); 01423 01424 if (pana_server_base->pana_key_update) { 01425 ns_dyn_mem_free(pana_server_base->pana_key_update); 01426 pana_server_base->pana_key_update = 0; 01427 } 01428 if (pana_nvm_storage_cb) { 01429 tr_debug("PS:NVM Cover"); 01430 pana_server_material_write(pana_nvm_buffer); 01431 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 01432 } 01433 01434 } else { 01435 pana_server_base->key_update_delay -= 100; 01436 } 01437 } 01438 01439 } 01440 01441 int8_t pana_server_nvm_callback_set(pana_server_update_cb *update_cb, pana_server_session_get_cb *nvm_get, pana_server_session_get_by_id_cb *nvm_session_get, uint8_t *nvm_static_buffer) 01442 { 01443 if (!update_cb || !nvm_static_buffer || !nvm_get || !nvm_session_get) { 01444 return -1; 01445 } 01446 pana_nvm_storage_cb = update_cb; 01447 pana_server_nvm_get = nvm_get; 01448 pana_server_nvm__session_get = nvm_session_get; 01449 pana_nvm_buffer = nvm_static_buffer; 01450 return 0; 01451 } 01452 01453 int8_t pana_server_process_ready_cb_set(void (*cb_fptr)(void)) 01454 { 01455 if (cb_fptr) { 01456 pana_key_update_process_ready = cb_fptr; 01457 return 0; 01458 } 01459 return -1; 01460 } 01461 01462 /* Pana Client session load from NVM API */ 01463 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer) 01464 { 01465 01466 if (!pana_server_base) { 01467 return -1; 01468 } 01469 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id); 01470 if (!cur) { 01471 return -1; 01472 } 01473 01474 if (pana_socket_id_get() == -1) { 01475 return -2; 01476 } 01477 01478 if (pana_server_session_restore(nvm_pointer, cur)) { 01479 return -3; 01480 } 01481 return 0; 01482 } 01483 01484 static void pana_success_server_build(buffer_t *buf, sec_suite_t *suite) 01485 { 01486 uint8_t *ptr; 01487 pana_header_t header; 01488 header.type = PANA_MSG_PA; 01489 header.flags = PANA_FLAGS_COMPLETE | PANA_FLAGS_REQUEST; 01490 //REQUEST 01491 header.seq = suite->pana_session.req_seq; 01492 header.session_id = suite->pana_session.session_id; 01493 01494 buf->buf_ptr = PANA_HEADER_LENGTH; 01495 ptr = buffer_data_pointer(buf); 01496 01497 uint8_t eap_status[4]; 01498 eap_header_build(eap_status, 4,EAP_SUCCESS, suite->pana_session.eap_id_seq, 0); 01499 01500 ptr = pana_avp_32_bit_write(AVP_RESULT_CODE, 0, ptr); 01501 ptr = pana_avp_write_n_bytes(AVP_EAP_PAYLOAD_CODE, 4, eap_status, ptr); 01502 ptr = pana_avp_32_bit_write(AVP_KEY_ID_CODE, suite->pana_session.pana_key_id, ptr); 01503 ptr = pana_avp_32_bit_write(AVP_SESSION_LIFETIME_CODE, suite->pana_session.session_lifetime, ptr); 01504 //ENC 01505 uint8_t key_material[18]; 01506 pana_server_set_key_material(key_material, false, suite->pana_session.auth_cnt); 01507 ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite); 01508 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 01509 buffer_data_end_set(buf, ptr); 01510 buf = build_pana_base(buf, &header, suite); 01511 if (!buf) { 01512 return; 01513 } 01514 01515 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 01516 01517 //Encode Pana Auth 01518 pana_set_agend_address(buf, false, suite); 01519 if (suite->pana_session.address_status & 1) { 01520 buf = pana_relay_avp_build(buf, suite); 01521 if (buf) { 01522 header.flags = 0; 01523 header.type = PANA_MSG_RELAY; 01524 header.session_id = 0; 01525 header.seq = 0; 01526 buf = build_pana_base(buf, &header, suite); 01527 } 01528 } 01529 01530 protocol_push(buf); 01531 } 01532 01533 01534 01535 static void pana_server_build_key_push(buffer_t *buf, sec_suite_t *suite) 01536 { 01537 uint8_t *ptr; 01538 pana_header_t header; 01539 header.type = PANA_MSG_PNA; 01540 header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING; 01541 //REQUEST 01542 header.seq = suite->pana_session.req_seq; 01543 header.session_id = suite->pana_session.session_id; 01544 01545 01546 buf->buf_ptr = PANA_HEADER_LENGTH; 01547 ptr = buffer_data_pointer(buf); 01548 //ENC 01549 uint8_t key_material[18]; 01550 pana_server_set_key_material(key_material, true, suite->pana_session.auth_cnt); 01551 ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite); 01552 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 01553 01554 buffer_data_end_set(buf, ptr); 01555 buf = build_pana_base(buf, &header, suite); 01556 if (!buf) { 01557 return; 01558 } 01559 01560 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 01561 pana_set_agend_address(buf, true, suite); 01562 01563 protocol_push(buf); 01564 } 01565 01566 int8_t pana_network_key_get(int8_t interface_id, ns_keys_t *key) 01567 { 01568 (void)interface_id; 01569 01570 if (pana_server_base && key) { 01571 pana_key_material_t *primary_key = pana_server_key_get(true); 01572 pana_key_material_t *prev_key = pana_server_key_get(false); 01573 if (prev_key->key_id == 0) { 01574 prev_key = 0; 01575 } 01576 key->current_active_key_index = primary_key->key_id; 01577 memcpy(key->current_active_network_key , primary_key->key_material, 16); 01578 if (prev_key) { 01579 key->previous_active_key_index = prev_key->key_id; 01580 memcpy(key->previous_active_network_key , prev_key->key_material, 16); 01581 } else { 01582 memset(key->previous_active_network_key, 0, 16); 01583 } 01584 return 0; 01585 } 01586 return -1; 01587 } 01588 01589 int8_t pana_server_trig_new_key(int8_t interface_id) 01590 { 01591 01592 if (!pana_server_base) { 01593 return -1; 01594 } 01595 if (pana_server_base->network_interface_id != interface_id) { 01596 return -2; 01597 } 01598 if (pana_server_base->key_update_delay) { 01599 tr_debug("TRIG faster"); 01600 pana_server_base->key_update_delay = 1; 01601 return 0; 01602 } 01603 return -1; 01604 01605 } 01606 01607 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id) 01608 { 01609 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01610 if (!cur) { 01611 return -1; 01612 } 01613 01614 if (!pana_socket_init(pana_server_packet_handler, pana_server_state_machine_func, tls_server_up)) { 01615 return -1; 01616 } 01617 01618 sec_suite_list_clean(); 01619 01620 //Allocate 01621 if (pana_server_base == 0) { 01622 pana_server_base = pana_server_staructure_allocate(); 01623 } 01624 if (!pana_server_base || !cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) { 01625 return -1; 01626 } 01627 01628 net_tls_cipher_e cipher_mode; 01629 pana_server_base->open_pana_authentication_cnt = 0; 01630 pana_server_base->network_interface_id = interface_id; 01631 pana_server_base->pana_key_update = 0; 01632 pana_server_base->key_update_delay = 0; 01633 pana_server_material_read(nvm_data); 01634 if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_PSK) { 01635 cipher_mode = NET_TLS_PSK_CIPHER; 01636 } else if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_ECC) { 01637 cipher_mode = NET_TLS_ECC_CIPHER; 01638 } else { 01639 cipher_mode = NET_TLS_PSK_AND_ECC_CIPHER; 01640 } 01641 01642 cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode; 01643 cur->if_lowpan_security_params->pana_params->psk_key_id = 0;//TODO????? 01644 cur->if_lowpan_security_params->pana_params->pana_client = 0; 01645 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 01646 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 01647 01648 return 0; 01649 } 01650 01651 int8_t pana_server_key_material_load(int8_t interface_id) 01652 { 01653 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01654 if (!cur) { 01655 return -1; 01656 } else if (!pana_server_base) { 01657 return -1; 01658 } 01659 uint8_t *key_ptr; 01660 pana_key_material_t *key_mat; 01661 if (pana_server_base->pana_key_update) { 01662 01663 pana_server_base->auth_cnt++; 01664 //Load First Primary to master 01665 key_mat = pana_server_key_get(true); 01666 key_ptr = pana_key_get(key_mat->key_material); 01667 mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01668 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true); 01669 if (cur->nwk_wpan_nvm_api) { 01670 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01671 } 01672 //Set Secondary to coming key 01673 key_mat = pana_server_key_get(false); 01674 key_ptr = pana_key_get(key_mat->key_material); 01675 mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01676 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false); 01677 } else { 01678 bool secondary_active = false; 01679 //Load first Secondary and then Primary 01680 key_mat = pana_server_key_get(false); 01681 if (key_mat->key_id) { 01682 key_ptr = pana_key_get(key_mat->key_material); 01683 secondary_active = true; 01684 mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01685 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true); 01686 if (cur->nwk_wpan_nvm_api) { 01687 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01688 } 01689 } 01690 key_mat = pana_server_key_get(true); 01691 key_ptr = pana_key_get(key_mat->key_material); 01692 if (secondary_active) { 01693 mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01694 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false); 01695 mac_helper_security_key_swap_next_to_default(cur); 01696 mle_service_security_key_trig(cur->id, key_mat->key_id); 01697 } else { 01698 mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01699 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true); 01700 } 01701 if (cur->nwk_wpan_nvm_api) { 01702 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01703 } 01704 } 01705 return 0; 01706 } 01707 01708 static void pana_client_authentication_fail(sec_suite_t *suite) 01709 { 01710 if (suite->pana_session.nvm_offset) { 01711 //tr_debug("NVM Session Remove"); 01712 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE); 01713 } 01714 if (pana_server_base && pana_server_base->open_pana_authentication_cnt) { 01715 pana_server_base->open_pana_authentication_cnt--; 01716 } 01717 } 01718 01719 #else 01720 int8_t pana_server_nvm_callback_set(pana_server_update_cb *update_cb, pana_server_session_get_cb *nvm_get, pana_server_session_get_by_id_cb *nvm_session_get, uint8_t *nvm_static_buffer) 01721 { 01722 (void)update_cb; 01723 (void)nvm_static_buffer; 01724 return -1; 01725 } 01726 01727 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer) 01728 { 01729 (void) nvm_pointer; 01730 return -1; 01731 } 01732 01733 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id) 01734 { 01735 (void) nvm_data; 01736 (void)interface_id; 01737 return -1; 01738 } 01739 #endif 01740 #else 01741 int8_t pana_server_nvm_callback_set(pana_server_update_cb *update_cb, pana_server_session_get_cb *nvm_get, pana_server_session_get_by_id_cb *nvm_session_get, uint8_t *nvm_static_buffer) 01742 { 01743 (void)update_cb; 01744 (void)nvm_static_buffer; 01745 return -1; 01746 } 01747 01748 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer) 01749 { 01750 (void) nvm_pointer; 01751 return -1; 01752 } 01753 01754 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id) 01755 { 01756 (void) nvm_data; 01757 (void)interface_id; 01758 return -1; 01759 } 01760 #endif
Generated on Fri Jul 22 2022 04:53:58 by
1.7.2
