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
sec_prot_keys.c
00001 /* 00002 * Copyright (c) 2016-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 "NWK_INTERFACE/Include/protocol.h" 00025 #include "Common_Protocols/ipv6_constants.h" 00026 #include "socket_api.h" 00027 #include "6LoWPAN/ws/ws_config.h" 00028 #include "Security/kmp/kmp_addr.h" 00029 #include "Security/kmp/kmp_api.h" 00030 #include "Security/PANA/pana_eap_header.h" 00031 #include "Security/eapol/eapol_helper.h" 00032 #include "Security/protocols/sec_prot_certs.h" 00033 #include "Security/protocols/sec_prot_keys.h" 00034 #include "Security/protocols/sec_prot.h" 00035 #include "Security/protocols/sec_prot_lib.h" 00036 00037 #ifdef HAVE_WS 00038 00039 #define TRACE_GROUP "spke" 00040 00041 sec_prot_keys_t *sec_prot_keys_create(sec_prot_gtk_keys_t *gtks, const sec_prot_certs_t *certs) 00042 { 00043 sec_prot_keys_t *sec_keys = ns_dyn_mem_alloc(sizeof(sec_prot_keys_t)); 00044 if (!sec_keys) { 00045 return NULL; 00046 } 00047 00048 sec_prot_keys_init(sec_keys, gtks, certs); 00049 00050 return sec_keys; 00051 } 00052 00053 void sec_prot_keys_init(sec_prot_keys_t *sec_keys, sec_prot_gtk_keys_t *gtks, const sec_prot_certs_t *certs) 00054 { 00055 memset(sec_keys, 0, sizeof(sec_prot_keys_t)); 00056 sec_keys->pmk_lifetime = PMK_LIFETIME_INSTALL; 00057 sec_keys->ptk_lifetime = PTK_LIFETIME_INSTALL; 00058 sec_keys->pmk_key_replay_cnt = 0; 00059 sec_keys->gtks = gtks; 00060 sec_keys->certs = certs; 00061 sec_keys->gtkl = 0; 00062 sec_keys->gtk_set_index = -1; 00063 sec_keys->pmk_set = false; 00064 sec_keys->ptk_set = false; 00065 sec_keys->pmk_key_replay_cnt_set = false; 00066 sec_keys->updated = false; 00067 sec_keys->ptk_eui_64_set = false; 00068 sec_keys->pmk_mismatch = false; 00069 sec_keys->ptk_mismatch = false; 00070 } 00071 00072 void sec_prot_keys_delete(sec_prot_keys_t *sec_keys) 00073 { 00074 ns_dyn_mem_free(sec_keys); 00075 } 00076 00077 sec_prot_gtk_keys_t *sec_prot_keys_gtks_create(void) 00078 { 00079 sec_prot_gtk_keys_t *gtks = ns_dyn_mem_alloc(sizeof(sec_prot_gtk_keys_t)); 00080 if (!gtks) { 00081 return NULL; 00082 } 00083 00084 sec_prot_keys_gtks_init(gtks); 00085 00086 return gtks; 00087 } 00088 00089 void sec_prot_keys_gtks_init(sec_prot_gtk_keys_t *gtks) 00090 { 00091 memset(gtks, 0, sizeof(sec_prot_gtk_keys_t)); 00092 gtks->updated = false; 00093 } 00094 00095 void sec_prot_keys_gtks_delete(sec_prot_gtk_keys_t *gtks) 00096 { 00097 ns_dyn_mem_free(gtks); 00098 } 00099 00100 void sec_prot_keys_pmk_write(sec_prot_keys_t *sec_keys, uint8_t *pmk) 00101 { 00102 memcpy(sec_keys->pmk, pmk, PMK_LEN); 00103 sec_keys->pmk_key_replay_cnt = 0; 00104 sec_keys->pmk_key_replay_cnt_set = false; 00105 sec_keys->pmk_lifetime = PMK_LIFETIME_INSTALL; 00106 sec_keys->pmk_set = true; 00107 sec_keys->updated = true; 00108 } 00109 00110 void sec_prot_keys_pmk_delete(sec_prot_keys_t *sec_keys) 00111 { 00112 memset(sec_keys->pmk, 0, PMK_LEN); 00113 sec_keys->pmk_key_replay_cnt = 0; 00114 sec_keys->pmk_key_replay_cnt_set = false; 00115 sec_keys->pmk_lifetime = PMK_LIFETIME_INSTALL; 00116 sec_keys->pmk_set = false; 00117 sec_keys->updated = true; 00118 } 00119 00120 uint8_t *sec_prot_keys_pmk_get(sec_prot_keys_t *sec_keys) 00121 { 00122 if (!sec_keys->pmk_set) { 00123 return NULL; 00124 } 00125 00126 return sec_keys->pmk; 00127 } 00128 00129 uint64_t sec_prot_keys_pmk_replay_cnt_get(sec_prot_keys_t *sec_keys) 00130 { 00131 return sec_keys->pmk_key_replay_cnt; 00132 } 00133 00134 void sec_prot_keys_pmk_replay_cnt_set(sec_prot_keys_t *sec_keys, uint64_t counter) 00135 { 00136 sec_keys->pmk_key_replay_cnt_set = true; 00137 sec_keys->pmk_key_replay_cnt = counter; 00138 } 00139 00140 void sec_prot_keys_pmk_replay_cnt_increment(sec_prot_keys_t *sec_keys) 00141 { 00142 // Start from zero i.e. does not increment on first call 00143 if (!sec_keys->pmk_key_replay_cnt_set) { 00144 sec_keys->pmk_key_replay_cnt_set = true; 00145 return; 00146 } 00147 sec_keys->pmk_key_replay_cnt++; 00148 } 00149 00150 bool sec_prot_keys_pmk_replay_cnt_compare(uint64_t received_counter, sec_prot_keys_t *sec_keys) 00151 { 00152 // If previous value is set must be greater 00153 if (sec_keys->pmk_key_replay_cnt_set && received_counter > sec_keys->pmk_key_replay_cnt) { 00154 return true; 00155 } else if (!sec_keys->pmk_key_replay_cnt_set && received_counter >= sec_keys->pmk_key_replay_cnt) { 00156 // Otherwise allows also same value e.g. zero 00157 return true; 00158 } 00159 00160 return false; 00161 } 00162 00163 void sec_prot_keys_pmk_mismatch_set(sec_prot_keys_t *sec_keys) 00164 { 00165 sec_keys->pmk_mismatch = true; 00166 } 00167 00168 void sec_prot_keys_pmk_mismatch_reset(sec_prot_keys_t *sec_keys) 00169 { 00170 sec_keys->pmk_mismatch = false; 00171 } 00172 00173 bool sec_prot_keys_pmk_mismatch_is_set(sec_prot_keys_t *sec_keys) 00174 { 00175 return sec_keys->pmk_mismatch; 00176 } 00177 00178 bool sec_prot_keys_pmk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t default_lifetime, uint8_t seconds) 00179 { 00180 if (!sec_keys->pmk_set) { 00181 return false; 00182 } 00183 00184 if (sec_keys->pmk_lifetime == PMK_LIFETIME_INSTALL) { 00185 sec_keys->pmk_lifetime = default_lifetime; 00186 } 00187 00188 if (sec_keys->pmk_lifetime > seconds) { 00189 sec_keys->pmk_lifetime -= seconds; 00190 } else { 00191 if (sec_keys->pmk_lifetime > 0) { 00192 sec_keys->pmk_lifetime = 0; 00193 sec_prot_keys_ptk_delete(sec_keys); 00194 sec_prot_keys_pmk_delete(sec_keys); 00195 return true; 00196 } 00197 } 00198 return false; 00199 } 00200 00201 void sec_prot_keys_ptk_write(sec_prot_keys_t *sec_keys, uint8_t *ptk) 00202 { 00203 memcpy(sec_keys->ptk, ptk, PTK_LEN); 00204 sec_keys->ptk_lifetime = PTK_LIFETIME_INSTALL; 00205 sec_keys->ptk_set = true; 00206 sec_keys->updated = true; 00207 } 00208 00209 void sec_prot_keys_ptk_delete(sec_prot_keys_t *sec_keys) 00210 { 00211 memset(sec_keys->ptk, 0, PTK_LEN); 00212 sec_keys->ptk_lifetime = PTK_LIFETIME_INSTALL; 00213 sec_keys->ptk_set = false; 00214 sec_keys->updated = true; 00215 } 00216 00217 uint8_t *sec_prot_keys_ptk_get(sec_prot_keys_t *sec_keys) 00218 { 00219 if (!sec_keys->ptk_set) { 00220 return NULL; 00221 } 00222 00223 return sec_keys->ptk; 00224 } 00225 00226 void sec_prot_keys_ptk_mismatch_set(sec_prot_keys_t *sec_keys) 00227 { 00228 sec_keys->ptk_mismatch = true; 00229 } 00230 00231 void sec_prot_keys_ptk_mismatch_reset(sec_prot_keys_t *sec_keys) 00232 { 00233 sec_keys->ptk_mismatch = false; 00234 } 00235 00236 bool sec_prot_keys_ptk_mismatch_is_set(sec_prot_keys_t *sec_keys) 00237 { 00238 return sec_keys->ptk_mismatch; 00239 } 00240 00241 void sec_prot_keys_ptk_eui_64_write(sec_prot_keys_t *sec_keys, const uint8_t *eui_64) 00242 { 00243 memcpy(sec_keys->ptk_eui_64, eui_64, 8); 00244 sec_keys->ptk_eui_64_set = true; 00245 sec_keys->updated = true; 00246 } 00247 00248 uint8_t *sec_prot_keys_ptk_eui_64_get(sec_prot_keys_t *sec_keys) 00249 { 00250 if (!sec_keys->ptk_eui_64_set) { 00251 return NULL; 00252 } 00253 00254 return sec_keys->ptk_eui_64; 00255 } 00256 00257 void sec_prot_keys_ptk_eui_64_delete(sec_prot_keys_t *sec_keys) 00258 { 00259 memset(sec_keys->ptk_eui_64, 0, 8); 00260 sec_keys->ptk_eui_64_set = false; 00261 sec_keys->updated = true; 00262 } 00263 00264 bool sec_prot_keys_ptk_lifetime_decrement(sec_prot_keys_t *sec_keys, uint32_t default_lifetime, uint8_t seconds) 00265 { 00266 if (!sec_keys->ptk_set) { 00267 return false; 00268 } 00269 00270 if (sec_keys->ptk_lifetime == PTK_LIFETIME_INSTALL) { 00271 sec_keys->ptk_lifetime = default_lifetime; 00272 } 00273 00274 if (sec_keys->ptk_lifetime > seconds) { 00275 sec_keys->ptk_lifetime -= seconds; 00276 } else { 00277 if (sec_keys->ptk_lifetime > 0) { 00278 sec_prot_keys_ptk_delete(sec_keys); 00279 sec_keys->ptk_lifetime = 0; 00280 return true; 00281 } 00282 } 00283 return false; 00284 } 00285 00286 bool sec_prot_keys_are_updated(sec_prot_keys_t *sec_keys) 00287 { 00288 return sec_keys->updated; 00289 } 00290 00291 void sec_prot_keys_updated_reset(sec_prot_keys_t *sec_keys) 00292 { 00293 sec_keys->updated = false; 00294 } 00295 00296 uint8_t sec_prot_keys_fresh_gtkl_get(sec_prot_gtk_keys_t *gtks) 00297 { 00298 uint8_t gtkl = 0; 00299 00300 for (uint8_t i = 0; i < GTK_NUM; i++) { 00301 if (sec_prot_keys_gtk_status_is_live(gtks, i)) { 00302 gtkl |= 1 << i; 00303 } 00304 } 00305 00306 return gtkl; 00307 } 00308 00309 void sec_prot_keys_gtkl_set(sec_prot_keys_t *sec_keys, uint8_t gtkl) 00310 { 00311 sec_keys->gtkl = gtkl; 00312 } 00313 00314 bool sec_prot_keys_gtkl_gtk_is_live(sec_prot_keys_t *sec_keys, uint8_t index) 00315 { 00316 if (index >= GTK_NUM) { 00317 return false; 00318 } 00319 00320 if (sec_keys->gtkl & (1 << index)) { 00321 return true; 00322 } 00323 00324 return false; 00325 } 00326 00327 int8_t sec_prot_keys_gtkl_gtk_live_set(sec_prot_keys_t *sec_keys, uint8_t index) 00328 { 00329 if (index >= GTK_NUM) { 00330 return -1; 00331 } 00332 00333 sec_keys->gtkl |= (1 << index); 00334 00335 return 0; 00336 } 00337 00338 int8_t sec_prot_keys_gtk_insert_index_set(sec_prot_keys_t *sec_keys, uint8_t index) 00339 { 00340 if (index >= GTK_NUM || !sec_keys->gtks->gtk[index].set) { 00341 return -1; 00342 } 00343 00344 sec_keys->gtk_set_index = index; 00345 return 0; 00346 } 00347 00348 int8_t sec_prot_keys_gtk_insert_index_get(sec_prot_keys_t *sec_keys) 00349 { 00350 return sec_keys->gtk_set_index; 00351 } 00352 00353 void sec_prot_keys_gtk_insert_index_clear(sec_prot_keys_t *sec_keys) 00354 { 00355 sec_keys->gtk_set_index = -1; 00356 } 00357 00358 void sec_prot_keys_gtkl_from_gtk_insert_index_set(sec_prot_keys_t *sec_keys) 00359 { 00360 if (sec_keys->gtk_set_index >= 0) { 00361 sec_prot_keys_gtkl_gtk_live_set(sec_keys, sec_keys->gtk_set_index); 00362 sec_prot_keys_gtk_insert_index_clear(sec_keys); 00363 } 00364 } 00365 00366 int8_t sec_prot_keys_gtk_insert_index_from_gtkl_get(sec_prot_keys_t *sec_keys) 00367 { 00368 // Get currently active key index 00369 int8_t active_index = sec_prot_keys_gtk_status_active_get(sec_keys->gtks); 00370 00371 if (active_index >= 0 && !sec_prot_keys_gtkl_gtk_is_live(sec_keys, active_index)) { 00372 // If currently active key is not live on remote, inserts it 00373 sec_prot_keys_gtk_insert_index_set(sec_keys, active_index); 00374 return active_index; 00375 } 00376 00377 // Checks all keys 00378 for (uint8_t i = 0; i < GTK_NUM; i++) { 00379 if (sec_prot_keys_gtk_status_is_live(sec_keys->gtks, i)) { 00380 // If key is live, but not indicated on GTKL inserts it 00381 if (!sec_prot_keys_gtkl_gtk_is_live(sec_keys, i)) { 00382 sec_prot_keys_gtk_insert_index_set(sec_keys, i); 00383 return i; 00384 } 00385 } 00386 } 00387 00388 return -1; 00389 } 00390 00391 uint8_t *sec_prot_keys_get_gtk_to_insert(sec_prot_keys_t *sec_keys, uint8_t *index) 00392 { 00393 if (sec_keys->gtk_set_index >= 0 && sec_keys->gtks->gtk[sec_keys->gtk_set_index].set) { 00394 *index = sec_keys->gtk_set_index; 00395 return sec_keys->gtks->gtk[sec_keys->gtk_set_index].key; 00396 } else { 00397 return NULL; 00398 } 00399 } 00400 00401 int8_t sec_prot_keys_gtk_set(sec_prot_gtk_keys_t *gtks, uint8_t index, uint8_t *gtk, uint32_t lifetime) 00402 { 00403 if (!gtk || index >= GTK_NUM) { 00404 return -1; 00405 } 00406 00407 // If same GTK is given again, do not update 00408 if (gtks->gtk[index].set && memcmp(gtks->gtk[index].key, gtk, GTK_LEN) == 0) { 00409 return -1; 00410 } 00411 00412 sec_prot_keys_gtk_clear(gtks, index); 00413 uint8_t install_order = sec_prot_keys_gtk_install_order_last_get(gtks); 00414 00415 gtks->gtk[index].set = true; 00416 gtks->gtk[index].lifetime = lifetime; 00417 gtks->gtk[index].status = GTK_STATUS_NEW; 00418 gtks->gtk[index].install_order = install_order; 00419 memcpy(gtks->gtk[index].key, gtk, GTK_LEN); 00420 00421 gtks->updated = true; 00422 00423 return 0; 00424 } 00425 00426 int8_t sec_prot_keys_gtk_clear(sec_prot_gtk_keys_t *gtks, uint8_t index) 00427 { 00428 if (!gtks || index >= GTK_NUM) { 00429 return -1; 00430 } 00431 00432 gtks->gtk[index].set = false; 00433 gtks->gtk[index].lifetime = 0; // Should be provided by authenticator 00434 gtks->gtk[index].status = GTK_STATUS_NEW; 00435 memset(gtks->gtk[index].key, 0, GTK_LEN); 00436 00437 sec_prot_keys_gtk_install_order_update(gtks); 00438 00439 return 0; 00440 } 00441 00442 bool sec_prot_keys_gtk_is_set(sec_prot_gtk_keys_t *gtks, uint8_t index) 00443 { 00444 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00445 return false; 00446 } 00447 00448 return true; 00449 } 00450 00451 uint8_t *sec_prot_keys_gtk_get(sec_prot_gtk_keys_t *gtks, uint8_t index) 00452 { 00453 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00454 return NULL; 00455 } 00456 00457 return gtks->gtk[index].key; 00458 } 00459 00460 uint32_t sec_prot_keys_gtk_lifetime_get(sec_prot_gtk_keys_t *gtks, uint8_t index) 00461 { 00462 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00463 return 0; 00464 } 00465 00466 return gtks->gtk[index].lifetime; 00467 } 00468 00469 uint32_t sec_prot_keys_gtk_lifetime_decrement(sec_prot_gtk_keys_t *gtks, uint8_t index, uint16_t seconds) 00470 { 00471 if (gtks->gtk[index].lifetime > seconds) { 00472 gtks->gtk[index].lifetime -= seconds; 00473 } else { 00474 gtks->gtk[index].lifetime = 0; 00475 } 00476 00477 return gtks->gtk[index].lifetime; 00478 } 00479 00480 bool sec_prot_keys_gtks_are_updated(sec_prot_gtk_keys_t *gtks) 00481 { 00482 return gtks->updated; 00483 } 00484 00485 void sec_prot_keys_gtks_updated_set(sec_prot_gtk_keys_t *gtks) 00486 { 00487 gtks->updated = true; 00488 } 00489 00490 void sec_prot_keys_gtks_updated_reset(sec_prot_gtk_keys_t *gtks) 00491 { 00492 gtks->updated = false; 00493 } 00494 00495 void sec_prot_keys_gtk_status_fresh_set(sec_prot_gtk_keys_t *gtks, uint8_t index) 00496 { 00497 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00498 return; 00499 } 00500 00501 // Active key remains as active, old keys are never reused 00502 if (gtks->gtk[index].status < GTK_STATUS_FRESH) { 00503 gtks->gtk[index].status = GTK_STATUS_FRESH; 00504 } 00505 } 00506 00507 void sec_prot_keys_gtk_status_all_fresh_set(sec_prot_gtk_keys_t *gtks) 00508 { 00509 for (uint8_t i = 0; i < GTK_NUM; i++) { 00510 sec_prot_keys_gtk_status_fresh_set(gtks, i); 00511 } 00512 } 00513 00514 int8_t sec_prot_keys_gtk_status_active_set(sec_prot_gtk_keys_t *gtks, uint8_t index) 00515 { 00516 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00517 return -1; 00518 } 00519 00520 // If key is valid to be taken into use sets it active 00521 if (gtks->gtk[index].status == GTK_STATUS_FRESH) { 00522 // Sets previously active key old 00523 for (uint8_t i = 0; i < GTK_NUM; i++) { 00524 // Sets previously active key old 00525 if (gtks->gtk[i].status == GTK_STATUS_ACTIVE) { 00526 gtks->gtk[i].status = GTK_STATUS_OLD; 00527 } 00528 } 00529 gtks->gtk[index].status = GTK_STATUS_ACTIVE; 00530 return 0; 00531 } 00532 00533 return -1; 00534 } 00535 00536 int8_t sec_prot_keys_gtk_status_active_get(sec_prot_gtk_keys_t *gtks) 00537 { 00538 for (uint8_t i = 0; i < GTK_NUM; i++) { 00539 if (gtks->gtk[i].status == GTK_STATUS_ACTIVE) { 00540 return i; 00541 } 00542 } 00543 00544 return -1; 00545 } 00546 00547 bool sec_prot_keys_gtk_status_is_live(sec_prot_gtk_keys_t *gtks, uint8_t index) 00548 { 00549 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00550 return false; 00551 } 00552 00553 if (gtks->gtk[index].status == GTK_STATUS_FRESH || gtks->gtk[index].status == GTK_STATUS_ACTIVE) { 00554 return true; 00555 } 00556 00557 return false; 00558 } 00559 00560 void sec_prot_keys_gtk_status_new_set(sec_prot_gtk_keys_t *gtks, uint8_t index) 00561 { 00562 if (index >= GTK_NUM || !gtks->gtk[index].set) { 00563 return; 00564 } 00565 00566 gtks->gtk[index].status = GTK_STATUS_NEW; 00567 } 00568 00569 void sec_prot_keys_gtks_hash_generate(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash) 00570 { 00571 memset(gtkhash, 0, GTK_ALL_HASHES_LEN); 00572 00573 uint8_t *gtk_hash_ptr = gtkhash; 00574 00575 for (uint8_t i = 0; i < GTK_NUM; i++) { 00576 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00577 uint8_t *gtk = sec_prot_keys_gtk_get(gtks, i); 00578 sec_prot_lib_gtkhash_generate(gtk, gtk_hash_ptr); 00579 } 00580 gtk_hash_ptr += GTK_HASH_LEN; 00581 } 00582 } 00583 00584 void sec_prot_keys_gtk_hash_generate(uint8_t *gtk, uint8_t *gtk_hash) 00585 { 00586 sec_prot_lib_gtkhash_generate(gtk, gtk_hash); 00587 } 00588 00589 gtk_mismatch_e sec_prot_keys_gtks_hash_update(sec_prot_gtk_keys_t *gtks, uint8_t *gtkhash) 00590 { 00591 uint8_t *gtk_hash_ptr = gtkhash; 00592 00593 gtk_mismatch_e mismatch = GTK_NO_MISMATCH; 00594 00595 for (uint8_t i = 0; i < GTK_NUM; i++, gtk_hash_ptr += 8) { 00596 // If hash is not set, stop using the key 00597 if (sec_prot_keys_gtk_hash_empty(gtk_hash_ptr)) { 00598 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00599 uint32_t lifetime = sec_prot_keys_gtk_lifetime_get(gtks, i); 00600 if (lifetime > GTK_EXPIRE_MISMATCH_TIME) { 00601 tr_info("GTK mismatch %i expired time, lifetime: %"PRIu32"", i, lifetime); 00602 if (mismatch < GTK_LIFETIME_MISMATCH) { 00603 mismatch = GTK_LIFETIME_MISMATCH; 00604 } 00605 } 00606 sec_prot_keys_gtk_clear(gtks, i); 00607 } 00608 } else { 00609 // Check is hash matches to existing key 00610 uint8_t gtk_hash[8]; 00611 uint8_t *gtk = sec_prot_keys_gtk_get(gtks, i); 00612 if (!gtk) { 00613 // Hash set but GTK is not known, set mismatch 00614 tr_info("GTK mismatch: %i", i); 00615 if (mismatch < GTK_HASH_MISMATCH) { 00616 mismatch = GTK_HASH_MISMATCH; 00617 } 00618 continue; 00619 } 00620 00621 sec_prot_lib_gtkhash_generate(gtk, gtk_hash); 00622 00623 if (memcmp(gtk_hash, gtk_hash_ptr, 8) == 0) { 00624 // Key is fresh (or active, if old do not change state) 00625 sec_prot_keys_gtk_status_fresh_set(gtks, i); 00626 } else { 00627 // Hash does not match, set mismatch and delete key 00628 tr_info("GTK mismatch: %i", i); 00629 if (mismatch < GTK_HASH_MISMATCH) { 00630 mismatch = GTK_HASH_MISMATCH; 00631 } 00632 sec_prot_keys_gtk_clear(gtks, i); 00633 } 00634 } 00635 } 00636 00637 return mismatch; 00638 } 00639 00640 bool sec_prot_keys_gtk_hash_empty(uint8_t *gtkhash) 00641 { 00642 const uint8_t empty_hash[GTK_HASH_LEN] = {0}; 00643 if (memcmp(gtkhash, empty_hash, GTK_HASH_LEN) == 0) { 00644 return true; 00645 } else { 00646 return false; 00647 } 00648 } 00649 00650 int8_t sec_prot_keys_gtk_install_order_last_get(sec_prot_gtk_keys_t *gtks) 00651 { 00652 int8_t install_order = -1; 00653 00654 // Gets the last key index 00655 for (uint8_t i = 0; i < GTK_NUM; i++) { 00656 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00657 if (gtks->gtk[i].install_order > install_order) { 00658 install_order = gtks->gtk[i].install_order; 00659 } 00660 } 00661 } 00662 00663 return install_order + 1; 00664 } 00665 00666 int8_t sec_prot_keys_gtk_install_order_last_index_get(sec_prot_gtk_keys_t *gtks) 00667 { 00668 int8_t install_order = -1; 00669 int8_t index = -1; 00670 00671 // Gets the last key index 00672 for (uint8_t i = 0; i < GTK_NUM; i++) { 00673 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00674 if (gtks->gtk[i].install_order > install_order) { 00675 install_order = gtks->gtk[i].install_order; 00676 index = i; 00677 } 00678 } 00679 } 00680 00681 return index; 00682 } 00683 00684 uint32_t sec_prot_keys_gtk_install_order_last_lifetime_get(sec_prot_gtk_keys_t *gtks) 00685 { 00686 uint32_t lifetime = 0; 00687 int8_t install_order = -1; 00688 00689 // Gets the last key index 00690 for (uint8_t i = 0; i < GTK_NUM; i++) { 00691 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00692 if (gtks->gtk[i].install_order > install_order) { 00693 install_order = gtks->gtk[i].install_order; 00694 lifetime = gtks->gtk[i].lifetime; 00695 } 00696 } 00697 } 00698 00699 return lifetime; 00700 } 00701 00702 int8_t sec_prot_keys_gtk_install_order_first_index_get(sec_prot_gtk_keys_t *gtks) 00703 { 00704 // Gets the first key index 00705 for (uint8_t i = 0; i < GTK_NUM; i++) { 00706 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00707 if (gtks->gtk[i].install_order == GTK_INSTALL_ORDER_FIRST) { 00708 return i; 00709 } 00710 } 00711 } 00712 00713 return -1; 00714 } 00715 00716 int8_t sec_prot_keys_gtk_install_order_second_index_get(sec_prot_gtk_keys_t *gtks) 00717 { 00718 // Gets the first key index 00719 for (uint8_t i = 0; i < GTK_NUM; i++) { 00720 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00721 if (gtks->gtk[i].install_order == GTK_INSTALL_ORDER_SECOND) { 00722 return i; 00723 } 00724 } 00725 } 00726 00727 return -1; 00728 } 00729 00730 void sec_prot_keys_gtk_install_order_update(sec_prot_gtk_keys_t *gtks) 00731 { 00732 int8_t ordered_indexes[4] = {-1, -1, -1, -1}; 00733 00734 // Creates table of ordered indexes 00735 for (uint8_t i = 0; i < GTK_NUM; i++) { 00736 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00737 ordered_indexes[gtks->gtk[i].install_order] = i; 00738 } 00739 } 00740 00741 // Updates indexes of the GTKs 00742 uint8_t new_install_order = 0; 00743 for (uint8_t i = 0; i < GTK_NUM; i++) { 00744 if (ordered_indexes[i] >= 0) { 00745 gtks->gtk[ordered_indexes[i]].install_order = new_install_order++; 00746 } 00747 } 00748 } 00749 00750 int8_t sec_prot_keys_gtk_install_index_get(sec_prot_gtk_keys_t *gtks) 00751 { 00752 // Gets the index of the last key to be installed 00753 int8_t install_index = sec_prot_keys_gtk_install_order_last_index_get(gtks); 00754 if (install_index < 0) { 00755 install_index = 0; 00756 } 00757 00758 // Checks if there is free index, and available uses that for new GTK 00759 for (uint8_t ctr = 0, i = install_index; ctr < GTK_NUM; ctr++) { 00760 if (!sec_prot_keys_gtk_is_set(gtks, i)) { 00761 install_index = i; 00762 break; 00763 } 00764 i++; 00765 if (i >= GTK_NUM) { 00766 i = 0; 00767 } 00768 } 00769 00770 return install_index; 00771 } 00772 00773 uint8_t sec_prot_keys_gtk_count(sec_prot_gtk_keys_t *gtks) 00774 { 00775 uint8_t count = 0; 00776 00777 for (uint8_t i = 0; i < GTK_NUM; i++) { 00778 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00779 count++; 00780 } 00781 } 00782 00783 return count; 00784 } 00785 00786 #endif /* HAVE_WS */
Generated on Tue Jul 12 2022 13:54:49 by
1.7.2