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: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
eap_protocol.c
00001 /* 00002 * Copyright (c) 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 #include "nsconfig.h" 00020 00021 #include "ns_types.h" 00022 #include "eventOS_event.h" 00023 #include "ns_trace.h" 00024 #include "string.h" 00025 #include "Core/include/socket.h" 00026 #include "NWK_INTERFACE/Include/protocol.h" 00027 #include "6LoWPAN/Bootstraps/protocol_6lowpan.h" 00028 #include "6LoWPAN/Bootstraps/protocol_6lowpan_bootstrap.h" 00029 #ifdef ECC 00030 #include "libX509_V3.h" 00031 #include "ecc.h" 00032 #endif 00033 #include "Security/Common/sec_lib.h" 00034 #include "net_nvm_api.h" 00035 #include "Security/PANA/pana.h" 00036 00037 #include "common_functions.h" 00038 #include "Security/PANA/pana_eap_header.h" 00039 #ifdef PANA 00040 00041 #define TRACE_GROUP "eap" 00042 00043 const uint8_t EAP_ANYMOUS[9] = {'a', 'n', 'o', 'n', 'y', 'm', 'o', 'u', 's'}; 00044 00045 static buffer_t *eap_common_headroom_get_to_buffer(buffer_t *buf, uint16_t header_size) 00046 { 00047 if ((buf = buffer_headroom(buf, header_size)) == 0) { 00048 return NULL; 00049 } 00050 buffer_data_reserve_header(buf, header_size); 00051 return buf; 00052 } 00053 00054 void pana_eap_identity_build(buffer_t *buf, sec_suite_t *suite) 00055 { 00056 uint8_t *ptr; 00057 uint8_t eap_code; 00058 buf->buf_ptr = 0; 00059 const uint8_t *nonce_ptr; 00060 if (suite->pana_session.user_server) { 00061 buf->buf_end = 0; 00062 eap_code = EAP_REQ; 00063 nonce_ptr = suite->pana_session.pana_heap->agent_nonce; 00064 } else { 00065 00066 buf->buf_end = 9; 00067 ptr = buf->buf ; 00068 memcpy(ptr, EAP_ANYMOUS, 9); 00069 eap_code = EAP_RESPONSE; 00070 nonce_ptr = suite->pana_session.pana_heap->client_nonce; 00071 } 00072 00073 buf = eap_common_headroom_get_to_buffer(buf, eap_header_size(eap_code)); 00074 if (!buf) { 00075 return; 00076 } 00077 00078 eap_header_build(buffer_data_pointer(buf), buffer_data_length(buf), eap_code, suite->pana_session.eap_id_seq, EAP_IDENTITY); 00079 00080 pana_eap_payload_down(buf, nonce_ptr, suite); 00081 tr_warn("TX EAP Identity!"); 00082 } 00083 00084 void pana_eap_tls_start_build(buffer_t *buf, sec_suite_t *suite) 00085 { 00086 buf->buf_ptr = 0; 00087 buf->buf_end = 0; 00088 if (suite->tls_session->tls_heap) { 00089 tls_heap_t *tls_heap = suite->tls_session->tls_heap; 00090 tls_heap->tls_handshake_h_len = 0; 00091 } 00092 00093 uint8_t header_size = eap_header_size(EAP_REQ); 00094 header_size += eap_tls_header_size(EAP_TLS_START); 00095 00096 buf = eap_common_headroom_get_to_buffer(buf, header_size); 00097 if (!buf) { 00098 return; 00099 } 00100 00101 uint8_t *ptr = eap_header_build(buffer_data_pointer(buf), buffer_data_length(buf),EAP_REQ, suite->pana_session.eap_id_seq, EAP_TLS); 00102 00103 eap_tls_header_build(ptr, EAP_TLS_START, 0); 00104 00105 pana_eap_payload_down(buf, NULL, suite); 00106 00107 } 00108 00109 00110 void pana_eap_tls_finnish_build(buffer_t *buf, sec_suite_t *suite) 00111 { 00112 buffer_data_clear(buf); 00113 uint8_t eap_code; 00114 if (suite->state == TLS_ALERT) { 00115 eap_code = EAP_FAILURE; 00116 } else { 00117 eap_code = EAP_RESPONSE; 00118 } 00119 00120 00121 uint8_t header_size = eap_header_size(eap_code); 00122 header_size += eap_tls_header_size(0); 00123 00124 buf = eap_common_headroom_get_to_buffer(buf, header_size); 00125 if (!buf) { 00126 return; 00127 } 00128 00129 uint8_t *ptr = eap_header_build(buffer_data_pointer(buf), buffer_data_length(buf),eap_code, suite->pana_session.eap_id_seq, EAP_TLS); 00130 00131 eap_tls_header_build(ptr, 0, 0); 00132 00133 pana_eap_payload_down(buf, NULL, suite); 00134 } 00135 00136 bool pana_eap_frag_re_tx(sec_suite_t *suite) 00137 { 00138 buffer_t *f_buf; 00139 if (suite->pana_session.eap_assy_buf) { 00140 buffer_t *buf = 0; 00141 f_buf = buffer_get(suite->pana_session.last_assy_size + 50); 00142 buf = suite->pana_session.eap_assy_buf; 00143 if (f_buf) { 00144 memcpy(buffer_data_pointer(f_buf), buffer_data_pointer(buf) + suite->pana_session.assy_off_set, suite->pana_session.last_assy_size); 00145 buffer_data_length_set(f_buf, suite->pana_session.last_assy_size); 00146 goto success_push; 00147 } 00148 } else if (suite->pana_session.eap_frag_buf) { 00149 f_buf = buffer_get(127); 00150 if (f_buf) { 00151 00152 //tr_debug("EAP assembly re REQ timer"); 00153 f_buf->buf_ptr = f_buf->buf_end ; 00154 goto success_push; 00155 } 00156 } 00157 return false; 00158 success_push: 00159 f_buf->interface = suite->interface; 00160 memcpy(f_buf->dst_sa .address , suite->session_address, 16); 00161 f_buf->src_sa .addr_type = ADDR_NONE ; 00162 pana_eap_down(f_buf, suite); 00163 return true; 00164 } 00165 00166 buffer_t *eap_down(buffer_t *buf, sec_suite_t *suite) 00167 { 00168 //tr_debug("EAP Down"); 00169 uint16_t tls_payload_len = 0; 00170 uint8_t eap_code; 00171 uint8_t eap_tls_flags = 0; 00172 tls_payload_len = buffer_data_length(buf); 00173 if (tls_payload_len > EAP_MTU_SIZE) { 00174 //Check Fragmentation 00175 if (suite->pana_session.assy_length) { 00176 tr_debug("Already Fragmentation"); 00177 buffer_free(buf); 00178 buf = (buffer_t *)0; 00179 return buf; 00180 } else { 00181 pana_lib_parameters_s *parameters = pana_parameters_get(); 00182 00183 buffer_t *f_buf = buffer_get(parameters->EAP_FRAGMENT_SIZE + 50); 00184 buf->seq = suite->pana_session.eap_id_seq; 00185 suite->pana_session.eap_assy_buf = buf; 00186 suite->pana_session.assy_length = tls_payload_len; 00187 suite->pana_session.assy_off_set = 0; 00188 suite->pana_session.last_assy_size = parameters->EAP_FRAGMENT_SIZE; 00189 if (suite->pana_session.user_server) { 00190 //tr_debug("Set Re Tx Timer"); 00191 pana_timeout_timer_set(suite, suite->state); 00192 } else { 00193 sec_set_auth_timeout(suite,TLS_KEY_CHANGE); 00194 } 00195 if (f_buf) { 00196 f_buf->interface = suite->interface; 00197 eap_tls_flags = EAP_TLS_FRAGMENT_LENGTH | EAP_TLS_MORE_FRAGMENTS; 00198 memcpy(buffer_data_pointer(f_buf), buffer_data_pointer(buf), parameters->EAP_FRAGMENT_SIZE); 00199 memcpy(f_buf->dst_sa .address , buf->src_sa .address , 16); 00200 buf->src_sa .addr_type = ADDR_NONE ; 00201 f_buf->src_sa .addr_type = ADDR_NONE ; 00202 buffer_data_length_set(f_buf, parameters->EAP_FRAGMENT_SIZE); 00203 buf = f_buf; 00204 00205 } else { 00206 return NULL; 00207 } 00208 } 00209 } else { 00210 if (suite->pana_session.assy_length) { 00211 if (suite->pana_session.assy_length > (suite->pana_session.assy_off_set + suite->pana_session.last_assy_size)) { 00212 eap_tls_flags = EAP_TLS_MORE_FRAGMENTS; 00213 if (suite->pana_session.assy_off_set == 0) { 00214 eap_tls_flags |= EAP_TLS_FRAGMENT_LENGTH; 00215 //tr_debug("Retry First"); 00216 } 00217 } 00218 } 00219 } 00220 00221 if (suite->pana_session.user_server) { 00222 eap_code = EAP_REQ; 00223 } else { 00224 eap_code = EAP_RESPONSE; 00225 } 00226 00227 uint8_t header_size = eap_header_size(eap_code); 00228 header_size += eap_tls_header_size(eap_tls_flags); 00229 00230 buf = eap_common_headroom_get_to_buffer(buf, header_size); 00231 if (!buf) { 00232 return NULL; 00233 } 00234 00235 uint8_t *ptr = eap_header_build(buffer_data_pointer(buf), buffer_data_length(buf),eap_code, suite->pana_session.eap_id_seq, EAP_TLS); 00236 00237 eap_tls_header_build(ptr, eap_tls_flags, suite->pana_session.assy_length); 00238 00239 return (buf); 00240 } 00241 00242 buffer_t *eap_up(buffer_t *buf, sec_suite_t *suite) 00243 { 00244 uint8_t *ptr = buffer_data_pointer(buf); 00245 uint16_t payload_length = buffer_data_length(buf); 00246 eap_header_t header; 00247 if (!eap_header_parse(ptr, payload_length, &header)) { 00248 return buffer_free(buf); 00249 } 00250 00251 if (header.eap_code == EAP_RESPONSE) { 00252 if (header.id_seq != suite->pana_session.eap_id_seq) { 00253 tr_warn("EAP:Drop Packet by ID"); 00254 suite->timer = 65; 00255 return buffer_free(buf); 00256 } 00257 //tr_debug("EAP RES"); 00258 suite->pana_session.eap_id_seq++; 00259 suite->retry_counter = 0; 00260 } else if (header.eap_code == EAP_REQ) { 00261 00262 if (header.type == EAP_IDENTITY) { 00263 suite->pana_session.eap_id_seq = header.id_seq; 00264 } else { 00265 00266 uint8_t eap_seq = suite->pana_session.eap_id_seq; 00267 if (eap_seq == 0xff) { 00268 eap_seq = 0; 00269 } else { 00270 eap_seq++; 00271 } 00272 00273 if (eap_seq != header.id_seq) { 00274 if (suite->pana_session.eap_id_seq == header.id_seq) { 00275 //tr_debug("EAP:Same SEQ"); 00276 if (suite->pana_session.assy_length) { 00277 tr_debug("SEND ACK. Should send same packet again"); 00278 } else if (suite->pana_session.frag_length) { 00279 tr_debug("SEND ACK. Should send same packet again"); 00280 buf->buf_ptr = buf->buf_end ; 00281 buf = buffer_turnaround(buf); 00282 memcpy(buf->dst_sa .address , buf->src_sa .address , 16); 00283 buf->src_sa .addr_type = ADDR_NONE ; 00284 return buf; 00285 } else { 00286 tr_debug("REQ but Frag ready"); 00287 return buffer_free(buf); 00288 } 00289 } else { 00290 tr_debug("EAP:Drop unknown Req ID. MSG: %x, ses: %x", header.id_seq, suite->pana_session.eap_id_seq); 00291 return buffer_free(buf); 00292 } 00293 } else { 00294 suite->pana_session.eap_id_seq = header.id_seq; 00295 } 00296 } 00297 } 00298 00299 switch (header.type) { 00300 case EAP_IDENTITY: 00301 if (header.eap_code == EAP_REQ) { 00302 sec_lib_state_machine_trig(suite, EAP_IDENTITY_RES); 00303 } else { 00304 #ifdef PANA_SERVER_API 00305 if (suite->pana_session.user_server) { 00306 sec_lib_state_machine_trig(suite, TLS_START); 00307 } 00308 #endif 00309 } 00310 return buffer_free(buf); 00311 00312 case EAP_TLS: 00313 case EAP_TTLS: { 00314 eap_tls_header_t eap_tls_header; 00315 if (!eap_tls_header_parse(header.data_ptr, header.length -5, &eap_tls_header) ) { 00316 return buffer_free(buf); 00317 } 00318 00319 if (eap_tls_header.eap_tls_flags & EAP_TLS_START) { 00320 suite->pana_session.eap_id_seq = header.id_seq; 00321 sec_lib_state_machine_trig(suite, TLS_INIT); 00322 return buffer_free(buf); 00323 } 00324 buffer_data_pointer_set(buf, eap_tls_header.data_ptr); 00325 00326 if (header.eap_code == EAP_RESPONSE) { 00327 if (eap_tls_header.eap_tls_flags) { 00328 if (suite->pana_session.assy_length) { 00329 suite->pana_session.assy_off_set += suite->pana_session.last_assy_size; 00330 if (suite->pana_session.assy_off_set < suite->pana_session.assy_length) { 00331 tr_warn("Packet TX process fail"); 00332 } else { 00333 tr_debug("EAP Frag TX Done & Start RX frag"); 00334 00335 } 00336 //tr_debug("Free Frag Buf"); 00337 if (suite->pana_session.eap_assy_buf) { 00338 tr_debug("Free Frag Buf"); 00339 buffer_free(suite->pana_session.eap_assy_buf); 00340 suite->pana_session.eap_assy_buf = 0; 00341 } 00342 suite->pana_session.assy_length = 0; 00343 suite->pana_session.assy_off_set = 0; 00344 suite->pana_session.last_assy_size = 0; 00345 } 00346 } 00347 } 00348 00349 if ((eap_tls_header.eap_tls_flags & EAP_TLS_MORE_FRAGMENTS) == 0) { 00350 if (suite->pana_session.frag_length) { 00351 buffer_t *t_buf = suite->pana_session.eap_frag_buf; 00352 00353 uint16_t check_len = suite->pana_session.frag_off_set; 00354 check_len += eap_tls_header.tls_frame_length; 00355 suite->pana_session.eap_frag_buf = NULL; 00356 suite->pana_session.frag_length = 0; 00357 if (check_len == buffer_data_length(t_buf)) { 00358 memcpy(buffer_data_pointer(t_buf) + suite->pana_session.frag_off_set, eap_tls_header.data_ptr, eap_tls_header.tls_frame_length); 00359 t_buf->seq = header.id_seq; 00360 tr_debug("Full packet RX"); 00361 buffer_free(buf); 00362 buf = t_buf; 00363 suite->pana_session.frag_off_set = 0; 00364 } else { 00365 00366 buffer_free(t_buf); 00367 suite->pana_session.frag_off_set = 0; 00368 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00369 return buffer_free(buf); 00370 } 00371 } else if (suite->pana_session.assy_length) { 00372 buffer_t *t_buf = suite->pana_session.eap_assy_buf; 00373 if (header.eap_code == EAP_RESPONSE) { 00374 suite->pana_session.assy_off_set += suite->pana_session.last_assy_size; 00375 if (eap_tls_header.tls_frame_length == 0) { 00376 t_buf->seq = header.id_seq; 00377 } 00378 } else { 00379 uint8_t cmp_seq = t_buf->seq ; 00380 if (cmp_seq == 0xff) { 00381 cmp_seq = 0; 00382 } else { 00383 cmp_seq++; 00384 } 00385 if (cmp_seq == header.id_seq) { 00386 suite->pana_session.assy_off_set += suite->pana_session.last_assy_size; 00387 if (eap_tls_header.tls_frame_length == 0) { 00388 t_buf->seq = header.id_seq; 00389 } 00390 } else { 00391 tr_debug("RETX"); 00392 } 00393 } 00394 if (suite->pana_session.assy_off_set < suite->pana_session.assy_length) { 00395 if (eap_tls_header.tls_frame_length == 0) { 00396 uint16_t len = 0; 00397 buffer_t *f_buf = 0; 00398 buffer_free(buf); 00399 suite->retry_counter = 0; 00400 pana_lib_parameters_s *parameters = pana_parameters_get(); 00401 if (suite->pana_session.assy_off_set + parameters->EAP_FRAGMENT_SIZE < suite->pana_session.assy_length) { 00402 len = parameters->EAP_FRAGMENT_SIZE; 00403 } else { 00404 len = suite->pana_session.assy_length - suite->pana_session.assy_off_set; 00405 } 00406 00407 f_buf = buffer_get(len + 50); 00408 if (f_buf) { 00409 //memcpy(f_buf->dst_sa.address, t_buf->src_sa.address, 16); 00410 f_buf->interface = suite->interface; 00411 f_buf->src_sa .addr_type = ADDR_NONE ; 00412 f_buf->dst_sa .addr_type = ADDR_NONE ; 00413 memcpy(buffer_data_pointer(f_buf), buffer_data_pointer(t_buf) + suite->pana_session.assy_off_set, len); 00414 buffer_data_length_set(f_buf, len); 00415 suite->pana_session.last_assy_size = len; 00416 tr_debug("Push frag"); 00417 return (f_buf); 00418 } else { 00419 tr_warn("No Mem"); 00420 return NULL; 00421 } 00422 } else { 00423 //IT cuold be alert 00424 buf->session_ptr = suite; 00425 eap_tls_payload_push(buf); 00426 return NULL; 00427 } 00428 } else { 00429 tr_debug("EAP Frag TX Done"); 00430 suite->pana_session.eap_assy_buf = buffer_free(t_buf); 00431 suite->pana_session.assy_length = 0; 00432 suite->pana_session.assy_off_set = 0; 00433 suite->pana_session.last_assy_size = 0; 00434 } 00435 } else if (!eap_tls_header.tls_frame_length) { 00436 if (header.eap_code == EAP_RESPONSE) { 00437 #ifdef PANA_SERVER_API 00438 if (suite->state == TLS_KEY_CHANGE && suite->pana_session.user_server) { 00439 //tr_debug("TLS Auth Ready"); 00440 pana_key_calculation(suite); 00441 sec_lib_state_machine_trig(suite, TLS_EAP_END_PANA_VERIFY); 00442 } 00443 #endif 00444 } 00445 00446 return buffer_free(buf); 00447 } 00448 buf->session_ptr = suite; 00449 eap_tls_payload_push(buf); 00450 return NULL; 00451 00452 } 00453 00454 //More flag is active 00455 if (!eap_tls_header.tls_frame_length) { 00456 tr_debug("More without Data"); 00457 return buffer_free(buf); 00458 } 00459 bool skip_packet = false; 00460 00461 if (eap_tls_header.tls_length) { 00462 //Check did we have a already action 00463 if (suite->pana_session.frag_length == 0) { 00464 00465 buffer_t *f_buf = buffer_get(eap_tls_header.tls_length); 00466 tr_debug("First Fragment"); 00467 if (f_buf) { 00468 buffer_data_length_set(f_buf, eap_tls_header.tls_length); 00469 memcpy(buffer_data_pointer(f_buf), eap_tls_header.data_ptr, eap_tls_header.tls_frame_length); 00470 suite->pana_session.frag_off_set = eap_tls_header.tls_frame_length; 00471 f_buf->seq = header.id_seq; 00472 suite->pana_session.eap_frag_buf = f_buf; 00473 suite->pana_session.frag_length = eap_tls_header.tls_length; 00474 skip_packet = true; 00475 } else { 00476 tr_debug("No free men for Fragment: %i", eap_tls_header.tls_length); 00477 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00478 return buffer_free(buf); 00479 } 00480 } else if (suite->pana_session.frag_length != eap_tls_header.tls_length) { 00481 tr_debug("Fragment started already"); 00482 skip_packet = true; 00483 } else { 00484 00485 } 00486 } 00487 00488 if (!skip_packet && suite->pana_session.frag_length) { 00489 uint16_t check_len = 0; 00490 buffer_t *t_buf = suite->pana_session.eap_frag_buf; 00491 check_len = suite->pana_session.frag_off_set; 00492 check_len += eap_tls_header.tls_frame_length; 00493 00494 //new sequency 00495 if (check_len < buffer_data_length(t_buf)) { 00496 tr_debug("Copy Data to Fragment"); 00497 memcpy(buffer_data_pointer(t_buf) + suite->pana_session.frag_off_set, eap_tls_header.data_ptr, eap_tls_header.tls_frame_length); 00498 suite->pana_session.frag_off_set += eap_tls_header.tls_frame_length; 00499 t_buf->seq = suite->pana_session.eap_id_seq; 00500 } else { 00501 tr_debug("Overflow possible Free Current entry and set Alert"); 00502 buffer_free(t_buf); 00503 suite->pana_session.eap_frag_buf = NULL; 00504 suite->pana_session.frag_length = 0; 00505 suite->pana_session.frag_off_set = 0; 00506 sec_lib_state_machine_trig(suite, TLS_ALERT_INTERNAL); 00507 return buffer_free(buf); 00508 } 00509 } 00510 00511 if (header.eap_code == EAP_RESPONSE) { 00512 #ifdef PANA_SERVER_API 00513 if (suite->state == TLS_TX_SERVER_KEY_EXCHANGE) { 00514 if (suite->pana_session.assy_length) { 00515 suite->retry_counter = 0; 00516 } 00517 } 00518 #endif 00519 pana_timeout_timer_set(suite, suite->state); 00520 } 00521 /* TX ACK or new request to sender*/ 00522 buf = buffer_turnaround(buf); 00523 buf->buf_ptr = buf->buf_end ; 00524 memcpy(buf->dst_sa .address , buf->src_sa .address , 16); 00525 buf->src_sa .addr_type = ADDR_NONE ; 00526 return (buf); 00527 } 00528 00529 00530 default: 00531 tr_debug("%x", header.type); 00532 return buffer_free(buf); 00533 } 00534 } 00535 #endif
Generated on Tue Jul 12 2022 13:02:51 by
