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