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