Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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-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 #include "nsconfig.h"
00018 #include <string.h>
00019 #include "ns_types.h"
00020 #include "ns_trace.h"
00021 #include "nsdynmemLIB.h"
00022 #include "platform/arm_hal_interrupt.h"
00023 #include "mac_api.h"
00024 #include "sw_mac.h"
00025 #include "mac_common_defines.h"
00026 #include "common_functions.h"
00027 #include "MAC/IEEE802_15_4/mac_defines.h"
00028 #include "MAC/IEEE802_15_4/mac_security_mib.h"
00029 
00030 #define TRACE_GROUP "mMIB"
00031 /**
00032  * Allocate device description table based on size
00033  */
00034 static mlme_device_descriptor_t *mac_sec_mib_device_description_table_allocate(uint8_t table_size)
00035 {
00036     mlme_device_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_device_descriptor_t) * table_size);
00037     if (table_ptr) {
00038         memset(table_ptr, 0xff, (sizeof(mlme_device_descriptor_t) * table_size));
00039     }
00040     return table_ptr;
00041 }
00042 
00043 static mlme_key_descriptor_t *mac_sec_mib_key_description_table_allocate(uint8_t table_size)
00044 {
00045     mlme_key_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_descriptor_t) * table_size);
00046     if (table_ptr) {
00047         memset(table_ptr, 0, (sizeof(mlme_key_descriptor_t) * table_size));
00048     }
00049     return table_ptr;
00050 }
00051 
00052 static mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_table_allocate(uint16_t list_size)
00053 {
00054     mlme_key_device_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_device_descriptor_t) * list_size);
00055     if (table_ptr) {
00056         memset(table_ptr, 0, (sizeof(mlme_key_device_descriptor_t) * list_size));
00057     }
00058     return table_ptr;
00059 }
00060 
00061 static mlme_key_usage_descriptor_t *mac_sec_mib_key_usage_table_allocate(uint16_t list_size)
00062 {
00063 
00064     mlme_key_usage_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_usage_descriptor_t) * list_size);
00065     if (table_ptr) {
00066         memset(table_ptr, 0, (sizeof(mlme_key_usage_descriptor_t) * list_size));
00067     }
00068     return table_ptr;
00069 }
00070 
00071 
00072 static mlme_key_id_lookup_descriptor_t *mac_sec_mib_key_lookup_table_allocate(uint16_t list_size)
00073 {
00074 
00075     mlme_key_id_lookup_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_id_lookup_descriptor_t) * list_size);
00076     if (table_ptr) {
00077         memset(table_ptr, 0, (sizeof(mlme_key_id_lookup_descriptor_t) * list_size));
00078     }
00079     return table_ptr;
00080 }
00081 
00082 static int mac_sec_mib_frame_counter_key_buffer_allocate(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t list_size, uint16_t device_count)
00083 {
00084     rf_mac_setup->key_device_frame_counter_list_buffer = ns_dyn_mem_alloc(sizeof(uint32_t) * list_size * device_count);
00085     if (!rf_mac_setup->key_device_frame_counter_list_buffer) {
00086         return -1;
00087     }
00088     memset(rf_mac_setup->key_device_frame_counter_list_buffer, 0, (sizeof(uint32_t) * list_size * device_count));
00089     rf_mac_setup->secFrameCounterPerKey = true;
00090     mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
00091     uint32_t *frame_counter_pointer = rf_mac_setup->key_device_frame_counter_list_buffer;
00092     for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
00093         key_descriptor_list->KeyDeviceFrameCouterList = frame_counter_pointer;
00094         key_descriptor_list->KeyFrameCounterPerKey = true;
00095         key_descriptor_list->KeyFrameCounter = 0;
00096         //Update Pointers
00097         key_descriptor_list++;
00098         frame_counter_pointer += device_count;
00099     }
00100 
00101     return 0;
00102 }
00103 
00104 static void mac_sec_mib_frame_counter_key_buffer_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00105 {
00106     mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
00107     for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
00108         key_descriptor_list->KeyDeviceFrameCouterList = NULL;
00109         key_descriptor_list->KeyFrameCounterPerKey = false;
00110         //Update Pointers
00111         key_descriptor_list++;
00112     }
00113     ns_dyn_mem_free(rf_mac_setup->key_device_frame_counter_list_buffer);
00114     rf_mac_setup->key_device_frame_counter_list_buffer = NULL;
00115     rf_mac_setup->secFrameCounterPerKey = false;
00116 }
00117 
00118 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, uint16_t pan_id)
00119 {
00120 
00121     mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
00122     if (!device_table) {
00123         return NULL;
00124     }
00125 
00126     for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
00127         if ((pan_id == 0xffff || device_table->PANId == pan_id) && device_table->ShortAddress == mac16) {
00128             return device_table;
00129         }
00130         device_table++;
00131     }
00132 
00133     return NULL;
00134 }
00135 
00136 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, uint16_t pan_id)
00137 {
00138 
00139     mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
00140     if (!device_table) {
00141         return NULL;
00142     }
00143 
00144     for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
00145         if ((pan_id == 0xffff || device_table->PANId == pan_id)) {
00146             if (memcmp(device_table->ExtAddress, mac64, 8) == 0) {
00147                 return device_table;
00148             }
00149         }
00150         device_table++;
00151     }
00152     return NULL;
00153 }
00154 
00155 //Remove entry from the list
00156 static void mac_sec_mib_key_device_description_remove_from_list(mlme_key_descriptor_t *key_descpription_table, uint8_t device_descriptor_handle)
00157 {
00158     bool removed_entry = false;
00159     mlme_key_device_descriptor_t *cur, *prev;
00160     prev = NULL;
00161     cur = key_descpription_table->KeyDeviceList;
00162     for (uint8_t i = 0; i < key_descpription_table->KeyDeviceListEntries; i++) {
00163         if (removed_entry) {
00164             //copy current to last one
00165             *prev = *cur;
00166         } else if (cur->DeviceDescriptorHandle == device_descriptor_handle) {
00167             removed_entry = true;
00168             //tr_debug("Remove user %u from key", device_descriptor_handle);
00169         }
00170         prev = cur;
00171         cur++;
00172     }
00173 
00174     if (removed_entry) {
00175         key_descpription_table->KeyDeviceListEntries--;
00176         //Clear Also frame counter per key if it its enabled
00177         if (key_descpription_table->KeyFrameCounterPerKey) {
00178             //SET frame counter to 0
00179             mac_sec_mib_key_device_frame_counter_set(key_descpription_table, NULL, 0, device_descriptor_handle);
00180         }
00181     }
00182 }
00183 
00184 static void mac_sec_mib_device_description_remove(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t device_handle)
00185 {
00186     for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
00187         mac_sec_mib_key_device_description_remove_from_list(&rf_mac_setup->key_description_table[i], device_handle);
00188     }
00189 }
00190 
00191 
00192 static int8_t  mac_sec_mib_device_description_table_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00193 {
00194     ns_dyn_mem_free(rf_mac_setup->device_description_table);
00195     rf_mac_setup->device_description_table = NULL;
00196     rf_mac_setup->device_description_table_size = 0;
00197     return 0;
00198 }
00199 
00200 static void mac_sec_mib_security_material_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00201 {
00202     ns_dyn_mem_free(rf_mac_setup->key_description_table);
00203     ns_dyn_mem_free(rf_mac_setup->key_device_desc_buffer);
00204     ns_dyn_mem_free(rf_mac_setup->key_usage_list_buffer);
00205     ns_dyn_mem_free(rf_mac_setup->key_lookup_buffer);
00206     rf_mac_setup->key_usage_list_buffer = NULL;
00207     rf_mac_setup->key_description_table = NULL;
00208     rf_mac_setup->key_lookup_buffer = NULL;
00209     rf_mac_setup->key_device_desc_buffer = NULL;
00210     rf_mac_setup->key_description_table_size = 0;
00211     rf_mac_setup->key_lookup_list_size = 0;
00212     rf_mac_setup->key_usage_list_size = 0;
00213 }
00214 
00215 static int8_t  mac_sec_mib_key_description_table_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00216 {
00217     mac_sec_mib_security_material_free(rf_mac_setup);
00218     return 0;
00219 }
00220 
00221 static int8_t  mac_sec_mib_device_description_table_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t table_size)
00222 {
00223 
00224     rf_mac_setup->device_description_table = mac_sec_mib_device_description_table_allocate(table_size);
00225     if (!rf_mac_setup->device_description_table) {
00226         return -1;
00227     }
00228 
00229     rf_mac_setup->device_description_table_size = table_size;
00230     return 0;
00231 }
00232 
00233 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)
00234 {
00235 
00236     rf_mac_setup->key_description_table = mac_sec_mib_key_description_table_allocate(table_size);
00237     rf_mac_setup->key_device_desc_buffer = mac_sec_mib_key_device_description_table_allocate(device_decription_size * table_size);
00238     rf_mac_setup->key_usage_list_buffer = mac_sec_mib_key_usage_table_allocate(key_usage_size * table_size);
00239     rf_mac_setup->key_lookup_buffer = mac_sec_mib_key_lookup_table_allocate(key_lookup_size * table_size);
00240 
00241     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) {
00242         mac_sec_mib_security_material_free(rf_mac_setup);
00243         return -1;
00244     }
00245 
00246     //SET description buffer sizes
00247     rf_mac_setup->key_description_table_size = table_size;
00248     rf_mac_setup->key_lookup_list_size = key_lookup_size;
00249     rf_mac_setup->key_usage_list_size = key_usage_size;
00250 
00251     mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
00252     mlme_key_device_descriptor_t *key_device_decription = rf_mac_setup->key_device_desc_buffer;
00253     mlme_key_usage_descriptor_t *key_usage_ptr = rf_mac_setup->key_usage_list_buffer;
00254     mlme_key_id_lookup_descriptor_t *key_lookup = rf_mac_setup->key_lookup_buffer;
00255 
00256 
00257     for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
00258 
00259         //Update Pointer values after first init
00260         if (i) {
00261             key_device_decription += device_decription_size;
00262             key_usage_ptr += key_usage_size;
00263             key_lookup += key_lookup_size;
00264             key_descriptor_list++;
00265         }
00266         key_descriptor_list->KeyDeviceListSize = device_decription_size;
00267         key_descriptor_list->KeyDeviceList = key_device_decription;
00268         key_descriptor_list->KeyUsageList = key_usage_ptr;
00269         key_descriptor_list->KeyIdLookupList = key_lookup;
00270     }
00271 
00272     return 0;
00273 
00274 }
00275 
00276 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)
00277 {
00278 
00279     //validate index to list size
00280     if (!rf_mac_setup || !device_descriptor || atribute_index >= rf_mac_setup->device_description_table_size) {
00281         return -1;
00282     }
00283 
00284     mlme_device_descriptor_t *device_ptr = rf_mac_setup->device_description_table + atribute_index;
00285 
00286     //Copy description
00287     if (memcmp(device_ptr->ExtAddress, device_descriptor->ExtAddress, 8)) {
00288         //Remove last handles key user's
00289         mac_sec_mib_device_description_remove(rf_mac_setup, atribute_index);
00290         //tr_debug("Over write %u, mac16 %x mac64: %s, %"PRIu32, atribute_index, device_ptr->ShortAddress, trace_array(device_ptr->ExtAddress, 8), device_ptr->FrameCounter);
00291     }
00292 
00293     //tr_debug("Set %u, mac16 %x mac64: %s, %"PRIu32, atribute_index, device_descriptor->ShortAddress, trace_array(device_descriptor->ExtAddress, 8), device_descriptor->FrameCounter);
00294 
00295     *device_ptr = *device_descriptor;
00296     return 0;
00297 }
00298 
00299 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)
00300 {
00301 
00302     //validate index to list size
00303     if (!rf_mac_setup || !key_descriptor || atribute_index >= rf_mac_setup->key_description_table_size) {
00304         return -1;
00305     }
00306 
00307     if (key_descriptor->KeyDeviceListEntries > rf_mac_setup->key_description_table_size || (key_descriptor->KeyDeviceListEntries && !key_descriptor->KeyDeviceList)) {
00308         return -1;
00309     }
00310 
00311     if (key_descriptor->KeyIdLookupListEntries > rf_mac_setup->key_lookup_list_size || (key_descriptor->KeyIdLookupListEntries && !key_descriptor->KeyIdLookupList)) {
00312         return -1;
00313     }
00314 
00315     if (key_descriptor->KeyUsageListEntries > rf_mac_setup->key_usage_list_size || (key_descriptor->KeyUsageListEntries && !key_descriptor->KeyUsageList)) {
00316         return -1;
00317     }
00318 
00319     mlme_key_descriptor_t *key_ptr = rf_mac_setup->key_description_table + atribute_index;
00320 
00321     //Copy description
00322     tr_debug("Set key %"PRIu8, atribute_index);
00323 
00324     memcpy(key_ptr->Key, key_descriptor->Key, 16);
00325     key_ptr->KeyDeviceListEntries = key_descriptor->KeyDeviceListEntries;
00326     key_ptr->unique_key_descriptor = false;
00327 
00328     if (key_ptr->KeyDeviceListEntries) {
00329         memcpy(key_ptr->KeyDeviceList, key_descriptor->KeyDeviceList, sizeof(mlme_key_device_descriptor_t) * key_ptr->KeyDeviceListEntries);
00330         //Check unique key
00331         if (key_ptr->KeyDeviceListEntries == 1) {
00332             key_ptr->unique_key_descriptor = key_descriptor->KeyDeviceList->UniqueDevice;
00333         }
00334     }
00335 
00336     key_ptr->KeyIdLookupListEntries = key_descriptor->KeyIdLookupListEntries;
00337 
00338     if (key_ptr->KeyIdLookupListEntries) {
00339         memcpy(key_ptr->KeyIdLookupList, key_descriptor->KeyIdLookupList, sizeof(mlme_key_id_lookup_descriptor_t) * key_ptr->KeyIdLookupListEntries);
00340     }
00341 
00342     key_ptr->KeyUsageListEntries = key_descriptor->KeyUsageListEntries;
00343 
00344     if (key_ptr->KeyUsageListEntries) {
00345         memcpy(key_ptr->KeyUsageList, key_descriptor->KeyUsageList, sizeof(mlme_key_usage_descriptor_t) * key_ptr->KeyUsageListEntries);
00346     }
00347 
00348     if (key_ptr->KeyFrameCounterPerKey) {
00349         key_ptr->KeyFrameCounter = 0;
00350         if (key_ptr->KeyDeviceListEntries == 0) {
00351             //Clear all frame counters from old possible user's
00352             uint32_t *counter_ptr = key_ptr->KeyDeviceFrameCouterList;
00353             for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
00354                 *counter_ptr++ = 0;
00355             }
00356         }
00357     }
00358 
00359     return 0;
00360 }
00361 
00362 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)
00363 {
00364     if (!rf_mac_setup || attribute_index >= rf_mac_setup->device_description_table_size) {
00365         return NULL;
00366     }
00367     return rf_mac_setup->device_description_table + attribute_index;
00368 }
00369 
00370 void mac_sec_mib_device_description_pan_update(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t pan_id)
00371 {
00372     mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
00373     if (!device_table) {
00374         return;
00375     }
00376 
00377     for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
00378 
00379         device_table->PANId = pan_id;
00380         device_table++;
00381     }
00382 
00383 }
00384 
00385 
00386 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, uint16_t pan_id)
00387 {
00388     if (rf_mac_setup) {
00389         if (type == MAC_ADDR_MODE_16_BIT) {
00390             uint16_t short_id = common_read_16_bit(address);
00391             return  mac_sec_mib_device_description_get_by_mac16(rf_mac_setup, short_id, pan_id);
00392         } else if (type == MAC_ADDR_MODE_64_BIT) {
00393             return mac_sec_mib_device_description_get_by_mac64(rf_mac_setup, address, pan_id);
00394         }
00395     }
00396 
00397     return NULL;
00398 }
00399 
00400 uint8_t mac_mib_device_descption_attribute_get_by_descriptor(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_device_descriptor_t *descriptor)
00401 {
00402     if (!rf_mac_setup || !descriptor) {
00403         return 0xff;
00404     }
00405     mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
00406     for (uint8_t i = 0; i < rf_mac_setup->device_description_table_size; i++) {
00407         if (device_table == descriptor) {
00408             return i;
00409         }
00410         device_table++;
00411     }
00412     return 0xff;
00413 }
00414 
00415 
00416 static bool mac_sec_key_description_lookup_validate(mlme_key_descriptor_t *key_description, uint8_t *lookupdata)
00417 {
00418     uint8_t lookup_length;
00419     mlme_key_id_lookup_descriptor_t *cur_lookup_ptr = key_description->KeyIdLookupList;
00420 
00421     for (uint8_t i = 0; i < key_description->KeyIdLookupListEntries; i++) {
00422         if (cur_lookup_ptr->LookupDataSize) {
00423             lookup_length = 9;
00424         } else {
00425             lookup_length = 5;
00426         }
00427 
00428         if (memcmp(cur_lookup_ptr->LookupData, lookupdata, lookup_length) == 0) {
00429             return true;
00430         }
00431         cur_lookup_ptr++;
00432     }
00433     return false;
00434 }
00435 
00436 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)
00437 {
00438     if (!rf_mac_setup || !key_source) {
00439         return NULL;
00440     }
00441 
00442     mlme_key_descriptor_t *key_description;
00443     uint8_t lookup_data[9];
00444     memset(lookup_data, 0, 9);
00445 
00446     switch (key_source->KeyIdMode) {
00447         case MAC_KEY_ID_MODE_IMPLICIT:
00448             if (address_mode == MAC_ADDR_MODE_64_BIT) {
00449                 memcpy(lookup_data, address_ptr, 8);
00450             } else if (address_mode == MAC_ADDR_MODE_16_BIT) {
00451                 common_write_16_bit(pan_id, lookup_data);
00452                 memcpy(&lookup_data[2], address_ptr, 2);
00453             } else {
00454                 return NULL; //Not supported this yet
00455             }
00456             break;
00457         case MAC_KEY_ID_MODE_IDX:
00458             //SET Default keysource
00459             memcpy(lookup_data, rf_mac_setup->mac_default_key_source, 8);
00460             lookup_data[8] = key_source->KeyIndex;
00461             break;
00462 
00463         case MAC_KEY_ID_MODE_SRC4_IDX:
00464             memcpy(lookup_data, key_source->Keysource, 4);
00465             lookup_data[4] = key_source->KeyIndex;
00466             break;
00467 
00468         case MAC_KEY_ID_MODE_SRC8_IDX:
00469             memcpy(lookup_data, key_source->Keysource, 8);
00470             lookup_data[8] = key_source->KeyIndex;
00471             break;
00472     }
00473     key_description = rf_mac_setup->key_description_table;
00474     for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
00475 
00476         if (mac_sec_key_description_lookup_validate(key_description, lookup_data)) {
00477             return key_description;
00478         }
00479         key_description++;
00480     }
00481 
00482     //tr_debug("LookuPdata search fail %s", trace_array(lookup_data, 9));
00483 
00484     return NULL;
00485 }
00486 
00487 mlme_key_descriptor_t *mac_sec_key_description_get_by_attribute(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t atribute_index)
00488 {
00489     //validate index to list size
00490     if (atribute_index >= rf_mac_setup->key_description_table_size) {
00491         return NULL;
00492     }
00493 
00494 
00495     return rf_mac_setup->key_description_table + atribute_index;
00496 }
00497 
00498 int8_t mac_sec_mib_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_description_storage_size_t *storage_sizes)
00499 {
00500 
00501     if (!rf_mac_setup || !storage_sizes) {
00502         return -1;
00503     }
00504 
00505     mac_sec_mib_deinit(rf_mac_setup);
00506     if (mac_sec_mib_device_description_table_init(rf_mac_setup, storage_sizes->device_decription_table_size) != 0) {
00507         return -1;
00508     }
00509 
00510     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)) {
00511         mac_sec_mib_deinit(rf_mac_setup);
00512         return -1;
00513     }
00514 
00515     return 0;
00516 }
00517 
00518 
00519 int8_t mac_sec_mib_frame_counter_per_key_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, bool enabled)
00520 {
00521     if (enabled) {
00522         if (rf_mac_setup->key_device_frame_counter_list_buffer) {
00523             return 0;
00524         }
00525         return mac_sec_mib_frame_counter_key_buffer_allocate(rf_mac_setup, rf_mac_setup->key_description_table_size, rf_mac_setup->device_description_table_size);
00526     }
00527 
00528     //Clear Key Descriptors
00529 
00530     //Free current list
00531     mac_sec_mib_frame_counter_key_buffer_free(rf_mac_setup);
00532     return 0;
00533 }
00534 
00535 
00536 void mac_sec_mib_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
00537 {
00538     if (!rf_mac_setup) {
00539         return;
00540     }
00541     mac_sec_mib_frame_counter_key_buffer_free(rf_mac_setup);
00542     mac_sec_mib_device_description_table_deinit(rf_mac_setup);
00543     mac_sec_mib_key_description_table_deinit(rf_mac_setup);
00544 
00545 }
00546 
00547 uint32_t mac_sec_mib_key_outgoing_frame_counter_get(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
00548 {
00549     uint32_t value;
00550     platform_enter_critical();
00551     if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
00552         value = key_descpription->KeyFrameCounter;
00553     } else {
00554         value = rf_mac_setup->security_frame_counter;
00555     }
00556     platform_exit_critical();
00557     return value;
00558 }
00559 
00560 void mac_sec_mib_key_outgoing_frame_counter_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_key_descriptor_t *key_descpription, uint32_t value)
00561 {
00562     platform_enter_critical();
00563     if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
00564         key_descpription->KeyFrameCounter = value;
00565     } else {
00566         rf_mac_setup->security_frame_counter = value;
00567     }
00568     platform_exit_critical();
00569 }
00570 
00571 void mac_sec_mib_key_outgoing_frame_counter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
00572 {
00573     platform_enter_critical();
00574     if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
00575         key_descpription->KeyFrameCounter++;
00576     } else {
00577         rf_mac_setup->security_frame_counter++;
00578     }
00579     platform_exit_critical();
00580 }
00581 
00582 void mac_sec_mib_key_outgoing_frame_counter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
00583 {
00584     platform_enter_critical();
00585     if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
00586         key_descpription->KeyFrameCounter--;
00587     } else {
00588         rf_mac_setup->security_frame_counter--;
00589     }
00590     platform_exit_critical();
00591 }
00592 
00593 
00594 void mac_sec_mib_key_device_frame_counter_set(mlme_key_descriptor_t *key_descpription_table, mlme_device_descriptor_t *device_info, uint32_t frame_counter, uint8_t attribute_index)
00595 {
00596     if (key_descpription_table->KeyFrameCounterPerKey) {
00597         uint32_t *counter_ptr = key_descpription_table->KeyDeviceFrameCouterList + attribute_index;
00598         *counter_ptr = frame_counter;
00599     } else {
00600         device_info->FrameCounter = frame_counter;
00601     }
00602 }
00603 
00604 uint32_t mac_mib_key_device_frame_counter_get(mlme_key_descriptor_t *key_descpription_table, mlme_device_descriptor_t *device_info, uint8_t attribute_index)
00605 {
00606     if (key_descpription_table->KeyFrameCounterPerKey) {
00607         uint32_t *counter_ptr = key_descpription_table->KeyDeviceFrameCouterList + attribute_index;
00608         return *counter_ptr;
00609     }
00610     return device_info->FrameCounter;
00611 }
00612 
00613 
00614 //allocate new entry and update entries size
00615 mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_list_update(mlme_key_descriptor_t *key_descpription_table)
00616 {
00617     if (!key_descpription_table || key_descpription_table->KeyDeviceListEntries == key_descpription_table->KeyDeviceListSize) {
00618         return NULL;
00619     }
00620     mlme_key_device_descriptor_t *new_entry = key_descpription_table->KeyDeviceList;
00621     new_entry += key_descpription_table->KeyDeviceListEntries++;
00622     new_entry->Blacklisted = false;
00623     new_entry->UniqueDevice = false;
00624     return new_entry;
00625 }
00626 
00627 //Discover device entry from the list
00628 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)
00629 {
00630     if (key_description_table) {
00631         mlme_key_device_descriptor_t *entry = key_description_table->KeyDeviceList;
00632         for (uint8_t i = 0; i < key_description_table->KeyDeviceListEntries; i++) {
00633             if (entry->DeviceDescriptorHandle == device_descriptor_handle) {
00634                 return entry;
00635             }
00636             entry++;
00637         }
00638     }
00639 
00640     return NULL;
00641 }
00642 
00643 //Black list device from key descriptior list
00644 
00645 void mac_sec_mib_device_description_blacklist(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t device_handle)
00646 {
00647     if (!rf_mac_setup) {
00648         return;
00649     }
00650     mlme_key_device_descriptor_t *descriptor;
00651     for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
00652         descriptor = mac_sec_mib_key_device_description_discover_from_list(&rf_mac_setup->key_description_table[i], device_handle);
00653         if (descriptor) {
00654             descriptor->Blacklisted = true;
00655         }
00656 
00657     }
00658 }
00659 
00660