diff -r bad0cc58d154 -r c74b3d9f6b9e eapol/eapol_framework/eapol_common/core/eapol_core.cpp --- a/eapol/eapol_framework/eapol_common/core/eapol_core.cpp Tue Aug 31 15:16:37 2010 +0300 +++ b/eapol/eapol_framework/eapol_common/core/eapol_core.cpp Wed Sep 01 12:23:57 2010 +0100 @@ -16,13 +16,13 @@ */ /* -* %version: 100 % +* %version: 67.1.2.1.2 % */ // This is enumeration of EAPOL source code. #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) #undef EAP_FILE_NUMBER_ENUM - #define EAP_FILE_NUMBER_ENUM 747 + #define EAP_FILE_NUMBER_ENUM 48 #undef EAP_FILE_NUMBER_DATE #define EAP_FILE_NUMBER_DATE 1127594498 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) @@ -61,7 +61,6 @@ EAP_ASSERT(m_shutdown_was_called == true); delete m_eap_core; - m_eap_core = 0; EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); } @@ -78,8 +77,14 @@ abs_eapol_core_c * const partner, const bool is_client_when_true) : m_partner(partner) - , m_eap_core(0) +#if !defined(NO_EAP_SESSION_CORE) + , m_eap_core(new eap_session_core_c(tools, this, is_client_when_true)) +#else + , m_eap_core(new eap_core_c(tools, this, is_client_when_true, 0, false)) +#endif +#if defined(USE_EAPOL_KEY_STATE) , m_eapol_key_state_map(tools, this) +#endif //#if defined(USE_EAPOL_KEY_STATE) , m_am_tools(tools) , m_master_session_key(m_am_tools) , m_authentication_type(eapol_key_authentication_type_none) @@ -93,7 +98,9 @@ , m_is_valid(false) , m_shutdown_was_called(false) , m_block_state_notifications(false) +#if defined(USE_EAPOL_KEY_STATE) , m_skip_start_4_way_handshake(false) +#endif //#if defined(USE_EAPOL_KEY_STATE) { EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); @@ -107,19 +114,8 @@ __DATE__, __TIME__)); -#if defined(EAP_USE_WPXM) - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("eapol_core_c::eapol_core_c(): WPX enabled."))); -#else - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("eapol_core_c::eapol_core_c(): WPX disabled."))); -#endif //#if defined(EAP_USE_WPXM) - - if (m_partner != 0) + if (m_eap_core != 0 + && m_eap_core->get_is_valid() == true) { set_is_valid(); } @@ -130,118 +126,6 @@ //-------------------------------------------------- // -EAP_FUNC_EXPORT eap_status_e eapol_core_c::configure() -{ - EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); - - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("%s: eapol_core_c::configure()\n"), - (m_is_client == true) ? "client": "server")); - - EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::configure()"); - - eap_status_e status(eap_status_process_general_error); - - m_eapol_header_offset = m_partner->get_header_offset( - &m_MTU, &m_trailer_length); - -#if defined(NO_EAP_CORE_CLIENT_MESSAGE_IF) - m_eap_core = eap_session_core_base_c::new_eap_session_core_c( - m_am_tools, - this, - m_is_client, - m_MTU-eapol_header_wr_c::get_header_length()); -#else - m_eap_core = new_eap_core_client_message_if_c( - m_am_tools, - this, - m_is_client, - m_MTU-eapol_header_wr_c::get_header_length()); -#endif - - if (m_eap_core == 0 - || m_eap_core->get_is_valid() == false) - { - return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); - } - - { - eap_variable_data_c max_eapol_starts(m_am_tools); - - status = read_configure( - cf_str_EAPOL_CORE_starts_max_count.get_field(), - &max_eapol_starts); - if (status != eap_status_ok - || max_eapol_starts.get_is_valid_data() == false - || max_eapol_starts.get_data_length() < sizeof(u32_t)) - { - // Probably not found from db. Use the default value. - m_max_eapol_starts = EAPOL_CORE_MAX_EAPOL_START_SENDINGS; - } - else - { - m_max_eapol_starts = *reinterpret_cast( - max_eapol_starts.get_data(sizeof(u32_t))); - } - } - - { - eap_variable_data_c eapol_start_interval(m_am_tools); - - status = read_configure( - cf_str_EAPOL_CORE_send_start_interval.get_field(), - &eapol_start_interval); - if (status != eap_status_ok - || eapol_start_interval.get_is_valid_data() == false - || eapol_start_interval.get_data_length() < sizeof(u32_t)) - { - // Probably not found from db. Use the default value. - m_eapol_start_interval = EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT; - } - else - { - m_eapol_start_interval = *reinterpret_cast( - eapol_start_interval.get_data(sizeof(u32_t))); - } - } - -#if defined(USE_EAP_CORE_SERVER) - if (m_is_client == false) - { - eap_variable_data_c data(m_am_tools); - - eap_status_e status = read_configure( - cf_str_EAPOL_CORE_skip_start_4_way_handshake.get_field(), - &data); - if (status == eap_status_ok - && data.get_data_length() == sizeof(u32_t) - && data.get_data(data.get_data_length()) != 0) - { - u32_t *flag = reinterpret_cast(data.get_data(data.get_data_length())); - - if (flag != 0) - { - if ((*flag) != 0ul) - { - m_skip_start_4_way_handshake = true; - } - else - { - m_skip_start_4_way_handshake = false; - } - } - } - } -#endif //#if defined(USE_EAP_CORE_SERVER) - - return EAP_STATUS_RETURN(m_am_tools, m_eap_core->configure()); -} - -//-------------------------------------------------- - -// EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_process( const eap_am_network_id_c * const receive_network_id, eap_general_header_base_c * const packet_data, @@ -381,7 +265,7 @@ #if defined(EAP_USE_WPXM) && m_authentication_type != eapol_key_authentication_type_WPXM #endif //#if defined(EAP_USE_WPXM) - && m_authentication_type != eapol_key_authentication_type_WPS + && m_authentication_type != eapol_key_authentication_type_WFA_SC && m_authentication_type != eapol_key_authentication_type_EAP_authentication_no_encryption ) { @@ -395,26 +279,34 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); } + +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + // Test first we are connected. if (eapol_key_state->get_is_associated() == true) { - eap_header_wr_c eap( - m_am_tools, - eapol.get_eap_header(), - eapol.get_data_length()); - - status = m_eap_core->packet_process( - receive_network_id, - &eap, - eapol.get_data_length()); - - EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); + status = m_eap_core->synchronous_create_eap_session(receive_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } } - else - { - EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); - return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); - } + +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + + eap_header_wr_c eap( + m_am_tools, + eapol.get_eap_header(), + eapol.get_data_length()); + + status = m_eap_core->packet_process( + receive_network_id, + &eap, + eapol.get_data_length()); + + EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); } else if (m_is_client == false && eapol.get_packet_type() == eapol_packet_type_logoff) @@ -427,7 +319,7 @@ if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP && m_authentication_type != eapol_key_authentication_type_WPA_EAP && m_authentication_type != eapol_key_authentication_type_dynamic_WEP - && m_authentication_type != eapol_key_authentication_type_WPS + && m_authentication_type != eapol_key_authentication_type_WFA_SC #if defined(EAP_USE_WPXM) && m_authentication_type != eapol_key_authentication_type_WPXM #endif //#if defined(EAP_USE_WPXM) @@ -450,6 +342,7 @@ m_is_client, false); } +#if defined(USE_EAPOL_KEY_STATE) else if (eapol.get_packet_type() == eapol_packet_type_key) { if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP @@ -496,6 +389,40 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); } } +#endif //#if defined(USE_EAPOL_KEY_STATE) +#if ! defined(USE_EAPOL_KEY_STATE) + else if ( + m_is_client == true + && eapol.get_packet_type() == eapol_packet_type_key) + { + // Handle EAPOL-Key frame. + // Here is assumed the EAPOL-Key frame includes RC4 Key Descriptor. + /** + * @{ Here we need to check the Descriptor Type field. + * It may be RC4 Key Descriptor, RSNA Key Descriptor or other descriptor. } + */ + + eapol_RC4_key_header_c eapol_key_msg( + m_am_tools, + eapol.get_header_buffer(eapol.get_header_buffer_length()), + eapol.get_header_buffer_length()); + if (eapol_key_msg.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + else if (eapol_key_msg.check_header() != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = handle_RC4_key_descriptor( + receive_network_id, + &eapol_key_msg, + packet_length); + } +#endif //#if ! defined(USE_EAPOL_KEY_STATE) else { EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: %s, packet_type=0x%02x=%s not handled, data length 0x%04x.\n"), @@ -530,7 +457,7 @@ EAP_ASSERT(data_length <= sent_packet->get_data_length()); EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); - if (header_offset < m_eapol_header_offset+eapol_header_wr_c::get_header_length()) + if (header_offset < eap_header_wr_c::get_header_length()) { EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); @@ -540,7 +467,7 @@ eapol_header_wr_c eapol( m_am_tools, sent_packet->get_data_offset( - header_offset-eapol_header_wr_c::get_header_length(), data_length), + header_offset-eap_header_wr_c::get_header_length(), data_length), data_length); if (eapol.get_is_valid() == false) @@ -612,11 +539,8 @@ } eap_status_e status = m_partner->packet_send( - send_network_id, - sent_packet, - header_offset-eapol_header_wr_c::get_header_length(), - data_length+eapol_header_wr_c::get_header_length(), - buffer_length); + send_network_id, sent_packet, header_offset-eapol_header_wr_c::get_header_length(), + data_length+eapol_header_wr_c::get_header_length(), buffer_length); EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); @@ -748,6 +672,13 @@ this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) +#if !defined(NO_EAP_SESSION_CORE) + // First we remove possible EAP session. + (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); +#endif +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + // Here we swap the addresses. eap_am_network_id_c send_network_id(m_am_tools, receive_network_id->get_destination_id(), @@ -826,7 +757,7 @@ if (m_authentication_type == eapol_key_authentication_type_EAP_authentication_no_encryption) { - // Some APs need broadcast EAPOL-Start-message. + // This is a hack for this security mode. Some APs need broadcast EAPOL-Start-message. const u8_t BROADCAST_ADDRESS[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; @@ -933,12 +864,14 @@ { // It is bad idea to terminate on-going authentication // when EAPOL-Start is received. - // Because of that remove_eap_session() is called + // Because of that synchronous_remove_eap_session() is called // only when force_clean_restart is true. +#if !defined(NO_EAP_SESSION_CORE) bool previous_block = m_block_state_notifications; m_block_state_notifications = true; - (void) m_eap_core->remove_eap_session(false, receive_network_id); + (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); m_block_state_notifications = previous_block; +#endif } if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP @@ -947,7 +880,7 @@ #if defined(EAP_USE_WPXM) || m_authentication_type == eapol_key_authentication_type_WPXM #endif //#if defined(EAP_USE_WPXM) - || m_authentication_type == eapol_key_authentication_type_WPS + || m_authentication_type == eapol_key_authentication_type_WFA_SC || m_authentication_type == eapol_key_authentication_type_EAP_authentication_no_encryption ) { @@ -1062,13 +995,6 @@ } } // for() -#if 1 - - status = m_partner->complete_check_pmksa_cache(bssid_sta_receive_network_ids); - return EAP_STATUS_RETURN(m_am_tools, status); - -#else - if (bssid_sta_receive_network_ids->get_object_count() > 0ul) { EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); @@ -1079,9 +1005,6 @@ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); } - -#endif - } //-------------------------------------------------- @@ -1123,14 +1046,13 @@ } status = remove_eapol_key_state( - &send_network_id, - true); + &send_network_id); if (status != eap_status_ok) { EAP_TRACE_DEBUG( m_am_tools, TRACE_FLAGS_DEFAULT, - (EAPL("WARNING: eapol_core_c::remove_pmksa_from_cache(): ") + (EAPL("WARNING: eapol_core_c::disassociation(): ") EAPL("remove_eapol_key_state(), eap_status_e %d\n"), status)); return EAP_STATUS_RETURN(m_am_tools, status); @@ -1156,6 +1078,8 @@ EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::start_preauthentication()"); +#if defined(USE_EAPOL_KEY_STATE) + if (receive_network_id->get_type() != eapol_ethernet_type_preauthentication) { EAP_TRACE_DEBUG( @@ -1298,8 +1222,7 @@ if (status != eap_status_ok) { status = remove_eapol_key_state( - &send_network_id, - true); + &send_network_id); if (status != eap_status_ok) { EAP_TRACE_DEBUG( @@ -1321,6 +1244,8 @@ true, false); +#endif //#if defined(USE_EAPOL_KEY_STATE) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } @@ -1359,6 +1284,8 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); } +#if defined(USE_EAPOL_KEY_STATE) + // Here we swap the addresses. eap_am_network_id_c old_send_network_id( m_am_tools, @@ -1455,6 +1382,8 @@ } } +#endif //#if defined(USE_EAPOL_KEY_STATE) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } @@ -1500,6 +1429,8 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); } +#if defined(USE_EAPOL_KEY_STATE) + // Here we swap the addresses. eap_am_network_id_c old_send_network_id( m_am_tools, @@ -1599,6 +1530,8 @@ status = eap_status_not_found; } +#endif //#if defined(USE_EAPOL_KEY_STATE) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } @@ -1606,7 +1539,7 @@ //-------------------------------------------------- // -EAP_FUNC_EXPORT eap_status_e eapol_core_c::read_reassociation_parameters( +eap_status_e eapol_core_c::read_reassociation_parameters( const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. const eapol_key_authentication_type_e authentication_type, @@ -1626,6 +1559,8 @@ eap_status_e status(eap_status_process_general_error); +#if defined(USE_EAPOL_KEY_STATE) + // No need to check authentication type anymore. It can be changed in reassociation. #if defined(EAP_USE_WPXM) @@ -1731,6 +1666,8 @@ status = eap_status_not_found; } +#endif //#if defined(USE_EAPOL_KEY_STATE) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } @@ -1797,6 +1734,7 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#if defined(USE_EAPOL_KEY_STATE) if (m_skip_start_4_way_handshake == true && (authentication_type == eapol_key_authentication_type_RSNA_EAP || authentication_type == eapol_key_authentication_type_RSNA_PSK @@ -1813,6 +1751,7 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); } else +#endif //#if defined(USE_EAPOL_KEY_STATE) { #if !defined(NO_EAPOL_KEY_STATE_SERVER) status = eapol_key_state->start_4_way_handshake( @@ -1850,7 +1789,7 @@ //-------------------------------------------------- // -EAP_FUNC_EXPORT eap_status_e eapol_core_c::complete_reassociation( +eap_status_e eapol_core_c::complete_reassociation( const eapol_wlan_authentication_state_e reassociation_result, const eap_am_network_id_c * const receive_network_id, const eapol_key_authentication_type_e authentication_type, @@ -1870,6 +1809,8 @@ EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::complete_reassociation()"); +#if defined(USE_EAPOL_KEY_STATE) + // Here we swap the addresses. eap_am_network_id_c send_network_id( m_am_tools, @@ -1922,6 +1863,7 @@ return EAP_STATUS_RETURN(m_am_tools, status); } else +#endif //#if defined(USE_EAPOL_KEY_STATE) { EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); @@ -2057,6 +1999,8 @@ master_session_key->get_data_length())); } +#if defined(USE_EAPOL_KEY_STATE) + eap_network_id_selector_c state_selector( m_am_tools, send_network_id); @@ -2092,6 +2036,20 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); } +#else + + // Store the session key so it can be used when EAPOL-Key is received. + m_master_session_key.reset(); + + status = m_master_session_key.set_copy_of_buffer(master_session_key); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#endif //#if defined(USE_EAPOL_KEY_STATE) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } @@ -2146,6 +2104,369 @@ //-------------------------------------------------- +#if !defined(USE_EAPOL_KEY_STATE) + +// +eap_status_e eapol_core_c::handle_RC4_key_descriptor( + const eap_am_network_id_c * const receive_network_id, + eapol_RC4_key_header_c* const packet, + const u32_t packet_length) +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::handle_RC4_key_descriptor()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::handle_RC4_key_descriptor()"); + + eap_status_e status = eap_status_process_general_error; + + // Check the packet length + if (static_cast(packet->get_header_length()) != packet_length + && static_cast(packet->get_header_length() + packet->get_key_length()) != packet_length) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("ERROR: Illegal EAPOL-Key frame length, packet->get_header_length() %d, packet_length %d\n"), + packet->get_header_length(), + packet_length)); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); + } + + // Get MS-MPPE-Recv-Key and MS-MPPE-Send-Key + // Recv-Key is the first 32 bytes of master session key and Send-Key is the next 32 bytes. + eap_variable_data_c mppe_recv_key(m_am_tools); + eap_variable_data_c mppe_send_key(m_am_tools); + if (m_master_session_key.get_data_length() == 16ul) + { + status = mppe_recv_key.set_buffer( + m_master_session_key.get_data(m_master_session_key.get_data_length()), + m_master_session_key.get_data_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_master_session_key.get_data(m_master_session_key.get_data_length()), + m_master_session_key.get_data_length(), + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + status = mppe_recv_key.set_buffer( + m_master_session_key.get_data(MPPE_KEY_LENGTH), + MPPE_KEY_LENGTH, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = mppe_send_key.set_buffer( + m_master_session_key.get_data_offset(MPPE_KEY_LENGTH, MPPE_KEY_LENGTH), + MPPE_KEY_LENGTH, + false, + false); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + + if (mppe_recv_key.get_is_valid() == false + || mppe_send_key.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Verify the the MD5 signature in Eapol-Key + crypto_md5_c md5(m_am_tools); + crypto_hmac_c hmac_md5(m_am_tools, &md5, false); + if (hmac_md5.get_is_valid() == false) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // MPPE-Send-Key is used as the signature key. + if (hmac_md5.hmac_set_key(&mppe_send_key) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_init failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + // Save the signature from the packet + eap_variable_data_c signature(m_am_tools); + status = signature.set_copy_of_buffer(packet->get_key_signature(), EAPOL_RC4_KEY_SIGNATURE_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + // Replace the signature with zeros. + packet->zero_key_signature(m_am_tools); + + // Send the data to HMAC-MD5 module + if (hmac_md5.hmac_update(packet->get_header_buffer(packet_length), packet_length) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_update failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Get the calculated signature + u8_t tmp_signature[EAPOL_RC4_KEY_SIGNATURE_LENGTH]; + u32_t length = EAPOL_RC4_KEY_SIGNATURE_LENGTH; + if (hmac_md5.hmac_final(tmp_signature, &length) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_final failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Compare the calculated and original signature + if (m_am_tools->memcmp( + tmp_signature, + signature.get_data( + EAPOL_RC4_KEY_SIGNATURE_LENGTH), + EAPOL_RC4_KEY_SIGNATURE_LENGTH) != 0) + { + // Signatures did not match. Something's wrong. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAPOL-Key HMAC-MD5 check failed.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAPOL-Key HMAC-MD5 check passed.\n"))); + + eap_variable_data_c key_out(m_am_tools); + // Decrypt the RC4 encrypted key + if (packet->get_key() == 0) + { + // EAPOL-Key does not contain the key. This means that we should use + // the first bytes from MS-MPPE-Recv-Key as the key. There is a slight + // confusion in draft-congdon-radius-8021x-23.txt regarding this but this is how + // it works. + if (packet->get_key_length() > 0) + { + status = key_out.set_copy_of_buffer(mppe_recv_key.get_data(packet->get_key_length()), packet->get_key_length()); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + else + { + // Key message with no key length? + // Just ignore the message. + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got empty WEP unicast key message.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); + } + } + else + { + // Set-up RC4 key. Key is the IV and the MS-MPPE-Recv-Key truncated together. + eap_variable_data_c rc4_key(m_am_tools); + status = rc4_key.set_copy_of_buffer(packet->get_key_IV(), EAPOL_RC4_KEY_IV_LENGTH); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + rc4_key.add_data(&mppe_recv_key); + + // Set-up RC4 module + crypto_rc4_c rc4(m_am_tools); + // Set the key for RC4 + if (rc4.set_key(&rc4_key) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: rc4_set_key failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + + // Decrypt the key to key_out + key_out.set_buffer_length(packet->get_key_length()); + if (rc4.decrypt_data(packet->get_key(), key_out.get_data(packet->get_key_length()), packet->get_key_length()) != eap_status_ok) + { + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: rc4 failed\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); + } + key_out.set_data_length(packet->get_key_length()); + } + + // Find out the key type. At the moment only WEP keys are supported. + eapol_key_type_e key_type; + switch (packet->get_key_flag()) + { + case eapol_RC4_key_flag_broadcast: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WEP broadcast key\n"))); + key_type = eapol_key_type_broadcast; + break; + case eapol_RC4_key_flag_unicast: + EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WEP unicast key\n"))); + key_type = eapol_key_type_unicast; + break; + default: + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); + } + + EAP_TRACE_DATA_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("Key"), + key_out.get_data(key_out.get_data_length()), + key_out.get_data_length())); + + // Here we swap the addresses. + eap_am_network_id_c send_network_id(m_am_tools, + receive_network_id->get_destination_id(), + receive_network_id->get_source_id(), + receive_network_id->get_type()); + if (send_network_id.get_is_valid_data() == false) + { + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + eapol_session_key_c wep_key( + m_am_tools, + &key_out, + key_type, + packet->get_key_index(), + true); + + // Forward the keys to lower layers + status = m_partner->packet_data_session_key( + &send_network_id, + &wep_key); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +#endif //#if !defined(USE_EAPOL_KEY_STATE) + +//-------------------------------------------------- + +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::configure() +{ + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("%s: eapol_core_c::configure()\n"), + (m_is_client == true) ? "client": "server")); + + EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::configure()"); + + m_eapol_header_offset = m_partner->get_header_offset( + &m_MTU, &m_trailer_length); + + eap_status_e status = eap_status_process_general_error; + + { + eap_variable_data_c max_eapol_starts(m_am_tools); + + status = read_configure( + cf_str_EAPOL_CORE_starts_max_count.get_field(), + &max_eapol_starts); + if (status != eap_status_ok + || max_eapol_starts.get_is_valid_data() == false + || max_eapol_starts.get_data_length() < sizeof(u32_t)) + { + // Probably not found from db. Use the default value. + m_max_eapol_starts = EAPOL_CORE_MAX_EAPOL_START_SENDINGS; + } + else + { + m_max_eapol_starts = *reinterpret_cast( + max_eapol_starts.get_data(sizeof(u32_t))); + } + } + + { + eap_variable_data_c eapol_start_interval(m_am_tools); + + status = read_configure( + cf_str_EAPOL_CORE_send_start_interval.get_field(), + &eapol_start_interval); + if (status != eap_status_ok + || eapol_start_interval.get_is_valid_data() == false + || eapol_start_interval.get_data_length() < sizeof(u32_t)) + { + // Probably not found from db. Use the default value. + m_eapol_start_interval = EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT; + } + else + { + m_eapol_start_interval = *reinterpret_cast( + eapol_start_interval.get_data(sizeof(u32_t))); + } + } + +#if defined(USE_EAP_CORE_SERVER) + if (m_is_client == false) + { + eap_variable_data_c data(m_am_tools); + + eap_status_e status = read_configure( + cf_str_EAPOL_CORE_skip_start_4_way_handshake.get_field(), + &data); + if (status == eap_status_ok + && data.get_data_length() == sizeof(u32_t) + && data.get_data(data.get_data_length()) != 0) + { + u32_t *flag = reinterpret_cast(data.get_data(data.get_data_length())); + + if (flag != 0) + { + if ((*flag) != 0ul) + { + m_skip_start_4_way_handshake = true; + } + else + { + m_skip_start_4_way_handshake = false; + } + } + } + } +#endif //#if defined(USE_EAP_CORE_SERVER) + + return EAP_STATUS_RETURN(m_am_tools, m_eap_core->configure()); +} + +//-------------------------------------------------- + +#if defined(USE_EAPOL_KEY_STATE) + // EAP_FUNC_EXPORT eap_status_e eapol_core_c::shutdown_operation( eapol_key_state_c * const handler, @@ -2161,6 +2482,8 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- // @@ -2184,7 +2507,10 @@ } m_shutdown_was_called = true; - eap_status_e status = m_eapol_key_state_map.for_each(shutdown_operation, true); + eap_status_e status; +#if defined(USE_EAPOL_KEY_STATE) + status = m_eapol_key_state_map.for_each(shutdown_operation, true); +#endif //#if defined(USE_EAPOL_KEY_STATE) if (m_eap_core != 0) { @@ -2193,7 +2519,9 @@ // This will cancel all timers of this object. m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); +#if defined(USE_EAPOL_KEY_STATE) m_partner->cancel_timer(this, EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID); +#endif //#if defined(USE_EAPOL_KEY_STATE) return EAP_STATUS_RETURN(m_am_tools, status); } @@ -2319,6 +2647,7 @@ state_notification(¬ification); } } +#if defined(USE_EAPOL_KEY_STATE) else if (id == EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID) { EAP_TRACE_DEBUG( @@ -2334,8 +2663,9 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); } - (void) remove_eapol_key_state(send_network_id, false); + (void) remove_eapol_key_state(send_network_id); } +#endif //#if defined(USE_EAPOL_KEY_STATE) return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); } @@ -2363,6 +2693,7 @@ = reinterpret_cast(data); delete send_network_id; } +#if defined(USE_EAPOL_KEY_STATE) else if (id == EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID) { @@ -2370,12 +2701,15 @@ = reinterpret_cast(data); delete send_network_id; } +#endif //#if defined(USE_EAPOL_KEY_STATE) return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); } //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) + // EAP_FUNC_EXPORT eap_status_e eapol_core_c::init_eapol_key_pmksa_caching_timeout( const eap_am_network_id_c * const send_network_id) @@ -2434,8 +2768,12 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) + // EAP_FUNC_EXPORT eap_status_e eapol_core_c::indicate_eapol_key_state_started_eap_authentication( const eap_am_network_id_c * const send_network_id) @@ -2486,12 +2824,15 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) + // EAP_FUNC_EXPORT eap_status_e eapol_core_c::remove_eapol_key_state( - const eap_am_network_id_c * const send_network_id, - const bool force_remove) + const eap_am_network_id_c * const send_network_id) { EAP_TRACE_DEBUG( m_am_tools, @@ -2523,8 +2864,7 @@ if (eapol_key_state != 0) { - if (force_remove == false - && eapol_key_state->get_marked_removed() == false) + if (eapol_key_state->get_marked_removed() == false) { // Do not remove object in use. EAP_TRACE_DEBUG( @@ -2560,10 +2900,14 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) + // -EAP_FUNC_EXPORT eap_status_e eapol_core_c::asynchronous_init_remove_eapol_key_state( +eap_status_e eapol_core_c::asynchronous_init_remove_eapol_key_state( const eap_am_network_id_c * const send_network_id) { EAP_TRACE_DEBUG( @@ -2647,6 +2991,8 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- EAP_FUNC_EXPORT void eapol_core_c::state_notification( @@ -2697,6 +3043,7 @@ if (state->get_current_state() == eap_state_identity_request_received || state->get_current_state() == eap_state_eap_response_sent) { +#if defined(USE_EAPOL_KEY_STATE) // Indicate EAPOL Key state the started EAP-authentication. status = indicate_eapol_key_state_started_eap_authentication( state->get_send_network_id()); @@ -2709,6 +3056,7 @@ EAPL("indicate_eapol_key_state_started_eap_authentication(), eap_status_e %d\n"), status)); } +#endif //#if defined(USE_EAPOL_KEY_STATE) } } @@ -2720,10 +3068,10 @@ (EAPL("ERROR: eapol_core_c::state_notification(): %s: EAP-authentication FAILED\n"), (state->get_is_client() == true ? "client": "server"))); +#if defined(USE_EAPOL_KEY_STATE) // Remove possible EAPOL Key state. status = remove_eapol_key_state( - state->get_send_network_id(), - true); + state->get_send_network_id()); if (status != eap_status_ok) { EAP_TRACE_DEBUG( @@ -2733,6 +3081,7 @@ EAPL("remove_eapol_key_state(), eap_status_e %d\n"), status)); } +#endif //#if defined(USE_EAPOL_KEY_STATE) } else if (state->get_current_state() == eap_state_authentication_finished_successfully) @@ -2743,6 +3092,7 @@ (EAPL("eapol_core_c::state_notification(): %s: EAP authentication SUCCESS\n"), (state->get_is_client() == true ? "client": "server"))); +#if defined(USE_EAPOL_KEY_STATE) eap_network_id_selector_c state_selector( m_am_tools, state->get_send_network_id()); @@ -2870,6 +3220,7 @@ EAPL("allow_4_way_handshake() failed, no eapol_key_state_c object\n"))); } } +#endif //#if defined(USE_EAPOL_KEY_STATE) } else { @@ -2888,6 +3239,7 @@ state->get_is_client())); } } +#if defined(USE_EAPOL_KEY_STATE) else if (state->get_protocol_layer() == eap_protocol_layer_eapol_key) { // This nofifation is from eapol_key_state_c object. @@ -3041,6 +3393,8 @@ state->get_is_client())); } } +#endif //#if defined(USE_EAPOL_KEY_STATE) + m_partner->state_notification(state); } @@ -3109,6 +3463,21 @@ //-------------------------------------------------- +// +EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_all_timers() +{ + EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); + + EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); + + const eap_status_e status = m_partner->cancel_all_timers(); + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); +} + +//-------------------------------------------------- + EAP_FUNC_EXPORT eap_status_e eapol_core_c::check_is_valid_eap_type( const eap_type_value_e eap_type) { @@ -3129,6 +3498,8 @@ //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) + // EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_authentication_session( eapol_key_state_c * const handler, @@ -3151,6 +3522,8 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_all_authentication_sessions() @@ -3172,19 +3545,26 @@ bool previous_block = m_block_state_notifications; m_block_state_notifications = true; +#if !defined(NO_EAP_SESSION_CORE) if (m_eap_core != 0) { - status = m_eap_core->cancel_all_eap_sessions(); + status = m_eap_core->synchronous_cancel_all_eap_sessions(); } - +#endif //#if !defined(NO_EAP_SESSION_CORE) + + +#if defined(USE_EAPOL_KEY_STATE) status = m_eapol_key_state_map.for_each(cancel_authentication_session, true); +#endif //#if defined(USE_EAPOL_KEY_STATE) m_block_state_notifications = previous_block; // This will cancel all timers of this object. m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); +#if defined(USE_EAPOL_KEY_STATE) m_partner->cancel_timer(this, EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID); +#endif //#if defined(USE_EAPOL_KEY_STATE) EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); @@ -3192,6 +3572,8 @@ //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) + EAP_FUNC_EXPORT eap_status_e eapol_core_c::get_and_increment_global_key_counter( eap_variable_data_c * const key_counter) { @@ -3199,8 +3581,11 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) /** * Function creates a state for later use. This is for optimazing 4-Way Handshake. * @param receive_network_id carries the MAC addresses. @@ -3368,8 +3753,7 @@ if (status != eap_status_ok) { status = remove_eapol_key_state( - &send_network_id, - true); + &send_network_id); if (status != eap_status_ok) { EAP_TRACE_DEBUG( @@ -3387,8 +3771,11 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) /** * @param receive_network_id carries the MAC addresses. * MAC address of Authenticator should be in source address. MAC address of @@ -3465,10 +3852,112 @@ eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + if (eapol_key_state != 0) + { + // Reuse the session. + eapol_key_state->unset_marked_removed(); + + if (m_is_client == false) + { + // In test version do not reset server. + } + else + { + status = eapol_key_state->reset(); + if (status != eap_status_ok) + { + // We cannot reuse the session. + EAP_TRACE_ERROR( + m_am_tools, + TRACE_FLAGS_ERROR, + (EAPL("eapol_core_c::association(): eapol_key_state NOT reused.\n"))); + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + } + } +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + if (eapol_key_state == 0) { + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + eapol_key_state = new eapol_key_state_c( + m_am_tools, + this, + m_partner, + m_is_client, + receive_network_id, + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + pre_shared_key_PSK); + if (eapol_key_state == 0 + || eapol_key_state->get_is_valid() == false) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); + } + + status = eapol_key_state->initialize( + receive_network_id, + authentication_type, + authenticator_RSNA_IE, + supplicant_RSNA_IE, + eapol_pairwise_cipher, + eapol_group_cipher, + pre_shared_key_PSK); + if (status != eap_status_ok) + { + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + + status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); + if (status != eap_status_ok) + { + if (eapol_key_state != 0) + { + eapol_key_state->shutdown(); + } + else + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), + eapol_key_state)); + } + delete eapol_key_state; + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } + +#else + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); + +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + } else { @@ -3487,6 +3976,29 @@ } } + +#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + status = eapol_key_state->configure(); + if (status != eap_status_ok) + { + status = remove_eapol_key_state( + &send_network_id); + if (status != eap_status_ok) + { + EAP_TRACE_DEBUG( + m_am_tools, + TRACE_FLAGS_DEFAULT, + (EAPL("WARNING: eapol_core_c::association(): ") + EAPL("remove_eapol_key_state(), eap_status_e %d\n"), + status)); + } + + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); + return EAP_STATUS_RETURN(m_am_tools, status); + } +#endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + + if (authentication_type == eapol_key_authentication_type_RSNA_PSK || authentication_type == eapol_key_authentication_type_WPA_PSK) { @@ -3494,6 +4006,7 @@ #if !defined(NO_EAPOL_KEY_STATE_SERVER) if (m_is_client == false) { +#if defined(USE_EAPOL_KEY_STATE) if (m_skip_start_4_way_handshake == true) { // This is test to skip 4-Way Handshake start. @@ -3506,6 +4019,7 @@ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); } else +#endif //#if defined(USE_EAPOL_KEY_STATE) { status = eapol_key_state->start_4_way_handshake( receive_network_id); @@ -3523,35 +4037,40 @@ eapol_key_state->allow_4_way_handshake(); } } +#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) else if (authentication_type == eapol_key_authentication_type_RSNA_EAP || authentication_type == eapol_key_authentication_type_WPA_EAP || authentication_type == eapol_key_authentication_type_dynamic_WEP || authentication_type == eapol_key_authentication_type_WPXM - || authentication_type == eapol_key_authentication_type_WPS + || authentication_type == eapol_key_authentication_type_WFA_SC || authentication_type == eapol_key_authentication_type_EAP_authentication_no_encryption ) { // Creates a EAP-session. - status = m_eap_core->create_eap_session(receive_network_id); + status = m_eap_core->synchronous_create_eap_session(receive_network_id); if (status != eap_status_ok) { EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } } +#endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) + return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- +#if defined(USE_EAPOL_KEY_STATE) /** * @param receive_network_id carries the MAC addresses. * MAC address of Authenticator should be in source address. * MAC address of Supplicant should be in destination address. */ EAP_FUNC_EXPORT eap_status_e eapol_core_c::disassociation( - const bool complete_to_lower_layer, const eap_am_network_id_c * const receive_network_id ) { @@ -3584,10 +4103,10 @@ (void) m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); +#if !defined(NO_EAP_SESSION_CORE) // First we remove possible EAP session. - (void) m_eap_core->remove_eap_session( - complete_to_lower_layer, - receive_network_id); + (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); +#endif status = init_eapol_key_pmksa_caching_timeout( &send_network_id); @@ -3605,6 +4124,8 @@ return EAP_STATUS_RETURN(m_am_tools, status); } +#endif //#if defined(USE_EAPOL_KEY_STATE) + //-------------------------------------------------- /// @see abs_eap_core_c::add_rogue_ap(). @@ -3642,6 +4163,8 @@ eap_status_e status = eap_status_process_general_error; +#if defined(USE_EAPOL_KEY_STATE) + // Here we swap the addresses. eap_am_network_id_c send_network_id( m_am_tools, @@ -3684,6 +4207,12 @@ status = eap_status_handler_does_not_exists_error; } +#else + + status = eap_status_not_supported; + +#endif //#if defined(USE_EAPOL_KEY_STATE) + EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); return EAP_STATUS_RETURN(m_am_tools, status); } @@ -3704,154 +4233,6 @@ //-------------------------------------------------- -#if defined(USE_EAP_SIMPLE_CONFIG) - -EAP_FUNC_EXPORT eap_status_e eapol_core_c::save_simple_config_session( - const simple_config_state_e state, - EAP_TEMPLATE_CONST eap_array_c * const credential_array, - const eap_variable_data_c * const new_password, - const simple_config_Device_Password_ID_e Device_Password_ID, - const simple_config_payloads_c * const other_configuration) -{ - EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); - - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("%s: eapol_core_c::save_simple_config_session().\n"), - (m_is_client == true) ? "client": "server")); - - const eap_status_e status = m_partner->save_simple_config_session( - state, - credential_array, - new_password, - Device_Password_ID, - other_configuration); - - EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); - return EAP_STATUS_RETURN(m_am_tools, status); -} - -#endif // #if defined(USE_EAP_SIMPLE_CONFIG) - -//-------------------------------------------------- - -// -EAP_FUNC_EXPORT eap_status_e eapol_core_c::set_eap_database_reference_values( - const eap_variable_data_c * const reference) -{ - EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); - - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("eapol_core_c::set_eap_database_reference_values()\n"))); - - EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::set_eap_database_reference_values()"); - - eap_status_e status(eap_status_ok); - - if (m_eap_core != 0) - { - status = m_eap_core->set_eap_database_reference_values(reference); - } - - EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); - return EAP_STATUS_RETURN(m_am_tools, status); -} - -//-------------------------------------------------- - -// -EAP_FUNC_EXPORT eap_status_e eapol_core_c::get_802_11_authentication_mode( - const eap_am_network_id_c * const receive_network_id, - const eapol_key_authentication_type_e authentication_type, - const eap_variable_data_c * const SSID, - const eap_variable_data_c * const preshared_key) -{ - EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); - - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("eapol_core_c::get_802_11_authentication_mode()\n"))); - - EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::get_802_11_authentication_mode()"); - - eap_status_e status(eap_status_ok); - - if (m_eap_core != 0) - { - status = m_eap_core->get_802_11_authentication_mode( - receive_network_id, - authentication_type, - SSID, - preshared_key); - } - - EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); - return EAP_STATUS_RETURN(m_am_tools, status); -} - -//-------------------------------------------------- - -// -EAP_FUNC_EXPORT eap_status_e eapol_core_c::complete_get_802_11_authentication_mode( - const eap_status_e completion_status, - const eap_am_network_id_c * const receive_network_id, - const eapol_key_802_11_authentication_mode_e mode) -{ - EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); - - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("eapol_core_c::complete_get_802_11_authentication_mode()\n"))); - - EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::complete_get_802_11_authentication_mode()"); - - eap_status_e status(eap_status_ok); - - if (m_partner != 0) - { - status = m_partner->complete_get_802_11_authentication_mode( - completion_status, - receive_network_id, - mode); - } - - EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); - return EAP_STATUS_RETURN(m_am_tools, status); -} - -//-------------------------------------------------- - -// -EAP_FUNC_EXPORT eap_status_e eapol_core_c::complete_remove_eap_session( - const bool complete_to_lower_layer, - const eap_am_network_id_c * const receive_network_id) -{ - EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); - - EAP_TRACE_DEBUG( - m_am_tools, - TRACE_FLAGS_DEFAULT, - (EAPL("eapol_core_c::complete_remove_eap_session()\n"))); - - EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::complete_remove_eap_session()"); - - eap_status_e status(eap_status_ok); - - if (m_partner != 0) - { - status = m_partner->complete_disassociation( - complete_to_lower_layer, - receive_network_id); - } - - EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); - return EAP_STATUS_RETURN(m_am_tools, status); -} - -//-------------------------------------------------- + + // End.