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.
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 mac_pairwise_key_info_t *key_table = main_list->mac_pairwise_key_table; 00081 for (uint8_t i = 0; i<main_list->key_table_size; i++) { 00082 if (key_table->key_decriptor_attribute == key_attribute) { 00083 return false; 00084 } 00085 key_table++; 00086 } 00087 00088 return true; 00089 } 00090 00091 mac_pairwise_key_info_t *mac_pairwise_key_info_get(mac_pairwise_interface_entry_t *main_list, uint8_t device_id) { 00092 mac_pairwise_key_info_t *key_table = main_list->mac_pairwise_key_table; 00093 for (uint8_t i = 0; i<main_list->key_table_size; i++) { 00094 if (key_table->device_descriptor_attribute == device_id) { 00095 return key_table; 00096 } 00097 key_table++; 00098 } 00099 00100 if (main_list->key_table_size == main_list->key_list_size ) { 00101 return NULL; 00102 } 00103 00104 00105 bool unique_id = false; 00106 mac_pairwise_key_info_t *new_entry = main_list->mac_pairwise_key_table + main_list->key_table_size; 00107 new_entry->device_descriptor_attribute = device_id; 00108 new_entry->key_decriptor_attribute = main_list->network_key_offset; 00109 //Allocate key id 00110 while(!unique_id) { 00111 unique_id = mac_pairwise_key_deacriptro_attribute_get(main_list, new_entry->key_decriptor_attribute); 00112 if (!unique_id) { 00113 new_entry->key_decriptor_attribute++; 00114 } 00115 } 00116 00117 main_list->key_table_size++; 00118 return new_entry; 00119 } 00120 00121 static bool mac_pairwise_key_info_delete(mac_pairwise_interface_entry_t *main_list, uint8_t device_id, uint8_t *key_attribute) { 00122 bool removed_entry = false; 00123 00124 mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table; 00125 mac_pairwise_key_info_t *prev = NULL; 00126 for (uint8_t i = 0; i<main_list->key_table_size; i++) { 00127 if (removed_entry) { 00128 *prev = *cur; 00129 } else { 00130 if (cur->device_descriptor_attribute == device_id) { 00131 removed_entry = true; 00132 *key_attribute = cur->key_decriptor_attribute; 00133 } 00134 } 00135 prev = cur; 00136 cur++; 00137 } 00138 if (removed_entry) { 00139 main_list->key_table_size--; 00140 } 00141 00142 return removed_entry; 00143 } 00144 00145 00146 static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class_discover(int8_t interfaceId) 00147 { 00148 00149 ns_list_foreach(mac_pairwise_interface_entry_t, cur, &mac_pairwise_info) { 00150 if (interfaceId == cur->interfaceId) { 00151 return cur; 00152 } 00153 } 00154 00155 return NULL; 00156 } 00157 00158 00159 static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class(uint8_t key_list_size) 00160 { 00161 00162 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_list_allocate(key_list_size); 00163 if (!main_list) { 00164 return NULL; 00165 } 00166 tr_debug("Set new Key main Class"); 00167 ns_list_add_to_end(&mac_pairwise_info, main_list); 00168 00169 return main_list; 00170 } 00171 00172 00173 static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) { 00174 //Delete mle entries & Keys 00175 mac_neighbor_table_entry_t *cur_entry; 00176 mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table; 00177 for (uint8_t i = 0; i< main_list->key_table_size; i++) { 00178 cur_entry = mac_neighbor_table_attribute_discover(mac_neighbor_info(interface), cur->device_descriptor_attribute); 00179 if (cur_entry) { 00180 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), cur_entry); 00181 } 00182 mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute); 00183 } 00184 main_list->key_table_size = 0; 00185 } 00186 00187 int mac_pairwise_key_interface_register(int8_t interface_id, uint8_t mac_supported_key_decription_size, uint8_t network_key_size) 00188 { 00189 if (!mac_supported_key_decription_size || !network_key_size ) { 00190 return -2; 00191 } 00192 00193 if (mac_supported_key_decription_size < network_key_size) { 00194 return -2; 00195 } 00196 00197 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00198 if (!interface) { 00199 return -1; 00200 } 00201 00202 if (mac_pairwise_key_main_class_discover(interface_id)) { 00203 return -2; 00204 } 00205 00206 uint8_t pairwise_key_list_size; 00207 uint8_t network_key_offset; 00208 00209 if (mac_supported_key_decription_size == network_key_size) { 00210 pairwise_key_list_size = 1; 00211 network_key_offset = 0; 00212 } else { 00213 pairwise_key_list_size = (mac_supported_key_decription_size - network_key_size); 00214 network_key_offset = network_key_size; 00215 } 00216 00217 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class(pairwise_key_list_size); 00218 if (!main_list) { 00219 return -1; 00220 } 00221 00222 main_list->interfaceId = interface_id; 00223 main_list->network_key_offset = network_key_offset; 00224 00225 return 0; 00226 00227 } 00228 00229 int mac_pairwise_key_interface_unregister(int8_t interface_id) 00230 { 00231 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00232 if (!interface) { 00233 return -1; 00234 } 00235 00236 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id); 00237 if (!main_list) { 00238 return -1; 00239 } 00240 00241 mac_pairwise_key_list_free(interface, main_list); 00242 00243 //Can delete Main Class also 00244 ns_list_remove(&mac_pairwise_info, main_list); 00245 ns_dyn_mem_free(main_list->mac_pairwise_key_table); 00246 ns_dyn_mem_free(main_list); 00247 return 0; 00248 00249 } 00250 00251 00252 00253 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]) 00254 { 00255 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00256 bool new_entry_created; 00257 00258 if (!interface || !interface->mac_api) { 00259 return -1; 00260 } 00261 00262 (void)valid_life_time; 00263 tr_debug("Pairwise_key addr %s, key %s", trace_array(eui64, 8), trace_array(key, 16)); 00264 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id); 00265 if (!main_list) { 00266 return -1; 00267 } 00268 00269 //Allocate mle entry 00270 mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, &new_entry_created); 00271 if (!mac_entry) { 00272 return -1; 00273 } 00274 00275 mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), mac_entry, true); 00276 mac_entry->mac16 = 0xffff; 00277 00278 //Allocate key description 00279 00280 mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mac_entry->index ); 00281 00282 if (!key_desc) { 00283 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); 00284 return -1; 00285 } 00286 00287 mlme_device_descriptor_t device_desc; 00288 mac_helper_device_description_write(interface, &device_desc, mac_entry->mac64 , mac_entry->mac16 ,0, false); 00289 mac_helper_devicetable_set(&device_desc, interface,mac_entry->index , interface->mac_parameters->mac_default_key_index, new_entry_created); 00290 00291 //set key descriptor 00292 if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) { 00293 main_list->key_table_size--; 00294 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); 00295 return -1; 00296 } 00297 00298 return 0; 00299 } 00300 00301 int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8]) 00302 { 00303 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00304 if (!interface || !interface->mac_api) { 00305 return -1; 00306 } 00307 00308 mac_pairwise_interface_entry_t *main_list; 00309 tr_debug("Pairwise_key delete %s", trace_array(eui64, 8)); 00310 main_list = mac_pairwise_key_main_class_discover(interface_id); 00311 if (!main_list) { 00312 return -1; 00313 } 00314 //Get from mac 00315 mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, NULL); 00316 if (!mac_entry) { 00317 return -1; 00318 } 00319 00320 //discover by mle entry attribute 00321 uint8_t key_attribute; 00322 00323 if (!mac_pairwise_key_info_delete(main_list, mac_entry->index , &key_attribute)) { 00324 return -1; 00325 } 00326 00327 //kill Entry & overwrite key 00328 mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute); 00329 00330 mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry); 00331 00332 return 0; 00333 } 00334 00335 00336 int mac_pairwise_key_flush_list(int8_t interface_id) 00337 { 00338 protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id); 00339 if (!interface) { 00340 return -1; 00341 } 00342 00343 tr_debug("Pairwise_key flush"); 00344 mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id); 00345 if (!main_list) { 00346 return -1; 00347 } 00348 00349 mac_pairwise_key_list_free(interface, main_list); 00350 00351 return 0; 00352 } 00353 00354
Generated on Tue Aug 9 2022 00:37:12 by
1.7.2