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_pairwise_key.c Source File

mac_pairwise_key.c

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