takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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     mac_pairwise_key_info_t *key_table = main_list->mac_pairwise_key_table;
00081     for (uint8_t i = 0; i<main_list->key_table_size; i++) {
00082         if (key_table->key_decriptor_attribute == key_attribute) {
00083             return false;
00084         }
00085         key_table++;
00086     }
00087 
00088     return true;
00089 }
00090 
00091 mac_pairwise_key_info_t *mac_pairwise_key_info_get(mac_pairwise_interface_entry_t *main_list, uint8_t device_id) {
00092     mac_pairwise_key_info_t *key_table = main_list->mac_pairwise_key_table;
00093     for (uint8_t i = 0; i<main_list->key_table_size; i++) {
00094         if (key_table->device_descriptor_attribute == device_id) {
00095             return key_table;
00096         }
00097         key_table++;
00098     }
00099 
00100     if (main_list->key_table_size == main_list->key_list_size ) {
00101         return NULL;
00102     }
00103 
00104 
00105     bool unique_id = false;
00106     mac_pairwise_key_info_t *new_entry = main_list->mac_pairwise_key_table + main_list->key_table_size;
00107     new_entry->device_descriptor_attribute = device_id;
00108     new_entry->key_decriptor_attribute = main_list->network_key_offset;
00109     //Allocate key id
00110     while(!unique_id) {
00111         unique_id = mac_pairwise_key_deacriptro_attribute_get(main_list, new_entry->key_decriptor_attribute);
00112         if (!unique_id) {
00113             new_entry->key_decriptor_attribute++;
00114         }
00115     }
00116 
00117     main_list->key_table_size++;
00118     return new_entry;
00119 }
00120 
00121 static bool mac_pairwise_key_info_delete(mac_pairwise_interface_entry_t *main_list, uint8_t device_id, uint8_t *key_attribute) {
00122     bool removed_entry = false;
00123 
00124     mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table;
00125     mac_pairwise_key_info_t *prev = NULL;
00126     for (uint8_t i = 0; i<main_list->key_table_size; i++) {
00127         if (removed_entry) {
00128             *prev = *cur;
00129         } else {
00130             if (cur->device_descriptor_attribute == device_id) {
00131                 removed_entry = true;
00132                 *key_attribute = cur->key_decriptor_attribute;
00133             }
00134         }
00135         prev = cur;
00136         cur++;
00137     }
00138     if (removed_entry) {
00139         main_list->key_table_size--;
00140     }
00141 
00142     return removed_entry;
00143 }
00144 
00145 
00146 static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class_discover(int8_t interfaceId)
00147 {
00148 
00149     ns_list_foreach(mac_pairwise_interface_entry_t, cur, &mac_pairwise_info) {
00150         if (interfaceId == cur->interfaceId) {
00151             return cur;
00152         }
00153     }
00154 
00155     return NULL;
00156 }
00157 
00158 
00159 static mac_pairwise_interface_entry_t *mac_pairwise_key_main_class(uint8_t key_list_size)
00160 {
00161 
00162     mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_list_allocate(key_list_size);
00163     if (!main_list) {
00164         return NULL;
00165     }
00166     tr_debug("Set new Key main Class");
00167     ns_list_add_to_end(&mac_pairwise_info, main_list);
00168 
00169     return main_list;
00170 }
00171 
00172 
00173 static void mac_pairwise_key_list_free(protocol_interface_info_entry_t *interface, mac_pairwise_interface_entry_t *main_list) {
00174     //Delete mle entries & Keys
00175     mac_neighbor_table_entry_t *cur_entry;
00176     mac_pairwise_key_info_t *cur = main_list->mac_pairwise_key_table;
00177     for (uint8_t i = 0; i< main_list->key_table_size; i++) {
00178         cur_entry = mac_neighbor_table_attribute_discover(mac_neighbor_info(interface), cur->device_descriptor_attribute);
00179         if (cur_entry) {
00180             mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), cur_entry);
00181         }
00182         mac_helper_security_pairwisekey_set(interface, NULL, NULL, cur->key_decriptor_attribute);
00183     }
00184     main_list->key_table_size = 0;
00185 }
00186 
00187 int mac_pairwise_key_interface_register(int8_t interface_id, uint8_t mac_supported_key_decription_size, uint8_t network_key_size)
00188 {
00189     if (!mac_supported_key_decription_size || !network_key_size ) {
00190         return -2;
00191     }
00192 
00193     if (mac_supported_key_decription_size < network_key_size) {
00194         return -2;
00195     }
00196 
00197     protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
00198     if (!interface) {
00199         return -1;
00200     }
00201 
00202     if (mac_pairwise_key_main_class_discover(interface_id)) {
00203         return -2;
00204     }
00205 
00206     uint8_t pairwise_key_list_size;
00207     uint8_t network_key_offset;
00208 
00209     if (mac_supported_key_decription_size == network_key_size) {
00210         pairwise_key_list_size = 1;
00211         network_key_offset = 0;
00212     } else {
00213         pairwise_key_list_size = (mac_supported_key_decription_size - network_key_size);
00214         network_key_offset = network_key_size;
00215     }
00216 
00217     mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class(pairwise_key_list_size);
00218     if (!main_list) {
00219         return -1;
00220     }
00221 
00222     main_list->interfaceId = interface_id;
00223     main_list->network_key_offset = network_key_offset;
00224 
00225     return 0;
00226 
00227 }
00228 
00229 int mac_pairwise_key_interface_unregister(int8_t interface_id)
00230 {
00231     protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
00232     if (!interface) {
00233         return -1;
00234     }
00235 
00236     mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id);
00237     if (!main_list) {
00238         return -1;
00239     }
00240 
00241     mac_pairwise_key_list_free(interface, main_list);
00242 
00243     //Can delete Main Class also
00244     ns_list_remove(&mac_pairwise_info, main_list);
00245     ns_dyn_mem_free(main_list->mac_pairwise_key_table);
00246     ns_dyn_mem_free(main_list);
00247     return 0;
00248 
00249 }
00250 
00251 
00252 
00253 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])
00254 {
00255     protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
00256     bool new_entry_created;
00257 
00258     if (!interface || !interface->mac_api) {
00259         return -1;
00260     }
00261 
00262     (void)valid_life_time;
00263     tr_debug("Pairwise_key addr %s, key %s", trace_array(eui64, 8), trace_array(key, 16));
00264     mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id);
00265     if (!main_list) {
00266         return -1;
00267     }
00268 
00269     //Allocate mle entry
00270     mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, &new_entry_created);
00271     if (!mac_entry) {
00272         return -1;
00273     }
00274 
00275     mac_neighbor_table_trusted_neighbor(mac_neighbor_info(interface), mac_entry, true);
00276     mac_entry->mac16  = 0xffff;
00277 
00278     //Allocate key description
00279 
00280     mac_pairwise_key_info_t *key_desc = mac_pairwise_key_info_get(main_list, mac_entry->index );
00281 
00282     if (!key_desc) {
00283         mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
00284         return -1;
00285     }
00286 
00287     mlme_device_descriptor_t device_desc;
00288     mac_helper_device_description_write(interface, &device_desc, mac_entry->mac64 , mac_entry->mac16 ,0, false);
00289     mac_helper_devicetable_set(&device_desc, interface,mac_entry->index , interface->mac_parameters->mac_default_key_index, new_entry_created);
00290 
00291     //set key descriptor
00292     if (mac_helper_security_pairwisekey_set(interface, key, eui64, key_desc->key_decriptor_attribute) != 0) {
00293         main_list->key_table_size--;
00294         mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
00295         return -1;
00296     }
00297 
00298     return 0;
00299 }
00300 
00301 int mac_pairwise_key_del(int8_t interface_id, const uint8_t eui64[static 8])
00302 {
00303     protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
00304     if (!interface || !interface->mac_api) {
00305         return -1;
00306     }
00307 
00308     mac_pairwise_interface_entry_t *main_list;
00309     tr_debug("Pairwise_key delete %s", trace_array(eui64, 8));
00310     main_list = mac_pairwise_key_main_class_discover(interface_id);
00311     if (!main_list) {
00312         return -1;
00313     }
00314     //Get from mac
00315     mac_neighbor_table_entry_t *mac_entry = mac_neighbor_entry_get_by_mac64(mac_neighbor_info(interface), eui64, true, NULL);
00316     if (!mac_entry) {
00317         return -1;
00318     }
00319 
00320     //discover by mle entry attribute
00321     uint8_t key_attribute;
00322 
00323     if (!mac_pairwise_key_info_delete(main_list, mac_entry->index , &key_attribute)) {
00324         return -1;
00325     }
00326 
00327     //kill Entry & overwrite key
00328     mac_helper_security_pairwisekey_set(interface, NULL, NULL, key_attribute);
00329 
00330     mac_neighbor_table_neighbor_remove(mac_neighbor_info(interface), mac_entry);
00331 
00332     return 0;
00333 }
00334 
00335 
00336 int mac_pairwise_key_flush_list(int8_t interface_id)
00337 {
00338     protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_id(interface_id);
00339     if (!interface) {
00340         return -1;
00341     }
00342 
00343     tr_debug("Pairwise_key flush");
00344     mac_pairwise_interface_entry_t *main_list = mac_pairwise_key_main_class_discover(interface_id);
00345     if (!main_list) {
00346         return -1;
00347     }
00348 
00349     mac_pairwise_key_list_free(interface, main_list);
00350 
00351     return 0;
00352 }
00353 
00354