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
eapol_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 00019 00020 #include "nsconfig.h" 00021 00022 #include "ns_types.h" 00023 #include "eventOS_event.h" 00024 #include "ns_trace.h" 00025 #include "string.h" 00026 #include "common_functions.h" 00027 #include "Security/PANA/pana_eap_header.h" 00028 #include "Security/eapol/eapol_helper.h" 00029 00030 #ifdef HAVE_WS 00031 00032 #define KEY_INFO_VERSION_BIT_MASK 0x0007 00033 #define KEY_INFO_VERSION_BIT_SHIFT 0 00034 #define KEY_INFO_KEY_TYPE_BIT_MASK 0x0008 00035 #define KEY_INFO_KEY_TYPE_BIT_SHIFT 3 00036 #define KEY_INFO_INSTALL_BIT_MASK 0x0040 00037 #define KEY_INFO_INSTALL_BIT_SHIFT 6 00038 #define KEY_INFO_ACK_BIT_MASK 0x0080 00039 #define KEY_INFO_ACK_BIT_SHIFT 7 00040 #define KEY_INFO_MIC_MASK 0x0100 00041 #define KEY_INFO_MIC_SHIFT 8 00042 #define KEY_INFO_SECURE_MASK 0x0200 00043 #define KEY_INFO_SECURE_SHIFT 9 00044 #define KEY_INFO_ERROR_MASK 0x0400 00045 #define KEY_INFO_ERROR_SHIFT 10 00046 #define KEY_INFO_REQUEST_MASK 0x0800 00047 #define KEY_INFO_REQUEST_SHIFT 11 00048 #define KEY_INFO_ENC_KEY_DATA_MASK 0x1000 00049 #define KEY_INFO_ENC_KEY_DATA_SHIFT 12 00050 #define KEY_INFO_SMK_MASK 0x2000 00051 #define KEY_INFO_SMK_SHIFT 13 00052 00053 static uint8_t *eapol_key_information_write(eapol_key_information_t *key_information, uint8_t *ptr) 00054 { 00055 uint16_t key_info = 0; 00056 key_info |= (key_information->description_version << KEY_INFO_VERSION_BIT_SHIFT); 00057 key_info |= (key_information->pairwise_key << KEY_INFO_KEY_TYPE_BIT_SHIFT); 00058 key_info |= (key_information->install << KEY_INFO_INSTALL_BIT_SHIFT); 00059 key_info |= (key_information->key_ack << KEY_INFO_ACK_BIT_SHIFT); 00060 key_info |= (key_information->key_mic << KEY_INFO_MIC_SHIFT); 00061 key_info |= (key_information->secured_key_frame << KEY_INFO_SECURE_SHIFT); 00062 key_info |= (key_information->error << KEY_INFO_ERROR_SHIFT); 00063 key_info |= (key_information->request << KEY_INFO_REQUEST_SHIFT); 00064 key_info |= (key_information->encrypted_key_data << KEY_INFO_ENC_KEY_DATA_SHIFT); 00065 key_info |= (key_information->smk_handshake << KEY_INFO_SMK_SHIFT); 00066 return common_write_16_bit(key_info, ptr); 00067 } 00068 00069 static uint8_t *eapol_key_information_read(eapol_key_information_t *key_information, uint8_t *ptr) 00070 { 00071 uint16_t key_info = common_read_16_bit(ptr); 00072 key_information->description_version = ((key_info & KEY_INFO_VERSION_BIT_MASK) >> KEY_INFO_VERSION_BIT_SHIFT); 00073 key_information->pairwise_key = ((key_info & KEY_INFO_KEY_TYPE_BIT_MASK) >> KEY_INFO_KEY_TYPE_BIT_SHIFT); 00074 key_information->install = ((key_info & KEY_INFO_INSTALL_BIT_MASK) >> KEY_INFO_INSTALL_BIT_SHIFT); 00075 key_information->key_ack = ((key_info & KEY_INFO_ACK_BIT_MASK) >> KEY_INFO_ACK_BIT_SHIFT); 00076 key_information->key_mic = ((key_info & KEY_INFO_MIC_MASK) >> KEY_INFO_MIC_SHIFT); 00077 key_information->secured_key_frame = ((key_info & KEY_INFO_SECURE_MASK) >> KEY_INFO_SECURE_SHIFT); 00078 key_information->error = ((key_info & KEY_INFO_ERROR_MASK) >> KEY_INFO_ERROR_SHIFT); 00079 key_information->request = ((key_info & KEY_INFO_REQUEST_MASK) >> KEY_INFO_REQUEST_SHIFT); 00080 key_information->encrypted_key_data = ((key_info & KEY_INFO_ENC_KEY_DATA_MASK) >> KEY_INFO_ENC_KEY_DATA_SHIFT); 00081 key_information->smk_handshake = ((key_info & KEY_INFO_SMK_MASK) >> KEY_INFO_SMK_SHIFT); 00082 return ptr + 2; 00083 } 00084 00085 00086 static bool eapol_parse_eap_packet(eapol_pdu_t *eapol_pdu) 00087 { 00088 return eap_header_parse(eapol_pdu->packet_body, eapol_pdu->packet_length, &eapol_pdu->msg.eap); 00089 } 00090 00091 00092 static bool eapol_parse_key_packet(eapol_pdu_t *eapol_pdu) 00093 { 00094 if (eapol_pdu->packet_length < EAPOL_KEY_FRAME_BASE_SIZE) { 00095 return false; 00096 } 00097 uint8_t *ptr = eapol_pdu->packet_body; 00098 eapol_key_frame_t *key_frame = &eapol_pdu->msg.key; 00099 key_frame->key_description = *ptr++; 00100 if (key_frame->key_description != EAPOL_RSN_KEY_DESCRIPTION) { 00101 return false; 00102 } 00103 ptr = eapol_key_information_read(&key_frame->key_information, ptr); 00104 if (key_frame->key_information.description_version != KEY_DESCRIPTION_HMAC_SHA1_MIC_AES_ENC) { 00105 return false; 00106 } 00107 key_frame->key_length = common_read_16_bit(ptr); 00108 ptr += 2; 00109 00110 key_frame->replay_counter = common_read_64_bit(ptr); 00111 ptr += 8; 00112 00113 key_frame->key_nonce = ptr; 00114 ptr += 32; 00115 00116 key_frame->key_iv = ptr; 00117 ptr += 16; 00118 00119 key_frame->key_rsc = ptr; 00120 ptr += 16; //Skip 8 byte RSC + RESERVED 8 00121 00122 key_frame->key_mic = ptr; 00123 ptr += 16; 00124 00125 key_frame->key_data_length = common_read_16_bit(ptr); 00126 ptr += 2; 00127 key_frame->key_data = ptr; 00128 if (key_frame->key_data_length > (eapol_pdu->packet_length - EAPOL_KEY_FRAME_BASE_SIZE)) { 00129 return false; 00130 } 00131 00132 return true; 00133 00134 } 00135 00136 void eapol_write_key_packet_mic(uint8_t *eapol_pdu, uint8_t *mic) 00137 { 00138 if (mic) { 00139 memcpy(&eapol_pdu[81], mic, 16); 00140 } else { 00141 memset(&eapol_pdu[81], 0, 16); 00142 } 00143 } 00144 00145 bool eapol_parse_pdu_header(uint8_t *ptr, uint16_t data_length, eapol_pdu_t *eapol_pdu) 00146 { 00147 //Validate MIN length 00148 if (data_length < EAPOL_BASE_LENGTH) { 00149 return false; 00150 } 00151 //Validate Protocol version 00152 uint8_t protocol = *ptr++; 00153 if (protocol != EAPOL_PROTOCOL_VERSION) { 00154 return false; 00155 } 00156 eapol_pdu->packet_type = *ptr++; 00157 eapol_pdu->packet_length = common_read_16_bit(ptr); 00158 ptr += 2; 00159 //Validate Body Length 00160 if (eapol_pdu->packet_length > data_length - EAPOL_BASE_LENGTH) { 00161 return false; 00162 } 00163 eapol_pdu->packet_body = ptr; 00164 00165 if (eapol_pdu->packet_type == EAPOL_EAP_TYPE) { 00166 return eapol_parse_eap_packet(eapol_pdu); 00167 } else if (eapol_pdu->packet_type == EAPOL_KEY_TYPE) { 00168 return eapol_parse_key_packet(eapol_pdu); 00169 } else { 00170 return false; 00171 } 00172 00173 } 00174 00175 uint8_t *eapol_write_pdu_frame(uint8_t *ptr, eapol_pdu_t *eapol_pdu) 00176 { 00177 *ptr++ = EAPOL_PROTOCOL_VERSION; 00178 *ptr++ = eapol_pdu->packet_type; 00179 ptr = common_write_16_bit(eapol_pdu->packet_length, ptr); 00180 eapol_pdu->packet_body = ptr; 00181 00182 if (eapol_pdu->packet_type == EAPOL_EAP_TYPE) { 00183 eap_header_t *eap_header = &eapol_pdu->msg.eap; 00184 ptr = eap_header_build(ptr, eap_header->length, eap_header->eap_code, eap_header->id_seq, eap_header->type); 00185 memcpy(ptr, eap_header->data_ptr, eap_header->length - (ptr - eapol_pdu->packet_body)); 00186 ptr += eap_header->length - (ptr - eapol_pdu->packet_body); 00187 00188 } else if (eapol_pdu->packet_type == EAPOL_KEY_TYPE) { 00189 eapol_key_frame_t *key_frame = &eapol_pdu->msg.key; 00190 *ptr++ = key_frame->key_description; 00191 ptr = eapol_key_information_write(&key_frame->key_information, ptr); 00192 ptr = common_write_16_bit(key_frame->key_length, ptr); 00193 ptr = common_write_64_bit(key_frame->replay_counter, ptr); 00194 00195 if (key_frame->key_nonce) { 00196 memcpy(ptr, key_frame->key_nonce, 32); 00197 } else { 00198 memset(ptr, 0, 32); 00199 } 00200 ptr += 32; 00201 00202 if (key_frame->key_iv) { 00203 memcpy(ptr, key_frame->key_iv, 16); 00204 } else { 00205 memset(ptr, 0, 16); 00206 } 00207 ptr += 16; 00208 00209 if (key_frame->key_rsc) { 00210 memcpy(ptr, key_frame->key_rsc, 8); 00211 } else { 00212 memset(ptr, 0, 8); 00213 } 00214 ptr += 8; 00215 00216 //Reserved 8bytes 00217 memset(ptr, 0, 8); 00218 ptr += 8; 00219 00220 if (key_frame->key_mic && key_frame->key_information.key_mic) { 00221 memcpy(ptr, key_frame->key_mic, 16); 00222 } else { 00223 memset(ptr, 0, 16); 00224 } 00225 ptr += 16; 00226 ptr = common_write_16_bit(key_frame->key_data_length, ptr); 00227 if (key_frame->key_data_length && key_frame->key_data) { 00228 memcpy(ptr, key_frame->key_data, key_frame->key_data_length); 00229 ptr += key_frame->key_data_length; 00230 } 00231 } 00232 00233 return ptr; 00234 } 00235 00236 00237 00238 uint16_t eapol_pdu_eap_frame_init(eapol_pdu_t *eapol_pdu, uint8_t eap_code, uint8_t id_seq, uint8_t type, uint16_t data_length, uint8_t *data_ptr) 00239 { 00240 memset(eapol_pdu, 0, sizeof(eapol_pdu_t)); 00241 00242 eapol_pdu->packet_type = EAPOL_EAP_TYPE; 00243 eapol_pdu->packet_length = data_length; 00244 eapol_pdu->msg.eap.eap_code = eap_code; 00245 eapol_pdu->msg.eap.data_ptr = data_ptr; 00246 eapol_pdu->msg.eap.length = data_length; 00247 eapol_pdu->msg.eap.id_seq = id_seq; 00248 eapol_pdu->msg.eap.type = type; 00249 00250 if (eap_code == EAP_REQ || eap_code == EAP_RESPONSE) { 00251 eapol_pdu->packet_body += 5; 00252 eapol_pdu->msg.eap.length++; // Add space for type 00253 eapol_pdu->packet_length++; 00254 } else { 00255 eapol_pdu->packet_body += 4; 00256 } 00257 00258 return eapol_pdu_total_length(eapol_pdu); 00259 00260 } 00261 00262 uint16_t eapol_pdu_key_frame_init(eapol_pdu_t *eapol_pdu, uint16_t data_length, uint8_t *data_ptr) 00263 { 00264 memset(eapol_pdu, 0, sizeof(eapol_pdu_t)); 00265 00266 eapol_pdu->packet_type = EAPOL_KEY_TYPE; 00267 eapol_pdu->packet_length = data_length + EAPOL_KEY_FRAME_BASE_SIZE; 00268 eapol_pdu->msg.key.key_data = data_ptr; 00269 eapol_pdu->msg.key.key_description = EAPOL_RSN_KEY_DESCRIPTION; 00270 eapol_pdu->msg.key.key_data_length = data_length; 00271 eapol_pdu->msg.key.key_information.description_version = KEY_DESCRIPTION_HMAC_SHA1_MIC_AES_ENC; 00272 00273 return eapol_pdu_total_length(eapol_pdu); 00274 00275 } 00276 00277 uint8_t eapol_pdu_key_mask_get(eapol_pdu_t *eapol_pdu) 00278 { 00279 uint8_t key_mask = 0; 00280 00281 if (eapol_pdu->msg.key.key_information.install) { 00282 key_mask |= KEY_INFO_INSTALL; 00283 } 00284 if (eapol_pdu->msg.key.key_information.key_ack) { 00285 key_mask |= KEY_INFO_KEY_ACK; 00286 } 00287 if (eapol_pdu->msg.key.key_information.key_mic) { 00288 key_mask |= KEY_INFO_KEY_MIC; 00289 } 00290 if (eapol_pdu->msg.key.key_information.secured_key_frame) { 00291 key_mask |= KEY_INFO_SECURED_KEY_FRAME; 00292 } 00293 00294 return key_mask; 00295 } 00296 00297 #endif 00298
Generated on Tue Jul 12 2022 13:54:17 by
