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