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
mac_pairwise_key.c
00001 /* 00002 * Copyright (c) 2015-2018, 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 /* 00019 * \file mac_pairwise_key.c 00020 * 00021 */ 00022 #include "nsconfig.h" 00023 #include <string.h> 00024 #include "ns_types.h" 00025 #include "ns_trace.h" 00026 #include "nsdynmemLIB.h" 00027 #include "mac_common_defines.h" 00028 #include "6LoWPAN/MAC/mac_helper.h" 00029 #include "6LoWPAN/MAC/mac_pairwise_key.h" 00030 #include "MLE/mle.h" 00031 #include "NWK_INTERFACE/Include/protocol.h" 00032 #include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h" 00033 00034 #define TRACE_GROUP "mPKe" 00035 00036 typedef struct mac_pairwise_key_entry { 00037 uint8_t eui64[8]; /*!< eui64 which is key source */ 00038 uint8_t pairwiseKey[16]; /*!< Paiwise key */ 00039 uint32_t frameCounterRX; 00040 ns_list_link_t link; /*!< List link entry */ 00041 } mac_pairwise_key_entry_t; 00042 00043 typedef struct mac_pairwise_key_info { 00044 uint8_t device_descriptor_attribute; 00045 uint8_t key_decriptor_attribute; 00046 } mac_pairwise_key_info_t; 00047 00048 typedef NS_LIST_HEAD (mac_pairwise_key_entry_t, link) mac_pairwise_key_list_t; 00049 00050 typedef struct mac_pairwise_interface_entry { 00051 int8_t interfaceId; 00052 mac_pairwise_key_info_t *mac_pairwise_key_table; 00053 uint8_t key_table_size; 00054 uint8_t key_list_size; 00055 uint8_t network_key_offset; 00056 ns_list_link_t link; /*!< List link entry */ 00057 } mac_pairwise_interface_entry_t; 00058 00059 static NS_LIST_DEFINE(mac_pairwise_info, mac_pairwise_interface_entry_t, link); 00060 00061 00062 static mac_pairwise_interface_entry_t *mac_pairwise_key_list_allocate(uint8_t list_size) 00063 { 00064 mac_pairwise_interface_entry_t *newEntry = ns_dyn_mem_alloc(sizeof(mac_pairwise_interface_entry_t)); 00065 00066 mac_pairwise_key_info_t *key_table = ns_dyn_mem_alloc(sizeof(mac_pairwise_key_info_t) * list_size); 00067 if (!newEntry || !key_table) { 00068 ns_dyn_mem_free(newEntry); 00069 ns_dyn_mem_free(key_table); 00070 return NULL; 00071 } 00072 memset(newEntry, 0, sizeof(mac_pairwise_interface_entry_t)); 00073 memset(key_table, 0, sizeof(mac_pairwise_key_info_t) * list_size); 00074 newEntry->mac_pairwise_key_table = key_table; 00075 newEntry->key_list_size = list_size; 00076 return newEntry; 00077 } 00078 00079 static bool mac_pairwise_key_deacriptro_attribute_get(mac_pairwise_interface_entry_t *main_list, uint8_t key_attribute) 00080 { 00081 mac_pairwise_key_info_t *key_table = main_list->mac_pairwise_key_table; 00082 for (uint8_t i = 0; i < main_list->key_table_size; i++) { 00083 if (key_table->key_decriptor_attribute == key_attribute) { 00084 return false; 00085 } 00086 key_table++; 00087 } 00088 00089 return true; 00090 } 00091 00092 mac_pairwise_key_info_t *mac_pairwise_key_info_get(mac_pairwise_interface_entry_t *main_list, uint8_t device_id) 00093 { 00094 mac_pairwise_key_info_t *key_table = main_list->mac_pairwise_key_table; 00095 for (uint8_t i = 0; i < main_list->key_table_size; i++) { 00096 if (key_table->device_descriptor_attribute == device_id) { 00097 return key_table; 00098 } 00099 key_table++; 00100 } 00101 00102 if (main_list->key_table_size == main_list->key_list_size) { 00103 return NULL; 00104 } 00105 00106 00107 bool unique_id = false; 00108 mac_pairwise_key_info_t *new_entry = main_list->mac_pairwise_key_table + main_list->key_table_size; 00109 new_entry->device_descriptor_attribute = device_id; 00110 new_entry->key_decriptor_attribute = main_list->network_key_offset; 00111 //Allocate key id 00112 while (!unique_id) { 00113 unique_id = mac_pairwise_key_deacriptro_attribute_get(main_list, new_entry->key_decriptor_attribute); 00114 if (!unique_id) { 00115 new_entry->key_decriptor_attribute++; 00116 } 00117 } 00118 00119 main_list->key_table_size++; 00120 return new_entry; 00121 } 00122 00123 static bool mac_pairwise_key_info_delete(mac_pairwise_interface_entry_t *main_list, uint8_t device_id, uint8_t *key_attribute) 00124 { 00125 bool removed_entry = false; 00126 00127 mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table; 00128 mac_pairwise_key_info_t *prev = NULL; 00129 for (uint8_t i = 0; i < main_list->key_table_size; i++) { 00130 if (removed_entry) { 00131 *prev = *cur; 00132 } else { 00133 if (cur->device_descriptor_attribute == device_id) { 00134 removed_entry = true; 00135 *key_attribute = cur->key_decriptor_attribute; 00136 } 00137 } 00138 prev = cur; 00139 cur++; 00140 } 00141 if (removed_entry) { 00142 main_list->key_table_size--; 00143 } 00144 00145 return removed_entry; 00146 } 00147 00148 00149 static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class_discover(int8_t interfaceId) 00150 { 00151 00152 ns_list_foreach(mac_pairwise_interface_entry_t, cur, &mac_pairwise_info) { 00153 if (interfaceId == cur->interfaceId) { 00154 return cur; 00155 } 00156 } 00157 00158 return NULL; 00159 } 00160 00161 00162 static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class(uint8_t key_list_size) 00163 { 00164 00165 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_list_allocate(key_list_size); 00166 if (!main_list) { 00167 return NULL; 00168 } 00169 tr_debug("Set new Key main Class"); 00170 ns_list_add_to_end(&mac_pairwise_info, main_list); 00171 00172 return main_list; 00173 } 00174 00175 00176 static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) 00177 { 00178 //Delete mle entries & Keys 00179 mac_neighbor_table_entry_t *cur_entry; 00180 mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table; 00181 for (uint8_t i = 0; i < main_list->key_table_size; i++) { 00182 cur_entry = mac_neighbor_table_attribute_discover(mac_neighbor_info(interface), cur->device_descriptor_attribute); 00183 if (cur_entry) { 00184 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), cur_entry); 00185 } 00186 mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute); 00187 } 00188 main_list->key_table_size = 0; 00189 } 00190 00191 int mac_pairwise_key_interface_register(int8_t interface_id, uint8_t mac_supported_key_decription_size, uint8_t network_key_size) 00192 { 00193 if (!mac_supported_key_decription_size || !network_key_size) { 00194 return -2; 00195 } 00196 00197 if (mac_supported_key_decription_size < network_key_size) { 00198 return -2; 00199 } 00200 00201 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00202 if (!interface) { 00203 return -1; 00204 } 00205 00206 if (mac_pairwise_key_main_class_discover(interface_id)) { 00207 return -2; 00208 } 00209 00210 uint8_t pairwise_key_list_size; 00211 uint8_t network_key_offset; 00212 00213 if (mac_supported_key_decription_size == network_key_size) { 00214 pairwise_key_list_size = 1; 00215 network_key_offset = 0; 00216 } else { 00217 pairwise_key_list_size = (mac_supported_key_decription_size - network_key_size); 00218 network_key_offset = network_key_size; 00219 } 00220 00221 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class(pairwise_key_list_size); 00222 if (!main_list) { 00223 return -1; 00224 } 00225 00226 main_list->interfaceId = interface_id; 00227 main_list->network_key_offset = network_key_offset; 00228 00229 return 0; 00230 00231 } 00232 00233 int mac_pairwise_key_interface_unregister(int8_t interface_id) 00234 { 00235 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00236 if (!interface) { 00237 return -1; 00238 } 00239 00240 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id); 00241 if (!main_list) { 00242 return -1; 00243 } 00244 00245 mac_pairwise_key_list_free(interface, main_list); 00246 00247 //Can delete Main Class also 00248 ns_list_remove(&mac_pairwise_info, main_list); 00249 ns_dyn_mem_free(main_list->mac_pairwise_key_table); 00250 ns_dyn_mem_free(main_list); 00251 return 0; 00252 00253 } 00254 00255 00256 00257 int mac_pairwise_key_add(int8_t interface_id, uint32_t valid_life_time, const uint8_t eui64[static 8], const uint8_t key[static 16]) 00258 { 00259 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00260 bool new_entry_created; 00261 00262 if (!interface || !interface->mac_api) { 00263 return -1; 00264 } 00265 00266 (void)valid_life_time; 00267 tr_debug("Pairwise_key addr %s, key %s", trace_array(eui64, 8), trace_array(key, 16)); 00268 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id); 00269 if (!main_list) { 00270 return -1; 00271 } 00272 00273 //Allocate mle entry 00274 mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, &new_entry_created); 00275 if (!mac_entry) { 00276 return -1; 00277 } 00278 00279 mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), mac_entry, true); 00280 mac_entry->mac16 = 0xffff; 00281 00282 //Allocate key description 00283 00284 mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mac_entry->index ); 00285 00286 if (!key_desc) { 00287 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); 00288 return -1; 00289 } 00290 00291 mlme_device_descriptor_t device_desc; 00292 mac_helper_device_description_write(interface, &device_desc, mac_entry->mac64 , mac_entry->mac16 , 0, false); 00293 mac_helper_devicetable_set(&device_desc, interface, mac_entry->index , interface->mac_parameters->mac_default_key_index, new_entry_created); 00294 00295 //set key descriptor 00296 if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) { 00297 main_list->key_table_size--; 00298 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); 00299 return -1; 00300 } 00301 00302 return 0; 00303 } 00304 00305 int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8]) 00306 { 00307 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00308 if (!interface || !interface->mac_api) { 00309 return -1; 00310 } 00311 00312 mac_pairwise_interface_entry_t *main_list; 00313 tr_debug("Pairwise_key delete %s", trace_array(eui64, 8)); 00314 main_list = mac_pairwise_key_main_class_discover(interface_id); 00315 if (!main_list) { 00316 return -1; 00317 } 00318 //Get from mac 00319 mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, NULL); 00320 if (!mac_entry) { 00321 return -1; 00322 } 00323 00324 //discover by mle entry attribute 00325 uint8_t key_attribute; 00326 00327 if (!mac_pairwise_key_info_delete(main_list, mac_entry->index , &key_attribute)) { 00328 return -1; 00329 } 00330 00331 //kill Entry & overwrite key 00332 mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute); 00333 00334 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); 00335 00336 return 0; 00337 } 00338 00339 00340 int mac_pairwise_key_flush_list(int8_t interface_id) 00341 { 00342 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00343 if (!interface) { 00344 return -1; 00345 } 00346 00347 tr_debug("Pairwise_key flush"); 00348 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id); 00349 if (!main_list) { 00350 return -1; 00351 } 00352 00353 mac_pairwise_key_list_free(interface, main_list); 00354 00355 return 0; 00356 } 00357 00358
Generated on Tue Jul 12 2022 13:54:31 by
