eapol/eapol_framework/eapol_common/type/gsmsim/core/eap_type_gsmsim.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
equal deleted inserted replaced
-1:000000000000 0:c8830336c852
       
     1 /*
       
     2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  EAP and WLAN authentication protocols.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // This is enumeration of EAPOL source code.
       
    20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    21 	#undef EAP_FILE_NUMBER_ENUM
       
    22 	#define EAP_FILE_NUMBER_ENUM 77 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 
       
    28 
       
    29 #include "eap_am_memory.h"
       
    30 #include "eap_tools.h"
       
    31 #include "eap_type_gsmsim.h"
       
    32 #include "eap_type_gsmsim_header.h"
       
    33 #include "eap_type_gsmsim_payloads.h"
       
    34 #include "eap_type_gsmsim_mac_attributes.h"
       
    35 #include "abs_eap_am_type_gsmsim.h"
       
    36 #include "eap_crypto_api.h"
       
    37 #include "eap_state_notification.h"
       
    38 #include "abs_eap_am_mutex.h"
       
    39 #include "eap_automatic_variable.h"
       
    40 #include "eap_am_type_gsmsim.h"
       
    41 
       
    42 
       
    43 //--------------------------------------------------
       
    44 
       
    45 /** @file */
       
    46 
       
    47 // 
       
    48 EAP_FUNC_EXPORT eap_type_gsmsim_c::~eap_type_gsmsim_c()
       
    49 {
       
    50 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    51 
       
    52 	EAP_TRACE_DEBUG(
       
    53 		m_am_tools, 
       
    54 		TRACE_FLAGS_DEFAULT, 
       
    55 		(EAPL("eap_type_gsmsim_c::~eap_type_gsmsim_c(): this = 0x%08x => 0x%08x\n"),
       
    56 		this,
       
    57 		dynamic_cast<abs_eap_base_timer_c *>(this)));
       
    58 
       
    59 	EAP_ASSERT(m_shutdown_was_called == true);
       
    60 
       
    61 	if (m_free_am_type_gsmsim == true
       
    62 		&& m_am_type_gsmsim != 0)
       
    63 	{
       
    64 		delete m_am_type_gsmsim;
       
    65 	}
       
    66 
       
    67 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    68 }
       
    69 
       
    70 //--------------------------------------------------
       
    71 
       
    72 #if defined(_WIN32) && !defined(__GNUC__)
       
    73 	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
       
    74 #endif
       
    75 
       
    76 // 
       
    77 EAP_FUNC_EXPORT eap_type_gsmsim_c::eap_type_gsmsim_c(
       
    78 	abs_eap_am_tools_c * const tools,
       
    79 	abs_eap_base_type_c * const partner,
       
    80 	eap_am_type_gsmsim_c * const am_type_gsmsim,
       
    81 	const bool free_am_type_gsmsim,
       
    82 	const bool is_client_when_true,
       
    83 	const eap_am_network_id_c * const receive_network_id)
       
    84 	: eap_base_type_c(tools, partner)
       
    85 	, m_am_tools(tools)
       
    86 	, m_state(eap_type_gsmsim_state_none)
       
    87 	, m_saved_previous_state(eap_type_gsmsim_state_none)
       
    88 	, m_send_network_id(m_am_tools)
       
    89 	, m_nonce_mt(m_am_tools)
       
    90 	, m_nonce_s(m_am_tools)
       
    91 	, m_IV(m_am_tools)
       
    92 	, m_saved_EAP_packet(m_am_tools)
       
    93 	, m_XKEY(m_am_tools)
       
    94 	, m_K_encr(m_am_tools)
       
    95 	, m_K_aut(m_am_tools)
       
    96 	, m_master_session_key(m_am_tools, eap_type_gsmsim)
       
    97 	, m_IMSI(m_am_tools)
       
    98 	, m_pseudonym(m_am_tools)
       
    99 	, m_reauthentication_identity(m_am_tools)
       
   100 	, m_automatic_realm(m_am_tools)
       
   101 	, m_automatic_realm_read(false)
       
   102 	, m_identity(m_am_tools)
       
   103 	, m_NAI(m_am_tools)
       
   104 	, m_n_rands(m_am_tools)
       
   105 	, m_n_sres(m_am_tools)
       
   106 	, m_gsmsim_version_list(m_am_tools)
       
   107 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
   108 	, m_triplets(0)
       
   109 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
   110 	, m_reauthentication_counter(0u)
       
   111 	, m_include_identity_to_start_response(gsmsim_payload_NONE)
       
   112 	, m_start_response_includes_identity(gsmsim_payload_NONE)
       
   113 	, m_failure_message_received(false)
       
   114 	, m_authentication_finished_successfully(false)
       
   115 	, m_last_eap_identifier(0)
       
   116 	, m_gsmsim_selected_version(GSMSIM_ILLEGAL_VERSION)
       
   117 	, m_2_digit_mnc_map_of_mcc_of_imsi_array(tools)
       
   118 	, m_uma_automatic_realm_prefix(tools)
       
   119 	, m_use_uma_profile(false)
       
   120 	, m_am_type_gsmsim(am_type_gsmsim)
       
   121 #if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS)
       
   122 	, m_nonce_mt_file(tools)
       
   123 #endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS)
       
   124 	, m_manual_username(tools)
       
   125 	, m_manual_realm(tools)
       
   126 	, m_gsmsim_header_offset(0u)
       
   127 	, m_MTU(0u)
       
   128 	, m_trailer_length(0u)
       
   129 	, m_minimum_rand_count(EAP_TYPE_GSMSIM_DEFAULT_MINIMUM_RAND_COUNT)
       
   130 	, m_length_of_mnc(EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES)
       
   131 	, m_authentication_type(GSMSIM_AUTHENTICATION_TYPE_NONE)
       
   132 	, m_identity_type(GSMSIM_IDENTITY_TYPE_NONE)
       
   133 	, m_client_error_code(eap_gsmsim_client_error_code_none)
       
   134 	, m_gsmsim_notification_code(eap_gsmsim_notification_none)
       
   135 	, m_failure_message_delay_time(EAP_TYPE_GSMSIM_TIMER_TIMEOUT_VALUE_DELAY_FAILURE_MESSAGE_SENT)
       
   136 	, m_is_valid(false)
       
   137 	, m_is_client(is_client_when_true)
       
   138 	, m_wait_eap_success_packet(true)
       
   139 	, m_check_identifier_of_eap_identity_response(false)
       
   140 	, m_free_am_type_gsmsim(free_am_type_gsmsim)
       
   141 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION)
       
   142 	, m_client_responds_retransmitted_packets(false)
       
   143 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION)
       
   144 	, m_gsmsim_test_version(false)
       
   145 	, m_gsmsim_randomly_refuse_eap_identity(false)
       
   146 	, m_check_nai_realm(false)
       
   147 	, m_fail_reauthentication_counter_check(false)
       
   148 	, m_accept_eap_identity_response(true)
       
   149 	, m_use_random_identity_on_eap_identity_response(false)
       
   150 	, m_shutdown_was_called(false)
       
   151 	, m_reset_was_called(false)
       
   152 	, m_do_rand_uniqueness_check(true)
       
   153 	, m_use_pseudonym_identity(true)
       
   154 	, m_use_reauthentication_identity(true)
       
   155 	, m_erroneus_packet_received(false)
       
   156 	, m_sim_notification_packet_received(false)
       
   157 	, m_use_manual_username(false)
       
   158 	, m_use_manual_realm(false)
       
   159 	, m_randomly_fail_successfull_authentication(false)
       
   160 	, m_allow_use_result_indication(true)
       
   161 	, m_use_result_indication(false)
       
   162 	, m_use_eap_expanded_type(false)
       
   163 {
       
   164 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   165 
       
   166 	EAP_TRACE_DEBUG(
       
   167 		m_am_tools, 
       
   168 		TRACE_FLAGS_DEFAULT, 
       
   169 		(EAPL("eap_type_gsmsim_c::eap_type_gsmsim_c(): this = 0x%08x => 0x%08x, ")
       
   170 		 EAPL("partner 0x%08x, type partner 0x%08x, compiled %s %s\n"),
       
   171 		 this,
       
   172 		 dynamic_cast<abs_eap_base_timer_c *>(this),
       
   173 		 partner,
       
   174 		 get_type_partner(),
       
   175 		__DATE__,
       
   176 		__TIME__));
       
   177 
       
   178 	// This is the only supported version.
       
   179 	m_supported_versions[0] = GSMSIM_VERSION_1;
       
   180 
       
   181 	if (m_am_type_gsmsim == 0)
       
   182 	{
       
   183 		// Something wrong with AM.
       
   184 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   185 		return;
       
   186 	}
       
   187 	m_am_type_gsmsim->set_am_partner(this);
       
   188 
       
   189 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   190 
       
   191 #if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   192 
       
   193 	initialize_state(eap_type_gsmsim_state_pending_kc_sres_query, false, false,
       
   194 		gsmsim_subtype_Notification,
       
   195 		gsmsim_subtype_Challenge, // Re-transmitted EAP-Request/SIM/Challenge is allowed.
       
   196 		gsmsim_subtype_NONE,
       
   197 		gsmsim_subtype_NONE);
       
   198 
       
   199 	initialize_state(eap_type_gsmsim_state_pending_triplet_query, false, false,
       
   200 		gsmsim_subtype_Notification,
       
   201 		gsmsim_subtype_Start, // Note EAP-Response/SIM/Start message is allowed here, eap_type_gsmsim_c::handle_start_response_message() will drop EAP-Response/SIM/Start message quietly.
       
   202 		gsmsim_subtype_Client_Error,
       
   203 		gsmsim_subtype_Challenge); // Re-transmitted EAP-Response/SIM/Challenge is allowed.
       
   204 
       
   205 	initialize_state(eap_type_gsmsim_state_waiting_for_start_request, false, false,
       
   206 		gsmsim_subtype_Notification,
       
   207 		gsmsim_subtype_Start,
       
   208 		gsmsim_subtype_NONE,
       
   209 		gsmsim_subtype_NONE);
       
   210 
       
   211 	initialize_state(eap_type_gsmsim_state_pseydonym_waiting_for_start_request, false, false,
       
   212 		gsmsim_subtype_Notification,
       
   213 		gsmsim_subtype_Start,
       
   214 		gsmsim_subtype_Re_authentication,
       
   215 		gsmsim_subtype_NONE);
       
   216 
       
   217 	initialize_state(eap_type_gsmsim_state_imsi_waiting_for_start_request, false, false,
       
   218 		gsmsim_subtype_Notification,
       
   219 		gsmsim_subtype_Start,
       
   220 		gsmsim_subtype_NONE,
       
   221 		gsmsim_subtype_NONE);
       
   222 
       
   223 	initialize_state(eap_type_gsmsim_state_waiting_for_start_response, true, false,
       
   224 		gsmsim_subtype_Notification,
       
   225 		gsmsim_subtype_Start,
       
   226 		gsmsim_subtype_Client_Error,
       
   227 		gsmsim_subtype_NONE);
       
   228 
       
   229 	initialize_state(eap_type_gsmsim_state_waiting_for_notification_request_success, false, true,
       
   230 		gsmsim_subtype_Notification,
       
   231 		gsmsim_subtype_Challenge,
       
   232 		gsmsim_subtype_Re_authentication,
       
   233 		gsmsim_subtype_NONE);
       
   234 
       
   235 	initialize_state(eap_type_gsmsim_state_waiting_for_notification_response_failure, true, false,
       
   236 		gsmsim_subtype_Notification,
       
   237 		gsmsim_subtype_NONE,
       
   238 		gsmsim_subtype_NONE,
       
   239 		gsmsim_subtype_NONE);
       
   240 
       
   241 	initialize_state(eap_type_gsmsim_state_waiting_for_notification_response_success, true, false,
       
   242 		gsmsim_subtype_Notification,
       
   243 		gsmsim_subtype_NONE,
       
   244 		gsmsim_subtype_NONE,
       
   245 		gsmsim_subtype_NONE);
       
   246 
       
   247 	initialize_state(eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity, true, false,
       
   248 		gsmsim_subtype_Notification,
       
   249 		gsmsim_subtype_Start,
       
   250 		gsmsim_subtype_Client_Error,
       
   251 		gsmsim_subtype_NONE);
       
   252 
       
   253 	initialize_state(eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity, true, false,
       
   254 		gsmsim_subtype_Notification,
       
   255 		gsmsim_subtype_Start,
       
   256 		gsmsim_subtype_Client_Error,
       
   257 		gsmsim_subtype_NONE);
       
   258 
       
   259 	initialize_state(eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity, true, false,
       
   260 		gsmsim_subtype_Notification,
       
   261 		gsmsim_subtype_Start,
       
   262 		gsmsim_subtype_Client_Error,
       
   263 		gsmsim_subtype_NONE);
       
   264 
       
   265 	initialize_state(eap_type_gsmsim_state_analyse_start_request, false, false,
       
   266 		gsmsim_subtype_Notification,
       
   267 		gsmsim_subtype_NONE,
       
   268 		gsmsim_subtype_NONE,
       
   269 		gsmsim_subtype_NONE);
       
   270 
       
   271 	initialize_state(eap_type_gsmsim_state_waiting_for_challenge_request, false, false,
       
   272 		gsmsim_subtype_Notification,
       
   273 		gsmsim_subtype_Challenge,
       
   274 		gsmsim_subtype_Start,
       
   275 		gsmsim_subtype_NONE);
       
   276 
       
   277 	initialize_state(eap_type_gsmsim_state_waiting_for_challenge_response, false, false,
       
   278 		gsmsim_subtype_Notification,
       
   279 		gsmsim_subtype_Challenge,
       
   280 		gsmsim_subtype_Start,
       
   281 		gsmsim_subtype_Client_Error);
       
   282 
       
   283 	initialize_state(eap_type_gsmsim_state_waiting_for_reauth_request, false, false,
       
   284 		gsmsim_subtype_Notification,
       
   285 		gsmsim_subtype_Re_authentication,
       
   286 		gsmsim_subtype_Start,
       
   287 		gsmsim_subtype_NONE);
       
   288 
       
   289 	initialize_state(eap_type_gsmsim_state_waiting_for_reauth_response, false, false,
       
   290 		gsmsim_subtype_Notification,
       
   291 		gsmsim_subtype_Re_authentication,
       
   292 		gsmsim_subtype_Start,
       
   293 		gsmsim_subtype_Client_Error);
       
   294 
       
   295 	initialize_state(eap_type_gsmsim_state_success, false, false,
       
   296 		gsmsim_subtype_Notification,
       
   297 		gsmsim_subtype_Challenge,
       
   298 		gsmsim_subtype_NONE,
       
   299 		gsmsim_subtype_NONE);
       
   300 
       
   301 	initialize_state(eap_type_gsmsim_state_waiting_for_success, false, false,
       
   302 		gsmsim_subtype_Notification,
       
   303 		gsmsim_subtype_Challenge,
       
   304 		gsmsim_subtype_Re_authentication,
       
   305 		gsmsim_subtype_NONE);
       
   306 
       
   307 	initialize_state(eap_type_gsmsim_state_failure, false, false,
       
   308 		gsmsim_subtype_NONE,
       
   309 		gsmsim_subtype_NONE,
       
   310 		gsmsim_subtype_NONE,
       
   311 		gsmsim_subtype_NONE);
       
   312 
       
   313 #endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   314 
       
   315 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   316 
       
   317 	{
       
   318 		// Here we swap the addresses.
       
   319 		eap_am_network_id_c send_network_id(m_am_tools,
       
   320 			receive_network_id->get_destination_id(),
       
   321 			receive_network_id->get_source_id(),
       
   322 			receive_network_id->get_type());
       
   323 
       
   324 		eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id);
       
   325 
       
   326 		if (status != eap_status_ok
       
   327 			|| m_send_network_id.get_is_valid_data() == false)
       
   328 		{
       
   329 			(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   330 			return;
       
   331 		}
       
   332 	}
       
   333 
       
   334 	set_is_valid();
       
   335 
       
   336 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   337 }
       
   338 
       
   339 //-----------------------------------------------
       
   340 
       
   341 #if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   342 
       
   343 //
       
   344 void eap_type_gsmsim_c::initialize_state(
       
   345 				const eap_type_gsmsim_state_variable_e state,
       
   346 				const bool must_be_initiator,
       
   347 				const bool must_be_responder,
       
   348 				const gsmsim_subtype_e type0,
       
   349 				const gsmsim_subtype_e type1,
       
   350 				const gsmsim_subtype_e type2,
       
   351 				const gsmsim_subtype_e type3)
       
   352 {
       
   353 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   354 
       
   355 	m_parameters[(state)].init_state(must_be_initiator, must_be_responder,
       
   356 		type0, type1, type2, type3);
       
   357 
       
   358 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   359 }
       
   360 
       
   361 #endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   362 
       
   363 //--------------------------------------------------
       
   364 
       
   365 /**
       
   366  * This function stores the last encryption IV. In CBC-mode previous encrypted block is
       
   367  * used as a IV of next block.
       
   368  */
       
   369 eap_status_e eap_type_gsmsim_c::store_last_encryption_iv(const eap_variable_data_c * const encryption_IV)
       
   370 {
       
   371 	return m_IV.get_payload_buffer()->set_copy_of_buffer(encryption_IV);
       
   372 }
       
   373 
       
   374 //--------------------------------------------------
       
   375 
       
   376 EAP_FUNC_EXPORT eap_gsmsim_version eap_type_gsmsim_c::select_version(
       
   377 	const gsmsim_variable_data_c * const version_payload,
       
   378 	bool * const includes_other_version_than_1)
       
   379 {
       
   380 	u32_t version_payload_length = version_payload->get_original_header()->get_data_length();
       
   381 	u32_t real_payload_length = version_payload->get_original_header()->get_reserved();
       
   382 	eap_gsmsim_version selected_version = GSMSIM_ILLEGAL_VERSION;
       
   383 
       
   384 	if (real_payload_length == 0
       
   385 		|| real_payload_length > version_payload_length)
       
   386 	{
       
   387 		return GSMSIM_ILLEGAL_VERSION;
       
   388 	}
       
   389 
       
   390 	u32_t version_count = real_payload_length/sizeof(u16_t);
       
   391 	u16_t *payload_version_list = reinterpret_cast<u16_t *>(version_payload->get_original_header()->get_data(real_payload_length));
       
   392 
       
   393 	for (u32_t ind = 0u; ind < version_count; ind++)
       
   394 	{
       
   395 		u8_t * const payload_version_network_order = reinterpret_cast<u8_t *>(&(payload_version_list[ind]));
       
   396 		u16_t payload_version_host_order
       
   397 			= eap_read_u16_t_network_order(payload_version_network_order, sizeof(u16_t));
       
   398 		if (payload_version_host_order == static_cast<u16_t>(GSMSIM_VERSION_1))
       
   399 		{
       
   400 			selected_version = static_cast<eap_gsmsim_version>(payload_version_host_order);
       
   401 		}
       
   402 		else if (payload_version_host_order != static_cast<u16_t>(GSMSIM_VERSION_1))
       
   403 		{
       
   404 			*includes_other_version_than_1 = true;
       
   405 		}
       
   406 	}
       
   407 
       
   408 	return selected_version;
       
   409 }
       
   410 
       
   411 //--------------------------------------------------
       
   412 
       
   413 EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_identity_string(const eap_type_gsmsim_identity_type identity_type)
       
   414 {
       
   415 #if defined(USE_EAP_TRACE_STRINGS)
       
   416 	EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_NONE)
       
   417 	else EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_IMSI_ID)
       
   418 	else EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID)
       
   419 	else EAP_IF_RETURN_STRING(identity_type, GSMSIM_IDENTITY_TYPE_RE_AUTH_ID)
       
   420 	else
       
   421 #endif // #if defined(USE_EAP_TRACE_STRINGS)
       
   422 	{
       
   423 		EAP_UNREFERENCED_PARAMETER(identity_type);
       
   424 		return EAPL("Unknown AKA identity");
       
   425 	}
       
   426 }
       
   427 
       
   428 //--------------------------------------------------
       
   429 
       
   430 EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_state_string(eap_type_gsmsim_state_variable_e state)
       
   431 {
       
   432 
       
   433 #if defined(USE_EAP_TRACE_STRINGS)
       
   434 	EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_identity_request)
       
   435 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_identity_query)
       
   436 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_request)
       
   437 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_imsi_waiting_for_start_request)
       
   438 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pseydonym_waiting_for_start_request)
       
   439 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyse_start_request)
       
   440 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_challenge_request)
       
   441 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_challenge_request)
       
   442 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_kc_sres_query)
       
   443 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_success)
       
   444 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_reauth_request)
       
   445 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_reauthentication_request)
       
   446 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_pseudonym_decode_query)
       
   447 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_identity_response)
       
   448 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response_with_at_permanent_identity)
       
   449 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response_with_at_full_auth_identity)
       
   450 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response_with_at_any_identity)
       
   451 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_start_response)
       
   452 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_challenge_response)
       
   453 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_pending_triplet_query)
       
   454 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_challenge_response)
       
   455 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_start_response)
       
   456 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_notification_request_success)
       
   457 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_notification_response_failure)
       
   458 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_notification_response_success)
       
   459 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_waiting_for_reauth_response)
       
   460 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_analyses_reauthentication_response)
       
   461 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_success)
       
   462 	else EAP_IF_RETURN_STRING(state, eap_type_gsmsim_state_failure)
       
   463 	else
       
   464 #else
       
   465 EAP_UNREFERENCED_PARAMETER(state);
       
   466 #endif // #if defined(USE_EAP_TRACE_STRINGS)
       
   467 	{
       
   468 		return EAPL("Unknown GSMSIM state");
       
   469 	}
       
   470 }
       
   471 
       
   472 //--------------------------------------------------
       
   473 
       
   474 EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_state_string() const
       
   475 {
       
   476 	return get_state_string(m_state);
       
   477 }
       
   478 
       
   479 //--------------------------------------------------
       
   480 
       
   481 EAP_FUNC_EXPORT eap_const_string eap_type_gsmsim_c::get_saved_previous_state_string() const
       
   482 {
       
   483 	return get_state_string(m_saved_previous_state);
       
   484 }
       
   485 
       
   486 //--------------------------------------------------
       
   487 
       
   488 /**
       
   489  * This function sets the new state and notifies the lower layer of this change.
       
   490  */
       
   491 void eap_type_gsmsim_c::set_state(eap_type_gsmsim_state_variable_e state)
       
   492 {
       
   493 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   494 	
       
   495 	eap_type_gsmsim_state_variable_e previous_state = m_state;
       
   496 	
       
   497 	EAP_TRACE_DEBUG(
       
   498 		m_am_tools, 
       
   499 		TRACE_FLAGS_DEFAULT, 
       
   500 		(EAPL("eap_type_gsmsim_c::set_state(): old state %d=%s\n"),
       
   501 		 m_state,
       
   502 		 get_state_string()));
       
   503 
       
   504 	EAP_TRACE_DEBUG(
       
   505 		m_am_tools, 
       
   506 		TRACE_FLAGS_DEFAULT, 
       
   507 		(EAPL("eap_type_gsmsim_c::set_state(): new state %d=%s\n"),
       
   508 		 state,
       
   509 		 get_state_string(state)));
       
   510 
       
   511 	m_state = state;
       
   512 	
       
   513 	eap_type_gsmsim_state_notification_c notification(
       
   514 		m_am_tools,
       
   515 		&m_send_network_id,
       
   516 		m_is_client,
       
   517 		eap_state_notification_eap,
       
   518 		eap_protocol_layer_eap_type,
       
   519 		eap_type_gsmsim,
       
   520 		previous_state,
       
   521 		state,
       
   522 		m_last_eap_identifier,
       
   523 		false);
       
   524 	state_notification(&notification);
       
   525 	
       
   526 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   527 }
       
   528 
       
   529 //--------------------------------------------------
       
   530 
       
   531 #if defined(USE_EAP_GSMSIM_VERIFY_STATES)
       
   532 
       
   533 /**
       
   534  * This function checks the valid states.
       
   535  */
       
   536 bool eap_type_gsmsim_c::verify_states(
       
   537 	const eap_type_gsmsim_state_variable_e * const valid_states,
       
   538 	const u32_t count) const
       
   539 {
       
   540 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   541 
       
   542 	for (u32_t ind = 0ul; ind < count; ind++)
       
   543 	{
       
   544 		if (m_state == valid_states[ind])
       
   545 		{
       
   546 			return true;
       
   547 		}
       
   548 	}
       
   549 
       
   550 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   551 	return false;
       
   552 }
       
   553 
       
   554 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES)
       
   555 
       
   556 //--------------------------------------------------
       
   557 
       
   558 #if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   559 
       
   560 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_valid_state(gsmsim_subtype_e type)
       
   561 {
       
   562 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   563 	const eap_type_gsmsim_state_variable_parameters_c * const state_variable = get_state_variable();
       
   564 
       
   565 	if (state_variable == 0)
       
   566 	{
       
   567 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   568 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state);
       
   569 	}
       
   570 
       
   571 	if (state_variable->check_initiator(!get_is_client()) == false)
       
   572 	{
       
   573 		EAP_TRACE_DEBUG(
       
   574 			m_am_tools,
       
   575 			TRACE_FLAGS_GSMSIM_ERROR,
       
   576 			(EAPL("ERROR: eap_type_gsmsim_state_c::check_valid_state(): Initiator type %d is wrong in eap_type_gsmsim_state_variable_e %d=%s.\n"),
       
   577 			get_is_client(), m_state, get_state_string()));
       
   578 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   579 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state);
       
   580 	}
       
   581 
       
   582 	if (state_variable->check_valid_types(type) == false)
       
   583 	{
       
   584 		EAP_TRACE_DEBUG(
       
   585 			m_am_tools,
       
   586 			TRACE_FLAGS_GSMSIM_ERROR,
       
   587 			(EAPL("ERROR: eap_type_gsmsim_state_c::check_valid_state(): gsmsim_subtype_e %d is wrong in eap_type_gsmsim_state_variable_e %d=%s.\n"),
       
   588 			type, m_state, get_state_string()));
       
   589 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   590 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_subtype);
       
   591 	}
       
   592 
       
   593 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   594 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   595 }
       
   596 
       
   597 #endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   598 
       
   599 //--------------------------------------------------
       
   600 
       
   601 #if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   602 
       
   603 EAP_FUNC_EXPORT const eap_type_gsmsim_state_variable_parameters_c * eap_type_gsmsim_c::get_state_variable()
       
   604 {
       
   605 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   606 	if (m_state < eap_type_gsmsim_state_last_value)
       
   607 	{
       
   608 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   609 		return &(m_parameters[m_state]);
       
   610 	}
       
   611 	else
       
   612 	{
       
   613 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   614 		return 0;
       
   615 	}
       
   616 }
       
   617 
       
   618 #endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
   619 
       
   620 //--------------------------------------------------
       
   621 
       
   622 /**
       
   623  * This function saves the current m_state to m_saved_previous_state.
       
   624  * The saved state is restored in error case.
       
   625  */
       
   626 void eap_type_gsmsim_c::save_current_state()
       
   627 {
       
   628 	m_saved_previous_state = m_state;
       
   629 }
       
   630 
       
   631 //--------------------------------------------------
       
   632 
       
   633 /**
       
   634  * This function restores the saved state.
       
   635  */
       
   636 void eap_type_gsmsim_c::restore_saved_previous_state()
       
   637 {
       
   638 	set_state(m_saved_previous_state);
       
   639 }
       
   640 
       
   641 //--------------------------------------------------
       
   642 
       
   643 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::store_identity(
       
   644 	const eap_variable_data_c * const IMSI_or_pseudonym,
       
   645 	const bool IMSI_is_used)
       
   646 {
       
   647 	eap_status_e status = m_identity.init(IMSI_or_pseudonym->get_data_length()+1u);
       
   648 	if (status != eap_status_ok)
       
   649 	{
       
   650 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   651 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   652 	}
       
   653 	m_identity.set_is_valid();
       
   654 
       
   655 	if (IMSI_is_used == true)
       
   656 	{
       
   657 		// Note the first octet is reserved for IMSI prefix.
       
   658 		status = m_identity.set_copy_of_buffer(GSMSIM_IMSI_PREFIX_CHARACTER, 1u);
       
   659 		if (status != eap_status_ok)
       
   660 		{
       
   661 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   662 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   663 		}
       
   664 	}
       
   665 
       
   666 	status = m_identity.add_data(IMSI_or_pseudonym);
       
   667 	if (status != eap_status_ok)
       
   668 	{
       
   669 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   670 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   671 	}
       
   672 
       
   673 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   674 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   675 }
       
   676 
       
   677 //--------------------------------------------------
       
   678 
       
   679 /// not used: expansion_0 = prf(key, seed | 0)
       
   680 /// not used: expansion_i = prf(key, expansion_i-1 | seed | i), where i = 1, 2...
       
   681 
       
   682 /// The following is from "DIGITAL SIGNATURE STANDARD (DSS)" FIPS PUB 186-2:
       
   683 /// Let x be the signer's private key. The following may be used to generate m values of x:
       
   684 /// Step 1. Choose a new, secret value for the seed-key, XKEY.
       
   685 /// Step 2. In hexadecimal notation let
       
   686 ///             t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0.
       
   687 ///             This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS.
       
   688 /// Step 3. For j = 0 to m - 1 do
       
   689 ///             a. XSEEDj = optional user input.
       
   690 ///             b. XVAL = (XKEY + XSEEDj) mod 2^b.
       
   691 ///             c. xj = G(t,XVAL) mod q.
       
   692 ///             d. XKEY = (1 + XKEY + xj) mod 2^b.
       
   693 /// 
       
   694 /// Within GSMSIM the following parameters are used:
       
   695 /// 160-bit XKEY and XVAL values are used, so b = 160.
       
   696 /// XKEY = SHA1(n*Kc| NONCE_MT)
       
   697 /// The optional user input values (XSEED_j) are set to zero.
       
   698 /// xj = G(t, XVAL)
       
   699 
       
   700 /// Random generator become as follows:
       
   701 /// Step 1. Choose a new, secret value for the seed-key, XKEY.
       
   702 /// Step 2. In hexadecimal notation let
       
   703 ///             t = 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0.
       
   704 ///             This is the initial value for H0 || H1 || H2 || H3 || H4 in the SHS.
       
   705 /// Step 3. For j = 0 to m - 1 do
       
   706 ///             c. xj = G(t,XKEY).
       
   707 ///             d. XKEY = (1 + XKEY + xj) mod 2^b.
       
   708 
       
   709 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::data_exp(
       
   710 	const u32_t data_length,
       
   711 	eap_variable_data_c * const expansion,
       
   712 	const eap_variable_data_c * const key,
       
   713 	const eap_variable_data_c * const seed)
       
   714 {
       
   715 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   716 	eap_status_e status = eap_status_process_general_error;
       
   717 
       
   718 	EAP_UNREFERENCED_PARAMETER(seed);
       
   719 
       
   720 	u32_t count = data_length/EAP_TYPE_GSMSIM_KEYMAT_SIZE;
       
   721 	if ((data_length % EAP_TYPE_GSMSIM_KEYMAT_SIZE) != 0)
       
   722 	{
       
   723 		++count;
       
   724 	}
       
   725 
       
   726 	status = expansion->init(count*EAP_TYPE_GSMSIM_KEYMAT_SIZE);
       
   727 	if (status != eap_status_ok)
       
   728 	{
       
   729 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   730 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   731 	}
       
   732 	expansion->set_is_valid();
       
   733 	expansion->set_data_length(count*EAP_TYPE_GSMSIM_KEYMAT_SIZE);
       
   734 
       
   735 	status = m_am_tools->get_crypto()->dss_pseudo_random(
       
   736 		expansion->get_data(),
       
   737 		expansion->get_data_length(),
       
   738 		key->get_data(),
       
   739 		key->get_data_length());
       
   740 
       
   741 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   742 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   743 }
       
   744 
       
   745 //--------------------------------------------------
       
   746 
       
   747 //
       
   748 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_shared_secred_keys(
       
   749 	const u32_t key_length,
       
   750 	const eap_variable_data_c * const n_Kc,
       
   751 	const eap_variable_data_c * const n_sres,
       
   752 	eap_variable_data_c * const XKEY,
       
   753 	eap_variable_data_c * const K_encr,
       
   754 	eap_variable_data_c * const K_aut,
       
   755 	eap_variable_data_c * const master_session_key)
       
   756 {
       
   757 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   758 
       
   759 	EAP_UNREFERENCED_PARAMETER(n_sres);
       
   760 
       
   761 	u16_t selected_version = eap_htons(static_cast<u16_t>(m_gsmsim_selected_version));
       
   762 
       
   763 	EAP_TRACE_DEBUG(
       
   764 		m_am_tools,
       
   765 		TRACE_FLAGS_DEFAULT,
       
   766 		(EAPL("generate_shared_secred_keys():\n")));
       
   767 
       
   768 	if (m_NAI.get_is_valid_data() == false)
       
   769 	{
       
   770 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   771 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai);
       
   772 	}
       
   773 	EAP_TRACE_DATA_DEBUG(
       
   774 		m_am_tools,
       
   775 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   776 		(EAPL("full auth NAI"),
       
   777 		m_NAI.get_data(),
       
   778 		m_NAI.get_data_length()));
       
   779 
       
   780 	if (n_Kc->get_is_valid_data() == false)
       
   781 	{
       
   782 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   783 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   784 	}
       
   785 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*Kc"),
       
   786 		n_Kc->get_data(),
       
   787 		n_Kc->get_data_length()));
       
   788 
       
   789 	if (n_sres->get_is_valid_data() == false)
       
   790 	{
       
   791 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   792 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   793 	}
       
   794 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*SRES"),
       
   795 		n_sres->get_data(),
       
   796 		n_sres->get_data_length()));
       
   797 
       
   798 	if (m_nonce_mt.get_is_valid_data() == false)
       
   799 	{
       
   800 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   801 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   802 	}
       
   803 	EAP_TRACE_DATA_DEBUG(
       
   804 		m_am_tools,
       
   805 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   806 		(EAPL("NONCE MT"),
       
   807 		m_nonce_mt.get_data(),
       
   808 		m_nonce_mt.get_data_length()));
       
   809 
       
   810 	if (m_gsmsim_version_list.get_is_valid_data() == false)
       
   811 	{
       
   812 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   813 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   814 	}
       
   815 	EAP_TRACE_DATA_DEBUG(
       
   816 		m_am_tools,
       
   817 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   818 		(EAPL("version list"),
       
   819 		m_gsmsim_version_list.get_data(),
       
   820 		m_gsmsim_version_list.get_data_length()));
       
   821 
       
   822 	EAP_TRACE_DATA_DEBUG(
       
   823 		m_am_tools,
       
   824 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   825 		(EAPL("selected version"),
       
   826 		&selected_version,
       
   827 		sizeof(selected_version)));
       
   828 
       
   829 	eap_status_e status = eap_status_process_general_error;
       
   830 
       
   831 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
   832 
       
   833 	// XKEY = SHA1(NAI | n*Kc | NONCE_MT | Version List | Selected Version)
       
   834 
       
   835 	crypto_sha1_c sha1(m_am_tools);
       
   836 
       
   837 	if (sha1.get_is_valid() == false)
       
   838 	{
       
   839 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   840 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   841 	}
       
   842 
       
   843 	if (sha1.hash_init() != eap_status_ok)
       
   844 	{
       
   845 		EAP_TRACE_ERROR(
       
   846 			m_am_tools,
       
   847 			TRACE_FLAGS_GSMSIM_ERROR,
       
   848 			(EAPL("ERROR: generate_shared_secred_keys(): init() failed.\n")));
       
   849 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   850 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   851 	}
       
   852 
       
   853 	status = sha1.hash_update(
       
   854 		m_NAI.get_data(),
       
   855 		m_NAI.get_data_length());
       
   856 	if (status != eap_status_ok)
       
   857 	{
       
   858 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   859 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   860 	}
       
   861 
       
   862 	status = sha1.hash_update(
       
   863 		n_Kc->get_data(),
       
   864 		n_Kc->get_data_length());
       
   865 	if (status != eap_status_ok)
       
   866 	{
       
   867 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   868 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   869 	}
       
   870 
       
   871 	status = sha1.hash_update(
       
   872 		m_nonce_mt.get_data(),
       
   873 		m_nonce_mt.get_data_length());
       
   874 	if (status != eap_status_ok)
       
   875 	{
       
   876 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   877 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   878 	}
       
   879 
       
   880 	status = sha1.hash_update(
       
   881 		m_gsmsim_version_list.get_data(),
       
   882 		m_gsmsim_version_list.get_data_length());
       
   883 	if (status != eap_status_ok)
       
   884 	{
       
   885 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   886 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   887 	}
       
   888 
       
   889 	status = sha1.hash_update(
       
   890 		reinterpret_cast<u8_t *>(&selected_version),
       
   891 		sizeof(selected_version));
       
   892 	if (status != eap_status_ok)
       
   893 	{
       
   894 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   895 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   896 	}
       
   897 
       
   898 	status = XKEY->init(key_length);
       
   899 	if (status != eap_status_ok)
       
   900 	{
       
   901 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   902 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   903 	}
       
   904 	XKEY->set_is_valid();
       
   905 	XKEY->set_data_length(key_length);
       
   906 
       
   907 	u32_t md_length = key_length;
       
   908 
       
   909 	status = sha1.hash_final(
       
   910 		XKEY->get_data_offset(0u, key_length),
       
   911 		&md_length);
       
   912 	if (status != eap_status_ok)
       
   913 	{
       
   914 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   915 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   916 	}
       
   917 
       
   918 	EAP_ASSERT_ALWAYS(md_length == key_length);
       
   919 
       
   920 
       
   921 	EAP_TRACE_DEBUG(
       
   922 		m_am_tools,
       
   923 		TRACE_FLAGS_DEFAULT,
       
   924 		(EAPL("generate_shared_secred_keys(): XKEY\n")));
       
   925 	EAP_TRACE_DATA_DEBUG(
       
   926 		m_am_tools,
       
   927 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   928 		(EAPL("     XKEY"),
       
   929 		XKEY->get_data(),
       
   930 		XKEY->get_data_length()));
       
   931 
       
   932 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
   933 
       
   934 	u32_t aes_key_length = m_am_tools->get_crypto()->aes_key_length();
       
   935 	u32_t data_length = aes_key_length + EAP_TYPE_GSMSIM_MAC_SIZE + EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE;
       
   936 
       
   937 	eap_variable_data_c expansion(m_am_tools);
       
   938 	eap_variable_data_c seed(m_am_tools);
       
   939 
       
   940 	status = seed.add_data(&m_NAI);
       
   941 	if (status != eap_status_ok)
       
   942 	{
       
   943 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   944 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   945 	}
       
   946 
       
   947 	status = data_exp(
       
   948 		data_length,
       
   949 		&expansion,
       
   950 		XKEY,
       
   951 		&seed);
       
   952 	if (status != eap_status_ok)
       
   953 	{
       
   954 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   955 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   956 	}
       
   957 
       
   958 	EAP_TRACE_DEBUG(
       
   959 		m_am_tools,
       
   960 		TRACE_FLAGS_DEFAULT,
       
   961 		(EAPL("generate_shared_secred_keys(): expansion\n")));
       
   962 	EAP_TRACE_DATA_DEBUG(
       
   963 		m_am_tools,
       
   964 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   965 		(EAPL("expansion"),
       
   966 		expansion.get_data(),
       
   967 		expansion.get_data_length()));
       
   968 
       
   969 	u8_t *data = expansion.get_data_offset(0u, data_length);
       
   970 	if (data == 0)
       
   971 	{
       
   972 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   973 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   974 	}
       
   975 	const u8_t * const data_begin = data;
       
   976 
       
   977 	EAP_UNREFERENCED_PARAMETER(data_begin);
       
   978 
       
   979 	// K_encr, K_aut and master_session_key
       
   980 
       
   981 	status = K_encr->set_copy_of_buffer(data, aes_key_length);
       
   982 	if (status != eap_status_ok)
       
   983 	{
       
   984 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   985 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   986 	}
       
   987 	data += aes_key_length;
       
   988 	EAP_ASSERT_ALWAYS(static_cast<u32_t>(data-data_begin) <= data_length);
       
   989 
       
   990 	status = K_aut->set_copy_of_buffer(data, EAP_TYPE_GSMSIM_MAC_SIZE);
       
   991 	if (status != eap_status_ok)
       
   992 	{
       
   993 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   994 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   995 	}
       
   996 	data += EAP_TYPE_GSMSIM_MAC_SIZE;
       
   997 	EAP_ASSERT_ALWAYS(static_cast<u32_t>(data-data_begin) <= data_length);
       
   998 
       
   999 	status = master_session_key->set_copy_of_buffer(data, EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE);
       
  1000 	if (status != eap_status_ok)
       
  1001 	{
       
  1002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1004 	}
       
  1005 	data += EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE;
       
  1006 	EAP_ASSERT_ALWAYS(static_cast<u32_t>(data-data_begin) <= data_length);
       
  1007 
       
  1008 
       
  1009 	EAP_TRACE_DEBUG(
       
  1010 		m_am_tools,
       
  1011 		TRACE_FLAGS_DEFAULT,
       
  1012 		(EAPL("generate_shared_secred_keys(): K_encr\n")));
       
  1013 	EAP_TRACE_DATA_DEBUG(
       
  1014 		m_am_tools,
       
  1015 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1016 		(EAPL("   K_encr"),
       
  1017 		K_encr->get_data(),
       
  1018 		K_encr->get_data_length()));
       
  1019 
       
  1020 	EAP_TRACE_DEBUG(
       
  1021 		m_am_tools,
       
  1022 		TRACE_FLAGS_DEFAULT,
       
  1023 		(EAPL("generate_shared_secred_keys(): K_aut\n")));
       
  1024 	EAP_TRACE_DATA_DEBUG(
       
  1025 		m_am_tools,
       
  1026 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1027 		(EAPL("    K_aut"),
       
  1028 		K_aut->get_data(),
       
  1029 		K_aut->get_data_length()));
       
  1030 
       
  1031 	EAP_TRACE_DEBUG(
       
  1032 		m_am_tools,
       
  1033 		TRACE_FLAGS_DEFAULT,
       
  1034 		(EAPL("generate_shared_secred_keys(): master_session_key\n")));
       
  1035 	EAP_TRACE_DATA_DEBUG(
       
  1036 		m_am_tools,
       
  1037 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1038 		(EAPL(" MSK+EMSK"),
       
  1039 		master_session_key->get_data(),
       
  1040 		master_session_key->get_data_length()));
       
  1041 
       
  1042 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1043 
       
  1044 
       
  1045 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1046 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1047 }
       
  1048 
       
  1049 //--------------------------------------------------
       
  1050 
       
  1051 //
       
  1052 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_reauth_shared_secred_keys(
       
  1053 	const u32_t key_length,
       
  1054 	const eap_variable_data_c * const orig_XKEY,
       
  1055 	const u32_t reauth_counter,
       
  1056 	const eap_variable_data_c * const reauth_identity,
       
  1057 	const eap_variable_data_c * const reauth_nonce_s,
       
  1058 	eap_variable_data_c * const master_session_key)
       
  1059 {
       
  1060 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1061 
       
  1062 	u16_t counter = eap_htons(static_cast<u16_t>(reauth_counter));
       
  1063 	eap_variable_data_c reauth_XKEY(m_am_tools);
       
  1064 
       
  1065 	EAP_TRACE_DEBUG(
       
  1066 		m_am_tools,
       
  1067 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1068 		(EAPL("generate_reauth_shared_secred_keys():\n")));
       
  1069 	EAP_TRACE_DATA_DEBUG(
       
  1070 		m_am_tools,
       
  1071 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1072 		(EAPL("reauth NAI"),
       
  1073 		reauth_identity->get_data(),
       
  1074 		reauth_identity->get_data_length()));
       
  1075 	EAP_TRACE_DATA_DEBUG(
       
  1076 		m_am_tools,
       
  1077 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1078 		(EAPL("reauth_counter"),
       
  1079 		&counter,
       
  1080 		sizeof(counter)));
       
  1081 	EAP_TRACE_DATA_DEBUG(
       
  1082 		m_am_tools,
       
  1083 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1084 		(EAPL("NONCE_S"),
       
  1085 		reauth_nonce_s->get_data(),
       
  1086 		reauth_nonce_s->get_data_length()));
       
  1087 	EAP_TRACE_DATA_DEBUG(
       
  1088 		m_am_tools,
       
  1089 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1090 		(EAPL("orig_XKEY"),
       
  1091 		orig_XKEY->get_data(),
       
  1092 		orig_XKEY->get_data_length()));
       
  1093 
       
  1094 	eap_status_e status = eap_status_process_general_error;
       
  1095 
       
  1096 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1097 
       
  1098 	// XKEY = SHA1(Identity|counter|NONCE_S|original XKEY)
       
  1099 
       
  1100 	crypto_sha1_c sha1(m_am_tools);
       
  1101 
       
  1102 	if (sha1.get_is_valid() == false)
       
  1103 	{
       
  1104 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1105 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1106 	}
       
  1107 
       
  1108 	if (sha1.hash_init() != eap_status_ok)
       
  1109 	{
       
  1110 		EAP_TRACE_ERROR(
       
  1111 			m_am_tools,
       
  1112 			TRACE_FLAGS_GSMSIM_ERROR,
       
  1113 			(EAPL("ERROR: generate_reauth_shared_secred_keys(): init() failed.\n")));
       
  1114 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1115 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1116 	}
       
  1117 
       
  1118 	status = sha1.hash_update(
       
  1119 		reauth_identity->get_data(),
       
  1120 		reauth_identity->get_data_length());
       
  1121 	if (status != eap_status_ok)
       
  1122 	{
       
  1123 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1124 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1125 	}
       
  1126 
       
  1127 	status = sha1.hash_update(
       
  1128 		&counter,
       
  1129 		sizeof(counter));
       
  1130 	if (status != eap_status_ok)
       
  1131 	{
       
  1132 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1133 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1134 	}
       
  1135 
       
  1136 	status = sha1.hash_update(
       
  1137 		reauth_nonce_s->get_data(),
       
  1138 		reauth_nonce_s->get_data_length());
       
  1139 	if (status != eap_status_ok)
       
  1140 	{
       
  1141 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1142 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1143 	}
       
  1144 
       
  1145 	status = sha1.hash_update(
       
  1146 		orig_XKEY->get_data(),
       
  1147 		orig_XKEY->get_data_length());
       
  1148 	if (status != eap_status_ok)
       
  1149 	{
       
  1150 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1151 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1152 	}
       
  1153 
       
  1154 	status = reauth_XKEY.init(key_length);
       
  1155 	if (status != eap_status_ok)
       
  1156 	{
       
  1157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1158 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1159 	}
       
  1160 	reauth_XKEY.set_is_valid();
       
  1161 	reauth_XKEY.set_data_length(key_length);
       
  1162 
       
  1163 	u32_t md_length = key_length;
       
  1164 
       
  1165 	status = sha1.hash_final(
       
  1166 		reauth_XKEY.get_data_offset(0u, key_length),
       
  1167 		&md_length);
       
  1168 	if (status != eap_status_ok)
       
  1169 	{
       
  1170 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1171 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1172 	}
       
  1173 
       
  1174 	EAP_ASSERT_ALWAYS(md_length == key_length);
       
  1175 
       
  1176 
       
  1177 	EAP_TRACE_DEBUG(
       
  1178 		m_am_tools,
       
  1179 		TRACE_FLAGS_DEFAULT,
       
  1180 		(EAPL("generate_reauth_shared_secred_keys(): reauth_XKEY\n")));
       
  1181 	EAP_TRACE_DATA_DEBUG(
       
  1182 		m_am_tools,
       
  1183 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1184 		(EAPL("reauth_XKEY"),
       
  1185 		reauth_XKEY.get_data(),
       
  1186 		reauth_XKEY.get_data_length()));
       
  1187 
       
  1188 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1189 
       
  1190 	u32_t aes_key_length = m_am_tools->get_crypto()->aes_key_length();
       
  1191 	u32_t data_length = aes_key_length + EAP_TYPE_GSMSIM_MAC_SIZE + EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE;
       
  1192 
       
  1193 	eap_variable_data_c expansion(m_am_tools);
       
  1194 	eap_variable_data_c seed(m_am_tools);
       
  1195 
       
  1196 	status = seed.add_data(&m_NAI);
       
  1197 	if (status != eap_status_ok)
       
  1198 	{
       
  1199 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1200 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1201 	}
       
  1202 
       
  1203 	status = data_exp(
       
  1204 		data_length,
       
  1205 		&expansion,
       
  1206 		&reauth_XKEY,
       
  1207 		&seed);
       
  1208 	if (status != eap_status_ok)
       
  1209 	{
       
  1210 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1211 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1212 	}
       
  1213 
       
  1214 	EAP_TRACE_DEBUG(
       
  1215 		m_am_tools,
       
  1216 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1217 		(EAPL("generate_reauth_shared_secred_keys(): expansion\n")));
       
  1218 	EAP_TRACE_DATA_DEBUG(
       
  1219 		m_am_tools,
       
  1220 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1221 		(EAPL("expansion"),
       
  1222 		expansion.get_data(),
       
  1223 		expansion.get_data_length()));
       
  1224 
       
  1225 	u8_t *data = expansion.get_data_offset(0u, data_length);
       
  1226 	if (data == 0)
       
  1227 	{
       
  1228 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1229 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1230 	}
       
  1231 	const u8_t * const data_begin = data;
       
  1232 
       
  1233 	EAP_UNREFERENCED_PARAMETER(data_begin);
       
  1234 
       
  1235 	// Only master_session_key is used in re-authentication.
       
  1236 
       
  1237 	status = master_session_key->set_copy_of_buffer(data, EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE);
       
  1238 	if (status != eap_status_ok)
       
  1239 	{
       
  1240 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1241 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1242 	}
       
  1243 	data += EAP_TYPE_GSMSIM_MASTER_SESSION_KEY_SIZE;
       
  1244 	EAP_ASSERT_ALWAYS(static_cast<u32_t>(data-data_begin) <= data_length);
       
  1245 
       
  1246 
       
  1247 	EAP_TRACE_DEBUG(
       
  1248 		m_am_tools,
       
  1249 		TRACE_FLAGS_DEFAULT,
       
  1250 		(EAPL("generate_reauth_shared_secred_keys(): master_session_key\n")));
       
  1251 	EAP_TRACE_DATA_DEBUG(
       
  1252 		m_am_tools,
       
  1253 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1254 		(EAPL("     MSK+EMSK"),
       
  1255 		master_session_key->get_data(),
       
  1256 		master_session_key->get_data_length()));
       
  1257 
       
  1258 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1259 
       
  1260 
       
  1261 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1262 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1263 }
       
  1264 
       
  1265 //--------------------------------------------------
       
  1266 
       
  1267 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  1268 /**
       
  1269  * This function stores pointer to the received triplet array.
       
  1270  */
       
  1271 void eap_type_gsmsim_c::set_triplets(eap_type_sim_triplet_array_c * const triplets)
       
  1272 {
       
  1273 	if (m_triplets != 0)
       
  1274 	{
       
  1275 		delete m_triplets;
       
  1276 		m_triplets = 0;
       
  1277 	}
       
  1278 	m_triplets = triplets;
       
  1279 }
       
  1280 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  1281 
       
  1282 //--------------------------------------------------
       
  1283 
       
  1284 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::save_version(
       
  1285 	const u16_t * const payload_version_list,
       
  1286 	const u32_t version_count,
       
  1287 	const eap_gsmsim_version selected_version)
       
  1288 {
       
  1289 	m_gsmsim_selected_version = selected_version;
       
  1290 
       
  1291 	eap_status_e status = m_gsmsim_version_list.set_copy_of_buffer(
       
  1292 		payload_version_list,
       
  1293 		sizeof(payload_version_list[0])*version_count);
       
  1294 
       
  1295 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1296 }
       
  1297 
       
  1298 //--------------------------------------------------
       
  1299 
       
  1300 EAP_FUNC_EXPORT bool eap_type_gsmsim_c::random_selection()
       
  1301 {
       
  1302 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1303 
       
  1304 	crypto_random_c rand(m_am_tools);
       
  1305 
       
  1306 	if (rand.get_is_valid() == false)
       
  1307 	{
       
  1308 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1309 		return false;
       
  1310 	}
       
  1311 
       
  1312 	return (rand.get_rand_integer(0, 1) != 0);
       
  1313 }
       
  1314 
       
  1315 //--------------------------------------------------
       
  1316 
       
  1317 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_final_notification()
       
  1318 {
       
  1319 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1320 
       
  1321 	if (m_is_valid == true)
       
  1322 	{
       
  1323 		if (m_is_client == true
       
  1324 			&& m_n_rands.get_is_valid_data() == true)
       
  1325 		{
       
  1326 			eap_status_e status = m_am_type_gsmsim->set_rand_is_used(&m_n_rands);
       
  1327 			if (status != eap_status_ok)
       
  1328 			{
       
  1329 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1330 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  1331 			}
       
  1332 		}
       
  1333 
       
  1334 		if (m_authentication_finished_successfully == false)
       
  1335 		{
       
  1336 			EAP_TRACE_ERROR(
       
  1337 				m_am_tools, 
       
  1338 				TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  1339 				(EAPL("EAP_type_GSMSIM: %s, authentication FAILED, state %s\n"),
       
  1340 				 (m_is_client == true) ? "client": "server",
       
  1341 				 get_state_string()));
       
  1342 
       
  1343 			if (m_gsmsim_notification_code != eap_gsmsim_notification_none)
       
  1344 			{
       
  1345 				// We have received EAP-Request/SIM notification, we pass the received code to the adaptation module.
       
  1346 				m_am_type_gsmsim->handle_gsmsim_notification(m_gsmsim_notification_code);
       
  1347 			}
       
  1348 
       
  1349 			set_state(eap_type_gsmsim_state_failure);
       
  1350 
       
  1351 			// Notifies the lower level of unsuccessfull authentication.
       
  1352 			eap_state_notification_c notification(
       
  1353 				m_am_tools,
       
  1354 				&m_send_network_id,
       
  1355 				m_is_client,
       
  1356 				eap_state_notification_eap,
       
  1357 				eap_protocol_layer_eap,
       
  1358 				eap_type_gsmsim,
       
  1359 				eap_state_none,
       
  1360 				eap_state_authentication_terminated_unsuccessfully,
       
  1361 				m_last_eap_identifier,
       
  1362 				false);
       
  1363 
       
  1364 			notification.set_authentication_error(eap_status_authentication_failure);
       
  1365 
       
  1366 			state_notification(&notification);
       
  1367 
       
  1368 			// Indicate GSMSIM AM authentication finish.
       
  1369 			m_am_type_gsmsim->authentication_finished(false, m_authentication_type, m_identity_type);
       
  1370 		}
       
  1371 	}
       
  1372 
       
  1373 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1374 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1375 }
       
  1376 
       
  1377 //--------------------------------------------------
       
  1378 
       
  1379 //
       
  1380 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_padding_payload(
       
  1381 	gsmsim_header_c * const gsmsim,
       
  1382 	const u32_t gsmsim_buffer_length,
       
  1383 	const u32_t eap_header_size,
       
  1384 	u32_t * const gsmsim_data_offset,
       
  1385 	u32_t * const gsmsim_data_free,
       
  1386 	u32_t * const packet_buffer_free,
       
  1387 	u32_t * const packet_buffer_offset,
       
  1388 	const u32_t plaintext_length)
       
  1389 {
       
  1390 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1391 
       
  1392 	gsmsim_payload_AT_header_c gp_padding(
       
  1393 		m_am_tools,
       
  1394 		gsmsim->get_data_offset(
       
  1395 			*gsmsim_data_offset, *gsmsim_data_free),
       
  1396 		*gsmsim_data_free);
       
  1397 
       
  1398 	if (gp_padding.get_is_valid() == false)
       
  1399 	{
       
  1400 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1401 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1402 	}
       
  1403 
       
  1404 	crypto_aes_c aes(m_am_tools);
       
  1405 	crypto_cbc_c cbc_aes(m_am_tools, &aes, false);
       
  1406 
       
  1407 	if (cbc_aes.get_is_valid() == false)
       
  1408 	{
       
  1409 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1410 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1411 	}
       
  1412 
       
  1413 	u32_t cbc_aes_data_length = cbc_aes.aligned_data_length(plaintext_length);
       
  1414 	u32_t padding_bytes_length = 0u;
       
  1415 
       
  1416 	if (cbc_aes_data_length > plaintext_length+gsmsim_payload_AT_header_c::get_header_length())
       
  1417 	{
       
  1418 		// Fill with zero (0x00) bytes.
       
  1419 		padding_bytes_length = cbc_aes_data_length - (plaintext_length+gsmsim_payload_AT_header_c::get_header_length());
       
  1420 	}
       
  1421 
       
  1422 	u32_t padding_payload_length = gsmsim_payload_AT_header_c::get_header_length()+padding_bytes_length;
       
  1423 
       
  1424 	if ((padding_payload_length % EAP_TYPE_GSMSIM_PADDING_MODULUS) != 0)
       
  1425 	{
       
  1426 		// ERROR
       
  1427 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1428 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding);
       
  1429 	}
       
  1430 
       
  1431 	if (padding_payload_length > EAP_TYPE_GSMSIM_PADDING_MAX_VALUE)
       
  1432 	{
       
  1433 		padding_payload_length = 0ul;
       
  1434 		padding_bytes_length = 0ul;
       
  1435 	}
       
  1436 
       
  1437 	// Note the reserved field is the begin of padding.
       
  1438 	// The reserved field is set zero in reset_header() function.
       
  1439 	gp_padding.reset_header(static_cast<u16_t>(padding_payload_length));
       
  1440 	gp_padding.set_data_length(static_cast<u16_t>(padding_bytes_length));
       
  1441 	gp_padding.set_current_payload(gsmsim_payload_AT_PADDING);
       
  1442 
       
  1443 	if (padding_payload_length > 0u)
       
  1444 	{
       
  1445 		if (padding_bytes_length > 0ul)
       
  1446 		{
       
  1447 			u8_t *padding = gp_padding.get_data(padding_bytes_length);
       
  1448 			if (padding == 0)
       
  1449 			{
       
  1450 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1451 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1452 			}
       
  1453 
       
  1454 			cbc_aes.add_padding_bytes(
       
  1455 				padding,
       
  1456 				padding_bytes_length,
       
  1457 				0ul);
       
  1458 		}
       
  1459 
       
  1460 		update_payload_indexes(
       
  1461 			gsmsim_buffer_length,
       
  1462 			eap_header_size,
       
  1463 			gp_padding.get_header_length()+gp_padding.get_data_length(),
       
  1464 			gsmsim_data_offset,
       
  1465 			gsmsim_data_free,
       
  1466 			packet_buffer_offset,
       
  1467 			packet_buffer_free);
       
  1468 
       
  1469 		EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_padding);
       
  1470 	}
       
  1471 	else
       
  1472 	{
       
  1473 		EAP_TRACE_DEBUG(
       
  1474 			m_am_tools, 
       
  1475 			TRACE_FLAGS_DEFAULT, 
       
  1476 			(EAPL("GSMSIM: Padding payload not needed.\n")));
       
  1477 	}
       
  1478 
       
  1479 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1480 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1481 }
       
  1482 
       
  1483 //--------------------------------------------------
       
  1484 
       
  1485 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_variable_payload(
       
  1486 	gsmsim_header_c * const gsmsim,
       
  1487 	const u32_t gsmsim_buffer_length,
       
  1488 	const u32_t eap_header_size,
       
  1489 	u32_t * const gsmsim_data_offset,
       
  1490 	u32_t * const gsmsim_data_free,
       
  1491 	u32_t * const packet_buffer_free,
       
  1492 	u32_t * const packet_buffer_offset,
       
  1493 	const eap_variable_data_c * const data_payload,
       
  1494 	const gsmsim_payload_AT_type_e data_payload_type)
       
  1495 {
       
  1496 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1497 
       
  1498 	eap_status_e status = eap_status_process_general_error;
       
  1499 	u16_t data_length = 0u;
       
  1500 
       
  1501 	if (data_payload != 0)
       
  1502 	{
       
  1503 		if (data_payload->get_is_valid_data() == false)
       
  1504 		{
       
  1505 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1506 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  1507 		}
       
  1508 
       
  1509 		if (data_payload->get_data_length() > gsmsim_payload_AT_header_c::get_max_payload_data_length())
       
  1510 		{
       
  1511 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1512 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1513 		}
       
  1514 
       
  1515 		data_length = static_cast<u16_t>(data_payload->get_data_length());
       
  1516 	}
       
  1517 	else
       
  1518 	{
       
  1519 		// No data.
       
  1520 		data_length = 0u;
       
  1521 	}
       
  1522 
       
  1523 	gsmsim_payload_AT_header_c gp_data(
       
  1524 		m_am_tools,
       
  1525 		gsmsim->get_data_offset(*gsmsim_data_offset, *gsmsim_data_free),
       
  1526 		*gsmsim_data_free);
       
  1527 
       
  1528 	if (gp_data.get_is_valid() == false)
       
  1529 	{
       
  1530 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1531 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1532 	}
       
  1533 
       
  1534 	gp_data.reset_header(data_length);
       
  1535 
       
  1536 	if (data_length > 0u)
       
  1537 	{
       
  1538 		u8_t *payload_buffer = gp_data.get_data(data_length);
       
  1539 		if (payload_buffer == 0)
       
  1540 		{
       
  1541 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1542 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1543 		}
       
  1544 
       
  1545 		m_am_tools->memmove(
       
  1546 			payload_buffer,
       
  1547 			data_payload->get_data(),
       
  1548 			data_payload->get_data_length());
       
  1549 	}
       
  1550 
       
  1551 	gp_data.set_data_length(data_length);
       
  1552 
       
  1553 	status = eap_status_ok;
       
  1554 
       
  1555 
       
  1556 	gp_data.set_current_payload(data_payload_type);
       
  1557 
       
  1558 	update_payload_indexes(
       
  1559 		gsmsim_buffer_length,
       
  1560 		eap_header_size,
       
  1561 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1562 		gsmsim_data_offset,
       
  1563 		gsmsim_data_free,
       
  1564 		packet_buffer_offset,
       
  1565 		packet_buffer_free);
       
  1566 
       
  1567 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1568 
       
  1569 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1570 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1571 }
       
  1572 
       
  1573 //--------------------------------------------------
       
  1574 
       
  1575 // Note the specification of IMSI payload is not same as pseudonym.
       
  1576 // IMSI and pseudonym specifications should be integrated.
       
  1577 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_pseudonym_or_imsi_payload(
       
  1578 	gsmsim_header_c * const gsmsim,
       
  1579 	const u32_t gsmsim_buffer_length,
       
  1580 	const u32_t eap_header_size,
       
  1581 	u32_t * const gsmsim_data_offset,
       
  1582 	u32_t * const gsmsim_data_free,
       
  1583 	u32_t * const packet_buffer_free,
       
  1584 	u32_t * const packet_buffer_offset,
       
  1585 	const eap_variable_data_c * const pseudonym_or_imsi,
       
  1586 	const gsmsim_payload_AT_type_e data_payload_type)
       
  1587 {
       
  1588 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1589 
       
  1590 	eap_status_e status = eap_status_process_general_error;
       
  1591 
       
  1592 	if (pseudonym_or_imsi->get_is_valid_data() == false)
       
  1593 	{
       
  1594 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1595 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  1596 	}
       
  1597 
       
  1598 	u32_t padding_zero_count = 0u;
       
  1599 	// Add padding zero octets
       
  1600 	if ((pseudonym_or_imsi->get_data_length() % 4u) != 0)
       
  1601 	{
       
  1602 		padding_zero_count = 4u - (pseudonym_or_imsi->get_data_length() % 4u);
       
  1603 	}
       
  1604 
       
  1605 	if (pseudonym_or_imsi->get_data_length()+padding_zero_count
       
  1606 		> gsmsim_payload_AT_header_c::get_max_payload_data_length())
       
  1607 	{
       
  1608 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1609 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1610 	}
       
  1611 
       
  1612 	if (pseudonym_or_imsi->get_data_length()+padding_zero_count > *packet_buffer_free)
       
  1613 	{
       
  1614 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1615 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1616 	}
       
  1617 
       
  1618 	gsmsim_payload_AT_header_c gp_data(
       
  1619 		m_am_tools,
       
  1620 		gsmsim->get_data_offset(
       
  1621 			*gsmsim_data_offset, 
       
  1622 			*gsmsim_data_free),
       
  1623 		*gsmsim_data_free);
       
  1624 
       
  1625 	if (gp_data.get_is_valid() == false)
       
  1626 	{
       
  1627 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1628 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1629 	}
       
  1630 
       
  1631 	gp_data.reset_header(static_cast<u16_t>(pseudonym_or_imsi->get_data_length()+padding_zero_count));
       
  1632 
       
  1633 	u8_t *payload_buffer = gp_data.get_data(pseudonym_or_imsi->get_data_length()+padding_zero_count);
       
  1634 
       
  1635 	if (payload_buffer == 0
       
  1636 		|| pseudonym_or_imsi->get_data_length() == 0)
       
  1637 	{
       
  1638 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1639 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1640 	}
       
  1641 
       
  1642 	m_am_tools->memmove(
       
  1643 		payload_buffer,
       
  1644 		pseudonym_or_imsi->get_data(),
       
  1645 		pseudonym_or_imsi->get_data_length());
       
  1646 
       
  1647 	if (padding_zero_count > 0u)
       
  1648 	{
       
  1649 		m_am_tools->memset(
       
  1650 			payload_buffer+(pseudonym_or_imsi->get_data_length()),
       
  1651 			0,
       
  1652 			padding_zero_count);
       
  1653 	}
       
  1654 
       
  1655 	// Note the reserved field includes the actual length of pseudonym in network order.
       
  1656 	// This must be less or equal to the length field.
       
  1657 	gp_data.set_reserved(static_cast<u16_t>(pseudonym_or_imsi->get_data_length()));
       
  1658 
       
  1659 	gp_data.set_data_length(static_cast<u16_t>(pseudonym_or_imsi->get_data_length()+padding_zero_count));
       
  1660 
       
  1661 	status = eap_status_ok;
       
  1662 
       
  1663 	gp_data.set_current_payload(data_payload_type);
       
  1664 
       
  1665 	update_payload_indexes(
       
  1666 		gsmsim_buffer_length,
       
  1667 		eap_header_size,
       
  1668 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1669 		gsmsim_data_offset,
       
  1670 		gsmsim_data_free,
       
  1671 		packet_buffer_offset,
       
  1672 		packet_buffer_free);
       
  1673 
       
  1674 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1675 
       
  1676 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1677 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1678 }
       
  1679 
       
  1680 //--------------------------------------------------
       
  1681 
       
  1682 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_version_list(
       
  1683 	gsmsim_header_c * const gsmsim,
       
  1684 	const u32_t gsmsim_buffer_length,
       
  1685 	const u32_t eap_header_size,
       
  1686 	u32_t * const gsmsim_data_offset,
       
  1687 	u32_t * const gsmsim_data_free,
       
  1688 	u32_t * const packet_buffer_free,
       
  1689 	u32_t * const packet_buffer_offset,
       
  1690 	const eap_gsmsim_version *gsmsim_versions,
       
  1691 	const u32_t gsmsim_versions_count,
       
  1692 	const gsmsim_payload_AT_type_e data_payload_type)
       
  1693 {
       
  1694 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1695 
       
  1696 	eap_status_e status = eap_status_process_general_error;
       
  1697 
       
  1698 	u32_t version_list_size = sizeof(u16_t)*gsmsim_versions_count;
       
  1699 	u32_t padding_zero_count = 0u;
       
  1700 	// Add padding zero octets
       
  1701 	if ((version_list_size % 4u) != 0)
       
  1702 	{
       
  1703 		padding_zero_count = 4u - (version_list_size % 4u);
       
  1704 	}
       
  1705 
       
  1706 	if (version_list_size+padding_zero_count
       
  1707 		> gsmsim_payload_AT_header_c::get_max_payload_data_length())
       
  1708 	{
       
  1709 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1710 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1711 	}
       
  1712 
       
  1713 	if (version_list_size+padding_zero_count > *packet_buffer_free)
       
  1714 	{
       
  1715 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1716 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1717 	}
       
  1718 
       
  1719 	gsmsim_payload_AT_header_c gp_data(
       
  1720 		m_am_tools,
       
  1721 		gsmsim->get_data_offset(
       
  1722 			*gsmsim_data_offset, 
       
  1723 			*gsmsim_data_free),
       
  1724 		*gsmsim_data_free);
       
  1725 
       
  1726 	if (gp_data.get_is_valid() == false)
       
  1727 	{
       
  1728 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1729 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1730 	}
       
  1731 
       
  1732 	gp_data.reset_header(static_cast<u16_t>(version_list_size+padding_zero_count));
       
  1733 
       
  1734 	u8_t *payload_buffer = gp_data.get_data(version_list_size+padding_zero_count);
       
  1735 
       
  1736 	if (payload_buffer == 0
       
  1737 		|| version_list_size == 0)
       
  1738 	{
       
  1739 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1740 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1741 	}
       
  1742 
       
  1743 	u16_t *payload_version_list = reinterpret_cast<u16_t *>(payload_buffer);
       
  1744 	u32_t ind;
       
  1745 	for (ind = 0u; ind < gsmsim_versions_count; ind++)
       
  1746 	{
       
  1747 		payload_version_list[ind] = eap_htons(static_cast<u16_t>(gsmsim_versions[ind]));
       
  1748 	}
       
  1749 
       
  1750 	if (padding_zero_count > 0u)
       
  1751 	{
       
  1752 		m_am_tools->memset(
       
  1753 			payload_buffer+(version_list_size),
       
  1754 			0,
       
  1755 			padding_zero_count);
       
  1756 	}
       
  1757 
       
  1758 	// Note the reserved field includes the actual length of version list in network order.
       
  1759 	// This must be less or equal to the length field.
       
  1760 	gp_data.set_reserved(static_cast<u16_t>(version_list_size));
       
  1761 
       
  1762 	gp_data.set_data_length(static_cast<u16_t>(version_list_size+padding_zero_count));
       
  1763 
       
  1764 	status = eap_status_ok;
       
  1765 
       
  1766 	gp_data.set_current_payload(data_payload_type);
       
  1767 
       
  1768 	update_payload_indexes(
       
  1769 		gsmsim_buffer_length,
       
  1770 		eap_header_size,
       
  1771 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1772 		gsmsim_data_offset,
       
  1773 		gsmsim_data_free,
       
  1774 		packet_buffer_offset,
       
  1775 		packet_buffer_free);
       
  1776 
       
  1777 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1778 
       
  1779 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1780 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1781 }
       
  1782 
       
  1783 //--------------------------------------------------
       
  1784 
       
  1785 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_notification_payload(
       
  1786 	gsmsim_header_c * const gsmsim,
       
  1787 	const u32_t gsmsim_buffer_length,
       
  1788 	const u32_t eap_header_size,
       
  1789 	u32_t * const gsmsim_data_offset,
       
  1790 	u32_t * const gsmsim_data_free,
       
  1791 	u32_t * const packet_buffer_free,
       
  1792 	u32_t * const packet_buffer_offset,
       
  1793 	const eap_gsmsim_notification_codes_e notification_code)
       
  1794 {
       
  1795 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1796 
       
  1797 	eap_status_e status = eap_status_process_general_error;
       
  1798 
       
  1799 	gsmsim_payload_AT_header_c gp_data(
       
  1800 		m_am_tools,
       
  1801 		gsmsim->get_data_offset(
       
  1802 			*gsmsim_data_offset, 
       
  1803 			*gsmsim_data_free),
       
  1804 		*gsmsim_data_free);
       
  1805 
       
  1806 	if (gp_data.get_is_valid() == false)
       
  1807 	{
       
  1808 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1809 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1810 	}
       
  1811 
       
  1812 	gp_data.reset_header(0u);
       
  1813 
       
  1814 	// Note the reserved field includes the notificatio code in network order.
       
  1815 	gp_data.set_reserved(static_cast<u16_t>(notification_code));
       
  1816 
       
  1817 	gp_data.set_data_length(0u);
       
  1818 
       
  1819 	status = eap_status_ok;
       
  1820 
       
  1821 	gp_data.set_current_payload(gsmsim_payload_AT_NOTIFICATION);
       
  1822 
       
  1823 	update_payload_indexes(
       
  1824 		gsmsim_buffer_length,
       
  1825 		eap_header_size,
       
  1826 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1827 		gsmsim_data_offset,
       
  1828 		gsmsim_data_free,
       
  1829 		packet_buffer_offset,
       
  1830 		packet_buffer_free);
       
  1831 
       
  1832 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1833 
       
  1834 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1835 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1836 }
       
  1837 
       
  1838 //--------------------------------------------------
       
  1839 
       
  1840 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_client_error_payload(
       
  1841 	gsmsim_header_c * const gsmsim,
       
  1842 	const u32_t gsmsim_buffer_length,
       
  1843 	const u32_t eap_header_size,
       
  1844 	u32_t * const gsmsim_data_offset,
       
  1845 	u32_t * const gsmsim_data_free,
       
  1846 	u32_t * const packet_buffer_free,
       
  1847 	u32_t * const packet_buffer_offset,
       
  1848 	const eap_gsmsim_client_error_code_e client_error_code)
       
  1849 {
       
  1850 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1851 
       
  1852 	eap_status_e status = eap_status_process_general_error;
       
  1853 
       
  1854 	gsmsim_payload_AT_header_c gp_data(
       
  1855 		m_am_tools,
       
  1856 		gsmsim->get_data_offset(
       
  1857 			*gsmsim_data_offset, 
       
  1858 			*gsmsim_data_free),
       
  1859 		*gsmsim_data_free);
       
  1860 
       
  1861 	if (gp_data.get_is_valid() == false)
       
  1862 	{
       
  1863 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1864 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1865 	}
       
  1866 
       
  1867 	gp_data.reset_header(0u);
       
  1868 
       
  1869 	// Note the reserved field includes the triplet status in network order.
       
  1870 	// This must be less or equal to the length field.
       
  1871 	gp_data.set_reserved(static_cast<u16_t>(client_error_code));
       
  1872 
       
  1873 	gp_data.set_data_length(0u);
       
  1874 
       
  1875 	status = eap_status_ok;
       
  1876 
       
  1877 	gp_data.set_current_payload(gsmsim_payload_AT_CLIENT_ERROR_CODE);
       
  1878 
       
  1879 	update_payload_indexes(
       
  1880 		gsmsim_buffer_length,
       
  1881 		eap_header_size,
       
  1882 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1883 		gsmsim_data_offset,
       
  1884 		gsmsim_data_free,
       
  1885 		packet_buffer_offset,
       
  1886 		packet_buffer_free);
       
  1887 
       
  1888 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1889 
       
  1890 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1891 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1892 }
       
  1893 
       
  1894 //--------------------------------------------------
       
  1895 
       
  1896 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_version_payload(
       
  1897 	gsmsim_header_c * const gsmsim,
       
  1898 	const u32_t gsmsim_buffer_length,
       
  1899 	const u32_t eap_header_size,
       
  1900 	u32_t * const gsmsim_data_offset,
       
  1901 	u32_t * const gsmsim_data_free,
       
  1902 	u32_t * const packet_buffer_free,
       
  1903 	u32_t * const packet_buffer_offset,
       
  1904 	const eap_gsmsim_version version)
       
  1905 {
       
  1906 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1907 
       
  1908 	eap_status_e status = eap_status_process_general_error;
       
  1909 
       
  1910 	gsmsim_payload_AT_header_c gp_data(
       
  1911 		m_am_tools,
       
  1912 		gsmsim->get_data_offset(
       
  1913 			*gsmsim_data_offset, 
       
  1914 			*gsmsim_data_free),
       
  1915 		*gsmsim_data_free);
       
  1916 
       
  1917 	if (gp_data.get_is_valid() == false)
       
  1918 	{
       
  1919 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1920 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1921 	}
       
  1922 
       
  1923 	gp_data.reset_header(0u);
       
  1924 
       
  1925 	// Note the reserved field includes the selected version in network order.
       
  1926 	gp_data.set_reserved(static_cast<u16_t>(version));
       
  1927 
       
  1928 	gp_data.set_data_length(0u);
       
  1929 
       
  1930 	status = eap_status_ok;
       
  1931 
       
  1932 	gp_data.set_current_payload(gsmsim_payload_AT_SELECTED_VERSION);
       
  1933 
       
  1934 	update_payload_indexes(
       
  1935 		gsmsim_buffer_length,
       
  1936 		eap_header_size,
       
  1937 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1938 		gsmsim_data_offset,
       
  1939 		gsmsim_data_free,
       
  1940 		packet_buffer_offset,
       
  1941 		packet_buffer_free);
       
  1942 
       
  1943 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1944 
       
  1945 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1946 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1947 }
       
  1948 
       
  1949 //--------------------------------------------------
       
  1950 
       
  1951 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_counter_payload(
       
  1952 	gsmsim_header_c * const gsmsim,
       
  1953 	const u32_t gsmsim_buffer_length,
       
  1954 	const u32_t eap_header_size,
       
  1955 	u32_t * const gsmsim_data_offset,
       
  1956 	u32_t * const gsmsim_data_free,
       
  1957 	u32_t * const packet_buffer_free,
       
  1958 	u32_t * const packet_buffer_offset,
       
  1959 	u16_t counter)
       
  1960 {
       
  1961 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1962 
       
  1963 	eap_status_e status = eap_status_process_general_error;
       
  1964 
       
  1965 	gsmsim_payload_AT_header_c gp_data(
       
  1966 		m_am_tools,
       
  1967 		gsmsim->get_data_offset(
       
  1968 			*gsmsim_data_offset, 
       
  1969 			*gsmsim_data_free),
       
  1970 		*gsmsim_data_free);
       
  1971 
       
  1972 	if (gp_data.get_is_valid() == false)
       
  1973 	{
       
  1974 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1975 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1976 	}
       
  1977 
       
  1978 	gp_data.reset_header(0u);
       
  1979 
       
  1980 	// Note the reserved field includes the selected version in network order.
       
  1981 	gp_data.set_reserved(counter);
       
  1982 
       
  1983 	gp_data.set_data_length(0u);
       
  1984 
       
  1985 	status = eap_status_ok;
       
  1986 
       
  1987 	gp_data.set_current_payload(gsmsim_payload_AT_COUNTER);
       
  1988 
       
  1989 	update_payload_indexes(
       
  1990 		gsmsim_buffer_length,
       
  1991 		eap_header_size,
       
  1992 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  1993 		gsmsim_data_offset,
       
  1994 		gsmsim_data_free,
       
  1995 		packet_buffer_offset,
       
  1996 		packet_buffer_free);
       
  1997 
       
  1998 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  1999 
       
  2000 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2001 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2002 }
       
  2003 
       
  2004 //--------------------------------------------------
       
  2005 
       
  2006 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_simple_payload(
       
  2007 	gsmsim_header_c * const gsmsim,
       
  2008 	const u32_t gsmsim_buffer_length,
       
  2009 	const u32_t eap_header_size,
       
  2010 	u32_t * const gsmsim_data_offset,
       
  2011 	u32_t * const gsmsim_data_free,
       
  2012 	u32_t * const packet_buffer_free,
       
  2013 	u32_t * const packet_buffer_offset,
       
  2014 	const gsmsim_payload_AT_type_e data_payload_type)
       
  2015 {
       
  2016 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2017 
       
  2018 	eap_status_e status = eap_status_process_general_error;
       
  2019 
       
  2020 	gsmsim_payload_AT_header_c gp_data(
       
  2021 		m_am_tools,
       
  2022 		gsmsim->get_data_offset(
       
  2023 			*gsmsim_data_offset, 
       
  2024 			*gsmsim_data_free),
       
  2025 		*gsmsim_data_free);
       
  2026 
       
  2027 	if (gp_data.get_is_valid() == false)
       
  2028 	{
       
  2029 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2030 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2031 	}
       
  2032 
       
  2033 	gp_data.reset_header(0u);
       
  2034 
       
  2035 	gp_data.set_reserved(0u);
       
  2036 
       
  2037 	gp_data.set_data_length(0u);
       
  2038 
       
  2039 	status = eap_status_ok;
       
  2040 
       
  2041 	gp_data.set_current_payload(data_payload_type);
       
  2042 
       
  2043 	update_payload_indexes(
       
  2044 		gsmsim_buffer_length,
       
  2045 		eap_header_size,
       
  2046 		gp_data.get_header_length()+gp_data.get_data_length(),
       
  2047 		gsmsim_data_offset,
       
  2048 		gsmsim_data_free,
       
  2049 		packet_buffer_offset,
       
  2050 		packet_buffer_free);
       
  2051 
       
  2052 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_data);
       
  2053 
       
  2054 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2055 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2056 }
       
  2057 
       
  2058 //--------------------------------------------------
       
  2059 
       
  2060 //
       
  2061 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::encrypt_DATA_payload(
       
  2062 	u8_t * const data,
       
  2063 	const u32_t cbc_aes_data_length,
       
  2064 	const eap_variable_data_c * const IV,
       
  2065 	const eap_variable_data_c * const encryption_key
       
  2066 	)
       
  2067 {
       
  2068 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2069 
       
  2070 	eap_status_e status = eap_status_process_general_error;
       
  2071 
       
  2072 	if (data == 0
       
  2073 		|| cbc_aes_data_length == 0
       
  2074 		|| IV == 0
       
  2075 		|| IV->get_is_valid_data() == false
       
  2076 		|| encryption_key == 0
       
  2077 		|| encryption_key->get_is_valid_data() == false)
       
  2078 	{
       
  2079 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2080 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  2081 	}
       
  2082 	
       
  2083 	crypto_aes_c aes(m_am_tools);
       
  2084 	crypto_cbc_c cbc_aes(m_am_tools, &aes, false);
       
  2085 
       
  2086 	if (cbc_aes.get_is_valid() == false)
       
  2087 	{
       
  2088 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2089 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2090 	}
       
  2091 
       
  2092 	u32_t aes_key_length = aes.get_key_length();
       
  2093 	if (encryption_key->get_data_length() < aes_key_length)
       
  2094 	{
       
  2095 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2096 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  2097 	}
       
  2098 
       
  2099 	status = cbc_aes.set_encryption_key(
       
  2100 		IV->get_data(),
       
  2101 		IV->get_data_length(),
       
  2102 		encryption_key->get_data(),
       
  2103 		aes_key_length);
       
  2104 	if (status != eap_status_ok)
       
  2105 	{
       
  2106 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2107 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2108 	}
       
  2109 
       
  2110 	status = cbc_aes.encrypt_data(
       
  2111 		data,
       
  2112 		cbc_aes_data_length);
       
  2113 
       
  2114 	store_last_encryption_iv(cbc_aes.get_tmp_IV());
       
  2115 
       
  2116 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2117 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2118 }
       
  2119 
       
  2120 //--------------------------------------------------
       
  2121 
       
  2122 //
       
  2123 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::add_mac_payload(
       
  2124 	gsmsim_header_c * const gsmsim,
       
  2125 	const u32_t gsmsim_buffer_length,
       
  2126 	const u32_t eap_header_size,
       
  2127 	u32_t * const gsmsim_data_offset,
       
  2128 	u32_t * const gsmsim_data_free,
       
  2129 	u32_t * const packet_buffer_free,
       
  2130 	u32_t * const packet_buffer_offset,
       
  2131 	u8_t ** const MAC_data,
       
  2132 	u32_t * const MAC_data_length)
       
  2133 {
       
  2134 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2135 
       
  2136 	gsmsim_payload_AT_header_c gp_MAC(
       
  2137 		m_am_tools,
       
  2138 		gsmsim->get_data_offset(
       
  2139 			*gsmsim_data_offset, *gsmsim_data_free),
       
  2140 		*gsmsim_data_free);
       
  2141 
       
  2142 	if (gp_MAC.get_is_valid() == false)
       
  2143 	{
       
  2144 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2145 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2146 	}
       
  2147 
       
  2148 	u32_t eap_type_gsmsim_mac_size = EAP_TYPE_GSMSIM_MAC_SIZE;
       
  2149 
       
  2150 	gp_MAC.reset_header(static_cast<u16_t>(eap_type_gsmsim_mac_size));
       
  2151 	gp_MAC.set_data_length(static_cast<u16_t>(eap_type_gsmsim_mac_size));
       
  2152 	gp_MAC.set_current_payload(gsmsim_payload_AT_MAC);
       
  2153 
       
  2154 	*MAC_data = gp_MAC.get_data(eap_type_gsmsim_mac_size);
       
  2155 	if (*MAC_data == 0)
       
  2156 	{
       
  2157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2158 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  2159 	}
       
  2160 	*MAC_data_length = eap_type_gsmsim_mac_size;
       
  2161 
       
  2162 	m_am_tools->memset(*MAC_data, 0, eap_type_gsmsim_mac_size);
       
  2163 
       
  2164 	// MAC is calculated later using call create_message_authentication_code().
       
  2165 
       
  2166 	update_payload_indexes(
       
  2167 		gsmsim_buffer_length,
       
  2168 		eap_header_size,
       
  2169 		gp_MAC.get_header_length()+gp_MAC.get_data_length(),
       
  2170 		gsmsim_data_offset,
       
  2171 		gsmsim_data_free,
       
  2172 		packet_buffer_offset,
       
  2173 		packet_buffer_free);
       
  2174 
       
  2175 	EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_MAC);
       
  2176 
       
  2177 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2178 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2179 }
       
  2180 
       
  2181 //--------------------------------------------------
       
  2182 
       
  2183 //
       
  2184 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_version_list(
       
  2185 	const gsmsim_payload_AT_header_c * const payload,
       
  2186 	const u16_t version_list_length,
       
  2187 	u8_t *version_list,
       
  2188 	bool * const includes_other_version_than_1)
       
  2189 {
       
  2190 	eap_status_e status(eap_status_process_general_error);
       
  2191 
       
  2192 	if (payload->get_data_length() > version_list_length)
       
  2193 	{
       
  2194 		// Check padding bytes are zero.
       
  2195 		const u8_t * const padding = &version_list[version_list_length];
       
  2196 		const u32_t padding_count = payload->get_data_length() - version_list_length;
       
  2197 
       
  2198 		crypto_aes_c aes(m_am_tools);
       
  2199 		crypto_cbc_c cbc_aes(m_am_tools, &aes, false);
       
  2200 
       
  2201 		if (cbc_aes.get_is_valid() == false)
       
  2202 		{
       
  2203 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2204 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2205 		}
       
  2206 
       
  2207 		status = cbc_aes.check_padding_bytes(
       
  2208 			padding,
       
  2209 			padding_count,
       
  2210 			0ul);
       
  2211 		if (status != eap_status_ok)
       
  2212 		{
       
  2213 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2214 			// Illegal padding byte.
       
  2215 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding);
       
  2216 		}
       
  2217 	}
       
  2218 
       
  2219 	gsmsim_variable_data_c tmp_version_list(m_am_tools);
       
  2220 
       
  2221 	status = tmp_version_list.set_buffer(
       
  2222 		payload, version_list, version_list_length, false, false);
       
  2223 	if (status != eap_status_ok)
       
  2224 	{
       
  2225 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2226 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2227 	}
       
  2228 
       
  2229 	eap_gsmsim_version selected_version = select_version(&tmp_version_list, includes_other_version_than_1);
       
  2230 
       
  2231 	if (selected_version == GSMSIM_ILLEGAL_VERSION)
       
  2232 	{
       
  2233 		// ERROR, no supported version.
       
  2234 		EAP_TRACE_ERROR(
       
  2235 			m_am_tools, 
       
  2236 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  2237 			(EAPL("ERROR: eap_type_gsmsim_c::check_version_list(), illegal version list.\n")));
       
  2238 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2239 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  2240 	}
       
  2241 
       
  2242 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2243 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2244 }
       
  2245 
       
  2246 //--------------------------------------------------
       
  2247 
       
  2248 //
       
  2249 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_generic_payload(
       
  2250 	const gsmsim_payload_AT_type_e current_payload,
       
  2251 	const gsmsim_payload_AT_header_c * const payload,
       
  2252 	gsmsim_payloads_c * const p_gsmsim_payloads,
       
  2253 	const gsmsim_subtype_e subtype)
       
  2254 {
       
  2255 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2256 
       
  2257 	EAP_GSMSIM_TRACE_PAYLOAD("Parsing payload", payload);
       
  2258 
       
  2259 	if ((payload->get_payload_length() % static_cast<u16_t>(GSMSIM_PAYLOAD_LENGTH_ALIGN)) != 0)
       
  2260 	{
       
  2261 		EAP_TRACE_ERROR(
       
  2262 			m_am_tools,
       
  2263 			TRACE_FLAGS_GSMSIM_ERROR,
       
  2264 			(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2265 			 EAPL("current payload 0x%04x=%s, length 0x%04x not aligned to 0x%04x.\n"),
       
  2266 			payload, current_payload, payload->get_payload_AT_string(),
       
  2267 			payload->get_payload_length(), GSMSIM_PAYLOAD_LENGTH_ALIGN));
       
  2268 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2269 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);		
       
  2270 	}
       
  2271 
       
  2272 	eap_status_e status(eap_status_process_general_error);
       
  2273 
       
  2274 	if (current_payload == gsmsim_payload_AT_NONCE_MT)
       
  2275 	{
       
  2276 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2277 		// |AT_NONCE_MT    | Length = 5    |           Reserved            |
       
  2278 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2279 		// |                                                               |
       
  2280 		// |                           NONCE_MT                            |
       
  2281 		// |                                                               |
       
  2282 		// |                                                               |
       
  2283 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2284 		if (payload->get_reserved() != 0u)
       
  2285 		{
       
  2286 			EAP_TRACE_ERROR(
       
  2287 				m_am_tools,
       
  2288 				TRACE_FLAGS_GSMSIM_ERROR,
       
  2289 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2290 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2291 				payload, current_payload, payload->get_payload_AT_string(),
       
  2292 				 payload->get_payload_length(), payload->get_reserved()));
       
  2293 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2294 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2295 		}
       
  2296 
       
  2297 		if (payload->get_data_length() != EAP_TYPE_GSMSIM_NONCE_MT_SIZE)
       
  2298 		{
       
  2299 			EAP_TRACE_ERROR(
       
  2300 				m_am_tools,
       
  2301 				TRACE_FLAGS_GSMSIM_ERROR,
       
  2302 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2303 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"),
       
  2304 				payload, current_payload, payload->get_payload_AT_string(),
       
  2305 				 payload->get_payload_length(), payload->get_data_length()));
       
  2306 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2307 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2308 		}
       
  2309 
       
  2310 		u8_t * buffer
       
  2311 			= static_cast<u8_t *>(payload->get_data(EAP_TYPE_GSMSIM_NONCE_MT_SIZE));
       
  2312 
       
  2313 		if (buffer == 0)
       
  2314 		{
       
  2315 			EAP_TRACE_ERROR(
       
  2316 				m_am_tools, 
       
  2317 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2318 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2319 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2320 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2321 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2322 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2323 		}
       
  2324 
       
  2325 		// Note here we get a reference to the data bytes of the received packet.
       
  2326 		status = p_gsmsim_payloads->get_NONCE_MT()->set_buffer(
       
  2327 			payload, buffer, payload->get_data_length(), false, false);
       
  2328 
       
  2329 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2330 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2331 	}
       
  2332 	else if (current_payload == gsmsim_payload_AT_NONCE_S)
       
  2333 	{
       
  2334 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2335 		// |AT_NONCE_S     | Length = 5    |           Reserved            |
       
  2336 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2337 		// |                                                               |
       
  2338 		// |                           NONCE_S                             |
       
  2339 		// |                                                               |
       
  2340 		// |                                                               |
       
  2341 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2342 		if (payload->get_reserved() != 0u)
       
  2343 		{
       
  2344 			EAP_TRACE_ERROR(
       
  2345 				m_am_tools, 
       
  2346 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2347 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2348 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2349 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2350 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2351 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2352 		}
       
  2353 
       
  2354 		if (payload->get_data_length() != EAP_TYPE_GSMSIM_NONCE_MT_SIZE)
       
  2355 		{
       
  2356 			EAP_TRACE_ERROR(
       
  2357 				m_am_tools, 
       
  2358 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2359 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2360 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"),
       
  2361 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length()));
       
  2362 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2363 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2364 		}
       
  2365 
       
  2366 		u8_t * buffer
       
  2367 			= static_cast<u8_t *>(payload->get_data(EAP_TYPE_GSMSIM_NONCE_MT_SIZE));
       
  2368 
       
  2369 		if (buffer == 0)
       
  2370 		{
       
  2371 			EAP_TRACE_ERROR(
       
  2372 				m_am_tools, 
       
  2373 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2374 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2375 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2376 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2377 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2378 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2379 		}
       
  2380 
       
  2381 		// Note here we get a reference to the data bytes of the received packet.
       
  2382 		status = p_gsmsim_payloads->get_NONCE_S()->set_buffer(
       
  2383 			payload, buffer, payload->get_data_length(), false, false);
       
  2384 
       
  2385 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2386 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2387 	}
       
  2388 	else if (current_payload == gsmsim_payload_AT_RAND)
       
  2389 	{
       
  2390 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2391 		// | AT_RAND       | Length        |           Reserved            |
       
  2392 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2393 		// |                            n*RAND ...
       
  2394 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2395 		if (payload->get_reserved() != 0u)
       
  2396 		{
       
  2397 			EAP_TRACE_ERROR(
       
  2398 				m_am_tools, 
       
  2399 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2400 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2401 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2402 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2403 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2404 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2405 		}
       
  2406 
       
  2407 		if (payload->get_data_length() < m_minimum_rand_count*SIM_RAND_LENGTH)
       
  2408 		{
       
  2409 			EAP_TRACE_ERROR(
       
  2410 				m_am_tools, 
       
  2411 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2412 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2413 				 EAPL("current payload 0x%04x=%s, length 0x%04x. Too few RAND bytes 0x%04x, 0x%04x bytes required.\n"),
       
  2414 				payload,
       
  2415 				current_payload,
       
  2416 				payload->get_payload_AT_string(),
       
  2417 				payload->get_payload_length(),
       
  2418 				payload->get_data_length(),
       
  2419 				m_minimum_rand_count*SIM_RAND_LENGTH));
       
  2420 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2421 			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges);
       
  2422 		}
       
  2423 
       
  2424 		if ((payload->get_data_length() % SIM_RAND_LENGTH) != 0)
       
  2425 		{
       
  2426 			EAP_TRACE_ERROR(
       
  2427 				m_am_tools, 
       
  2428 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2429 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2430 				 EAPL("current payload 0x%04x=%s, length 0x%04x, n*RAND length ")
       
  2431 				 EAPL("0x%04x is not multiple of one RAND length 0x%04x bytes.\n"),
       
  2432 				payload,
       
  2433 				current_payload,
       
  2434 				payload->get_payload_AT_string(),
       
  2435 				payload->get_payload_length(),
       
  2436 				payload->get_data_length(),
       
  2437 				SIM_RAND_LENGTH));
       
  2438 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2439 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  2440 		}
       
  2441 
       
  2442 		u8_t * n_rands = static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  2443 		if (n_rands == 0)
       
  2444 		{
       
  2445 			EAP_TRACE_ERROR(
       
  2446 				m_am_tools, 
       
  2447 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2448 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2449 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2450 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2451 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2452 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2453 		}
       
  2454 
       
  2455 		status = p_gsmsim_payloads->get_n_RANDs()->set_buffer(
       
  2456 			payload, n_rands, payload->get_data_length(), false, false);
       
  2457 
       
  2458 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2459 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2460 	}
       
  2461 	else if (current_payload == gsmsim_payload_AT_PADDING)
       
  2462 	{
       
  2463 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2464 		// |  AT_PADDING   | Length        | Padding...                    |
       
  2465 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
       
  2466 		// |                                                               |
       
  2467 		// |                                                               |
       
  2468 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2469 
       
  2470 		u8_t * padding = 0;
       
  2471 
       
  2472 		// Note two first octets of padding are the reserved field. It must be zero.
       
  2473 		if (payload->get_reserved() != 0u)
       
  2474 		{
       
  2475 			EAP_TRACE_ERROR(
       
  2476 				m_am_tools, 
       
  2477 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2478 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2479 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2480 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2481 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2482 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2483 		}
       
  2484 
       
  2485 		// NOTE padding data length could be zero.
       
  2486 		if (payload->get_data_length() != 0u)
       
  2487 		{
       
  2488 			padding = static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  2489 		}
       
  2490 
       
  2491 		status = p_gsmsim_payloads->get_padding_payload()->set_buffer(
       
  2492 			payload, padding, payload->get_data_length(), false, false);
       
  2493 
       
  2494 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2495 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2496 	}
       
  2497 	else if (current_payload == gsmsim_payload_AT_NEXT_PSEUDONYM)
       
  2498 	{
       
  2499 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2500 		// | AT_NEXT...YM  | Length        | Actual Pseudonym Length       |
       
  2501 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2502 		// |                                                               |
       
  2503 		// |                           Pseudonym                           |
       
  2504 		// |                                                               |
       
  2505 		// |                                                               |
       
  2506 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2507 
       
  2508 		// Note the reserved field includes the actual length of pseudonym.
       
  2509 		// This must be less or equal to the length field.
       
  2510 		u16_t pseudonym_length = payload->get_reserved();
       
  2511 		if (pseudonym_length == 0u
       
  2512 			|| pseudonym_length > payload->get_data_length())
       
  2513 		{
       
  2514 			EAP_TRACE_ERROR(
       
  2515 				m_am_tools, 
       
  2516 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2517 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2518 				 EAPL("current payload 0x%04x=%s, length 0x%04x, pseudonym length field incorrect 0x%04x.\n"),
       
  2519 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2520 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2521 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2522 		}
       
  2523 
       
  2524 		u8_t * pseudonym = static_cast<u8_t *>(payload->get_data(pseudonym_length));
       
  2525 		if (pseudonym == 0)
       
  2526 		{
       
  2527 			EAP_TRACE_ERROR(
       
  2528 				m_am_tools,
       
  2529 				TRACE_FLAGS_GSMSIM_ERROR,
       
  2530 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2531 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2532 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2533 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2534 		}
       
  2535 
       
  2536 		status = p_gsmsim_payloads->get_NEXT_PSEUDONYM()->set_buffer(
       
  2537 			payload, pseudonym, pseudonym_length, false, false);
       
  2538 
       
  2539 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2540 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2541 	}
       
  2542 	else if (current_payload == gsmsim_payload_AT_NEXT_REAUTH_ID)
       
  2543 	{
       
  2544 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2545 		// | AT_NEXT...ID  | Length        | Actual Identity Length        |
       
  2546 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2547 		// |                                                               |
       
  2548 		// |                  Reauthentication identity                    |
       
  2549 		// |                                                               |
       
  2550 		// |                                                               |
       
  2551 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2552 
       
  2553 		// Note the reserved field includes the actual length of reauthentication identity.
       
  2554 		// This must be less or equal to the length field.
       
  2555 		u16_t next_reauth_id_length = payload->get_reserved();
       
  2556 		if (next_reauth_id_length == 0u
       
  2557 			|| next_reauth_id_length > payload->get_data_length())
       
  2558 		{
       
  2559 			EAP_TRACE_ERROR(
       
  2560 				m_am_tools, 
       
  2561 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2562 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2563 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reauthentication identity length field incorrect 0x%04x.\n"),
       
  2564 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2565 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2566 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2567 		}
       
  2568 
       
  2569 		u8_t * next_reauth_id = static_cast<u8_t *>(payload->get_data(next_reauth_id_length));
       
  2570 		if (next_reauth_id == 0)
       
  2571 		{
       
  2572 			EAP_TRACE_ERROR(
       
  2573 				m_am_tools, 
       
  2574 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2575 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2576 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2577 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2578 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2579 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2580 		}
       
  2581 
       
  2582 		status = p_gsmsim_payloads->get_NEXT_REAUTH_ID()->set_buffer(
       
  2583 			payload, next_reauth_id, next_reauth_id_length, false, false);
       
  2584 
       
  2585 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2586 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2587 	}
       
  2588 	else if (current_payload == gsmsim_payload_AT_RESULT_IND)
       
  2589 	{
       
  2590 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2591 		// | AT_RESULT_IND | Length = 1    |      Reserved                 |
       
  2592 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2593 
       
  2594 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2595 		{
       
  2596 			EAP_TRACE_ERROR(
       
  2597 				m_am_tools, 
       
  2598 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2599 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2600 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2601 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2602 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2603 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2604 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2605 		}
       
  2606 
       
  2607 		EAP_TRACE_DEBUG(
       
  2608 			m_am_tools, 
       
  2609 			TRACE_FLAGS_DEFAULT, 
       
  2610 			(EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2611 			 EAPL("current payload 0x%04x=%s, length 0x%04x, notification code %d.\n"),
       
  2612 			payload,
       
  2613 			current_payload,
       
  2614 			payload->get_payload_AT_string(),
       
  2615 			payload->get_payload_length(),
       
  2616 			payload->get_reserved()));
       
  2617 
       
  2618 		status = p_gsmsim_payloads->get_RESULT_IND()->set_buffer(
       
  2619 			payload, 0, 0u, false, false);
       
  2620 
       
  2621 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2622 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2623 	}
       
  2624 	else if (current_payload == gsmsim_payload_AT_NOTIFICATION)
       
  2625 	{
       
  2626 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2627 		// |AT_NOTIFICATION| Length = 1    |      Notification Code        |
       
  2628 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2629 
       
  2630 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2631 		{
       
  2632 			EAP_TRACE_ERROR(
       
  2633 				m_am_tools, 
       
  2634 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2635 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2636 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2637 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2638 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2639 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2640 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2641 		}
       
  2642 
       
  2643 		// Note the reserved field includes the notification code (triplet status).
       
  2644 		eap_gsmsim_notification_codes_e notification_code = static_cast<eap_gsmsim_notification_codes_e>(payload->get_reserved());
       
  2645 		EAP_UNREFERENCED_PARAMETER(notification_code);
       
  2646 
       
  2647 		EAP_TRACE_DEBUG(
       
  2648 			m_am_tools, 
       
  2649 			TRACE_FLAGS_DEFAULT, 
       
  2650 			(EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2651 			 EAPL("current payload 0x%04x=%s, length 0x%04x, notification code %d.\n"),
       
  2652 			payload,
       
  2653 			current_payload,
       
  2654 			payload->get_payload_AT_string(),
       
  2655 			payload->get_payload_length(),
       
  2656 			payload->get_reserved()));
       
  2657 
       
  2658 		status = p_gsmsim_payloads->get_NOTIFICATION()->set_buffer(
       
  2659 			payload, 0, 0u, false, false);
       
  2660 
       
  2661 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2662 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2663 	}
       
  2664 	else if (current_payload == gsmsim_payload_AT_COUNTER)
       
  2665 	{
       
  2666 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2667 		// |AT_COUNTER     | Length = 1    |      Counter                  |
       
  2668 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2669 
       
  2670 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2671 		{
       
  2672 			EAP_TRACE_ERROR(
       
  2673 				m_am_tools, 
       
  2674 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2675 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2676 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2677 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2678 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2679 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2680 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2681 		}
       
  2682 
       
  2683 		status = p_gsmsim_payloads->get_COUNTER()->set_buffer(
       
  2684 			payload, 0, 0u, false, false);
       
  2685 
       
  2686 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2687 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2688 	}
       
  2689 	else if (current_payload == gsmsim_payload_AT_COUNTER_TOO_SMALL)
       
  2690 	{
       
  2691 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2692 		// |AT_COUNTER_TOO.| Length = 1    |           Reserved            |
       
  2693 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2694 
       
  2695 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2696 		{
       
  2697 			EAP_TRACE_ERROR(
       
  2698 				m_am_tools, 
       
  2699 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2700 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2701 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2702 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2703 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2704 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2705 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2706 		}
       
  2707 
       
  2708 		EAP_TRACE_DEBUG(
       
  2709 			m_am_tools, 
       
  2710 			TRACE_FLAGS_DEFAULT, 
       
  2711 			(EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2712 			 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved %d.\n"),
       
  2713 			payload,
       
  2714 			current_payload,
       
  2715 			payload->get_payload_AT_string(),
       
  2716 			payload->get_payload_length(),
       
  2717 			payload->get_reserved()));
       
  2718 
       
  2719 		status = p_gsmsim_payloads->get_COUNTER_TOO_SMALL()->set_buffer(
       
  2720 			payload, 0, 0u, false, false);
       
  2721 
       
  2722 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2723 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2724 	}
       
  2725 	else if (current_payload == gsmsim_payload_AT_MAC)
       
  2726 	{
       
  2727 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2728 		// | AT_MAC        | Length = 5    |           Reserved            |
       
  2729 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2730 		// |                                                               |
       
  2731 		// |                           MAC                                 |
       
  2732 		// |                                                               |
       
  2733 		// |                                                               |
       
  2734 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2735 		if (payload->get_reserved() != 0u)
       
  2736 		{
       
  2737 			EAP_TRACE_ERROR(
       
  2738 				m_am_tools, 
       
  2739 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2740 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2741 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2742 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2743 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2744 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2745 		}
       
  2746 
       
  2747 		if (payload->get_data_length() != EAP_TYPE_GSMSIM_MAC_SIZE)
       
  2748 		{
       
  2749 			EAP_TRACE_ERROR(
       
  2750 				m_am_tools, 
       
  2751 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2752 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2753 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"),
       
  2754 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length()));
       
  2755 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2756 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2757 		}
       
  2758 
       
  2759 		u8_t * buffer
       
  2760 			= static_cast<u8_t *>(payload->get_data(EAP_TYPE_GSMSIM_MAC_SIZE));
       
  2761 
       
  2762 		if (buffer == 0)
       
  2763 		{
       
  2764 			EAP_TRACE_ERROR(
       
  2765 				m_am_tools, 
       
  2766 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2767 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2768 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2769 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2770 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2771 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2772 		}
       
  2773 
       
  2774 		status = p_gsmsim_payloads->get_MAC()->set_buffer(
       
  2775 			payload, buffer, payload->get_data_length(), false, false);
       
  2776 
       
  2777 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2778 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2779 	}
       
  2780 	else if (current_payload == gsmsim_payload_AT_IV)
       
  2781 	{
       
  2782 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2783 		// | AT_IV         | Length = 5    |           Reserved            |
       
  2784 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2785 		// |                                                               |
       
  2786 		// |                 Initialization Vector (optional)              |
       
  2787 		// |                                                               |
       
  2788 		// |                                                               |
       
  2789 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2790 
       
  2791 		if (payload->get_reserved() != 0u)
       
  2792 		{
       
  2793 			EAP_TRACE_ERROR(
       
  2794 				m_am_tools, 
       
  2795 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2796 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2797 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2798 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2799 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2800 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2801 		}
       
  2802 
       
  2803 		crypto_aes_c aes(m_am_tools);
       
  2804 
       
  2805 		if (aes.get_is_valid() == false)
       
  2806 		{
       
  2807 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2808 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2809 		}
       
  2810 
       
  2811 		if (payload->get_data_length() != aes.get_block_size())
       
  2812 		{
       
  2813 			EAP_TRACE_ERROR(
       
  2814 				m_am_tools, 
       
  2815 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2816 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2817 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"),
       
  2818 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length()));
       
  2819 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2820 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2821 		}
       
  2822 
       
  2823 		u8_t * buffer
       
  2824 			= static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  2825 
       
  2826 		if (buffer == 0)
       
  2827 		{
       
  2828 			EAP_TRACE_ERROR(
       
  2829 				m_am_tools, 
       
  2830 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2831 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2832 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2833 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2834 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2835 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2836 		}
       
  2837 
       
  2838 		// Note here we get a reference to the data bytes of the received packet.
       
  2839 		status = p_gsmsim_payloads->get_IV()->set_buffer(
       
  2840 			payload, buffer, payload->get_data_length(), false, false);
       
  2841 
       
  2842 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2843 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2844 	}
       
  2845 	else if (current_payload == gsmsim_payload_AT_ENCR_DATA)
       
  2846 	{
       
  2847 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2848 		// | AT_ENCR_DATA  | Length        |           Reserved            |
       
  2849 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2850 		// |                                                               |
       
  2851 		// |                    Encrypted Data (optional)                  |
       
  2852 		// |                                                               |
       
  2853 		// |                                                               |
       
  2854 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2855 		if (payload->get_reserved() != 0u)
       
  2856 		{
       
  2857 			EAP_TRACE_ERROR(
       
  2858 				m_am_tools, 
       
  2859 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2860 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2861 				 EAPL("current payload 0x%04x=%s, length 0x%04x, reserved field incorrect 0x%04x.\n"),
       
  2862 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  2863 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2864 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2865 		}
       
  2866 
       
  2867 		if (payload->get_data_length() < 8u)
       
  2868 		{
       
  2869 			EAP_TRACE_ERROR(
       
  2870 				m_am_tools, 
       
  2871 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2872 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2873 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x.\n"),
       
  2874 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_data_length()));
       
  2875 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2876 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2877 		}
       
  2878 
       
  2879 		u8_t * buffer
       
  2880 			= static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  2881 
       
  2882 		if (buffer == 0)
       
  2883 		{
       
  2884 			EAP_TRACE_ERROR(
       
  2885 				m_am_tools, 
       
  2886 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2887 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2888 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2889 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  2890 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2891 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2892 		}
       
  2893 
       
  2894 		status = p_gsmsim_payloads->get_ENCR_DATA()->set_buffer(
       
  2895 			payload, buffer, payload->get_data_length(), false, false);
       
  2896 
       
  2897 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2898 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2899 	}
       
  2900 	else if (current_payload == gsmsim_payload_AT_PERMANENT_ID_REQ)
       
  2901 	{
       
  2902 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2903 		// |AT_PERM..._REQ | Length = 1    |           Reserved            |
       
  2904 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2905 
       
  2906 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2907 		{
       
  2908 			EAP_TRACE_ERROR(
       
  2909 				m_am_tools, 
       
  2910 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2911 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2912 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2913 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2914 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2915 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2916 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2917 		}
       
  2918 
       
  2919 		status = p_gsmsim_payloads->get_PERMANENT_ID_REQ()->set_buffer(
       
  2920 			payload, 0, 0, false, false);
       
  2921 
       
  2922 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2923 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2924 	}
       
  2925 	else if (current_payload == gsmsim_payload_AT_FULLAUTH_ID_REQ)
       
  2926 	{
       
  2927 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2928 		// |AT_FULL..._REQ | Length = 1    |           Reserved            |
       
  2929 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2930 
       
  2931 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2932 		{
       
  2933 			EAP_TRACE_ERROR(
       
  2934 				m_am_tools, 
       
  2935 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2936 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2937 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2938 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2939 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2940 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2941 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2942 		}
       
  2943 
       
  2944 		status = p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->set_buffer(
       
  2945 			payload, 0, 0, false, false);
       
  2946 
       
  2947 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2948 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2949 	}
       
  2950 	else if (current_payload == gsmsim_payload_AT_ANY_ID_REQ)
       
  2951 	{
       
  2952 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2953 		// |AT_ANY..._REQ  | Length = 1    |           Reserved            |
       
  2954 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2955 
       
  2956 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  2957 		{
       
  2958 			EAP_TRACE_ERROR(
       
  2959 				m_am_tools, 
       
  2960 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2961 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2962 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  2963 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2964 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  2965 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2966 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2967 		}
       
  2968 
       
  2969 		status = p_gsmsim_payloads->get_ANY_ID_REQ()->set_buffer(
       
  2970 			payload, 0, 0, false, false);
       
  2971 
       
  2972 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2973 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2974 	}
       
  2975 	else if (current_payload == gsmsim_payload_AT_IDENTITY)
       
  2976 	{
       
  2977 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2978 		// | AT_IDENTITY   | Length        | Actual Identity Length        |
       
  2979 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2980 		// |                                                               |
       
  2981 		// .                 Current Identity (optional)                   .
       
  2982 		// |                                                               |
       
  2983 		// |                                                               |
       
  2984 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2985 		u16_t identity_length = payload->get_reserved();
       
  2986 
       
  2987 		if (payload->get_data_length() == 0
       
  2988 			|| identity_length > payload->get_data_length()
       
  2989 			|| identity_length < 1u)
       
  2990 		{
       
  2991 			EAP_TRACE_ERROR(
       
  2992 				m_am_tools, 
       
  2993 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  2994 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  2995 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, identity_length 0x%04x.\n"),
       
  2996 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  2997 				 payload->get_data_length(), identity_length));
       
  2998 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2999 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3000 		}
       
  3001 
       
  3002 		u8_t * identity_data
       
  3003 			= static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  3004 
       
  3005 		if (identity_data == 0)
       
  3006 		{
       
  3007 			EAP_TRACE_ERROR(
       
  3008 				m_am_tools, 
       
  3009 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3010 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3011 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  3012 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  3013 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3014 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3015 		}
       
  3016 
       
  3017 		if (identity_length < payload->get_data_length())
       
  3018 		{
       
  3019 			crypto_aes_c aes(m_am_tools);
       
  3020 			crypto_cbc_c cbc_aes(m_am_tools, &aes, false);
       
  3021 
       
  3022 			if (cbc_aes.get_is_valid() == false)
       
  3023 			{
       
  3024 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3025 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3026 			}
       
  3027 
       
  3028 			// Includes padding bytes. Those must be zero.
       
  3029 			eap_status_e status = cbc_aes.check_padding_bytes(
       
  3030 				identity_data+identity_length,
       
  3031 				payload->get_data_length()-identity_length,
       
  3032 				0ul);
       
  3033 			if (status != eap_status_ok)
       
  3034 			{
       
  3035 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3036 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3037 			}
       
  3038 		}
       
  3039 
       
  3040 		// We assume the prefix byte is included.
       
  3041 		status = p_gsmsim_payloads->get_IDENTITY_payload()->set_buffer(
       
  3042 			payload, identity_data, identity_length, false, false);
       
  3043 
       
  3044 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3045 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3046 	}
       
  3047 	else if (current_payload == gsmsim_payload_AT_VERSION_LIST)
       
  3048 	{
       
  3049 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3050 		// | AT_VERSION_L..| Length        | Actual Version List Length    |
       
  3051 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3052 		// |  Supported Version 1          |  Padding                      |                        
       
  3053 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   
       
  3054 
       
  3055 		// Note the reserved field includes the actual length of version list.
       
  3056 		// This must be less or equal to the length field.
       
  3057 		u16_t version_list_length = payload->get_reserved();
       
  3058 		if (version_list_length == 0u
       
  3059 			|| version_list_length > payload->get_data_length())
       
  3060 		{
       
  3061 			EAP_TRACE_ERROR(
       
  3062 				m_am_tools, 
       
  3063 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3064 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3065 				 EAPL("current payload 0x%04x=%s, length 0x%04x, version list length field incorrect 0x%04x.\n"),
       
  3066 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), payload->get_reserved()));
       
  3067 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3068 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3069 		}
       
  3070 
       
  3071 		u8_t * version_list = static_cast<u8_t *>(payload->get_data(version_list_length));
       
  3072 		if (version_list == 0)
       
  3073 		{
       
  3074 			EAP_TRACE_ERROR(
       
  3075 				m_am_tools, 
       
  3076 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3077 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3078 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  3079 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  3080 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3081 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3082 		}
       
  3083 
       
  3084 		bool includes_other_version_than_1 = false;
       
  3085 
       
  3086 		eap_status_e status = check_version_list(payload, version_list_length, version_list, &includes_other_version_than_1);
       
  3087 		if (status != eap_status_ok)
       
  3088 		{
       
  3089 			EAP_TRACE_ERROR(
       
  3090 				m_am_tools, 
       
  3091 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3092 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3093 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  3094 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length()));
       
  3095 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3096 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3097 		}
       
  3098 
       
  3099 		p_gsmsim_payloads->set_includes_other_version_than_1(includes_other_version_than_1);
       
  3100 
       
  3101 		status = p_gsmsim_payloads->get_VERSION_LIST()->set_buffer(
       
  3102 			payload, version_list, version_list_length, false, false);
       
  3103 
       
  3104 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3105 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3106 	}
       
  3107 	else if (current_payload == gsmsim_payload_AT_SELECTED_VERSION)
       
  3108 	{
       
  3109 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3110 		// | AT_SELECTED...| Length = 1    |    Selected Version           |
       
  3111 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3112 
       
  3113 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  3114 		{
       
  3115 			EAP_TRACE_ERROR(
       
  3116 				m_am_tools, 
       
  3117 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3118 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3119 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  3120 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  3121 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  3122 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3123 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3124 		}
       
  3125 
       
  3126 		// Note the reserved field includes the selected version.
       
  3127 		eap_gsmsim_version selected_version = static_cast<eap_gsmsim_version>(payload->get_reserved());
       
  3128 
       
  3129 		if (selected_version != GSMSIM_VERSION_1) // This is the only supported GSMSIM version.
       
  3130 		{
       
  3131 			EAP_TRACE_ERROR(
       
  3132 				m_am_tools, 
       
  3133 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3134 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3135 				 EAPL("current payload 0x%04x=%s, length 0x%04x, illegal GSMSIM version %d.\n"),
       
  3136 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), selected_version));
       
  3137 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3138 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3139 		}
       
  3140 
       
  3141 		EAP_TRACE_DEBUG(
       
  3142 			m_am_tools, 
       
  3143 			TRACE_FLAGS_DEFAULT, 
       
  3144 			(EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3145 			 EAPL("current payload 0x%04x=%s, length 0x%04x, selected_version %d.\n"),
       
  3146 			payload,
       
  3147 			current_payload,
       
  3148 			payload->get_payload_AT_string(),
       
  3149 			payload->get_payload_length(),
       
  3150 			selected_version));
       
  3151 
       
  3152 		status = p_gsmsim_payloads->get_SELECTED_VERSION()->set_buffer(
       
  3153 			payload, 0, 0u, false, false);
       
  3154 
       
  3155 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3156 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3157 	}
       
  3158 	else if (current_payload == gsmsim_payload_AT_CLIENT_ERROR_CODE)
       
  3159 	{
       
  3160 		// The format of the AT_CLIENT_ERROR_CODE attribute is shown below.
       
  3161 
       
  3162 		//  0                   1                   2                   3
       
  3163 		//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  3164 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3165 		// |AT_CLIENT_ERR..| Length = 1    |     Client Error Code         |
       
  3166 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3167 		// Note the reserved field includes the selected version.
       
  3168 
       
  3169 		if (payload->get_data_length() != GSMSIM_PAYLOAD_ZERO_DATA_LENGTH)
       
  3170 		{
       
  3171 			EAP_TRACE_ERROR(
       
  3172 				m_am_tools, 
       
  3173 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3174 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3175 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data length incorrect 0x%04x, should be 0x%04x.\n"),
       
  3176 				 payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), 
       
  3177 				 payload->get_data_length(), GSMSIM_PAYLOAD_ZERO_DATA_LENGTH));
       
  3178 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3179 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3180 		}
       
  3181 
       
  3182 		eap_gsmsim_client_error_code_e client_error_code = static_cast<eap_gsmsim_client_error_code_e>(payload->get_reserved());
       
  3183 
       
  3184 		if (client_error_code > eap_gsmsim_client_error_code_maximum_value)
       
  3185 		{
       
  3186 			EAP_TRACE_ERROR(
       
  3187 				m_am_tools, 
       
  3188 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3189 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3190 				 EAPL("current payload 0x%04x=%s, length 0x%04x, illegal GSMSIM version %d.\n"),
       
  3191 				payload, current_payload, payload->get_payload_AT_string(), payload->get_payload_length(), client_error_code));
       
  3192 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3193 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3194 		}
       
  3195 
       
  3196 		EAP_TRACE_DEBUG(
       
  3197 			m_am_tools, 
       
  3198 			TRACE_FLAGS_DEFAULT, 
       
  3199 			(EAPL("eap_type_gsmsim_c::parse_generic_payload(0x%08x): ")
       
  3200 			 EAPL("current payload 0x%04x=%s, length 0x%04x, client_error_code %d.\n"),
       
  3201 			payload,
       
  3202 			current_payload,
       
  3203 			payload->get_payload_AT_string(),
       
  3204 			payload->get_payload_length(),
       
  3205 			client_error_code));
       
  3206 
       
  3207 		status = p_gsmsim_payloads->get_CLIENT_ERROR_CODE()->set_buffer(
       
  3208 			payload, 0, 0u, false, false);
       
  3209 
       
  3210 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3211 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3212 	}
       
  3213 	else if (128 <= current_payload && current_payload <= 255)
       
  3214 	{
       
  3215 		// Unknown skippable attribute.
       
  3216 		if (subtype == gsmsim_subtype_Start)
       
  3217 		{
       
  3218 			// EAP-Request/SIM/Start and EAP-Response/SIM/Start messages may
       
  3219 			// include unknown non-skippable attributes if version list includes
       
  3220 			// other than version 1.
       
  3221 			p_gsmsim_payloads->set_includes_unknown_attribute(current_payload);
       
  3222 
       
  3223 			EAP_TRACE_ERROR(
       
  3224 				m_am_tools, 
       
  3225 				TRACE_FLAGS_DEFAULT, 
       
  3226 				(EAPL("IGNORED: eap_type_gsmsim_c::parse_generic_payload(): Marked non-skippable attribute %d=0x%04x.\n"),
       
  3227 				current_payload,
       
  3228 				current_payload));
       
  3229 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3230 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3231 		}
       
  3232 		else
       
  3233 		{
       
  3234 			// Silently ignore this payload.
       
  3235 			EAP_TRACE_ERROR(
       
  3236 				m_am_tools, 
       
  3237 				TRACE_FLAGS_DEFAULT, 
       
  3238 				(EAPL("IGNORED: eap_type_gsmsim_c::parse_generic_payload(): Ignored skippable attribute %d=0x%04x.\n"),
       
  3239 				current_payload,
       
  3240 				current_payload));
       
  3241 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3242 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3243 		}
       
  3244 	}
       
  3245 	else
       
  3246 	{
       
  3247 		// Unknown non-skippable attribute.
       
  3248 		if (subtype == gsmsim_subtype_Start)
       
  3249 		{
       
  3250 			// EAP-Request/SIM/Start and EAP-Response/SIM/Start messages may
       
  3251 			// include unknown non-skippable attributes if version list includes
       
  3252 			// other than version 1.
       
  3253 			p_gsmsim_payloads->set_includes_unknown_attribute(current_payload);
       
  3254 
       
  3255 			EAP_TRACE_ERROR(
       
  3256 				m_am_tools, 
       
  3257 				TRACE_FLAGS_DEFAULT, 
       
  3258 				(EAPL("IGNORED: eap_type_gsmsim_c::parse_generic_payload(): Marked non-skippable attribute %d=0x%04x.\n"),
       
  3259 				current_payload,
       
  3260 				current_payload));
       
  3261 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3262 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3263 		}
       
  3264 		else
       
  3265 		{
       
  3266 			EAP_TRACE_ERROR(
       
  3267 				m_am_tools, 
       
  3268 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3269 				(EAPL("ERROR: eap_type_gsmsim_c::parse_generic_payload(): Unknown non-skippable attribute %d=0x%04x.\n"),
       
  3270 				current_payload,
       
  3271 				current_payload));
       
  3272 		}
       
  3273 
       
  3274 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3275 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unsupported_gsmsim_payload);
       
  3276 	}
       
  3277 }
       
  3278 
       
  3279 //--------------------------------------------------
       
  3280 
       
  3281 //
       
  3282 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::analyse_gsmsim_packet(
       
  3283 	const eap_am_network_id_c * const receive_network_id,
       
  3284 	gsmsim_header_c * const received_gsmsim,
       
  3285 	const u32_t gsmsim_packet_length,
       
  3286 	gsmsim_payloads_c * const p_gsmsim_payloads)
       
  3287 {
       
  3288 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3289 
       
  3290 	eap_status_e status = eap_status_process_general_error;
       
  3291 
       
  3292 	if (m_is_client == true)
       
  3293 	{
       
  3294 		// Client
       
  3295 
       
  3296 		if (received_gsmsim->get_subtype() == gsmsim_subtype_Start)
       
  3297 		{
       
  3298 			status = handle_start_request_message(
       
  3299 				receive_network_id,
       
  3300 				received_gsmsim,
       
  3301 				gsmsim_packet_length,
       
  3302 				p_gsmsim_payloads);
       
  3303 		}
       
  3304 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Challenge)
       
  3305 		{
       
  3306 			status = handle_challenge_request_message(
       
  3307 				receive_network_id,
       
  3308 				received_gsmsim,
       
  3309 				gsmsim_packet_length,
       
  3310 				p_gsmsim_payloads);
       
  3311 		}
       
  3312 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Notification)
       
  3313 		{
       
  3314 			status = handle_gsmsim_notification_request_message(
       
  3315 				receive_network_id,
       
  3316 				received_gsmsim,
       
  3317 				gsmsim_packet_length,
       
  3318 				p_gsmsim_payloads);
       
  3319 		}
       
  3320 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Re_authentication)
       
  3321 		{
       
  3322 			status = handle_reauthentication_request_message(
       
  3323 				receive_network_id,
       
  3324 				received_gsmsim,
       
  3325 				gsmsim_packet_length,
       
  3326 				p_gsmsim_payloads);
       
  3327 		}
       
  3328 		else
       
  3329 		{
       
  3330 			// Unknown message in this state.
       
  3331 			EAP_TRACE_ERROR(
       
  3332 				m_am_tools, 
       
  3333 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3334 				(EAPL("ERROR: eap_type_gsmsim_c::analyse_gsmsim_packet(): ")
       
  3335 				 EAPL("Unknown message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"),
       
  3336 				received_gsmsim->get_subtype(),
       
  3337 				received_gsmsim->get_subtype_string(),
       
  3338 				m_state,
       
  3339 				get_state_string()));
       
  3340 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3341 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3342 		}
       
  3343 	}
       
  3344 	else
       
  3345 	{
       
  3346 		// Server
       
  3347 
       
  3348 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  3349 		if (received_gsmsim->get_subtype() == gsmsim_subtype_Start)
       
  3350 		{
       
  3351 			status = handle_start_response_message(
       
  3352 				received_gsmsim,
       
  3353 				gsmsim_packet_length,
       
  3354 				p_gsmsim_payloads);
       
  3355 		}
       
  3356 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Challenge)
       
  3357 		{
       
  3358 			status = handle_challenge_response_message(
       
  3359 				receive_network_id,
       
  3360 				received_gsmsim,
       
  3361 				gsmsim_packet_length,
       
  3362 				p_gsmsim_payloads);
       
  3363 		}
       
  3364 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Notification)
       
  3365 		{
       
  3366 			status = handle_notification_response_message(
       
  3367 				receive_network_id,
       
  3368 				received_gsmsim,
       
  3369 				gsmsim_packet_length,
       
  3370 				p_gsmsim_payloads);
       
  3371 		}
       
  3372 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Re_authentication)
       
  3373 		{
       
  3374 			status = handle_reauthentication_response_message(
       
  3375 				receive_network_id,
       
  3376 				received_gsmsim,
       
  3377 				gsmsim_packet_length,
       
  3378 				p_gsmsim_payloads);
       
  3379 		}
       
  3380 		else if (received_gsmsim->get_subtype() == gsmsim_subtype_Client_Error)
       
  3381 		{
       
  3382 			status = handle_client_error_response_message(
       
  3383 				receive_network_id,
       
  3384 				received_gsmsim,
       
  3385 				gsmsim_packet_length,
       
  3386 				p_gsmsim_payloads);
       
  3387 		}
       
  3388 		else
       
  3389 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  3390 		{
       
  3391 			// Unknown message in this state.
       
  3392 			EAP_TRACE_ERROR(
       
  3393 				m_am_tools, 
       
  3394 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  3395 				(EAPL("ERROR: eap_type_gsmsim_c::analyse_gsmsim_packet(): ")
       
  3396 				 EAPL("Unknown message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"),
       
  3397 				received_gsmsim->get_subtype(),
       
  3398 				received_gsmsim->get_subtype_string(),
       
  3399 				m_state,
       
  3400 				get_state_string()));
       
  3401 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3402 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3403 		}
       
  3404 	}
       
  3405 
       
  3406 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3407 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3408 }
       
  3409 
       
  3410 //--------------------------------------------------
       
  3411 
       
  3412 //
       
  3413 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_gsmsim_payload(
       
  3414 	const gsmsim_payload_AT_header_c * const p_payload,
       
  3415 	u32_t * const buffer_length,
       
  3416 	gsmsim_payloads_c * const p_gsmsim_payloads,
       
  3417 	const gsmsim_subtype_e subtype)
       
  3418 {
       
  3419 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3420 
       
  3421 	gsmsim_payload_AT_header_c payload(
       
  3422 		m_am_tools,
       
  3423 		p_payload->get_header_buffer(*buffer_length),
       
  3424 		*buffer_length); // Const correctness is gone.
       
  3425 
       
  3426 	gsmsim_payload_AT_type_e current_payload = payload.get_current_payload();
       
  3427 
       
  3428 	eap_status_e status = eap_status_header_corrupted;
       
  3429 
       
  3430 	if (payload.get_is_valid() == true
       
  3431 		&& current_payload != gsmsim_payload_NONE)
       
  3432 	{
       
  3433 		if (*buffer_length < payload.get_header_length()+payload.get_data_length())
       
  3434 		{
       
  3435 			EAP_TRACE_ERROR(
       
  3436 				m_am_tools,
       
  3437 				TRACE_FLAGS_GSMSIM_ERROR,
       
  3438 				(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(0x%08x): current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"),
       
  3439 				payload.get_header_buffer(0ul),
       
  3440 				 current_payload,
       
  3441 				 payload.get_payload_AT_string(),
       
  3442 				 payload.get_data_length(),
       
  3443 				 *buffer_length));
       
  3444 			EAP_TRACE_ERROR(
       
  3445 				m_am_tools,
       
  3446 				TRACE_FLAGS_GSMSIM_ERROR,
       
  3447 				(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(): GSMSIM-payload header is corrupted.\n")));
       
  3448 			EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
       
  3449 				payload.get_header_buffer(*buffer_length),
       
  3450 				*buffer_length));
       
  3451 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3452 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3453 		}
       
  3454 
       
  3455 		status = parse_generic_payload(current_payload, &payload, p_gsmsim_payloads, subtype);
       
  3456 		if (status != eap_status_ok)
       
  3457 		{
       
  3458 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3459 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3460 		}
       
  3461 
       
  3462 		EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length());
       
  3463 		*buffer_length -= payload.get_header_length()+payload.get_data_length();
       
  3464 
       
  3465 		while(*buffer_length >= payload.get_header_length()
       
  3466 			&& payload.get_is_valid() == true
       
  3467 			&& payload.get_header_buffer_length() >= (payload.get_header_length()+payload.get_data_length()))
       
  3468 		{
       
  3469 			payload.set_header_buffer(
       
  3470 					payload.get_next_header(),
       
  3471 					payload.get_header_buffer_length()-(payload.get_header_length()+payload.get_data_length()));
       
  3472 			if (payload.get_is_valid() == false)
       
  3473 			{
       
  3474 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3475 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3476 			}
       
  3477 
       
  3478 			current_payload = payload.get_current_payload();
       
  3479 
       
  3480 			if (*buffer_length < payload.get_header_length()+payload.get_data_length())
       
  3481 			{
       
  3482 				EAP_TRACE_ERROR(
       
  3483 					m_am_tools,
       
  3484 					TRACE_FLAGS_GSMSIM_ERROR,
       
  3485 					(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(0x%08x): current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"),
       
  3486 					 payload.get_header_buffer(0ul),
       
  3487 					 current_payload,
       
  3488 					 payload.get_payload_AT_string(),
       
  3489 					 payload.get_data_length(),
       
  3490 					 *buffer_length));
       
  3491 				EAP_TRACE_ERROR(
       
  3492 					m_am_tools,
       
  3493 					TRACE_FLAGS_GSMSIM_ERROR,
       
  3494 					(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(): GSMSIM-payload header is corrupted.\n")));
       
  3495 				EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
       
  3496 					payload.get_header_buffer(*buffer_length),
       
  3497 					*buffer_length));
       
  3498 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3499 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3500 			}
       
  3501 
       
  3502 			status = parse_generic_payload(current_payload, &payload, p_gsmsim_payloads, subtype);
       
  3503 			if (status != eap_status_ok)
       
  3504 			{
       
  3505 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3506 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3507 			}
       
  3508 
       
  3509 			EAP_ASSERT_ALWAYS(*buffer_length >= payload.get_header_length()+payload.get_data_length());
       
  3510 			*buffer_length -= payload.get_header_length()+payload.get_data_length();
       
  3511 		}
       
  3512 	}
       
  3513 
       
  3514 	if (*buffer_length != 0u)
       
  3515 	{
       
  3516 		EAP_TRACE_ERROR(
       
  3517 			m_am_tools,
       
  3518 			TRACE_FLAGS_GSMSIM_ERROR,
       
  3519 			(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_payload(): ")
       
  3520 			 EAPL("GSMSIM-header is corrupted. Buffer length and payload length does not match. %lu illegal bytes.\n"),
       
  3521 			 *buffer_length));
       
  3522 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3523 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3524 	}
       
  3525 
       
  3526 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3527 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3528 }
       
  3529 
       
  3530 //--------------------------------------------------
       
  3531 
       
  3532 //
       
  3533 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::parse_gsmsim_packet(
       
  3534 	gsmsim_header_c * const gsmsim,
       
  3535 	const u32_t gsmsim_packet_length,
       
  3536 	gsmsim_payloads_c * const p_gsmsim_payloads)
       
  3537 {
       
  3538 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3539 
       
  3540 	if (gsmsim->get_length() < gsmsim->get_header_length())
       
  3541 	{
       
  3542 		EAP_TRACE_ERROR(
       
  3543 			m_am_tools,
       
  3544 			TRACE_FLAGS_GSMSIM_ERROR,
       
  3545 			(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_packet(): ")
       
  3546 			 EAPL("GSMSIM-header is corrupted. Buffer length and payload ")
       
  3547 			 EAPL("length does not match. GSMSIM-header length %lu < minimum GSMSIM-header length %lu.\n"),
       
  3548 			gsmsim->get_length(),
       
  3549 			gsmsim->get_header_length()));
       
  3550 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3551 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3552 	}
       
  3553 
       
  3554 	if (gsmsim->get_length() > gsmsim_packet_length)
       
  3555 	{
       
  3556 		EAP_TRACE_ERROR(
       
  3557 			m_am_tools, 
       
  3558 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  3559 			(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_packet(): ")
       
  3560 			 EAPL("GSMSIM-header is corrupted. Buffer length and payload ")
       
  3561 			 EAPL("length does not match. GSMSIM-header length %lu > packet length %lu\n"),
       
  3562 			gsmsim->get_length(),
       
  3563 			gsmsim_packet_length));
       
  3564 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3565 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3566 	}
       
  3567 
       
  3568 	u32_t buffer_length = gsmsim->get_length() - gsmsim->get_header_length();
       
  3569 
       
  3570 	if (buffer_length == 0u)
       
  3571 	{
       
  3572 		// No payload in this packet.
       
  3573 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3574 	}
       
  3575 
       
  3576 
       
  3577 	gsmsim_payload_AT_header_c payload(
       
  3578 		m_am_tools,
       
  3579 		gsmsim->get_data(buffer_length),
       
  3580 		buffer_length);
       
  3581 
       
  3582 	if (payload.get_is_valid() == false)
       
  3583 	{
       
  3584 		EAP_TRACE_ERROR(
       
  3585 			m_am_tools, 
       
  3586 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  3587 			(EAPL("ERROR: No gsmsim_payload_AT_header_c.\n")));
       
  3588 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3589 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3590 	}
       
  3591 
       
  3592 
       
  3593 	eap_status_e status = parse_gsmsim_payload(
       
  3594 		&payload,
       
  3595 		&buffer_length,
       
  3596 		p_gsmsim_payloads,
       
  3597 		gsmsim->get_subtype());
       
  3598 
       
  3599 	if (status != eap_status_ok)
       
  3600 	{
       
  3601 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3602 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3603 	}
       
  3604 	else if (buffer_length != 0u)
       
  3605 	{
       
  3606 		EAP_TRACE_ERROR(
       
  3607 			m_am_tools,
       
  3608 			TRACE_FLAGS_GSMSIM_ERROR,
       
  3609 			(EAPL("ERROR: eap_type_gsmsim_c::parse_gsmsim_packet(): ")
       
  3610 			 EAPL("GSMSIM-header is corrupted. Buffer length and payload ")
       
  3611 			 EAPL("length does not match. Illegal byte count %lu\n"),
       
  3612 			buffer_length));
       
  3613 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3614 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3615 	}
       
  3616 
       
  3617 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3618 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3619 }
       
  3620 
       
  3621 //--------------------------------------------------
       
  3622 
       
  3623 //
       
  3624 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_packet(
       
  3625 	const eap_am_network_id_c * const receive_network_id,
       
  3626 	gsmsim_header_c * const received_gsmsim,
       
  3627 	const u32_t gsmsim_length,
       
  3628 	gsmsim_payloads_c * const p_gsmsim_payloads)
       
  3629 {
       
  3630 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3631 
       
  3632 	eap_status_e status(eap_status_header_corrupted);
       
  3633 
       
  3634 #if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
  3635 
       
  3636 	status = check_valid_state(received_gsmsim->get_subtype());
       
  3637 	if (status != eap_status_ok)
       
  3638 	{
       
  3639 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3640 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3641 	}
       
  3642 
       
  3643 #endif //#if !defined(NO_EAP_TYPE_GSMSIM_MESSAGE_STATE_CHECK)
       
  3644 
       
  3645 	status = parse_gsmsim_packet(received_gsmsim, gsmsim_length, p_gsmsim_payloads);
       
  3646 	if (status != eap_status_ok)
       
  3647 	{
       
  3648 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3649 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3650 	}
       
  3651 
       
  3652 	status = analyse_gsmsim_packet(
       
  3653 		receive_network_id,
       
  3654 		received_gsmsim,
       
  3655 		gsmsim_length,
       
  3656 		p_gsmsim_payloads);
       
  3657 
       
  3658 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3659 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3660 }
       
  3661 
       
  3662 
       
  3663 //--------------------------------------------------
       
  3664 
       
  3665 #if defined(USE_EAP_TRACE)
       
  3666 
       
  3667 // 
       
  3668 EAP_FUNC_EXPORT void eap_type_gsmsim_c::packet_trace(
       
  3669 	eap_const_string prefix,
       
  3670 	const eap_am_network_id_c * const /* receive_network_id */,
       
  3671 	eap_header_wr_c * const eap_packet,
       
  3672 	const u32_t /* eap_packet_length */)
       
  3673 {
       
  3674 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3675 
       
  3676 	EAP_UNREFERENCED_PARAMETER(prefix);
       
  3677 
       
  3678 	if (eap_packet->get_length() > eap_header_base_c::get_header_length()
       
  3679 		&& eap_packet->get_type() == eap_type_gsmsim)
       
  3680 	{
       
  3681 		gsmsim_header_c gsmsim_eap(
       
  3682 			m_am_tools,
       
  3683 			eap_packet->get_header_buffer(eap_packet->get_header_buffer_length()),
       
  3684 			eap_packet->get_header_buffer_length());
       
  3685 
       
  3686 		gsmsim_eap.get_code(); // This is just to make some use in release version.
       
  3687 
       
  3688 		EAP_TRACE_DEBUG(
       
  3689 			m_am_tools,
       
  3690 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  3691 			(EAPL("%s EAP_type_GSMSIM: %s, (0x%08x), code=0x%02x=%s, identifier=0x%02x, ")
       
  3692 			 EAPL("length=0x%04x, type=0x%08x=%s, subtype=0x%02x=%s\n"),
       
  3693 			 prefix,
       
  3694 			 (m_is_client == true) ? "client": "server",
       
  3695 			 this,
       
  3696 			 gsmsim_eap.get_code(),
       
  3697 			 gsmsim_eap.get_code_string(),
       
  3698 			 gsmsim_eap.get_identifier(),
       
  3699 			 gsmsim_eap.get_length(),
       
  3700 			 convert_eap_type_to_u32_t(gsmsim_eap.get_type()),
       
  3701 			 gsmsim_eap.get_eap_type_string(),
       
  3702 			 gsmsim_eap.get_subtype(),
       
  3703 			 gsmsim_eap.get_subtype_string()));
       
  3704 		
       
  3705 		EAP_TRACE_DEBUG(m_am_tools, eap_am_tools_c::eap_trace_mask_eap_messages,
       
  3706 			(EAPL("\n\t%s\n\tcode       = 0x%02x   = %s\n\tidentifier = 0x%02x")
       
  3707 			 EAPL("\n\tlength     = 0x%04x = %lu\n\ttype       = 0x%08x   = %s\n\tsubtype    = 0x%02x   = %s\n"),
       
  3708 			(m_is_client == true) ? "client": "server",
       
  3709 			gsmsim_eap.get_code(),
       
  3710 			gsmsim_eap.get_code_string(),
       
  3711 			gsmsim_eap.get_identifier(),
       
  3712 			gsmsim_eap.get_length(),
       
  3713 			gsmsim_eap.get_length(),
       
  3714 			convert_eap_type_to_u32_t(gsmsim_eap.get_type()),
       
  3715 			gsmsim_eap.get_eap_type_string(),
       
  3716 			gsmsim_eap.get_subtype(),
       
  3717 			gsmsim_eap.get_subtype_string()));
       
  3718 	}
       
  3719 	else if (eap_packet->get_length() > eap_header_base_c::get_header_length())
       
  3720 	{
       
  3721 		EAP_TRACE_DEBUG(
       
  3722 			m_am_tools,
       
  3723 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  3724 			(EAPL("%s EAP_type_GSMSIM: %s, (0x%08x), code=0x%02x=%s, identifier=0x%02x, length=0x%04x, type=0x%08x=%s\n"),
       
  3725 			prefix,
       
  3726 			(m_is_client == true) ? "client": "server",
       
  3727 			this,
       
  3728 			eap_packet->get_code(),
       
  3729 			eap_packet->get_code_string(),
       
  3730 			eap_packet->get_identifier(),
       
  3731 			eap_packet->get_length(),
       
  3732 			convert_eap_type_to_u32_t(eap_packet->get_type()),
       
  3733 			eap_packet->get_type_string()));
       
  3734 
       
  3735 		EAP_TRACE_DEBUG(
       
  3736 			m_am_tools,
       
  3737 			eap_am_tools_c::eap_trace_mask_eap_messages,
       
  3738 			(EAPL("\n\t%s\n\tcode       = 0x%02x   = %s\n\tidentifier = 0x%02x\n\tlength     = 0x%04x = %lu\n\ttype       = 0x%08x   = %s\n"),
       
  3739 			(m_is_client == true) ? "client": "server",
       
  3740 			eap_packet->get_code(),
       
  3741 			eap_packet->get_code_string(),
       
  3742 			eap_packet->get_identifier(),
       
  3743 			eap_packet->get_length(),
       
  3744 			eap_packet->get_length(),
       
  3745 			convert_eap_type_to_u32_t(eap_packet->get_type()),
       
  3746 			eap_packet->get_type_string()));
       
  3747 	}
       
  3748 	else
       
  3749 	{
       
  3750 		EAP_TRACE_DEBUG(
       
  3751 			m_am_tools,
       
  3752 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  3753 			(EAPL("%s EAP_type_GSMSIM: %s, (0x%08x), code=0x%02x=%s, identifier=0x%02x, length=0x%04x\n"),
       
  3754 			prefix,
       
  3755 			(m_is_client == true) ? "client": "server",
       
  3756 			this,
       
  3757 			eap_packet->get_code(),
       
  3758 			eap_packet->get_code_string(),
       
  3759 			eap_packet->get_identifier(),
       
  3760 			eap_packet->get_length()));
       
  3761 
       
  3762 		EAP_TRACE_DEBUG(
       
  3763 			m_am_tools,
       
  3764 			eap_am_tools_c::eap_trace_mask_eap_messages,
       
  3765 			(EAPL("\n\t%s\n\tcode       = 0x%02x   = %s\n\tidentifier = 0x%02x\n\tlength     = 0x%04x = %lu\n"),
       
  3766 			(m_is_client == true) ? "client": "server",
       
  3767 			eap_packet->get_code(),
       
  3768 			eap_packet->get_code_string(),
       
  3769 			eap_packet->get_identifier(),
       
  3770 			eap_packet->get_length(),
       
  3771 			eap_packet->get_length()));
       
  3772 	}
       
  3773 
       
  3774 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3775 }
       
  3776 
       
  3777 #endif //#if defined(USE_EAP_TRACE)
       
  3778 
       
  3779 //--------------------------------------------------
       
  3780 
       
  3781 // 
       
  3782 EAP_FUNC_EXPORT eap_variable_data_c * eap_type_gsmsim_c::get_nai_realm()
       
  3783 {
       
  3784 	return &m_manual_realm;
       
  3785 }
       
  3786 
       
  3787 //--------------------------------------------------
       
  3788 
       
  3789 // 
       
  3790 EAP_FUNC_EXPORT void eap_type_gsmsim_c::update_buffer_indexes(
       
  3791 	const u32_t maximum_buffer_size,
       
  3792 	const u32_t payload_size,
       
  3793 	u32_t * const buffer_offset,
       
  3794 	u32_t * const buffer_free)
       
  3795 {
       
  3796 	EAP_UNREFERENCED_PARAMETER(maximum_buffer_size);
       
  3797 
       
  3798 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3799 
       
  3800 	EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length);
       
  3801 	EAP_ASSERT_ALWAYS(*buffer_free >= payload_size);
       
  3802 	EAP_ASSERT_ALWAYS(m_gsmsim_header_offset+m_MTU == *buffer_offset + *buffer_free);
       
  3803 
       
  3804 	*buffer_free -= payload_size;
       
  3805 	*buffer_offset += payload_size;
       
  3806 
       
  3807 	EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length);
       
  3808 	EAP_ASSERT_ALWAYS(*buffer_offset <= m_gsmsim_header_offset+m_MTU);
       
  3809 
       
  3810 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3811 }
       
  3812 
       
  3813 //--------------------------------------------------
       
  3814 
       
  3815 // 
       
  3816 EAP_FUNC_EXPORT void eap_type_gsmsim_c::update_payload_indexes(
       
  3817 	const u32_t maximum_buffer_size,
       
  3818 	const u32_t eap_header_size,
       
  3819 	const u32_t payload_size,
       
  3820 	u32_t * const data_offset,
       
  3821 	u32_t * const data_free,
       
  3822 	u32_t * const buffer_offset,
       
  3823 	u32_t * const buffer_free)
       
  3824 {
       
  3825 	EAP_UNREFERENCED_PARAMETER(eap_header_size);
       
  3826 
       
  3827 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3828 
       
  3829 	EAP_ASSERT_ALWAYS(*buffer_offset == m_gsmsim_header_offset + eap_header_size + *data_offset);
       
  3830 	EAP_ASSERT_ALWAYS(*buffer_free == *data_free);
       
  3831 	EAP_ASSERT_ALWAYS(*data_free >= payload_size);
       
  3832 
       
  3833 	*data_free -= payload_size;
       
  3834 	*data_offset += payload_size;
       
  3835 
       
  3836 	update_buffer_indexes(
       
  3837 		maximum_buffer_size,
       
  3838 		payload_size,
       
  3839 		buffer_offset,
       
  3840 		buffer_free);
       
  3841 
       
  3842 	EAP_ASSERT_ALWAYS(*buffer_offset == m_gsmsim_header_offset + eap_header_size + *data_offset);
       
  3843 	EAP_ASSERT_ALWAYS(*buffer_free == *data_free);
       
  3844 
       
  3845 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3846 }
       
  3847 
       
  3848 //--------------------------------------------------
       
  3849 
       
  3850 // 
       
  3851 EAP_FUNC_EXPORT bool eap_type_gsmsim_c::get_is_client() 
       
  3852 {
       
  3853 	return m_is_client;
       
  3854 }
       
  3855 
       
  3856 //--------------------------------------------------
       
  3857 
       
  3858 // 
       
  3859 EAP_FUNC_EXPORT void eap_type_gsmsim_c::set_is_valid()
       
  3860 {
       
  3861 	m_is_valid = true;
       
  3862 }
       
  3863 
       
  3864 //--------------------------------------------------
       
  3865 
       
  3866 // 
       
  3867 EAP_FUNC_EXPORT bool eap_type_gsmsim_c::get_is_valid()
       
  3868 {
       
  3869 	return m_is_valid;
       
  3870 }
       
  3871 
       
  3872 //--------------------------------------------------
       
  3873 
       
  3874 // 
       
  3875 EAP_FUNC_EXPORT void eap_type_gsmsim_c::state_notification(
       
  3876 	const abs_eap_state_notification_c * const state
       
  3877 	)
       
  3878 {
       
  3879 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3880 
       
  3881 	EAP_TRACE_DEBUG(
       
  3882 		m_am_tools, 
       
  3883 		TRACE_FLAGS_DEFAULT, 
       
  3884 		(EAPL("eap_type_gsmsim_c::state_notification(): get_type_partner() 0x%08x\n"), 
       
  3885 		 get_type_partner()));
       
  3886 
       
  3887 	get_type_partner()->state_notification(state);
       
  3888 
       
  3889 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3890 }
       
  3891 
       
  3892 //--------------------------------------------------
       
  3893 
       
  3894 // 
       
  3895 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::finish_successful_authentication(
       
  3896 	const eap_am_network_id_c * const receive_network_id)
       
  3897 {
       
  3898 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3899 
       
  3900 	EAP_TRACE_DEBUG(
       
  3901 		m_am_tools, 
       
  3902 		TRACE_FLAGS_DEFAULT, 
       
  3903 		(EAPL("eap_type_gsmsim_c::finish_successful_authentication().\n")));
       
  3904 
       
  3905 	if (m_is_client
       
  3906 		&& m_n_rands.get_is_valid_data() == true)
       
  3907 	{
       
  3908 		if (m_do_rand_uniqueness_check == true)
       
  3909 		{
       
  3910 			eap_status_e status = m_am_type_gsmsim->set_rand_is_used(
       
  3911 				&m_n_rands);
       
  3912 			if (status != eap_status_ok)
       
  3913 			{
       
  3914 				// ERROR: write to database failed..
       
  3915 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3916 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
  3917 			}
       
  3918 		}
       
  3919 	}
       
  3920 
       
  3921 	// Here we swap the addresses.
       
  3922 	eap_am_network_id_c send_network_id(m_am_tools,
       
  3923 		receive_network_id->get_destination_id(),
       
  3924 		receive_network_id->get_source_id(),
       
  3925 		receive_network_id->get_type());
       
  3926 
       
  3927 	if (m_master_session_key.get_is_valid_data() == false
       
  3928 		|| m_master_session_key.get_data_length() == 0u)
       
  3929 	{
       
  3930 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3931 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3932 	}
       
  3933 
       
  3934 	eap_status_e status = get_type_partner()->packet_data_crypto_keys(
       
  3935 		&send_network_id,
       
  3936 		&m_master_session_key);
       
  3937 	if (status != eap_status_ok)
       
  3938 	{
       
  3939 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3940 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3941 	}
       
  3942 
       
  3943 	m_authentication_finished_successfully = true;
       
  3944 	set_state(eap_type_gsmsim_state_success);
       
  3945 
       
  3946 	eap_state_notification_c notification(
       
  3947 		m_am_tools,
       
  3948 		&m_send_network_id,
       
  3949 		m_is_client,
       
  3950 		eap_state_notification_eap,
       
  3951 		eap_protocol_layer_eap,
       
  3952 		eap_type_gsmsim,
       
  3953 		eap_state_none,
       
  3954 		eap_state_authentication_finished_successfully,
       
  3955 		m_last_eap_identifier,
       
  3956 		true);
       
  3957 	state_notification(&notification);
       
  3958 
       
  3959 	// Indicate GSMSIM AM authentication finish.
       
  3960 	m_am_type_gsmsim->authentication_finished(true, m_authentication_type, m_identity_type);
       
  3961 
       
  3962 
       
  3963 	if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION)
       
  3964 	{
       
  3965 		EAP_TRACE_ALWAYS(
       
  3966 			m_am_tools, 
       
  3967 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  3968 			(EAPL("EAP_type_GSMSIM: %s, re-authentication EAP-SUCCESS, ")
       
  3969 			 EAPL("re-authentication identity\n"),
       
  3970 			(m_is_client == true) ? "client": "server"));
       
  3971 	}
       
  3972 	else if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH)
       
  3973 	{
       
  3974 		if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID)
       
  3975 		{
       
  3976 			EAP_TRACE_ALWAYS(
       
  3977 				m_am_tools, 
       
  3978 				TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  3979 				(EAPL("EAP_type_GSMSIM: %s, full authentication EAP-SUCCESS, ")
       
  3980 				 EAPL("pseudonym identity\n"),
       
  3981 				(m_is_client == true) ? "client": "server"));
       
  3982 		}
       
  3983 		else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID)
       
  3984 		{
       
  3985 			EAP_TRACE_ALWAYS(
       
  3986 				m_am_tools, 
       
  3987 				TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  3988 				(EAPL("EAP_type_GSMSIM: %s, full authentication EAP-SUCCESS, ")
       
  3989 				 EAPL("IMSI identity\n"),
       
  3990 				(m_is_client == true) ? "client": "server"));
       
  3991 		}
       
  3992 		else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID)
       
  3993 		{
       
  3994 			EAP_TRACE_ALWAYS(
       
  3995 				m_am_tools, 
       
  3996 				TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  3997 				(EAPL("EAP_type_GSMSIM: %s, full authentication EAP-SUCCESS, ")
       
  3998 				 EAPL("Re-auth identity\n"),
       
  3999 				(m_is_client == true) ? "client": "server"));
       
  4000 		}
       
  4001 		else
       
  4002 		{
       
  4003 			EAP_TRACE_ERROR(
       
  4004 				m_am_tools, 
       
  4005 				TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS|TRACE_FLAGS_GSMSIM_ERROR, 
       
  4006 				(EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication EAP-SUCCESS, ")
       
  4007 				 EAPL("unknown identity\n"),
       
  4008 				(m_is_client == true) ? "client": "server"));
       
  4009 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4010 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  4011 		}
       
  4012 	}
       
  4013 	else
       
  4014 	{
       
  4015 		EAP_TRACE_ERROR(
       
  4016 			m_am_tools, 
       
  4017 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS|TRACE_FLAGS_GSMSIM_ERROR, 
       
  4018 			(EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication EAP-SUCCESS, ")
       
  4019 			 EAPL("unknown identity\n"),
       
  4020 			(m_is_client == true) ? "client": "server"));
       
  4021 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4022 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  4023 	}
       
  4024 
       
  4025 
       
  4026 	cancel_error_message_delay_timer();
       
  4027 
       
  4028 	cancel_notification_message_delay_timer();
       
  4029 
       
  4030 	status = eap_status_ok;
       
  4031 
       
  4032 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4033 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4034 }
       
  4035 
       
  4036 //--------------------------------------------------
       
  4037 
       
  4038 // 
       
  4039 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::packet_process(
       
  4040 	const eap_am_network_id_c * const receive_network_id,
       
  4041 	eap_header_wr_c * const received_eap,
       
  4042 	const u32_t eap_packet_length)
       
  4043 {
       
  4044 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4045 
       
  4046 	if (receive_network_id == 0
       
  4047 		|| receive_network_id->get_is_valid_data() == false)
       
  4048 	{
       
  4049 		EAP_TRACE_ERROR(
       
  4050 			m_am_tools, 
       
  4051 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4052 			(EAPL("ERROR: eap_type_gsmsim_c::packet_process(): receive_network_id=0x%08x is invalid.\n"),
       
  4053 			receive_network_id));
       
  4054 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4055 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4056 	}
       
  4057 
       
  4058 	if (received_eap == 0
       
  4059 		|| received_eap->get_is_valid() == false)
       
  4060 	{
       
  4061 		EAP_TRACE_ERROR(
       
  4062 			m_am_tools, 
       
  4063 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4064 			(EAPL("ERROR: eap_type_gsmsim_c::packet_process(): received_eap 0x%08x is invalid.\n"),
       
  4065 			received_eap));
       
  4066 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4067 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4068 	}
       
  4069 
       
  4070 	EAP_GSMSIM_PACKET_TRACE(
       
  4071 		EAPL("->"),
       
  4072 		receive_network_id,
       
  4073 		received_eap,
       
  4074 		eap_packet_length);
       
  4075 
       
  4076 	if (eap_packet_length < received_eap->get_length())
       
  4077 	{
       
  4078 		EAP_TRACE_ERROR(
       
  4079 			m_am_tools, 
       
  4080 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4081 			(EAPL("ERROR: eap_type_gsmsim_c::packet_process(): ")
       
  4082 			 EAPL("eap_packet_length=0x%04x < received_eap->get_length()=0x%04x.\n"),
       
  4083 			eap_packet_length, received_eap->get_length()));
       
  4084 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4085 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  4086 	}
       
  4087 
       
  4088 	if (received_eap->get_length() < eap_header_base_c::get_header_length())
       
  4089 	{
       
  4090 		EAP_TRACE_ERROR(
       
  4091 			m_am_tools, 
       
  4092 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4093 			(EAPL("ERROR: eap_type_gsmsim_c::packet_process(): received_eap->get_length() ")
       
  4094 			 EAPL("< eap_header_base_c::get_header_length().\n")));
       
  4095 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4096 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  4097 	}
       
  4098 
       
  4099 
       
  4100 	// NOTE: by disabling these calls throughput increases about 18%.
       
  4101 	// Disabling also decreases random seeds.
       
  4102 	m_am_tools->get_crypto()->add_rand_seed(
       
  4103 		received_eap->get_header_buffer(eap_packet_length),
       
  4104 		eap_packet_length);
       
  4105 	m_am_tools->get_crypto()->add_rand_seed_hw_ticks();
       
  4106 
       
  4107 	eap_status_e status = eap_status_process_general_error;
       
  4108 
       
  4109 	if ((m_is_client == true
       
  4110 		&& received_eap->get_code() == eap_code_request)
       
  4111 		|| (m_is_client == false
       
  4112 		&& received_eap->get_code() == eap_code_response))
       
  4113 	{
       
  4114 		if (received_eap->get_type() == eap_type_identity
       
  4115 			|| received_eap->get_type() == eap_type_gsmsim)
       
  4116 		{
       
  4117 			if (received_eap->get_type() == eap_type_identity
       
  4118 				&& received_eap->get_code() == eap_code_request
       
  4119 				&& received_eap->get_length() <= eap_header_base_c::get_header_length())
       
  4120 			{
       
  4121 				status = eap_status_header_corrupted;
       
  4122 			}
       
  4123 			else if (received_eap->get_type() == eap_type_identity
       
  4124 				&& received_eap->get_code() == eap_code_response
       
  4125 				&& received_eap->get_length() <= eap_header_base_c::get_header_length())
       
  4126 			{
       
  4127 				status = eap_status_header_corrupted;
       
  4128 			}
       
  4129 			else if (received_eap->get_type() == eap_type_gsmsim
       
  4130 				&& received_eap->get_length() < received_eap->get_header_length())
       
  4131 			{
       
  4132 				status = eap_status_header_corrupted;
       
  4133 			}
       
  4134 			else
       
  4135 			{
       
  4136 				gsmsim_header_c gsmsim_header(
       
  4137 					m_am_tools,
       
  4138 					received_eap->get_header_buffer(received_eap->get_header_buffer_length()),
       
  4139 					received_eap->get_header_buffer_length());
       
  4140 
       
  4141 				if (gsmsim_header.get_is_valid() == false)
       
  4142 				{
       
  4143 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4144 					return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  4145 				}
       
  4146 
       
  4147 				status = gsmsim_packet_process(
       
  4148 					receive_network_id,
       
  4149 					&gsmsim_header,
       
  4150 					eap_packet_length,
       
  4151 					m_is_client);
       
  4152 
       
  4153 				if (status != eap_status_ok
       
  4154 					&& status != eap_status_success
       
  4155 					&& status != eap_status_drop_packet_quietly
       
  4156 					&& status != eap_status_pending_request)
       
  4157 				{
       
  4158 					eap_status_string_c status_string;
       
  4159 					EAP_UNREFERENCED_PARAMETER(status_string);
       
  4160 					EAP_TRACE_DEBUG(
       
  4161 						m_am_tools, 
       
  4162 						TRACE_FLAGS_GSMSIM_ERROR, 
       
  4163 						(EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process() failed\n"),
       
  4164 						status_string.get_status_string(status), status));
       
  4165 
       
  4166 					if (m_is_client == true)
       
  4167 					{
       
  4168 						status = initialize_error_message(
       
  4169 							status);
       
  4170 					}
       
  4171 					else
       
  4172 					{
       
  4173 						status = initialize_notification_message();
       
  4174 					}
       
  4175 
       
  4176 					if (status != eap_status_ok)
       
  4177 					{
       
  4178 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4179 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  4180 					}
       
  4181 				}
       
  4182 				else if (status == eap_status_ok)
       
  4183 				{
       
  4184 					EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false);
       
  4185 				}
       
  4186 			}
       
  4187 
       
  4188 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4189 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4190 		}
       
  4191 		else if (received_eap->get_type() == eap_type_notification)
       
  4192 		{
       
  4193 			EAP_TRACE_DEBUG(
       
  4194 				m_am_tools, 
       
  4195 				TRACE_FLAGS_DEFAULT, 
       
  4196 				(EAPL("dropped EAP type notification: code=0x%02x, ")
       
  4197 				 EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x\n"),
       
  4198 				 received_eap->get_code(),
       
  4199 				 received_eap->get_identifier(), 
       
  4200 				 received_eap->get_length(),
       
  4201 				 convert_eap_type_to_u32_t(received_eap->get_type())));
       
  4202 
       
  4203 			status = eap_status_illegal_eap_type;
       
  4204 
       
  4205 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4206 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4207 		}
       
  4208 		else
       
  4209 		{
       
  4210 			EAP_TRACE_ERROR(
       
  4211 				m_am_tools, 
       
  4212 				TRACE_FLAGS_DEFAULT, 
       
  4213 				(EAPL("dropped EAP type unknown: code=0x%02x, ")
       
  4214 				 EAPL("identifier=0x%02x, length=0x%04x, type=0x%08x\n"),
       
  4215 				 received_eap->get_code(),
       
  4216 				 received_eap->get_identifier(), 
       
  4217 				 received_eap->get_length(),
       
  4218 				 convert_eap_type_to_u32_t(received_eap->get_type())));
       
  4219 
       
  4220 			status = eap_status_illegal_eap_type;
       
  4221 
       
  4222 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4223 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4224 		}
       
  4225 	}
       
  4226 	else if (m_is_client == true
       
  4227 		&& (received_eap->get_code() == eap_code_success
       
  4228 		|| received_eap->get_code() == eap_code_failure))
       
  4229 	{
       
  4230 		// Here we swap the addresses.
       
  4231 		eap_am_network_id_c send_network_id(m_am_tools,
       
  4232 			receive_network_id->get_destination_id(),
       
  4233 			receive_network_id->get_source_id(),
       
  4234 			receive_network_id->get_type());
       
  4235 
       
  4236 		if (received_eap->get_code() == eap_code_success)
       
  4237 		{
       
  4238 			if (m_state == eap_type_gsmsim_state_waiting_for_success)
       
  4239 			{
       
  4240 				EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false);
       
  4241 
       
  4242 				if (m_wait_eap_success_packet == false)
       
  4243 				{
       
  4244 					/**
       
  4245 					 * @{ Check right functionality.
       
  4246 					 * Here we return eap_status_ok, eap_status_success was returned after successfull
       
  4247 					 * EAP-Request/SIM/Challenge. This may change after EAP, 802.1X and 802.11i specifications are ready. }
       
  4248 					 */
       
  4249 					status = eap_status_ok;
       
  4250 				}
       
  4251 				else
       
  4252 				{
       
  4253 					status = finish_successful_authentication(
       
  4254 						receive_network_id);
       
  4255 				}
       
  4256 			}
       
  4257 			else
       
  4258 			{
       
  4259 				EAP_TRACE_DEBUG(
       
  4260 					m_am_tools, 
       
  4261 					TRACE_FLAGS_DEFAULT, 
       
  4262 					(EAPL("dropped EAP-Success: code=0x%02x, identifier=0x%02x, ")
       
  4263 					 EAPL("length=0x%04x, state %d=%s, is client %d\n"),
       
  4264 					received_eap->get_code(),
       
  4265 					received_eap->get_identifier(),
       
  4266 					received_eap->get_length(),
       
  4267 					m_state,
       
  4268 					get_state_string(),
       
  4269 					(m_is_client == true)));
       
  4270 				status = eap_status_drop_packet_quietly;
       
  4271 			}
       
  4272 		}
       
  4273 		else if (received_eap->get_code() == eap_code_failure)
       
  4274 		{
       
  4275 			// EAP is quite sloppy protocol.
       
  4276 			// Somebody just send a EAP-failure message and authentication is terminated.
       
  4277 
       
  4278 			// Save received failure. We do not change our state yet.
       
  4279 			// The real correct EAP message could be received later if this failure was
       
  4280 			// send by nasty attacker.
       
  4281 			m_failure_message_received = true;
       
  4282 			// We handle the EAP-Request/Failure message after a timeout.
       
  4283 
       
  4284 			status = eap_status_ok;
       
  4285 		}
       
  4286 		else
       
  4287 		{
       
  4288 			EAP_TRACE_ERROR(
       
  4289 				m_am_tools, 
       
  4290 				TRACE_FLAGS_DEFAULT, 
       
  4291 				(EAPL("dropped EAP code unknown: code=0x%02x, ")
       
  4292 				 EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"),
       
  4293 				 received_eap->get_code(), received_eap->get_identifier(), 
       
  4294 				 received_eap->get_length(), (m_is_client == true)));
       
  4295 			status = eap_status_illegal_eap_code;
       
  4296 		}
       
  4297 	}
       
  4298 	else
       
  4299 	{
       
  4300 		EAP_TRACE_ERROR(
       
  4301 			m_am_tools, 
       
  4302 			TRACE_FLAGS_DEFAULT, 
       
  4303 			(EAPL("dropped EAP code unknown: code=0x%02x, ")
       
  4304 			 EAPL("identifier=0x%02x, length=0x%04x, is client %d\n"),
       
  4305 			 received_eap->get_code(), received_eap->get_identifier(), 
       
  4306 			 received_eap->get_length(), (m_is_client == true)));
       
  4307 		status = eap_status_illegal_eap_code;
       
  4308 	}
       
  4309 
       
  4310 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4311 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4312 }
       
  4313 
       
  4314 //--------------------------------------------------
       
  4315 
       
  4316 //
       
  4317 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::new_handler(
       
  4318 	const eap_am_network_id_c * const /* receive_network_id */,
       
  4319 	const bool is_client_when_true)
       
  4320 {
       
  4321 	EAP_TRACE_DEBUG(
       
  4322 		m_am_tools, 
       
  4323 		TRACE_FLAGS_DEFAULT, 
       
  4324 		(EAPL("eap_type_gsmsim_c::new_handler(): Creating new handler 0x%08x.\n"),
       
  4325 		this));
       
  4326 
       
  4327 	// We do not have handler yet and the message is identity EAP-message.
       
  4328 	// A new handler is needed.
       
  4329 	// Handler is selected using own address and peer address.
       
  4330 
       
  4331 	m_is_client = is_client_when_true;
       
  4332 
       
  4333 	if (is_client_when_true == true)
       
  4334 	{
       
  4335 		set_state(eap_type_gsmsim_state_waiting_for_identity_request);
       
  4336 	}
       
  4337 	else if (is_client_when_true == false)
       
  4338 	{
       
  4339 		set_state(eap_type_gsmsim_state_waiting_for_identity_response);
       
  4340 	}
       
  4341 
       
  4342 	EAP_TRACE_DEBUG(
       
  4343 		m_am_tools, 
       
  4344 		TRACE_FLAGS_DEFAULT, 
       
  4345 		(EAPL("eap_type_gsmsim_c::aka_packet_process(0x%08x): New handler created.\n"),
       
  4346 		 this));
       
  4347 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" own address"),
       
  4348 		m_send_network_id.get_source_id()->get_data(m_send_network_id.get_source_id()->get_data_length()),
       
  4349 		m_send_network_id.get_source_id()->get_data_length()));
       
  4350 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("peer address"),
       
  4351 		m_send_network_id.get_destination_id()->get_data(m_send_network_id.get_destination_id()->get_data_length()),
       
  4352 		m_send_network_id.get_destination_id()->get_data_length()));
       
  4353 
       
  4354 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4355 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4356 }
       
  4357 
       
  4358 //--------------------------------------------------
       
  4359 
       
  4360 //
       
  4361 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::gsmsim_packet_process(
       
  4362 	const eap_am_network_id_c * const receive_network_id,
       
  4363 	gsmsim_header_c * const received_gsmsim,
       
  4364 	const u32_t gsmsim_packet_length,
       
  4365 	const bool is_client_when_true)
       
  4366 {
       
  4367 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4368 
       
  4369 	if (receive_network_id == 0
       
  4370 		|| receive_network_id->get_is_valid_data() == false)
       
  4371 	{
       
  4372 		EAP_TRACE_ERROR(
       
  4373 			m_am_tools, 
       
  4374 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4375 			(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4376 			 EAPL("receive_network_id=0x%08x is invalid.\n"),
       
  4377 			receive_network_id));
       
  4378 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4379 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4380 	}
       
  4381 
       
  4382 	if (received_gsmsim == 0
       
  4383 		|| received_gsmsim->get_is_valid() == false)
       
  4384 	{
       
  4385 		EAP_TRACE_ERROR(
       
  4386 			m_am_tools, 
       
  4387 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4388 			(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4389 			 EAPL("received_gsmsim 0x%08x is invalid.\n"),
       
  4390 			received_gsmsim));
       
  4391 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4392 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4393 	}
       
  4394 
       
  4395 	if (gsmsim_packet_length < received_gsmsim->get_length())
       
  4396 	{
       
  4397 		EAP_TRACE_ERROR(
       
  4398 			m_am_tools, 
       
  4399 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4400 			(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4401 			 EAPL("gsmsim_packet_length < received_gsmsim->get_length().\n")));
       
  4402 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4403 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  4404 	}
       
  4405 
       
  4406 	if (received_gsmsim->get_type() == eap_type_gsmsim)
       
  4407 	{
       
  4408 		EAP_TRACE_DEBUG(
       
  4409 			m_am_tools, 
       
  4410 			TRACE_FLAGS_DEFAULT, 
       
  4411 			(EAPL("eap_type_gsmsim_c::gsmsim_packet_process(), GSMSIM subtype %d=%s\n"),
       
  4412 			received_gsmsim->get_subtype(), received_gsmsim->get_subtype_string()));
       
  4413 	}
       
  4414 	else
       
  4415 	{
       
  4416 		EAP_TRACE_DEBUG(
       
  4417 			m_am_tools, 
       
  4418 			TRACE_FLAGS_DEFAULT, 
       
  4419 			(EAPL("eap_type_gsmsim_c::gsmsim_packet_process(), EAP-type 0x%08x=%s\n"),
       
  4420 			convert_eap_type_to_u32_t(received_gsmsim->get_type()),
       
  4421 			received_gsmsim->get_eap_type_string()));
       
  4422 	}
       
  4423 
       
  4424 	eap_status_e status = eap_status_process_general_error;
       
  4425 
       
  4426 	// Here we swap the addresses.
       
  4427 	eap_am_network_id_c send_network_id(m_am_tools,
       
  4428 		receive_network_id->get_destination_id(),
       
  4429 		receive_network_id->get_source_id(),
       
  4430 		receive_network_id->get_type());
       
  4431 
       
  4432 	if (m_state == eap_type_gsmsim_state_none)
       
  4433 	{
       
  4434 		EAP_TRACE_DEBUG(
       
  4435 			m_am_tools, 
       
  4436 			TRACE_FLAGS_DEFAULT, 
       
  4437 			(EAPL("eap_type_gsmsim_c::gsmsim_packet_process(): No handler found.\n")));
       
  4438 
       
  4439 		if (is_client_when_true == false
       
  4440 			&& received_gsmsim->get_type() == eap_type_identity)
       
  4441 		{
       
  4442 			// The EAP-identity is plain EAP-packet without additional fields..
       
  4443 			eap_header_rd_c eap_header(
       
  4444 				m_am_tools,
       
  4445 				received_gsmsim->get_header_buffer(
       
  4446 					received_gsmsim->get_header_buffer_length()),
       
  4447 				received_gsmsim->get_header_buffer_length());
       
  4448 
       
  4449 			// This is just to make some use in release version.
       
  4450 			eap_header.get_type_data_length();
       
  4451 
       
  4452 			EAP_TRACE_DATA_DEBUG(
       
  4453 				m_am_tools,
       
  4454 				TRACE_FLAGS_DEFAULT,
       
  4455 				(EAPL("received: EAP-identity"),
       
  4456 				eap_header.get_type_data(eap_header.get_type_data_length()),
       
  4457 				eap_header.get_type_data_length()));
       
  4458 
       
  4459 			status = new_handler(
       
  4460 				receive_network_id,
       
  4461 				is_client_when_true);
       
  4462 			if (status != eap_status_ok)
       
  4463 			{
       
  4464 				EAP_TRACE_DEBUG(
       
  4465 					m_am_tools, 
       
  4466 					TRACE_FLAGS_GSMSIM_ERROR, 
       
  4467 					(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4468 					 EAPL("new_handler() failed, status %d.\n"),
       
  4469 					status));
       
  4470 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4471 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4472 			}
       
  4473 		}
       
  4474 		else if (is_client_when_true == true
       
  4475 			&& received_gsmsim->get_code() == eap_code_request)
       
  4476 		{
       
  4477 			if (received_gsmsim->get_length() < received_gsmsim->get_header_length())
       
  4478 			{
       
  4479 				status = eap_status_process_illegal_packet_error;
       
  4480 				eap_status_string_c status_string;
       
  4481 				EAP_TRACE_DEBUG(
       
  4482 					m_am_tools,
       
  4483 					TRACE_FLAGS_GSMSIM_ERROR,
       
  4484 					(EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): corrupted GSMSIM-header.\n"),
       
  4485 					status_string.get_status_string(status), status));
       
  4486 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4487 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4488 			}
       
  4489 
       
  4490 			// Here we create a handler and set state to
       
  4491 			//  eap_type_gsmsim_state_waiting_for_start_request
       
  4492 			// if first EAP-Request is EAP-Request/SIM/Start.
       
  4493 			if (received_gsmsim->get_subtype() == gsmsim_subtype_Start)
       
  4494 			{
       
  4495 				eap_header_rd_c eap_header(
       
  4496 					m_am_tools,
       
  4497 					received_gsmsim->get_header_buffer(received_gsmsim->get_header_buffer_length()),
       
  4498 					received_gsmsim->get_header_buffer_length());
       
  4499 
       
  4500 				EAP_UNREFERENCED_PARAMETER(eap_header);
       
  4501 
       
  4502 				EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("received: EAP-Request/GSMSIM/Start"),
       
  4503 					eap_header.get_type_data(eap_header.get_type_data_length()),
       
  4504 					eap_header.get_type_data_length()));
       
  4505 
       
  4506 				// We must query the previous sent EAP-Identity from EAP_Core.
       
  4507 				// The EAP_Core saves the sent EAP-Identity when the EAP-Identity is
       
  4508 				// sent to the network.
       
  4509 				// Previous EAP-type was NOT this instance. EAP-Identity was queried from other instance.
       
  4510 				status = get_type_partner()->get_saved_eap_identity(&m_identity);
       
  4511 				if (status == eap_status_ok)
       
  4512 				{
       
  4513 					status = m_NAI.set_copy_of_buffer(&m_identity);
       
  4514 					if (status != eap_status_ok)
       
  4515 					{
       
  4516 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4517 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  4518 					}
       
  4519 
       
  4520 					m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH;
       
  4521 					set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID);
       
  4522 				}
       
  4523 
       
  4524 				status = new_handler(
       
  4525 					receive_network_id,
       
  4526 					is_client_when_true);
       
  4527 				if (status != eap_status_ok)
       
  4528 				{
       
  4529 					EAP_TRACE_DEBUG(
       
  4530 						m_am_tools, 
       
  4531 						TRACE_FLAGS_GSMSIM_ERROR, 
       
  4532 						(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): new_handler() failed, status %d.\n"),
       
  4533 						status));
       
  4534 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4535 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  4536 				}
       
  4537 				set_state(eap_type_gsmsim_state_waiting_for_start_request);
       
  4538 			}
       
  4539 			else
       
  4540 			{
       
  4541 				EAP_TRACE_DEBUG(
       
  4542 					m_am_tools, 
       
  4543 					TRACE_FLAGS_GSMSIM_ERROR, 
       
  4544 					(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4545 					 EAPL("Only EAP-Request/SIM/Start message in EAP-SIM client ")
       
  4546 					 EAPL("causes creation of new handler. This EAP-packet is dropped.\n")));
       
  4547 
       
  4548 				EAP_TRACE_DATA_DEBUG(
       
  4549 					m_am_tools,
       
  4550 					TRACE_FLAGS_GSMSIM_ERROR,
       
  4551 					(EAPL("ERROR: received:      source"),
       
  4552 					receive_network_id->get_source(),
       
  4553 					receive_network_id->get_source_length()));
       
  4554 				EAP_TRACE_DATA_DEBUG(
       
  4555 					m_am_tools,
       
  4556 					TRACE_FLAGS_GSMSIM_ERROR,
       
  4557 					(EAPL("ERROR: received: destination"),
       
  4558 					receive_network_id->get_destination(),
       
  4559 					receive_network_id->get_destination_length()));
       
  4560 
       
  4561 				if (received_gsmsim->get_type() == eap_type_gsmsim)
       
  4562 				{
       
  4563 					EAP_TRACE_DEBUG(
       
  4564 						m_am_tools, 
       
  4565 						TRACE_FLAGS_GSMSIM_ERROR, 
       
  4566 						(EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ")
       
  4567 						 EAPL("length=0x%04x, type=0x%08x, subtype=0x%02x, client %d\n"),
       
  4568 						received_gsmsim->get_code(),
       
  4569 						received_gsmsim->get_identifier(),
       
  4570 						received_gsmsim->get_length(),
       
  4571 						convert_eap_type_to_u32_t(received_gsmsim->get_type()),
       
  4572 						received_gsmsim->get_subtype(),
       
  4573 						is_client_when_true));
       
  4574 				}
       
  4575 				else
       
  4576 				{
       
  4577 					EAP_TRACE_DEBUG(
       
  4578 						m_am_tools, 
       
  4579 						TRACE_FLAGS_GSMSIM_ERROR, 
       
  4580 						(EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ")
       
  4581 						 EAPL("length=0x%04x, type=0x%08x, client %d\n"),
       
  4582 						received_gsmsim->get_code(),
       
  4583 						received_gsmsim->get_identifier(),
       
  4584 						received_gsmsim->get_length(),
       
  4585 						convert_eap_type_to_u32_t(received_gsmsim->get_type()),
       
  4586 						is_client_when_true));
       
  4587 				}
       
  4588 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  4589 			}
       
  4590 		}
       
  4591 		else
       
  4592 		{
       
  4593 			EAP_TRACE_DEBUG(
       
  4594 				m_am_tools, 
       
  4595 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  4596 				(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4597 				 EAPL("Only EAP-identity message in server causes creation ")
       
  4598 				 EAPL("of new handler. This EAP-packet is dropped.\n")));
       
  4599 
       
  4600 			EAP_TRACE_DATA_DEBUG(
       
  4601 				m_am_tools,
       
  4602 				TRACE_FLAGS_GSMSIM_ERROR,
       
  4603 				(EAPL("ERROR: received:      source"),
       
  4604 				receive_network_id->get_source(),
       
  4605 				receive_network_id->get_source_length()));
       
  4606 			EAP_TRACE_DATA_DEBUG(
       
  4607 				m_am_tools,
       
  4608 				TRACE_FLAGS_GSMSIM_ERROR,
       
  4609 				(EAPL("ERROR: received: destination"),
       
  4610 				receive_network_id->get_destination(),
       
  4611 				receive_network_id->get_destination_length()));
       
  4612 
       
  4613 			if (received_gsmsim->get_type() == eap_type_gsmsim)
       
  4614 			{
       
  4615 				EAP_TRACE_DEBUG(
       
  4616 					m_am_tools, 
       
  4617 					TRACE_FLAGS_GSMSIM_ERROR, 
       
  4618 					(EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ")
       
  4619 					 EAPL("length=0x%04x, type=0x%08x, subtype=0x%02x, client %d\n"),
       
  4620 					received_gsmsim->get_code(),
       
  4621 					received_gsmsim->get_identifier(),
       
  4622 					received_gsmsim->get_length(),
       
  4623 					convert_eap_type_to_u32_t(received_gsmsim->get_type()),
       
  4624 					received_gsmsim->get_subtype(),
       
  4625 					is_client_when_true));
       
  4626 			}
       
  4627 			else
       
  4628 			{
       
  4629 				EAP_TRACE_DEBUG(
       
  4630 					m_am_tools, 
       
  4631 					TRACE_FLAGS_GSMSIM_ERROR, 
       
  4632 					(EAPL("ERROR: erroneous EAP packet: code=0x%02x, identifier=0x%02x, ")
       
  4633 					 EAPL("length=0x%04x, type=0x%08x, client %d\n"),
       
  4634 					received_gsmsim->get_code(),
       
  4635 					received_gsmsim->get_identifier(),
       
  4636 					received_gsmsim->get_length(),
       
  4637 					convert_eap_type_to_u32_t(received_gsmsim->get_type()),
       
  4638 					is_client_when_true));
       
  4639 			}
       
  4640 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  4641 		}
       
  4642 	}
       
  4643 
       
  4644 	EAP_TRACE_DEBUG(
       
  4645 		m_am_tools, 
       
  4646 		TRACE_FLAGS_DEFAULT, 
       
  4647 		(EAPL("eap_type_gsmsim_c::gsmsim_packet_process(): state %d=%s\n"),
       
  4648 		 m_state,
       
  4649 		 get_state_string()));
       
  4650 
       
  4651 	EAP_TRACE_DATA_DEBUG(
       
  4652 		m_am_tools, 
       
  4653 		TRACE_FLAGS_DEFAULT, 
       
  4654 		(EAPL("received: GSMSIM packet"),
       
  4655 		 received_gsmsim->get_header_buffer(
       
  4656 			 received_gsmsim->get_header_length()+received_gsmsim->get_data_length()),
       
  4657 		 received_gsmsim->get_header_length()+received_gsmsim->get_data_length()));
       
  4658 
       
  4659 	if (received_gsmsim->get_type() == eap_type_identity)
       
  4660 	{
       
  4661 		if (is_client_when_true == true)
       
  4662 		{
       
  4663 			EAP_TRACE_DEBUG(
       
  4664 				m_am_tools, 
       
  4665 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  4666 				(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4667 				 EAPL("EAP-Request/Identity is not handled here anymore.\n")));
       
  4668 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4669 			status = eap_status_process_general_error;
       
  4670 		}
       
  4671 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  4672 		else if (is_client_when_true == false)
       
  4673 		{
       
  4674 			eap_header_rd_c eap_header(
       
  4675 				m_am_tools,
       
  4676 				received_gsmsim->get_header_buffer(
       
  4677 					received_gsmsim->get_header_buffer_length()),
       
  4678 				received_gsmsim->get_header_buffer_length());
       
  4679 
       
  4680 			const eap_type_gsmsim_state_variable_e saved_state = m_state;
       
  4681 
       
  4682 			EAP_UNREFERENCED_PARAMETER(saved_state);
       
  4683 
       
  4684 			status = handle_identity_response_message(
       
  4685 				&eap_header,
       
  4686 				gsmsim_packet_length);
       
  4687 
       
  4688 			if (status != eap_status_ok
       
  4689 				&& status != eap_status_success
       
  4690 				&& status != eap_status_drop_packet_quietly)
       
  4691 			{
       
  4692 				eap_status_string_c status_string;
       
  4693 				EAP_UNREFERENCED_PARAMETER(status_string);
       
  4694 				EAP_TRACE_DEBUG(
       
  4695 					m_am_tools, 
       
  4696 					TRACE_FLAGS_GSMSIM_ERROR, 
       
  4697 					(EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4698 					 EAPL("handle_identity_response_message().\n"),
       
  4699 					 status_string.get_status_string(status), status));
       
  4700 			}
       
  4701 
       
  4702 			if (status == eap_status_ok)
       
  4703 			{
       
  4704 				eap_state_notification_c notification(
       
  4705 					m_am_tools,
       
  4706 					&m_send_network_id,
       
  4707 					m_is_client,
       
  4708 					eap_state_notification_eap,
       
  4709 					eap_protocol_layer_eap,
       
  4710 					eap_type_gsmsim,
       
  4711 					eap_state_none,
       
  4712 					eap_state_identity_response_received,
       
  4713 					m_last_eap_identifier,
       
  4714 					false);
       
  4715 				state_notification(&notification);
       
  4716 			}
       
  4717 		}
       
  4718 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  4719 
       
  4720 
       
  4721 		if (status == eap_status_ok
       
  4722 			|| status == eap_status_success)
       
  4723 		{
       
  4724 			// Ok, good EAP message received.
       
  4725 			if (m_is_client == true)
       
  4726 			{
       
  4727 				m_failure_message_received = false;
       
  4728 			}
       
  4729 		}
       
  4730 		else
       
  4731 		{
       
  4732 			EAP_TRACE_ERROR(
       
  4733 				m_am_tools, 
       
  4734 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  4735 				(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4736 				 EAPL("handle_identity_response_message() failed, status %d.\n"),
       
  4737 				 status));
       
  4738 		}
       
  4739 
       
  4740 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4741 	}
       
  4742 
       
  4743 	if (gsmsim_packet_length < received_gsmsim->get_header_length())
       
  4744 	{
       
  4745 		EAP_TRACE_ERROR(
       
  4746 			m_am_tools,
       
  4747 			TRACE_FLAGS_GSMSIM_ERROR,
       
  4748 			(EAPL("ERROR: eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4749 			 EAPL("gsmsim_packet_length < gsmsim_header_c::get_header_length().\n")));
       
  4750 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4751 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  4752 	}
       
  4753 
       
  4754 	status = received_gsmsim->check_header();
       
  4755 	if (status != eap_status_ok)
       
  4756 	{
       
  4757 		eap_status_string_c status_string;
       
  4758 		EAP_TRACE_ERROR(
       
  4759 			m_am_tools,
       
  4760 			TRACE_FLAGS_GSMSIM_ERROR,
       
  4761 			(EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4762 			 EAPL("corrupted GSMSIM-header.\n"),
       
  4763 			status_string.get_status_string(status), status));
       
  4764 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4765 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4766 	}
       
  4767 
       
  4768 	EAP_TRACE_DEBUG(
       
  4769 		m_am_tools, 
       
  4770 		TRACE_FLAGS_DEFAULT, 
       
  4771 		(EAPL("received: GSMSIM-type %10s, %s, state %2d=%s\n"),
       
  4772 		 received_gsmsim->get_subtype_string(),
       
  4773 		 (m_is_client) ? EAPL("client") : EAPL("server"),
       
  4774 		 m_state,
       
  4775 		 get_state_string()
       
  4776 		 ));
       
  4777 
       
  4778 	gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools);
       
  4779 	eap_automatic_variable_c<gsmsim_payloads_c> l_gsmsim_payloads_automatic(
       
  4780 		m_am_tools,
       
  4781 		l_gsmsim_payloads);
       
  4782 
       
  4783 	if (l_gsmsim_payloads == 0
       
  4784 		|| l_gsmsim_payloads->get_is_valid() == false)
       
  4785 	{
       
  4786 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4787 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4788 	}
       
  4789 
       
  4790 	status = handle_gsmsim_packet(
       
  4791 		receive_network_id,
       
  4792 		received_gsmsim,
       
  4793 		gsmsim_packet_length,
       
  4794 		l_gsmsim_payloads);
       
  4795 
       
  4796 	if (status != eap_status_ok
       
  4797 		&& status != eap_status_success
       
  4798 		&& status != eap_status_drop_packet_quietly
       
  4799 		&& status != eap_status_pending_request)
       
  4800 	{
       
  4801 		eap_status_string_c status_string;
       
  4802 		EAP_UNREFERENCED_PARAMETER(status_string);
       
  4803 		EAP_TRACE_DEBUG(
       
  4804 			m_am_tools, 
       
  4805 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4806 			(EAPL("ERROR: %s=%d eap_type_gsmsim_c::gsmsim_packet_process(): ")
       
  4807 			 EAPL("handle_gsmsim_packet().\n"),
       
  4808 			status_string.get_status_string(status), status));
       
  4809 	}
       
  4810 
       
  4811 	if (status == eap_status_ok
       
  4812 		|| status == eap_status_success
       
  4813 		|| status == eap_status_pending_request)
       
  4814 	{
       
  4815 		// Ok, good EAP message received.
       
  4816 		if (m_is_client == true)
       
  4817 		{
       
  4818 			m_failure_message_received = false;
       
  4819 		}
       
  4820 	}
       
  4821 
       
  4822 	if (status == eap_status_ok)
       
  4823 	{
       
  4824 		// Do nothing special.
       
  4825 	}
       
  4826 	else if (status == eap_status_drop_packet_quietly)
       
  4827 	{
       
  4828 		// We will drop this message quietly.
       
  4829 	}
       
  4830 	else if (status != eap_status_ok)
       
  4831 	{
       
  4832 		// EAP-Failure will be sent from shutdown().
       
  4833 	}
       
  4834 
       
  4835 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4836 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4837 }
       
  4838 
       
  4839 //--------------------------------------------------
       
  4840 
       
  4841 //
       
  4842 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_error_message_delay_timer()
       
  4843 {
       
  4844 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4845 
       
  4846 	eap_status_e status = cancel_timer(
       
  4847 		this,
       
  4848 		EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID);
       
  4849 
       
  4850 	m_erroneus_packet_received = false;
       
  4851 
       
  4852 	EAP_TRACE_DEBUG(
       
  4853 		m_am_tools, 
       
  4854 		TRACE_FLAGS_DEFAULT, 
       
  4855 		(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID cancelled.\n"),
       
  4856 		 (m_is_client == true) ? "client": "server"));
       
  4857 
       
  4858 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4859 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4860 }
       
  4861 
       
  4862 //--------------------------------------------------
       
  4863 
       
  4864 //
       
  4865 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_error_message_delay_timer()
       
  4866 {
       
  4867 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4868 
       
  4869 	eap_status_e status = set_timer(
       
  4870 		this,
       
  4871 		EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID,
       
  4872 		0,
       
  4873 		m_failure_message_delay_time);
       
  4874 
       
  4875 	EAP_TRACE_DEBUG(
       
  4876 		m_am_tools, 
       
  4877 		TRACE_FLAGS_DEFAULT, 
       
  4878 		(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID set.\n"),
       
  4879 		 (m_is_client == true) ? "client": "server"));
       
  4880 
       
  4881 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4882 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4883 }
       
  4884 
       
  4885 //--------------------------------------------------
       
  4886 
       
  4887 //
       
  4888 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_notification_message_delay_timer()
       
  4889 {
       
  4890 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4891 
       
  4892 	eap_status_e status = cancel_timer(
       
  4893 		this,
       
  4894 		EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID);
       
  4895 
       
  4896 	m_erroneus_packet_received = false;
       
  4897 
       
  4898 	EAP_TRACE_DEBUG(
       
  4899 		m_am_tools, 
       
  4900 		TRACE_FLAGS_DEFAULT, 
       
  4901 		(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID cancelled.\n"),
       
  4902 		 (m_is_client == true) ? "client": "server"));
       
  4903 
       
  4904 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4905 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4906 }
       
  4907 
       
  4908 //--------------------------------------------------
       
  4909 
       
  4910 //
       
  4911 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_notification_message_delay_timer()
       
  4912 {
       
  4913 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4914 
       
  4915 	eap_status_e status = set_timer(
       
  4916 		this,
       
  4917 		EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID,
       
  4918 		0,
       
  4919 		m_failure_message_delay_time);
       
  4920 
       
  4921 	EAP_TRACE_DEBUG(
       
  4922 		m_am_tools, 
       
  4923 		TRACE_FLAGS_DEFAULT, 
       
  4924 		(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID set.\n"),
       
  4925 		 (m_is_client == true) ? "client": "server"));
       
  4926 
       
  4927 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4928 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4929 }
       
  4930 
       
  4931 //--------------------------------------------------
       
  4932 
       
  4933 //
       
  4934 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_error_packet()
       
  4935 {
       
  4936 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4937 
       
  4938 	eap_status_e status = eap_status_process_general_error;
       
  4939 
       
  4940 	EAP_TRACE_DEBUG(
       
  4941 		m_am_tools, 
       
  4942 		TRACE_FLAGS_GSMSIM_ERROR, 
       
  4943 		(EAPL("ERROR: eap_type_gsmsim_c::handle_error_packet(): ")
       
  4944 		 EAPL("erroneus_packet_received %d, m_client_error_code %d\n"),
       
  4945 		 m_erroneus_packet_received,
       
  4946 		 m_client_error_code));
       
  4947 
       
  4948 	if (m_state == eap_type_gsmsim_state_none)
       
  4949 	{
       
  4950 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4951 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  4952 	}
       
  4953 
       
  4954 	if (m_erroneus_packet_received == true)
       
  4955 	{
       
  4956 		set_state(eap_type_gsmsim_state_failure);
       
  4957 
       
  4958 		if (m_is_client == true)
       
  4959 		{
       
  4960 			// Client will send EAP-Response/SIM/Client-Error.
       
  4961 			status = send_gsmsim_client_error_response();
       
  4962 		}
       
  4963 		else
       
  4964 		{
       
  4965 			// Server will send EAP-Failure.
       
  4966 			// Notifies the lower level of unsuccessfull authentication.
       
  4967 			eap_state_notification_c notification(
       
  4968 				m_am_tools,
       
  4969 				&m_send_network_id,
       
  4970 				m_is_client,
       
  4971 				eap_state_notification_eap,
       
  4972 				eap_protocol_layer_eap,
       
  4973 				eap_type_gsmsim,
       
  4974 				eap_state_none,
       
  4975 				eap_state_authentication_terminated_unsuccessfully,
       
  4976 				m_last_eap_identifier,
       
  4977 				false);
       
  4978 
       
  4979 			notification.set_authentication_error(eap_status_authentication_failure);
       
  4980 
       
  4981 			state_notification(&notification);
       
  4982 
       
  4983 			status = eap_status_ok;
       
  4984 		}
       
  4985 	}
       
  4986 	else
       
  4987 	{
       
  4988 		// One erroneous packet is already received.
       
  4989 		EAP_TRACE_DEBUG(
       
  4990 			m_am_tools, 
       
  4991 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  4992 			(EAPL("WARNING: eap_type_gsmsim_c::handle_error_packet(): one erroneus packet already received. This is ignored.\n")));
       
  4993 		status = eap_status_ok;
       
  4994 	}
       
  4995 
       
  4996 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4997 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4998 }
       
  4999 
       
  5000 //--------------------------------------------------
       
  5001 
       
  5002 //
       
  5003 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::initialize_error_message(
       
  5004 	const eap_status_e error_status)
       
  5005 {
       
  5006 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5007 
       
  5008 	eap_status_e status = eap_status_process_general_error;
       
  5009 
       
  5010 	eap_status_string_c status_string;
       
  5011 	EAP_UNREFERENCED_PARAMETER(status_string);
       
  5012 
       
  5013 	EAP_TRACE_DEBUG(
       
  5014 		m_am_tools, 
       
  5015 		TRACE_FLAGS_GSMSIM_ERROR, 
       
  5016 		(EAPL("ERROR: eap_type_gsmsim_c::initialize_error_message(): erroneus_packet_received %d, error_status %s\n"),
       
  5017 		 m_erroneus_packet_received,
       
  5018 		 status_string.get_status_string(error_status)));
       
  5019 
       
  5020 	if (m_erroneus_packet_received == false)
       
  5021 	{
       
  5022 		// Only the first erroneus packet is recorded.
       
  5023 		m_erroneus_packet_received = true;
       
  5024 
       
  5025 		if (m_is_client == true)
       
  5026 		{
       
  5027 			// Client will send EAP-Response/SIM/Client-Error.
       
  5028 			switch(error_status)
       
  5029 			{
       
  5030 			case eap_status_no_matching_protocol_version:
       
  5031 				m_client_error_code = eap_gsmsim_client_error_code_unsupported_version;
       
  5032 				break;
       
  5033 			case eap_status_not_enough_challenges:
       
  5034 				m_client_error_code = eap_gsmsim_client_error_code_insufficient_number_of_challenges;
       
  5035 				break;
       
  5036 			case eap_status_not_fresh_challenges:
       
  5037 				m_client_error_code = eap_gsmsim_client_error_code_rands_are_not_fresh;
       
  5038 				break;
       
  5039 			default:
       
  5040 				m_client_error_code = eap_gsmsim_client_error_code_unable_to_process_packet;
       
  5041 				break;
       
  5042 			};
       
  5043 		}
       
  5044 		else
       
  5045 		{
       
  5046 			// Server will send EAP-Failure.
       
  5047 		}
       
  5048 
       
  5049 		if (m_failure_message_delay_time > 0ul)
       
  5050 		{
       
  5051 			// First try set delay timer.
       
  5052 			status = set_error_message_delay_timer();
       
  5053 			if (status != eap_status_ok)
       
  5054 			{
       
  5055 				// ERROR: Process error packet immediately.
       
  5056 				status = handle_error_packet();
       
  5057 			}
       
  5058 		}
       
  5059 		else
       
  5060 		{
       
  5061 			// Process error packet immediately.
       
  5062 			status = handle_error_packet();
       
  5063 		}
       
  5064 	}
       
  5065 	else
       
  5066 	{
       
  5067 		// Error packet is already processed.
       
  5068 		status = eap_status_ok;
       
  5069 	}
       
  5070 
       
  5071 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5072 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5073 }
       
  5074 
       
  5075 //--------------------------------------------------
       
  5076 
       
  5077 //
       
  5078 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_notification_packet()
       
  5079 {
       
  5080 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5081 
       
  5082 	eap_status_e status = eap_status_process_general_error;
       
  5083 
       
  5084 	EAP_TRACE_DEBUG(
       
  5085 		m_am_tools, 
       
  5086 		TRACE_FLAGS_GSMSIM_ERROR, 
       
  5087 		(EAPL("eap_type_gsmsim_c::handle_notification_packet(): sim_notification_packet_received %d\n"),
       
  5088 		 m_sim_notification_packet_received));
       
  5089 
       
  5090 	if (m_state == eap_type_gsmsim_state_none)
       
  5091 	{
       
  5092 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5093 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5094 	}
       
  5095 
       
  5096 	if (m_sim_notification_packet_received == true)
       
  5097 	{
       
  5098 		bool add_at_counter_attribute = false;
       
  5099 		if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION)
       
  5100 		{
       
  5101 			add_at_counter_attribute = true;
       
  5102 		}
       
  5103 
       
  5104 		if (m_is_client == true)
       
  5105 		{
       
  5106 			// Client will send EAP-Response/SIM/Notification.
       
  5107 			if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false)
       
  5108 			{
       
  5109 				// The code values with the F bit set to zero (code values 0...32767)
       
  5110 				// are used on unsuccessful cases.
       
  5111 				// The receipt of a notification code from this range implies failed EAP
       
  5112 				// exchange, so the peer can use the notification as a failure indication.
       
  5113 				set_state(eap_type_gsmsim_state_failure);
       
  5114 			}
       
  5115 
       
  5116 			status = send_gsmsim_notification_response(
       
  5117 				m_gsmsim_notification_code,
       
  5118 				add_at_counter_attribute);
       
  5119 		}
       
  5120 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  5121 		else
       
  5122 		{
       
  5123 			set_state(eap_type_gsmsim_state_waiting_for_notification_response_failure);
       
  5124 
       
  5125 			// Server will send EAP-Request/SIM/Notification.
       
  5126 			status = send_gsmsim_notification_request(
       
  5127 				m_gsmsim_notification_code,
       
  5128 				add_at_counter_attribute);
       
  5129 		}
       
  5130 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  5131 	}
       
  5132 	else
       
  5133 	{
       
  5134 		EAP_TRACE_DEBUG(
       
  5135 			m_am_tools, 
       
  5136 			TRACE_FLAGS_GSMSIM_ERROR, 
       
  5137 			(EAPL("eap_type_gsmsim_c::handle_notification_packet(): one SIM/Notification packet already received. This is ignored.\n")));
       
  5138 
       
  5139 		status = eap_status_ok;
       
  5140 	}
       
  5141 
       
  5142 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5143 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5144 }
       
  5145 
       
  5146 //--------------------------------------------------
       
  5147 
       
  5148 //
       
  5149 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::initialize_notification_message()
       
  5150 {
       
  5151 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5152 
       
  5153 	eap_status_e status = eap_status_process_general_error;
       
  5154 
       
  5155 	if (m_state == eap_type_gsmsim_state_none)
       
  5156 	{
       
  5157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5158 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5159 	}
       
  5160 
       
  5161 	if (m_sim_notification_packet_received == false)
       
  5162 	{
       
  5163 		// Only the first SIM notification packet is recorded.
       
  5164 		m_sim_notification_packet_received = true;
       
  5165 
       
  5166 		if (m_is_client == true)
       
  5167 		{
       
  5168 			// Client will send empty EAP-Response/SIM/Notification.
       
  5169 		}
       
  5170 		else
       
  5171 		{
       
  5172 			// Server will send EAP-Request/SIM/Notification.
       
  5173 			if (m_gsmsim_notification_code == eap_gsmsim_notification_none)
       
  5174 			{
       
  5175 				m_gsmsim_notification_code = eap_gsmsim_notification_no_F_P_set_general_failure;
       
  5176 			}
       
  5177 
       
  5178 			EAP_TRACE_DEBUG(
       
  5179 				m_am_tools, 
       
  5180 				TRACE_FLAGS_DEFAULT, 
       
  5181 				(EAPL("eap_type_gsmsim_c::initialize_notification_message(0x%08x), notification_code = 0x%04x, F bit %d, P bit %d.\n"),
       
  5182 				 this,
       
  5183 				 m_gsmsim_notification_code,
       
  5184 				 get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code),
       
  5185 				 get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code)));
       
  5186 		}
       
  5187 
       
  5188 		if (m_failure_message_delay_time > 0ul)
       
  5189 		{
       
  5190 			// First try set delay timer.
       
  5191 			status = set_notification_message_delay_timer();
       
  5192 			if (status != eap_status_ok)
       
  5193 			{
       
  5194 				// ERROR: Process SIM notification packet immediately.
       
  5195 				status = handle_notification_packet();
       
  5196 			}
       
  5197 		}
       
  5198 		else
       
  5199 		{
       
  5200 			// Process SIM notification packet immediately.
       
  5201 			status = handle_notification_packet();
       
  5202 		}
       
  5203 	}
       
  5204 	else
       
  5205 	{
       
  5206 		// SIM notification packet is already processed.
       
  5207 		status = eap_status_ok;
       
  5208 	}
       
  5209 
       
  5210 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5211 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5212 }
       
  5213 
       
  5214 //--------------------------------------------------
       
  5215 
       
  5216 //
       
  5217 EAP_FUNC_EXPORT u32_t eap_type_gsmsim_c::get_header_offset(
       
  5218 	u32_t * const MTU,
       
  5219 	u32_t * const trailer_length)
       
  5220 {
       
  5221 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5222 
       
  5223 	u32_t offset = get_type_partner()->get_header_offset(MTU, trailer_length);
       
  5224 
       
  5225 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5226 	return offset;
       
  5227 }
       
  5228 
       
  5229 //--------------------------------------------------
       
  5230 
       
  5231 //
       
  5232 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::extra_message_authentication_code_bytes(
       
  5233 	const gsmsim_subtype_e subtype,
       
  5234 	const eap_code_value_e code,
       
  5235 	crypto_hmac_c *hmac_sha1)
       
  5236 {
       
  5237 	eap_status_e status(eap_status_ok);
       
  5238 
       
  5239 	if (code == eap_code_request)
       
  5240 	{
       
  5241 		if (subtype == gsmsim_subtype_Challenge)
       
  5242 		{
       
  5243 			status = hmac_sha1->hmac_update(
       
  5244 				m_nonce_mt.get_data(),
       
  5245 				m_nonce_mt.get_data_length());
       
  5246 			if (status != eap_status_ok)
       
  5247 			{
       
  5248 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5249 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5250 			}
       
  5251 		}
       
  5252 	}
       
  5253 	else if (code == eap_code_response)
       
  5254 	{
       
  5255 		if (subtype == gsmsim_subtype_Challenge)
       
  5256 		{
       
  5257 			status = hmac_sha1->hmac_update(
       
  5258 				m_n_sres.get_data(),
       
  5259 				m_n_sres.get_data_length());
       
  5260 			if (status != eap_status_ok)
       
  5261 			{
       
  5262 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5263 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5264 			}
       
  5265 		}
       
  5266 		else if (subtype == gsmsim_subtype_Re_authentication)
       
  5267 		{
       
  5268 			status = hmac_sha1->hmac_update(
       
  5269 				m_nonce_s.get_data(),
       
  5270 				m_nonce_s.get_data_length());
       
  5271 			if (status != eap_status_ok)
       
  5272 			{
       
  5273 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5274 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5275 			}
       
  5276 		}
       
  5277 	}
       
  5278 	else
       
  5279 	{
       
  5280 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"),
       
  5281 			code));
       
  5282 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5283 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5284 	}
       
  5285 
       
  5286 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5287 }
       
  5288 
       
  5289 //--------------------------------------------------
       
  5290 
       
  5291 //
       
  5292 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::create_message_authentication_code(
       
  5293 	eap_type_gsmsim_MAC_attributes_c *MAC_attributes,
       
  5294 	const gsmsim_subtype_e subtype,
       
  5295 	const eap_code_value_e code,
       
  5296 	const eap_variable_data_c * const authentication_key
       
  5297 )
       
  5298 {
       
  5299 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5300 
       
  5301 	if (MAC_attributes == 0
       
  5302 		|| authentication_key == 0
       
  5303 		|| authentication_key->get_is_valid_data() == false
       
  5304 		//|| MAC_attributes->get_handler() == 0
       
  5305 		|| MAC_attributes->get_data() == 0
       
  5306 		|| MAC_attributes->get_data_length() == 0u
       
  5307 		|| MAC_attributes->get_MAC() == 0)
       
  5308 	{
       
  5309 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5310 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5311 	}
       
  5312 
       
  5313 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("authentication_key"),
       
  5314 		authentication_key->get_data(),
       
  5315 		authentication_key->get_data_length()));
       
  5316 
       
  5317 	eap_status_e status = eap_status_process_general_error;
       
  5318 
       
  5319 #if defined(USE_EAP_TRACE)
       
  5320 	{
       
  5321 		eap_variable_data_c buffer(m_am_tools);
       
  5322 
       
  5323 		status = buffer.set_buffer_length(2048);
       
  5324 		if (status != eap_status_ok)
       
  5325 		{
       
  5326 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5327 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5328 		}
       
  5329 
       
  5330 		status = buffer.set_buffer_length(buffer.get_buffer_length());
       
  5331 		if (status != eap_status_ok)
       
  5332 		{
       
  5333 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5334 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5335 		}
       
  5336 
       
  5337 		u8_t * const tmpbuffer = buffer.get_data();
       
  5338 		if (tmpbuffer == 0)
       
  5339 		{
       
  5340 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5341 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5342 		}
       
  5343 
       
  5344 		u32_t offset = 0;
       
  5345 
       
  5346 		m_am_tools->memmove(tmpbuffer+offset,
       
  5347 			(MAC_attributes->get_data()),
       
  5348 			MAC_attributes->get_data_length());
       
  5349 		offset += MAC_attributes->get_data_length();
       
  5350 
       
  5351 		if (code == eap_code_request)
       
  5352 		{
       
  5353 			if (subtype == gsmsim_subtype_Challenge)
       
  5354 			{
       
  5355 				m_am_tools->memmove(tmpbuffer+offset,
       
  5356 					m_nonce_mt.get_data(),
       
  5357 					m_nonce_mt.get_data_length());
       
  5358 				offset += m_nonce_mt.get_data_length();
       
  5359 			}
       
  5360 		}
       
  5361 		else if (code == eap_code_response)
       
  5362 		{
       
  5363 			if (subtype == gsmsim_subtype_Challenge)
       
  5364 			{
       
  5365 				m_am_tools->memmove(tmpbuffer+offset,
       
  5366 					m_n_sres.get_data(),
       
  5367 					m_n_sres.get_data_length());
       
  5368 				offset += m_n_sres.get_data_length();
       
  5369 			}
       
  5370 			else if (subtype == gsmsim_subtype_Re_authentication)
       
  5371 			{
       
  5372 				m_am_tools->memmove(tmpbuffer+offset,
       
  5373 					m_nonce_s.get_data(),
       
  5374 					m_nonce_s.get_data_length());
       
  5375 				offset += m_nonce_s.get_data_length();
       
  5376 			}
       
  5377 		}
       
  5378 		else
       
  5379 		{
       
  5380 			EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"),
       
  5381 				code));
       
  5382 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5383 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5384 		}
       
  5385 
       
  5386 		EAP_TRACE_DEBUG(
       
  5387 			m_am_tools, 
       
  5388 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  5389 			(EAPL("create_message_authentication_code(): MAC calculated over the following bytes:\n")));
       
  5390 		EAP_TRACE_DATA_DEBUG(
       
  5391 			m_am_tools, 
       
  5392 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  5393 			(EAPL("MAC data"),
       
  5394 			 tmpbuffer,
       
  5395 			 offset));
       
  5396 	}
       
  5397 #endif // #if defined(USE_EAP_TRACE)
       
  5398 
       
  5399 
       
  5400 	crypto_sha1_c sha1(m_am_tools);
       
  5401 	crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
  5402 
       
  5403 	if (hmac_sha1.get_is_valid() == false)
       
  5404 	{
       
  5405 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5406 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5407 	}
       
  5408 
       
  5409 	if (hmac_sha1.hmac_set_key(
       
  5410 		authentication_key
       
  5411 		) != eap_status_ok)
       
  5412 	{
       
  5413 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_GSMSIM_ERROR, (EAPL("ERROR: create_message_authentication_code(): set_key() failed.\n")));
       
  5414 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5415 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5416 	}
       
  5417 
       
  5418 	status = hmac_sha1.hmac_update(
       
  5419 		MAC_attributes->get_data(),
       
  5420 		MAC_attributes->get_data_length());
       
  5421 	if (status != eap_status_ok)
       
  5422 	{
       
  5423 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5424 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5425 	}
       
  5426 
       
  5427 	status = extra_message_authentication_code_bytes(subtype, code, &hmac_sha1);
       
  5428 	if (status != eap_status_ok)
       
  5429 	{
       
  5430 		eap_status_string_c status_string;
       
  5431 		EAP_TRACE_ERROR(
       
  5432 			m_am_tools,
       
  5433 			TRACE_FLAGS_GSMSIM_ERROR,
       
  5434 			(EAPL("ERROR: %s=%d create_message_authentication_code(): extra_message_authentication_code_bytes().\n"),
       
  5435 			status_string.get_status_string(status), status));
       
  5436 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5437 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5438 	}
       
  5439 
       
  5440 	u32_t length = 0u;
       
  5441 
       
  5442 	status = hmac_sha1.hmac_128_final(
       
  5443 		MAC_attributes->get_MAC(),
       
  5444 		&length);
       
  5445 	if (status != eap_status_ok)
       
  5446 	{
       
  5447 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5448 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5449 	}
       
  5450 
       
  5451 	EAP_ASSERT(length == EAP_TYPE_GSMSIM_MAC_SIZE);
       
  5452 
       
  5453 	EAP_TRACE_DEBUG(
       
  5454 		m_am_tools, 
       
  5455 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  5456 		(EAPL("MAC:\n")));
       
  5457 	EAP_TRACE_DATA_DEBUG(
       
  5458 		m_am_tools, 
       
  5459 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  5460 		(EAPL("MAC"),
       
  5461 		 MAC_attributes->get_MAC(),
       
  5462 		 length));
       
  5463 
       
  5464 
       
  5465 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5466 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5467 }
       
  5468 
       
  5469 //--------------------------------------------------
       
  5470 
       
  5471 //
       
  5472 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_message_authentication_code(
       
  5473 	const eap_variable_data_c * const authentication_key,
       
  5474 	gsmsim_payloads_c * const p_gsmsim_payloads,
       
  5475 	const gsmsim_header_c * const gsmsim_packet,
       
  5476 	const u32_t gsmsim_packet_length)
       
  5477 {
       
  5478 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5479 
       
  5480 	if (authentication_key == 0
       
  5481 		|| authentication_key->get_is_valid_data() == false)
       
  5482 	{
       
  5483 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5484 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5485 	}
       
  5486 	if (p_gsmsim_payloads->get_MAC() == 0
       
  5487 		|| p_gsmsim_payloads->get_MAC()->get_payload_included() == false)
       
  5488 	{
       
  5489 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5490 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5491 	}
       
  5492 	if (gsmsim_packet == 0
       
  5493 		|| gsmsim_packet_length == 0)
       
  5494 	{
       
  5495 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5496 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5497 	}
       
  5498 
       
  5499 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("authentication_key"),
       
  5500 		authentication_key->get_data(),
       
  5501 		authentication_key->get_data_length()));
       
  5502 
       
  5503 	crypto_sha1_c sha1(m_am_tools);
       
  5504 	crypto_hmac_c hmac_sha1(m_am_tools, &sha1, false);
       
  5505 
       
  5506 	if (hmac_sha1.get_is_valid() == false)
       
  5507 	{
       
  5508 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5509 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5510 	}
       
  5511 
       
  5512 	if (hmac_sha1.hmac_set_key(
       
  5513 		authentication_key
       
  5514 		) != eap_status_ok)
       
  5515 	{
       
  5516 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5517 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5518 	}
       
  5519 
       
  5520 	u8_t saved_MAC[EAP_TYPE_GSMSIM_MAC_SIZE];
       
  5521 
       
  5522 	m_am_tools->memmove(
       
  5523 		saved_MAC,
       
  5524 		p_gsmsim_payloads->get_MAC()->get_data(p_gsmsim_payloads->get_MAC()->get_data_length()),
       
  5525 		p_gsmsim_payloads->get_MAC()->get_data_length());
       
  5526 
       
  5527 	m_am_tools->memset(
       
  5528 		p_gsmsim_payloads->get_MAC()->get_data(p_gsmsim_payloads->get_MAC()->get_data_length()),
       
  5529 		0,
       
  5530 		p_gsmsim_payloads->get_MAC()->get_data_length());
       
  5531 
       
  5532 
       
  5533 	eap_status_e status = hmac_sha1.hmac_update(
       
  5534 		gsmsim_packet->get_header_buffer(gsmsim_packet_length),
       
  5535 		gsmsim_packet_length);
       
  5536 	if (status != eap_status_ok)
       
  5537 	{
       
  5538 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5539 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5540 	}
       
  5541 
       
  5542 	status = extra_message_authentication_code_bytes(
       
  5543 		gsmsim_packet->get_subtype(),
       
  5544 		gsmsim_packet->get_code(),
       
  5545 		&hmac_sha1);
       
  5546 	if (status != eap_status_ok)
       
  5547 	{
       
  5548 		eap_status_string_c status_string;
       
  5549 		EAP_TRACE_ERROR(
       
  5550 			m_am_tools,
       
  5551 			TRACE_FLAGS_GSMSIM_ERROR,
       
  5552 			(EAPL("ERROR: %s=%d check_message_authentication_code(): extra_message_authentication_code_bytes().\n"),
       
  5553 			status_string.get_status_string(status), status));
       
  5554 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5555 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5556 	}
       
  5557 
       
  5558 
       
  5559 	eap_variable_data_c *end_of_authentication = 0;
       
  5560 	if (p_gsmsim_payloads->get_MAC()->get_payload_included() == true)
       
  5561 	{
       
  5562 		end_of_authentication = p_gsmsim_payloads->get_MAC()->get_payload_buffer();
       
  5563 	}
       
  5564 	else
       
  5565 	{
       
  5566 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5567 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  5568 	}
       
  5569 
       
  5570 
       
  5571 	u32_t length = 0u;
       
  5572 
       
  5573 	eap_variable_data_c tmp_MAC(m_am_tools);
       
  5574 	status = tmp_MAC.init(EAP_TYPE_GSMSIM_MAC_SIZE);
       
  5575 	if (status != eap_status_ok)
       
  5576 	{
       
  5577 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5578 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5579 	}
       
  5580 	tmp_MAC.set_is_valid();
       
  5581 	tmp_MAC.set_data_length(EAP_TYPE_GSMSIM_MAC_SIZE);
       
  5582 
       
  5583 	u8_t * const mac_data = tmp_MAC.get_data_offset(0u, EAP_TYPE_GSMSIM_MAC_SIZE);
       
  5584 	if (mac_data == 0)
       
  5585 	{
       
  5586 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5587 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5588 	}
       
  5589 
       
  5590 	status = hmac_sha1.hmac_128_final(
       
  5591 		mac_data,
       
  5592 		&length);
       
  5593 	if (status != eap_status_ok)
       
  5594 	{
       
  5595 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5596 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5597 	}
       
  5598 
       
  5599 	EAP_ASSERT(length == EAP_TYPE_GSMSIM_MAC_SIZE);
       
  5600 
       
  5601 
       
  5602 
       
  5603 #if defined(USE_EAP_TRACE)
       
  5604 	{
       
  5605 		eap_variable_data_c buffer(m_am_tools);
       
  5606 
       
  5607 		status = buffer.set_buffer_length(2048);
       
  5608 		if (status != eap_status_ok)
       
  5609 		{
       
  5610 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5611 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5612 		}
       
  5613 
       
  5614 		status = buffer.set_buffer_length(buffer.get_buffer_length());
       
  5615 		if (status != eap_status_ok)
       
  5616 		{
       
  5617 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5618 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5619 		}
       
  5620 
       
  5621 		u8_t * const tmpbuffer = buffer.get_data();
       
  5622 		if (tmpbuffer == 0)
       
  5623 		{
       
  5624 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5625 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5626 		}
       
  5627 
       
  5628 		u32_t offset = 0;
       
  5629 
       
  5630 		m_am_tools->memmove(tmpbuffer+offset,
       
  5631 			gsmsim_packet->get_header_buffer(gsmsim_packet_length),
       
  5632 			gsmsim_packet_length);
       
  5633 		offset += gsmsim_packet_length;
       
  5634 
       
  5635 		if (gsmsim_packet->get_code() == eap_code_request)
       
  5636 		{
       
  5637 			if (gsmsim_packet->get_subtype() == gsmsim_subtype_Challenge)
       
  5638 			{
       
  5639 				m_am_tools->memmove(tmpbuffer+offset,
       
  5640 					m_nonce_mt.get_data(),
       
  5641 					m_nonce_mt.get_data_length());
       
  5642 				offset += m_nonce_mt.get_data_length();
       
  5643 			}
       
  5644 		}
       
  5645 		else if (gsmsim_packet->get_code() == eap_code_response)
       
  5646 		{
       
  5647 			if (gsmsim_packet->get_subtype() == gsmsim_subtype_Challenge)
       
  5648 			{
       
  5649 				m_am_tools->memmove(tmpbuffer+offset,
       
  5650 					m_n_sres.get_data(),
       
  5651 					m_n_sres.get_data_length());
       
  5652 				offset += m_n_sres.get_data_length();
       
  5653 			}
       
  5654 			else if (gsmsim_packet->get_subtype() == gsmsim_subtype_Re_authentication)
       
  5655 			{
       
  5656 				m_am_tools->memmove(tmpbuffer+offset,
       
  5657 					m_nonce_s.get_data(),
       
  5658 					m_nonce_s.get_data_length());
       
  5659 				offset += m_nonce_s.get_data_length();
       
  5660 			}
       
  5661 		}
       
  5662 		else
       
  5663 		{
       
  5664 			EAP_TRACE_ERROR(
       
  5665 				m_am_tools,
       
  5666 				TRACE_FLAGS_GSMSIM_ERROR,
       
  5667 				(EAPL("ERROR: extra_message_authentication_code_bytes(): unsupported EAP-Code %d.\n"),
       
  5668 				gsmsim_packet->get_code()));
       
  5669 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5670 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5671 		}
       
  5672 
       
  5673 		EAP_TRACE_DEBUG(
       
  5674 			m_am_tools, 
       
  5675 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  5676 			(EAPL("check_message_authentication_code(): MAC calculated over the following bytes:\n")));
       
  5677 		EAP_TRACE_DATA_DEBUG(
       
  5678 			m_am_tools, 
       
  5679 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, 
       
  5680 			(EAPL("MAC data"),
       
  5681 			 tmpbuffer,
       
  5682 			 offset));
       
  5683 
       
  5684 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC:\n")));
       
  5685 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC"),
       
  5686 			tmp_MAC.get_data(),
       
  5687 			tmp_MAC.get_data_length()));
       
  5688 	}
       
  5689 #endif // #if defined(USE_EAP_TRACE)
       
  5690 
       
  5691 
       
  5692 	if (length != end_of_authentication->get_data_length()
       
  5693 		|| tmp_MAC.get_data_length()
       
  5694 			!= end_of_authentication->get_data_length())
       
  5695 	{
       
  5696 		EAP_TRACE_ERROR(
       
  5697 			m_am_tools, 
       
  5698 			TRACE_FLAGS_EAP_AM_CRYPTO|TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, 
       
  5699 			(EAPL("ERROR: MAC differs.\n")));
       
  5700 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5701 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  5702 	}
       
  5703 
       
  5704 	if (m_am_tools->memcmp(
       
  5705 			tmp_MAC.get_data(),
       
  5706 			saved_MAC,
       
  5707 			tmp_MAC.get_data_length()) != 0)
       
  5708 	{
       
  5709 		EAP_TRACE_ERROR(
       
  5710 			m_am_tools, 
       
  5711 			TRACE_FLAGS_EAP_AM_CRYPTO|TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, 
       
  5712 			(EAPL("ERROR: MAC differs.\n")));
       
  5713 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5714 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  5715 	}
       
  5716 
       
  5717 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("MAC OK.\n")));
       
  5718 
       
  5719 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5720 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5721 }
       
  5722 
       
  5723 //--------------------------------------------------
       
  5724 
       
  5725 //
       
  5726 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::timer_expired(
       
  5727 	const u32_t id, void *data)
       
  5728 {
       
  5729 	EAP_UNREFERENCED_PARAMETER(id);
       
  5730 	EAP_UNREFERENCED_PARAMETER(data);
       
  5731 
       
  5732 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5733 
       
  5734 	EAP_TRACE_DEBUG(
       
  5735 		m_am_tools, 
       
  5736 		TRACE_FLAGS_DEFAULT, 
       
  5737 		(EAPL("TIMER: [0x%08x]->eap_type_gsmsim_c::timer_expired(id 0x%02x, data 0x%08x).\n"),
       
  5738 		this, id, data));
       
  5739 
       
  5740 	eap_status_e status = eap_status_process_general_error;
       
  5741 
       
  5742 	if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID)
       
  5743 	{
       
  5744 		EAP_TRACE_DEBUG(
       
  5745 			m_am_tools, 
       
  5746 			TRACE_FLAGS_DEFAULT, 
       
  5747 			(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID elapsed.\n"),
       
  5748 			 (m_is_client == true) ? "client": "server"));
       
  5749 
       
  5750 		if (m_state == eap_type_gsmsim_state_failure)
       
  5751 		{
       
  5752 			// Athentication is already failed.
       
  5753 
       
  5754 			// We set the session timeout to zero.
       
  5755 			// This will terminate this session immediately.
       
  5756 			status = get_type_partner()->set_session_timeout(0ul);
       
  5757 		}
       
  5758 		else
       
  5759 		{
       
  5760 			status = handle_error_packet();
       
  5761 		}
       
  5762 	}
       
  5763 	else if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID)
       
  5764 	{
       
  5765 		EAP_TRACE_DEBUG(
       
  5766 			m_am_tools, 
       
  5767 			TRACE_FLAGS_DEFAULT, 
       
  5768 			(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID elapsed.\n"),
       
  5769 			 (m_is_client == true) ? "client": "server"));
       
  5770 
       
  5771 		status = handle_notification_packet();
       
  5772 	}
       
  5773 
       
  5774 
       
  5775 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5776 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5777 }
       
  5778 
       
  5779 //--------------------------------------------------
       
  5780 
       
  5781 //
       
  5782 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::timer_delete_data(
       
  5783 	const u32_t id, void *data)
       
  5784 {
       
  5785 	EAP_UNREFERENCED_PARAMETER(id);
       
  5786 	EAP_UNREFERENCED_PARAMETER(data);
       
  5787 
       
  5788 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5789 
       
  5790 	EAP_TRACE_DEBUG(
       
  5791 		m_am_tools, 
       
  5792 		TRACE_FLAGS_DEFAULT, 
       
  5793 		(EAPL("TIMER: [0x%08x]->eap_type_gsmsim_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"),
       
  5794 		this, id, data));
       
  5795 
       
  5796 	if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID)
       
  5797 	{
       
  5798 		EAP_TRACE_DEBUG(
       
  5799 			m_am_tools, 
       
  5800 			TRACE_FLAGS_DEFAULT, 
       
  5801 			(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_FAILURE_MESSAGE_SENT_ID delete data.\n"),
       
  5802 			 (m_is_client == true) ? "client": "server"));
       
  5803 	}
       
  5804 	else if (id == EAP_TYPE_GSMSIM_TIMER_DELAY_NOTIFICATION_MESSAGE_ID)
       
  5805 	{
       
  5806 		EAP_TRACE_DEBUG(
       
  5807 			m_am_tools, 
       
  5808 			TRACE_FLAGS_DEFAULT, 
       
  5809 			(EAPL("TIMER: %s: EAP_TYPE_TIMER_DELAY_NOTIFICATION_MESSAGE_ID delete data.\n"),
       
  5810 			 (m_is_client == true) ? "client": "server"));
       
  5811 	}
       
  5812 
       
  5813 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5814 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5815 }
       
  5816 
       
  5817 //--------------------------------------------------
       
  5818 
       
  5819 //
       
  5820 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::packet_send(
       
  5821 	const eap_am_network_id_c * const network_id,
       
  5822 	eap_buf_chain_wr_c * const sent_packet,
       
  5823 	const u32_t header_offset,
       
  5824 	const u32_t data_length,
       
  5825 	const u32_t buffer_length)
       
  5826 {
       
  5827 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5828 	EAP_TRACE_DEBUG(
       
  5829 		m_am_tools, 
       
  5830 		TRACE_FLAGS_DEFAULT, 
       
  5831 		(EAPL("eap_type_gsmsim_c::packet_send().\n")));
       
  5832 
       
  5833 	eap_header_wr_c eap(
       
  5834 		m_am_tools,
       
  5835 		sent_packet->get_data_offset(
       
  5836 			header_offset, data_length),
       
  5837 		data_length);
       
  5838 	if (eap.get_is_valid() == false)
       
  5839 	{
       
  5840 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5841 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  5842 	}
       
  5843 
       
  5844 	EAP_GSMSIM_PACKET_TRACE(
       
  5845 		EAPL("<-"),
       
  5846 		network_id,
       
  5847 		&eap,
       
  5848 		data_length);
       
  5849 
       
  5850 	eap_status_e status = get_type_partner()->packet_send(
       
  5851 		network_id, 
       
  5852 		sent_packet, 
       
  5853 		header_offset, 
       
  5854 		data_length,
       
  5855 		buffer_length
       
  5856 		);
       
  5857 
       
  5858 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5859 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5860 }
       
  5861 
       
  5862 //--------------------------------------------------
       
  5863 
       
  5864 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::read_configure(
       
  5865 	const eap_configuration_field_c * const field,
       
  5866 	eap_variable_data_c * const data)
       
  5867 {
       
  5868 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5869 
       
  5870 	// NOTE this will be read from AM of GSMSIM EAP-type.
       
  5871 	const eap_status_e status = m_am_type_gsmsim->type_configure_read(field, data);
       
  5872 
       
  5873 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5874 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5875 }
       
  5876 
       
  5877 //--------------------------------------------------
       
  5878 
       
  5879 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::write_configure(
       
  5880 	const eap_configuration_field_c * const field,
       
  5881 	eap_variable_data_c * const data)
       
  5882 {
       
  5883 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5884 
       
  5885 	// NOTE this will be written to AM of GSMSIM EAP-type.
       
  5886 	const eap_status_e status = m_am_type_gsmsim->type_configure_write(field, data);
       
  5887 
       
  5888 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5889 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5890 }
       
  5891 
       
  5892 //--------------------------------------------------
       
  5893 
       
  5894 // This is commented in eap_base_type_c::configure().
       
  5895 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::configure()
       
  5896 {
       
  5897 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5898 
       
  5899 	EAP_TRACE_DEBUG(
       
  5900 		m_am_tools, 
       
  5901 		TRACE_FLAGS_DEFAULT, 
       
  5902 		(EAPL("eap_type_gsmsim_c::configure(): this = 0x%08x => 0x%08x\n"),
       
  5903 		this,
       
  5904 		dynamic_cast<abs_eap_base_timer_c *>(this)));
       
  5905 
       
  5906 	eap_status_e status(eap_status_process_general_error);
       
  5907 
       
  5908 
       
  5909 	// This must be configured first.
       
  5910 	status = m_am_type_gsmsim->configure();
       
  5911 	if (status != eap_status_ok)
       
  5912 	{
       
  5913 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5914 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5915 	}
       
  5916 
       
  5917 	//----------------------------------------------------------
       
  5918 
       
  5919 	{
       
  5920 		eap_variable_data_c error_message_delay_time(m_am_tools);
       
  5921 
       
  5922 		status = read_configure(
       
  5923 			cf_str_EAP_GSMSIM_failure_message_delay_time.get_field(),
       
  5924 			&error_message_delay_time);
       
  5925 		if (status == eap_status_ok
       
  5926 			&& error_message_delay_time.get_is_valid_data() == true
       
  5927 			&& error_message_delay_time.get_data_length() == sizeof(u32_t)
       
  5928 			&& error_message_delay_time.get_data() != 0)
       
  5929 		{
       
  5930 			// This is optional value.
       
  5931 			m_failure_message_delay_time = *reinterpret_cast<u32_t *>(
       
  5932 				error_message_delay_time.get_data());
       
  5933 		}
       
  5934 	}
       
  5935 
       
  5936 	//----------------------------------------------------------
       
  5937 
       
  5938 	{
       
  5939 		eap_variable_data_c minimum_rand_count(m_am_tools);
       
  5940 
       
  5941 		status = read_configure(
       
  5942 			cf_str_EAP_GSMSIM_minimum_rand_count.get_field(),
       
  5943 			&minimum_rand_count);
       
  5944 		if (status == eap_status_ok
       
  5945 			&& minimum_rand_count.get_is_valid_data() == true
       
  5946 			&& minimum_rand_count.get_data_length() == sizeof(u32_t)
       
  5947 			&& minimum_rand_count.get_data() != 0)
       
  5948 		{
       
  5949 			// This is optional value.
       
  5950 			m_minimum_rand_count = *reinterpret_cast<u32_t *>(
       
  5951 				minimum_rand_count.get_data());
       
  5952 		}
       
  5953 	}
       
  5954 
       
  5955 	//----------------------------------------------------------
       
  5956 
       
  5957 	{
       
  5958 		eap_variable_data_c use_manual_realm(m_am_tools);
       
  5959 
       
  5960 		status = read_configure(
       
  5961 			cf_str_EAP_GSMSIM_use_manual_realm.get_field(),
       
  5962 			&use_manual_realm);
       
  5963 		if (status == eap_status_ok
       
  5964 			&& use_manual_realm.get_is_valid_data() == true
       
  5965 			&& use_manual_realm.get_data_length() == sizeof(u32_t))
       
  5966 		{
       
  5967 			u32_t *flag = reinterpret_cast<u32_t *>(use_manual_realm.get_data());
       
  5968 			if (flag != 0)
       
  5969 			{
       
  5970 				if (*flag == 0)
       
  5971 				{
       
  5972 					m_use_manual_realm = false;
       
  5973 				}
       
  5974 				else
       
  5975 				{
       
  5976 					m_use_manual_realm = true;
       
  5977 				}
       
  5978 			}
       
  5979 			else
       
  5980 			{
       
  5981 				EAP_TRACE_DEBUG(
       
  5982 					m_am_tools, 
       
  5983 					TRACE_FLAGS_GSMSIM_ERROR, 
       
  5984 					(EAPL("ERROR: illegal configuration value %s\n"),
       
  5985 					cf_str_EAP_GSMSIM_use_manual_realm.get_field()->get_field()));
       
  5986 			}
       
  5987 		}
       
  5988 	}
       
  5989 
       
  5990 	//----------------------------------------------------------
       
  5991 
       
  5992 	{
       
  5993 		status = read_configure(
       
  5994 			cf_str_EAP_GSMSIM_manual_realm.get_field(),
       
  5995 			get_nai_realm());
       
  5996 		if (status == eap_status_ok
       
  5997 			&& get_nai_realm()->get_is_valid_data() == true)
       
  5998 		{
       
  5999 			// OK NAI realm is configured.
       
  6000 		}
       
  6001 		else
       
  6002 		{
       
  6003 			// No configured NAI realm.
       
  6004 			// We will use automatic realm "wlan.mnc456.mcc123.3gppnetwork.org" as a realm.
       
  6005 			// Look at eap_type_gsmsim_c::generate_nai().
       
  6006 		}
       
  6007 	}
       
  6008 
       
  6009 	//----------------------------------------------------------
       
  6010 
       
  6011 	{
       
  6012 		eap_variable_data_c check_identifier_of_eap_identity_response(m_am_tools);
       
  6013 
       
  6014 		status = read_configure(
       
  6015 			cf_str_EAP_GSMSIM_check_identifier_of_eap_identity_response.get_field(),
       
  6016 			&check_identifier_of_eap_identity_response);
       
  6017 
       
  6018 		if (status == eap_status_ok
       
  6019 			&& check_identifier_of_eap_identity_response.get_is_valid_data() == true)
       
  6020 		{
       
  6021 			u32_t *flag = reinterpret_cast<u32_t *>(
       
  6022 				check_identifier_of_eap_identity_response.get_data());
       
  6023 			if (flag != 0)
       
  6024 			{
       
  6025 				if (*flag == 0)
       
  6026 				{
       
  6027 					m_check_identifier_of_eap_identity_response = false;
       
  6028 				}
       
  6029 				else
       
  6030 				{
       
  6031 					m_check_identifier_of_eap_identity_response = true;
       
  6032 				}
       
  6033 			}
       
  6034 		}
       
  6035 		else
       
  6036 		{
       
  6037 			EAP_TRACE_DEBUG(
       
  6038 				m_am_tools, 
       
  6039 				TRACE_FLAGS_GSMSIM_ERROR, 
       
  6040 				(EAPL("ERROR: illegal configuration value %s\n"),
       
  6041 				cf_str_EAP_GSMSIM_check_identifier_of_eap_identity_response
       
  6042 				 .get_field()->get_field()));
       
  6043 		}
       
  6044 	}
       
  6045 
       
  6046 	//----------------------------------------------------------
       
  6047 
       
  6048 	{
       
  6049 		eap_variable_data_c EAP_GSMSIM_check_nai_realm(m_am_tools);
       
  6050 
       
  6051 		status = read_configure(
       
  6052 			cf_str_EAP_GSMSIM_check_nai_realm.get_field(),
       
  6053 			&EAP_GSMSIM_check_nai_realm);
       
  6054 		if (status == eap_status_ok
       
  6055 			&& EAP_GSMSIM_check_nai_realm.get_is_valid_data() == true)
       
  6056 		{
       
  6057 			u32_t *check_nai_realm = reinterpret_cast<u32_t *>(
       
  6058 				EAP_GSMSIM_check_nai_realm.get_data());
       
  6059 			if (check_nai_realm != 0
       
  6060 				&& *check_nai_realm != 0)
       
  6061 			{
       
  6062 				m_check_nai_realm = true;
       
  6063 			}
       
  6064 		}
       
  6065 	}
       
  6066 
       
  6067 	//----------------------------------------------------------
       
  6068 
       
  6069 #if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS)
       
  6070 	{
       
  6071 		status = read_configure(
       
  6072 			cf_str_EAP_GSMSIM_nonce_mt_file.get_field(),
       
  6073 			&m_nonce_mt_file);
       
  6074 		if (status == eap_status_ok
       
  6075 			&& m_nonce_mt_file.get_is_valid_data() == true
       
  6076 			&& m_nonce_mt_file.get_data_length() != 0
       
  6077 			&& m_nonce_mt_file.get_data() != 0)
       
  6078 		{
       
  6079 			// This is optional value.
       
  6080 		}
       
  6081 	}
       
  6082 #endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS)
       
  6083 
       
  6084 	//----------------------------------------------------------
       
  6085 
       
  6086 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION)
       
  6087 	{
       
  6088 		eap_variable_data_c EAP_GSMSIM_client_responds_retransmitted_packets(m_am_tools);
       
  6089 
       
  6090 		status = read_configure(
       
  6091 			cf_str_EAP_GSMSIM_client_responds_retransmitted_packets.get_field(),
       
  6092 			&EAP_GSMSIM_client_responds_retransmitted_packets);
       
  6093 		if (status == eap_status_ok
       
  6094 			&& EAP_GSMSIM_client_responds_retransmitted_packets.get_is_valid_data() == true
       
  6095 			&& EAP_GSMSIM_client_responds_retransmitted_packets.get_data_length() == sizeof(u32_t)
       
  6096 			&& EAP_GSMSIM_client_responds_retransmitted_packets.get_data() != 0)
       
  6097 		{
       
  6098 			// This is optional value.
       
  6099 			u32_t *flag = reinterpret_cast<u32_t *>(
       
  6100 				EAP_GSMSIM_client_responds_retransmitted_packets.get_data());
       
  6101 			if (flag != 0)
       
  6102 			{
       
  6103 				if (*flag == 0)
       
  6104 				{
       
  6105 					m_client_responds_retransmitted_packets = false;
       
  6106 				}
       
  6107 				else
       
  6108 				{
       
  6109 					m_client_responds_retransmitted_packets = true;
       
  6110 				}
       
  6111 			}
       
  6112 		}
       
  6113 	}
       
  6114 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION)
       
  6115 
       
  6116 	//----------------------------------------------------------
       
  6117 
       
  6118 	{
       
  6119 		eap_variable_data_c test_version(m_am_tools);
       
  6120 
       
  6121 		status = read_configure(
       
  6122 			cf_str_EAP_GSMSIM_test_version.get_field(),
       
  6123 			&test_version);
       
  6124 		if (status == eap_status_ok
       
  6125 			&& test_version.get_is_valid_data() == true
       
  6126 			&& test_version.get_data_length() == sizeof(u32_t)
       
  6127 			&& test_version.get_data() != 0)
       
  6128 		{
       
  6129 			// This is optional value.
       
  6130 			u32_t *flag = reinterpret_cast<u32_t *>(test_version.get_data());
       
  6131 			if (flag != 0)
       
  6132 			{
       
  6133 				if (*flag == 0)
       
  6134 				{
       
  6135 					m_gsmsim_test_version = false;
       
  6136 				}
       
  6137 				else
       
  6138 				{
       
  6139 					m_gsmsim_test_version = true;
       
  6140 				}
       
  6141 			}
       
  6142 		}
       
  6143 	}
       
  6144 
       
  6145 	//----------------------------------------------------------
       
  6146 
       
  6147 	{
       
  6148 		eap_variable_data_c randomly_refuse_eap_identity(m_am_tools);
       
  6149 
       
  6150 		status = read_configure(
       
  6151 			cf_str_EAP_GSMSIM_randomly_refuse_eap_identity.get_field(),
       
  6152 			&randomly_refuse_eap_identity);
       
  6153 		if (status == eap_status_ok
       
  6154 			&& randomly_refuse_eap_identity.get_is_valid_data() == true
       
  6155 			&& randomly_refuse_eap_identity.get_data_length() == sizeof(u32_t)
       
  6156 			&& randomly_refuse_eap_identity.get_data() != 0)
       
  6157 		{
       
  6158 			// This is optional value.
       
  6159 			u32_t *flag = reinterpret_cast<u32_t *>(randomly_refuse_eap_identity.get_data());
       
  6160 			if (flag != 0)
       
  6161 			{
       
  6162 				if (*flag == 0)
       
  6163 				{
       
  6164 					m_gsmsim_randomly_refuse_eap_identity = false;
       
  6165 				}
       
  6166 				else
       
  6167 				{
       
  6168 					m_gsmsim_randomly_refuse_eap_identity = true;
       
  6169 				}
       
  6170 			}
       
  6171 		}
       
  6172 	}
       
  6173 
       
  6174 	//----------------------------------------------------------
       
  6175 
       
  6176 	{
       
  6177 		eap_variable_data_c do_rand_uniqueness_check(m_am_tools);
       
  6178 
       
  6179 		status = read_configure(
       
  6180 			cf_str_EAP_GSMSIM_do_rand_uniqueness_check.get_field(),
       
  6181 			&do_rand_uniqueness_check);
       
  6182 
       
  6183 		if (status == eap_status_ok
       
  6184 			&& do_rand_uniqueness_check.get_is_valid_data() == true
       
  6185 			&& do_rand_uniqueness_check.get_data_length() == sizeof(u32_t))
       
  6186 		{
       
  6187 			u32_t *flag = reinterpret_cast<u32_t *>(do_rand_uniqueness_check.get_data());
       
  6188 			if (flag != 0)
       
  6189 			{
       
  6190 				if (*flag == 0)
       
  6191 				{
       
  6192 					m_do_rand_uniqueness_check = false;
       
  6193 				}
       
  6194 				else
       
  6195 				{
       
  6196 					m_do_rand_uniqueness_check = true;
       
  6197 				}
       
  6198 			}
       
  6199 		}
       
  6200 	}
       
  6201 
       
  6202 	//----------------------------------------------------------
       
  6203 
       
  6204 	{
       
  6205 		eap_variable_data_c use_manual_username(m_am_tools);
       
  6206 
       
  6207 		status = read_configure(
       
  6208 			cf_str_EAP_GSMSIM_use_manual_username.get_field(),
       
  6209 			&use_manual_username);
       
  6210 		if (status == eap_status_ok
       
  6211 			&& use_manual_username.get_is_valid_data() == true
       
  6212 			&& use_manual_username.get_data_length() == sizeof(u32_t))
       
  6213 		{
       
  6214 			u32_t *use_manual_username_flag = reinterpret_cast<u32_t *>(
       
  6215 				use_manual_username.get_data());
       
  6216 			if (use_manual_username_flag != 0
       
  6217 				&& *use_manual_username_flag != 0)
       
  6218 			{
       
  6219 				m_use_manual_username = true;
       
  6220 			}
       
  6221 		}
       
  6222 	}
       
  6223 
       
  6224 	//----------------------------------------------------------
       
  6225 
       
  6226 	if (m_use_manual_username == true)
       
  6227 	{
       
  6228 		status = read_configure(
       
  6229 			cf_str_EAP_GSMSIM_manual_username.get_field(),
       
  6230 			&m_manual_username);
       
  6231 		if (status == eap_status_ok
       
  6232 			&& m_manual_username.get_is_valid_data() == true)
       
  6233 		{
       
  6234 			// This is optional value.
       
  6235 		}
       
  6236 		else
       
  6237 		{
       
  6238 			// No username defined.
       
  6239 			m_use_manual_username = false;
       
  6240 		}
       
  6241 	}
       
  6242 
       
  6243 	//----------------------------------------------------------
       
  6244 
       
  6245 	{
       
  6246 		eap_variable_data_c fail_re_authentication_counter_check(m_am_tools);
       
  6247 
       
  6248 		status = read_configure(
       
  6249 			cf_str_EAP_GSMSIM_fail_re_authentication_counter_check.get_field(),
       
  6250 			&fail_re_authentication_counter_check);
       
  6251 		if (status == eap_status_ok
       
  6252 			&& fail_re_authentication_counter_check.get_is_valid_data() == true
       
  6253 			&& fail_re_authentication_counter_check.get_data_length() == sizeof(u32_t)
       
  6254 			&& fail_re_authentication_counter_check.get_data() != 0)
       
  6255 		{
       
  6256 			// This is optional value.
       
  6257 			u32_t *flag = reinterpret_cast<u32_t *>(
       
  6258 				fail_re_authentication_counter_check.get_data());
       
  6259 			if (flag != 0)
       
  6260 			{
       
  6261 				if (*flag == 0)
       
  6262 				{
       
  6263 					m_fail_reauthentication_counter_check = false;
       
  6264 				}
       
  6265 				else
       
  6266 				{
       
  6267 					m_fail_reauthentication_counter_check = true;
       
  6268 				}
       
  6269 			}
       
  6270 		}
       
  6271 	}
       
  6272 
       
  6273 	//----------------------------------------------------------
       
  6274 
       
  6275 	{
       
  6276 		eap_variable_data_c accept_eap_identity_response(m_am_tools);
       
  6277 
       
  6278 		status = read_configure(
       
  6279 			cf_str_EAP_GSMSIM_accept_eap_identity_response.get_field(),
       
  6280 			&accept_eap_identity_response);
       
  6281 		if (status == eap_status_ok
       
  6282 			&& accept_eap_identity_response.get_is_valid_data() == true
       
  6283 			&& accept_eap_identity_response.get_data_length() == sizeof(u32_t)
       
  6284 			&& accept_eap_identity_response.get_data() != 0)
       
  6285 		{
       
  6286 			// This is optional value.
       
  6287 			u32_t *flag = reinterpret_cast<u32_t *>(accept_eap_identity_response.get_data());
       
  6288 			if (flag != 0)
       
  6289 			{
       
  6290 				if (*flag != 0)
       
  6291 				{
       
  6292 					m_accept_eap_identity_response = true;
       
  6293 				}
       
  6294 				else if (*flag == 0)
       
  6295 				{
       
  6296 					m_accept_eap_identity_response = false;
       
  6297 				}
       
  6298 			}
       
  6299 		}
       
  6300 	}
       
  6301 
       
  6302 	//----------------------------------------------------------
       
  6303 
       
  6304 	{
       
  6305 		eap_variable_data_c use_random_identity_on_eap_identity_response(m_am_tools);
       
  6306 
       
  6307 		status = read_configure(
       
  6308 			cf_str_EAP_GSMSIM_use_random_identity_on_eap_identity_response.get_field(),
       
  6309 			&use_random_identity_on_eap_identity_response);
       
  6310 		if (status == eap_status_ok
       
  6311 			&& use_random_identity_on_eap_identity_response.get_is_valid_data() == true
       
  6312 			&& use_random_identity_on_eap_identity_response.get_data_length() == sizeof(u32_t)
       
  6313 			&& use_random_identity_on_eap_identity_response.get_data() != 0)
       
  6314 		{
       
  6315 			// This is optional value.
       
  6316 			u32_t *flag = reinterpret_cast<u32_t *>(
       
  6317 				use_random_identity_on_eap_identity_response.get_data());
       
  6318 			if (flag != 0)
       
  6319 			{
       
  6320 				if (*flag != 0)
       
  6321 				{
       
  6322 					m_use_random_identity_on_eap_identity_response = true;
       
  6323 				}
       
  6324 				else if (*flag == 0)
       
  6325 				{
       
  6326 					m_use_random_identity_on_eap_identity_response = false;
       
  6327 				}
       
  6328 			}
       
  6329 		}
       
  6330 	}
       
  6331 
       
  6332 	//----------------------------------------------------------
       
  6333 
       
  6334 	{
       
  6335 		eap_variable_data_c use_pseudonym_identity(m_am_tools);
       
  6336 
       
  6337 		status = read_configure(
       
  6338 			cf_str_EAP_GSMSIM_use_pseudonym_identity.get_field(),
       
  6339 			&use_pseudonym_identity);
       
  6340 		if (status == eap_status_ok
       
  6341 			&& use_pseudonym_identity.get_is_valid_data() == true
       
  6342 			&& use_pseudonym_identity.get_data_length() == sizeof(u32_t)
       
  6343 			&& use_pseudonym_identity.get_data() != 0)
       
  6344 		{
       
  6345 			// This is optional value.
       
  6346 			u32_t *flag = reinterpret_cast<u32_t *>(use_pseudonym_identity.get_data());
       
  6347 			if (flag != 0)
       
  6348 			{
       
  6349 				if (*flag != 0)
       
  6350 				{
       
  6351 					m_use_pseudonym_identity = true;
       
  6352 				}
       
  6353 				else if (*flag == 0)
       
  6354 				{
       
  6355 					m_use_pseudonym_identity = false;
       
  6356 				}
       
  6357 			}
       
  6358 		}
       
  6359 	}
       
  6360 
       
  6361 	//----------------------------------------------------------
       
  6362 
       
  6363 	{
       
  6364 		eap_variable_data_c use_reauthentication_identity(m_am_tools);
       
  6365 
       
  6366 		status = read_configure(
       
  6367 			cf_str_EAP_GSMSIM_use_reauthentication_identity.get_field(),
       
  6368 			&use_reauthentication_identity);
       
  6369 		if (status == eap_status_ok
       
  6370 			&& use_reauthentication_identity.get_is_valid_data() == true
       
  6371 			&& use_reauthentication_identity.get_data_length() == sizeof(u32_t)
       
  6372 			&& use_reauthentication_identity.get_data() != 0)
       
  6373 		{
       
  6374 			// This is optional value.
       
  6375 			u32_t *flag = reinterpret_cast<u32_t *>(use_reauthentication_identity.get_data());
       
  6376 			if (flag != 0)
       
  6377 			{
       
  6378 				if (*flag != 0)
       
  6379 				{
       
  6380 					m_use_reauthentication_identity = true;
       
  6381 				}
       
  6382 				else if (*flag == 0)
       
  6383 				{
       
  6384 					m_use_reauthentication_identity = false;
       
  6385 				}
       
  6386 			}
       
  6387 		}
       
  6388 	}
       
  6389 
       
  6390 	//----------------------------------------------------------
       
  6391 
       
  6392 	{
       
  6393 		eap_variable_data_c randomly_fail_successfull_authentication(m_am_tools);
       
  6394 
       
  6395 		status = read_configure(
       
  6396 			cf_str_EAP_GSMSIM_randomly_fail_successfull_authentication.get_field(),
       
  6397 			&randomly_fail_successfull_authentication);
       
  6398 		if (status == eap_status_ok
       
  6399 			&& randomly_fail_successfull_authentication.get_is_valid_data() == true
       
  6400 			&& randomly_fail_successfull_authentication.get_data_length() == sizeof(u32_t)
       
  6401 			&& randomly_fail_successfull_authentication.get_data() != 0)
       
  6402 		{
       
  6403 			// This is optional value.
       
  6404 			u32_t *flag = reinterpret_cast<u32_t *>(
       
  6405 				randomly_fail_successfull_authentication.get_data());
       
  6406 			if (flag != 0)
       
  6407 			{
       
  6408 				if (*flag != 0)
       
  6409 				{
       
  6410 					m_randomly_fail_successfull_authentication = true;
       
  6411 				}
       
  6412 				else
       
  6413 				{
       
  6414 					m_randomly_fail_successfull_authentication = false;
       
  6415 				}
       
  6416 			}
       
  6417 		}
       
  6418 	}
       
  6419 
       
  6420 	//----------------------------------------------------------
       
  6421 
       
  6422 	{
       
  6423 		eap_variable_data_c allow_use_result_indication(m_am_tools);
       
  6424 
       
  6425 		status = read_configure(
       
  6426 			cf_str_EAP_GSMSIM_allow_use_result_indication.get_field(),
       
  6427 			&allow_use_result_indication);
       
  6428 		if (status == eap_status_ok
       
  6429 			&& allow_use_result_indication.get_is_valid_data() == true
       
  6430 			&& allow_use_result_indication.get_data_length() == sizeof(u32_t)
       
  6431 			&& allow_use_result_indication.get_data() != 0)
       
  6432 		{
       
  6433 			// This is optional value.
       
  6434 			u32_t *flag = reinterpret_cast<u32_t *>(allow_use_result_indication.get_data());
       
  6435 			if (flag != 0)
       
  6436 			{
       
  6437 				if (*flag != 0)
       
  6438 				{
       
  6439 					m_allow_use_result_indication = true;
       
  6440 				}
       
  6441 				else
       
  6442 				{
       
  6443 					m_allow_use_result_indication = false;
       
  6444 				}
       
  6445 			}
       
  6446 		}
       
  6447 	}
       
  6448 
       
  6449 	if (m_is_client == false)
       
  6450 	{
       
  6451 		eap_variable_data_c server_allow_use_result_indication(m_am_tools);
       
  6452 
       
  6453 		status = read_configure(
       
  6454 			cf_str_EAP_GSMSIM_server_allow_use_result_indication.get_field(),
       
  6455 			&server_allow_use_result_indication);
       
  6456 		if (status == eap_status_ok
       
  6457 			&& server_allow_use_result_indication.get_is_valid_data() == true
       
  6458 			&& server_allow_use_result_indication.get_data_length() == sizeof(u32_t)
       
  6459 			&& server_allow_use_result_indication.get_data() != 0)
       
  6460 		{
       
  6461 			// This is optional value.
       
  6462 			u32_t *flag = reinterpret_cast<u32_t *>(server_allow_use_result_indication.get_data());
       
  6463 			if (flag != 0)
       
  6464 			{
       
  6465 				if (*flag != 0)
       
  6466 				{
       
  6467 					m_allow_use_result_indication = true;
       
  6468 				}
       
  6469 				else
       
  6470 				{
       
  6471 					m_allow_use_result_indication = false;
       
  6472 				}
       
  6473 			}
       
  6474 		}
       
  6475 	}
       
  6476 
       
  6477 	//----------------------------------------------------------
       
  6478 
       
  6479 #if defined(USE_EAP_EXPANDED_TYPES)
       
  6480 	{
       
  6481 		eap_variable_data_c use_eap_expanded_type(m_am_tools);
       
  6482 
       
  6483 		eap_status_e status = read_configure(
       
  6484 			cf_str_EAP_GSMSIM_use_eap_expanded_type.get_field(),
       
  6485 			&use_eap_expanded_type);
       
  6486 
       
  6487 		if (status != eap_status_ok)
       
  6488 		{
       
  6489 			status = read_configure(
       
  6490 				cf_str_EAP_CORE_use_eap_expanded_type.get_field(),
       
  6491 				&use_eap_expanded_type);
       
  6492 		}
       
  6493 
       
  6494 		if (status == eap_status_ok
       
  6495 			&& use_eap_expanded_type.get_data_length() == sizeof(u32_t)
       
  6496 			&& use_eap_expanded_type.get_data() != 0)
       
  6497 		{
       
  6498 			u32_t *flag = reinterpret_cast<u32_t *>(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length()));
       
  6499 
       
  6500 			if (flag != 0)
       
  6501 			{
       
  6502 				if ((*flag) != 0ul)
       
  6503 				{
       
  6504 					m_use_eap_expanded_type = true;
       
  6505 				}
       
  6506 				else
       
  6507 				{
       
  6508 					m_use_eap_expanded_type = false;
       
  6509 				}
       
  6510 			}
       
  6511 		}
       
  6512 	}
       
  6513 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
  6514 
       
  6515 	//----------------------------------------------------------
       
  6516 
       
  6517 	{
       
  6518 		(void) read_configure(
       
  6519 			cf_str_EAP_GSMSIM_2_digit_mnc_map_of_mcc_of_imsi_array.get_field(),
       
  6520 			&m_2_digit_mnc_map_of_mcc_of_imsi_array);
       
  6521 		// This is optional value.
       
  6522 	}
       
  6523 
       
  6524 	{
       
  6525 		eap_variable_data_c use_uma_profile(m_am_tools);
       
  6526 
       
  6527 		eap_status_e status = read_configure(
       
  6528 			cf_str_EAP_GSMSIM_UMA_profile.get_field(),
       
  6529 			&use_uma_profile);
       
  6530 		if (status == eap_status_ok
       
  6531 			&& use_uma_profile.get_is_valid_data() == true
       
  6532 			&& use_uma_profile.get_data_length() == sizeof(u32_t))
       
  6533 		{
       
  6534 			u32_t *flag = reinterpret_cast<u32_t *>(use_uma_profile.get_data());
       
  6535 			if (flag != 0)
       
  6536 			{
       
  6537 				if (*flag == 0)
       
  6538 				{
       
  6539 					m_use_uma_profile = false;
       
  6540 				}
       
  6541 				else
       
  6542 				{
       
  6543 					m_use_uma_profile = true;
       
  6544 				}
       
  6545 			}
       
  6546 		}		
       
  6547 	}
       
  6548 
       
  6549 	if (m_use_uma_profile == true)
       
  6550 	{
       
  6551 		(void) read_configure(
       
  6552 			cf_str_EAP_GSMSIM_UMA_realm_prefix.get_field(),
       
  6553 			&m_uma_automatic_realm_prefix);
       
  6554 		// m_uma_automatic_realm_prefix is optional value.
       
  6555 
       
  6556 		// In the UMA we must wait EAP-Success to fullfill the state machine of mVPN.
       
  6557 		m_wait_eap_success_packet = true;
       
  6558 	}
       
  6559 	else
       
  6560 	{
       
  6561 		eap_variable_data_c wait_eap_success_packet(m_am_tools);
       
  6562 
       
  6563 		status = read_configure(
       
  6564 			cf_str_EAP_GSMSIM_wait_eap_success_packet.get_field(),
       
  6565 			&wait_eap_success_packet);
       
  6566 
       
  6567 		if (status == eap_status_ok
       
  6568 			&& wait_eap_success_packet.get_is_valid_data() == true)
       
  6569 		{
       
  6570 			u32_t *flag = reinterpret_cast<u32_t *>(wait_eap_success_packet.get_data());
       
  6571 			if (flag != 0)
       
  6572 			{
       
  6573 				if (*flag == 0)
       
  6574 				{
       
  6575 					m_wait_eap_success_packet = false;
       
  6576 				}
       
  6577 				else
       
  6578 				{
       
  6579 					m_wait_eap_success_packet = true;
       
  6580 				}
       
  6581 			}
       
  6582 		}
       
  6583 
       
  6584 		if (get_type_partner()->get_is_tunneled_eap() == true)
       
  6585 		{
       
  6586 			// Inside the PEAP we must wait EAP-Success to fullfill the state machine of PEAP.
       
  6587 			m_wait_eap_success_packet = true;
       
  6588 		}
       
  6589 	}
       
  6590 
       
  6591 	//----------------------------------------------------------
       
  6592 
       
  6593 	m_gsmsim_header_offset = get_type_partner()->get_header_offset(
       
  6594 		&m_MTU, &m_trailer_length);
       
  6595 
       
  6596 	if (m_gsmsim_header_offset+m_MTU+m_trailer_length
       
  6597 		> EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH)
       
  6598 	{
       
  6599 		EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH
       
  6600 						  >= (m_gsmsim_header_offset+m_trailer_length));
       
  6601 
       
  6602 		m_MTU = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH
       
  6603 			- (m_gsmsim_header_offset+m_trailer_length);
       
  6604 	}
       
  6605 
       
  6606 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6607 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6608 }
       
  6609 
       
  6610 //--------------------------------------------------
       
  6611 
       
  6612 // This is commented in eap_base_type_c::shutdown().
       
  6613 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::shutdown()
       
  6614 {
       
  6615 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6616 
       
  6617 	EAP_TRACE_DEBUG(
       
  6618 		m_am_tools, 
       
  6619 		TRACE_FLAGS_DEFAULT, 
       
  6620 		(EAPL("eap_type_gsmsim_c::shutdown(): this = 0x%08x => 0x%08x\n"),
       
  6621 		this,
       
  6622 		dynamic_cast<abs_eap_base_timer_c *>(this)));
       
  6623 
       
  6624 	if (m_shutdown_was_called == true)
       
  6625 	{
       
  6626 		// Shutdown function was called already.
       
  6627 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6628 	}
       
  6629 	m_shutdown_was_called = true;
       
  6630 
       
  6631 	cancel_error_message_delay_timer();
       
  6632 	cancel_notification_message_delay_timer();
       
  6633 
       
  6634 	if (m_state != eap_type_gsmsim_state_none)
       
  6635 	{
       
  6636 		// We must cancel the pending query.
       
  6637 		if (m_state == eap_type_gsmsim_state_pending_identity_query)
       
  6638 		{
       
  6639 			m_am_type_gsmsim->cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query();
       
  6640 		}
       
  6641 		else if (m_state == eap_type_gsmsim_state_pending_kc_sres_query)
       
  6642 		{
       
  6643 			m_am_type_gsmsim->cancel_SIM_kc_sres_query();
       
  6644 		}
       
  6645 		else if (m_state == eap_type_gsmsim_state_pending_pseudonym_decode_query)
       
  6646 		{
       
  6647 			m_am_type_gsmsim->cancel_imsi_from_username_query();
       
  6648 		}
       
  6649 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  6650 		else if (m_state == eap_type_gsmsim_state_pending_triplet_query)
       
  6651 		{
       
  6652 			m_am_type_gsmsim->cancel_SIM_triplets_query();
       
  6653 		}
       
  6654 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  6655 
       
  6656 		send_final_notification();
       
  6657 	}
       
  6658 
       
  6659 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  6660 	if (m_triplets != 0)
       
  6661 	{
       
  6662 		delete m_triplets;
       
  6663 		m_triplets = 0;
       
  6664 	}
       
  6665 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  6666 
       
  6667 	eap_status_e status(eap_status_ok);
       
  6668 	if (m_am_type_gsmsim != 0)
       
  6669 	{
       
  6670 		status = m_am_type_gsmsim->shutdown();
       
  6671 	}
       
  6672 
       
  6673 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6674 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6675 }
       
  6676 
       
  6677 //--------------------------------------------------
       
  6678 
       
  6679 // This function is to allow reuse of this object.
       
  6680 // The whole object state must be reset.
       
  6681 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::reset()
       
  6682 {
       
  6683 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6684 
       
  6685 	EAP_TRACE_DEBUG(
       
  6686 		m_am_tools,
       
  6687 		TRACE_FLAGS_DEFAULT,
       
  6688 		(EAPL("GSMSIM: %s: function: eap_type_gsmsim_c::reset(): this = 0x%08x\n"),
       
  6689 		(m_is_client == true ? "client": "server"),
       
  6690 		this));
       
  6691 
       
  6692 	eap_status_e status = eap_status_not_supported;
       
  6693 
       
  6694 	m_reset_was_called = true;
       
  6695 
       
  6696 	m_use_result_indication = false;
       
  6697 	m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE;
       
  6698 	set_identity_type(GSMSIM_IDENTITY_TYPE_NONE);
       
  6699 
       
  6700 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  6701 	if (m_triplets != 0)
       
  6702 	{
       
  6703 		delete m_triplets;
       
  6704 		m_triplets = 0;
       
  6705 	}
       
  6706 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
  6707 
       
  6708 	m_state = eap_type_gsmsim_state_none;
       
  6709 	m_saved_previous_state = eap_type_gsmsim_state_none;
       
  6710 	m_gsmsim_selected_version = GSMSIM_ILLEGAL_VERSION;
       
  6711 	m_nonce_mt.reset();
       
  6712 	m_nonce_s.reset();
       
  6713 	m_IV.get_payload_buffer()->reset();
       
  6714 	m_saved_EAP_packet.reset();
       
  6715 	m_XKEY.reset();
       
  6716 	m_K_encr.reset();
       
  6717 	m_K_aut.reset();
       
  6718 	m_master_session_key.reset();
       
  6719 	m_automatic_realm.reset();
       
  6720 	m_automatic_realm_read = false;
       
  6721 	m_IMSI.reset();
       
  6722 	m_pseudonym.reset();
       
  6723 	m_reauthentication_identity.reset();
       
  6724 	m_identity.reset();
       
  6725 	m_NAI.reset();
       
  6726 	m_n_rands.reset();
       
  6727 	m_n_sres.reset();
       
  6728 
       
  6729 	{
       
  6730 		cancel_error_message_delay_timer();
       
  6731 		m_client_error_code = eap_gsmsim_client_error_code_none;
       
  6732 		m_erroneus_packet_received = false;
       
  6733 
       
  6734 		cancel_notification_message_delay_timer();
       
  6735 		m_gsmsim_notification_code = eap_gsmsim_notification_none;
       
  6736 		m_sim_notification_packet_received = false;
       
  6737 	}
       
  6738 
       
  6739 	status = m_am_type_gsmsim->reset();
       
  6740 	if (status != eap_status_ok)
       
  6741 	{
       
  6742 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6743 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6744 	}
       
  6745 
       
  6746 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6747 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6748 }
       
  6749 
       
  6750 //--------------------------------------------------
       
  6751 
       
  6752 //
       
  6753 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_timer(
       
  6754 	abs_eap_base_timer_c * const p_initializer, 
       
  6755 	const u32_t p_id, 
       
  6756 	void * const p_data,
       
  6757 	const u32_t p_time_ms)
       
  6758 {
       
  6759 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6760 
       
  6761 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  6762 
       
  6763 	const eap_status_e status = get_type_partner()->set_timer(
       
  6764 		p_initializer, 
       
  6765 		p_id, 
       
  6766 		p_data,
       
  6767 		p_time_ms);
       
  6768 
       
  6769 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6770 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6771 }
       
  6772 
       
  6773 //--------------------------------------------------
       
  6774 
       
  6775 //
       
  6776 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_timer(
       
  6777 	abs_eap_base_timer_c * const p_initializer, 
       
  6778 	const u32_t p_id)
       
  6779 {
       
  6780 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6781 
       
  6782 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  6783 
       
  6784 	const eap_status_e status = get_type_partner()->cancel_timer(
       
  6785 		p_initializer, 
       
  6786 		p_id);
       
  6787 
       
  6788 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6789 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6790 }
       
  6791 
       
  6792 //--------------------------------------------------
       
  6793 
       
  6794 //
       
  6795 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::cancel_all_timers()
       
  6796 {
       
  6797 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6798 
       
  6799 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  6800 
       
  6801 	const eap_status_e status = get_type_partner()->cancel_all_timers();
       
  6802 
       
  6803 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6804 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6805 }
       
  6806 
       
  6807 //--------------------------------------------------
       
  6808 
       
  6809 void eap_type_gsmsim_c::set_start_response_includes_identity(gsmsim_payload_AT_type_e type)
       
  6810 {
       
  6811 	EAP_TRACE_DEBUG(
       
  6812 		m_am_tools,
       
  6813 		TRACE_FLAGS_DEFAULT,
       
  6814 		(EAPL("GSMSIM: %s: eap_type_gsmsim_c::set_start_response_includes_identity(): %d=%s\n"),
       
  6815 		(m_is_client == true ? "client": "server"),
       
  6816 		type,
       
  6817 		gsmsim_payload_AT_header_c::get_payload_AT_string(type)));
       
  6818 
       
  6819 	m_start_response_includes_identity = type;
       
  6820 }
       
  6821 
       
  6822 //--------------------------------------------------
       
  6823 
       
  6824 void eap_type_gsmsim_c::set_identity_type(eap_type_gsmsim_identity_type type)
       
  6825 {
       
  6826 	EAP_TRACE_DEBUG(
       
  6827 		m_am_tools,
       
  6828 		TRACE_FLAGS_DEFAULT,
       
  6829 		(EAPL("GSMSIM: %s: eap_type_gsmsim_c::set_identity_type(): %d=%s\n"),
       
  6830 		(m_is_client == true ? "client": "server"),
       
  6831 		type,
       
  6832 		get_identity_string(type)));
       
  6833 
       
  6834 	m_identity_type = type;
       
  6835 }
       
  6836 
       
  6837 //--------------------------------------------------
       
  6838 // End.