mirror of https://github.com/ARMmbed/mbed-os.git
680 lines
25 KiB
C
680 lines
25 KiB
C
/*
|
|
* Copyright (c) 2016-2018, Arm Limited and affiliates.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "nsconfig.h"
|
|
#include <string.h>
|
|
#include "ns_types.h"
|
|
#include "ns_trace.h"
|
|
#include "nsdynmemLIB.h"
|
|
#include "platform/arm_hal_interrupt.h"
|
|
#include "mac_api.h"
|
|
#include "sw_mac.h"
|
|
#include "mac_common_defines.h"
|
|
#include "common_functions.h"
|
|
#include "MAC/IEEE802_15_4/mac_defines.h"
|
|
#include "MAC/IEEE802_15_4/mac_security_mib.h"
|
|
|
|
#define TRACE_GROUP "mMIB"
|
|
/**
|
|
* Allocate device description table based on size
|
|
*/
|
|
static mlme_device_descriptor_t *mac_sec_mib_device_description_table_allocate(uint8_t table_size)
|
|
{
|
|
mlme_device_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_device_descriptor_t) * table_size);
|
|
if (table_ptr) {
|
|
memset(table_ptr, 0xff, (sizeof(mlme_device_descriptor_t) * table_size));
|
|
}
|
|
return table_ptr;
|
|
}
|
|
|
|
static mlme_key_descriptor_t *mac_sec_mib_key_description_table_allocate(uint8_t table_size)
|
|
{
|
|
mlme_key_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_descriptor_t) * table_size);
|
|
if (table_ptr) {
|
|
memset(table_ptr, 0, (sizeof(mlme_key_descriptor_t) * table_size));
|
|
}
|
|
return table_ptr;
|
|
}
|
|
|
|
static mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_table_allocate(uint16_t list_size)
|
|
{
|
|
mlme_key_device_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_device_descriptor_t) * list_size);
|
|
if (table_ptr) {
|
|
memset(table_ptr, 0, (sizeof(mlme_key_device_descriptor_t) * list_size));
|
|
}
|
|
return table_ptr;
|
|
}
|
|
|
|
static mlme_key_usage_descriptor_t *mac_sec_mib_key_usage_table_allocate(uint16_t list_size)
|
|
{
|
|
|
|
mlme_key_usage_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_usage_descriptor_t) * list_size);
|
|
if (table_ptr) {
|
|
memset(table_ptr, 0, (sizeof(mlme_key_usage_descriptor_t) * list_size));
|
|
}
|
|
return table_ptr;
|
|
}
|
|
|
|
|
|
static mlme_key_id_lookup_descriptor_t *mac_sec_mib_key_lookup_table_allocate(uint16_t list_size)
|
|
{
|
|
|
|
mlme_key_id_lookup_descriptor_t *table_ptr = ns_dyn_mem_alloc(sizeof(mlme_key_id_lookup_descriptor_t) * list_size);
|
|
if (table_ptr) {
|
|
memset(table_ptr, 0, (sizeof(mlme_key_id_lookup_descriptor_t) * list_size));
|
|
}
|
|
return table_ptr;
|
|
}
|
|
|
|
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)
|
|
{
|
|
rf_mac_setup->key_device_frame_counter_list_buffer = ns_dyn_mem_alloc(sizeof(uint32_t) * list_size * device_count);
|
|
if (!rf_mac_setup->key_device_frame_counter_list_buffer) {
|
|
return -1;
|
|
}
|
|
memset(rf_mac_setup->key_device_frame_counter_list_buffer, 0, (sizeof(uint32_t) * list_size * device_count));
|
|
rf_mac_setup->secFrameCounterPerKey = true;
|
|
mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
|
|
uint32_t *frame_counter_pointer = rf_mac_setup->key_device_frame_counter_list_buffer;
|
|
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
|
key_descriptor_list->KeyDeviceFrameCouterList = frame_counter_pointer;
|
|
key_descriptor_list->KeyFrameCounterPerKey = true;
|
|
key_descriptor_list->KeyFrameCounter = 0;
|
|
//Update Pointers
|
|
key_descriptor_list++;
|
|
frame_counter_pointer += device_count;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void mac_sec_mib_frame_counter_key_buffer_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|
{
|
|
mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
|
|
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
|
key_descriptor_list->KeyDeviceFrameCouterList = NULL;
|
|
key_descriptor_list->KeyFrameCounterPerKey = false;
|
|
//Update Pointers
|
|
key_descriptor_list++;
|
|
}
|
|
ns_dyn_mem_free(rf_mac_setup->key_device_frame_counter_list_buffer);
|
|
rf_mac_setup->key_device_frame_counter_list_buffer = NULL;
|
|
rf_mac_setup->secFrameCounterPerKey = false;
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
|
|
if (!device_table) {
|
|
return NULL;
|
|
}
|
|
|
|
for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
|
|
if ((pan_id == 0xffff || device_table->PANId == pan_id) && device_table->ShortAddress == mac16) {
|
|
return device_table;
|
|
}
|
|
device_table++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
|
|
if (!device_table) {
|
|
return NULL;
|
|
}
|
|
|
|
for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
|
|
if ((pan_id == 0xffff || device_table->PANId == pan_id)) {
|
|
if (memcmp(device_table->ExtAddress, mac64, 8) == 0) {
|
|
return device_table;
|
|
}
|
|
}
|
|
device_table++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//Remove entry from the list
|
|
static void mac_sec_mib_key_device_description_remove_from_list(mlme_key_descriptor_t *key_descpription_table, uint8_t device_descriptor_handle)
|
|
{
|
|
bool removed_entry = false;
|
|
mlme_key_device_descriptor_t *cur, *prev;
|
|
prev = NULL;
|
|
cur = key_descpription_table->KeyDeviceList;
|
|
for (uint8_t i = 0; i < key_descpription_table->KeyDeviceListEntries; i++) {
|
|
if (removed_entry) {
|
|
//copy current to last one
|
|
*prev = *cur;
|
|
} else if (cur->DeviceDescriptorHandle == device_descriptor_handle) {
|
|
removed_entry = true;
|
|
//tr_debug("Remove user %u from key", device_descriptor_handle);
|
|
}
|
|
prev = cur;
|
|
cur++;
|
|
}
|
|
|
|
if (removed_entry) {
|
|
key_descpription_table->KeyDeviceListEntries--;
|
|
//Clear Also frame counter per key if it its enabled
|
|
if (key_descpription_table->KeyFrameCounterPerKey) {
|
|
//SET frame counter to 0
|
|
mac_sec_mib_key_device_frame_counter_set(key_descpription_table, NULL, 0, device_descriptor_handle);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void mac_sec_mib_device_description_remove(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t device_handle)
|
|
{
|
|
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
|
mac_sec_mib_key_device_description_remove_from_list(&rf_mac_setup->key_description_table[i], device_handle);
|
|
}
|
|
}
|
|
|
|
|
|
static int8_t mac_sec_mib_device_description_table_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|
{
|
|
ns_dyn_mem_free(rf_mac_setup->device_description_table);
|
|
rf_mac_setup->device_description_table = NULL;
|
|
rf_mac_setup->device_description_table_size = 0;
|
|
return 0;
|
|
}
|
|
|
|
static void mac_sec_mib_security_material_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|
{
|
|
ns_dyn_mem_free(rf_mac_setup->key_description_table);
|
|
ns_dyn_mem_free(rf_mac_setup->key_device_desc_buffer);
|
|
ns_dyn_mem_free(rf_mac_setup->key_usage_list_buffer);
|
|
ns_dyn_mem_free(rf_mac_setup->key_lookup_buffer);
|
|
rf_mac_setup->key_usage_list_buffer = NULL;
|
|
rf_mac_setup->key_description_table = NULL;
|
|
rf_mac_setup->key_lookup_buffer = NULL;
|
|
rf_mac_setup->key_device_desc_buffer = NULL;
|
|
rf_mac_setup->key_description_table_size = 0;
|
|
rf_mac_setup->key_lookup_list_size = 0;
|
|
rf_mac_setup->key_usage_list_size = 0;
|
|
}
|
|
|
|
static int8_t mac_sec_mib_key_description_table_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|
{
|
|
mac_sec_mib_security_material_free(rf_mac_setup);
|
|
return 0;
|
|
}
|
|
|
|
static int8_t mac_sec_mib_device_description_table_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t table_size)
|
|
{
|
|
|
|
rf_mac_setup->device_description_table = mac_sec_mib_device_description_table_allocate(table_size);
|
|
if (!rf_mac_setup->device_description_table) {
|
|
return -1;
|
|
}
|
|
|
|
rf_mac_setup->device_description_table_size = table_size;
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
rf_mac_setup->key_description_table = mac_sec_mib_key_description_table_allocate(table_size);
|
|
rf_mac_setup->key_device_desc_buffer = mac_sec_mib_key_device_description_table_allocate(device_decription_size * table_size);
|
|
rf_mac_setup->key_usage_list_buffer = mac_sec_mib_key_usage_table_allocate(key_usage_size * table_size);
|
|
rf_mac_setup->key_lookup_buffer = mac_sec_mib_key_lookup_table_allocate(key_lookup_size * table_size);
|
|
|
|
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) {
|
|
mac_sec_mib_security_material_free(rf_mac_setup);
|
|
return -1;
|
|
}
|
|
|
|
//SET description buffer sizes
|
|
rf_mac_setup->key_description_table_size = table_size;
|
|
rf_mac_setup->key_lookup_list_size = key_lookup_size;
|
|
rf_mac_setup->key_usage_list_size = key_usage_size;
|
|
|
|
mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
|
|
mlme_key_device_descriptor_t *key_device_decription = rf_mac_setup->key_device_desc_buffer;
|
|
mlme_key_usage_descriptor_t *key_usage_ptr = rf_mac_setup->key_usage_list_buffer;
|
|
mlme_key_id_lookup_descriptor_t *key_lookup = rf_mac_setup->key_lookup_buffer;
|
|
|
|
|
|
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
|
|
|
//Update Pointer values after first init
|
|
if (i) {
|
|
key_device_decription += device_decription_size;
|
|
key_usage_ptr += key_usage_size;
|
|
key_lookup += key_lookup_size;
|
|
key_descriptor_list++;
|
|
}
|
|
key_descriptor_list->KeyDeviceListSize = device_decription_size;
|
|
key_descriptor_list->KeyDeviceList = key_device_decription;
|
|
key_descriptor_list->KeyUsageList = key_usage_ptr;
|
|
key_descriptor_list->KeyIdLookupList = key_lookup;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
//validate index to list size
|
|
if (!rf_mac_setup || !device_descriptor || atribute_index >= rf_mac_setup->device_description_table_size) {
|
|
return -1;
|
|
}
|
|
|
|
platform_enter_critical();
|
|
mlme_device_descriptor_t *device_ptr = rf_mac_setup->device_description_table + atribute_index;
|
|
|
|
//Copy description
|
|
if (memcmp(device_ptr->ExtAddress, device_descriptor->ExtAddress, 8)) {
|
|
//Remove last handles key user's
|
|
mac_sec_mib_device_description_remove(rf_mac_setup, atribute_index);
|
|
//tr_debug("Over write %u, mac16 %x mac64: %s, %"PRIu32, atribute_index, device_ptr->ShortAddress, trace_array(device_ptr->ExtAddress, 8), device_ptr->FrameCounter);
|
|
}
|
|
|
|
//tr_debug("Set %u, mac16 %x mac64: %s, %"PRIu32, atribute_index, device_descriptor->ShortAddress, trace_array(device_descriptor->ExtAddress, 8), device_descriptor->FrameCounter);
|
|
|
|
*device_ptr = *device_descriptor;
|
|
|
|
if (rf_mac_setup->mac_ack_tx_active && !rf_mac_setup->ack_tx_possible &&
|
|
device_ptr->PANId == rf_mac_setup->enhanced_ack_buffer.DstPANId) {
|
|
|
|
//Compare address for pending neigbour add
|
|
if (rf_mac_setup->enhanced_ack_buffer.fcf_dsn.DstAddrMode == MAC_ADDR_MODE_16_BIT) {
|
|
uint16_t short_id = common_read_16_bit(rf_mac_setup->enhanced_ack_buffer.DstAddr);
|
|
if (short_id == device_ptr->ShortAddress) {
|
|
rf_mac_setup->ack_tx_possible = true;
|
|
}
|
|
} else if (rf_mac_setup->enhanced_ack_buffer.fcf_dsn.DstAddrMode == MAC_ADDR_MODE_64_BIT) {
|
|
if (memcmp(device_ptr->ExtAddress, rf_mac_setup->enhanced_ack_buffer.DstAddr, 8) == 0) {
|
|
rf_mac_setup->ack_tx_possible = true;
|
|
}
|
|
}
|
|
}
|
|
platform_exit_critical();
|
|
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
//validate index to list size
|
|
if (!rf_mac_setup || !key_descriptor || atribute_index >= rf_mac_setup->key_description_table_size) {
|
|
return -1;
|
|
}
|
|
|
|
if (key_descriptor->KeyDeviceListEntries > rf_mac_setup->key_description_table_size || (key_descriptor->KeyDeviceListEntries && !key_descriptor->KeyDeviceList)) {
|
|
return -1;
|
|
}
|
|
|
|
if (key_descriptor->KeyIdLookupListEntries > rf_mac_setup->key_lookup_list_size || (key_descriptor->KeyIdLookupListEntries && !key_descriptor->KeyIdLookupList)) {
|
|
return -1;
|
|
}
|
|
|
|
if (key_descriptor->KeyUsageListEntries > rf_mac_setup->key_usage_list_size || (key_descriptor->KeyUsageListEntries && !key_descriptor->KeyUsageList)) {
|
|
return -1;
|
|
}
|
|
|
|
mlme_key_descriptor_t *key_ptr = rf_mac_setup->key_description_table + atribute_index;
|
|
|
|
//Copy description
|
|
tr_debug("Set key %"PRIu8, atribute_index);
|
|
|
|
memcpy(key_ptr->Key, key_descriptor->Key, 16);
|
|
key_ptr->KeyDeviceListEntries = key_descriptor->KeyDeviceListEntries;
|
|
key_ptr->unique_key_descriptor = false;
|
|
|
|
if (key_ptr->KeyDeviceListEntries) {
|
|
memcpy(key_ptr->KeyDeviceList, key_descriptor->KeyDeviceList, sizeof(mlme_key_device_descriptor_t) * key_ptr->KeyDeviceListEntries);
|
|
//Check unique key
|
|
if (key_ptr->KeyDeviceListEntries == 1) {
|
|
key_ptr->unique_key_descriptor = key_descriptor->KeyDeviceList->UniqueDevice;
|
|
}
|
|
}
|
|
|
|
key_ptr->KeyIdLookupListEntries = key_descriptor->KeyIdLookupListEntries;
|
|
|
|
if (key_ptr->KeyIdLookupListEntries) {
|
|
memcpy(key_ptr->KeyIdLookupList, key_descriptor->KeyIdLookupList, sizeof(mlme_key_id_lookup_descriptor_t) * key_ptr->KeyIdLookupListEntries);
|
|
}
|
|
|
|
key_ptr->KeyUsageListEntries = key_descriptor->KeyUsageListEntries;
|
|
|
|
if (key_ptr->KeyUsageListEntries) {
|
|
memcpy(key_ptr->KeyUsageList, key_descriptor->KeyUsageList, sizeof(mlme_key_usage_descriptor_t) * key_ptr->KeyUsageListEntries);
|
|
}
|
|
|
|
if (key_ptr->KeyFrameCounterPerKey) {
|
|
key_ptr->KeyFrameCounter = 0;
|
|
if (key_ptr->KeyDeviceListEntries == 0) {
|
|
//Clear all frame counters from old possible user's
|
|
uint32_t *counter_ptr = key_ptr->KeyDeviceFrameCouterList;
|
|
for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
|
|
*counter_ptr++ = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (!rf_mac_setup || attribute_index >= rf_mac_setup->device_description_table_size) {
|
|
return NULL;
|
|
}
|
|
return rf_mac_setup->device_description_table + attribute_index;
|
|
}
|
|
|
|
void mac_sec_mib_device_description_pan_update(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t pan_id)
|
|
{
|
|
mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
|
|
if (!device_table) {
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
|
|
|
|
device_table->PANId = pan_id;
|
|
device_table++;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
if (rf_mac_setup) {
|
|
if (type == MAC_ADDR_MODE_16_BIT) {
|
|
uint16_t short_id = common_read_16_bit(address);
|
|
return mac_sec_mib_device_description_get_by_mac16(rf_mac_setup, short_id, pan_id);
|
|
} else if (type == MAC_ADDR_MODE_64_BIT) {
|
|
return mac_sec_mib_device_description_get_by_mac64(rf_mac_setup, address, pan_id);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
uint8_t mac_mib_device_descption_attribute_get_by_descriptor(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_device_descriptor_t *descriptor)
|
|
{
|
|
if (!rf_mac_setup || !descriptor) {
|
|
return 0xff;
|
|
}
|
|
mlme_device_descriptor_t *device_table = rf_mac_setup->device_description_table;
|
|
for (uint8_t i = 0; i < rf_mac_setup->device_description_table_size; i++) {
|
|
if (device_table == descriptor) {
|
|
return i;
|
|
}
|
|
device_table++;
|
|
}
|
|
return 0xff;
|
|
}
|
|
|
|
|
|
static bool mac_sec_key_description_lookup_validate(mlme_key_descriptor_t *key_description, uint8_t *lookupdata)
|
|
{
|
|
uint8_t lookup_length;
|
|
mlme_key_id_lookup_descriptor_t *cur_lookup_ptr = key_description->KeyIdLookupList;
|
|
|
|
for (uint8_t i = 0; i < key_description->KeyIdLookupListEntries; i++) {
|
|
if (cur_lookup_ptr->LookupDataSize) {
|
|
lookup_length = 9;
|
|
} else {
|
|
lookup_length = 5;
|
|
}
|
|
|
|
if (memcmp(cur_lookup_ptr->LookupData, lookupdata, lookup_length) == 0) {
|
|
return true;
|
|
}
|
|
cur_lookup_ptr++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (!rf_mac_setup || !key_source) {
|
|
return NULL;
|
|
}
|
|
|
|
mlme_key_descriptor_t *key_description;
|
|
uint8_t lookup_data[9];
|
|
memset(lookup_data, 0, 9);
|
|
|
|
switch (key_source->KeyIdMode) {
|
|
case MAC_KEY_ID_MODE_IMPLICIT:
|
|
if (address_mode == MAC_ADDR_MODE_64_BIT) {
|
|
memcpy(lookup_data, address_ptr, 8);
|
|
} else if (address_mode == MAC_ADDR_MODE_16_BIT) {
|
|
common_write_16_bit(pan_id, lookup_data);
|
|
memcpy(&lookup_data[2], address_ptr, 2);
|
|
} else {
|
|
return NULL; //Not supported this yet
|
|
}
|
|
break;
|
|
case MAC_KEY_ID_MODE_IDX:
|
|
//SET Default keysource
|
|
memcpy(lookup_data, rf_mac_setup->mac_default_key_source, 8);
|
|
lookup_data[8] = key_source->KeyIndex;
|
|
break;
|
|
|
|
case MAC_KEY_ID_MODE_SRC4_IDX:
|
|
memcpy(lookup_data, key_source->Keysource, 4);
|
|
lookup_data[4] = key_source->KeyIndex;
|
|
break;
|
|
|
|
case MAC_KEY_ID_MODE_SRC8_IDX:
|
|
memcpy(lookup_data, key_source->Keysource, 8);
|
|
lookup_data[8] = key_source->KeyIndex;
|
|
break;
|
|
}
|
|
key_description = rf_mac_setup->key_description_table;
|
|
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
|
|
|
if (mac_sec_key_description_lookup_validate(key_description, lookup_data)) {
|
|
return key_description;
|
|
}
|
|
key_description++;
|
|
}
|
|
|
|
//tr_debug("LookuPdata search fail %s", trace_array(lookup_data, 9));
|
|
|
|
return NULL;
|
|
}
|
|
|
|
mlme_key_descriptor_t *mac_sec_key_description_get_by_attribute(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t atribute_index)
|
|
{
|
|
//validate index to list size
|
|
if (atribute_index >= rf_mac_setup->key_description_table_size) {
|
|
return NULL;
|
|
}
|
|
|
|
|
|
return rf_mac_setup->key_description_table + atribute_index;
|
|
}
|
|
|
|
int8_t mac_sec_mib_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_description_storage_size_t *storage_sizes)
|
|
{
|
|
|
|
if (!rf_mac_setup || !storage_sizes) {
|
|
return -1;
|
|
}
|
|
|
|
mac_sec_mib_deinit(rf_mac_setup);
|
|
if (mac_sec_mib_device_description_table_init(rf_mac_setup, storage_sizes->device_decription_table_size) != 0) {
|
|
return -1;
|
|
}
|
|
|
|
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)) {
|
|
mac_sec_mib_deinit(rf_mac_setup);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int8_t mac_sec_mib_frame_counter_per_key_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, bool enabled)
|
|
{
|
|
if (enabled) {
|
|
if (rf_mac_setup->key_device_frame_counter_list_buffer) {
|
|
return 0;
|
|
}
|
|
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);
|
|
}
|
|
|
|
//Clear Key Descriptors
|
|
|
|
//Free current list
|
|
mac_sec_mib_frame_counter_key_buffer_free(rf_mac_setup);
|
|
return 0;
|
|
}
|
|
|
|
|
|
void mac_sec_mib_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
|
{
|
|
if (!rf_mac_setup) {
|
|
return;
|
|
}
|
|
mac_sec_mib_frame_counter_key_buffer_free(rf_mac_setup);
|
|
mac_sec_mib_device_description_table_deinit(rf_mac_setup);
|
|
mac_sec_mib_key_description_table_deinit(rf_mac_setup);
|
|
|
|
}
|
|
|
|
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)
|
|
{
|
|
uint32_t value;
|
|
platform_enter_critical();
|
|
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
|
value = key_descpription->KeyFrameCounter;
|
|
} else {
|
|
value = rf_mac_setup->security_frame_counter;
|
|
}
|
|
platform_exit_critical();
|
|
return value;
|
|
}
|
|
|
|
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)
|
|
{
|
|
platform_enter_critical();
|
|
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
|
key_descpription->KeyFrameCounter = value;
|
|
} else {
|
|
rf_mac_setup->security_frame_counter = value;
|
|
}
|
|
platform_exit_critical();
|
|
}
|
|
|
|
void mac_sec_mib_key_outgoing_frame_counter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
|
|
{
|
|
platform_enter_critical();
|
|
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
|
key_descpription->KeyFrameCounter++;
|
|
} else {
|
|
rf_mac_setup->security_frame_counter++;
|
|
}
|
|
platform_exit_critical();
|
|
}
|
|
|
|
void mac_sec_mib_key_outgoing_frame_counter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
|
|
{
|
|
platform_enter_critical();
|
|
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
|
key_descpription->KeyFrameCounter--;
|
|
} else {
|
|
rf_mac_setup->security_frame_counter--;
|
|
}
|
|
platform_exit_critical();
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
if (key_descpription_table->KeyFrameCounterPerKey) {
|
|
uint32_t *counter_ptr = key_descpription_table->KeyDeviceFrameCouterList + attribute_index;
|
|
*counter_ptr = frame_counter;
|
|
} else {
|
|
device_info->FrameCounter = frame_counter;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (key_descpription_table->KeyFrameCounterPerKey) {
|
|
uint32_t *counter_ptr = key_descpription_table->KeyDeviceFrameCouterList + attribute_index;
|
|
return *counter_ptr;
|
|
}
|
|
return device_info->FrameCounter;
|
|
}
|
|
|
|
|
|
//allocate new entry and update entries size
|
|
mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_list_update(mlme_key_descriptor_t *key_descpription_table)
|
|
{
|
|
if (!key_descpription_table || key_descpription_table->KeyDeviceListEntries == key_descpription_table->KeyDeviceListSize) {
|
|
return NULL;
|
|
}
|
|
mlme_key_device_descriptor_t *new_entry = key_descpription_table->KeyDeviceList;
|
|
new_entry += key_descpription_table->KeyDeviceListEntries++;
|
|
new_entry->Blacklisted = false;
|
|
new_entry->UniqueDevice = false;
|
|
return new_entry;
|
|
}
|
|
|
|
//Discover device entry from the list
|
|
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)
|
|
{
|
|
if (key_description_table) {
|
|
mlme_key_device_descriptor_t *entry = key_description_table->KeyDeviceList;
|
|
for (uint8_t i = 0; i < key_description_table->KeyDeviceListEntries; i++) {
|
|
if (entry->DeviceDescriptorHandle == device_descriptor_handle) {
|
|
return entry;
|
|
}
|
|
entry++;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//Black list device from key descriptior list
|
|
|
|
void mac_sec_mib_device_description_blacklist(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t device_handle)
|
|
{
|
|
if (!rf_mac_setup) {
|
|
return;
|
|
}
|
|
mlme_key_device_descriptor_t *descriptor;
|
|
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
|
descriptor = mac_sec_mib_key_device_description_discover_from_list(&rf_mac_setup->key_description_table[i], device_handle);
|
|
if (descriptor) {
|
|
descriptor->Blacklisted = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|