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_supp.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 <randLIB.h> 00021 #include "ns_types.h" 00022 #include "ns_list.h" 00023 #include "ns_trace.h" 00024 #include "nsdynmemLIB.h" 00025 #include "fhss_config.h " 00026 #include "eventOS_event.h" 00027 #include "eventOS_scheduler.h" 00028 #include "eventOS_event_timer.h" 00029 #include "ns_address.h" 00030 #include "NWK_INTERFACE/Include/protocol.h" 00031 #include "RPL/rpl_protocol.h" 00032 #include "RPL/rpl_control.h" 00033 #include "RPL/rpl_data.h" 00034 #include "6LoWPAN/ws/ws_config.h" 00035 #include "Security/kmp/kmp_addr.h" 00036 #include "Security/kmp/kmp_api.h" 00037 #include "Security/protocols/sec_prot_certs.h" 00038 #include "Security/protocols/sec_prot_keys.h" 00039 #include "Security/protocols/key_sec_prot/key_sec_prot.h" 00040 #include "Security/protocols/eap_tls_sec_prot/supp_eap_tls_sec_prot.h" 00041 #include "Security/protocols/tls_sec_prot/tls_sec_prot.h" 00042 #include "Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.h" 00043 #include "Security/protocols/gkh_sec_prot/supp_gkh_sec_prot.h" 00044 #include "6LoWPAN/ws/ws_pae_controller.h" 00045 #include "6LoWPAN/ws/ws_pae_timers.h" 00046 #include "6LoWPAN/ws/ws_pae_supp.h" 00047 #include "6LoWPAN/ws/ws_pae_lib.h" 00048 #include "6LoWPAN/ws/ws_pae_nvm_store.h" 00049 #include "6LoWPAN/ws/ws_pae_nvm_data.h" 00050 #include "6LoWPAN/MAC/mpx_api.h" 00051 #include "6LoWPAN/ws/ws_eapol_pdu.h" 00052 #include "Security/kmp/kmp_eapol_pdu_if.h" 00053 00054 #ifdef HAVE_WS 00055 #ifdef HAVE_PAE_SUPP 00056 00057 #define TRACE_GROUP "wsps" 00058 00059 #define PAE_TASKLET_INIT 1 00060 #define PAE_TASKLET_EVENT 2 00061 #define PAE_TASKLET_TIMER 3 00062 00063 // Wait for for authenticator to continue with authentication (e.g. after EAP-TLS to initiate 4WH) 00064 #define WAIT_FOR_AUTHENTICATION_TICKS 30 * 10 // 30 seconds 00065 00066 // Wait for re-authentication after GTK update 00067 #define WAIT_FOR_REAUTHENTICATION_TICKS 120 * 10 // 120 seconds 00068 00069 // How many times in maximum stored keys are used for authentication 00070 #define STORED_KEYS_MAXIMUM_USE_COUNT 1 00071 00072 // Delay for sending the initial EAPOL-Key 00073 #define INITIAL_KEY_TIMER_MIN 3 00074 #define INITIAL_KEY_TIMER_MAX 30 00075 00076 typedef struct { 00077 char network_name[33]; /**< Network name for keys */ 00078 sec_prot_gtk_keys_t *gtks; /**< Link to GTKs */ 00079 uint16_t new_pan_id; /**< new PAN ID indicated by bootstrap */ 00080 uint16_t key_pan_id; /**< PAN ID for keys */ 00081 bool updated : 1; /**< Network info has been updated */ 00082 } sec_prot_keys_nw_info_t; 00083 00084 typedef struct { 00085 ns_list_link_t link; /**< Link */ 00086 kmp_service_t *kmp_service; /**< KMP service */ 00087 protocol_interface_info_entry_t *interface_ptr; /**< Interface */ 00088 ws_pae_supp_auth_completed *auth_completed; /**< Authentication completed callback, continue bootstrap */ 00089 ws_pae_supp_nw_key_insert *nw_key_insert; /**< Key insert callback */ 00090 ws_pae_supp_nw_key_index_set *nw_key_index_set; /**< Key index set callback */ 00091 supp_entry_t entry; /**< Supplicant data */ 00092 kmp_addr_t target_addr; /**< EAPOL target (parent) address */ 00093 uint16_t initial_key_timer; /**< Timer to trigger initial EAPOL-Key */ 00094 trickle_t auth_trickle_timer; /**< Trickle timer for re-sending initial EAPOL-key or for GTK mismatch */ 00095 trickle_params_t auth_trickle_params; /**< Trickle parameters for initial EAPOL-key or for GTK mismatch */ 00096 sec_prot_gtk_keys_t gtks; /**< GTKs */ 00097 uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap */ 00098 sec_prot_keys_nw_info_t sec_keys_nw_info; /**< Security keys network information */ 00099 timer_settings_t *timer_settings; /**< Timer settings */ 00100 uint8_t nw_keys_used_cnt; /**< How many times bootstrap has been tried with current keys */ 00101 bool auth_trickle_running : 1; /**< Initial EAPOL-Key Trickle timer running */ 00102 bool auth_requested : 1; /**< Authentication has been requested by the bootstrap */ 00103 bool timer_running : 1; /**< Timer is running */ 00104 bool new_br_eui_64_set : 1; /**< Border router address has been set */ 00105 bool new_br_eui_64_fresh : 1; /**< Border router address is fresh (set during this authentication attempt) */ 00106 bool entry_address_active: 1; 00107 } pae_supp_t; 00108 00109 00110 #define TRICKLE_IMIN_180_SECS 180 00111 00112 static trickle_params_t initial_eapol_key_trickle_params = { 00113 .Imin = TRICKLE_IMIN_180_SECS, /* 180 second; ticks are 1 second */ 00114 .Imax = TRICKLE_IMIN_180_SECS << 1, /* 360 second */ 00115 .k = 0, /* infinity - no consistency checking */ 00116 .TimerExpirations = 3 00117 }; 00118 00119 static void ws_pae_supp_free(pae_supp_t *pae_supp); 00120 static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result); 00121 static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp); 00122 static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp); 00123 static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id); 00124 static int8_t ws_pae_supp_nvm_nw_info_write(pae_supp_t *pae_supp); 00125 static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp); 00126 static pae_supp_t *ws_pae_supp_get(protocol_interface_info_entry_t *interface_ptr); 00127 static int8_t ws_pae_supp_event_send(kmp_service_t *service, void *data); 00128 static void ws_pae_supp_tasklet_handler(arm_event_s *event); 00129 static int8_t ws_pae_supp_timer_if_start(kmp_service_t *service, kmp_api_t *kmp); 00130 static int8_t ws_pae_supp_timer_if_stop(kmp_service_t *service, kmp_api_t *kmp); 00131 static int8_t ws_pae_supp_timer_start(pae_supp_t *pae_supp); 00132 static int8_t ws_pae_supp_timer_stop(pae_supp_t *pae_supp); 00133 static bool ws_pae_supp_timer_running(pae_supp_t *pae_supp); 00134 static void ws_pae_supp_kmp_service_addr_get(kmp_service_t *service, kmp_api_t *kmp, kmp_addr_t *local_addr, kmp_addr_t *remote_addr); 00135 static kmp_api_t *ws_pae_supp_kmp_service_api_get(kmp_service_t *service, kmp_api_t *kmp, kmp_type_e type); 00136 static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_e type, const kmp_addr_t *addr); 00137 static kmp_api_t *ws_pae_supp_kmp_tx_status_ind(kmp_service_t *service, uint8_t instance_id); 00138 static kmp_api_t *ws_pae_supp_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, pae_supp_t *pae_supp); 00139 static int8_t ws_pae_supp_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64); 00140 static int8_t ws_pae_supp_parent_eui_64_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64); 00141 00142 static void ws_pae_supp_kmp_api_create_confirm(kmp_api_t *kmp, kmp_result_e result); 00143 static void ws_pae_supp_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e type, kmp_addr_t *addr); 00144 static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys); 00145 static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp); 00146 00147 00148 static const eapol_pdu_recv_cb_data_t eapol_pdu_recv_cb_data = { 00149 .priority = EAPOL_PDU_RECV_HIGH_PRIORITY, 00150 .addr_check = ws_pae_supp_eapol_pdu_address_check, 00151 .receive = kmp_eapol_pdu_if_receive 00152 }; 00153 00154 static const char *NW_INFO_FILE = NW_INFO_FILE_NAME; 00155 static const char *KEYS_FILE = KEYS_FILE_NAME; 00156 00157 static int8_t tasklet_id = -1; 00158 static NS_LIST_DEFINE(pae_supp_list, pae_supp_t, link); 00159 00160 static void ws_pae_supp_address_set(pae_supp_t *pae_supp, kmp_addr_t *address) 00161 { 00162 if (address) { 00163 // Sets target address in use 00164 pae_supp->entry.addr = *address; 00165 pae_supp->entry_address_active = true; 00166 } else { 00167 pae_supp->entry_address_active = false; 00168 } 00169 } 00170 00171 static bool ws_pae_supp_address_is_set(pae_supp_t *pae_supp) 00172 { 00173 return pae_supp->entry_address_active; 00174 } 00175 00176 int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64) 00177 { 00178 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00179 if (!pae_supp) { 00180 return -1; 00181 } 00182 00183 if (ws_pae_supp_nw_keys_valid_check(pae_supp, dest_pan_id) >= 0) { 00184 pae_supp->auth_completed(interface_ptr, AUTH_RESULT_OK, NULL); 00185 return 0; 00186 } 00187 00188 // Delete GTKs 00189 sec_prot_keys_gtks_init(pae_supp->sec_keys_nw_info.gtks); 00190 00191 /* PAN ID has changed, delete key data associated with border router 00192 i.e PMK, PTK, EA-IE data (border router EUI-64) */ 00193 if (pae_supp->sec_keys_nw_info.key_pan_id != 0xFFFF && pae_supp->sec_keys_nw_info.key_pan_id != dest_pan_id) { 00194 sec_prot_keys_pmk_delete(&pae_supp->entry.sec_keys); 00195 sec_prot_keys_ptk_delete(&pae_supp->entry.sec_keys); 00196 sec_prot_keys_ptk_eui_64_delete(&pae_supp->entry.sec_keys); 00197 } 00198 00199 pae_supp->sec_keys_nw_info.key_pan_id = dest_pan_id; 00200 00201 // Prepare to receive new border router address 00202 pae_supp->new_br_eui_64_fresh = false; 00203 00204 // Stores target/parent address 00205 kmp_address_init(KMP_ADDR_EUI_64, &pae_supp->target_addr, dest_eui_64); 00206 // Sets target address in use 00207 ws_pae_supp_address_set(pae_supp, &pae_supp->target_addr); 00208 00209 pae_supp->auth_requested = true; 00210 00211 // Randomizes the sending of initial EAPOL-Key messsage 00212 pae_supp->initial_key_timer = randLIB_get_random_in_range(INITIAL_KEY_TIMER_MIN, INITIAL_KEY_TIMER_MAX); 00213 00214 // Starts supplicant timer 00215 ws_pae_supp_timer_start(pae_supp); 00216 00217 tr_debug("PAE active, timer %i", pae_supp->initial_key_timer); 00218 00219 return 1; 00220 } 00221 00222 int8_t ws_pae_supp_nw_info_set(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name) 00223 { 00224 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00225 if (!pae_supp) { 00226 return -1; 00227 } 00228 00229 // PAN ID has been modified 00230 if (pan_id != 0xffff && pan_id != pae_supp->sec_keys_nw_info.new_pan_id) { 00231 pae_supp->sec_keys_nw_info.new_pan_id = pan_id; 00232 pae_supp->sec_keys_nw_info.updated = true; 00233 } 00234 00235 // Network name has been modified 00236 if (network_name && strncmp(pae_supp->sec_keys_nw_info.network_name, network_name, 33) != 0) { 00237 strncpy(pae_supp->sec_keys_nw_info.network_name, network_name, 32); 00238 pae_supp->sec_keys_nw_info.updated = true; 00239 } 00240 00241 00242 return 0; 00243 } 00244 00245 int8_t ws_pae_supp_border_router_addr_write(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64) 00246 { 00247 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00248 if (!pae_supp) { 00249 return -1; 00250 } 00251 00252 memcpy(pae_supp->new_br_eui_64, eui_64, 8); 00253 pae_supp->new_br_eui_64_set = true; 00254 pae_supp->new_br_eui_64_fresh = true; 00255 00256 return 0; 00257 } 00258 00259 int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64) 00260 { 00261 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00262 if (!pae_supp) { 00263 return -1; 00264 } 00265 00266 uint8_t *br_eui_64 = sec_prot_keys_ptk_eui_64_get(&pae_supp->entry.sec_keys); 00267 if (!br_eui_64) { 00268 return -1; 00269 } 00270 00271 memcpy(eui_64, br_eui_64, 8); 00272 00273 return 0; 00274 } 00275 00276 int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr) 00277 { 00278 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00279 if (!pae_supp) { 00280 return -1; 00281 } 00282 00283 tr_info("NW key valid"); 00284 00285 // Stored keys are valid 00286 pae_supp->nw_keys_used_cnt = 0; 00287 00288 // Update NVM if data has been changed 00289 ws_pae_supp_nvm_update(pae_supp); 00290 00291 return 0; 00292 } 00293 00294 int8_t ws_pae_supp_gtk_hash_update(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash) 00295 { 00296 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00297 if (!pae_supp) { 00298 return -1; 00299 } 00300 00301 // Check GTK hashes and initiate EAPOL procedure if mismatch is detected */ 00302 gtk_mismatch_e mismatch = sec_prot_keys_gtks_hash_update(&pae_supp->gtks, gtkhash); 00303 if (mismatch > GTK_NO_MISMATCH) { 00304 tr_info("GTK hash update %s %s %s %s", 00305 trace_array(>khash[0], 8), 00306 trace_array(>khash[8], 8), 00307 trace_array(>khash[16], 8), 00308 trace_array(>khash[24], 8)); 00309 00310 // Mismatch, initiate EAPOL 00311 if (!pae_supp->auth_trickle_running) { 00312 uint8_t timer_expirations = 3; 00313 // For GTK lifetime mismatch send only once 00314 if (mismatch == GTK_LIFETIME_MISMATCH) { 00315 timer_expirations = 1; 00316 } 00317 00318 pae_supp->auth_trickle_params.Imin = pae_supp->timer_settings->gtk_request_imin; 00319 pae_supp->auth_trickle_params.Imax = pae_supp->timer_settings->gtk_request_imax; 00320 pae_supp->auth_trickle_params.k = 0; 00321 pae_supp->auth_trickle_params.TimerExpirations = timer_expirations; 00322 00323 // Starts trickle 00324 trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); 00325 pae_supp->auth_trickle_running = true; 00326 00327 // Starts supplicant timer 00328 ws_pae_supp_timer_start(pae_supp); 00329 00330 tr_info("GTK update start imin: %i, imax: %i, max mismatch: %i, tr time: %i", pae_supp->timer_settings->gtk_request_imin, pae_supp->timer_settings->gtk_request_imax, pae_supp->timer_settings->gtk_max_mismatch, pae_supp->auth_trickle_timer.t); 00331 } else { 00332 // If trickle is already running, set inconsistent heard to speed up the trickle 00333 trickle_inconsistent_heard(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); 00334 } 00335 } 00336 00337 // Modify keys 00338 pae_supp->nw_key_insert(pae_supp->interface_ptr, pae_supp->sec_keys_nw_info.gtks); 00339 00340 return 0; 00341 } 00342 00343 int8_t ws_pae_supp_nw_key_index_update(protocol_interface_info_entry_t *interface_ptr, uint8_t index) 00344 { 00345 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00346 if (!pae_supp) { 00347 return -1; 00348 } 00349 00350 if (sec_prot_keys_gtk_status_active_set(&pae_supp->gtks, index) >= 0) { 00351 pae_supp->nw_key_index_set(interface_ptr, index); 00352 } else { 00353 tr_info("NW send key index: %i, no changes", index + 1); 00354 } 00355 00356 return 0; 00357 } 00358 00359 int8_t ws_pae_supp_gtks_set(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks) 00360 { 00361 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00362 if (!pae_supp) { 00363 return -1; 00364 } 00365 00366 pae_supp->gtks = *gtks; 00367 00368 return 0; 00369 } 00370 00371 int8_t ws_pae_supp_eapol_target_remove(protocol_interface_info_entry_t *interface_ptr) 00372 { 00373 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00374 if (!pae_supp) { 00375 return -1; 00376 } 00377 00378 // Sets target/parent address to null 00379 ws_pae_supp_address_set(pae_supp, NULL); 00380 00381 return 0; 00382 } 00383 00384 static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp) 00385 { 00386 // Check if NW info or GTKs have been changed 00387 if (pae_supp->sec_keys_nw_info.updated || sec_prot_keys_gtks_are_updated(pae_supp->sec_keys_nw_info.gtks)) { 00388 ws_pae_supp_nvm_nw_info_write(pae_supp); 00389 pae_supp->sec_keys_nw_info.updated = false; 00390 sec_prot_keys_gtks_updated_reset(pae_supp->sec_keys_nw_info.gtks); 00391 } 00392 00393 // Check if pairwise security keys have been changed 00394 if (sec_prot_keys_are_updated(&pae_supp->entry.sec_keys)) { 00395 ws_pae_supp_nvm_keys_write(pae_supp); 00396 sec_prot_keys_updated_reset(&pae_supp->entry.sec_keys); 00397 } 00398 } 00399 00400 static int8_t ws_pae_supp_nvm_nw_info_write(pae_supp_t *pae_supp) 00401 { 00402 nvm_tlv_entry_t *tlv_entry = ws_pae_controller_nvm_tlv_get(pae_supp->interface_ptr); 00403 if (!tlv_entry) { 00404 return -1; 00405 } 00406 00407 nvm_tlv_list_t tlv_list; 00408 ns_list_init(&tlv_list); 00409 00410 ws_pae_nvm_store_nw_info_tlv_create(tlv_entry, pae_supp->sec_keys_nw_info.key_pan_id, 00411 pae_supp->sec_keys_nw_info.network_name, 00412 &pae_supp->gtks); 00413 ns_list_add_to_end(&tlv_list, tlv_entry); 00414 00415 ws_pae_nvm_store_tlv_file_write(NW_INFO_FILE, &tlv_list); 00416 00417 return 0; 00418 } 00419 00420 static int8_t ws_pae_supp_nvm_nw_info_read(pae_supp_t *pae_supp) 00421 { 00422 nvm_tlv_list_t tlv_list; 00423 ns_list_init(&tlv_list); 00424 00425 ws_pae_nvm_store_tlv_file_read(NW_INFO_FILE, &tlv_list); 00426 00427 ns_list_foreach_safe(nvm_tlv_entry_t, entry, &tlv_list) { 00428 ws_pae_nvm_store_nw_info_tlv_read(entry, &pae_supp->sec_keys_nw_info.key_pan_id, 00429 pae_supp->sec_keys_nw_info.network_name, 00430 &pae_supp->gtks); 00431 ns_list_remove(&tlv_list, entry); 00432 ns_dyn_mem_free(entry); 00433 } 00434 00435 return 0; 00436 } 00437 00438 static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp) 00439 { 00440 nvm_tlv_entry_t *tlv_entry = ws_pae_controller_nvm_tlv_get(pae_supp->interface_ptr); 00441 if (!tlv_entry) { 00442 return -1; 00443 } 00444 00445 nvm_tlv_list_t tlv_list; 00446 ns_list_init(&tlv_list); 00447 00448 ws_pae_nvm_store_keys_tlv_create(tlv_entry, &pae_supp->entry.sec_keys); 00449 ns_list_add_to_end(&tlv_list, tlv_entry); 00450 00451 ws_pae_nvm_store_tlv_file_write(KEYS_FILE, &tlv_list); 00452 00453 return 0; 00454 } 00455 00456 static int8_t ws_pae_supp_nvm_keys_read(pae_supp_t *pae_supp) 00457 { 00458 nvm_tlv_list_t tlv_list; 00459 ns_list_init(&tlv_list); 00460 00461 ws_pae_nvm_store_tlv_file_read(KEYS_FILE, &tlv_list); 00462 00463 ns_list_foreach_safe(nvm_tlv_entry_t, entry, &tlv_list) { 00464 ws_pae_nvm_store_keys_tlv_read(entry, &pae_supp->entry.sec_keys); 00465 ns_list_remove(&tlv_list, entry); 00466 ns_dyn_mem_free(entry); 00467 } 00468 00469 return 0; 00470 } 00471 00472 static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result) 00473 { 00474 pae_supp->auth_trickle_running = false; 00475 if (pae_supp->auth_requested && pae_supp->auth_completed) { 00476 pae_supp->auth_requested = false; 00477 uint8_t *target_eui_64 = NULL; 00478 if (result != AUTH_RESULT_OK) { 00479 target_eui_64 = pae_supp->target_addr.eui_64; 00480 } 00481 pae_supp->auth_completed(pae_supp->interface_ptr, result, target_eui_64); 00482 } 00483 } 00484 00485 static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp) 00486 { 00487 if (!pae_supp->auth_requested) { 00488 // If not making initial authentication updates target (RPL parent) for each EAPOL-key message 00489 uint8_t parent_eui_64[8]; 00490 if (ws_pae_supp_parent_eui_64_get(pae_supp->interface_ptr, parent_eui_64) >= 0) { 00491 // Stores target/parent address 00492 kmp_address_init(KMP_ADDR_EUI_64, &pae_supp->target_addr, parent_eui_64); 00493 // Sets parent address in use 00494 ws_pae_supp_address_set(pae_supp, &pae_supp->target_addr); 00495 } else if (ws_pae_supp_address_is_set(pae_supp)) { 00496 /* If there is no RPL parent but there is target address from initial authentication 00497 bootstrap, tries to use it. This can happen if BR updates keys after EAPOL authentication 00498 but before bootstrap is completed and RPL parent is known */ 00499 tr_info("EAPOL initial auth target used"); 00500 } else { 00501 // No target, failure 00502 return -1; 00503 } 00504 00505 ws_pae_lib_supp_timer_ticks_set(&pae_supp->entry, WAIT_FOR_REAUTHENTICATION_TICKS); 00506 tr_info("PAE wait for auth seconds: %i", WAIT_FOR_REAUTHENTICATION_TICKS / 10); 00507 } 00508 00509 kmp_api_t *kmp = ws_pae_supp_kmp_create_and_start(pae_supp->kmp_service, IEEE_802_1X_MKA_KEY, pae_supp); 00510 if (!kmp) { 00511 return -1; 00512 } 00513 00514 tr_info("EAPOL target: %s", trace_array(kmp_address_eui_64_get(&pae_supp->entry.addr), 8)); 00515 00516 kmp_api_create_request(kmp, IEEE_802_1X_MKA_KEY, &pae_supp->entry.addr, &pae_supp->entry.sec_keys); 00517 00518 return 0; 00519 } 00520 00521 static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id) 00522 { 00523 // Checks how many times authentication has been tried with current network keys 00524 if (pae_supp->nw_keys_used_cnt >= STORED_KEYS_MAXIMUM_USE_COUNT) { 00525 tr_debug("Keys not valid, delete GTKs"); 00526 00527 // Delete GTKs 00528 sec_prot_keys_gtks_init(pae_supp->sec_keys_nw_info.gtks); 00529 sec_prot_keys_gtks_updated_set(pae_supp->sec_keys_nw_info.gtks); 00530 ws_pae_supp_nvm_update(pae_supp); 00531 00532 pae_supp->nw_keys_used_cnt = 0; 00533 return -1; 00534 } 00535 00536 /* Checks if keys match to PAN ID and that needed keys exists (PMK, PTK and a GTK), 00537 and calls inserts function that will update the network keys as needed */ 00538 if ((pan_id == pae_supp->sec_keys_nw_info.key_pan_id) && 00539 (sec_prot_keys_gtk_count(pae_supp->sec_keys_nw_info.gtks) > 0) && 00540 (sec_prot_keys_pmk_get(&pae_supp->entry.sec_keys) != NULL) && 00541 (sec_prot_keys_ptk_get(&pae_supp->entry.sec_keys) != NULL)) { 00542 tr_debug("Existing keys used, counter %i", pae_supp->nw_keys_used_cnt); 00543 if (pae_supp->nw_key_insert(pae_supp->interface_ptr, pae_supp->sec_keys_nw_info.gtks) >= 0) { 00544 tr_debug("Keys inserted"); 00545 } 00546 pae_supp->nw_keys_used_cnt++; 00547 return 0; 00548 } else { 00549 pae_supp->nw_keys_used_cnt = 0; 00550 return -1; 00551 } 00552 } 00553 00554 static void ws_pae_supp_keys_nw_info_init(sec_prot_keys_nw_info_t *sec_keys_nw_info, sec_prot_gtk_keys_t *gtks) 00555 { 00556 if (!sec_keys_nw_info) { 00557 return; 00558 } 00559 00560 memset(sec_keys_nw_info, 0, sizeof(sec_prot_keys_nw_info_t)); 00561 00562 sec_keys_nw_info->gtks = gtks; 00563 sec_keys_nw_info->new_pan_id = 0xFFFF; 00564 sec_keys_nw_info->key_pan_id = 0xFFFF; 00565 sec_keys_nw_info->updated = false; 00566 } 00567 00568 void ws_pae_supp_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_supp_auth_completed *completed, ws_pae_supp_nw_key_insert *nw_key_insert, ws_pae_supp_nw_key_index_set *nw_key_index_set) 00569 { 00570 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00571 if (!pae_supp) { 00572 return; 00573 } 00574 00575 pae_supp->auth_completed = completed; 00576 pae_supp->nw_key_insert = nw_key_insert; 00577 pae_supp->nw_key_index_set = nw_key_index_set; 00578 } 00579 00580 int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const sec_prot_certs_t *certs, timer_settings_t *timer_settings) 00581 { 00582 if (!interface_ptr) { 00583 return -1; 00584 } 00585 00586 if (ws_pae_supp_get(interface_ptr) != NULL) { 00587 return 0; 00588 } 00589 00590 pae_supp_t *pae_supp = ns_dyn_mem_alloc(sizeof(pae_supp_t)); 00591 if (!pae_supp) { 00592 return -1; 00593 } 00594 00595 pae_supp->interface_ptr = interface_ptr; 00596 pae_supp->auth_completed = NULL; 00597 pae_supp->nw_key_insert = NULL; 00598 pae_supp->nw_key_index_set = NULL; 00599 pae_supp->initial_key_timer = 0; 00600 pae_supp->nw_keys_used_cnt = 0; 00601 pae_supp->timer_settings = timer_settings; 00602 pae_supp->auth_trickle_running = false; 00603 pae_supp->auth_requested = false; 00604 pae_supp->timer_running = false; 00605 pae_supp->new_br_eui_64_set = false; 00606 pae_supp->new_br_eui_64_fresh = false; 00607 pae_supp->entry_address_active = false; 00608 00609 ws_pae_lib_supp_init(&pae_supp->entry); 00610 00611 ws_pae_supp_keys_nw_info_init(&pae_supp->sec_keys_nw_info, &pae_supp->gtks); 00612 00613 kmp_address_init(KMP_ADDR_EUI_64, &pae_supp->target_addr, 0); 00614 00615 sec_prot_keys_gtks_init(&pae_supp->gtks); 00616 sec_prot_keys_init(&pae_supp->entry.sec_keys, &pae_supp->gtks, certs); 00617 memset(pae_supp->new_br_eui_64, 0, 8); 00618 00619 pae_supp->kmp_service = kmp_service_create(); 00620 if (!pae_supp->kmp_service) { 00621 goto error; 00622 } 00623 00624 if (kmp_service_cb_register(pae_supp->kmp_service, ws_pae_supp_kmp_incoming_ind, ws_pae_supp_kmp_tx_status_ind, ws_pae_supp_kmp_service_addr_get, ws_pae_supp_kmp_service_api_get) < 0) { 00625 goto error; 00626 } 00627 00628 if (kmp_service_event_if_register(pae_supp->kmp_service, ws_pae_supp_event_send)) { 00629 goto error; 00630 } 00631 00632 if (kmp_service_timer_if_register(pae_supp->kmp_service, ws_pae_supp_timer_if_start, ws_pae_supp_timer_if_stop)) { 00633 goto error; 00634 } 00635 00636 if (kmp_eapol_pdu_if_register(pae_supp->kmp_service, interface_ptr) < 0) { 00637 goto error; 00638 } 00639 00640 if (ws_eapol_pdu_cb_register(interface_ptr, &eapol_pdu_recv_cb_data) < 0) { 00641 goto error; 00642 } 00643 00644 if (supp_key_sec_prot_register(pae_supp->kmp_service) < 0) { 00645 goto error; 00646 } 00647 00648 if (supp_eap_tls_sec_prot_register(pae_supp->kmp_service) < 0) { 00649 goto error; 00650 } 00651 00652 if (client_tls_sec_prot_register(pae_supp->kmp_service) < 0) { 00653 goto error; 00654 } 00655 00656 if (supp_fwh_sec_prot_register(pae_supp->kmp_service) < 0) { 00657 goto error; 00658 } 00659 00660 if (supp_gkh_sec_prot_register(pae_supp->kmp_service) < 0) { 00661 goto error; 00662 } 00663 00664 if (tasklet_id < 0) { 00665 tasklet_id = eventOS_event_handler_create(ws_pae_supp_tasklet_handler, PAE_TASKLET_INIT); 00666 if (tasklet_id < 0) { 00667 goto error; 00668 } 00669 } 00670 00671 if (ws_pae_supp_timer_stop(pae_supp) < 0) { 00672 goto error; 00673 } 00674 00675 ws_pae_supp_nvm_nw_info_read(pae_supp); 00676 ws_pae_supp_nvm_keys_read(pae_supp); 00677 00678 ns_list_add_to_end(&pae_supp_list, pae_supp); 00679 00680 return 0; 00681 00682 error: 00683 ws_pae_supp_free(pae_supp); 00684 00685 return -1; 00686 } 00687 00688 int8_t ws_pae_supp_delete(protocol_interface_info_entry_t *interface_ptr) 00689 { 00690 if (!interface_ptr) { 00691 return -1; 00692 } 00693 00694 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00695 if (!pae_supp) { 00696 return -1; 00697 } 00698 00699 ws_pae_supp_free(pae_supp); 00700 return 0; 00701 } 00702 00703 int8_t ws_pae_supp_timing_adjust(uint8_t timing) 00704 { 00705 supp_fwh_sec_prot_timing_adjust(timing); 00706 supp_eap_sec_prot_timing_adjust(timing); 00707 return 0; 00708 } 00709 00710 static void ws_pae_supp_free(pae_supp_t *pae_supp) 00711 { 00712 if (!pae_supp) { 00713 return; 00714 } 00715 00716 ws_pae_lib_supp_delete(&pae_supp->entry); 00717 00718 kmp_eapol_pdu_if_unregister(pae_supp->kmp_service); 00719 00720 ws_eapol_pdu_cb_unregister(pae_supp->interface_ptr, &eapol_pdu_recv_cb_data); 00721 00722 kmp_service_delete(pae_supp->kmp_service); 00723 00724 ns_list_remove(&pae_supp_list, pae_supp); 00725 ns_dyn_mem_free(pae_supp); 00726 } 00727 00728 static pae_supp_t *ws_pae_supp_get(protocol_interface_info_entry_t *interface_ptr) 00729 { 00730 ns_list_foreach(pae_supp_t, entry, &pae_supp_list) { 00731 if (entry->interface_ptr == interface_ptr) { 00732 return entry; 00733 } 00734 } 00735 00736 return NULL; 00737 } 00738 00739 static pae_supp_t *ws_pae_supp_by_kmp_service_get(kmp_service_t *service) 00740 { 00741 ns_list_foreach(pae_supp_t, entry, &pae_supp_list) { 00742 if (entry->kmp_service == service) { 00743 return entry; 00744 } 00745 } 00746 00747 return NULL; 00748 } 00749 00750 static int8_t ws_pae_supp_event_send(kmp_service_t *service, void *data) 00751 { 00752 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 00753 if (!pae_supp) { 00754 return -1; 00755 } 00756 00757 arm_event_s event = { 00758 .receiver = tasklet_id, 00759 .sender = 0, 00760 .event_id = pae_supp->interface_ptr->id, 00761 .data_ptr = data, 00762 .event_type = PAE_TASKLET_EVENT, 00763 .priority = ARM_LIB_LOW_PRIORITY_EVENT, 00764 }; 00765 00766 if (eventOS_event_send(&event) != 0) { 00767 return -1; 00768 } 00769 00770 return 0; 00771 } 00772 00773 static void ws_pae_supp_tasklet_handler(arm_event_s *event) 00774 { 00775 if (event->event_type == PAE_TASKLET_INIT) { 00776 00777 } else if (event->event_type == PAE_TASKLET_EVENT) { 00778 pae_supp_t *pae_supp = NULL; 00779 00780 ns_list_foreach(pae_supp_t, entry, &pae_supp_list) { 00781 if (entry->interface_ptr->id == event->event_id) { 00782 pae_supp = entry; 00783 break; 00784 } 00785 } 00786 00787 if (pae_supp) { 00788 kmp_service_event_if_event(pae_supp->kmp_service, event->data_ptr); 00789 } 00790 } 00791 } 00792 00793 void ws_pae_supp_fast_timer(uint16_t ticks) 00794 { 00795 ns_list_foreach(pae_supp_t, pae_supp, &pae_supp_list) { 00796 if (!ws_pae_supp_timer_running(pae_supp)) { 00797 continue; 00798 } 00799 00800 // Updates KMP timers and supplicant authentication ongoing timer 00801 bool running = ws_pae_lib_supp_timer_update(&pae_supp->entry, ticks, kmp_service_timer_if_timeout); 00802 00803 // Checks whether timer needs to be active 00804 if (!pae_supp->initial_key_timer && !pae_supp->auth_trickle_running && !running) { 00805 tr_debug("PAE idle"); 00806 // If not already completed, restart bootstrap 00807 ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_UNSPEC); 00808 00809 ws_pae_supp_timer_stop(pae_supp); 00810 } 00811 } 00812 } 00813 00814 void ws_pae_supp_slow_timer(uint16_t seconds) 00815 { 00816 ns_list_foreach(pae_supp_t, pae_supp, &pae_supp_list) { 00817 00818 // Checks whether initial EAPOL-Key message needs to be re-send or new GTK request to be sent 00819 if (pae_supp->auth_trickle_running) { 00820 if (trickle_timer(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params, seconds)) { 00821 if (ws_pae_supp_initial_key_send(pae_supp) < 0) { 00822 tr_info("EAPOL-Key send failed"); 00823 } 00824 } 00825 // Maximum number of trickle expires, authentication fails 00826 if (!trickle_running(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params)) { 00827 ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_UNSPEC); 00828 } 00829 } 00830 00831 // Decrements GTK lifetimes 00832 for (uint8_t i = 0; i < GTK_NUM; i++) { 00833 if (!sec_prot_keys_gtk_is_set(&pae_supp->gtks, i)) { 00834 continue; 00835 } 00836 sec_prot_keys_gtk_lifetime_decrement(&pae_supp->gtks, i, seconds); 00837 } 00838 00839 if (pae_supp->initial_key_timer > 0) { 00840 if (pae_supp->initial_key_timer > seconds) { 00841 pae_supp->initial_key_timer -= seconds; 00842 } else { 00843 pae_supp->initial_key_timer = 0; 00844 00845 // Sends initial EAPOL-Key message 00846 if (ws_pae_supp_initial_key_send(pae_supp) < 0) { 00847 tr_info("EAPOL-Key send failed"); 00848 } 00849 00850 // Starts trickle 00851 pae_supp->auth_trickle_params = initial_eapol_key_trickle_params; 00852 trickle_start(&pae_supp->auth_trickle_timer, &pae_supp->auth_trickle_params); 00853 pae_supp->auth_trickle_running = true; 00854 } 00855 } 00856 } 00857 } 00858 00859 static int8_t ws_pae_supp_timer_if_start(kmp_service_t *service, kmp_api_t *kmp) 00860 { 00861 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 00862 if (!pae_supp) { 00863 return -1; 00864 } 00865 00866 if (ws_pae_supp_timer_start(pae_supp) < 0) { 00867 return -1; 00868 } 00869 00870 kmp_entry_t *entry = kmp_api_data_get(kmp); 00871 if (!entry) { 00872 return -1; 00873 } 00874 ws_pae_lib_kmp_timer_start(&pae_supp->entry.kmp_list, entry); 00875 return 0; 00876 } 00877 00878 static int8_t ws_pae_supp_timer_if_stop(kmp_service_t *service, kmp_api_t *kmp) 00879 { 00880 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 00881 if (!pae_supp) { 00882 return -1; 00883 } 00884 00885 kmp_entry_t *entry = kmp_api_data_get(kmp); 00886 if (!entry) { 00887 return -1; 00888 } 00889 ws_pae_lib_kmp_timer_stop(&pae_supp->entry.kmp_list, entry); 00890 return 0; 00891 } 00892 00893 static int8_t ws_pae_supp_timer_start(pae_supp_t *pae_supp) 00894 { 00895 pae_supp->timer_running = true; 00896 return 0; 00897 } 00898 00899 static int8_t ws_pae_supp_timer_stop(pae_supp_t *pae_supp) 00900 { 00901 pae_supp->timer_running = false; 00902 return 0; 00903 } 00904 00905 static bool ws_pae_supp_timer_running(pae_supp_t *pae_supp) 00906 { 00907 return pae_supp->timer_running; 00908 } 00909 00910 static int8_t ws_pae_supp_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64) 00911 { 00912 pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); 00913 if (!pae_supp) { 00914 return -1; 00915 } 00916 00917 // Message from EAPOL target node, route to self 00918 if (pae_supp->entry_address_active) { 00919 if (memcmp(eui_64, pae_supp->entry.addr.eui_64, 8) == 0) { 00920 return 0; 00921 } 00922 } 00923 00924 // Get parent 00925 uint8_t parent_eui_64[8]; 00926 if (ws_pae_supp_parent_eui_64_get(interface_ptr, parent_eui_64) < 0) { 00927 return -1; 00928 } 00929 00930 // Message from RPL parent, route to self 00931 if (memcmp(parent_eui_64, eui_64, 8) == 0) { 00932 return 0; 00933 } 00934 00935 return -1; 00936 } 00937 00938 static int8_t ws_pae_supp_parent_eui_64_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64) 00939 { 00940 rpl_dodag_info_t dodag_info; 00941 if (!interface_ptr->rpl_domain) { 00942 return -1; 00943 } 00944 struct rpl_instance *instance = rpl_control_enumerate_instances(interface_ptr->rpl_domain, NULL); 00945 if (instance && rpl_control_read_dodag_info(instance, &dodag_info)) { 00946 // Get parent 00947 const uint8_t *parent_ll_addr = rpl_control_preferred_parent_addr(instance, false); 00948 if (parent_ll_addr) { 00949 memcpy(eui_64, &parent_ll_addr[8], 8); 00950 eui_64[0] |= 0x02; 00951 return 0; 00952 } 00953 } 00954 00955 return -1; 00956 } 00957 00958 static void ws_pae_supp_kmp_service_addr_get(kmp_service_t *service, kmp_api_t *kmp, kmp_addr_t *local_addr, kmp_addr_t *remote_addr) 00959 { 00960 (void) kmp; 00961 00962 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 00963 if (!pae_supp) { 00964 return; 00965 } 00966 00967 // Get own EUI-64 00968 link_layer_address_s mac_params; 00969 if (arm_nwk_mac_address_read(pae_supp->interface_ptr->id, &mac_params) >= 0) { 00970 kmp_address_eui_64_set(local_addr, mac_params.mac_long); 00971 } 00972 00973 // BR address has been received during authentication attempt 00974 if (pae_supp->new_br_eui_64_fresh) { 00975 kmp_address_eui_64_set(remote_addr, pae_supp->new_br_eui_64); 00976 } else { 00977 uint8_t *eui_64 = sec_prot_keys_ptk_eui_64_get(&pae_supp->entry.sec_keys); 00978 // BR address is set on security keys (confirmed using 4WH) 00979 if (eui_64) { 00980 kmp_address_eui_64_set(remote_addr, eui_64); 00981 } else { 00982 // For initial EAPOL key, if BR address has been received during previous attempt, generate PMKID using it 00983 if (pae_supp->new_br_eui_64_set && kmp_api_type_get(kmp) >= IEEE_802_1X_INITIAL_KEY) { 00984 kmp_address_eui_64_set(remote_addr, pae_supp->new_br_eui_64); 00985 } else { 00986 memset(remote_addr, 0, sizeof(kmp_addr_t)); 00987 tr_error("No border router EUI-64"); 00988 } 00989 } 00990 } 00991 } 00992 00993 static kmp_api_t *ws_pae_supp_kmp_service_api_get(kmp_service_t *service, kmp_api_t *kmp, kmp_type_e type) 00994 { 00995 (void) kmp; 00996 00997 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 00998 if (!pae_supp) { 00999 return NULL; 01000 } 01001 01002 return ws_pae_lib_kmp_list_type_get(&pae_supp->entry.kmp_list, type); 01003 } 01004 01005 static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_e type, const kmp_addr_t *addr) 01006 { 01007 // Should be MKA, 4WH or GKH and never initial EAPOL-key for supplicant 01008 if (type > IEEE_802_1X_INITIAL_KEY) { 01009 return NULL; 01010 } 01011 01012 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 01013 if (!pae_supp) { 01014 return NULL; 01015 } 01016 01017 if (!pae_supp->entry_address_active) { 01018 // Does no longer wait for authentication, ignores message 01019 return NULL; 01020 } 01021 01022 // No longer runs trickle timer for re-sending initial EAPOL-key 01023 pae_supp->auth_trickle_running = false; 01024 01025 // Updates parent address 01026 kmp_address_copy(&pae_supp->entry.addr, addr); 01027 01028 // Check if ongoing 01029 kmp_api_t *kmp = ws_pae_lib_kmp_list_type_get(&pae_supp->entry.kmp_list, type); 01030 /* If kmp receiving is enabled or it is not GKH, routes message to existing KMP. 01031 01032 For GKH creates an instance to handle message. If message is not valid (e.g. repeated 01033 message counter), GKH ignores message and waits for timeout. All further messages 01034 are routed to that instance. If valid message arrives, GKH instance handles the 01035 message, replies to authenticator and terminates. */ 01036 if (kmp && (!kmp_api_receive_disable(kmp) || type != IEEE_802_11_GKH)) { 01037 return kmp; 01038 } 01039 01040 // Create new instance 01041 kmp = ws_pae_supp_kmp_create_and_start(service, type, pae_supp); 01042 01043 // For EAP-TLS create also TLS in addition to EAP-TLS 01044 if (type == IEEE_802_1X_MKA) { 01045 if (ws_pae_lib_kmp_list_type_get(&pae_supp->entry.kmp_list, TLS_PROT) != NULL) { 01046 // TLS already exists, wait for it to be deleted 01047 ws_pae_lib_kmp_list_delete(&pae_supp->entry.kmp_list, kmp); 01048 return NULL; 01049 } 01050 // Create TLS instance */ 01051 if (ws_pae_supp_kmp_create_and_start(service, TLS_PROT, pae_supp) == NULL) { 01052 ws_pae_lib_kmp_list_delete(&pae_supp->entry.kmp_list, kmp); 01053 return NULL; 01054 } 01055 } 01056 01057 return kmp; 01058 } 01059 01060 static kmp_api_t *ws_pae_supp_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, pae_supp_t *pae_supp) 01061 { 01062 // Create new instance 01063 kmp_api_t *kmp = kmp_api_create(service, type); 01064 if (!kmp) { 01065 return NULL; 01066 } 01067 01068 // Updates parent address 01069 kmp_api_addr_set(kmp, &pae_supp->entry.addr); 01070 01071 // Sets security keys to KMP 01072 kmp_api_sec_keys_set(kmp, &pae_supp->entry.sec_keys); 01073 01074 kmp_api_cb_register( 01075 kmp, ws_pae_supp_kmp_api_create_confirm, 01076 ws_pae_supp_kmp_api_create_indication, 01077 ws_pae_supp_kmp_api_finished_indication, 01078 ws_pae_supp_kmp_api_finished); 01079 01080 kmp_entry_t *kmp_entry = ws_pae_lib_kmp_list_add(&pae_supp->entry.kmp_list, kmp); 01081 if (!kmp_entry) { 01082 kmp_api_delete(kmp); 01083 return NULL; 01084 } 01085 01086 kmp_api_data_set(kmp, kmp_entry); 01087 01088 if (kmp_api_start(kmp) < 0) { 01089 ws_pae_lib_kmp_list_delete(&pae_supp->entry.kmp_list, kmp); 01090 return NULL; 01091 } 01092 01093 return kmp; 01094 } 01095 01096 static void ws_pae_supp_kmp_api_create_confirm(kmp_api_t *kmp, kmp_result_e result) 01097 { 01098 kmp_service_t *service = kmp_api_service_get(kmp); 01099 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 01100 if (!pae_supp) { 01101 return; 01102 } 01103 01104 // KMP-CREATE.request has failed, authentication error 01105 if (result != KMP_RESULT_OK) { 01106 ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_UNSPEC); 01107 } 01108 } 01109 01110 static void ws_pae_supp_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e type, kmp_addr_t *addr) 01111 { 01112 (void) addr; 01113 (void) type; 01114 01115 // For now, accept every KMP-CREATE.indication 01116 kmp_api_create_response(kmp, KMP_RESULT_OK); 01117 } 01118 01119 static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys) 01120 { 01121 kmp_service_t *service = kmp_api_service_get(kmp); 01122 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 01123 if (!pae_supp) { 01124 return; 01125 } 01126 01127 kmp_type_e type = kmp_api_type_get(kmp); 01128 01129 // Whenever EAP-TLS, 4WH or GKH completes increase timer for wait for authentication 01130 if (type < IEEE_802_1X_INITIAL_KEY && result == KMP_RESULT_OK) { 01131 ws_pae_lib_supp_timer_ticks_set(&pae_supp->entry, WAIT_FOR_AUTHENTICATION_TICKS); 01132 } 01133 01134 /* When 4WH or GKH completes inserts keys and indicates authentication completed 01135 (if not alredy indicated) */ 01136 if ((type == IEEE_802_11_4WH || type == IEEE_802_11_GKH) && result == KMP_RESULT_OK) { 01137 if (sec_keys) { 01138 sec_prot_keys_t *keys = sec_keys; 01139 pae_supp->nw_key_insert(pae_supp->interface_ptr, keys->gtks); 01140 } 01141 01142 ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_OK); 01143 } 01144 01145 /* If initial EAPOL-key message sending fails to tx no acknowledge, indicates failure so 01146 that bootstrap can decide if EAPOL target should be changed */ 01147 else if (type > IEEE_802_1X_INITIAL_KEY && result == KMP_RESULT_ERR_TX_NO_ACK) { 01148 tr_info("Initial EAPOL-Key TX failure, target: %s", trace_array(kmp_address_eui_64_get(&pae_supp->entry.addr), 8)); 01149 ws_pae_supp_authenticate_response(pae_supp, AUTH_RESULT_ERR_TX_NO_ACK); 01150 } 01151 01152 } 01153 01154 static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp) 01155 { 01156 kmp_service_t *service = kmp_api_service_get(kmp); 01157 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 01158 if (!pae_supp) { 01159 return; 01160 } 01161 01162 // Delete KMP 01163 ws_pae_lib_kmp_list_delete(&pae_supp->entry.kmp_list, kmp); 01164 } 01165 01166 static kmp_api_t *ws_pae_supp_kmp_tx_status_ind(kmp_service_t *service, uint8_t instance_id) 01167 { 01168 pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service); 01169 if (!pae_supp) { 01170 return NULL; 01171 } 01172 01173 kmp_api_t *kmp = ws_pae_lib_kmp_list_instance_id_get(&pae_supp->entry.kmp_list, instance_id); 01174 if (!kmp) { 01175 return NULL; 01176 } 01177 01178 return kmp; 01179 } 01180 01181 #endif /* HAVE_PAE_SUPP */ 01182 #endif /* HAVE_WS */ 01183
Generated on Tue Jul 12 2022 13:55:04 by
