Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mle_service_security.c Source File

mle_service_security.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 mle_service_security.c
00020  * \brief Add short description about this file!!!
00021  *
00022  */
00023 
00024 #include "nsconfig.h"
00025 #include <string.h>
00026 #include <ns_types.h>
00027 #include "ns_trace.h"
00028 #include "common_functions.h"
00029 #include "ccmLIB.h"
00030 #include "nsdynmemLIB.h"
00031 #include "Core/include/address.h"
00032 #include "Core/include/ns_buffer.h"
00033 #include "MLE/mle.h"
00034 #include "mac_common_defines.h"
00035 #include "Service_Libs/mle_service/mle_service_security.h"
00036 
00037 #define TRACE_GROUP "mlSS"
00038 
00039 typedef struct {
00040     mle_security_components_t security_params;
00041     int8_t interface_id;
00042     ns_list_link_t link;
00043 } mle_service_security_isntance_list_t;
00044 
00045 typedef NS_LIST_HEAD (mle_service_security_isntance_list_t, link) mle_service_security_instance_list_t;
00046 
00047 static mle_service_security_instance_list_t srv_security_instance_list;
00048 
00049 
00050 static mle_security_key_t * mle_service_security_key_entry_get(mle_security_components_t *sec_ptr, bool primary );
00051 
00052 static mle_service_security_isntance_list_t * mle_service_security_instance_get(int8_t interface_id)
00053 {
00054     ns_list_foreach(mle_service_security_isntance_list_t, cur_ptr, &srv_security_instance_list) {
00055         if (cur_ptr->interface_id == interface_id) {
00056             return cur_ptr;
00057         }
00058     }
00059     return NULL;
00060 }
00061 
00062 mle_security_components_t * mle_service_security_params_get(int8_t interface_id)
00063 {
00064     ns_list_foreach(mle_service_security_isntance_list_t, cur_ptr, &srv_security_instance_list) {
00065         if (cur_ptr->interface_id == interface_id) {
00066             return &cur_ptr->security_params;
00067         }
00068     }
00069     return NULL;
00070 }
00071 
00072 
00073 int mle_service_security_instance_allocate(int8_t interface_id)
00074 {
00075     mle_service_security_isntance_list_t *srv_ptr = mle_service_security_instance_get(interface_id);
00076 
00077     if (!srv_ptr) {
00078         srv_ptr = ns_dyn_mem_alloc(sizeof(mle_service_security_isntance_list_t));
00079         if (!srv_ptr) {
00080             return -1;
00081         }
00082         ns_list_add_to_start(&srv_security_instance_list, srv_ptr);
00083         srv_ptr->interface_id = interface_id;
00084         srv_ptr->security_params.key_req = NULL;
00085         srv_ptr->security_params.security_notify = NULL;
00086         srv_ptr->security_params.security_frame_counter = 0;
00087         srv_ptr->security_params.sec_level = 0;
00088     }
00089 
00090     return 0;
00091 }
00092 
00093 int mle_service_security_instance_delete(int8_t interface_id)
00094 {
00095     ns_list_foreach(mle_service_security_isntance_list_t, cur_ptr, &srv_security_instance_list) {
00096         if (cur_ptr->interface_id == interface_id) {
00097             ns_list_remove(&srv_security_instance_list, cur_ptr);
00098             ns_dyn_mem_free(cur_ptr);
00099             return 0;
00100         }
00101     }
00102     return -1;
00103 }
00104 
00105 mle_security_key_t * mle_service_security_key_get(mle_security_components_t *sec_ptr, uint8_t key_id )
00106 {
00107     uint8_t i;
00108     mle_security_key_t *key;
00109     for (i=0; i< MLE_MAX_KEY_TABLE_SIZE; i++) {
00110         key = &sec_ptr->mle_security_key_table[i];
00111 
00112         if (key->key_valid && key->key_id == key_id) {
00113             return key;
00114         }
00115     }
00116     return NULL;
00117 }
00118 
00119 
00120 static mle_security_key_t * mle_service_security_key_get_free_entry(mle_security_components_t *sec_ptr, bool primary )
00121 {
00122     uint8_t i;
00123     mle_security_key_t *key;
00124     for (i=0; i< MLE_MAX_KEY_TABLE_SIZE; i++) {
00125         key = &sec_ptr->mle_security_key_table[i];
00126 
00127         if (!key->key_valid && key->primary_key == primary) {
00128             return key;
00129         }
00130     }
00131     return NULL;
00132 }
00133 
00134 static mle_security_key_t * mle_service_security_key_entry_get(mle_security_components_t *sec_ptr, bool primary )
00135 {
00136     uint8_t i;
00137     mle_security_key_t *key;
00138     for (i=0; i< MLE_MAX_KEY_TABLE_SIZE; i++) {
00139         key = &sec_ptr->mle_security_key_table[i];
00140 
00141         if (key->key_valid && key->primary_key == primary) {
00142             return key;
00143         }
00144     }
00145     return NULL;
00146 }
00147 
00148 void mle_service_security_parameters_init(mle_security_components_t *sec_ptr)
00149 {
00150     uint8_t i;
00151     for (i=0; i< MLE_MAX_KEY_TABLE_SIZE; i++) {
00152         sec_ptr->mle_security_key_table[i].key_id = 0xff;
00153         if (i) {
00154             sec_ptr->mle_security_key_table[i].primary_key = false;
00155         } else {
00156             sec_ptr->mle_security_key_table[i].primary_key = true;
00157         }
00158         sec_ptr->mle_security_key_table[i].key_valid = false;
00159         sec_ptr->mle_security_key_table[i].pending_primary = false;
00160         memset(sec_ptr->mle_security_key_table[i].aes_key,0,16);
00161     }
00162 }
00163 
00164 uint32_t mle_service_security_get_framecounter(mle_security_components_t *sec_ptr, bool increment)
00165 {
00166     if (increment) {
00167         return ++sec_ptr->security_frame_counter;
00168     }
00169     return sec_ptr->security_frame_counter;
00170 }
00171 
00172 uint8_t mle_service_security_get_default_key_id(mle_security_components_t *sec_ptr)
00173 {
00174     mle_security_key_t *default_key = mle_service_security_key_entry_get(sec_ptr, true );
00175     if (default_key) {
00176         return default_key->key_id;
00177     }
00178     return 0;
00179 }
00180 
00181 uint8_t *mle_service_security_get_default_key(mle_security_components_t *sec_ptr)
00182 {
00183     mle_security_key_t *default_key = mle_service_security_key_entry_get(sec_ptr, true );
00184     if (default_key) {
00185         return default_key->aes_key;
00186     }
00187     return 0;
00188 }
00189 
00190 uint8_t mle_service_security_get_next_key_id(mle_security_components_t *sec_ptr)
00191 {
00192     mle_security_key_t *default_key = mle_service_security_key_entry_get(sec_ptr, false );
00193     if (default_key) {
00194         return default_key->key_id;
00195     }
00196     return 0;
00197 }
00198 
00199 uint8_t *mle_service_security_get_next_key(mle_security_components_t *sec_ptr)
00200 {
00201     mle_security_key_t *default_key = mle_service_security_key_entry_get(sec_ptr, false );
00202     if (default_key) {
00203         return default_key->aes_key;
00204     }
00205     return 0;
00206 }
00207 
00208 void mle_service_security_header_buf_init(mle_security_components_t *sec_ptr, mle_security_header_t *securityHeader, bool keySrcValid, uint32_t keySrc)
00209 {
00210     securityHeader->securityLevel = sec_ptr->sec_level;
00211     if (securityHeader->securityLevel) {
00212         securityHeader->frameCounter = mle_service_security_get_framecounter(sec_ptr,true);
00213         securityHeader->KeyIndex = mle_service_security_get_default_key_id(sec_ptr);
00214         if (keySrcValid) {
00215             securityHeader->KeyIdMode = MAC_KEY_ID_MODE_SRC4_IDX;
00216             common_write_32_bit(keySrc, securityHeader->Keysource);
00217         } else {
00218             securityHeader->KeyIdMode = MAC_KEY_ID_MODE_IDX;
00219         }
00220     }
00221 }
00222 
00223 uint8_t *mle_service_security_get_key(mle_security_header_t *securityHeader, mle_security_components_t *sec_ptr, int8_t interfaceId)
00224 {
00225     if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_SRC4_IDX) {
00226         if (sec_ptr->key_req) {
00227             uint32_t keySeq = common_read_32_bit(securityHeader->Keysource);
00228             return sec_ptr->key_req(interfaceId, securityHeader->KeyIndex, keySeq);
00229         }
00230 
00231     } else if (securityHeader->KeyIdMode == MAC_KEY_ID_MODE_IDX) {
00232 
00233         mle_security_key_t *key;
00234 
00235         key = mle_service_security_key_get(sec_ptr, securityHeader->KeyIndex);
00236         if (key) {
00237 
00238             if (key->pending_primary) {
00239                 //Switch Key's
00240                 mle_security_key_t *primary = mle_service_security_key_entry_get(sec_ptr, true);
00241                 if (!primary) {
00242                     return NULL;
00243                 }
00244                 primary->primary_key = false;
00245                 key->pending_primary = false;
00246                 key->primary_key = true;
00247                 sec_ptr->security_frame_counter = 0;
00248                 //Inform Mac
00249                 if (sec_ptr->security_notify) {
00250                     //Notify User
00251                     sec_ptr->security_notify(interfaceId,MLE_SEC_KEY_UPDATE_NOTIFY , securityHeader->KeyIndex);
00252                 }
00253 
00254             }
00255             return key->aes_key;
00256         } else {
00257             if (sec_ptr->security_notify) {
00258                 //Notify User
00259                 return sec_ptr->security_notify(interfaceId,MLE_SEC_UNKNOWN_KEY , securityHeader->KeyIndex);
00260             }
00261         }
00262     }
00263     return NULL;
00264 }
00265 
00266 bool mle_service_security_key_update_trig(uint8_t interface_id,mle_security_components_t *sec_ptr, uint8_t keyId)
00267 {
00268     mle_security_key_t *key = mle_service_security_key_get(sec_ptr, keyId);
00269     if (!key) {
00270         return false;
00271     }
00272 
00273     if (!key->pending_primary) {
00274         return false;
00275     }
00276 
00277     //Switch Key's
00278     mle_security_key_t *primary = mle_service_security_key_entry_get(sec_ptr, true);
00279     if (!primary) {
00280         return false;
00281     }
00282 
00283     mle_service_reset_frame_counters(interface_id);
00284     primary->primary_key = false;
00285     key->pending_primary = false;
00286     key->primary_key = true;
00287 
00288     return true;
00289 }
00290 
00291 bool mle_service_security_key_set(mle_security_components_t *sec_ptr, const uint8_t *key, uint8_t keyId, bool set_primary)
00292 {
00293     bool key_changed = false;
00294     if (!sec_ptr) {
00295         return false;
00296     }
00297 
00298     mle_security_key_t *key_entry = mle_service_security_key_entry_get(sec_ptr, set_primary);
00299     if (!key_entry ) {
00300         //Define first key
00301         key_entry = mle_service_security_key_get_free_entry(sec_ptr, set_primary);
00302         if (!key_entry ) {
00303             return false;
00304         }
00305         key_entry->key_valid = true;
00306     }
00307 
00308     if (memcmp(key_entry->aes_key,key,16) != 0) {
00309         key_changed = true;
00310     }
00311 
00312     key_entry->key_id = keyId;
00313     memcpy(key_entry->aes_key, key, 16);
00314     key_entry->primary_key = set_primary;
00315     key_entry->pending_primary = !set_primary;
00316 
00317     if (set_primary) {
00318         //Clean Old Pending if Primary is configured
00319         key_entry = mle_service_security_key_entry_get(sec_ptr, !set_primary);
00320         if (key_entry) {
00321             key_entry->key_valid = false;
00322         }
00323     }
00324 
00325     return key_changed;
00326 }
00327 
00328