Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Tue Jul 12 2022 14:24:28 by
