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_security_mib.c
00001 /* 00002 * Copyright (c) 2016-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 #include "nsconfig.h" 00018 #include <string.h> 00019 #include "ns_types.h" 00020 #include "ns_trace.h" 00021 #include "nsdynmemLIB.h" 00022 #include "mac_api.h" 00023 #include "sw_mac.h" 00024 #include "mac_common_defines.h" 00025 #include "common_functions.h" 00026 #include "MAC/IEEE802_15_4/mac_defines.h" 00027 #include "MAC/IEEE802_15_4/mac_security_mib.h" 00028 00029 #define TRACE_GROUP "mMIB" 00030 /** 00031 * Allocate device description table based on size 00032 */ 00033 static mlme_device_descriptor_t * mac_sec_mib_device_description_table_allocate(uint8_t table_size) { 00034 mlme_device_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_device_descriptor_t) * table_size); 00035 if (table_ptr) { 00036 memset(table_ptr, 0xff, (sizeof(mlme_device_descriptor_t) * table_size)); 00037 } 00038 return table_ptr; 00039 } 00040 00041 static mlme_key_descriptor_t * mac_sec_mib_key_description_table_allocate(uint8_t table_size) { 00042 mlme_key_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_descriptor_t) * table_size); 00043 if (table_ptr) { 00044 memset(table_ptr, 0, (sizeof(mlme_key_descriptor_t) * table_size)); 00045 } 00046 return table_ptr; 00047 } 00048 00049 static mlme_key_device_descriptor_t * mac_sec_mib_key_device_description_table_allocate(uint16_t list_size) { 00050 mlme_key_device_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_device_descriptor_t) * list_size); 00051 if (table_ptr) { 00052 memset(table_ptr, 0, (sizeof(mlme_key_device_descriptor_t) * list_size)); 00053 } 00054 return table_ptr; 00055 } 00056 00057 static mlme_key_usage_descriptor_t * mac_sec_mib_key_usage_table_allocate(uint16_t list_size) { 00058 00059 mlme_key_usage_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_usage_descriptor_t) * list_size); 00060 if (table_ptr) { 00061 memset(table_ptr, 0, (sizeof(mlme_key_usage_descriptor_t) * list_size)); 00062 } 00063 return table_ptr; 00064 } 00065 00066 00067 static mlme_key_id_lookup_descriptor_t * mac_sec_mib_key_lookup_table_allocate(uint16_t list_size) { 00068 00069 mlme_key_id_lookup_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_id_lookup_descriptor_t) * list_size); 00070 if (table_ptr) { 00071 memset(table_ptr, 0, (sizeof(mlme_key_id_lookup_descriptor_t) * list_size)); 00072 } 00073 return table_ptr; 00074 } 00075 00076 static mlme_device_descriptor_t *mac_sec_mib_device_description_get_by_mac16(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t mac16) { 00077 00078 mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table; 00079 if (!device_table) { 00080 return NULL; 00081 } 00082 00083 for (int i=0; i < rf_mac_setup->device_description_table_size; i++) { 00084 if (device_table->ShortAddress == mac16) { 00085 return device_table; 00086 } 00087 device_table++; 00088 } 00089 00090 return NULL; 00091 } 00092 00093 static mlme_device_descriptor_t * mac_sec_mib_device_description_get_by_mac64(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *mac64) { 00094 00095 mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table; 00096 if (!device_table) { 00097 return NULL; 00098 } 00099 00100 for (int i=0; i < rf_mac_setup->device_description_table_size; i++) { 00101 if (memcmp(device_table->ExtAddress, mac64, 8) == 0) { 00102 return device_table; 00103 } 00104 device_table++; 00105 } 00106 return NULL; 00107 } 00108 00109 //Remove entry from the list 00110 static void mac_sec_mib_key_device_description_remove_from_list(mlme_key_descriptor_t *key_descpription_table, uint8_t device_descriptor_handle) 00111 { 00112 bool removed_entry = false; 00113 mlme_key_device_descriptor_t *cur, *prev; 00114 prev = NULL; 00115 cur = key_descpription_table->KeyDeviceList; 00116 for (uint8_t i=0; i< key_descpription_table->KeyDeviceListEntries; i++) { 00117 if (removed_entry) { 00118 //copy current to last one 00119 *prev = *cur; 00120 } else if (cur->DeviceDescriptorHandle == device_descriptor_handle) { 00121 removed_entry = true; 00122 tr_debug("Remove user %u from key", device_descriptor_handle); 00123 } 00124 prev = cur; 00125 cur++; 00126 } 00127 00128 if (removed_entry) { 00129 key_descpription_table->KeyDeviceListEntries--; 00130 } 00131 } 00132 00133 static void mac_sec_mib_device_description_remove(protocol_interface_rf_mac_setup_s *rf_mac_setup , uint8_t device_handle) 00134 { 00135 for(uint8_t i=0; i< rf_mac_setup->key_description_table_size; i++) { 00136 mac_sec_mib_key_device_description_remove_from_list(&rf_mac_setup->key_description_table[i], device_handle); 00137 } 00138 } 00139 00140 00141 static int8_t mac_sec_mib_device_description_table_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00142 { 00143 ns_dyn_mem_free(rf_mac_setup->device_description_table); 00144 rf_mac_setup->device_description_table = NULL; 00145 rf_mac_setup->device_description_table_size = 0; 00146 return 0; 00147 } 00148 00149 static void mac_sec_mib_security_material_free(protocol_interface_rf_mac_setup_s *rf_mac_setup) { 00150 ns_dyn_mem_free(rf_mac_setup->key_description_table); 00151 ns_dyn_mem_free(rf_mac_setup->key_device_desc_buffer); 00152 ns_dyn_mem_free(rf_mac_setup->key_usage_list_buffer); 00153 ns_dyn_mem_free(rf_mac_setup->key_lookup_buffer); 00154 rf_mac_setup->key_usage_list_buffer = NULL; 00155 rf_mac_setup->key_description_table = NULL; 00156 rf_mac_setup->key_lookup_buffer = NULL; 00157 rf_mac_setup->key_device_desc_buffer = NULL; 00158 rf_mac_setup->key_description_table_size = 0; 00159 rf_mac_setup->key_lookup_list_size = 0; 00160 rf_mac_setup->key_usage_list_size = 0; 00161 } 00162 00163 static int8_t mac_sec_mib_key_description_table_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup) { 00164 mac_sec_mib_security_material_free(rf_mac_setup); 00165 return 0; 00166 } 00167 00168 static int8_t mac_sec_mib_device_description_table_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t table_size) { 00169 00170 rf_mac_setup->device_description_table = mac_sec_mib_device_description_table_allocate(table_size); 00171 if (!rf_mac_setup->device_description_table) { 00172 return -1; 00173 } 00174 00175 rf_mac_setup->device_description_table_size = table_size; 00176 return 0; 00177 } 00178 00179 static int8_t mac_sec_mib_key_description_table_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t table_size, uint8_t device_decription_size, uint8_t key_lookup_size, uint8_t key_usage_size) { 00180 00181 rf_mac_setup->key_description_table = mac_sec_mib_key_description_table_allocate(table_size); 00182 rf_mac_setup->key_device_desc_buffer = mac_sec_mib_key_device_description_table_allocate(device_decription_size * table_size); 00183 rf_mac_setup->key_usage_list_buffer = mac_sec_mib_key_usage_table_allocate(key_usage_size * table_size); 00184 rf_mac_setup->key_lookup_buffer = mac_sec_mib_key_lookup_table_allocate(key_lookup_size * table_size); 00185 00186 if (!rf_mac_setup->key_lookup_buffer || !rf_mac_setup->key_description_table || !rf_mac_setup->key_device_desc_buffer || !rf_mac_setup->key_usage_list_buffer) { 00187 mac_sec_mib_security_material_free(rf_mac_setup); 00188 return -1; 00189 } 00190 00191 //SET description buffer sizes 00192 rf_mac_setup->key_description_table_size = table_size; 00193 rf_mac_setup->key_lookup_list_size = key_lookup_size; 00194 rf_mac_setup->key_usage_list_size = key_usage_size; 00195 00196 mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table; 00197 mlme_key_device_descriptor_t *key_device_decription = rf_mac_setup->key_device_desc_buffer; 00198 mlme_key_usage_descriptor_t *key_usage_ptr = rf_mac_setup->key_usage_list_buffer; 00199 mlme_key_id_lookup_descriptor_t *key_lookup = rf_mac_setup->key_lookup_buffer; 00200 00201 00202 for (uint8_t i = 0; i< rf_mac_setup->key_description_table_size; i++) { 00203 00204 //Update Pointer values after first init 00205 if (i) { 00206 key_device_decription += device_decription_size; 00207 key_usage_ptr += key_usage_size; 00208 key_lookup += key_lookup_size; 00209 key_descriptor_list++; 00210 } 00211 key_descriptor_list->KeyDeviceListSize = device_decription_size; 00212 key_descriptor_list->KeyDeviceList = key_device_decription; 00213 key_descriptor_list->KeyUsageList = key_usage_ptr; 00214 key_descriptor_list->KeyIdLookupList = key_lookup; 00215 } 00216 00217 return 0; 00218 00219 } 00220 00221 int8_t mac_sec_mib_device_description_set(uint8_t atribute_index, mlme_device_descriptor_t *device_descriptor, protocol_interface_rf_mac_setup_s *rf_mac_setup) { 00222 00223 //validate index to list size 00224 if (!rf_mac_setup || !device_descriptor || atribute_index >= rf_mac_setup->device_description_table_size) { 00225 tr_debug("Too many Devices"); 00226 return -1; 00227 } 00228 00229 mlme_device_descriptor_t *device_ptr = rf_mac_setup->device_description_table + atribute_index; 00230 00231 //Copy description 00232 if (memcmp(device_ptr->ExtAddress, device_descriptor->ExtAddress, 8)) { 00233 //Remove last handles key user's 00234 mac_sec_mib_device_description_remove(rf_mac_setup, atribute_index); 00235 tr_debug("Over write %u, mac16 %x mac64: %s, %"PRIu32, atribute_index, device_ptr->ShortAddress, trace_array(device_ptr->ExtAddress, 8), device_ptr->FrameCounter); 00236 } 00237 00238 tr_debug("Set %u, mac16 %x mac64: %s, %"PRIu32, atribute_index, device_descriptor->ShortAddress, trace_array(device_descriptor->ExtAddress, 8), device_descriptor->FrameCounter); 00239 00240 *device_ptr = *device_descriptor; 00241 return 0; 00242 } 00243 00244 int8_t mac_sec_mib_key_description_set(uint8_t atribute_index, mlme_key_descriptor_entry_t *key_descriptor, protocol_interface_rf_mac_setup_s *rf_mac_setup) { 00245 00246 //validate index to list size 00247 if (!rf_mac_setup || !key_descriptor || atribute_index >= rf_mac_setup->key_description_table_size) { 00248 return -1; 00249 } 00250 00251 if (key_descriptor->KeyDeviceListEntries > rf_mac_setup->key_description_table_size || (key_descriptor->KeyDeviceListEntries && !key_descriptor->KeyDeviceList)) { 00252 return -1; 00253 } 00254 00255 if (key_descriptor->KeyIdLookupListEntries > rf_mac_setup->key_lookup_list_size || (key_descriptor->KeyIdLookupListEntries && !key_descriptor->KeyIdLookupList)) { 00256 return -1; 00257 } 00258 00259 if (key_descriptor->KeyUsageListEntries > rf_mac_setup->key_usage_list_size || (key_descriptor->KeyUsageListEntries && !key_descriptor->KeyUsageList)) { 00260 return -1; 00261 } 00262 00263 mlme_key_descriptor_t *key_ptr = rf_mac_setup->key_description_table + atribute_index; 00264 00265 //Copy description 00266 tr_debug("Set key %"PRIu8, atribute_index); 00267 00268 memcpy(key_ptr->Key, key_descriptor->Key, 16); 00269 key_ptr->KeyDeviceListEntries = key_descriptor->KeyDeviceListEntries; 00270 key_ptr->unique_key_descriptor = false; 00271 00272 if(key_ptr->KeyDeviceListEntries) { 00273 memcpy(key_ptr->KeyDeviceList,key_descriptor->KeyDeviceList , sizeof(mlme_key_device_descriptor_t) * key_ptr->KeyDeviceListEntries); 00274 //Check unique key 00275 if (key_ptr->KeyDeviceListEntries == 1) { 00276 key_ptr->unique_key_descriptor = key_descriptor->KeyDeviceList->UniqueDevice; 00277 } 00278 } 00279 00280 key_ptr->KeyIdLookupListEntries = key_descriptor->KeyIdLookupListEntries; 00281 00282 if(key_ptr->KeyIdLookupListEntries) { 00283 memcpy(key_ptr->KeyIdLookupList,key_descriptor->KeyIdLookupList , sizeof(mlme_key_id_lookup_descriptor_t) * key_ptr->KeyIdLookupListEntries); 00284 } 00285 00286 key_ptr->KeyUsageListEntries = key_descriptor->KeyUsageListEntries; 00287 00288 if(key_ptr->KeyUsageListEntries) { 00289 memcpy(key_ptr->KeyUsageList,key_descriptor->KeyUsageList , sizeof(mlme_key_usage_descriptor_t) * key_ptr->KeyUsageListEntries); 00290 } 00291 00292 return 0; 00293 } 00294 00295 mlme_device_descriptor_t *mac_sec_mib_device_description_get_attribute_index(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t attribute_index) 00296 { 00297 if (!rf_mac_setup || attribute_index >= rf_mac_setup->device_description_table_size) { 00298 return NULL; 00299 } 00300 return rf_mac_setup->device_description_table + attribute_index; 00301 } 00302 00303 mlme_device_descriptor_t *mac_sec_mib_device_description_get(protocol_interface_rf_mac_setup_s *rf_mac_setup, const uint8_t *address, uint8_t type) 00304 { 00305 if( rf_mac_setup ){ 00306 if (type == MAC_ADDR_MODE_16_BIT) { 00307 uint16_t short_id = common_read_16_bit(address); 00308 return mac_sec_mib_device_description_get_by_mac16(rf_mac_setup, short_id); 00309 } else if (type == MAC_ADDR_MODE_64_BIT) { 00310 return mac_sec_mib_device_description_get_by_mac64(rf_mac_setup, address); 00311 } 00312 } 00313 00314 return NULL; 00315 } 00316 00317 uint8_t mac_mib_device_descption_attribute_get_by_descriptor(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_device_descriptor_t *descriptor) 00318 { 00319 if( !rf_mac_setup || !descriptor ){ 00320 return 0xff; 00321 } 00322 mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table; 00323 for (uint8_t i=0; i < rf_mac_setup->device_description_table_size; i++) { 00324 if (device_table == descriptor) { 00325 return i; 00326 } 00327 device_table++; 00328 } 00329 return 0xff; 00330 } 00331 00332 00333 static bool mac_sec_key_description_lookup_validate(mlme_key_descriptor_t * key_description, uint8_t *lookupdata) { 00334 uint8_t lookup_length; 00335 mlme_key_id_lookup_descriptor_t *cur_lookup_ptr = key_description->KeyIdLookupList; 00336 00337 for (uint8_t i=0; i<key_description->KeyIdLookupListEntries; i++) { 00338 if (cur_lookup_ptr->LookupDataSize ) { 00339 lookup_length = 9; 00340 } else { 00341 lookup_length = 5; 00342 } 00343 00344 if (memcmp(cur_lookup_ptr->LookupData, lookupdata, lookup_length) == 0) { 00345 return true; 00346 } 00347 cur_lookup_ptr++; 00348 } 00349 return false; 00350 } 00351 00352 mlme_key_descriptor_t * mac_sec_key_description_get(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_security_t *key_source, uint8_t address_mode, uint8_t *address_ptr, uint16_t pan_id) 00353 { 00354 if( !rf_mac_setup || !key_source ){ 00355 return NULL; 00356 } 00357 00358 mlme_key_descriptor_t *key_description; 00359 uint8_t lookup_data[9]; 00360 memset(lookup_data, 0, 9); 00361 00362 switch (key_source->KeyIdMode) { 00363 case MAC_KEY_ID_MODE_IMPLICIT: 00364 if (address_mode == MAC_ADDR_MODE_64_BIT) { 00365 memcpy(lookup_data, address_ptr, 8); 00366 } else if (address_mode == MAC_ADDR_MODE_16_BIT) { 00367 common_write_16_bit(pan_id,lookup_data); 00368 memcpy(&lookup_data[2], address_ptr, 2); 00369 } else { 00370 return NULL; //Not supported this yet 00371 } 00372 break; 00373 case MAC_KEY_ID_MODE_IDX: 00374 //SET Default keysource 00375 memcpy(lookup_data, rf_mac_setup->mac_default_key_source, 8); 00376 lookup_data[8] = key_source->KeyIndex; 00377 break; 00378 00379 case MAC_KEY_ID_MODE_SRC4_IDX: 00380 memcpy(lookup_data, key_source->Keysource ,4); 00381 lookup_data[4] = key_source->KeyIndex; 00382 break; 00383 00384 case MAC_KEY_ID_MODE_SRC8_IDX: 00385 memcpy(lookup_data, key_source->Keysource ,8); 00386 lookup_data[8] = key_source->KeyIndex; 00387 break; 00388 } 00389 key_description = rf_mac_setup->key_description_table; 00390 for (uint8_t i = 0; i< rf_mac_setup->key_description_table_size; i++) { 00391 00392 if (mac_sec_key_description_lookup_validate(key_description, lookup_data)) { 00393 return key_description; 00394 } 00395 key_description++; 00396 } 00397 00398 tr_debug("LookuPdata search fail %s", trace_array(lookup_data, 9)); 00399 00400 return NULL; 00401 } 00402 00403 int8_t mac_sec_mib_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_description_storage_size_t *storage_sizes) { 00404 00405 if( !rf_mac_setup || !storage_sizes){ 00406 return -1; 00407 } 00408 00409 mac_sec_mib_deinit(rf_mac_setup); 00410 if (mac_sec_mib_device_description_table_init(rf_mac_setup, storage_sizes->device_decription_table_size)!= 0) { 00411 return -1; 00412 } 00413 00414 if (mac_sec_mib_key_description_table_init(rf_mac_setup, storage_sizes->key_description_table_size, storage_sizes->device_decription_table_size, storage_sizes->key_lookup_size, storage_sizes->key_usage_size)) { 00415 mac_sec_mib_deinit(rf_mac_setup); 00416 return -1; 00417 } 00418 00419 return 0; 00420 } 00421 00422 void mac_sec_mib_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup) 00423 { 00424 if( !rf_mac_setup ){ 00425 return; 00426 } 00427 mac_sec_mib_device_description_table_deinit(rf_mac_setup); 00428 mac_sec_mib_key_description_table_deinit(rf_mac_setup); 00429 00430 } 00431 00432 //allocate new entry and update entries size 00433 mlme_key_device_descriptor_t * mac_sec_mib_key_device_description_list_update(mlme_key_descriptor_t *key_descpription_table) 00434 { 00435 if (!key_descpription_table || key_descpription_table->KeyDeviceListEntries == key_descpription_table->KeyDeviceListSize) { 00436 return NULL; 00437 } 00438 mlme_key_device_descriptor_t * new_entry = key_descpription_table->KeyDeviceList; 00439 new_entry += key_descpription_table->KeyDeviceListEntries++; 00440 new_entry->Blacklisted = false; 00441 new_entry->UniqueDevice = false; 00442 return new_entry; 00443 } 00444 00445 //Discover device entry from the list 00446 mlme_key_device_descriptor_t * mac_sec_mib_key_device_description_discover_from_list(mlme_key_descriptor_t *key_description_table, uint8_t device_descriptor_handle) 00447 { 00448 if( key_description_table ){ 00449 mlme_key_device_descriptor_t * entry = key_description_table->KeyDeviceList; 00450 for (uint8_t i=0; i< key_description_table->KeyDeviceListEntries; i++) { 00451 if (entry->DeviceDescriptorHandle == device_descriptor_handle) { 00452 return entry; 00453 } 00454 entry++; 00455 } 00456 } 00457 00458 return NULL; 00459 } 00460 00461 //Black list device from key descriptior list 00462 00463 void mac_sec_mib_device_description_blacklist(protocol_interface_rf_mac_setup_s *rf_mac_setup , uint8_t device_handle) { 00464 00465 if( !rf_mac_setup ){ 00466 return; 00467 } 00468 mlme_key_device_descriptor_t *descriptor; 00469 for(uint8_t i=0; i< rf_mac_setup->key_description_table_size; i++) { 00470 descriptor = mac_sec_mib_key_device_description_discover_from_list(&rf_mac_setup->key_description_table[i], device_handle); 00471 if (descriptor) { 00472 tr_debug("Black listed device %u lookup%s", device_handle, trace_array(rf_mac_setup->key_description_table[i].Key, 16)); 00473 descriptor->Blacklisted = true; 00474 } 00475 00476 } 00477 } 00478 00479
Generated on Tue Jul 12 2022 12:44:57 by
