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
kde_helper.c
00001 /* 00002 * Copyright (c) 2018-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 "ns_types.h" 00020 #include "eventOS_event.h" 00021 #include "ns_trace.h" 00022 #include "string.h" 00023 #include "common_functions.h" 00024 #include "Security/eapol/kde_helper.h" 00025 00026 #ifdef HAVE_WS 00027 00028 #define TRACE_GROUP "kdeh" 00029 00030 #define IEEE_802_11_OUI ieee_802_11_oui 00031 #define WISUN_OUI wisun_oui 00032 00033 const uint8_t ieee_802_11_oui[3] = {0x00, 0x0F, 0xAC}; 00034 const uint8_t wisun_oui[3] = {0x0C, 0x5A, 0x9E}; 00035 00036 #define KDE_TYPE 0xdd 00037 00038 // IEEE 802.11 00039 #define KDE_GTK 0x01 00040 #define KDE_PMKID 0x04 00041 #define KDE_LIFETIME 0x07 00042 // Wi-Sun 00043 #define KDE_PTKID 0x01 00044 #define KDE_GTKL 0x02 00045 00046 #define GTK_LEN 16 00047 #define PMKID_LEN 16 00048 #define PTKID_LEN 16 00049 00050 #define KDE_MIN_LEN 6 00051 #define KDE_FIXED_LEN 2 00052 00053 #define KDE_PADDED_MIN_LEN 16 00054 00055 #define KDE_TYPE_INDEX 0 00056 #define KDE_LENGTH_INDEX 1 00057 #define KDE_OUI1_INDEX 2 00058 #define KDE_OUI2_INDEX 3 00059 #define KDE_OUI3_INDEX 4 00060 #define KDE_DATA_TYPE_INDEX 5 00061 #define KDE_DATA_INDEX 6 00062 00063 /* 00064 From IEEE 802.11 chapter 11.6.2 EAPOL-Key frames 00065 00066 If the Encrypted Key Data subfield (of the Key Information field) is 1, 00067 the entire Key Data field shall be encrypted. If the Key Data field 00068 uses the NIST AES key wrap, then the Key Data field shall be padded before 00069 encrypting if the key data length is less than 16 octets or if it is not 00070 a multiple of 8. 00071 The padding consists of appending a single octet 0xdd followed by zero 00072 or more 0x00 octets. When processing a received EAPOL-Key message, the 00073 receiver shall ignore this trailing padding. 00074 */ 00075 uint16_t kde_padded_length_calc(uint16_t kde_length) 00076 { 00077 if (kde_length < KDE_PADDED_MIN_LEN) { 00078 return KDE_PADDED_MIN_LEN; 00079 } 00080 00081 return ((kde_length + 7) / 8) * 8; 00082 } 00083 00084 void kde_padding_write(uint8_t *start_ptr, uint8_t *end_ptr) 00085 { 00086 uint8_t padding = 0xdd; 00087 00088 while (start_ptr < end_ptr) { 00089 *start_ptr++ = padding; 00090 padding = 0x00; 00091 } 00092 } 00093 00094 static uint8_t *kde_header_write(uint8_t *ptr, const uint8_t *oui, uint8_t data_type, uint8_t data_length) 00095 { 00096 *ptr++ = KDE_TYPE; 00097 *ptr++ = data_length - KDE_FIXED_LEN; 00098 *ptr++ = oui[0]; 00099 *ptr++ = oui[1]; 00100 *ptr++ = oui[2]; 00101 *ptr++ = data_type; 00102 00103 return ptr; 00104 } 00105 00106 static const uint8_t *kde_search(const uint8_t *ptr, uint16_t len, const uint8_t *oui, uint8_t data_type, uint16_t kde_min_len) 00107 { 00108 while (len >= KDE_MIN_LEN) { 00109 uint16_t kde_len = ptr[1] + KDE_FIXED_LEN; 00110 00111 // For the type 0xdd the length shall be at least 6 */ 00112 if ((ptr[KDE_TYPE_INDEX] == 0xdd && kde_len < KDE_MIN_LEN) || kde_len > len) { 00113 return NULL; 00114 } 00115 00116 if (kde_len >= kde_min_len && ptr[KDE_OUI1_INDEX] == oui[0] && ptr[KDE_OUI2_INDEX] == oui[1] 00117 && ptr[KDE_OUI3_INDEX] == oui[2] && ptr[KDE_DATA_TYPE_INDEX] == data_type) { 00118 return &ptr[KDE_DATA_INDEX]; 00119 } 00120 00121 if (len > kde_len) { 00122 len -= kde_len; 00123 ptr += kde_len; 00124 } else { 00125 return NULL; 00126 } 00127 } 00128 00129 return NULL; 00130 } 00131 00132 uint8_t *kde_gtk_write(uint8_t *ptr, uint8_t key_id, const uint8_t *gtk) 00133 { 00134 ptr = kde_header_write(ptr, IEEE_802_11_OUI, KDE_GTK, KDE_GTK_LEN); 00135 00136 // bits 0-1: keyid (0,1,2, or 3), bit 2: Tx, other: reserved (0) 00137 *ptr++ = key_id; 00138 *ptr++ = 0x00; // reserved 00139 memcpy(ptr, gtk, GTK_LEN); 00140 ptr += GTK_LEN; 00141 00142 return ptr; 00143 } 00144 00145 uint8_t *kde_pmkid_write(uint8_t *ptr, const uint8_t *pmkid) 00146 { 00147 ptr = kde_header_write(ptr, IEEE_802_11_OUI, KDE_PMKID, KDE_PMKID_LEN); 00148 00149 memcpy(ptr, pmkid, PMKID_LEN); 00150 ptr += PMKID_LEN; 00151 00152 return ptr; 00153 } 00154 00155 uint8_t *kde_ptkid_write(uint8_t *ptr, const uint8_t *ptkid) 00156 { 00157 ptr = kde_header_write(ptr, WISUN_OUI, KDE_PTKID, KDE_PTKID_LEN); 00158 00159 memcpy(ptr, ptkid, PTKID_LEN); 00160 ptr += PTKID_LEN; 00161 00162 return ptr; 00163 } 00164 00165 uint8_t *kde_lifetime_write(uint8_t *ptr, uint32_t lifetime) 00166 { 00167 ptr = kde_header_write(ptr, IEEE_802_11_OUI, KDE_LIFETIME, KDE_LIFETIME_LEN); 00168 ptr = common_write_32_bit(lifetime, ptr); 00169 00170 return ptr; 00171 } 00172 00173 uint8_t *kde_gtkl_write(uint8_t *ptr, uint8_t gtkl) 00174 { 00175 ptr = kde_header_write(ptr, WISUN_OUI, KDE_GTKL, KDE_GTKL_LEN); 00176 *ptr++ = gtkl; 00177 00178 return ptr; 00179 } 00180 00181 int8_t kde_gtk_read(const uint8_t *ptr, uint16_t len, uint8_t *key_id, uint8_t *gtk) 00182 { 00183 ptr = kde_search(ptr, len, IEEE_802_11_OUI, KDE_GTK, KDE_GTK_LEN); 00184 if (ptr == NULL) { 00185 return -1; 00186 } 00187 00188 *key_id = *ptr++ & 0x03; 00189 ptr++; 00190 memcpy(gtk, ptr, GTK_LEN); 00191 00192 return 0; 00193 } 00194 00195 int8_t kde_pmkid_read(const uint8_t *ptr, uint16_t len, uint8_t *pmkid) 00196 { 00197 ptr = kde_search(ptr, len, IEEE_802_11_OUI, KDE_PMKID, KDE_PMKID_LEN); 00198 if (ptr == NULL) { 00199 return -1; 00200 } 00201 00202 memcpy(pmkid, ptr, PMKID_LEN); 00203 00204 return 0; 00205 } 00206 00207 int8_t kde_ptkid_read(const uint8_t *ptr, uint16_t len, uint8_t *ptkid) 00208 { 00209 ptr = kde_search(ptr, len, WISUN_OUI, KDE_PTKID, KDE_PTKID_LEN); 00210 if (ptr == NULL) { 00211 return -1; 00212 } 00213 00214 memcpy(ptkid, ptr, PTKID_LEN); 00215 00216 return 0; 00217 } 00218 00219 int8_t kde_lifetime_read(const uint8_t *ptr, uint16_t len, uint32_t *lifetime) 00220 { 00221 ptr = kde_search(ptr, len, IEEE_802_11_OUI, KDE_LIFETIME, KDE_LIFETIME_LEN); 00222 if (ptr == NULL) { 00223 return -1; 00224 } 00225 00226 *lifetime = common_read_32_bit(ptr); 00227 00228 return 0; 00229 } 00230 00231 int8_t kde_gtkl_read(const uint8_t *ptr, uint16_t len, uint8_t *gtkl) 00232 { 00233 ptr = kde_search(ptr, len, WISUN_OUI, KDE_GTKL, KDE_GTKL_LEN); 00234 if (ptr == NULL) { 00235 return -1; 00236 } 00237 00238 *gtkl = *ptr; 00239 00240 return 0; 00241 } 00242 00243 #endif 00244
Generated on Tue Jul 12 2022 13:54:25 by
