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