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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ws_pae_nvm_data.c
00001 /* 00002 * Copyright (c) 2019, 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 #include "nsconfig.h" 00019 #include <string.h> 00020 #include "ns_types.h" 00021 #include "ns_list.h" 00022 #include "ns_trace.h" 00023 #include "nsdynmemLIB.h" 00024 #include "common_functions.h" 00025 #include "6LoWPAN/ws/ws_config.h" 00026 #include "ns_file_system.h" 00027 #include "Security/protocols/sec_prot_certs.h" 00028 #include "Security/protocols/sec_prot_keys.h" 00029 #include "6LoWPAN/ws/ws_pae_nvm_store.h" 00030 #include "6LoWPAN/ws/ws_pae_nvm_data.h" 00031 00032 #ifdef HAVE_WS 00033 00034 #define TRACE_GROUP "wsnv" 00035 00036 #define PAE_NVM_NW_INFO_TAG 1 00037 #define PAE_NVM_KEYS_TAG 2 00038 #define PAE_NVM_FRAME_COUNTER_TAG 3 00039 00040 // pan_id (2) + network name (33) + (GTK set (1) + GTK lifetime (4) + GTK (16)) * 4 00041 #define PAE_NVM_NW_INFO_LEN 2 + 33 + (1 + 4 + GTK_LEN) * GTK_NUM 00042 00043 // PTK EUI-64 set (1) + PTK EUI-64 (8) + PMK set (1) + PMK (32) + PMK replay counter (8) + PTK set (1) + PTK (48) 00044 #define PAE_NVM_KEYS_LEN 1 + 8 + 1 + PMK_LEN + 8 + 1 + PTK_LEN 00045 00046 // (frame counter set (1) + GTK (16) + frame counter (4)) * 4 00047 #define PAE_NVM_FRAME_COUNTER_LEN (1 + GTK_LEN + 4) * GTK_NUM 00048 00049 #define PAE_NVM_FIELD_NOT_SET 0 // Field is not present 00050 #define PAE_NVM_FIELD_SET 1 // Field is present 00051 00052 nvm_tlv_entry_t *ws_pae_buffer_allocate(void) 00053 { 00054 //Allocate worts case buffer 00055 return ns_dyn_mem_temporary_alloc(sizeof(nvm_tlv_entry_t) + PAE_NVM_NW_INFO_LEN); 00056 } 00057 00058 void ws_pae_nvm_store_nw_info_tlv_create(nvm_tlv_entry_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks) 00059 { 00060 00061 tlv_entry->tag = PAE_NVM_NW_INFO_TAG; 00062 tlv_entry->len = PAE_NVM_NW_INFO_LEN; 00063 00064 uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN; 00065 00066 tlv = common_write_16_bit(pan_id, tlv); 00067 00068 memset(tlv, 0, 33); 00069 strncpy((char *)tlv, nw_name, 32); 00070 tlv += 33; 00071 00072 for (uint8_t i = 0; i < GTK_NUM; i++) { 00073 if (sec_prot_keys_gtk_is_set(gtks, i)) { 00074 *tlv++ = PAE_NVM_FIELD_SET; // GTK is set 00075 uint32_t lifetime = sec_prot_keys_gtk_lifetime_get(gtks, i); 00076 tlv = common_write_32_bit(lifetime, tlv); 00077 00078 uint8_t *gtk = sec_prot_keys_gtk_get(gtks, i); 00079 memcpy(tlv, gtk, GTK_LEN); 00080 tlv += GTK_LEN; 00081 } else { 00082 *tlv++ = PAE_NVM_FIELD_NOT_SET; // GTK is not set 00083 memset(tlv, 0, 4 + GTK_LEN); 00084 tlv += 4 + GTK_LEN; 00085 } 00086 } 00087 00088 tr_debug("NVM NW_INFO write PAN ID %i name: %s", pan_id, nw_name); 00089 00090 } 00091 00092 int8_t ws_pae_nvm_store_nw_info_tlv_read(nvm_tlv_entry_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks) 00093 { 00094 if (!tlv_entry || !pan_id || !nw_name || !gtks) { 00095 return -1; 00096 } 00097 00098 if (tlv_entry->tag != PAE_NVM_NW_INFO_TAG || tlv_entry->len != PAE_NVM_NW_INFO_LEN) { 00099 return -1; 00100 } 00101 00102 uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN; 00103 00104 *pan_id = common_read_16_bit(tlv); 00105 tlv += 2; 00106 00107 memset(nw_name, 0, 33); 00108 strncpy(nw_name, (char *) tlv, 32); 00109 tlv += 33; 00110 00111 for (uint8_t i = 0; i < GTK_NUM; i++) { 00112 if (*tlv++ == PAE_NVM_FIELD_SET) { /* GTK is set */ 00113 uint32_t lifetime = common_read_32_bit(tlv); 00114 tlv += 4; 00115 sec_prot_keys_gtk_set(gtks, i, tlv, lifetime); 00116 tlv += GTK_LEN; 00117 } else { 00118 tlv += 4 + GTK_LEN; 00119 } 00120 } 00121 sec_prot_keys_gtks_updated_reset(gtks); 00122 00123 tr_debug("NVM NW_INFO read PAN ID %i name: %s", *pan_id, nw_name); 00124 00125 return 0; 00126 } 00127 00128 void ws_pae_nvm_store_keys_tlv_create(nvm_tlv_entry_t *tlv_entry, sec_prot_keys_t *sec_keys) 00129 { 00130 tlv_entry->tag = PAE_NVM_KEYS_TAG; 00131 tlv_entry->len = PAE_NVM_KEYS_LEN; 00132 00133 uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN; 00134 00135 uint8_t *eui_64 = sec_prot_keys_ptk_eui_64_get(sec_keys); 00136 if (eui_64) { 00137 *tlv++ = PAE_NVM_FIELD_SET; 00138 memcpy(tlv, eui_64, 8); 00139 } else { 00140 *tlv++ = PAE_NVM_FIELD_NOT_SET; 00141 memset(tlv, 0, 8); 00142 } 00143 tlv += 8; 00144 00145 uint8_t *pmk = sec_prot_keys_pmk_get(sec_keys); 00146 if (pmk) { 00147 *tlv++ = PAE_NVM_FIELD_SET; 00148 memcpy(tlv, pmk, PMK_LEN); 00149 } else { 00150 *tlv++ = PAE_NVM_FIELD_NOT_SET; 00151 memset(tlv, 0, PMK_LEN); 00152 } 00153 tlv += PMK_LEN; 00154 00155 uint64_t counter = sec_prot_keys_pmk_replay_cnt_get(sec_keys); 00156 tlv = common_write_64_bit(counter, tlv); 00157 00158 uint8_t *ptk = sec_prot_keys_ptk_get(sec_keys); 00159 if (ptk) { 00160 *tlv++ = PAE_NVM_FIELD_SET; 00161 memcpy(tlv, ptk, PTK_LEN); 00162 } else { 00163 *tlv++ = PAE_NVM_FIELD_NOT_SET; 00164 memset(tlv, 0, PTK_LEN); 00165 } 00166 tlv += PTK_LEN; 00167 00168 tr_debug("NVM KEYS write"); 00169 00170 } 00171 00172 int8_t ws_pae_nvm_store_keys_tlv_read(nvm_tlv_entry_t *tlv_entry, sec_prot_keys_t *sec_keys) 00173 { 00174 if (!tlv_entry || !sec_keys) { 00175 return -1; 00176 } 00177 00178 if (tlv_entry->tag != PAE_NVM_KEYS_TAG || tlv_entry->len != PAE_NVM_KEYS_LEN) { 00179 return -1; 00180 } 00181 00182 uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN; 00183 00184 // EUI-64 set */ 00185 if (*tlv++ == PAE_NVM_FIELD_SET) { 00186 sec_prot_keys_ptk_eui_64_write(sec_keys, tlv); 00187 } 00188 tlv += 8; 00189 00190 // PMK set 00191 if (*tlv++ == PAE_NVM_FIELD_SET) { 00192 sec_prot_keys_pmk_write(sec_keys, tlv); 00193 } 00194 tlv += PMK_LEN; 00195 00196 uint64_t counter = common_read_64_bit(tlv); 00197 tlv += 8; 00198 sec_prot_keys_pmk_replay_cnt_set(sec_keys, counter); 00199 00200 // PTK set 00201 if (*tlv++ == PAE_NVM_FIELD_SET) { 00202 sec_prot_keys_ptk_write(sec_keys, tlv); 00203 } 00204 00205 tlv += PTK_LEN; 00206 00207 sec_prot_keys_updated_reset(sec_keys); 00208 00209 tr_debug("NVM KEYS read"); 00210 00211 return 0; 00212 } 00213 00214 void ws_pae_nvm_store_frame_counter_tlv_create(nvm_tlv_entry_t *tlv_entry, frame_counters_t *counters) 00215 { 00216 tlv_entry->tag = PAE_NVM_FRAME_COUNTER_TAG; 00217 tlv_entry->len = PAE_NVM_FRAME_COUNTER_LEN; 00218 00219 uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN; 00220 00221 for (uint8_t index = 0; index < GTK_NUM; index++) { 00222 if (!counters->counter[index].set) { 00223 *tlv++ = PAE_NVM_FIELD_NOT_SET; 00224 memset(tlv, 0, GTK_LEN + 4); 00225 tlv += GTK_LEN + 4; 00226 continue; 00227 } 00228 *tlv++ = PAE_NVM_FIELD_SET; 00229 memcpy(tlv, counters->counter[index].gtk, GTK_LEN); 00230 tlv += GTK_LEN; 00231 tlv = common_write_32_bit(counters->counter[index].frame_counter, tlv); 00232 } 00233 00234 tr_debug("NVM FRAME COUNTER write"); 00235 } 00236 00237 int8_t ws_pae_nvm_store_frame_counter_tlv_read(nvm_tlv_entry_t *tlv_entry, frame_counters_t *counters) 00238 { 00239 if (!tlv_entry || !counters) { 00240 return -1; 00241 } 00242 00243 if (tlv_entry->tag != PAE_NVM_FRAME_COUNTER_TAG || tlv_entry->len != PAE_NVM_FRAME_COUNTER_LEN) { 00244 return -1; 00245 } 00246 00247 uint8_t *tlv = ((uint8_t *) &tlv_entry->tag) + NVM_TLV_FIXED_LEN; 00248 00249 for (uint8_t index = 0; index < GTK_NUM; index++) { 00250 // Frame counter not set 00251 if (*tlv++ == PAE_NVM_FIELD_NOT_SET) { 00252 counters->counter[index].set = false; 00253 tlv += GTK_LEN + 4; 00254 continue; 00255 } 00256 // Frame counter is set, read GTK key and counter values 00257 counters->counter[index].set = true; 00258 memcpy(counters->counter[index].gtk, tlv, GTK_LEN); 00259 tlv += GTK_LEN; 00260 counters->counter[index].frame_counter = common_read_32_bit(tlv); 00261 tlv += 4; 00262 } 00263 00264 tr_debug("NVM FRAME COUNTER read"); 00265 00266 return 0; 00267 } 00268 00269 #endif /* HAVE_WS */ 00270
Generated on Tue Jul 12 2022 13:55:04 by
