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.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
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) { 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 tx_start_OK = true; 00752 } 00753 00754 } 00755 if (tx_start_OK) { 00756 pana_timeout_timer_set(suite, suite->state); 00757 } else { 00758 suite->timer = tls_backoff_random_timer_start(); 00759 } 00760 } else 00761 #endif 00762 { 00763 if (suite->pana_session.assy_length) { 00764 buffer_free(suite->pana_session.eap_assy_buf); 00765 suite->pana_session.eap_assy_buf = 0; 00766 suite->pana_session.assy_length = 0; 00767 suite->pana_session.assy_off_set = 0; 00768 } 00769 tr_debug("TLS_TX_SERVER_KEY_EXCHANGE timeout"); 00770 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00771 general_tx = 1; 00772 } 00773 break; 00774 00775 00776 default: 00777 general_tx = 1; 00778 break; 00779 } 00780 00781 if (general_tx) { 00782 if (sec_auth_re_check(suite)) { 00783 buffer_t *buf = buffer_get(140); 00784 if (buf) { 00785 buf->interface = suite->interface; 00786 suite->timer = 600; 00787 switch (suite->state) { 00788 case PANA_REQUEST_TX: 00789 pana_start_message_build(buf, suite); 00790 break; 00791 00792 case EAP_IDENTITY_REQ: 00793 pana_eap_identity_build(buf, suite); 00794 break; 00795 00796 case TLS_START: 00797 pana_eap_tls_start_build(buf, suite); 00798 break; 00799 00800 case TLS_SERVER_TX_SERVER_HELLO: 00801 tls_server_hello_build(buf, suite); 00802 pana_eap_down(buf, suite); 00803 break; 00804 00805 case TLS_KEY_CHANGE: 00806 //Print Handshake message 00807 tls_prepare_change_chipher_spec(suite); 00808 00809 tls_build_client_change_chipher_suite_finnish(buf, suite); 00810 tls_nonce_update(suite->tls_session->tls_nonce_explit); 00811 tr_debug("Set Keys"); 00812 pana_eap_down(buf, suite); 00813 00814 break; 00815 00816 case TLS_EAP_END_PANA_VERIFY: 00817 pana_success_server_build(buf, suite); 00818 break; 00819 00820 00821 case PANA_KEY_UPDATE: 00822 pana_server_build_key_push(buf, suite); 00823 break; 00824 00825 case PANA_FAILURE: 00826 pana_server_finnish_error_build(buf, suite); 00827 pana_down(buf, suite); 00828 00829 break; 00830 00831 case TLS_FINISH: 00832 case TLS_ALERT: 00833 eap_fragmentation_init(suite); 00834 pana_eap_tls_finnish_build(buf, suite); 00835 break; 00836 00837 00838 case TLS_ALERT_CLOSE_FATAL: 00839 case TLS_ALERT_INTERNAL: 00840 case TLS_ALERT_CHIPHER_SUITE: 00841 case TLS_ALERT_DECRYPT: 00842 case TLS_ALERT_BAD_CERTIFICATE: 00843 00844 eap_fragmentation_init(suite); 00845 00846 suite->setups &= ~(TLS_ECC_CERTIFICATE_REQUESTED | TLS_ECC_CERTIFICATE_RECEIVED | TLS_ECC_CERTIFICATE_VERIFY); 00847 #ifdef ECC 00848 { 00849 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00850 if (tls_heap) { 00851 tls_ecc_heap_free(tls_heap); 00852 } 00853 } 00854 #endif 00855 if (suite->state == TLS_ALERT_DECRYPT) { 00856 tls_alert_build(buf, ALERT_BAD_RECORD); 00857 } else if (suite->state == TLS_ALERT_CLOSE_FATAL) { 00858 tls_alert_build(buf, ALERT_INTERNAL_ERR); 00859 } else if (suite->state == TLS_ALERT_BAD_CERTIFICATE) { 00860 00861 tls_alert_build(buf, ALERT_BAD_CERTIFICATE); 00862 } else { 00863 tls_alert_build(buf, ALERT_INTERNAL_ERR); 00864 00865 } 00866 pana_eap_down(buf, suite); 00867 break; 00868 00869 00870 default: 00871 tr_debug("Unknown Packet. State: %x", suite->state); 00872 buf = buffer_free(buf); 00873 break; 00874 } 00875 00876 } else { 00877 suite->timer = 2; 00878 } 00879 } else { 00880 tr_debug("Tls Auth Re TX limit Reached. State: %x", suite->state); 00881 00882 switch (suite->state) { 00883 case TLS_SERVER_TX_SERVER_HELLO: 00884 case TLS_KEY_CHANGE: 00885 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00886 break; 00887 00888 default: 00889 if (suite->state == PANA_KEY_UPDATE) { 00890 tr_warn("Key Delivery Fail"); 00891 pana_key_update_delivery_ready(); 00892 } 00893 pana_server_pana_error_handler(suite); 00894 break; 00895 } 00896 } 00897 } 00898 } 00899 00900 static void pana_server_tls_session_init(sec_suite_t *suite) 00901 { 00902 //Generate TLS SESSION 00903 tls_session_id_genrate(suite->tls_session->tls_session_id, 4); 00904 suite->tls_session->id_length = 4; 00905 memset(suite->tls_session->tls_nonce_explit, 0, 8); 00906 } 00907 00908 static void pana_server_session_address_set_for_relay(sec_suite_t *suite, buffer_t *buf) 00909 { 00910 memcpy(suite->session_address, buf->dst_sa .address , 16); 00911 suite->session_port = buf->dst_sa .port ; 00912 suite->pana_session.address_status = 1; 00913 //Copy Relay Address 00914 memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16); 00915 suite->pana_session.relay_port = buf->src_sa .port ; 00916 memcpy(&(buf->src_sa ), &(buf->dst_sa ), sizeof(sockaddr_t)); 00917 00918 } 00919 00920 static sec_suite_t *pana_server_session_restore(uint8_t *nvm_data, protocol_interface_info_entry_t *interface) 00921 { 00922 sec_suite_t *suite = sec_lib_security_session_allocate(false); 00923 if (!suite) { 00924 return NULL; 00925 } 00926 //Restore 00927 pana_server_client_restore_from_nvm(suite, nvm_data); 00928 //Init Satic Information At ZIP 00929 suite->setups = TLS_SERVER_MODE; 00930 suite->interface = interface; 00931 suite->pana_session.key_wrap = pana_server_base->key_wrap; 00932 suite->pana_session.prf_algorythm = pana_server_base->prf_algorythm; 00933 suite->pana_session.integrity_algorythm = pana_server_base->integrity_algorythm; 00934 return suite; 00935 } 00936 00937 00938 static sec_suite_t * pana_server_get_session_by_session_id(uint32_t session_id, protocol_interface_info_entry_t *interface) 00939 { 00940 sec_suite_t *suite = sec_suite_selected_pana_session(session_id); 00941 if (!suite && pana_server_nvm__session_get) { 00942 if (!pana_server_nvm__session_get(session_id)) { 00943 return NULL; 00944 } 00945 suite = pana_server_session_restore(pana_nvm_buffer, interface); 00946 } 00947 00948 return suite; 00949 } 00950 00951 static sec_suite_t *pana_server_get_session_by_address(uint8_t *ll_address, protocol_interface_info_entry_t *interface) 00952 { 00953 sec_suite_t *suite = sec_suite_selected_address(ll_address); 00954 00955 if (!suite && pana_server_nvm_get) { 00956 if (!pana_server_nvm_get(ll_address)) { 00957 return NULL; 00958 } 00959 suite = pana_server_session_restore(pana_nvm_buffer, interface); 00960 } 00961 00962 return suite; 00963 } 00964 00965 00966 static void pana_server_packet_handler(buffer_t *buf) 00967 { 00968 bool relay_pack = false; 00969 sec_suite_t *suite = NULL; 00970 pana_header_t header; 00971 if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) { 00972 buffer_free(buf); 00973 return; 00974 } 00975 buffer_data_strip_header(buf, PANA_HEADER_LENGTH); 00976 00977 00978 if (header.type == PANA_MSG_RELAY) { 00979 /** Parse Relay */ 00980 buf = pana_relay_parse(buf); 00981 if (buf) { 00982 /** Parse Relayed Packet */ 00983 if (!pana_header_parse(buffer_data_pointer(buf), buffer_data_length(buf), &header)) { 00984 buffer_free(buf); 00985 return; 00986 } 00987 buffer_data_strip_header(buf, PANA_HEADER_LENGTH); 00988 relay_pack = true; 00989 } 00990 if (buf == 0) { 00991 tr_debug("Drop Pana Relay Pack"); 00992 return; 00993 } 00994 } 00995 00996 //Server will use address and session when address is LL and GP use only ID 00997 //SERVER: if type is relay parse relay address and save 00998 if (header.type == PANA_MSG_PNA) { 00999 //tr_debug("PNA"); 01000 suite = pana_server_get_session_by_session_id(header.session_id, buf->interface ); 01001 if (!suite || !(header.flags & PANA_FLAGS_PING)) { 01002 buffer_free(buf); 01003 return; 01004 } 01005 if (!pana_auth_msg_validate(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key)) { 01006 buffer_free(buf); 01007 return; 01008 } 01009 01010 if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 01011 if (suite->pana_session.req_seq != header.seq) { 01012 tr_debug("PNA RES:Drop Old seq"); 01013 buffer_free(buf); 01014 return; 01015 } 01016 01017 suite->pana_session.req_seq++; 01018 01019 if (suite->pana_session.session_ready ) { 01020 01021 tr_debug("Key push OK"); 01022 if (suite->state == PANA_KEY_UPDATE) { 01023 sec_lib_state_machine_lock(suite, PANA_READY); 01024 tr_debug("Key Delivery OK"); 01025 //Call SEC KEY UPDATE 01026 //tr_debug("NVM SEQ Update by Key Pull Ready"); 01027 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE); 01028 pana_key_update_delivery_ready(); 01029 } 01030 } 01031 buffer_free(buf); 01032 return; 01033 } else { 01034 if (suite->pana_session.res_seq == 0) { 01035 suite->pana_session.res_seq = header.seq; 01036 } else { 01037 if ((suite->pana_session.res_seq + 1) == header.seq) { 01038 suite->pana_session.res_seq = header.seq; 01039 } else if (suite->pana_session.res_seq != header.seq) { 01040 tr_debug("PNA REQ:Drop unknow Request"); 01041 buffer_free(buf); 01042 return; 01043 } 01044 } 01045 } 01046 01047 if (relay_pack) { 01048 pana_server_session_address_set_for_relay(suite, buf); 01049 01050 } else { 01051 if ((buf->src_sa .address [0] != 0xfe)) { 01052 //tr_debug("SET GP & SEQ"); 01053 suite->pana_session.address_status = 0; 01054 memcpy(suite->pana_session.session_relay_address, buf->src_sa .address , 16); 01055 suite->pana_session.relay_port = buf->src_sa .port ; 01056 suite->session_port = buf->src_sa .port ; 01057 01058 } else { 01059 if (memcmp(suite->session_address, buf->src_sa .address , 16) != 0) { 01060 tr_debug("PNA REQ:Drop By Address"); 01061 buffer_free(buf); 01062 return; 01063 } 01064 01065 //Shuold Update Relay Information 01066 suite->pana_session.address_status = 2; 01067 suite->session_port = buf->src_sa .port ; 01068 lowpan_neighbour_data_clean(suite->interface->id, buf->src_sa .address ); 01069 } 01070 } 01071 01072 if (!suite->pana_session.session_ready) { 01073 buffer_free(buf); 01074 return; 01075 } 01076 01077 //KEY PULL 01078 pana_avp_t avp_temp; 01079 //Read Resul and Key id if they are coming 01080 avp_temp.code = PANA_EAP_KEYREQ_TYPE; 01081 avp_temp.len = 0; 01082 uint8_t key_delivery; 01083 if (!pana_avp_discover(buffer_data_pointer(buf), buffer_data_length(buf), &avp_temp)) { 01084 key_delivery = 2; 01085 avp_temp.avp_ptr = NULL; 01086 } else { 01087 if (avp_temp.len != 2) { 01088 buffer_free(buf); 01089 return; 01090 } 01091 uint8_t *ptr = avp_temp.avp_ptr; 01092 pana_key_material_t *primary_key = pana_server_key_get(true); 01093 tr_debug("Network KEY Request: %s", trace_array(ptr, 2)); 01094 if (*ptr++ & 1) { 01095 tr_debug("REQ bit, 1"); 01096 //if(*ptr == pana_server_base->network_key_id) 01097 if (*ptr == primary_key->key_id) { 01098 if (pana_server_base->pana_key_update) { 01099 key_delivery = 3; 01100 } else { 01101 key_delivery = 4; 01102 } 01103 } else { 01104 key_delivery = 2; 01105 } 01106 01107 } else { 01108 //if(*ptr == pana_server_base->network_key_id) 01109 if (*ptr == primary_key->key_id) { 01110 key_delivery = 2; 01111 } else { 01112 key_delivery = 4; 01113 } 01114 } 01115 } 01116 01117 tr_debug("NVM SEQ update BY Client key Pull"); 01118 pana_pna_response_build(buf, key_delivery, &header, suite); 01119 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_UPDATE); 01120 return; 01121 } else if (header.type == PANA_MSG_PCI) { 01122 if (relay_pack) { 01123 suite = pana_server_get_session_by_address(buf->dst_sa .address , buf->interface ); 01124 } else { 01125 suite = pana_server_get_session_by_address(buf->src_sa .address , buf->interface ); 01126 } 01127 if (suite) { 01128 //Check State 01129 //if state ready create new session 01130 if (!suite->pana_session.session_ready ) { 01131 tr_debug("PCI received; Discard unfinished session and start a new one"); 01132 if (pana_server_base->open_pana_authentication_cnt) { 01133 pana_server_base->open_pana_authentication_cnt--; 01134 } 01135 sec_suite_remove(suite); 01136 suite = 0; 01137 } else { 01138 tr_debug("Accept new session"); 01139 } 01140 } 01141 01142 if (suite) { 01143 if (suite->pana_session.pana_heap == NULL) { 01144 suite->pana_session.pana_heap = pana_heap_structure_allocate(); 01145 } 01146 if (suite->tls_session == NULL) { 01147 suite->tls_session = amr_tls_session_allocate(); 01148 if (suite->tls_session == NULL) { 01149 if (suite->pana_session.pana_heap) { 01150 ns_dyn_mem_free(suite->pana_session.pana_heap); 01151 suite->pana_session.pana_heap = NULL; 01152 } 01153 } 01154 } 01155 if (suite->pana_session.pana_heap) { 01156 01157 arm_tls_session_clear(suite->tls_session); 01158 suite->tls_session->tls_heap = tls_heap_allocate(); 01159 if (suite->tls_session->tls_heap) { 01160 //Generate TLS SESSION 01161 pana_server_tls_session_init(suite); 01162 pana_client_session_init(suite); 01163 tr_debug("UPdate Auth Counter"); 01164 if (relay_pack) { 01165 pana_server_session_address_set_for_relay(suite, buf); 01166 } else { 01167 suite->pana_session.address_status = 2; 01168 memcpy(suite->session_address, buf->src_sa .address , 16); 01169 suite->session_port = buf->src_sa .port ; 01170 } 01171 pana_server_base->open_pana_authentication_cnt++; 01172 } else { 01173 tr_debug("TLS heap allocate"); 01174 } 01175 } 01176 01177 } else { 01178 //Generate session 01179 suite = sec_suite_create(); 01180 if (suite) { 01181 tr_debug("Create new Pana Session"); 01182 pana_server_tls_session_init(suite); 01183 pana_server_base->open_pana_authentication_cnt++; 01184 pana_client_session_init(suite); 01185 suite->interface = buf->interface ; 01186 if (relay_pack) { 01187 pana_server_session_address_set_for_relay(suite, buf); 01188 } else { 01189 suite->pana_session.address_status = 2; 01190 memcpy(suite->session_address, buf->src_sa .address , 16); 01191 suite->session_port = buf->src_sa .port ; 01192 } 01193 } 01194 } 01195 buffer_free(buf); 01196 return; 01197 } else if (header.type == PANA_MSG_PA) { 01198 01199 if (buf->src_sa .address [0] == 0xfe || relay_pack) { 01200 //accept only now session 01201 suite = sec_suite_selected_pana_session(header.session_id); 01202 if (!suite) { 01203 tr_debug("Drop Packet by session ID"); 01204 buffer_free(buf); 01205 return; 01206 } 01207 01208 01209 if ((header.flags & PANA_FLAGS_REQUEST) == PANA_FLAGS_RESPONSE) { 01210 if (suite->pana_session.req_seq == header.seq) { 01211 suite->pana_session.req_seq++; 01212 //ADD Check for EAP fragmentation!!!!!!!!!!!!!!! 01213 if ((header.flags & PANA_FLAGS_COMPLETE) == PANA_FLAGS_COMPLETE) { 01214 if (suite->state != TLS_EAP_END_PANA_VERIFY && suite->state != PANA_READY) { 01215 if (pana_server_base->open_pana_authentication_cnt) { 01216 pana_server_base->open_pana_authentication_cnt--; 01217 } 01218 tr_debug("Remove Current session by 'Comp bit'"); 01219 sec_suite_remove(suite); 01220 buffer_free(buf); 01221 return; 01222 } 01223 } 01224 } else { 01225 tr_debug("Pana RES:Drop Old seq"); 01226 buffer_free(buf); 01227 return; 01228 } 01229 } else { 01230 suite->pana_session.res_seq = header.seq; 01231 } 01232 01233 if (relay_pack) { 01234 buf->src_sa = buf->dst_sa ; 01235 } 01236 01237 if (header.flags & PANA_FLAGS_START) { 01238 pana_session_startms_parse(buf, &header, suite); 01239 } else if (header.flags & PANA_FLAGS_COMPLETE) { 01240 pana_complete_msg_parse(buf, &header, suite); 01241 } else { 01242 01243 buf = pana_auth_message_handler(buf, &header, suite); 01244 01245 if (buf) { 01246 pana_eap_tls_up(buf, suite); 01247 } 01248 } 01249 return; 01250 } 01251 buffer_free(buf); 01252 } else { 01253 buffer_free(buf); 01254 } 01255 } 01256 01257 01258 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) 01259 { 01260 int8_t ret_val; 01261 uint8_t supported_chipher_suites; 01262 protocol_interface_info_entry_t *cur; 01263 cur = protocol_stack_interface_info_get_by_id(interface_id); 01264 if (!cur) { 01265 return -1; 01266 } 01267 01268 if (!cur->if_lowpan_security_params) { 01269 return -1; 01270 } 01271 01272 if (cur->lowpan_info & INTERFACE_NWK_ACTIVE) { 01273 return -4; 01274 } else if (cur->if_lowpan_security_params->pana_params == 0) { 01275 return -3; 01276 } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) { 01277 return -5; 01278 } 01279 01280 switch (cipher_mode) { 01281 case NET_TLS_PSK_CIPHER: /**< Network Authentication support only PSK */ 01282 supported_chipher_suites = SEC_CIPHERSUITE_PSK; 01283 break; 01284 01285 case NET_TLS_ECC_CIPHER: /**< Network Authentication support only ECC */ 01286 case NET_TLS_PSK_AND_ECC_CIPHER: /**< Network Authentication support PSK & ECC */ 01287 #ifdef ECC 01288 //Verify Certficate 01289 if (sec_cetificate_chain_get(SEC_NWK_AUTHENTICATION_CERTI_CHAIN) == NULL) { 01290 return -1; 01291 } 01292 if (cipher_mode == NET_TLS_PSK_AND_ECC_CIPHER) { 01293 supported_chipher_suites = (SEC_CIPHERSUITE_PSK | SEC_CIPHERSUITE_ECC); 01294 } else { 01295 supported_chipher_suites = SEC_CIPHERSUITE_ECC; 01296 } 01297 break; 01298 #endif // if ECC is not supported, flow into default => nothing is supported. 01299 default: 01300 supported_chipher_suites = 0; 01301 break; 01302 } 01303 01304 01305 ret_val = pana_server_init(interface_id, key_material, supported_chipher_suites, time_period_before_activate_key); 01306 if (ret_val == 0) { 01307 cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode; 01308 cur->if_lowpan_security_params->pana_params->psk_key_id = 0; 01309 cur->if_lowpan_security_params->pana_params->pana_client = 0; 01310 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 01311 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 01312 } 01313 01314 return ret_val; 01315 } 01316 01317 int8_t pana_server_key_update(int8_t interface_id, const uint8_t *network_key_material) 01318 { 01319 01320 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01321 if (!cur) { 01322 return -1; 01323 } 01324 01325 if (!pana_server_base || pana_server_base->network_interface_id != interface_id || pana_server_base->pana_key_update) { 01326 return -2; 01327 } 01328 01329 if (!cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) { 01330 return -3; 01331 } 01332 01333 if ((cur->lowpan_info & INTERFACE_NWK_ACTIVE) == 0) { 01334 return -4; 01335 } else if (cur->if_lowpan_security_params->nwk_security_mode != NET_SEC_MODE_PANA_LINK_SECURITY) { 01336 return -5; 01337 } 01338 01339 01340 01341 pana_server_base->pana_key_update = ns_dyn_mem_temporary_alloc(sizeof(pana_key_update_t)); 01342 if (!pana_server_base->pana_key_update) { 01343 return -3; 01344 } 01345 01346 pana_key_material_t *primary_key = pana_server_key_get(true); 01347 01348 if (network_key_material) { 01349 memcpy(pana_server_base->pana_key_update->new_key_material, network_key_material, 16); 01350 } else { 01351 pana_server_set_random_key_value(pana_server_base->pana_key_update->new_key_material); 01352 network_key_material = pana_server_base->pana_key_update->new_key_material; 01353 } 01354 01355 pana_lib_parameters_s *parameters = pana_parameters_get(); 01356 01357 /* Update Key ID */ 01358 pana_server_base->pana_key_update->key_id = primary_key->key_id; 01359 if (pana_server_base->pana_key_update->key_id == parameters->KEY_ID_MAX_VALUE) { 01360 /* Start Lollipop Sechema from 1 again */ 01361 pana_server_base->pana_key_update->key_id = 0; 01362 } 01363 pana_server_base->pana_key_update->key_id++; 01364 01365 01366 //Set New Key to secondary key 01367 primary_key = pana_server_key_get(false); 01368 primary_key->key_id = pana_server_base->pana_key_update->key_id; 01369 memcpy(primary_key->key_material, pana_server_base->pana_key_update->new_key_material, 16); 01370 //TRIG Timers 01371 pana_server_base->pana_key_update->key_delivery_cnt = sec_pana_key_update_trig(parameters->KEY_UPDATE_THRESHOLD); 01372 uint8_t *key_ptr = pana_key_get(network_key_material); 01373 if (key_ptr) { 01374 //pana_server_base->auth_cnt++; 01375 tr_debug("SET Secondary Key ready"); 01376 mac_helper_security_next_key_set(cur, (key_ptr + 16), pana_server_base->pana_key_update->key_id, MAC_KEY_ID_MODE_IDX); 01377 mle_service_security_set_security_key(cur->id, key_ptr, pana_server_base->pana_key_update->key_id, false); 01378 } 01379 tr_debug("KEY Delivery CNT: %02x", pana_server_base->pana_key_update->key_delivery_cnt); 01380 if (pana_server_base->pana_key_update->key_delivery_cnt == 0) { 01381 tr_debug("TRIG NEW Key"); 01382 pana_server_base->pana_key_update->key_delivery_cnt = 1; 01383 pana_key_update_delivery_ready(); 01384 } 01385 if (pana_nvm_storage_cb) { 01386 pana_server_material_write(pana_nvm_buffer); 01387 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 01388 } 01389 return 0; 01390 } 01391 01392 void pana_key_update_delay_timer(void) 01393 { 01394 if (pana_server_base && pana_server_base->key_update_delay) { 01395 if (pana_server_base->key_update_delay <= 100) { 01396 protocol_interface_info_entry_t *cur; 01397 pana_server_base->key_update_delay = 0; 01398 cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id); 01399 01400 //SWAP new KEY 01401 if (cur) { 01402 tr_debug("Trig New Key ID"); 01403 uint8_t keyId = mle_service_security_next_key_id_get(cur->id); 01404 mac_helper_security_key_swap_next_to_default(cur); 01405 mle_service_security_key_trig(cur->id, keyId); 01406 if (cur->nwk_wpan_nvm_api) { 01407 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01408 } 01409 if (pana_key_update_process_ready) { 01410 pana_key_update_process_ready(); 01411 } 01412 } 01413 if (pana_server_base->primary_material) { 01414 pana_server_base->primary_material = 0; 01415 } else { 01416 pana_server_base->primary_material = 1; 01417 } 01418 01419 pana_key_material_t *primary_key = pana_server_key_get(true); 01420 primary_key->key_id = pana_server_base->pana_key_update->key_id; 01421 memcpy(primary_key->key_material , pana_server_base->pana_key_update->new_key_material, 16); 01422 01423 if (pana_server_base->pana_key_update) { 01424 ns_dyn_mem_free(pana_server_base->pana_key_update); 01425 pana_server_base->pana_key_update = 0; 01426 } 01427 if (pana_nvm_storage_cb) { 01428 tr_debug("PS:NVM Cover"); 01429 pana_server_material_write(pana_nvm_buffer); 01430 pana_nvm_storage_cb(PANA_SERVER_MATERIAL_UPDATE); 01431 } 01432 01433 } else { 01434 pana_server_base->key_update_delay -= 100; 01435 } 01436 } 01437 01438 } 01439 01440 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) 01441 { 01442 if (!update_cb || !nvm_static_buffer || !nvm_get || !nvm_session_get) { 01443 return -1; 01444 } 01445 pana_nvm_storage_cb = update_cb; 01446 pana_server_nvm_get = nvm_get; 01447 pana_server_nvm__session_get = nvm_session_get; 01448 pana_nvm_buffer = nvm_static_buffer; 01449 return 0; 01450 } 01451 01452 int8_t pana_server_process_ready_cb_set(void (*cb_fptr)(void)) 01453 { 01454 if (cb_fptr) { 01455 pana_key_update_process_ready = cb_fptr; 01456 return 0; 01457 } 01458 return -1; 01459 } 01460 01461 /* Pana Client session load from NVM API */ 01462 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer) 01463 { 01464 01465 if (!pana_server_base) { 01466 return -1; 01467 } 01468 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(pana_server_base->network_interface_id); 01469 if (!cur) { 01470 return -1; 01471 } 01472 01473 if (pana_socket_id_get() == -1) { 01474 return -2; 01475 } 01476 01477 if (pana_server_session_restore(nvm_pointer, cur)) { 01478 return -3; 01479 } 01480 return 0; 01481 } 01482 01483 static void pana_success_server_build(buffer_t *buf, sec_suite_t *suite) 01484 { 01485 uint8_t *ptr; 01486 pana_header_t header; 01487 header.type = PANA_MSG_PA; 01488 header.flags = PANA_FLAGS_COMPLETE | PANA_FLAGS_REQUEST; 01489 //REQUEST 01490 header.seq = suite->pana_session.req_seq; 01491 header.session_id = suite->pana_session.session_id; 01492 01493 buf->buf_ptr = PANA_HEADER_LENGTH; 01494 ptr = buffer_data_pointer(buf); 01495 01496 uint8_t eap_status[4]; 01497 eap_header_build(eap_status, 4,EAP_SUCCESS, suite->pana_session.eap_id_seq, 0); 01498 01499 ptr = pana_avp_32_bit_write(AVP_RESULT_CODE, 0, ptr); 01500 ptr = pana_avp_write_n_bytes(AVP_EAP_PAYLOAD_CODE, 4, eap_status, ptr); 01501 ptr = pana_avp_32_bit_write(AVP_KEY_ID_CODE, suite->pana_session.pana_key_id, ptr); 01502 ptr = pana_avp_32_bit_write(AVP_SESSION_LIFETIME_CODE, suite->pana_session.session_lifetime, ptr); 01503 //ENC 01504 uint8_t key_material[18]; 01505 pana_server_set_key_material(key_material, false, suite->pana_session.auth_cnt); 01506 ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite); 01507 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 01508 buffer_data_end_set(buf, ptr); 01509 buf = build_pana_base(buf, &header, suite); 01510 if (!buf) { 01511 return; 01512 } 01513 01514 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 01515 01516 //Encode Pana Auth 01517 pana_set_agend_address(buf, false, suite); 01518 if (suite->pana_session.address_status & 1) { 01519 buf = pana_relay_avp_build(buf, suite); 01520 if (buf) { 01521 header.flags = 0; 01522 header.type = PANA_MSG_RELAY; 01523 header.session_id = 0; 01524 header.seq = 0; 01525 buf = build_pana_base(buf, &header, suite); 01526 } 01527 } 01528 01529 protocol_push(buf); 01530 } 01531 01532 01533 01534 static void pana_server_build_key_push(buffer_t *buf, sec_suite_t *suite) 01535 { 01536 uint8_t *ptr; 01537 pana_header_t header; 01538 header.type = PANA_MSG_PNA; 01539 header.flags = PANA_FLAGS_REQUEST | PANA_FLAGS_PING; 01540 //REQUEST 01541 header.seq = suite->pana_session.req_seq; 01542 header.session_id = suite->pana_session.session_id; 01543 01544 01545 buf->buf_ptr = PANA_HEADER_LENGTH; 01546 ptr = buffer_data_pointer(buf); 01547 //ENC 01548 uint8_t key_material[18]; 01549 pana_server_set_key_material(key_material, true, suite->pana_session.auth_cnt); 01550 ptr = pana_avp_zip_key_material(ptr, key_material, header.seq, suite); 01551 ptr = pana_avp_write_n_bytes(AVP_AUTHENCY_CODE, 16, NULL, ptr); 01552 01553 buffer_data_end_set(buf, ptr); 01554 buf = build_pana_base(buf, &header, suite); 01555 if (!buf) { 01556 return; 01557 } 01558 01559 pana_auth_hash_calc(buffer_data_pointer(buf), buffer_data_length(buf), suite->pana_session.pana_auth_key); 01560 pana_set_agend_address(buf, true, suite); 01561 01562 protocol_push(buf); 01563 } 01564 01565 int8_t pana_network_key_get(int8_t interface_id, ns_keys_t *key) 01566 { 01567 (void)interface_id; 01568 01569 if (pana_server_base && key) { 01570 pana_key_material_t *primary_key = pana_server_key_get(true); 01571 pana_key_material_t *prev_key = pana_server_key_get(false); 01572 if (prev_key->key_id == 0) { 01573 prev_key = 0; 01574 } 01575 key->current_active_key_index = primary_key->key_id; 01576 memcpy(key->current_active_network_key , primary_key->key_material, 16); 01577 if (prev_key) { 01578 key->previous_active_key_index = prev_key->key_id; 01579 memcpy(key->previous_active_network_key , prev_key->key_material, 16); 01580 } else { 01581 memset(key->previous_active_network_key, 0, 16); 01582 } 01583 return 0; 01584 } 01585 return -1; 01586 } 01587 01588 int8_t pana_server_trig_new_key(int8_t interface_id) 01589 { 01590 01591 if (!pana_server_base) { 01592 return -1; 01593 } 01594 if (pana_server_base->network_interface_id != interface_id) { 01595 return -2; 01596 } 01597 if (pana_server_base->key_update_delay) { 01598 tr_debug("TRIG faster"); 01599 pana_server_base->key_update_delay = 1; 01600 return 0; 01601 } 01602 return -1; 01603 01604 } 01605 01606 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id) 01607 { 01608 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01609 if (!cur) { 01610 return -1; 01611 } 01612 01613 if (!pana_socket_init(pana_server_packet_handler, pana_server_state_machine_func, tls_server_up)) { 01614 return -1; 01615 } 01616 01617 sec_suite_list_clean(); 01618 01619 //Allocate 01620 if (pana_server_base == 0) { 01621 pana_server_base = pana_server_staructure_allocate(); 01622 } 01623 if (!pana_server_base || !cur->if_lowpan_security_params || !cur->if_lowpan_security_params->pana_params) { 01624 return -1; 01625 } 01626 01627 net_tls_cipher_e cipher_mode; 01628 pana_server_base->open_pana_authentication_cnt = 0; 01629 pana_server_base->network_interface_id = interface_id; 01630 pana_server_base->pana_key_update = 0; 01631 pana_server_base->key_update_delay = 0; 01632 pana_server_material_read(nvm_data); 01633 if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_PSK) { 01634 cipher_mode = NET_TLS_PSK_CIPHER; 01635 } else if (pana_server_base->supported_chipher_suites == SEC_CIPHERSUITE_ECC) { 01636 cipher_mode = NET_TLS_ECC_CIPHER; 01637 } else { 01638 cipher_mode = NET_TLS_PSK_AND_ECC_CIPHER; 01639 } 01640 01641 cur->if_lowpan_security_params->pana_params->nwk_chipher_mode = cipher_mode; 01642 cur->if_lowpan_security_params->pana_params->psk_key_id = 0;//TODO????? 01643 cur->if_lowpan_security_params->pana_params->pana_client = 0; 01644 cur->lowpan_info |= (INTERFACE_NWK_BOOTSRAP_PANA_AUTHENTICATION); 01645 cur->configure_flags |= INTERFACE_SECURITY_DEFINED; 01646 01647 return 0; 01648 } 01649 01650 int8_t pana_server_key_material_load(int8_t interface_id) 01651 { 01652 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01653 if (!cur) { 01654 return -1; 01655 } else if (!pana_server_base) { 01656 return -1; 01657 } 01658 uint8_t *key_ptr; 01659 pana_key_material_t *key_mat; 01660 if (pana_server_base->pana_key_update) { 01661 01662 pana_server_base->auth_cnt++; 01663 //Load First Primary to master 01664 key_mat = pana_server_key_get(true); 01665 key_ptr = pana_key_get(key_mat->key_material); 01666 mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01667 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true); 01668 if (cur->nwk_wpan_nvm_api) { 01669 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01670 } 01671 //Set Secondary to coming key 01672 key_mat = pana_server_key_get(false); 01673 key_ptr = pana_key_get(key_mat->key_material); 01674 mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01675 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false); 01676 } else { 01677 bool secondary_active = false; 01678 //Load first Secondary and then Primary 01679 key_mat = pana_server_key_get(false); 01680 if (key_mat->key_id) { 01681 key_ptr = pana_key_get(key_mat->key_material); 01682 secondary_active = true; 01683 mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01684 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true); 01685 if (cur->nwk_wpan_nvm_api) { 01686 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01687 } 01688 } 01689 key_mat = pana_server_key_get(true); 01690 key_ptr = pana_key_get(key_mat->key_material); 01691 if (secondary_active) { 01692 mac_helper_security_next_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01693 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, false); 01694 mac_helper_security_key_swap_next_to_default(cur); 01695 mle_service_security_key_trig(cur->id, key_mat->key_id); 01696 } else { 01697 mac_helper_security_default_key_set(cur, (key_ptr + 16), key_mat->key_id, MAC_KEY_ID_MODE_IDX); 01698 mle_service_security_set_security_key(cur->id, key_ptr, key_mat->key_id, true); 01699 } 01700 if (cur->nwk_wpan_nvm_api) { 01701 cur->nwk_wpan_nvm_api->nvm_params_update_cb(cur->nwk_wpan_nvm_api, true); 01702 } 01703 } 01704 return 0; 01705 } 01706 01707 static void pana_client_authentication_fail(sec_suite_t *suite) 01708 { 01709 if (suite->pana_session.nvm_offset) { 01710 //tr_debug("NVM Session Remove"); 01711 pana_session_nvm_udate(suite, PANA_SERVER_CLIENT_SESSION_REMOVE_UPDATE); 01712 } 01713 if (pana_server_base && pana_server_base->open_pana_authentication_cnt) { 01714 pana_server_base->open_pana_authentication_cnt--; 01715 } 01716 } 01717 01718 #else 01719 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) 01720 { 01721 (void)update_cb; 01722 (void)nvm_static_buffer; 01723 return -1; 01724 } 01725 01726 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer) 01727 { 01728 (void) nvm_pointer; 01729 return -1; 01730 } 01731 01732 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id) 01733 { 01734 (void) nvm_data; 01735 (void)interface_id; 01736 return -1; 01737 } 01738 #endif 01739 #else 01740 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) 01741 { 01742 (void)update_cb; 01743 (void)nvm_static_buffer; 01744 return -1; 01745 } 01746 01747 int8_t pana_server_nvm_client_session_load(uint8_t *nvm_pointer) 01748 { 01749 (void) nvm_pointer; 01750 return -1; 01751 } 01752 01753 int8_t pana_server_restore_from_nvm(uint8_t *nvm_data, int8_t interface_id) 01754 { 01755 (void) nvm_data; 01756 (void)interface_id; 01757 return -1; 01758 } 01759 #endif
Generated on Tue Jul 12 2022 13:03:08 by
