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
ws_pae_controller.c
00001 /* 00002 * Copyright (c) 2018-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 00018 #include "nsconfig.h" 00019 #include <string.h> 00020 #include "ns_types.h" 00021 #include "ns_list.h" 00022 #include "ns_trace.h" 00023 #include "nsdynmemLIB.h" 00024 #include "fhss_config.h " 00025 #include "ns_address.h" 00026 #include "NWK_INTERFACE/Include/protocol.h" 00027 #include "6LoWPAN/ws/ws_config.h" 00028 #include "6LoWPAN/ws/ws_pae_controller.h" 00029 #include "Security/protocols/sec_prot_certs.h" 00030 #include "Security/protocols/sec_prot_keys.h" 00031 #include "6LoWPAN/ws/ws_pae_timers.h" 00032 #include "6LoWPAN/ws/ws_pae_supp.h" 00033 #include "6LoWPAN/ws/ws_pae_auth.h" 00034 #include "6LoWPAN/ws/ws_pae_nvm_store.h" 00035 #include "6LoWPAN/ws/ws_pae_nvm_data.h" 00036 #include "mbedtls/sha256.h" 00037 00038 #ifdef HAVE_WS 00039 00040 #define TRACE_GROUP "wspc" 00041 00042 typedef int8_t ws_pae_delete(protocol_interface_info_entry_t *interface_ptr); 00043 typedef void ws_pae_timer(uint16_t ticks); 00044 typedef int8_t ws_pae_br_addr_write(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64); 00045 typedef int8_t ws_pae_br_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64); 00046 typedef void ws_pae_gtks_updated(protocol_interface_info_entry_t *interface_ptr); 00047 typedef int8_t ws_pae_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash); 00048 typedef int8_t ws_pae_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index); 00049 00050 typedef struct { 00051 uint8_t gtk[GTK_LEN]; /**< GTK key */ 00052 bool set : 1; /**< Key has been set */ 00053 bool installed : 1; /**< Key has been installed on MAC */ 00054 } nw_key_t; 00055 00056 typedef struct { 00057 ns_list_link_t link; /**< Link */ 00058 uint8_t target_eui_64[8]; /**< EAPOL target */ 00059 uint16_t target_pan_id; /**< EAPOL target PAN ID */ 00060 uint8_t br_eui_64[8]; /**< Border router EUI-64 */ 00061 sec_prot_gtk_keys_t gtks; /**< GTKs */ 00062 sec_prot_gtk_keys_t next_gtks; /**< Next GTKs */ 00063 int8_t gtk_index; /**< GTK index */ 00064 uint8_t gtkhash[32]; /**< GTK hashes */ 00065 sec_prot_certs_t certs; /**< Certificates */ 00066 nw_key_t nw_key[GTK_NUM]; /**< Currently active network keys (on MAC) */ 00067 char *network_name; /**< Network name for GAK generation */ 00068 uint16_t frame_cnt_store_timer; /**< Timer for storing frame counter value */ 00069 frame_counters_t frame_counters; /**< Frame counters */ 00070 timer_settings_t timer_settings; /**< Timer settings */ 00071 protocol_interface_info_entry_t *interface_ptr; /**< List link entry */ 00072 ws_pae_controller_auth_completed *auth_completed; /**< Authentication completed callback, continue bootstrap */ 00073 ws_pae_controller_nw_key_set *nw_key_set; /**< Key set callback */ 00074 ws_pae_controller_nw_key_clear *nw_key_clear; /**< Key clear callback */ 00075 ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set; /**< Send key index set callback */ 00076 ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set; /**< Frame counter set callback */ 00077 ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read; /**< Frame counter read callback */ 00078 ws_pae_controller_pan_ver_increment *pan_ver_increment; /**< PAN version increment callback */ 00079 ws_pae_delete *pae_delete; /**< PAE delete callback */ 00080 ws_pae_timer *pae_fast_timer; /**< PAE fast timer callback */ 00081 ws_pae_timer *pae_slow_timer; /**< PAE slow timer callback */ 00082 ws_pae_br_addr_write *pae_br_addr_write; /**< PAE Border router EUI-64 write callback */ 00083 ws_pae_br_addr_read *pae_br_addr_read; /**< PAE Border router EUI-64 read callback */ 00084 ws_pae_gtks_updated *pae_gtks_updated; /**< PAE GTKs updated */ 00085 ws_pae_gtk_hash_update *pae_gtk_hash_update; /**< PAE GTK HASH update */ 00086 ws_pae_nw_key_index_update *pae_nw_key_index_update; /**< PAE NW key index update */ 00087 nvm_tlv_entry_t *pae_nvm_buffer; /**< Buffer For PAE NVM write operation*/ 00088 bool gtks_set : 1; /**< GTKs are set */ 00089 bool gtkhash_set : 1; /**< GTK hashes are set */ 00090 bool key_index_set : 1; /**< NW key index is set */ 00091 } pae_controller_t; 00092 00093 typedef struct { 00094 uint16_t node_limit; /**< Max number of stored supplicants */ 00095 bool node_limit_set : 1; /**< Node limit set */ 00096 bool ext_cert_valid_enabled : 1; /**< Extended certificate validation enabled */ 00097 } pae_controller_config_t; 00098 00099 static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr); 00100 static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry); 00101 static void ws_pae_controller_frame_counter_timer_trigger(uint16_t seconds, pae_controller_t *entry); 00102 static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool use_threshold); 00103 static void ws_pae_controller_nvm_frame_counter_write(nvm_tlv_entry_t *tlv_entry); 00104 static int8_t ws_pae_controller_nvm_frame_counter_read(frame_counters_t *counters); 00105 static pae_controller_t *ws_pae_controller_get_or_create(int8_t interface_id); 00106 static void ws_pae_controller_gtk_hash_set(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash); 00107 static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks); 00108 static void ws_pae_controller_active_nw_key_clear(nw_key_t *nw_key); 00109 static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t *cur, uint8_t index); 00110 static int8_t ws_pae_controller_gak_from_gtk(uint8_t *gak, uint8_t *gtk, char *network_name); 00111 static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info_entry_t *interface_ptr, uint8_t index); 00112 static void ws_pae_controller_data_init(pae_controller_t *controller); 00113 static void ws_pae_controller_frame_counter_read(pae_controller_t *controller); 00114 static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counters); 00115 00116 static const char *FRAME_COUNTER_FILE = FRAME_COUNTER_FILE_NAME; 00117 00118 static NS_LIST_DEFINE(pae_controller_list, pae_controller_t, link); 00119 00120 pae_controller_config_t pae_controller_config = { 00121 .node_limit = 0, 00122 .node_limit_set = false, 00123 .ext_cert_valid_enabled = false 00124 }; 00125 00126 #if !defined(HAVE_PAE_SUPP) && !defined(HAVE_PAE_AUTH) 00127 00128 static void ws_pae_controller_test_keys_set(sec_prot_gtk_keys_t *gtks) 00129 { 00130 uint8_t gtk[GTK_LEN]; 00131 00132 // Test data 00133 for (int i = 0; i < GTK_LEN; i++) { 00134 gtk[i] = 0xcf - i; 00135 } 00136 00137 sec_prot_keys_gtk_set(gtks, 0, gtk, GTK_DEFAULT_LIFETIME); 00138 } 00139 00140 #else 00141 00142 #define ws_pae_controller_test_keys_set(gtks); 00143 00144 #endif 00145 00146 int8_t ws_pae_controller_authenticate(protocol_interface_info_entry_t *interface_ptr) 00147 { 00148 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00149 if (!controller) { 00150 return -1; 00151 } 00152 00153 #ifdef HAVE_PAE_SUPP 00154 // In case test keys are set uses those and does not initiate authentication 00155 if (controller->gtks_set) { 00156 if (sec_prot_keys_gtks_are_updated(&controller->gtks)) { 00157 ws_pae_controller_nw_key_check_and_insert(controller->interface_ptr, &controller->gtks); 00158 sec_prot_keys_gtks_updated_reset(&controller->gtks); 00159 ws_pae_supp_gtks_set(controller->interface_ptr, &controller->gtks); 00160 } 00161 controller->auth_completed(interface_ptr, AUTH_RESULT_OK, NULL); 00162 return 0; 00163 } 00164 00165 if (ws_pae_supp_authenticate(controller->interface_ptr, controller->target_pan_id, controller->target_eui_64) < 0) { 00166 controller->auth_completed(interface_ptr, AUTH_RESULT_ERR_UNSPEC, controller->target_eui_64); 00167 } 00168 00169 #else 00170 ws_pae_controller_test_keys_set(&controller->gtks); 00171 ws_pae_controller_nw_key_check_and_insert(interface_ptr, &controller->gtks); 00172 ws_pae_controller_nw_key_index_check_and_set(interface_ptr, 0); 00173 00174 controller->auth_completed(interface_ptr, AUTH_RESULT_OK); 00175 #endif 00176 00177 return 0; 00178 } 00179 00180 int8_t ws_pae_controller_bootstrap_done(protocol_interface_info_entry_t *interface_ptr) 00181 { 00182 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00183 if (!controller) { 00184 return -1; 00185 } 00186 00187 #ifdef HAVE_PAE_SUPP 00188 // RPL parent is known, remove EAPOL target that what was set using the authenticate call */ 00189 ws_pae_supp_eapol_target_remove(interface_ptr); 00190 00191 /* Trigger GTK hash update to supplicant, so it can check whether keys have been updated 00192 during bootstrap. Does nothing if GTKs are up to date. */ 00193 ws_pae_supp_gtk_hash_update(interface_ptr, controller->gtkhash); 00194 #endif 00195 00196 return 0; 00197 } 00198 00199 int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *interface_ptr, uint16_t local_port, const uint8_t *remote_addr, uint16_t remote_port) 00200 { 00201 (void) local_port; 00202 (void) remote_port; 00203 00204 if (!interface_ptr || !remote_addr) { 00205 return -1; 00206 } 00207 00208 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00209 if (!controller) { 00210 return -1; 00211 } 00212 00213 #ifdef HAVE_PAE_AUTH 00214 if (sec_prot_keys_gtks_are_updated(&controller->gtks)) { 00215 ws_pae_auth_gtks_updated(interface_ptr); 00216 if (controller->gtk_index >= 0) { 00217 controller->pae_nw_key_index_update(interface_ptr, controller->gtk_index); 00218 } 00219 sec_prot_keys_gtks_updated_reset(&controller->gtks); 00220 } 00221 #else 00222 ws_pae_controller_test_keys_set(&controller->gtks); 00223 ws_pae_controller_nw_key_check_and_insert(interface_ptr, &controller->gtks); 00224 ws_pae_controller_nw_key_index_check_and_set(interface_ptr, 0); 00225 #endif 00226 00227 if (ws_pae_auth_addresses_set(interface_ptr, local_port, remote_addr, remote_port) < 0) { 00228 return -1; 00229 } 00230 00231 if (pae_controller_config.node_limit_set) { 00232 ws_pae_auth_node_limit_set(controller->interface_ptr, pae_controller_config.node_limit); 00233 } 00234 00235 ws_pae_auth_cb_register(interface_ptr, ws_pae_controller_gtk_hash_set, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_nw_key_index_check_and_set); 00236 00237 ws_pae_auth_start(interface_ptr); 00238 00239 return 0; 00240 } 00241 00242 int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment) 00243 { 00244 if (!interface_ptr) { 00245 return -1; 00246 } 00247 00248 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00249 if (!controller) { 00250 return -1; 00251 } 00252 00253 controller->auth_completed = completed; 00254 controller->nw_key_set = nw_key_set; 00255 controller->nw_key_clear = nw_key_clear; 00256 controller->nw_send_key_index_set = nw_send_key_index_set; 00257 controller->nw_frame_counter_set = nw_frame_counter_set; 00258 controller->nw_frame_counter_read = nw_frame_counter_read; 00259 controller->pan_ver_increment = pan_ver_increment; 00260 00261 return 0; 00262 } 00263 00264 int8_t ws_pae_controller_set_target(protocol_interface_info_entry_t *interface_ptr, uint16_t target_pan_id, uint8_t *target_eui_64) 00265 { 00266 if (!interface_ptr) { 00267 return -1; 00268 } 00269 00270 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00271 if (!controller) { 00272 return -1; 00273 } 00274 00275 controller->target_pan_id = target_pan_id; 00276 memcpy(controller->target_eui_64, target_eui_64, 8); 00277 00278 return 0; 00279 } 00280 00281 int8_t ws_pae_controller_nw_info_set(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name) 00282 { 00283 (void) pan_id; 00284 (void) network_name; 00285 00286 if (!interface_ptr) { 00287 return -1; 00288 } 00289 00290 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00291 if (!controller) { 00292 return -1; 00293 } 00294 00295 controller->network_name = network_name; 00296 00297 return ws_pae_supp_nw_info_set(interface_ptr, pan_id, network_name); 00298 } 00299 00300 int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr) 00301 { 00302 if (!interface_ptr) { 00303 return -1; 00304 } 00305 00306 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00307 if (!controller) { 00308 return -1; 00309 } 00310 00311 return ws_pae_supp_nw_key_valid(interface_ptr); 00312 } 00313 00314 static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks) 00315 { 00316 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00317 if (!controller) { 00318 return -1; 00319 } 00320 00321 int8_t ret = -1; 00322 00323 // Adds, removes and updates network keys to MAC based on new GTKs 00324 nw_key_t *nw_key = controller->nw_key; 00325 for (uint8_t i = 0; i < GTK_NUM; i++) { 00326 // Gets GTK for the index (new, modified or none) 00327 uint8_t *gtk = sec_prot_keys_gtk_get(gtks, i); 00328 00329 // If network key is set and GTK key is not set or not the same, removes network key 00330 if (nw_key[i].set && (!gtk || memcmp(nw_key[i].gtk, gtk, GTK_LEN) != 0)) { 00331 // Removes key from MAC if installed 00332 if (nw_key[i].installed) { 00333 controller->nw_key_clear(interface_ptr, i); 00334 } 00335 nw_key[i].installed = false; 00336 nw_key[i].set = false; 00337 tr_info("NW key remove: %i", i); 00338 } 00339 00340 // If GTK key is not set, continues to next GTK 00341 if (!gtk) { 00342 continue; 00343 } 00344 00345 // Network key is set and installed, all done 00346 if (nw_key[i].set && nw_key[i].installed) { 00347 continue; 00348 } 00349 00350 // If network key is not set, stores the new GTK key to network key 00351 if (!nw_key[i].set) { 00352 nw_key[i].set = true; 00353 nw_key[i].installed = false; 00354 memcpy(nw_key[i].gtk, gtk, GTK_LEN); 00355 } 00356 00357 // If network key has not been installed, installs it and updates frame counter as needed 00358 if (!nw_key[i].installed) { 00359 uint8_t gtkhash[GTK_HASH_LEN]; 00360 sec_prot_keys_gtk_hash_generate(gtk, gtkhash); 00361 tr_info("NW key set: %i, hash: %s", i, trace_array(gtkhash, 8)); 00362 uint8_t gak[GTK_LEN]; 00363 if (ws_pae_controller_gak_from_gtk(gak, gtk, controller->network_name) >= 0) { 00364 // Install the new network key derived from GTK and network name (GAK) to MAC 00365 controller->nw_key_set(interface_ptr, i, i, gak); 00366 tr_info("NW: %s", controller->network_name); 00367 tr_info("NW: %s", trace_array((uint8_t *)controller->network_name, 20)); 00368 tr_info("GTK: %s", trace_array(gtk, 16)); 00369 tr_info("GAK: %s", trace_array(gak, 16)); 00370 nw_key[i].installed = true; 00371 ret = 0; 00372 } else { 00373 tr_error("GAK generation failed network name: %s", controller->network_name); 00374 continue; 00375 } 00376 00377 // If frame counter value has been stored for the network key, updates the frame counter if needed 00378 if (controller->frame_counters.counter[i].set && 00379 memcmp(gtk, controller->frame_counters.counter[i].gtk, GTK_LEN) == 0) { 00380 // Read current counter from MAC 00381 uint32_t curr_frame_counter; 00382 controller->nw_frame_counter_read(controller->interface_ptr, &curr_frame_counter, i); 00383 // If stored frame counter is greater than MAC counter 00384 if (controller->frame_counters.counter[i].frame_counter > curr_frame_counter) { 00385 tr_debug("Frame counter set: %i, stored %"PRIu32" current: %"PRIu32"", i, controller->frame_counters.counter[i].frame_counter, curr_frame_counter); 00386 curr_frame_counter = controller->frame_counters.counter[i].frame_counter; 00387 // Updates MAC frame counter 00388 controller->nw_frame_counter_set(controller->interface_ptr, curr_frame_counter, i); 00389 } 00390 } 00391 /* Trigger storing of frame counters; there is 5 seconds delay to give time for the 00392 other keys to be inserted, so that frame counters for several keys are updated on 00393 a same time. */ 00394 ws_pae_controller_frame_counter_timer_trigger(FRAME_COUNTER_STORE_TRIGGER, controller); 00395 } 00396 } 00397 00398 return ret; 00399 } 00400 00401 static void ws_pae_controller_active_nw_key_clear(nw_key_t *nw_key) 00402 { 00403 memset(nw_key, 0, sizeof(nw_key_t)); 00404 nw_key->set = false; 00405 nw_key->installed = false; 00406 } 00407 00408 static int8_t ws_pae_controller_gak_from_gtk(uint8_t *gak, uint8_t *gtk, char *network_name) 00409 { 00410 #if defined(HAVE_PAE_SUPP) || defined(HAVE_PAE_AUTH) 00411 uint8_t network_name_len = strlen(network_name); 00412 if (network_name_len == 0) { 00413 return -1; 00414 } 00415 00416 uint8_t input[network_name_len + GTK_LEN]; 00417 memcpy(input, network_name, network_name_len); 00418 memcpy(input + network_name_len, gtk, GTK_LEN); 00419 00420 int8_t ret_val = 0; 00421 00422 mbedtls_sha256_context ctx; 00423 00424 mbedtls_sha256_init(&ctx); 00425 00426 if (mbedtls_sha256_starts_ret(&ctx, 0) != 0) { 00427 ret_val = -1; 00428 goto error; 00429 } 00430 00431 if (mbedtls_sha256_update_ret(&ctx, input, network_name_len + GTK_LEN) != 0) { 00432 ret_val = -1; 00433 goto error; 00434 } 00435 00436 uint8_t output[32]; 00437 00438 if (mbedtls_sha256_finish_ret(&ctx, output) != 0) { 00439 ret_val = -1; 00440 goto error; 00441 } 00442 00443 memcpy(gak, &output[0], 16); 00444 00445 error: 00446 mbedtls_sha256_free(&ctx); 00447 00448 return ret_val; 00449 #else 00450 (void) network_name; 00451 memcpy(gak, gtk, 16); 00452 return 0; 00453 #endif 00454 } 00455 00456 int8_t ws_pae_controller_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index) 00457 { 00458 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00459 if (!controller) { 00460 return -1; 00461 } 00462 00463 if (controller->pae_nw_key_index_update) { 00464 controller->pae_nw_key_index_update(interface_ptr, index); 00465 } 00466 00467 return 0; 00468 } 00469 00470 void ws_pae_controller_nw_keys_remove(protocol_interface_info_entry_t *interface_ptr) 00471 { 00472 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00473 if (!controller) { 00474 return; 00475 } 00476 00477 tr_info("NW keys remove"); 00478 00479 nw_key_t *nw_key = controller->nw_key; 00480 for (uint8_t i = 0; i < GTK_NUM; i++) { 00481 // Deletes the key if it is set 00482 if (nw_key[i].set) { 00483 tr_info("NW key remove: %i", i); 00484 if (nw_key[i].installed) { 00485 controller->nw_key_clear(interface_ptr, i); 00486 } 00487 nw_key[i].set = false; 00488 nw_key[i].installed = false; 00489 } 00490 } 00491 } 00492 00493 static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info_entry_t *interface_ptr, uint8_t index) 00494 { 00495 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00496 if (!controller) { 00497 return; 00498 } 00499 00500 if (controller->nw_send_key_index_set) { 00501 tr_info("NW send key index set: %i", index + 1); 00502 controller->nw_send_key_index_set(interface_ptr, index); 00503 controller->gtk_index = index; 00504 } 00505 00506 // Do not update PAN version for initial key index set 00507 if (controller->key_index_set) { 00508 if (controller->pan_ver_increment) { 00509 controller->pan_ver_increment(interface_ptr); 00510 } 00511 } else { 00512 controller->key_index_set = true; 00513 } 00514 } 00515 00516 static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t *cur, uint8_t index) 00517 { 00518 pae_controller_t *controller = ws_pae_controller_get(cur); 00519 if (!controller) { 00520 return; 00521 } 00522 00523 if (controller->nw_send_key_index_set) { 00524 /* Checks if frame counters needs to be stored for the new GTK that is taken into 00525 use; this is the last check that stored counters are in sync before activating key */ 00526 ws_pae_controller_frame_counter_store(controller, true); 00527 // Activates key on MAC 00528 controller->nw_send_key_index_set(controller->interface_ptr, index); 00529 tr_info("NW send key index set: %i", index + 1); 00530 controller->gtk_index = index; 00531 } 00532 } 00533 00534 int8_t ws_pae_controller_init(protocol_interface_info_entry_t *interface_ptr) 00535 { 00536 if (!interface_ptr) { 00537 return -1; 00538 } 00539 00540 if (ws_pae_controller_get(interface_ptr) != NULL) { 00541 return 0; 00542 } 00543 00544 pae_controller_t *controller = ns_dyn_mem_alloc(sizeof(pae_controller_t)); 00545 void *pae_nvm_buffer = ws_pae_buffer_allocate(); 00546 00547 if (!controller || !pae_nvm_buffer) { 00548 ns_dyn_mem_free(controller); 00549 ns_dyn_mem_free(pae_nvm_buffer); 00550 return -1; 00551 } 00552 00553 controller->interface_ptr = interface_ptr; 00554 controller->auth_completed = NULL; 00555 controller->nw_key_set = NULL; 00556 controller->nw_key_clear = NULL; 00557 controller->nw_send_key_index_set = NULL; 00558 controller->nw_frame_counter_set = NULL; 00559 controller->pan_ver_increment = NULL; 00560 controller->pae_nvm_buffer = pae_nvm_buffer; 00561 00562 ws_pae_controller_data_init(controller); 00563 00564 ns_list_add_to_end(&pae_controller_list, controller); 00565 00566 return 0; 00567 } 00568 00569 static void ws_pae_controller_data_init(pae_controller_t *controller) 00570 { 00571 memset(controller->target_eui_64, 0, 8); 00572 memset(controller->br_eui_64, 0, 8); 00573 memset(controller->gtkhash, 0, 32); 00574 00575 ws_pae_controller_active_nw_key_clear(&controller->nw_key[0]); 00576 ws_pae_controller_active_nw_key_clear(&controller->nw_key[1]); 00577 ws_pae_controller_active_nw_key_clear(&controller->nw_key[2]); 00578 ws_pae_controller_active_nw_key_clear(&controller->nw_key[3]); 00579 00580 controller->target_pan_id = 0xffff; 00581 controller->pae_delete = NULL; 00582 controller->pae_fast_timer = NULL; 00583 controller->pae_slow_timer = NULL; 00584 controller->pae_br_addr_write = NULL; 00585 controller->pae_br_addr_read = NULL; 00586 controller->pae_gtks_updated = NULL; 00587 controller->pae_gtk_hash_update = NULL; 00588 controller->pae_nw_key_index_update = NULL; 00589 controller->gtks_set = false; 00590 controller->gtkhash_set = false; 00591 controller->key_index_set = false; 00592 controller->gtk_index = -1; 00593 controller->network_name = NULL; 00594 controller->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL; 00595 ws_pae_controller_frame_counter_reset(&controller->frame_counters); 00596 sec_prot_keys_gtks_init(&controller->gtks); 00597 sec_prot_keys_gtks_init(&controller->next_gtks); 00598 sec_prot_certs_init(&controller->certs); 00599 sec_prot_certs_ext_certificate_validation_set(&controller->certs, pae_controller_config.ext_cert_valid_enabled); 00600 ws_pae_timers_settings_init(&controller->timer_settings); 00601 } 00602 00603 static void ws_pae_controller_frame_counter_read(pae_controller_t *controller) 00604 { 00605 // Read frame counters 00606 if (ws_pae_controller_nvm_frame_counter_read(&controller->frame_counters) >= 0) { 00607 bool updated = false; 00608 // Checks frame counters 00609 for (uint8_t index = 0; index < GTK_NUM; index++) { 00610 if (controller->frame_counters.counter[index].set) { 00611 // Increments frame counters 00612 controller->frame_counters.counter[index].frame_counter += FRAME_COUNTER_INCREMENT; 00613 00614 tr_info("Read frame counter: index %i value %"PRIu32"", index, controller->frame_counters.counter[index].frame_counter); 00615 00616 updated = true; 00617 } 00618 } 00619 if (updated) { 00620 // Writes incremented frame counters 00621 ws_pae_nvm_store_frame_counter_tlv_create(controller->pae_nvm_buffer, &controller->frame_counters); 00622 ws_pae_controller_nvm_frame_counter_write(controller->pae_nvm_buffer); 00623 //ws_pae_controller_frame_counter_write(controller, &controller->frame_counters); 00624 } 00625 } 00626 } 00627 00628 static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counters) 00629 { 00630 for (uint8_t index = 0; index < GTK_NUM; index++) { 00631 memset(frame_counters->counter[index].gtk, 0, GTK_LEN); 00632 frame_counters->counter[index].frame_counter = 0; 00633 frame_counters->counter[index].set = false; 00634 } 00635 } 00636 00637 int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_ptr) 00638 { 00639 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00640 if (!controller) { 00641 return -1; 00642 } 00643 00644 if (ws_pae_supp_init(controller->interface_ptr, &controller->certs, &controller->timer_settings) < 0) { 00645 return -1; 00646 } 00647 00648 controller->pae_delete = ws_pae_supp_delete; 00649 controller->pae_fast_timer = ws_pae_supp_fast_timer; 00650 controller->pae_slow_timer = ws_pae_supp_slow_timer; 00651 controller->pae_br_addr_write = ws_pae_supp_border_router_addr_write; 00652 controller->pae_br_addr_read = ws_pae_supp_border_router_addr_read; 00653 controller->pae_gtk_hash_update = ws_pae_supp_gtk_hash_update; 00654 controller->pae_nw_key_index_update = ws_pae_supp_nw_key_index_update; 00655 00656 ws_pae_supp_cb_register(controller->interface_ptr, controller->auth_completed, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_active_nw_key_set); 00657 00658 ws_pae_controller_frame_counter_read(controller); 00659 00660 return 0; 00661 } 00662 00663 int8_t ws_pae_controller_auth_init(protocol_interface_info_entry_t *interface_ptr) 00664 { 00665 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00666 if (!controller) { 00667 return -1; 00668 } 00669 00670 if (ws_pae_auth_init(controller->interface_ptr, &controller->gtks, &controller->next_gtks, &controller->certs, &controller->timer_settings) < 0) { 00671 return -1; 00672 } 00673 00674 controller->pae_delete = ws_pae_auth_delete; 00675 controller->pae_fast_timer = ws_pae_auth_fast_timer; 00676 controller->pae_slow_timer = ws_pae_auth_slow_timer; 00677 controller->pae_gtks_updated = ws_pae_auth_gtks_updated; 00678 controller->pae_nw_key_index_update = ws_pae_auth_nw_key_index_update; 00679 00680 ws_pae_controller_frame_counter_read(controller); 00681 00682 return 0; 00683 } 00684 00685 int8_t ws_pae_controller_stop(protocol_interface_info_entry_t *interface_ptr) 00686 { 00687 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00688 if (!controller) { 00689 return -1; 00690 } 00691 00692 // Stores frame counter 00693 ws_pae_controller_frame_counter_store(controller, false); 00694 00695 // Removes network keys from PAE controller and MAC 00696 ws_pae_controller_nw_keys_remove(interface_ptr); 00697 00698 // If PAE has been initialized, deletes it 00699 if (controller->pae_delete) { 00700 controller->pae_delete(interface_ptr); 00701 } 00702 00703 // Free data 00704 sec_prot_certs_delete(&controller->certs); 00705 00706 // Init controller data 00707 ws_pae_controller_data_init(controller); 00708 00709 return 0; 00710 } 00711 00712 int8_t ws_pae_controller_delete(protocol_interface_info_entry_t *interface_ptr) 00713 { 00714 if (!interface_ptr) { 00715 return -1; 00716 } 00717 00718 ws_pae_controller_stop(interface_ptr); 00719 00720 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00721 if (!controller) { 00722 return -1; 00723 } 00724 00725 ns_list_remove(&pae_controller_list, controller); 00726 ns_dyn_mem_free(controller->pae_nvm_buffer); 00727 ns_dyn_mem_free(controller); 00728 00729 return 0; 00730 } 00731 00732 int8_t ws_pae_controller_timing_adjust(uint8_t timing) 00733 { 00734 ws_pae_supp_timing_adjust(timing); 00735 ws_pae_auth_timing_adjust(timing); 00736 return 0; 00737 } 00738 00739 int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry_s *new_chain) 00740 { 00741 if (!new_chain) { 00742 return -1; 00743 } 00744 00745 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00746 // Delete previous information 00747 sec_prot_certs_delete(&entry->certs); 00748 00749 // Adds a trusted certificate from index 0 00750 if (new_chain->cert_chain[0]) { 00751 cert_chain_entry_t *root_ca_chain = sec_prot_certs_chain_entry_create(); 00752 sec_prot_certs_cert_set(root_ca_chain, 0, (uint8_t *) new_chain->cert_chain[0], new_chain->cert_len[0]); 00753 sec_prot_certs_chain_list_add(&entry->certs.trusted_cert_chain_list, root_ca_chain); 00754 } 00755 00756 // Adds own certificate chain from indexes 1 to 3 00757 for (uint8_t i = 1; i < SEC_PROT_CERT_CHAIN_DEPTH; i++) { 00758 if (new_chain->cert_chain[i]) { 00759 sec_prot_certs_cert_set(&entry->certs.own_cert_chain, i - 1, (uint8_t *) new_chain->cert_chain[i], new_chain->cert_len[i]); 00760 if (new_chain->key_chain[i]) { 00761 // Will be the key from top certificate in chain after all certificates are added 00762 uint8_t key_len = strlen((char *) new_chain->key_chain[i]) + 1; 00763 sec_prot_certs_priv_key_set(&entry->certs.own_cert_chain, (uint8_t *) new_chain->key_chain[i], key_len); 00764 } 00765 } 00766 } 00767 00768 // Updates the length of own certificates 00769 entry->certs.own_cert_chain_len = sec_prot_certs_cert_chain_entry_len_get(&entry->certs.own_cert_chain); 00770 } 00771 00772 return 0; 00773 } 00774 00775 int8_t ws_pae_controller_own_certificate_add(const arm_certificate_entry_s *cert) 00776 { 00777 if (!cert) { 00778 return -1; 00779 } 00780 00781 int8_t ret = -1; 00782 00783 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00784 for (uint8_t i = 0; i < SEC_PROT_CERT_CHAIN_DEPTH; i++) { 00785 if (entry->certs.own_cert_chain.cert[i] == NULL) { 00786 sec_prot_certs_cert_set(&entry->certs.own_cert_chain, i, (uint8_t *) cert->cert, cert->cert_len); 00787 // Set private key if set for the certificate that is added 00788 if (cert->key && cert->key_len > 0) { 00789 sec_prot_certs_priv_key_set(&entry->certs.own_cert_chain, (uint8_t *) cert->key, cert->key_len); 00790 } 00791 ret = 0; 00792 break; 00793 } 00794 } 00795 // Updates the length of own certificates 00796 entry->certs.own_cert_chain_len = sec_prot_certs_cert_chain_entry_len_get(&entry->certs.own_cert_chain); 00797 } 00798 00799 return ret; 00800 } 00801 00802 int8_t ws_pae_controller_own_certificates_remove(void) 00803 { 00804 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00805 sec_prot_certs_chain_entry_init(&entry->certs.own_cert_chain); 00806 entry->certs.own_cert_chain_len = 0; 00807 } 00808 00809 return 0; 00810 } 00811 00812 int8_t ws_pae_controller_trusted_certificate_add(const arm_certificate_entry_s *cert) 00813 { 00814 if (!cert) { 00815 return -1; 00816 } 00817 00818 int8_t ret = -1; 00819 00820 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00821 cert_chain_entry_t *trusted_cert = sec_prot_certs_chain_entry_create(); 00822 sec_prot_certs_cert_set(trusted_cert, 0, (uint8_t *) cert->cert, cert->cert_len); 00823 00824 if (sec_prot_certs_chain_list_entry_find(&entry->certs.trusted_cert_chain_list, trusted_cert)) { 00825 sec_prot_certs_chain_entry_delete(trusted_cert); 00826 continue; 00827 } 00828 sec_prot_certs_chain_list_add(&entry->certs.trusted_cert_chain_list, trusted_cert); 00829 ret = 0; 00830 } 00831 00832 return ret; 00833 } 00834 00835 int8_t ws_pae_controller_trusted_certificate_remove(const arm_certificate_entry_s *cert) 00836 { 00837 if (!cert) { 00838 return -1; 00839 } 00840 00841 int8_t ret = -1; 00842 00843 cert_chain_entry_t *trusted_cert = sec_prot_certs_chain_entry_create(); 00844 sec_prot_certs_cert_set(trusted_cert, 0, (uint8_t *) cert->cert, cert->cert_len); 00845 00846 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00847 cert_chain_entry_t *removed_cert = sec_prot_certs_chain_list_entry_find(&entry->certs.trusted_cert_chain_list, trusted_cert); 00848 if (removed_cert) { 00849 sec_prot_certs_chain_list_entry_delete(&entry->certs.trusted_cert_chain_list, removed_cert); 00850 ret = 0; 00851 } 00852 } 00853 00854 sec_prot_certs_chain_entry_delete(trusted_cert); 00855 00856 return ret; 00857 } 00858 00859 int8_t ws_pae_controller_trusted_certificates_remove(void) 00860 { 00861 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00862 sec_prot_certs_chain_list_delete(&entry->certs.trusted_cert_chain_list); 00863 } 00864 00865 return 0; 00866 } 00867 00868 int8_t ws_pae_controller_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl) 00869 { 00870 if (!crl) { 00871 return -1; 00872 } 00873 00874 int8_t ret = -1; 00875 00876 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00877 cert_revocat_list_entry_t *cert_revoc_list = sec_prot_certs_revocat_list_entry_create(); 00878 sec_prot_certs_revocat_list_set(cert_revoc_list, crl->crl, crl->crl_len); 00879 00880 if (sec_prot_certs_revocat_lists_entry_find(&entry->certs.cert_revocat_lists, cert_revoc_list)) { 00881 sec_prot_certs_revocat_list_entry_delete(cert_revoc_list); 00882 continue; 00883 } 00884 00885 sec_prot_certs_revocat_lists_add(&entry->certs.cert_revocat_lists, cert_revoc_list); 00886 ret = 0; 00887 } 00888 00889 return ret; 00890 } 00891 00892 int8_t ws_pae_controller_certificate_revocation_list_remove(const arm_cert_revocation_list_entry_s *crl) 00893 { 00894 if (!crl) { 00895 return -1; 00896 } 00897 00898 int8_t ret = -1; 00899 00900 cert_revocat_list_entry_t *cert_revoc_list = sec_prot_certs_revocat_list_entry_create(); 00901 sec_prot_certs_revocat_list_set(cert_revoc_list, crl->crl, crl->crl_len); 00902 00903 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 00904 cert_revocat_list_entry_t *removed_cert_revoc_list = sec_prot_certs_revocat_lists_entry_find(&entry->certs.cert_revocat_lists, cert_revoc_list); 00905 if (removed_cert_revoc_list) { 00906 sec_prot_certs_revocat_lists_entry_delete(&entry->certs.cert_revocat_lists, removed_cert_revoc_list); 00907 ret = 0; 00908 } 00909 } 00910 00911 sec_prot_certs_revocat_list_entry_delete(cert_revoc_list); 00912 00913 return ret; 00914 } 00915 00916 int8_t ws_pae_controller_border_router_addr_write(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64) 00917 { 00918 if (!eui_64) { 00919 return -1; 00920 } 00921 00922 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00923 if (!controller) { 00924 return -1; 00925 } 00926 00927 if (controller->pae_br_addr_write) { 00928 return controller->pae_br_addr_write(interface_ptr, eui_64); 00929 } else { 00930 memcpy(controller->br_eui_64, eui_64, 8); 00931 } 00932 00933 return 0; 00934 } 00935 00936 int8_t ws_pae_controller_border_router_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64) 00937 { 00938 if (!eui_64) { 00939 return -1; 00940 } 00941 00942 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 00943 if (!controller) { 00944 return -1; 00945 } 00946 00947 if (controller->pae_br_addr_read) { 00948 return controller->pae_br_addr_read(interface_ptr, eui_64); 00949 } else { 00950 memcpy(eui_64, controller->br_eui_64, 8); 00951 } 00952 00953 return 0; 00954 } 00955 00956 int8_t ws_pae_controller_gtk_update(int8_t interface_id, uint8_t *gtk[GTK_NUM]) 00957 { 00958 if (!gtk) { 00959 return -1; 00960 } 00961 00962 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 00963 if (!controller) { 00964 return -1; 00965 } 00966 00967 // Removes keys set as not used 00968 for (uint8_t i = 0; i < GTK_NUM; i++) { 00969 if (!gtk[i]) { 00970 sec_prot_keys_gtk_clear(&controller->gtks, i); 00971 } 00972 } 00973 00974 // Inserts new keys 00975 for (uint8_t i = 0; i < GTK_NUM; i++) { 00976 if (gtk[i]) { 00977 uint32_t lifetime = sec_prot_keys_gtk_install_order_last_lifetime_get(&controller->gtks); 00978 lifetime += controller->timer_settings.gtk_expire_offset; 00979 if (sec_prot_keys_gtk_set(&controller->gtks, i, gtk[i], lifetime) >= 0) { 00980 controller->gtks_set = true; 00981 tr_info("GTK set index: %i, lifetime %"PRIu32", system time: %"PRIu32"", i, lifetime, protocol_core_monotonic_time / 10); 00982 } 00983 } 00984 } 00985 00986 // Notifies PAE authenticator that GTKs have been updated */ 00987 if (controller->pae_gtks_updated) { 00988 controller->pae_gtks_updated(controller->interface_ptr); 00989 } 00990 00991 return 0; 00992 } 00993 00994 int8_t ws_pae_controller_next_gtk_update(int8_t interface_id, uint8_t *gtk[GTK_NUM]) 00995 { 00996 if (!gtk) { 00997 return -1; 00998 } 00999 01000 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01001 if (!controller) { 01002 return -1; 01003 } 01004 01005 // Inserts new keys and removed keys set as not used 01006 for (uint8_t i = 0; i < GTK_NUM; i++) { 01007 if (gtk[i]) { 01008 sec_prot_keys_gtk_set(&controller->next_gtks, i, gtk[i], 0); 01009 } else { 01010 sec_prot_keys_gtk_clear(&controller->next_gtks, i); 01011 } 01012 } 01013 01014 return 0; 01015 } 01016 01017 int8_t ws_pae_controller_active_key_update(int8_t interface_id, uint8_t index) 01018 { 01019 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01020 if (!controller) { 01021 return -1; 01022 } 01023 01024 controller->gtk_index = index; 01025 01026 if (controller->pae_nw_key_index_update) { 01027 controller->pae_nw_key_index_update(controller->interface_ptr, index); 01028 } 01029 01030 return 0; 01031 } 01032 01033 int8_t ws_pae_controller_key_lifetime_update(int8_t interface_id, uint32_t gtk_lifetime, uint32_t pmk_lifetime, uint32_t ptk_lifetime) 01034 { 01035 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01036 if (!controller) { 01037 return -1; 01038 } 01039 01040 ws_pae_timers_lifetime_set(&controller->timer_settings, gtk_lifetime, pmk_lifetime, ptk_lifetime); 01041 01042 return 0; 01043 } 01044 01045 int8_t ws_pae_controller_gtk_time_settings_update(int8_t interface_id, uint8_t revocat_lifetime_reduct, uint8_t new_activation_time, uint8_t new_install_req, uint32_t max_mismatch) 01046 { 01047 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01048 if (!controller) { 01049 return -1; 01050 } 01051 01052 ws_pae_timers_gtk_time_settings_set(&controller->timer_settings, revocat_lifetime_reduct, new_activation_time, new_install_req, max_mismatch); 01053 01054 return 0; 01055 } 01056 01057 int8_t ws_pae_controller_node_keys_remove(int8_t interface_id, uint8_t *eui_64) 01058 { 01059 #ifndef HAVE_PAE_AUTH 01060 (void) eui_64; 01061 #endif 01062 01063 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01064 if (!controller) { 01065 return -1; 01066 } 01067 01068 return ws_pae_auth_node_keys_remove(controller->interface_ptr, eui_64); 01069 } 01070 01071 int8_t ws_pae_controller_node_access_revoke_start(int8_t interface_id) 01072 { 01073 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01074 if (!controller) { 01075 return -1; 01076 } 01077 01078 ws_pae_auth_node_access_revoke_start(controller->interface_ptr); 01079 01080 return -1; 01081 } 01082 01083 int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit) 01084 { 01085 #ifdef HAVE_PAE_AUTH 01086 pae_controller_config.node_limit = limit; 01087 pae_controller_config.node_limit_set = true; 01088 01089 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01090 if (!controller) { 01091 return -1; 01092 } 01093 01094 ws_pae_auth_node_limit_set(controller->interface_ptr, limit); 01095 01096 return 0; 01097 #else 01098 (void) interface_id; 01099 (void) limit; 01100 return -1; 01101 #endif 01102 } 01103 01104 int8_t ws_pae_controller_ext_certificate_validation_set(int8_t interface_id, bool enabled) 01105 { 01106 #ifdef HAVE_PAE_AUTH 01107 pae_controller_config.ext_cert_valid_enabled = enabled; 01108 01109 pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id); 01110 if (!controller) { 01111 return -1; 01112 } 01113 01114 sec_prot_certs_ext_certificate_validation_set(&controller->certs, enabled); 01115 01116 return 0; 01117 #else 01118 (void) interface_id; 01119 (void) enabled; 01120 return -1; 01121 #endif 01122 } 01123 01124 void ws_pae_controller_forced_gc(bool full_gc) 01125 { 01126 /* Purge only when on critical limit since node limit should handle limiting 01127 of entries in normal case */ 01128 if (!full_gc) { 01129 return; 01130 } 01131 01132 // Purge authenticators for each interface 01133 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 01134 ws_pae_auth_forced_gc(entry->interface_ptr); 01135 } 01136 } 01137 01138 static void ws_pae_controller_gtk_hash_set(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash) 01139 { 01140 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 01141 if (!controller) { 01142 return; 01143 } 01144 01145 memcpy(controller->gtkhash, gtkhash, 32); 01146 01147 tr_info("GTK hash set %s %s %s %s", 01148 trace_array(>khash[0], 8), 01149 trace_array(>khash[8], 8), 01150 trace_array(>khash[16], 8), 01151 trace_array(>khash[24], 8)); 01152 01153 // Do not update PAN version for initial hash set 01154 if (controller->gtkhash_set) { 01155 if (controller->pan_ver_increment) { 01156 controller->pan_ver_increment(interface_ptr); 01157 } 01158 } else { 01159 controller->gtkhash_set = true; 01160 } 01161 } 01162 01163 uint8_t *ws_pae_controller_gtk_hash_ptr_get(protocol_interface_info_entry_t *interface_ptr) 01164 { 01165 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 01166 if (!controller) { 01167 return NULL; 01168 } 01169 01170 return controller->gtkhash; 01171 } 01172 01173 int8_t ws_pae_controller_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash) 01174 { 01175 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 01176 if (!controller) { 01177 return -1; 01178 } 01179 01180 memcpy(controller->gtkhash, gtkhash, 32); 01181 01182 if (controller->pae_gtk_hash_update) { 01183 return controller->pae_gtk_hash_update(interface_ptr, gtkhash); 01184 } 01185 01186 return 0; 01187 } 01188 01189 void ws_pae_controller_fast_timer(uint16_t ticks) 01190 { 01191 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 01192 if (entry->pae_fast_timer) { 01193 entry->pae_fast_timer(ticks); 01194 } 01195 } 01196 } 01197 01198 void ws_pae_controller_slow_timer(uint16_t seconds) 01199 { 01200 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 01201 if (entry->pae_slow_timer) { 01202 entry->pae_slow_timer(seconds); 01203 } 01204 ws_pae_controller_frame_counter_timer(seconds, entry); 01205 } 01206 } 01207 01208 static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry) 01209 { 01210 if (entry->frame_cnt_store_timer > seconds) { 01211 entry->frame_cnt_store_timer -= seconds; 01212 } else { 01213 entry->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL; 01214 ws_pae_controller_frame_counter_store(entry, true); 01215 } 01216 } 01217 01218 static void ws_pae_controller_frame_counter_timer_trigger(uint16_t seconds, pae_controller_t *entry) 01219 { 01220 if (entry->frame_cnt_store_timer > seconds) { 01221 entry->frame_cnt_store_timer = seconds; 01222 } 01223 } 01224 01225 static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool use_threshold) 01226 { 01227 bool update_needed = false; 01228 01229 for (int i = 0; i < GTK_NUM; i++) { 01230 /* If network key is set, checks if frame counter needs to be updated to NVM 01231 * Note! The frame counters for non-installed keys (previous frame counters) are not changed. 01232 * This is because GTKs are removed e.g. if PAN configuration is not heard/cannot be 01233 * de-crypted during a bootstrap. If BR later installs previous keys using 4WH/GKH, the 01234 * frame counters will be still valid. 01235 */ 01236 if (entry->nw_key[i].installed) { 01237 // Reads frame counter for the key 01238 uint32_t curr_frame_counter; 01239 entry->nw_frame_counter_read(entry->interface_ptr, &curr_frame_counter, i); 01240 01241 // If frame counter for the network key has already been stored 01242 if (entry->frame_counters.counter[i].set && 01243 memcmp(entry->nw_key[i].gtk, entry->frame_counters.counter[i].gtk, GTK_LEN) == 0) { 01244 // If threshold check is disabled or frame counter has advanced for the threshold value, stores the new value 01245 if (!use_threshold || 01246 curr_frame_counter > entry->frame_counters.counter[i].frame_counter + FRAME_COUNTER_STORE_THRESHOLD) { 01247 entry->frame_counters.counter[i].frame_counter = curr_frame_counter; 01248 update_needed = true; 01249 tr_debug("Stored updated frame counter: index %i value %"PRIu32"", i, curr_frame_counter); 01250 } 01251 } else { 01252 // For new or modified network keys, stores the frame counter value 01253 entry->frame_counters.counter[i].set = true; 01254 memcpy(entry->frame_counters.counter[i].gtk, entry->nw_key[i].gtk, GTK_LEN); 01255 entry->frame_counters.counter[i].frame_counter = curr_frame_counter; 01256 update_needed = true; 01257 tr_debug("Stored new frame counter: index %i value %"PRIu32"", i, curr_frame_counter); 01258 } 01259 } 01260 } 01261 01262 if (update_needed) { 01263 tr_debug("Write frame counters: system time %"PRIu32"", protocol_core_monotonic_time / 10); 01264 // Writes modified frame counters 01265 ws_pae_nvm_store_frame_counter_tlv_create(entry->pae_nvm_buffer, &entry->frame_counters); 01266 ws_pae_controller_nvm_frame_counter_write(entry->pae_nvm_buffer); 01267 } 01268 } 01269 01270 static int8_t ws_pae_controller_nvm_frame_counter_read(frame_counters_t *counters) 01271 { 01272 nvm_tlv_list_t tlv_list; 01273 ns_list_init(&tlv_list); 01274 01275 if (ws_pae_nvm_store_tlv_file_read(FRAME_COUNTER_FILE, &tlv_list) < 0) { 01276 return -1; 01277 } 01278 01279 int8_t result = -1; 01280 ns_list_foreach_safe(nvm_tlv_entry_t, entry, &tlv_list) { 01281 if (ws_pae_nvm_store_frame_counter_tlv_read(entry, counters) >= 0) { 01282 result = 0; 01283 } 01284 ns_list_remove(&tlv_list, entry); 01285 ns_dyn_mem_free(entry); 01286 } 01287 01288 return result; 01289 } 01290 01291 static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr) 01292 { 01293 ns_list_foreach(pae_controller_t, entry, &pae_controller_list) { 01294 if (entry->interface_ptr == interface_ptr) { 01295 return entry; 01296 } 01297 } 01298 01299 return NULL; 01300 } 01301 01302 static pae_controller_t *ws_pae_controller_get_or_create(int8_t interface_id) 01303 { 01304 protocol_interface_info_entry_t *cur = protocol_stack_interface_info_get_by_id(interface_id); 01305 if (!cur) { 01306 return NULL; 01307 } 01308 01309 pae_controller_t *controller = ws_pae_controller_get(cur); 01310 01311 if (!controller) { 01312 if (ws_pae_controller_init(cur) < 0) { 01313 return NULL; 01314 } 01315 controller = ws_pae_controller_get(cur); 01316 } 01317 01318 return controller; 01319 } 01320 01321 nvm_tlv_entry_t *ws_pae_controller_nvm_tlv_get(protocol_interface_info_entry_t *interface_ptr) 01322 { 01323 pae_controller_t *controller = ws_pae_controller_get(interface_ptr); 01324 if (!controller) { 01325 return NULL; 01326 } 01327 01328 return controller->pae_nvm_buffer; 01329 } 01330 01331 static void ws_pae_controller_nvm_frame_counter_write(nvm_tlv_entry_t *tlv_entry) 01332 { 01333 nvm_tlv_list_t tlv_list; 01334 ns_list_init(&tlv_list); 01335 ns_list_add_to_end(&tlv_list, tlv_entry); 01336 ws_pae_nvm_store_tlv_file_write(FRAME_COUNTER_FILE, &tlv_list); 01337 01338 } 01339 01340 #endif /* HAVE_WS */ 01341
Generated on Tue Jul 12 2022 13:55:04 by
