Knight KE / Mbed OS Game_Master
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mac_security_mib.c Source File

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