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_lib.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 "NWK_INTERFACE/Include/protocol.h" 00026 #include "6LoWPAN/ws/ws_config.h" 00027 #include "Security/kmp/kmp_addr.h" 00028 #include "Security/kmp/kmp_api.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_lib.h" 00033 00034 #ifdef HAVE_WS 00035 00036 #define TRACE_GROUP "wspl" 00037 00038 void ws_pae_lib_kmp_list_init(kmp_list_t *kmp_list) 00039 { 00040 ns_list_init(kmp_list); 00041 } 00042 00043 kmp_entry_t *ws_pae_lib_kmp_list_add(kmp_list_t *kmp_list, kmp_api_t *kmp) 00044 { 00045 // Already in list 00046 kmp_entry_t *entry = ws_pae_lib_kmp_list_entry_get(kmp_list, kmp); 00047 if (entry) { 00048 return entry; 00049 } 00050 00051 entry = ns_dyn_mem_alloc(sizeof(kmp_entry_t)); 00052 if (!entry) { 00053 return NULL; 00054 } 00055 entry->kmp = kmp; 00056 entry->timer_running = false; 00057 00058 ns_list_add_to_end(kmp_list, entry); 00059 00060 return entry; 00061 } 00062 00063 int8_t ws_pae_lib_kmp_list_delete(kmp_list_t *kmp_list, kmp_api_t *kmp) 00064 { 00065 kmp_entry_t *entry = ws_pae_lib_kmp_list_entry_get(kmp_list, kmp); 00066 00067 if (entry) { 00068 ns_list_remove(kmp_list, entry); 00069 kmp_api_delete(entry->kmp); 00070 ns_dyn_mem_free(entry); 00071 return 0; 00072 } 00073 00074 return -1; 00075 } 00076 00077 kmp_api_t *ws_pae_lib_kmp_list_type_get(kmp_list_t *kmp_list, kmp_type_e type) 00078 { 00079 kmp_api_t *kmp = NULL; 00080 00081 ns_list_foreach(kmp_entry_t, cur, kmp_list) { 00082 // If kmp type matches 00083 if (kmp_api_type_get(cur->kmp) == type) { 00084 /* If receiving of messages has not been disabled for the kmp (kmp is not 00085 in terminating phase) prioritizes that kmp */ 00086 if (!kmp_api_receive_disable(cur->kmp)) { 00087 return cur->kmp; 00088 } 00089 // Otherwise returns any kmp that matches 00090 kmp = cur->kmp; 00091 } 00092 } 00093 return kmp; 00094 } 00095 00096 kmp_api_t *ws_pae_lib_kmp_list_instance_id_get(kmp_list_t *kmp_list, uint8_t instance_id) 00097 { 00098 ns_list_foreach(kmp_entry_t, cur, kmp_list) { 00099 if (kmp_api_instance_id_get(cur->kmp) == instance_id) { 00100 return cur->kmp; 00101 } 00102 } 00103 00104 return NULL; 00105 } 00106 00107 void ws_pae_lib_kmp_list_free(kmp_list_t *kmp_list) 00108 { 00109 ns_list_foreach_safe(kmp_entry_t, cur, kmp_list) { 00110 kmp_api_delete(cur->kmp); 00111 ns_dyn_mem_free(cur); 00112 } 00113 } 00114 00115 kmp_entry_t *ws_pae_lib_kmp_list_entry_get(kmp_list_t *kmp_list, kmp_api_t *kmp) 00116 { 00117 ns_list_foreach(kmp_entry_t, cur, kmp_list) { 00118 if (cur->kmp == kmp) { 00119 return cur; 00120 } 00121 } 00122 00123 return 0; 00124 } 00125 00126 void ws_pae_lib_kmp_timer_start(kmp_list_t *kmp_list, kmp_entry_t *entry) 00127 { 00128 if (ns_list_get_first(kmp_list) != entry) { 00129 ns_list_remove(kmp_list, entry); 00130 ns_list_add_to_start(kmp_list, entry); 00131 } 00132 entry->timer_running = true; 00133 } 00134 00135 void ws_pae_lib_kmp_timer_stop(kmp_list_t *kmp_list, kmp_entry_t *entry) 00136 { 00137 if (ns_list_get_last(kmp_list) != entry) { 00138 ns_list_remove(kmp_list, entry); 00139 ns_list_add_to_end(kmp_list, entry); 00140 } 00141 entry->timer_running = false; 00142 } 00143 00144 bool ws_pae_lib_kmp_timer_update(kmp_list_t *kmp_list, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout) 00145 { 00146 if (ns_list_is_empty(kmp_list)) { 00147 return false; 00148 } 00149 00150 bool timer_running = false; 00151 00152 ns_list_foreach_safe(kmp_entry_t, entry, kmp_list) { 00153 if (entry->timer_running) { 00154 timeout(entry->kmp, ticks); 00155 timer_running = true; 00156 } else { 00157 break; 00158 } 00159 } 00160 00161 return timer_running; 00162 } 00163 00164 void ws_pae_lib_supp_list_init(supp_list_t *supp_list) 00165 { 00166 ns_list_init(supp_list); 00167 } 00168 00169 supp_entry_t *ws_pae_lib_supp_list_add(supp_list_t *supp_list, const kmp_addr_t *addr) 00170 { 00171 supp_entry_t *entry = ns_dyn_mem_alloc(sizeof(supp_entry_t)); 00172 00173 if (!entry) { 00174 return NULL; 00175 } 00176 00177 ws_pae_lib_supp_init(entry); 00178 memset(&entry->addr, 0, sizeof(kmp_addr_t)); 00179 entry->addr.type = KMP_ADDR_EUI_64_AND_IP; 00180 kmp_address_copy(&entry->addr, addr); 00181 00182 ns_list_add_to_end(supp_list, entry); 00183 00184 return entry; 00185 } 00186 00187 int8_t ws_pae_lib_supp_list_remove(supp_list_t *supp_list, supp_entry_t *supp) 00188 { 00189 ns_list_remove(supp_list, supp); 00190 00191 ws_pae_lib_supp_delete(supp); 00192 00193 ns_dyn_mem_free(supp); 00194 return 0; 00195 } 00196 00197 supp_entry_t *ws_pae_lib_supp_list_entry_eui_64_get(const supp_list_t *supp_list, const uint8_t *eui_64) 00198 { 00199 ns_list_foreach(supp_entry_t, cur, supp_list) { 00200 if (memcmp(cur->addr.eui_64, eui_64, 8) == 0) { 00201 return cur; 00202 } 00203 } 00204 00205 return 0; 00206 } 00207 00208 void ws_pae_lib_supp_list_delete(supp_list_t *supp_list) 00209 { 00210 ns_list_foreach_safe(supp_entry_t, entry, supp_list) { 00211 ws_pae_lib_supp_list_remove(supp_list, entry); 00212 } 00213 } 00214 00215 bool ws_pae_lib_supp_list_timer_update(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout) 00216 { 00217 bool timer_running = false; 00218 00219 ns_list_foreach_safe(supp_entry_t, entry, active_supp_list) { 00220 bool running = ws_pae_lib_supp_timer_update(entry, ticks, timeout); 00221 if (running) { 00222 timer_running = true; 00223 } else { 00224 ws_pae_lib_supp_list_to_inactive(active_supp_list, inactive_supp_list, entry); 00225 } 00226 } 00227 00228 return timer_running; 00229 } 00230 00231 void ws_pae_lib_supp_list_slow_timer_update(supp_list_t *supp_list, timer_settings_t *timer_settings, uint16_t seconds) 00232 { 00233 ns_list_foreach(supp_entry_t, entry, supp_list) { 00234 if (sec_prot_keys_pmk_lifetime_decrement(&entry->sec_keys, timer_settings->pmk_lifetime, seconds)) { 00235 tr_info("PMK and PTK expired, eui-64: %s, system time: %"PRIu32"", trace_array(entry->addr.eui_64, 8), protocol_core_monotonic_time / 10); 00236 } 00237 if (sec_prot_keys_ptk_lifetime_decrement(&entry->sec_keys, timer_settings->ptk_lifetime, seconds)) { 00238 tr_info("PTK expired, eui-64: %s, system time: %"PRIu32"", trace_array(entry->addr.eui_64, 8), protocol_core_monotonic_time / 10); 00239 } 00240 } 00241 00242 } 00243 00244 void ws_pae_lib_supp_init(supp_entry_t *entry) 00245 { 00246 ws_pae_lib_kmp_list_init(&entry->kmp_list); 00247 memset(&entry->addr, 0, sizeof(kmp_addr_t)); 00248 memset(&entry->sec_keys, 0, sizeof(sec_prot_keys_t)); 00249 entry->ticks = 0; 00250 entry->retry_ticks = 0; 00251 entry->active = true; 00252 entry->access_revoked = false; 00253 } 00254 00255 void ws_pae_lib_supp_delete(supp_entry_t *entry) 00256 { 00257 ws_pae_lib_kmp_list_free(&entry->kmp_list); 00258 } 00259 00260 bool ws_pae_lib_supp_timer_update(supp_entry_t *entry, uint16_t ticks, ws_pae_lib_kmp_timer_timeout timeout) 00261 { 00262 // Updates KMP timers and calls timeout callback 00263 bool keep_timer_running = ws_pae_lib_kmp_timer_update(&entry->kmp_list, ticks, timeout); 00264 00265 // If KMPs are not active updates supplicant timer 00266 if (!keep_timer_running) { 00267 if (entry->ticks > ticks) { 00268 keep_timer_running = true; 00269 entry->ticks -= ticks; 00270 } else { 00271 entry->ticks = 0; 00272 entry->retry_ticks = 0; 00273 } 00274 } 00275 00276 // Updates retry timer 00277 if (entry->retry_ticks > ticks) { 00278 entry->retry_ticks -= ticks; 00279 } else { 00280 if (entry->retry_ticks > 0) { 00281 tr_info("EAP-TLS max ongoing delay timeout eui-64: %s", trace_array(entry->addr.eui_64, 8)); 00282 } 00283 entry->retry_ticks = 0; 00284 } 00285 00286 return keep_timer_running; 00287 } 00288 00289 void ws_pae_lib_supp_timer_ticks_set(supp_entry_t *entry, uint32_t ticks) 00290 { 00291 entry->ticks = ticks; 00292 } 00293 00294 void ws_pae_lib_supp_list_to_active(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, supp_entry_t *entry) 00295 { 00296 if (entry->active) { 00297 return; 00298 } 00299 00300 tr_debug("PAE: to active, eui-64: %s", trace_array(entry->addr.eui_64, 8)); 00301 00302 ns_list_remove(inactive_supp_list, entry); 00303 ns_list_add_to_start(active_supp_list, entry); 00304 00305 entry->active = true; 00306 entry->ticks = 0; 00307 00308 // Adds relay address data 00309 entry->addr.type = KMP_ADDR_EUI_64_AND_IP; 00310 } 00311 00312 void ws_pae_lib_supp_list_to_inactive(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, supp_entry_t *entry) 00313 { 00314 if (!entry->active) { 00315 return; 00316 } 00317 00318 tr_debug("PAE: to inactive, eui-64: %s", trace_array(entry->addr.eui_64, 8)); 00319 00320 if (entry->access_revoked) { 00321 tr_info("Access revoked; deleted, eui-64: %s", trace_array(entry->addr.eui_64, 8)); 00322 ws_pae_lib_supp_list_remove(active_supp_list, entry); 00323 return; 00324 } 00325 00326 ns_list_remove(active_supp_list, entry); 00327 ns_list_add_to_start(inactive_supp_list, entry); 00328 00329 entry->active = false; 00330 entry->ticks = 0; 00331 00332 // Removes relay address data 00333 entry->addr.type = KMP_ADDR_EUI_64; 00334 entry->addr.port = 0; 00335 memset(entry->addr.relay_address, 0, 16); 00336 } 00337 00338 void ws_pae_lib_supp_list_purge(supp_list_t *active_supp_list, supp_list_t *inactive_supp_list, uint16_t max_number, uint8_t max_purge) 00339 { 00340 uint16_t active_supp = ns_list_count(active_supp_list); 00341 uint16_t inactive_supp = ns_list_count(inactive_supp_list); 00342 00343 if (active_supp + inactive_supp > max_number) { 00344 uint16_t remove_count = active_supp + inactive_supp - max_number; 00345 if (max_purge > 0 && remove_count > max_purge) { 00346 remove_count = max_purge; 00347 } 00348 00349 // Remove entries from inactive list 00350 ns_list_foreach_safe(supp_entry_t, entry, inactive_supp_list) { 00351 if (remove_count > 0) { 00352 tr_info("Inactive supplicant removed, eui-64: %s", trace_array(kmp_address_eui_64_get(&entry->addr), 8)); 00353 ws_pae_lib_supp_list_remove(inactive_supp_list, entry); 00354 remove_count--; 00355 } else { 00356 break; 00357 } 00358 } 00359 } 00360 } 00361 00362 uint16_t ws_pae_lib_supp_list_kmp_count(supp_list_t *supp_list, kmp_type_e type) 00363 { 00364 uint16_t kmp_count = 0; 00365 00366 ns_list_foreach(supp_entry_t, entry, supp_list) { 00367 ns_list_foreach(kmp_entry_t, kmp_entry, &entry->kmp_list) { 00368 if (kmp_api_type_get(kmp_entry->kmp) == type) { 00369 kmp_count++; 00370 } 00371 } 00372 } 00373 00374 return kmp_count; 00375 } 00376 00377 supp_entry_t *ws_pae_lib_supp_list_entry_retry_timer_get(supp_list_t *supp_list) 00378 { 00379 supp_entry_t *retry_supp = NULL; 00380 00381 ns_list_foreach(supp_entry_t, entry, supp_list) { 00382 // Finds entry with shortest timeout i.e. oldest one 00383 if (entry->retry_ticks > 0) { 00384 if (!retry_supp || retry_supp->retry_ticks > entry->retry_ticks) { 00385 retry_supp = entry; 00386 } 00387 } 00388 } 00389 00390 return retry_supp; 00391 } 00392 00393 #endif /* HAVE_WS */
Generated on Tue Jul 12 2022 13:55:04 by
