eapol/eapol_framework/eapol_common/type/simple_config/simple_config/src/simple_config_record.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 601 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 #if defined(USE_EAP_SIMPLE_CONFIG)
       
    28 
       
    29 #include "eap_am_memory.h"
       
    30 #include "eap_am_export.h"
       
    31 #include "eap_am_tools.h"
       
    32 #include "eap_tools.h"
       
    33 #include "eap_crypto_api.h"
       
    34 #include "abs_simple_config_base_record.h"
       
    35 #include "simple_config_base_record.h"
       
    36 #include "simple_config_record.h"
       
    37 #include "simple_config_am_services.h"
       
    38 #include "simple_config_types.h"
       
    39 #include "simple_config_message.h"
       
    40 #include "eap_automatic_variable.h"
       
    41 #include "eap_state_notification.h"
       
    42 #include "eap_type_simple_config_types.h"
       
    43 #include "eap_header_string.h"
       
    44 #include "abs_eap_am_mutex.h"
       
    45 #include "simple_config_credential.h"
       
    46 #include "eapol_key_types.h"
       
    47 
       
    48 //--------------------------------------------------
       
    49 
       
    50 
       
    51 EAP_FUNC_EXPORT simple_config_record_c::~simple_config_record_c()
       
    52 {
       
    53 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    54 
       
    55 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
    56 					(EAPL("%s: function: simple_config_record_c::~simple_config_record_c(): this = 0x%08x, m_am_simple_config_services")
       
    57 					 EAPL(" = 0x%08x (validity %d).\n"),
       
    58 					 (m_is_client == true ? "client": "server"),
       
    59 					 this,
       
    60 					 m_am_simple_config_services,
       
    61 					 m_am_simple_config_services->get_is_valid()));
       
    62 
       
    63 	EAP_ASSERT(m_shutdown_was_called == true);
       
    64 
       
    65 	completion_action_clenup();
       
    66 
       
    67 	if (m_free_am_simple_config_services == true)
       
    68 	{
       
    69 		delete m_am_simple_config_services;
       
    70 	}
       
    71 	m_am_simple_config_services = 0;
       
    72 
       
    73 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    74 }
       
    75 
       
    76 //--------------------------------------------------
       
    77 
       
    78 #if defined(_WIN32) && !defined(__GNUC__)
       
    79 	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
       
    80 #endif
       
    81 
       
    82 EAP_FUNC_EXPORT simple_config_record_c::simple_config_record_c(
       
    83 	abs_eap_am_tools_c * const tools, ///< tools is pointer to the tools class. @see abs_eap_am_tools_c.
       
    84 	simple_config_am_services_c * const am_simple_config_services, ///< This is pointer to adaptation module of SIMPLE_CONFIG.
       
    85 	const bool free_am_simple_config_services,
       
    86 	const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false).
       
    87 	const eap_am_network_id_c * const receive_network_id)
       
    88 	: simple_config_base_record_c(tools /*, partner */)
       
    89 	, m_am_tools(tools)
       
    90 	, m_am_simple_config_services(am_simple_config_services)
       
    91 	, m_free_am_simple_config_services(free_am_simple_config_services)
       
    92 	, m_completion_queue(tools)
       
    93 	, m_M2D_payloads(tools)
       
    94 	, m_received_simple_config_message(tools, is_client_when_true)
       
    95 	, m_received_payloads(tools)
       
    96 	, m_previous_simple_config_message(tools, is_client_when_true)
       
    97 	, m_new_simple_config_message(tools, is_client_when_true)
       
    98 	, m_current_simple_config_message_type(simple_config_Message_Type_None)
       
    99 	, m_enrollee_nonce(tools)
       
   100 	, m_enrollee_mac(tools)
       
   101 	, m_registrar_nonce(tools)
       
   102 	, m_device_password(tools)
       
   103 	, m_PSK1(tools)
       
   104 	, m_PSK2(tools)
       
   105 	, m_E_SNonce1(tools)
       
   106 	, m_E_SNonce2(tools)
       
   107 	, m_EHash1(tools)
       
   108 	, m_EHash2(tools)
       
   109 	, m_R_SNonce1(tools)
       
   110 	, m_R_SNonce2(tools)
       
   111 	, m_RHash1(tools)
       
   112 	, m_RHash2(tools)
       
   113 	, m_own_private_dhe_key(tools)
       
   114 	, m_own_public_dhe_key(tools)
       
   115 	, m_peer_public_dhe_key(tools)
       
   116 	, m_shared_dh_key(tools)
       
   117 	, m_dhe_prime(tools)
       
   118 	, m_dhe_group_generator(tools)
       
   119 	, m_kdk(tools)
       
   120 	, m_auth_key(tools)
       
   121 	, m_key_wrap_key(tools)
       
   122 	, m_EMSK(tools)
       
   123 	, m_SSID(tools)
       
   124 	, m_signed_message_hash(tools)
       
   125 	, m_NAI(tools)
       
   126 	, m_NAI_realm(tools)
       
   127 	, m_send_network_id(tools)
       
   128 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
   129 	, m_network_key(tools)
       
   130 	, m_authentication_type(simple_config_Authentication_Type_None)
       
   131 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
   132 	, m_simple_config_state(simple_config_state_wait_simple_config_start)
       
   133 	, m_handshake_error(eap_status_ok)
       
   134 	, m_UUID_E(tools)
       
   135 	, m_UUID_R(tools)
       
   136 	, m_Rf_Bands(simple_config_RF_Bands_2_4_GHz)
       
   137 	, m_MAC_address(tools)
       
   138 	, m_local_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN)
       
   139 	, m_received_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN)
       
   140 	, m_new_password(tools)
       
   141 	, m_new_Device_Password_ID(simple_config_Device_Password_ID_Default_PIN)
       
   142 	, m_error_message_received_timeout(SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_TIMEOUT)
       
   143 	, m_is_valid(false)
       
   144 	, m_is_client(is_client_when_true)
       
   145 	, m_allow_message_send(true)
       
   146 	, m_already_in_completion_action_check(false)
       
   147 	, m_pending_query_network_and_device_parameters(false)
       
   148 	, m_simple_config_test_version(false)
       
   149 	, m_key_material_generated(false)
       
   150 	, m_force_simple_config_message_send(false)
       
   151 	, m_shutdown_was_called(false)
       
   152 	, m_M2D_received_timeout_active(false)
       
   153 {
       
   154 	if (m_am_tools == 0
       
   155 		|| m_am_tools->get_is_valid() == false)
       
   156 	{
       
   157 		// No need to delete anything here because it is done in destructor.
       
   158 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   159 		return;
       
   160 	}
       
   161 
       
   162 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   163 
       
   164 	EAP_TRACE_DEBUG(
       
   165 		m_am_tools,
       
   166 		TRACE_FLAGS_DEFAULT,
       
   167 		(EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::simple_config_record_c(): ")
       
   168 		 EAPL("this = 0x%08x\n"),
       
   169 		(m_is_client == true ? "client": "server"),
       
   170 		this));
       
   171 
       
   172 	if (receive_network_id == 0
       
   173 		|| receive_network_id->get_is_valid_data() == false)
       
   174 	{
       
   175 		// No need to delete anything here because it is done in destructor.
       
   176 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   177 		return;
       
   178 	}
       
   179 
       
   180 	if (m_am_simple_config_services == 0
       
   181 		|| m_am_simple_config_services->get_is_valid() == false)
       
   182 	{
       
   183 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
   184 						(EAPL("ERROR: %s: function: simple_config_record_c::simple_config_record_c() failed,")
       
   185 						 EAPL(" m_am_simple_config_services = 0x%08x (validity %d) is invalid.\n"),
       
   186 						 (m_is_client == true ? "client": "server"),
       
   187 						 m_am_simple_config_services, (m_am_simple_config_services != 0) ? m_am_simple_config_services->get_is_valid(): false));
       
   188 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   189 		return;
       
   190 	}
       
   191 	m_am_simple_config_services->set_simple_config_am_partner(this);
       
   192 
       
   193 	// Here we swap the addresses.
       
   194 	eap_am_network_id_c send_network_id(
       
   195 		m_am_tools,
       
   196 		receive_network_id->get_destination_id(),
       
   197 		receive_network_id->get_source_id(),
       
   198 		receive_network_id->get_type());
       
   199 
       
   200 	if (send_network_id.get_is_valid() == false)
       
   201 	{
       
   202 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   203 		return;
       
   204 	}
       
   205 
       
   206 	if (m_send_network_id.get_is_valid() == false)
       
   207 	{
       
   208 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   209 		return;
       
   210 	}
       
   211 
       
   212 	eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id);
       
   213 	if (status != eap_status_ok)
       
   214 	{
       
   215 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   216 		return;
       
   217 	}
       
   218 
       
   219 	if (m_send_network_id.get_is_valid() == false
       
   220 		|| m_received_simple_config_message.get_is_valid() == false
       
   221 		|| m_received_payloads.get_is_valid() == false
       
   222 		|| m_previous_simple_config_message.get_is_valid() == false
       
   223 		|| m_new_simple_config_message.get_is_valid() == false
       
   224 		|| m_enrollee_nonce.get_is_valid() == false
       
   225 		|| m_enrollee_mac.get_is_valid() == false
       
   226 		|| m_registrar_nonce.get_is_valid() == false
       
   227 		|| m_device_password.get_is_valid() == false
       
   228 		|| m_PSK1.get_is_valid() == false
       
   229 		|| m_PSK2.get_is_valid() == false
       
   230 		|| m_E_SNonce1.get_is_valid() == false
       
   231 		|| m_E_SNonce2.get_is_valid() == false
       
   232 		|| m_EHash1.get_is_valid() == false
       
   233 		|| m_EHash2.get_is_valid() == false
       
   234 		|| m_R_SNonce1.get_is_valid() == false
       
   235 		|| m_R_SNonce2.get_is_valid() == false
       
   236 		|| m_RHash1.get_is_valid() == false
       
   237 		|| m_RHash2.get_is_valid() == false
       
   238 		|| m_own_private_dhe_key.get_is_valid() == false
       
   239 		|| m_own_public_dhe_key.get_is_valid() == false
       
   240 		|| m_peer_public_dhe_key.get_is_valid() == false
       
   241 		|| m_shared_dh_key.get_is_valid() == false
       
   242 		|| m_dhe_prime.get_is_valid() == false
       
   243 		|| m_dhe_group_generator.get_is_valid() == false
       
   244 		|| m_kdk.get_is_valid() == false
       
   245 		|| m_auth_key.get_is_valid() == false
       
   246 		|| m_key_wrap_key.get_is_valid() == false
       
   247 		|| m_EMSK.get_is_valid() == false
       
   248 		|| m_SSID.get_is_valid() == false
       
   249 		|| m_signed_message_hash.get_is_valid() == false
       
   250 		|| m_NAI.get_is_valid() == false
       
   251 		|| m_NAI_realm.get_is_valid() == false
       
   252 		|| m_send_network_id.get_is_valid() == false
       
   253 		|| m_UUID_E.get_is_valid() == false
       
   254 		|| m_UUID_R.get_is_valid() == false
       
   255 		|| m_MAC_address.get_is_valid() == false
       
   256 		|| m_new_password.get_is_valid() == false)
       
   257 	{
       
   258 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   259 		return;
       
   260 	}
       
   261 
       
   262 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
   263 	if (m_is_client == false)
       
   264 	{
       
   265 		set_state(simple_config_state_wait_M1);
       
   266 	}
       
   267 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
   268 
       
   269 	set_is_valid();
       
   270 
       
   271 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   272 }
       
   273 
       
   274 //--------------------------------------------------
       
   275 
       
   276 EAP_FUNC_EXPORT void simple_config_record_c::set_state(const simple_config_state_e state)
       
   277 {
       
   278 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   279 
       
   280 	eap_simple_config_trace_string_c state_string;
       
   281 	EAP_TRACE_DEBUG(
       
   282 		m_am_tools,
       
   283 		TRACE_FLAGS_DEFAULT,
       
   284 		(EAPL("SIMPLE_CONFIG: %s: state_function: set_state() from %s to %s\n"),
       
   285 		(m_is_client == true ? "client": "server"),
       
   286 		state_string.get_state_string(m_simple_config_state),
       
   287 		state_string.get_state_string(state)));
       
   288 
       
   289 	if (m_simple_config_state != simple_config_state_failure)
       
   290 	{
       
   291 		m_simple_config_state = state;
       
   292 	}
       
   293 
       
   294 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   295 }
       
   296 
       
   297 //--------------------------------------------------
       
   298 
       
   299 EAP_FUNC_EXPORT simple_config_state_e simple_config_record_c::get_state() const
       
   300 {
       
   301 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   302 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   303 	return m_simple_config_state;
       
   304 }
       
   305 
       
   306 //--------------------------------------------------
       
   307 
       
   308 EAP_FUNC_EXPORT bool simple_config_record_c::verify_state(const simple_config_state_e state)
       
   309 {
       
   310 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   311 
       
   312 	eap_simple_config_trace_string_c state_string;
       
   313 
       
   314 	if (m_simple_config_state == state)
       
   315 	{
       
   316 		EAP_TRACE_DEBUG(
       
   317 			m_am_tools,
       
   318 			TRACE_FLAGS_DEFAULT,
       
   319 			(EAPL("SIMPLE_CONFIG: %s: state_function: verify_state(): current state %s == %s\n"),
       
   320 			 (m_is_client == true ? "client": "server"),
       
   321 			 state_string.get_state_string(m_simple_config_state),
       
   322 			 state_string.get_state_string(state)));
       
   323 
       
   324 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   325 		return true;
       
   326 	}
       
   327 	else
       
   328 	{
       
   329 		EAP_TRACE_DEBUG(
       
   330 			m_am_tools,
       
   331 			TRACE_FLAGS_DEFAULT,
       
   332 			(EAPL("ERROR: SIMPLE_CONFIG: %s: state_function: verify_state(): current state %s != %s\n"),
       
   333 			 (m_is_client == true ? "client": "server"),
       
   334 			 state_string.get_state_string(m_simple_config_state),
       
   335 			 state_string.get_state_string(state)));
       
   336 
       
   337 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   338 		return false;
       
   339 	}
       
   340 }
       
   341 
       
   342 //--------------------------------------------------
       
   343 
       
   344 EAP_FUNC_EXPORT void simple_config_record_c::set_is_valid()
       
   345 {
       
   346 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   347 
       
   348 	m_is_valid = true;
       
   349 
       
   350 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   351 }
       
   352 
       
   353 //--------------------------------------------------
       
   354 
       
   355 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::configure()
       
   356 {
       
   357 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   358 
       
   359 	EAP_TRACE_DEBUG(
       
   360 		m_am_tools,
       
   361 		TRACE_FLAGS_DEFAULT,
       
   362 		(EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::configure(): ")
       
   363 		 EAPL("this = 0x%08x\n"),
       
   364 		(m_is_client == true ? "client": "server"),
       
   365 		this));
       
   366 
       
   367 	eap_status_e status = m_am_simple_config_services->configure();
       
   368 	if (status != eap_status_ok)
       
   369 	{
       
   370 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   371 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   372 	}
       
   373 
       
   374 	if (get_type_partner() == 0)
       
   375 	{
       
   376 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   377 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   378 	}
       
   379 
       
   380 	if (m_is_client == true)
       
   381 	{
       
   382 		// Creates Enrollee Nonce.
       
   383 		status = generate_nonce(
       
   384 			&m_enrollee_nonce,
       
   385 			SIMPLE_CONFIG_ENROLLEE_NONCE_SIZE);
       
   386 		if (status != eap_status_ok)
       
   387 		{
       
   388 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   389 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   390 		}
       
   391 	}
       
   392 	else
       
   393 	{
       
   394 		// Creates Registrar Nonce.
       
   395 		status = generate_nonce(
       
   396 			&m_registrar_nonce,
       
   397 			SIMPLE_CONFIG_REGISTRAR_NONCE_SIZE);
       
   398 		if (status != eap_status_ok)
       
   399 		{
       
   400 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   401 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   402 		}
       
   403 	}
       
   404 
       
   405 	status = generate_dhe_keys();
       
   406 	if (status != eap_status_ok)
       
   407 	{
       
   408 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   409 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   410 	}
       
   411 
       
   412 	//----------------------------------------------------------
       
   413 
       
   414 	{
       
   415 		status = get_type_partner()->read_configure(
       
   416 			cf_str_EAP_SIMPLE_CONFIG_device_password.get_field(),
       
   417 			&m_device_password);
       
   418 		if (status != eap_status_ok
       
   419 			|| m_device_password.get_is_valid_data() == false)
       
   420 		{
       
   421 			// This is mandatory value.
       
   422 			EAP_TRACE_ERROR(
       
   423 				m_am_tools,
       
   424 				TRACE_FLAGS_DEFAULT,
       
   425 				(EAPL("ERROR: SIMPLE_CONFIG: %s: simple_config_record_c::configure(): Missing device password.\n"),
       
   426 				 (m_is_client == true ? "client": "server")));
       
   427 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   428 			return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_password);
       
   429 		}
       
   430 	}
       
   431 
       
   432 	if (m_is_client == false)
       
   433 	{
       
   434 		(void) get_type_partner()->read_configure(
       
   435 			cf_str_EAP_SIMPLE_CONFIG_server_device_password.get_field(),
       
   436 			&m_device_password);
       
   437 	}
       
   438 
       
   439 	//----------------------------------------------------------
       
   440 
       
   441 	{
       
   442 		eap_variable_data_c test_version(m_am_tools);
       
   443 
       
   444 		if (test_version.get_is_valid() == false)
       
   445 		{
       
   446 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   447 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   448 		}
       
   449 
       
   450 		status = get_type_partner()->read_configure(
       
   451 			cf_str_EAP_SIMPLE_CONFIG_test_version.get_field(),
       
   452 			&test_version);
       
   453 		if (status == eap_status_ok
       
   454 			&& test_version.get_is_valid_data() == true
       
   455 			&& test_version.get_data_length() == sizeof(u32_t)
       
   456 			&& test_version.get_data(sizeof(u32_t)) != 0)
       
   457 		{
       
   458 			// This is optional value.
       
   459 			u32_t *flag = reinterpret_cast<u32_t *>(test_version.get_data(sizeof(u32_t)));
       
   460 			if (flag != 0)
       
   461 			{
       
   462 				if (*flag == 0)
       
   463 				{
       
   464 					m_simple_config_test_version = false;
       
   465 				}
       
   466 				else
       
   467 				{
       
   468 					m_simple_config_test_version = true;
       
   469 				}
       
   470 			}
       
   471 		}
       
   472 
       
   473 		status = eap_status_ok;
       
   474 	}
       
   475 
       
   476 	//----------------------------------------------------------
       
   477 
       
   478 	{
       
   479 		eap_variable_data_c error_message_received_timeout(m_am_tools);
       
   480 
       
   481 		if (error_message_received_timeout.get_is_valid() == false)
       
   482 		{
       
   483 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   484 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   485 		}
       
   486 
       
   487 		eap_status_e status = read_configure(
       
   488 			cf_str_SIMPLE_CONFIG_error_message_received_timeout.get_field(),
       
   489 			&error_message_received_timeout);
       
   490 		if (status == eap_status_ok
       
   491 			&& error_message_received_timeout.get_is_valid_data() == true)
       
   492 		{
       
   493 			u32_t *error_message_received_timeout_value = reinterpret_cast<u32_t *>(
       
   494 				error_message_received_timeout.get_data(sizeof(u32_t)));
       
   495 			if (error_message_received_timeout_value != 0)
       
   496 			{
       
   497 				m_error_message_received_timeout = *error_message_received_timeout_value;
       
   498 			}
       
   499 		}
       
   500 	}
       
   501 
       
   502 	//----------------------------------------------------------
       
   503 
       
   504 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
   505 	if (m_is_client == false)
       
   506 	{
       
   507 		{
       
   508 			// This is optional.
       
   509 			(void) read_configure(
       
   510 				cf_str_SIMPLE_CONFIG_new_password.get_field(),
       
   511 				&m_new_password);
       
   512 		}
       
   513 
       
   514 		{
       
   515 			// This is optional.
       
   516 			(void) read_configure(
       
   517 				cf_str_SIMPLE_CONFIG_network_key.get_field(),
       
   518 				&m_network_key);
       
   519 		}
       
   520 
       
   521 		{
       
   522 			eap_variable_data_c authentication_type(m_am_tools);
       
   523 
       
   524 			eap_status_e status = read_configure(
       
   525 				cf_str_SIMPLE_CONFIG_authentication_type.get_field(),
       
   526 				&authentication_type);
       
   527 			if (status == eap_status_ok
       
   528 				&& authentication_type.get_is_valid() == true
       
   529 				&& authentication_type.get_data_length() > 0ul
       
   530 				&& authentication_type.get_data(
       
   531 					authentication_type.get_data_length()) != 0)
       
   532 			{
       
   533 
       
   534 				if (cf_str_SIMPLE_CONFIG_authentication_type_None.get_field()
       
   535 					->compare(
       
   536 						m_am_tools,
       
   537 						&authentication_type) == true)
       
   538 				{
       
   539 					m_authentication_type
       
   540 						= simple_config_Authentication_Type_None;
       
   541 				}
       
   542 				else if (cf_str_SIMPLE_CONFIG_authentication_type_Open.get_field()
       
   543 						 ->compare(
       
   544 							 m_am_tools,
       
   545 							 &authentication_type) == true)
       
   546 				{
       
   547 					m_authentication_type
       
   548 						= simple_config_Authentication_Type_Open;
       
   549 				}
       
   550 				else if (cf_str_SIMPLE_CONFIG_authentication_type_WPAPSK.get_field()
       
   551 						 ->compare(
       
   552 							 m_am_tools,
       
   553 							 &authentication_type) == true)
       
   554 				{
       
   555 					m_authentication_type
       
   556 						= simple_config_Authentication_Type_WPAPSK;
       
   557 				}
       
   558 				else if (cf_str_SIMPLE_CONFIG_authentication_type_Shared.get_field()
       
   559 						 ->compare(
       
   560 							 m_am_tools,
       
   561 							 &authentication_type) == true)
       
   562 				{
       
   563 					m_authentication_type
       
   564 						= simple_config_Authentication_Type_Shared;
       
   565 				}
       
   566 				else if (cf_str_SIMPLE_CONFIG_authentication_type_WPA.get_field()
       
   567 						 ->compare(
       
   568 							 m_am_tools,
       
   569 							 &authentication_type) == true)
       
   570 				{
       
   571 					m_authentication_type
       
   572 						= simple_config_Authentication_Type_WPA;
       
   573 				}
       
   574 				else if (cf_str_SIMPLE_CONFIG_authentication_type_WPA2.get_field()
       
   575 						 ->compare(
       
   576 							 m_am_tools,
       
   577 							 &authentication_type) == true)
       
   578 				{
       
   579 					m_authentication_type
       
   580 						= simple_config_Authentication_Type_WPA2;
       
   581 				}
       
   582 				else if (cf_str_SIMPLE_CONFIG_authentication_type_WPA2PSK.get_field()
       
   583 						 ->compare(
       
   584 							 m_am_tools,
       
   585 							 &authentication_type) == true)
       
   586 				{
       
   587 					m_authentication_type
       
   588 						= simple_config_Authentication_Type_WPA2PSK;
       
   589 				}
       
   590 			}
       
   591 		}
       
   592 	}
       
   593 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
   594 
       
   595 	//----------------------------------------------------------
       
   596 
       
   597 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   598 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   599 }
       
   600 
       
   601 //--------------------------------------------------
       
   602 
       
   603 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::shutdown()
       
   604 {
       
   605 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   606 
       
   607 	EAP_TRACE_DEBUG(
       
   608 		m_am_tools,
       
   609 		TRACE_FLAGS_DEFAULT,
       
   610 		(EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::shutdown(): ")
       
   611 		 EAPL("this = 0x%08x\n"),
       
   612 		(m_is_client == true ? "client": "server"),
       
   613 		this));
       
   614 
       
   615 	if (m_shutdown_was_called == true)
       
   616 	{
       
   617 		// Shutdown function was called already.
       
   618 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   619 	}
       
   620 	m_shutdown_was_called = true;
       
   621 
       
   622 
       
   623 	// Cancel all timers.
       
   624 	cancel_error_message_timeout();
       
   625 	cancel_M2D_received_timeout();
       
   626 
       
   627 
       
   628 	if (get_state() != simple_config_state_simple_config_success)
       
   629 	{
       
   630 		set_state(simple_config_state_failure);
       
   631 	}
       
   632 
       
   633 	eap_status_e status = eap_status_ok;
       
   634 
       
   635 	if (m_pending_query_network_and_device_parameters == true)
       
   636 	{
       
   637 		EAP_TRACE_DEBUG(
       
   638 			m_am_tools,
       
   639 			TRACE_FLAGS_DEFAULT,
       
   640 			(EAPL("SIMPLE_CONFIG: function: simple_config_record_c::shutdown(): calls cancel_query_dh_parameters()\n")));
       
   641 
       
   642 		m_am_simple_config_services->cancel_query_network_and_device_parameters();
       
   643 		m_pending_query_network_and_device_parameters = false;
       
   644 	}
       
   645 
       
   646 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   647 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   648 }
       
   649 
       
   650 //--------------------------------------------------
       
   651 
       
   652 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::set_nai_realm(
       
   653 	const eap_variable_data_c * const NAI_realm)
       
   654 {
       
   655 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   656 
       
   657 	eap_status_e status = m_NAI_realm.set_copy_of_buffer(NAI_realm);
       
   658 
       
   659 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   660 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   661 }
       
   662 
       
   663 //--------------------------------------------------
       
   664 
       
   665 //
       
   666 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::completion_action_add(
       
   667 	simple_config_completion_action_e action)
       
   668 {
       
   669 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   670 
       
   671 	simple_config_completion_c *completion_action = new simple_config_completion_c(
       
   672 		m_am_tools,
       
   673 		action);
       
   674 
       
   675 	if (completion_action == 0
       
   676 		|| completion_action->get_is_valid() == false)
       
   677 	{
       
   678 		delete completion_action;
       
   679 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   680 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   681 	}
       
   682 
       
   683 	// add_object() will delete completion_action if operation fails.
       
   684 	eap_status_e status = m_completion_queue.add_object(completion_action, true);
       
   685 	if (status != eap_status_ok)
       
   686 	{
       
   687 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   688 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   689 	}
       
   690 
       
   691 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   692 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   693 					(EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_add(): action %s\n"),
       
   694 					 (m_is_client == true ? "client": "server"),
       
   695 					 completion_action->get_completion_action_string()));
       
   696 
       
   697 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   698 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   699 }
       
   700 
       
   701 //--------------------------------------------------
       
   702 
       
   703 //
       
   704 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::completion_action_clenup()
       
   705 {
       
   706 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   707 
       
   708 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   709 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   710 					(EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_clenup()\n"),
       
   711 					 (m_is_client == true ? "client": "server")));
       
   712 
       
   713 	eap_status_e final_status = eap_status_ok;
       
   714 	u32_t counter(0ul);
       
   715 
       
   716 	while(m_completion_queue.get_object_count() > 0ul)
       
   717 	{
       
   718 		simple_config_completion_c * const completion_action = m_completion_queue.get_object(0ul);
       
   719 		EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace.
       
   720 
       
   721 		EAP_TRACE_DEBUG(
       
   722 			m_am_tools,
       
   723 			TRACE_FLAGS_DEFAULT,
       
   724 			(EAPL("ERROR: SIMPLE_CONFIG: %s: send_function: completion_action_clenup(): ")
       
   725 			 EAPL("action[%u] %s not completed.\n"),
       
   726 			 (m_is_client == true ? "client": "server"),
       
   727 			 counter,
       
   728 			 completion_action->get_completion_action_string()));
       
   729 
       
   730 		final_status = m_completion_queue.remove_object(0ul);
       
   731 		if (final_status != eap_status_ok)
       
   732 		{
       
   733 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   734 			return EAP_STATUS_RETURN(m_am_tools, final_status);
       
   735 		}
       
   736 
       
   737 		++counter;
       
   738 
       
   739 	} // while()
       
   740 
       
   741 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   742 	return EAP_STATUS_RETURN(m_am_tools, final_status);
       
   743 }
       
   744 
       
   745 //--------------------------------------------------
       
   746 
       
   747 //
       
   748 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::completion_action_check()
       
   749 {
       
   750 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   751 
       
   752 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   753 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   754 					(EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_check()\n"),
       
   755 					 (m_is_client == true ? "client": "server")));
       
   756 
       
   757 	if (m_already_in_completion_action_check == true)
       
   758 	{
       
   759 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   760 		// This is recursive call of completion_action_check().
       
   761 		// This MUST return eap_status_ok. Other return values will skip
       
   762 		// further prosessing of completion action list.
       
   763 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   764 	}
       
   765 	m_already_in_completion_action_check = true;
       
   766 
       
   767 	eap_automatic_simple_value_c<bool> restore_already_in_completion_action_check(
       
   768 		m_am_tools,
       
   769 		&m_already_in_completion_action_check,
       
   770 		false);
       
   771 
       
   772 	eap_status_e status = eap_status_ok;
       
   773 	bool continue_with_next_action = true;
       
   774 	u32_t counter = 0ul;
       
   775 
       
   776 	while(continue_with_next_action == true
       
   777 		&& m_completion_queue.get_object_count() > 0ul)
       
   778 	{
       
   779 		simple_config_completion_c * const completion_action = m_completion_queue.get_object(0ul);
       
   780 		EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace.
       
   781 
       
   782 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   783 						(EAPL("SIMPLE_CONFIG: %s: send_function: completion_action_check(): action[%u] %s\n"),
       
   784 						 (m_is_client == true ? "client": "server"),
       
   785 						 counter,
       
   786 						 completion_action->get_completion_action_string()));
       
   787 
       
   788 		if (continue_with_next_action == true)
       
   789 		{
       
   790 			status = m_completion_queue.remove_object(0ul);
       
   791 			if (status != eap_status_ok)
       
   792 			{
       
   793 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   794 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   795 			}
       
   796 		}
       
   797 
       
   798 		++counter;
       
   799 
       
   800 	} // while()
       
   801 
       
   802 	if (continue_with_next_action == false)
       
   803 	{
       
   804 		status = eap_status_pending_request;
       
   805 	}
       
   806 
       
   807 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   808 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   809 }
       
   810 
       
   811 //--------------------------------------------------
       
   812 
       
   813 // This is commented in abs_simple_config_base_application_c.
       
   814 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::read_configure(
       
   815 	const eap_configuration_field_c * const field,
       
   816 	eap_variable_data_c * const data)
       
   817 {
       
   818 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   819 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   820 
       
   821 	return get_type_partner()->read_configure(
       
   822 			field,
       
   823 			data);
       
   824 }
       
   825 
       
   826 //--------------------------------------------------
       
   827 
       
   828 // This is commented in abs_simple_config_base_application_c.
       
   829 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::write_configure(
       
   830 	const eap_configuration_field_c * const field,
       
   831 	eap_variable_data_c * const data)
       
   832 {
       
   833 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   834 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   835 
       
   836 	return get_type_partner()->write_configure(
       
   837 			field,
       
   838 			data);
       
   839 }
       
   840 
       
   841 //--------------------------------------------------
       
   842 
       
   843 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::add_common_attributes(
       
   844 	simple_config_payloads_c * const payloads,
       
   845 	const simple_config_Message_Type_e message_type,
       
   846 	const bool add_enrollee_nonce,
       
   847 	const bool add_registrar_nonce)
       
   848 {
       
   849 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   850 
       
   851 	EAP_TRACE_DEBUG(
       
   852 		m_am_tools,
       
   853 		TRACE_FLAGS_DEFAULT,
       
   854 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::add_common_attributes()\n"),
       
   855 		(m_is_client == true ? "client": "server")));
       
   856 
       
   857 	if (payloads == 0
       
   858 		|| payloads->get_is_valid() == false)
       
   859 	{
       
   860 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   861 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   862 	}
       
   863 
       
   864 	if (message_type > simple_config_Message_keep_this_last)
       
   865 	{
       
   866 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   867 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   868 	}
       
   869 
       
   870 	eap_status_e status(eap_status_process_general_error);
       
   871 
       
   872 	{
       
   873 		u8_t Version[]
       
   874 			= { SIMPLE_CONFIG_VERSION };
       
   875 
       
   876 		status = payloads->copy_attribute_data(
       
   877 			simple_config_Attribute_Type_Version,
       
   878 			true,
       
   879 			Version,
       
   880 			sizeof(Version));
       
   881 		if (status != eap_status_ok)
       
   882 		{
       
   883 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   884 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   885 		}
       
   886 	}
       
   887 
       
   888 	{
       
   889 		u8_t Message_type(static_cast<u8_t>(message_type));
       
   890 
       
   891 		status = payloads->copy_attribute_data(
       
   892 			simple_config_Attribute_Type_Message_Type,
       
   893 			true,
       
   894 			&Message_type,
       
   895 			sizeof(Message_type));
       
   896 		if (status != eap_status_ok)
       
   897 		{
       
   898 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   899 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   900 		}
       
   901 		
       
   902 		// Save the type for indicating it to the lower layer in transmission
       
   903 		m_current_simple_config_message_type = message_type;
       
   904 	}
       
   905 
       
   906 	if (add_enrollee_nonce == true)
       
   907 	{
       
   908 		if (m_enrollee_nonce.get_is_valid() == false)
       
   909 		{
       
   910 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   911 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   912 		}
       
   913 
       
   914 		status = payloads->copy_attribute_data(
       
   915 			simple_config_Attribute_Type_Enrollee_Nonce,
       
   916 			true,
       
   917 			m_enrollee_nonce.get_data(),
       
   918 			m_enrollee_nonce.get_data_length());
       
   919 		if (status != eap_status_ok)
       
   920 		{
       
   921 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   922 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   923 		}
       
   924 	}
       
   925 
       
   926 	if (add_registrar_nonce == true)
       
   927 	{
       
   928 		if (m_registrar_nonce.get_is_valid() == false)
       
   929 		{
       
   930 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   931 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   932 		}
       
   933 
       
   934 		status = payloads->copy_attribute_data(
       
   935 			simple_config_Attribute_Type_Registrar_Nonce,
       
   936 			true,
       
   937 			m_registrar_nonce.get_data(),
       
   938 			m_registrar_nonce.get_data_length());
       
   939 		if (status != eap_status_ok)
       
   940 		{
       
   941 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   942 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   943 		}
       
   944 	}
       
   945 
       
   946 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   947 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   948 }
       
   949 
       
   950 //--------------------------------------------------
       
   951 
       
   952 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M1(
       
   953 	const simple_config_payloads_c * const network_and_device_parameters)
       
   954 {
       
   955 	EAP_TRACE_DEBUG(
       
   956 		m_am_tools,
       
   957 		TRACE_FLAGS_DEFAULT,
       
   958 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M1()\n"),
       
   959 		(m_is_client == true ? "client": "server")));
       
   960 
       
   961 	if (network_and_device_parameters == 0
       
   962 		|| network_and_device_parameters->get_is_valid() == false)
       
   963 	{
       
   964 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   965 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   966 	}
       
   967 
       
   968 	eap_status_e status(eap_status_process_general_error);
       
   969 
       
   970 
       
   971 	{
       
   972 		// Save Enrollee MAC.
       
   973 		status = m_enrollee_mac.set_copy_of_buffer(
       
   974 			m_send_network_id.get_source_id());
       
   975 		if (status != eap_status_ok)
       
   976 		{
       
   977 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   978 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   979 		}
       
   980 	}
       
   981 
       
   982 	
       
   983 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
   984 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
   985 
       
   986 	if (payloads == 0
       
   987 		|| payloads->get_is_valid() == false)
       
   988 	{
       
   989 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   990 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   991 	}
       
   992 
       
   993 	status = add_common_attributes(
       
   994 		payloads,
       
   995 		simple_config_Message_Type_M1,
       
   996 		false,
       
   997 		false);
       
   998 	if (status != eap_status_ok)
       
   999 	{
       
  1000 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1001 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1002 	}
       
  1003 
       
  1004 	status = payloads->copy_attribute(
       
  1005 		network_and_device_parameters,
       
  1006 		simple_config_Attribute_Type_UUID_E);
       
  1007 	if (status != eap_status_ok)
       
  1008 	{
       
  1009 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1010 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1011 	}
       
  1012 
       
  1013 	{
       
  1014 		if (m_enrollee_mac.get_is_valid() == false)
       
  1015 		{
       
  1016 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1017 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1018 		}
       
  1019 
       
  1020 		status = payloads->copy_attribute_data(
       
  1021 			simple_config_Attribute_Type_MAC_Address,
       
  1022 			true,
       
  1023 			m_enrollee_mac.get_data(),
       
  1024 			m_enrollee_mac.get_data_length());
       
  1025 		if (status != eap_status_ok)
       
  1026 		{
       
  1027 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1028 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1029 		}
       
  1030 	}
       
  1031 
       
  1032 
       
  1033 	{
       
  1034 		if (m_enrollee_nonce.get_is_valid() == false)
       
  1035 		{
       
  1036 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1037 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1038 		}
       
  1039 
       
  1040 		status = payloads->copy_attribute_data(
       
  1041 			simple_config_Attribute_Type_Enrollee_Nonce,
       
  1042 			true,
       
  1043 			m_enrollee_nonce.get_data(),
       
  1044 			m_enrollee_nonce.get_data_length());
       
  1045 		if (status != eap_status_ok)
       
  1046 		{
       
  1047 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1048 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1049 		}
       
  1050 	}
       
  1051 
       
  1052 	{
       
  1053 		if (m_own_public_dhe_key.get_is_valid() == false)
       
  1054 		{
       
  1055 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1056 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1057 		}
       
  1058 
       
  1059 		status = payloads->copy_attribute_data(
       
  1060 			simple_config_Attribute_Type_Public_Key,
       
  1061 			true,
       
  1062 			m_own_public_dhe_key.get_data(),
       
  1063 			m_own_public_dhe_key.get_data_length());
       
  1064 		if (status != eap_status_ok)
       
  1065 		{
       
  1066 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1067 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1068 		}
       
  1069 	}
       
  1070 
       
  1071 	status = payloads->copy_attribute(
       
  1072 		network_and_device_parameters,
       
  1073 		simple_config_Attribute_Type_Authentication_Type_Flags);
       
  1074 	if (status != eap_status_ok)
       
  1075 	{
       
  1076 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1077 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1078 	}
       
  1079 
       
  1080 	status = payloads->copy_attribute(
       
  1081 		network_and_device_parameters,
       
  1082 		simple_config_Attribute_Type_Encryption_Type_Flags);
       
  1083 	if (status != eap_status_ok)
       
  1084 	{
       
  1085 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1086 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1087 	}
       
  1088 
       
  1089 	status = payloads->copy_attribute(
       
  1090 		network_and_device_parameters,
       
  1091 		simple_config_Attribute_Type_Connection_Type_Flags);
       
  1092 	if (status != eap_status_ok)
       
  1093 	{
       
  1094 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1095 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1096 	}
       
  1097 
       
  1098 	status = payloads->copy_attribute(
       
  1099 		network_and_device_parameters,
       
  1100 		simple_config_Attribute_Type_Config_Methods);
       
  1101 	if (status != eap_status_ok)
       
  1102 	{
       
  1103 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1104 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1105 	}
       
  1106 
       
  1107 	status = payloads->copy_attribute(
       
  1108 		network_and_device_parameters,
       
  1109 		simple_config_Attribute_Type_Simple_Config_State);
       
  1110 	if (status != eap_status_ok)
       
  1111 	{
       
  1112 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1113 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1114 	}
       
  1115 
       
  1116 	status = payloads->copy_attribute(
       
  1117 		network_and_device_parameters,
       
  1118 		simple_config_Attribute_Type_Manufacturer);
       
  1119 	if (status != eap_status_ok)
       
  1120 	{
       
  1121 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1122 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1123 	}
       
  1124 
       
  1125 	status = payloads->copy_attribute(
       
  1126 		network_and_device_parameters,
       
  1127 		simple_config_Attribute_Type_Model_Name);
       
  1128 	if (status != eap_status_ok)
       
  1129 	{
       
  1130 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1131 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1132 	}
       
  1133 
       
  1134 	status = payloads->copy_attribute(
       
  1135 		network_and_device_parameters,
       
  1136 		simple_config_Attribute_Type_Model_Number);
       
  1137 	if (status != eap_status_ok)
       
  1138 	{
       
  1139 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1140 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1141 	}
       
  1142 
       
  1143 	status = payloads->copy_attribute(
       
  1144 		network_and_device_parameters,
       
  1145 		simple_config_Attribute_Type_Serial_Number);
       
  1146 	if (status != eap_status_ok)
       
  1147 	{
       
  1148 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1149 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1150 	}
       
  1151 
       
  1152 	status = payloads->copy_attribute(
       
  1153 		network_and_device_parameters,
       
  1154 		simple_config_Attribute_Type_Primary_Device_Type);
       
  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 
       
  1161 	status = payloads->copy_attribute(
       
  1162 		network_and_device_parameters,
       
  1163 		simple_config_Attribute_Type_Device_Name);
       
  1164 	if (status != eap_status_ok)
       
  1165 	{
       
  1166 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1167 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1168 	}
       
  1169 
       
  1170 	status = payloads->copy_attribute(
       
  1171 		network_and_device_parameters,
       
  1172 		simple_config_Attribute_Type_RF_Band);
       
  1173 	if (status != eap_status_ok)
       
  1174 	{
       
  1175 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1176 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1177 	}
       
  1178 
       
  1179 	status = payloads->copy_attribute(
       
  1180 		network_and_device_parameters,
       
  1181 		simple_config_Attribute_Type_Association_State);
       
  1182 	if (status != eap_status_ok)
       
  1183 	{
       
  1184 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1185 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1186 	}
       
  1187 
       
  1188 	status = payloads->copy_attribute(
       
  1189 		network_and_device_parameters,
       
  1190 		simple_config_Attribute_Type_Device_Password_ID);
       
  1191 	if (status != eap_status_ok)
       
  1192 	{
       
  1193 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1194 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1195 	}
       
  1196 
       
  1197 	if (payloads->get_attribute_pointer(
       
  1198 		simple_config_Attribute_Type_Configuration_Error) != 0)
       
  1199 	{
       
  1200 		status = payloads->copy_attribute(
       
  1201 			network_and_device_parameters,
       
  1202 			simple_config_Attribute_Type_Configuration_Error);
       
  1203 	}
       
  1204 	else
       
  1205 	{
       
  1206 		status = eap_status_not_found;
       
  1207 	}
       
  1208 
       
  1209 	if (status != eap_status_ok)
       
  1210 	{
       
  1211 		simple_config_Configuration_Error_e Configuration_Error(simple_config_Configuration_Error_No_Error);
       
  1212 		u16_t network_order_Configuration_Error(eap_htons(static_cast<u16_t>(Configuration_Error)));
       
  1213 
       
  1214 		status = payloads->copy_attribute_data(
       
  1215 			simple_config_Attribute_Type_Configuration_Error,
       
  1216 			true,
       
  1217 			&network_order_Configuration_Error,
       
  1218 			sizeof(network_order_Configuration_Error));
       
  1219 		if (status != eap_status_ok)
       
  1220 		{
       
  1221 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1222 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1223 		}
       
  1224 	}
       
  1225 
       
  1226 	status = payloads->copy_attribute(
       
  1227 		network_and_device_parameters,
       
  1228 		simple_config_Attribute_Type_OS_Version);
       
  1229 	if (status != eap_status_ok)
       
  1230 	{
       
  1231 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1232 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1233 	}
       
  1234 
       
  1235 
       
  1236 	if (m_new_simple_config_message.get_is_valid() == false)
       
  1237 	{
       
  1238 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1239 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1240 	}
       
  1241 
       
  1242 	status = payloads->create_simple_config_message(
       
  1243 		&m_new_simple_config_message,
       
  1244 		false);
       
  1245 	if (status != eap_status_ok)
       
  1246 	{
       
  1247 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1248 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1249 	}
       
  1250 
       
  1251 
       
  1252 	set_state(simple_config_state_wait_M2);
       
  1253 
       
  1254 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1255 }
       
  1256 
       
  1257 //--------------------------------------------------
       
  1258 
       
  1259 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  1260 
       
  1261 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M2(
       
  1262 	const simple_config_payloads_c * const network_and_device_parameters)
       
  1263 {
       
  1264 	EAP_TRACE_DEBUG(
       
  1265 		m_am_tools,
       
  1266 		TRACE_FLAGS_DEFAULT,
       
  1267 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M2()\n"),
       
  1268 		(m_is_client == true ? "client": "server")));
       
  1269 
       
  1270 	if (network_and_device_parameters == 0
       
  1271 		|| network_and_device_parameters->get_is_valid() == false)
       
  1272 	{
       
  1273 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1274 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1275 	}
       
  1276 
       
  1277 	eap_status_e status(eap_status_process_general_error);
       
  1278 	
       
  1279 
       
  1280 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  1281 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  1282 
       
  1283 	if (payloads == 0
       
  1284 		|| payloads->get_is_valid() == false)
       
  1285 	{
       
  1286 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1287 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1288 	}
       
  1289 
       
  1290 	status = add_common_attributes(
       
  1291 		payloads,
       
  1292 		simple_config_Message_Type_M2,
       
  1293 		true,
       
  1294 		true);
       
  1295 	if (status != eap_status_ok)
       
  1296 	{
       
  1297 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1298 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1299 	}
       
  1300 
       
  1301 	status = payloads->copy_attribute(
       
  1302 		network_and_device_parameters,
       
  1303 		simple_config_Attribute_Type_UUID_R);
       
  1304 	if (status != eap_status_ok)
       
  1305 	{
       
  1306 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1307 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1308 	}
       
  1309 
       
  1310 	{
       
  1311 		status = payloads->copy_attribute_data(
       
  1312 			simple_config_Attribute_Type_Public_Key,
       
  1313 			true,
       
  1314 			m_own_public_dhe_key.get_data(),
       
  1315 			m_own_public_dhe_key.get_data_length());
       
  1316 		if (status != eap_status_ok)
       
  1317 		{
       
  1318 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1319 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1320 		}
       
  1321 	}
       
  1322 
       
  1323 	status = payloads->copy_attribute(
       
  1324 		network_and_device_parameters,
       
  1325 		simple_config_Attribute_Type_Authentication_Type_Flags);
       
  1326 	if (status != eap_status_ok)
       
  1327 	{
       
  1328 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1329 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1330 	}
       
  1331 
       
  1332 	status = payloads->copy_attribute(
       
  1333 		network_and_device_parameters,
       
  1334 		simple_config_Attribute_Type_Encryption_Type_Flags);
       
  1335 	if (status != eap_status_ok)
       
  1336 	{
       
  1337 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1338 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1339 	}
       
  1340 
       
  1341 	status = payloads->copy_attribute(
       
  1342 		network_and_device_parameters,
       
  1343 		simple_config_Attribute_Type_Connection_Type_Flags);
       
  1344 	if (status != eap_status_ok)
       
  1345 	{
       
  1346 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1347 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1348 	}
       
  1349 
       
  1350 	status = payloads->copy_attribute(
       
  1351 		network_and_device_parameters,
       
  1352 		simple_config_Attribute_Type_Config_Methods);
       
  1353 	if (status != eap_status_ok)
       
  1354 	{
       
  1355 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1356 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1357 	}
       
  1358 
       
  1359 	status = payloads->copy_attribute(
       
  1360 		network_and_device_parameters,
       
  1361 		simple_config_Attribute_Type_Manufacturer);
       
  1362 	if (status != eap_status_ok)
       
  1363 	{
       
  1364 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1365 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1366 	}
       
  1367 
       
  1368 	status = payloads->copy_attribute(
       
  1369 		network_and_device_parameters,
       
  1370 		simple_config_Attribute_Type_Model_Name);
       
  1371 	if (status != eap_status_ok)
       
  1372 	{
       
  1373 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1374 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1375 	}
       
  1376 
       
  1377 	status = payloads->copy_attribute(
       
  1378 		network_and_device_parameters,
       
  1379 		simple_config_Attribute_Type_Model_Number);
       
  1380 	if (status != eap_status_ok)
       
  1381 	{
       
  1382 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1383 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1384 	}
       
  1385 
       
  1386 	status = payloads->copy_attribute(
       
  1387 		network_and_device_parameters,
       
  1388 		simple_config_Attribute_Type_Serial_Number);
       
  1389 	if (status != eap_status_ok)
       
  1390 	{
       
  1391 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1392 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1393 	}
       
  1394 
       
  1395 	status = payloads->copy_attribute(
       
  1396 		network_and_device_parameters,
       
  1397 		simple_config_Attribute_Type_Primary_Device_Type);
       
  1398 	if (status != eap_status_ok)
       
  1399 	{
       
  1400 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1401 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1402 	}
       
  1403 
       
  1404 	status = payloads->copy_attribute(
       
  1405 		network_and_device_parameters,
       
  1406 		simple_config_Attribute_Type_Device_Name);
       
  1407 	if (status != eap_status_ok)
       
  1408 	{
       
  1409 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1410 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1411 	}
       
  1412 
       
  1413 	status = payloads->copy_attribute(
       
  1414 		network_and_device_parameters,
       
  1415 		simple_config_Attribute_Type_RF_Band);
       
  1416 	if (status != eap_status_ok)
       
  1417 	{
       
  1418 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1419 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1420 	}
       
  1421 
       
  1422 	status = payloads->copy_attribute(
       
  1423 		network_and_device_parameters,
       
  1424 		simple_config_Attribute_Type_Association_State);
       
  1425 	if (status != eap_status_ok)
       
  1426 	{
       
  1427 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1428 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1429 	}
       
  1430 
       
  1431 	if (payloads->get_attribute_pointer(
       
  1432 		simple_config_Attribute_Type_Configuration_Error) != 0)
       
  1433 	{
       
  1434 		status = payloads->copy_attribute(
       
  1435 			network_and_device_parameters,
       
  1436 			simple_config_Attribute_Type_Configuration_Error);
       
  1437 	}
       
  1438 	else
       
  1439 	{
       
  1440 		status = eap_status_missing_payload;
       
  1441 	}
       
  1442 
       
  1443 	if (status != eap_status_ok)
       
  1444 	{
       
  1445 		// Because the Configuration_Error is missing there is no error.
       
  1446 		simple_config_Configuration_Error_e Configuration_Error(simple_config_Configuration_Error_No_Error);
       
  1447 		u16_t network_order_Configuration_Error(eap_htons(static_cast<u16_t>(Configuration_Error)));
       
  1448 
       
  1449 		status = payloads->copy_attribute_data(
       
  1450 			simple_config_Attribute_Type_Configuration_Error,
       
  1451 			true,
       
  1452 			&network_order_Configuration_Error,
       
  1453 			sizeof(network_order_Configuration_Error));
       
  1454 		if (status != eap_status_ok)
       
  1455 		{
       
  1456 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1457 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1458 		}
       
  1459 	}
       
  1460 
       
  1461 	status = payloads->copy_attribute(
       
  1462 		network_and_device_parameters,
       
  1463 		simple_config_Attribute_Type_Device_Password_ID);
       
  1464 	if (status != eap_status_ok)
       
  1465 	{
       
  1466 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1467 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1468 	}
       
  1469 
       
  1470 	status = payloads->copy_attribute(
       
  1471 		network_and_device_parameters,
       
  1472 		simple_config_Attribute_Type_OS_Version);
       
  1473 	if (status != eap_status_ok)
       
  1474 	{
       
  1475 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1476 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1477 	}
       
  1478 
       
  1479 
       
  1480 	if (m_new_simple_config_message.get_is_valid() == false)
       
  1481 	{
       
  1482 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1483 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1484 	}
       
  1485 
       
  1486 	status = payloads->create_simple_config_message(
       
  1487 		&m_new_simple_config_message,
       
  1488 		false);
       
  1489 	if (status != eap_status_ok)
       
  1490 	{
       
  1491 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1492 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1493 	}
       
  1494 
       
  1495 	status = add_authenticator_attribute(
       
  1496 		&m_received_simple_config_message,
       
  1497 		&m_new_simple_config_message);
       
  1498 	if (status != eap_status_ok)
       
  1499 	{
       
  1500 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1501 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1502 	}
       
  1503 
       
  1504 	set_state(simple_config_state_wait_M3);
       
  1505 
       
  1506 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1507 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1508 }
       
  1509 
       
  1510 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  1511 
       
  1512 //--------------------------------------------------
       
  1513 
       
  1514 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  1515 
       
  1516 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M2D(
       
  1517 	const simple_config_payloads_c * const network_and_device_parameters)
       
  1518 {
       
  1519 	EAP_TRACE_DEBUG(
       
  1520 		m_am_tools,
       
  1521 		TRACE_FLAGS_DEFAULT,
       
  1522 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M2D()\n"),
       
  1523 		(m_is_client == true ? "client": "server")));
       
  1524 
       
  1525 	if (network_and_device_parameters == 0
       
  1526 		|| network_and_device_parameters->get_is_valid() == false)
       
  1527 	{
       
  1528 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1529 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1530 	}
       
  1531 
       
  1532 	eap_status_e status(eap_status_process_general_error);
       
  1533 	
       
  1534 
       
  1535 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  1536 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  1537 
       
  1538 	if (payloads == 0
       
  1539 		|| payloads->get_is_valid() == false)
       
  1540 	{
       
  1541 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1542 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1543 	}
       
  1544 	
       
  1545 	status = add_common_attributes(
       
  1546 		payloads,
       
  1547 		simple_config_Message_Type_M2D,
       
  1548 		true,
       
  1549 		true);
       
  1550 	if (status != eap_status_ok)
       
  1551 	{
       
  1552 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1553 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1554 	}
       
  1555 
       
  1556 	status = payloads->copy_attribute(
       
  1557 		network_and_device_parameters,
       
  1558 		simple_config_Attribute_Type_UUID_R);
       
  1559 	if (status != eap_status_ok)
       
  1560 	{
       
  1561 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1562 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1563 	}
       
  1564 
       
  1565 	status = payloads->copy_attribute(
       
  1566 		network_and_device_parameters,
       
  1567 		simple_config_Attribute_Type_Authentication_Type_Flags);
       
  1568 	if (status != eap_status_ok)
       
  1569 	{
       
  1570 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1571 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1572 	}
       
  1573 
       
  1574 	status = payloads->copy_attribute(
       
  1575 		network_and_device_parameters,
       
  1576 		simple_config_Attribute_Type_Encryption_Type_Flags);
       
  1577 	if (status != eap_status_ok)
       
  1578 	{
       
  1579 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1580 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1581 	}
       
  1582 
       
  1583 	status = payloads->copy_attribute(
       
  1584 		network_and_device_parameters,
       
  1585 		simple_config_Attribute_Type_Connection_Type_Flags);
       
  1586 	if (status != eap_status_ok)
       
  1587 	{
       
  1588 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1589 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1590 	}
       
  1591 
       
  1592 	status = payloads->copy_attribute(
       
  1593 		network_and_device_parameters,
       
  1594 		simple_config_Attribute_Type_Config_Methods);
       
  1595 	if (status != eap_status_ok)
       
  1596 	{
       
  1597 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1598 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1599 	}
       
  1600 
       
  1601 	status = payloads->copy_attribute(
       
  1602 		network_and_device_parameters,
       
  1603 		simple_config_Attribute_Type_Manufacturer);
       
  1604 	if (status != eap_status_ok)
       
  1605 	{
       
  1606 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1607 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1608 	}
       
  1609 
       
  1610 	status = payloads->copy_attribute(
       
  1611 		network_and_device_parameters,
       
  1612 		simple_config_Attribute_Type_Model_Name);
       
  1613 	if (status != eap_status_ok)
       
  1614 	{
       
  1615 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1616 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1617 	}
       
  1618 
       
  1619 	status = payloads->copy_attribute(
       
  1620 		network_and_device_parameters,
       
  1621 		simple_config_Attribute_Type_Model_Number);
       
  1622 	if (status != eap_status_ok)
       
  1623 	{
       
  1624 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1625 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1626 	}
       
  1627 
       
  1628 	status = payloads->copy_attribute(
       
  1629 		network_and_device_parameters,
       
  1630 		simple_config_Attribute_Type_Serial_Number);
       
  1631 	if (status != eap_status_ok)
       
  1632 	{
       
  1633 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1634 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1635 	}
       
  1636 
       
  1637 	status = payloads->copy_attribute(
       
  1638 		network_and_device_parameters,
       
  1639 		simple_config_Attribute_Type_Primary_Device_Type);
       
  1640 	if (status != eap_status_ok)
       
  1641 	{
       
  1642 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1643 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1644 	}
       
  1645 
       
  1646 	status = payloads->copy_attribute(
       
  1647 		network_and_device_parameters,
       
  1648 		simple_config_Attribute_Type_Device_Name);
       
  1649 	if (status != eap_status_ok)
       
  1650 	{
       
  1651 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1652 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1653 	}
       
  1654 
       
  1655 	status = payloads->copy_attribute(
       
  1656 		network_and_device_parameters,
       
  1657 		simple_config_Attribute_Type_RF_Band);
       
  1658 	if (status != eap_status_ok)
       
  1659 	{
       
  1660 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1661 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1662 	}
       
  1663 
       
  1664 	status = payloads->copy_attribute(
       
  1665 		network_and_device_parameters,
       
  1666 		simple_config_Attribute_Type_Association_State);
       
  1667 	if (status != eap_status_ok)
       
  1668 	{
       
  1669 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1670 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1671 	}
       
  1672 
       
  1673 	if (network_and_device_parameters->get_attribute_pointer(
       
  1674 		simple_config_Attribute_Type_Configuration_Error) != 0)
       
  1675 	{
       
  1676 		status = payloads->copy_attribute(
       
  1677 			network_and_device_parameters,
       
  1678 			simple_config_Attribute_Type_Configuration_Error);
       
  1679 	}
       
  1680 	else
       
  1681 	{
       
  1682 		status = eap_status_missing_payload;
       
  1683 	}
       
  1684 
       
  1685 	if (status != eap_status_ok)
       
  1686 	{
       
  1687 		simple_config_Configuration_Error_e Configuration_Error(simple_config_Configuration_Error_No_Error);
       
  1688 		u16_t network_order_Configuration_Error(eap_htons(static_cast<u16_t>(Configuration_Error)));
       
  1689 
       
  1690 		status = payloads->copy_attribute_data(
       
  1691 			simple_config_Attribute_Type_Configuration_Error,
       
  1692 			true,
       
  1693 			&network_order_Configuration_Error,
       
  1694 			sizeof(network_order_Configuration_Error));
       
  1695 		if (status != eap_status_ok)
       
  1696 		{
       
  1697 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1698 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1699 		}
       
  1700 	}
       
  1701 
       
  1702 	status = payloads->copy_attribute(
       
  1703 		network_and_device_parameters,
       
  1704 		simple_config_Attribute_Type_OS_Version);
       
  1705 	if (status != eap_status_ok)
       
  1706 	{
       
  1707 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1708 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1709 	}
       
  1710 
       
  1711 
       
  1712 	if (m_new_simple_config_message.get_is_valid() == false)
       
  1713 	{
       
  1714 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1715 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1716 	}
       
  1717 
       
  1718 	status = payloads->create_simple_config_message(
       
  1719 		&m_new_simple_config_message,
       
  1720 		false);
       
  1721 	if (status != eap_status_ok)
       
  1722 	{
       
  1723 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1724 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1725 	}
       
  1726 
       
  1727 	set_state(simple_config_state_wait_WSC_ACK);
       
  1728 
       
  1729 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1730 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1731 }
       
  1732 
       
  1733 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  1734 
       
  1735 //--------------------------------------------------
       
  1736 
       
  1737 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M3()
       
  1738 {
       
  1739 	EAP_TRACE_DEBUG(
       
  1740 		m_am_tools,
       
  1741 		TRACE_FLAGS_DEFAULT,
       
  1742 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M3()\n"),
       
  1743 		(m_is_client == true ? "client": "server")));
       
  1744 
       
  1745 	eap_status_e status(eap_status_process_general_error);
       
  1746 
       
  1747 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1748 
       
  1749 	// Create HASHs
       
  1750 	status = generate_er_hashs(
       
  1751 		false,
       
  1752 		&m_device_password,
       
  1753 		&m_own_public_dhe_key,
       
  1754 		&m_peer_public_dhe_key,
       
  1755 		&m_PSK1,
       
  1756 		&m_E_SNonce1,
       
  1757 		&m_EHash1,
       
  1758 		&m_PSK2,
       
  1759 		&m_E_SNonce2,
       
  1760 		&m_EHash2);
       
  1761 	if (status != eap_status_ok)
       
  1762 	{
       
  1763 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1764 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1765 	}
       
  1766 
       
  1767 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1768 
       
  1769 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  1770 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  1771 
       
  1772 	if (payloads == 0
       
  1773 		|| payloads->get_is_valid() == false)
       
  1774 	{
       
  1775 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1776 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1777 	}
       
  1778 	
       
  1779 	status = add_common_attributes(
       
  1780 		payloads,
       
  1781 		simple_config_Message_Type_M3,
       
  1782 		false,
       
  1783 		true);
       
  1784 	if (status != eap_status_ok)
       
  1785 	{
       
  1786 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1787 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1788 	}
       
  1789 
       
  1790 	status = payloads->copy_attribute_data(
       
  1791 		simple_config_Attribute_Type_E_Hash1,
       
  1792 		true,
       
  1793 		m_EHash1.get_data(),
       
  1794 		m_EHash1.get_data_length());
       
  1795 	if (status != eap_status_ok)
       
  1796 	{
       
  1797 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1798 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1799 	}
       
  1800 
       
  1801 	status = payloads->copy_attribute_data(
       
  1802 		simple_config_Attribute_Type_E_Hash2,
       
  1803 		true,
       
  1804 		m_EHash2.get_data(),
       
  1805 		m_EHash2.get_data_length());
       
  1806 	if (status != eap_status_ok)
       
  1807 	{
       
  1808 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1809 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1810 	}
       
  1811 
       
  1812 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1813 
       
  1814 	if (m_new_simple_config_message.get_is_valid() == false)
       
  1815 	{
       
  1816 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1817 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1818 	}
       
  1819 
       
  1820 	status = payloads->create_simple_config_message(
       
  1821 		&m_new_simple_config_message,
       
  1822 		false);
       
  1823 	if (status != eap_status_ok)
       
  1824 	{
       
  1825 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1826 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1827 	}
       
  1828 
       
  1829 	status = add_authenticator_attribute(
       
  1830 		&m_received_simple_config_message,
       
  1831 		&m_new_simple_config_message);
       
  1832 	if (status != eap_status_ok)
       
  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 	set_state(simple_config_state_wait_M4);
       
  1841 
       
  1842 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1843 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1844 }
       
  1845 
       
  1846 //--------------------------------------------------
       
  1847 
       
  1848 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  1849 
       
  1850 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M4()
       
  1851 {
       
  1852 	EAP_TRACE_DEBUG(
       
  1853 		m_am_tools,
       
  1854 		TRACE_FLAGS_DEFAULT,
       
  1855 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M4()\n"),
       
  1856 		(m_is_client == true ? "client": "server")));
       
  1857 
       
  1858 	eap_status_e status(eap_status_process_general_error);
       
  1859 
       
  1860 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1861 
       
  1862 	// Create HASHs
       
  1863 	status = generate_er_hashs(
       
  1864 		false,
       
  1865 		&m_device_password,
       
  1866 		&m_peer_public_dhe_key,
       
  1867 		&m_own_public_dhe_key,
       
  1868 		&m_PSK1,
       
  1869 		&m_R_SNonce1,
       
  1870 		&m_RHash1,
       
  1871 		&m_PSK2,
       
  1872 		&m_R_SNonce2,
       
  1873 		&m_RHash2);
       
  1874 	if (status != eap_status_ok)
       
  1875 	{
       
  1876 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1877 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1878 	}
       
  1879 
       
  1880 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1881 
       
  1882 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  1883 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  1884 
       
  1885 	if (payloads == 0
       
  1886 		|| payloads->get_is_valid() == false)
       
  1887 	{
       
  1888 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1889 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1890 	}
       
  1891 	
       
  1892 	status = add_common_attributes(
       
  1893 		payloads,
       
  1894 		simple_config_Message_Type_M4,
       
  1895 		true,
       
  1896 		false);
       
  1897 	if (status != eap_status_ok)
       
  1898 	{
       
  1899 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1900 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1901 	}
       
  1902 
       
  1903 	status = payloads->copy_attribute_data(
       
  1904 		simple_config_Attribute_Type_R_Hash1,
       
  1905 		true,
       
  1906 		m_RHash1.get_data(),
       
  1907 		m_RHash1.get_data_length());
       
  1908 	if (status != eap_status_ok)
       
  1909 	{
       
  1910 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1911 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1912 	}
       
  1913 
       
  1914 	status = payloads->copy_attribute_data(
       
  1915 		simple_config_Attribute_Type_R_Hash2,
       
  1916 		true,
       
  1917 		m_RHash2.get_data(),
       
  1918 		m_RHash2.get_data_length());
       
  1919 	if (status != eap_status_ok)
       
  1920 	{
       
  1921 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1922 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1923 	}
       
  1924 
       
  1925 
       
  1926 	simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools);
       
  1927 	eap_automatic_variable_c<simple_config_variable_data_c> automatic_encrypted_settings(m_am_tools, encrypted_settings);
       
  1928 
       
  1929 	if (encrypted_settings == 0
       
  1930 		|| encrypted_settings->get_is_valid() == false)
       
  1931 	{
       
  1932 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1933 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1934 	}
       
  1935 
       
  1936 	{
       
  1937 		// Create Encrypted Settings.
       
  1938 		// This one includes R-SNonce1 (R-S1).
       
  1939 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  1940 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  1941 
       
  1942 		if (plaintext_payloads == 0
       
  1943 			|| plaintext_payloads->get_is_valid() == false)
       
  1944 		{
       
  1945 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1946 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1947 		}
       
  1948 
       
  1949 		status = plaintext_payloads->copy_attribute_data(
       
  1950 			simple_config_Attribute_Type_R_SNonce1,
       
  1951 			true,
       
  1952 			m_R_SNonce1.get_data(),
       
  1953 			m_R_SNonce1.get_data_length());
       
  1954 		if (status != eap_status_ok)
       
  1955 		{
       
  1956 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1957 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1958 		}
       
  1959 
       
  1960 		status = encrypt_payloads(
       
  1961 			&m_auth_key,
       
  1962 			&m_key_wrap_key,
       
  1963 			plaintext_payloads,
       
  1964 			encrypted_settings);
       
  1965 		if (status != eap_status_ok)
       
  1966 		{
       
  1967 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1968 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1969 		}
       
  1970 	}
       
  1971 
       
  1972 	automatic_encrypted_settings.do_not_free_variable();
       
  1973 
       
  1974 	status = payloads->add_attribute(
       
  1975 		encrypted_settings);
       
  1976 	if (status != eap_status_ok)
       
  1977 	{
       
  1978 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1979 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1980 	}
       
  1981 
       
  1982 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1983 
       
  1984 	if (m_new_simple_config_message.get_is_valid() == false)
       
  1985 	{
       
  1986 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1987 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1988 	}
       
  1989 
       
  1990 	status = payloads->create_simple_config_message(
       
  1991 		&m_new_simple_config_message,
       
  1992 		false);
       
  1993 	if (status != eap_status_ok)
       
  1994 	{
       
  1995 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1996 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1997 	}
       
  1998 
       
  1999 	status = add_authenticator_attribute(
       
  2000 		&m_received_simple_config_message,
       
  2001 		&m_new_simple_config_message);
       
  2002 	if (status != eap_status_ok)
       
  2003 	{
       
  2004 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2005 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2006 	}
       
  2007 
       
  2008 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2009 
       
  2010 	set_state(simple_config_state_wait_M5);
       
  2011 
       
  2012 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2013 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2014 }
       
  2015 
       
  2016 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  2017 
       
  2018 //--------------------------------------------------
       
  2019 
       
  2020 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M5()
       
  2021 {
       
  2022 	EAP_TRACE_DEBUG(
       
  2023 		m_am_tools,
       
  2024 		TRACE_FLAGS_DEFAULT,
       
  2025 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5()\n"),
       
  2026 		(m_is_client == true ? "client": "server")));
       
  2027 
       
  2028 	eap_status_e status(eap_status_process_general_error);
       
  2029 
       
  2030 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2031 
       
  2032 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2033 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2034 
       
  2035 	if (payloads == 0
       
  2036 		|| payloads->get_is_valid() == false)
       
  2037 	{
       
  2038 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2039 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2040 	}
       
  2041 	
       
  2042 	EAP_TRACE_DEBUG(
       
  2043 		m_am_tools,
       
  2044 		TRACE_FLAGS_DEFAULT,
       
  2045 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls add_common_attributes()\n"),
       
  2046 		(m_is_client == true ? "client": "server")));
       
  2047 
       
  2048 	status = add_common_attributes(
       
  2049 		payloads,
       
  2050 		simple_config_Message_Type_M5,
       
  2051 		false,
       
  2052 		true);
       
  2053 	if (status != eap_status_ok)
       
  2054 	{
       
  2055 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2056 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2057 	}
       
  2058 
       
  2059 
       
  2060 	simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools);
       
  2061 	eap_automatic_variable_c<simple_config_variable_data_c> automatic_encrypted_settings(m_am_tools, encrypted_settings);
       
  2062 
       
  2063 	if (encrypted_settings == 0
       
  2064 		|| encrypted_settings->get_is_valid() == false)
       
  2065 	{
       
  2066 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2067 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2068 	}
       
  2069 
       
  2070 	{
       
  2071 		// Create Encrypted Settings.
       
  2072 		// This one includes E-SNonce1 (E-S1).
       
  2073 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  2074 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  2075 
       
  2076 		if (plaintext_payloads == 0
       
  2077 			|| plaintext_payloads->get_is_valid() == false)
       
  2078 		{
       
  2079 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2080 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2081 		}
       
  2082 
       
  2083 		EAP_TRACE_DEBUG(
       
  2084 			m_am_tools,
       
  2085 			TRACE_FLAGS_DEFAULT,
       
  2086 			(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls copy_attribute_data()\n"),
       
  2087 			(m_is_client == true ? "client": "server")));
       
  2088 
       
  2089 		status = plaintext_payloads->copy_attribute_data(
       
  2090 			simple_config_Attribute_Type_E_SNonce1,
       
  2091 			true,
       
  2092 			m_E_SNonce1.get_data(),
       
  2093 			m_E_SNonce1.get_data_length());
       
  2094 		if (status != eap_status_ok)
       
  2095 		{
       
  2096 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2097 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2098 		}
       
  2099 
       
  2100 		EAP_TRACE_DEBUG(
       
  2101 			m_am_tools,
       
  2102 			TRACE_FLAGS_DEFAULT,
       
  2103 			(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls encrypt_payloads()\n"),
       
  2104 			(m_is_client == true ? "client": "server")));
       
  2105 
       
  2106 		status = encrypt_payloads(
       
  2107 			&m_auth_key,
       
  2108 			&m_key_wrap_key,
       
  2109 			plaintext_payloads,
       
  2110 			encrypted_settings);
       
  2111 		if (status != eap_status_ok)
       
  2112 		{
       
  2113 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2114 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2115 		}
       
  2116 	}
       
  2117 
       
  2118 	EAP_TRACE_DEBUG(
       
  2119 		m_am_tools,
       
  2120 		TRACE_FLAGS_DEFAULT,
       
  2121 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls payloads.add_attribute()\n"),
       
  2122 		(m_is_client == true ? "client": "server")));
       
  2123 
       
  2124 	automatic_encrypted_settings.do_not_free_variable();
       
  2125 
       
  2126 	status = payloads->add_attribute(
       
  2127 		encrypted_settings);
       
  2128 	if (status != eap_status_ok)
       
  2129 	{
       
  2130 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2131 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2132 	}
       
  2133 
       
  2134 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2135 
       
  2136 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2137 	{
       
  2138 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2139 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2140 	}
       
  2141 
       
  2142 	EAP_TRACE_DEBUG(
       
  2143 		m_am_tools,
       
  2144 		TRACE_FLAGS_DEFAULT,
       
  2145 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls payloads.create_simple_config_message()\n"),
       
  2146 		(m_is_client == true ? "client": "server")));
       
  2147 
       
  2148 	status = payloads->create_simple_config_message(
       
  2149 		&m_new_simple_config_message,
       
  2150 		false);
       
  2151 	if (status != eap_status_ok)
       
  2152 	{
       
  2153 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2154 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2155 	}
       
  2156 
       
  2157 	EAP_TRACE_DEBUG(
       
  2158 		m_am_tools,
       
  2159 		TRACE_FLAGS_DEFAULT,
       
  2160 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls m_received_simple_config_message.get_is_valid()\n"),
       
  2161 		(m_is_client == true ? "client": "server")));
       
  2162 
       
  2163 	if (m_received_simple_config_message.get_is_valid() == false)
       
  2164 	{
       
  2165 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2166 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2167 	}
       
  2168 
       
  2169 	EAP_TRACE_DEBUG(
       
  2170 		m_am_tools,
       
  2171 		TRACE_FLAGS_DEFAULT,
       
  2172 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls m_new_simple_config_message.get_is_valid()\n"),
       
  2173 		(m_is_client == true ? "client": "server")));
       
  2174 
       
  2175 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2176 	{
       
  2177 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2178 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2179 	}
       
  2180 
       
  2181 	EAP_TRACE_DEBUG(
       
  2182 		m_am_tools,
       
  2183 		TRACE_FLAGS_DEFAULT,
       
  2184 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): calls add_authenticator_attribute()\n"),
       
  2185 		(m_is_client == true ? "client": "server")));
       
  2186 
       
  2187 	status = add_authenticator_attribute(
       
  2188 		&m_received_simple_config_message,
       
  2189 		&m_new_simple_config_message);
       
  2190 	if (status != eap_status_ok)
       
  2191 	{
       
  2192 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2193 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2194 	}
       
  2195 
       
  2196 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2197 
       
  2198 	set_state(simple_config_state_wait_M6);
       
  2199 
       
  2200 	EAP_TRACE_DEBUG(
       
  2201 		m_am_tools,
       
  2202 		TRACE_FLAGS_DEFAULT,
       
  2203 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M5(): returns\n"),
       
  2204 		(m_is_client == true ? "client": "server")));
       
  2205 
       
  2206 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2207 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2208 }
       
  2209 
       
  2210 //--------------------------------------------------
       
  2211 
       
  2212 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  2213 
       
  2214 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M6()
       
  2215 {
       
  2216 	EAP_TRACE_DEBUG(
       
  2217 		m_am_tools,
       
  2218 		TRACE_FLAGS_DEFAULT,
       
  2219 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M6()\n"),
       
  2220 		(m_is_client == true ? "client": "server")));
       
  2221 
       
  2222 	eap_status_e status(eap_status_process_general_error);
       
  2223 
       
  2224 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2225 
       
  2226 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2227 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2228 
       
  2229 	if (payloads == 0
       
  2230 		|| payloads->get_is_valid() == false)
       
  2231 	{
       
  2232 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2233 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2234 	}
       
  2235 
       
  2236 	status = add_common_attributes(
       
  2237 		payloads,
       
  2238 		simple_config_Message_Type_M6,
       
  2239 		true,
       
  2240 		false);
       
  2241 	if (status != eap_status_ok)
       
  2242 	{
       
  2243 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2244 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2245 	}
       
  2246 
       
  2247 	simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools);
       
  2248 	eap_automatic_variable_c<simple_config_variable_data_c> automatic_encrypted_settings(m_am_tools, encrypted_settings);
       
  2249 
       
  2250 	if (encrypted_settings == 0
       
  2251 		|| encrypted_settings->get_is_valid() == false)
       
  2252 	{
       
  2253 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2254 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2255 	}
       
  2256 
       
  2257 	{
       
  2258 		// Create Encrypted Settings.
       
  2259 		// This one includes R-SNonce2 (R-S2).
       
  2260 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  2261 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  2262 
       
  2263 		if (plaintext_payloads == 0
       
  2264 			|| plaintext_payloads->get_is_valid() == false)
       
  2265 		{
       
  2266 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2267 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2268 		}
       
  2269 
       
  2270 		status = plaintext_payloads->copy_attribute_data(
       
  2271 			simple_config_Attribute_Type_R_SNonce2,
       
  2272 			true,
       
  2273 			m_R_SNonce2.get_data(),
       
  2274 			m_R_SNonce2.get_data_length());
       
  2275 		if (status != eap_status_ok)
       
  2276 		{
       
  2277 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2278 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2279 		}
       
  2280 
       
  2281 		status = encrypt_payloads(
       
  2282 			&m_auth_key,
       
  2283 			&m_key_wrap_key,
       
  2284 			plaintext_payloads,
       
  2285 			encrypted_settings);
       
  2286 		if (status != eap_status_ok)
       
  2287 		{
       
  2288 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2289 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2290 		}
       
  2291 	}
       
  2292 
       
  2293 	automatic_encrypted_settings.do_not_free_variable();
       
  2294 
       
  2295 	status = payloads->add_attribute(
       
  2296 		encrypted_settings);
       
  2297 	if (status != eap_status_ok)
       
  2298 	{
       
  2299 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2300 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2301 	}
       
  2302 
       
  2303 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2304 
       
  2305 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2306 	{
       
  2307 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2308 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2309 	}
       
  2310 
       
  2311 	status = payloads->create_simple_config_message(
       
  2312 		&m_new_simple_config_message,
       
  2313 		false);
       
  2314 	if (status != eap_status_ok)
       
  2315 	{
       
  2316 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2317 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2318 	}
       
  2319 
       
  2320 	status = add_authenticator_attribute(
       
  2321 		&m_received_simple_config_message,
       
  2322 		&m_new_simple_config_message);
       
  2323 	if (status != eap_status_ok)
       
  2324 	{
       
  2325 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2326 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2327 	}
       
  2328 
       
  2329 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2330 
       
  2331 	set_state(simple_config_state_wait_M7);
       
  2332 
       
  2333 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2334 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2335 }
       
  2336 
       
  2337 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  2338 
       
  2339 //--------------------------------------------------
       
  2340 
       
  2341 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M7()
       
  2342 {
       
  2343 	EAP_TRACE_DEBUG(
       
  2344 		m_am_tools,
       
  2345 		TRACE_FLAGS_DEFAULT,
       
  2346 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M7()\n"),
       
  2347 		(m_is_client == true ? "client": "server")));
       
  2348 
       
  2349 	eap_status_e status(eap_status_process_general_error);
       
  2350 
       
  2351 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2352 
       
  2353 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2354 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2355 
       
  2356 	if (payloads == 0
       
  2357 		|| payloads->get_is_valid() == false)
       
  2358 	{
       
  2359 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2360 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2361 	}
       
  2362 
       
  2363 	status = add_common_attributes(
       
  2364 		payloads,
       
  2365 		simple_config_Message_Type_M7,
       
  2366 		false,
       
  2367 		true);
       
  2368 	if (status != eap_status_ok)
       
  2369 	{
       
  2370 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2371 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2372 	}
       
  2373 
       
  2374 
       
  2375 	simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools);
       
  2376 	eap_automatic_variable_c<simple_config_variable_data_c> automatic_encrypted_settings(m_am_tools, encrypted_settings);
       
  2377 
       
  2378 	if (encrypted_settings == 0
       
  2379 		|| encrypted_settings->get_is_valid() == false)
       
  2380 	{
       
  2381 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2382 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2383 	}
       
  2384 
       
  2385 
       
  2386 	{
       
  2387 		// Create Encrypted Settings.
       
  2388 		// This one includes E-SNonce2 (E-S2).
       
  2389 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  2390 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  2391 
       
  2392 		if (plaintext_payloads == 0
       
  2393 			|| plaintext_payloads->get_is_valid() == false)
       
  2394 		{
       
  2395 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2396 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2397 		}
       
  2398 
       
  2399 		status = plaintext_payloads->copy_attribute_data(
       
  2400 			simple_config_Attribute_Type_E_SNonce2,
       
  2401 			true,
       
  2402 			m_E_SNonce2.get_data(),
       
  2403 			m_E_SNonce2.get_data_length());
       
  2404 		if (status != eap_status_ok)
       
  2405 		{
       
  2406 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2407 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2408 		}
       
  2409 
       
  2410 		status = encrypt_payloads(
       
  2411 			&m_auth_key,
       
  2412 			&m_key_wrap_key,
       
  2413 			plaintext_payloads,
       
  2414 			encrypted_settings);
       
  2415 		if (status != eap_status_ok)
       
  2416 		{
       
  2417 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2418 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2419 		}
       
  2420 	}
       
  2421 
       
  2422 	automatic_encrypted_settings.do_not_free_variable();
       
  2423 
       
  2424 	status = payloads->add_attribute(
       
  2425 		encrypted_settings);
       
  2426 	if (status != eap_status_ok)
       
  2427 	{
       
  2428 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2429 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2430 	}
       
  2431 
       
  2432 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2433 
       
  2434 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2435 	{
       
  2436 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2437 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2438 	}
       
  2439 
       
  2440 	status = payloads->create_simple_config_message(
       
  2441 		&m_new_simple_config_message,
       
  2442 		false);
       
  2443 	if (status != eap_status_ok)
       
  2444 	{
       
  2445 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2446 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2447 	}
       
  2448 
       
  2449 	status = add_authenticator_attribute(
       
  2450 		&m_received_simple_config_message,
       
  2451 		&m_new_simple_config_message);
       
  2452 	if (status != eap_status_ok)
       
  2453 	{
       
  2454 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2455 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2456 	}
       
  2457 
       
  2458 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2459 
       
  2460 	set_state(simple_config_state_wait_M8);
       
  2461 
       
  2462 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2463 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2464 }
       
  2465 
       
  2466 //--------------------------------------------------
       
  2467 
       
  2468 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  2469 
       
  2470 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_M8()
       
  2471 {
       
  2472 	EAP_TRACE_DEBUG(
       
  2473 		m_am_tools,
       
  2474 		TRACE_FLAGS_DEFAULT,
       
  2475 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_M8()\n"),
       
  2476 		(m_is_client == true ? "client": "server")));
       
  2477 
       
  2478 	eap_status_e status(eap_status_process_general_error);
       
  2479 
       
  2480 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2481 
       
  2482 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2483 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2484 
       
  2485 	if (payloads == 0
       
  2486 		|| payloads->get_is_valid() == false)
       
  2487 	{
       
  2488 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2489 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2490 	}
       
  2491 	
       
  2492 	status = add_common_attributes(
       
  2493 		payloads,
       
  2494 		simple_config_Message_Type_M8,
       
  2495 		true,
       
  2496 		false);
       
  2497 	if (status != eap_status_ok)
       
  2498 	{
       
  2499 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2500 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2501 	}
       
  2502 
       
  2503 
       
  2504 	simple_config_variable_data_c * encrypted_settings = new simple_config_variable_data_c(m_am_tools);
       
  2505 	eap_automatic_variable_c<simple_config_variable_data_c> automatic_encrypted_settings(m_am_tools, encrypted_settings);
       
  2506 
       
  2507 	if (encrypted_settings == 0
       
  2508 		|| encrypted_settings->get_is_valid() == false)
       
  2509 	{
       
  2510 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2511 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2512 	}
       
  2513 
       
  2514 	// Create Encrypted Settings.
       
  2515 	{
       
  2516 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  2517 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  2518 
       
  2519 		if (plaintext_payloads == 0
       
  2520 			|| plaintext_payloads->get_is_valid() == false)
       
  2521 		{
       
  2522 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2523 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2524 		}
       
  2525 
       
  2526 		// Create Credential attribute
       
  2527 		{
       
  2528 			u32_t SIMPLE_CONFIG_TEST_CREDENTIAL_COUNT = 2ul;
       
  2529 
       
  2530 			for (u32_t ind = 0ul; ind < SIMPLE_CONFIG_TEST_CREDENTIAL_COUNT; ind++)
       
  2531 			{
       
  2532 				simple_config_payloads_c * credential_payloads = new simple_config_payloads_c(m_am_tools);
       
  2533 				eap_automatic_variable_c<simple_config_payloads_c> automatic_credential_payloads(m_am_tools, credential_payloads);
       
  2534 
       
  2535 				if (credential_payloads == 0
       
  2536 					|| credential_payloads->get_is_valid() == false)
       
  2537 				{
       
  2538 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2539 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2540 				}
       
  2541 
       
  2542 
       
  2543 				{
       
  2544 					u8_t network_index(static_cast<u8_t>(ind+SIMPLE_CONFIG_DEFAULT_NETWORK_KEY_INDEX));
       
  2545 
       
  2546 					status = credential_payloads->copy_attribute_data(
       
  2547 						simple_config_Attribute_Type_Network_Index,
       
  2548 						true,
       
  2549 						&network_index,
       
  2550 						sizeof(network_index));
       
  2551 					if (status != eap_status_ok)
       
  2552 					{
       
  2553 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2554 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2555 					}
       
  2556 
       
  2557 					status = credential_payloads->copy_attribute_data(
       
  2558 						simple_config_Attribute_Type_SSID,
       
  2559 						true,
       
  2560 						m_SSID.get_data(),
       
  2561 						m_SSID.get_data_length());
       
  2562 					if (status != eap_status_ok)
       
  2563 					{
       
  2564 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2565 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2566 					}
       
  2567 
       
  2568 					{
       
  2569 						u16_t network_order_Authentication_Type(eap_htons(static_cast<u16_t>(m_authentication_type)));
       
  2570 
       
  2571 						status = credential_payloads->copy_attribute_data(
       
  2572 							simple_config_Attribute_Type_Authentication_Type,
       
  2573 							true,
       
  2574 							&network_order_Authentication_Type,
       
  2575 							sizeof(network_order_Authentication_Type));
       
  2576 						if (status != eap_status_ok)
       
  2577 						{
       
  2578 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2579 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2580 						}
       
  2581 					}
       
  2582 
       
  2583 					{
       
  2584 						u16_t network_order_Encryption_Type(eap_htons(static_cast<u16_t>(simple_config_Encryption_Type_AES)));
       
  2585 
       
  2586 						status = credential_payloads->copy_attribute_data(
       
  2587 							simple_config_Attribute_Type_Encryption_Type,
       
  2588 							true,
       
  2589 							&network_order_Encryption_Type,
       
  2590 							sizeof(network_order_Encryption_Type));
       
  2591 						if (status != eap_status_ok)
       
  2592 						{
       
  2593 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2594 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2595 						}
       
  2596 					}
       
  2597 
       
  2598 
       
  2599 					// Creates some test data.
       
  2600 					eap_array_c<network_key_and_index_c> * network_keys = new eap_array_c<network_key_and_index_c>(m_am_tools);
       
  2601 					eap_automatic_variable_c<eap_array_c<network_key_and_index_c> > automatic_network_keys(m_am_tools, network_keys);
       
  2602 					
       
  2603 					if (network_keys == 0)
       
  2604 					{
       
  2605 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2606 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2607 					}
       
  2608 
       
  2609 					{
       
  2610 						const u32_t MAX_COUNT_OF_KEYS = 3ul;
       
  2611 
       
  2612 						for (u32_t ind = 0ul; ind < MAX_COUNT_OF_KEYS; ++ind)
       
  2613 						{
       
  2614 							network_key_and_index_c * const obj = new network_key_and_index_c(m_am_tools);
       
  2615 
       
  2616 							if (obj != 0)
       
  2617 							{
       
  2618 								u8_t network_key_index(static_cast<u8_t>(ind));
       
  2619 
       
  2620 								obj->set_network_key_index(network_key_index);
       
  2621 
       
  2622 								status = obj->get_network_key()->set_copy_of_buffer(
       
  2623 									&m_network_key);
       
  2624 								if (status != eap_status_ok)
       
  2625 								{
       
  2626 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2627 									return EAP_STATUS_RETURN(m_am_tools, status);
       
  2628 								}
       
  2629 
       
  2630 								status = network_keys->add_object(obj, true);
       
  2631 								if (status != eap_status_ok)
       
  2632 								{
       
  2633 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2634 									return EAP_STATUS_RETURN(m_am_tools, status);
       
  2635 								}
       
  2636 							}
       
  2637 						}
       
  2638 					}
       
  2639 
       
  2640 					{
       
  2641 						for (u32_t ind = 0ul; ind < network_keys->get_object_count(); ++ind)
       
  2642 						{
       
  2643 							network_key_and_index_c * const obj = network_keys->get_object(ind);
       
  2644 
       
  2645 							if (obj != 0)
       
  2646 							{
       
  2647 								u8_t network_key_index(obj->get_network_key_index());
       
  2648 
       
  2649 								status = credential_payloads->copy_attribute_data(
       
  2650 									simple_config_Attribute_Type_Network_Key_Index,
       
  2651 									true,
       
  2652 									&network_key_index,
       
  2653 									sizeof(network_key_index));
       
  2654 								if (status != eap_status_ok)
       
  2655 								{
       
  2656 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2657 									return EAP_STATUS_RETURN(m_am_tools, status);
       
  2658 								}
       
  2659 
       
  2660 								status = credential_payloads->copy_attribute_data(
       
  2661 									simple_config_Attribute_Type_Network_Key,
       
  2662 									true,
       
  2663 									obj->get_network_key()->get_data(),
       
  2664 									obj->get_network_key()->get_data_length());
       
  2665 								if (status != eap_status_ok)
       
  2666 								{
       
  2667 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2668 									return EAP_STATUS_RETURN(m_am_tools, status);
       
  2669 								}
       
  2670 							}
       
  2671 						}
       
  2672 					}
       
  2673 
       
  2674 					status = credential_payloads->copy_attribute_data(
       
  2675 						simple_config_Attribute_Type_MAC_Address,
       
  2676 						true,
       
  2677 						m_MAC_address.get_data(),
       
  2678 						m_MAC_address.get_data_length());
       
  2679 					if (status != eap_status_ok)
       
  2680 					{
       
  2681 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2682 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2683 					}
       
  2684 
       
  2685 				}
       
  2686 
       
  2687 				simple_config_message_c * credential_data = new simple_config_message_c(m_am_tools, m_is_client);
       
  2688 				eap_automatic_variable_c<simple_config_message_c> automatic_credential_data(m_am_tools, credential_data);
       
  2689 
       
  2690 				if (credential_data == 0
       
  2691 					|| credential_data->get_is_valid() == false)
       
  2692 				{
       
  2693 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2694 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2695 				}
       
  2696 
       
  2697 
       
  2698 				status = credential_payloads->create_simple_config_message(
       
  2699 					credential_data,
       
  2700 					false);
       
  2701 				if (status != eap_status_ok)
       
  2702 				{
       
  2703 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2704 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2705 				}
       
  2706 
       
  2707 				status = plaintext_payloads->copy_attribute_data(
       
  2708 					simple_config_Attribute_Type_Credential,
       
  2709 					true,
       
  2710 					credential_data->get_simple_config_message_data()->get_data(),
       
  2711 					credential_data->get_simple_config_message_data()->get_data_length());
       
  2712 				if (status != eap_status_ok)
       
  2713 				{
       
  2714 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2715 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2716 				}
       
  2717 			}
       
  2718 
       
  2719 			// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2720 			// Add other optional encrypted attributes.
       
  2721 
       
  2722 			if (m_new_password.get_is_valid_data() == true)
       
  2723 			{
       
  2724 				status = plaintext_payloads->copy_attribute_data(
       
  2725 					simple_config_Attribute_Type_New_Password,
       
  2726 					true,
       
  2727 					m_new_password.get_data(),
       
  2728 					m_new_password.get_data_length());
       
  2729 				if (status != eap_status_ok)
       
  2730 				{
       
  2731 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2732 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2733 				}
       
  2734 
       
  2735 				{
       
  2736 					u16_t device_password_id(static_cast<u16_t>(simple_config_Device_Password_ID_Default_PIN));
       
  2737 					u16_t network_order_device_password_id(eap_htons(device_password_id));
       
  2738 
       
  2739 					status = plaintext_payloads->copy_attribute_data(
       
  2740 						simple_config_Attribute_Type_Device_Password_ID,
       
  2741 						true,
       
  2742 						&network_order_device_password_id,
       
  2743 						sizeof(network_order_device_password_id));
       
  2744 					if (status != eap_status_ok)
       
  2745 					{
       
  2746 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2747 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2748 					}
       
  2749 				}
       
  2750 			}
       
  2751 
       
  2752 		}
       
  2753 
       
  2754 		status = encrypt_payloads(
       
  2755 			&m_auth_key,
       
  2756 			&m_key_wrap_key,
       
  2757 			plaintext_payloads,
       
  2758 			encrypted_settings);
       
  2759 		if (status != eap_status_ok)
       
  2760 		{
       
  2761 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2762 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2763 		}
       
  2764 	}
       
  2765 
       
  2766 	automatic_encrypted_settings.do_not_free_variable();
       
  2767 
       
  2768 	status = payloads->add_attribute(
       
  2769 		encrypted_settings);
       
  2770 	if (status != eap_status_ok)
       
  2771 	{
       
  2772 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2773 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2774 	}
       
  2775 
       
  2776 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2777 
       
  2778 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2779 	{
       
  2780 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2781 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2782 	}
       
  2783 
       
  2784 	status = payloads->create_simple_config_message(
       
  2785 		&m_new_simple_config_message,
       
  2786 		false);
       
  2787 	if (status != eap_status_ok)
       
  2788 	{
       
  2789 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2790 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2791 	}
       
  2792 
       
  2793 	status = add_authenticator_attribute(
       
  2794 		&m_received_simple_config_message,
       
  2795 		&m_new_simple_config_message);
       
  2796 	if (status != eap_status_ok)
       
  2797 	{
       
  2798 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2799 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2800 	}
       
  2801 
       
  2802 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2803 
       
  2804 	set_state(simple_config_state_wait_WSC_DONE);
       
  2805 
       
  2806 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2807 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2808 }
       
  2809 
       
  2810 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  2811 
       
  2812 //--------------------------------------------------
       
  2813 
       
  2814 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_WSC_ACK()
       
  2815 {
       
  2816 	EAP_TRACE_DEBUG(
       
  2817 		m_am_tools,
       
  2818 		TRACE_FLAGS_DEFAULT,
       
  2819 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_WSC_ACK()\n"),
       
  2820 		(m_is_client == true ? "client": "server")));
       
  2821 
       
  2822 	eap_status_e status(eap_status_process_general_error);
       
  2823 
       
  2824 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2825 
       
  2826 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2827 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2828 
       
  2829 	if (payloads == 0
       
  2830 		|| payloads->get_is_valid() == false)
       
  2831 	{
       
  2832 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2833 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2834 	}
       
  2835 	
       
  2836 	status = add_common_attributes(
       
  2837 		payloads,
       
  2838 		simple_config_Message_Type_WSC_ACK,
       
  2839 		true,
       
  2840 		true);
       
  2841 	if (status != eap_status_ok)
       
  2842 	{
       
  2843 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2844 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2845 	}
       
  2846 
       
  2847 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2848 
       
  2849 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2850 	{
       
  2851 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2852 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2853 	}
       
  2854 
       
  2855 	status = payloads->create_simple_config_message(
       
  2856 		&m_new_simple_config_message,
       
  2857 		false);
       
  2858 	if (status != eap_status_ok)
       
  2859 	{
       
  2860 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2861 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2862 	}
       
  2863 
       
  2864 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2865 
       
  2866 	set_state(simple_config_state_failure);
       
  2867 
       
  2868 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2869 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2870 }
       
  2871 
       
  2872 //--------------------------------------------------
       
  2873 
       
  2874 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_WSC_NACK()
       
  2875 {
       
  2876 	EAP_TRACE_DEBUG(
       
  2877 		m_am_tools,
       
  2878 		TRACE_FLAGS_DEFAULT,
       
  2879 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_WSC_NACK()\n"),
       
  2880 		(m_is_client == true ? "client": "server")));
       
  2881 
       
  2882 	eap_status_e status(eap_status_process_general_error);
       
  2883 
       
  2884 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2885 
       
  2886 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2887 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2888 
       
  2889 	if (payloads == 0
       
  2890 		|| payloads->get_is_valid() == false)
       
  2891 	{
       
  2892 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2893 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2894 	}
       
  2895 
       
  2896 	status = add_common_attributes(
       
  2897 		payloads,
       
  2898 		simple_config_Message_Type_WSC_NACK,
       
  2899 		true,
       
  2900 		true);
       
  2901 	if (status != eap_status_ok)
       
  2902 	{
       
  2903 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2904 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2905 	}
       
  2906 
       
  2907 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2908 
       
  2909 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2910 	{
       
  2911 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2912 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2913 	}
       
  2914 
       
  2915 	status = payloads->create_simple_config_message(
       
  2916 		&m_new_simple_config_message,
       
  2917 		false);
       
  2918 	if (status != eap_status_ok)
       
  2919 	{
       
  2920 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2921 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2922 	}
       
  2923 
       
  2924 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2925 
       
  2926 	set_state(simple_config_state_failure);
       
  2927 
       
  2928 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2929 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2930 }
       
  2931 
       
  2932 //--------------------------------------------------
       
  2933 
       
  2934 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_WSC_Done()
       
  2935 {
       
  2936 	EAP_TRACE_DEBUG(
       
  2937 		m_am_tools,
       
  2938 		TRACE_FLAGS_DEFAULT,
       
  2939 		(EAPL("SIMPLE_CONFIG: %s: message_function: simple_config_record_c::send_WSC_Done()\n"),
       
  2940 		(m_is_client == true ? "client": "server")));
       
  2941 
       
  2942 	eap_status_e status(eap_status_process_general_error);
       
  2943 
       
  2944 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2945 
       
  2946 	simple_config_payloads_c * payloads = new simple_config_payloads_c(m_am_tools);
       
  2947 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, payloads);
       
  2948 
       
  2949 	if (payloads == 0
       
  2950 		|| payloads->get_is_valid() == false)
       
  2951 	{
       
  2952 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2953 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2954 	}
       
  2955 	
       
  2956 	status = add_common_attributes(
       
  2957 		payloads,
       
  2958 		simple_config_Message_Type_WSC_DONE,
       
  2959 		true,
       
  2960 		true);
       
  2961 	if (status != eap_status_ok)
       
  2962 	{
       
  2963 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2964 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2965 	}
       
  2966 
       
  2967 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2968 
       
  2969 	if (m_new_simple_config_message.get_is_valid() == false)
       
  2970 	{
       
  2971 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2972 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2973 	}
       
  2974 
       
  2975 	status = payloads->create_simple_config_message(
       
  2976 		&m_new_simple_config_message,
       
  2977 		false);
       
  2978 	if (status != eap_status_ok)
       
  2979 	{
       
  2980 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2981 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2982 	}
       
  2983 
       
  2984 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  2985 
       
  2986 	set_state(simple_config_state_simple_config_success);
       
  2987 
       
  2988 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2989 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2990 }
       
  2991 
       
  2992 //--------------------------------------------------
       
  2993 
       
  2994 EAP_FUNC_EXPORT void simple_config_record_c::send_error_notification(const eap_status_e error)
       
  2995 {
       
  2996 	EAP_TRACE_DEBUG(m_am_tools, 
       
  2997 		TRACE_FLAGS_DEFAULT, 
       
  2998 		(EAPL("simple_config_record_c::send_error_notification, error=%d\n"),
       
  2999 		error));	
       
  3000 
       
  3001 	// Notifies the lower level of an authentication error.
       
  3002 	eap_state_notification_c notification(
       
  3003 		m_am_tools,
       
  3004 		&m_send_network_id,
       
  3005 		m_is_client,
       
  3006 		eap_state_notification_generic,
       
  3007 		eap_protocol_layer_general,
       
  3008 		eap_type_none,
       
  3009 		eap_state_none,
       
  3010 		eap_general_state_authentication_error,
       
  3011 		0,
       
  3012 		false);
       
  3013 
       
  3014 	notification.set_authentication_error(error);
       
  3015 
       
  3016 	get_type_partner()->state_notification(&notification);
       
  3017 }
       
  3018 
       
  3019 //--------------------------------------------------
       
  3020 
       
  3021 //
       
  3022 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::initalize_error_message_timeout()
       
  3023 {
       
  3024 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3025 
       
  3026 	cancel_error_message_timeout();
       
  3027 
       
  3028 	eap_status_e status = get_type_partner()->set_timer(
       
  3029 		this,
       
  3030 		SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID,
       
  3031 		0,
       
  3032 		m_error_message_received_timeout);
       
  3033 
       
  3034 	if (status != eap_status_ok)
       
  3035 	{
       
  3036 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3037 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3038 	}
       
  3039 
       
  3040 	EAP_TRACE_DEBUG(
       
  3041 		m_am_tools, 
       
  3042 		TRACE_FLAGS_DEFAULT, 
       
  3043 		(EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID set %d ms, this = 0x%08x.\n"),
       
  3044 		 (m_is_client == true) ? "client": "server",
       
  3045 		 m_error_message_received_timeout,
       
  3046 		 this));
       
  3047 
       
  3048 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3049 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3050 }
       
  3051 
       
  3052 //--------------------------------------------------
       
  3053 
       
  3054 //
       
  3055 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::cancel_error_message_timeout()
       
  3056 {
       
  3057 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3058 
       
  3059 	eap_status_e status = get_type_partner()->cancel_timer(
       
  3060 		this,
       
  3061 		SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID);
       
  3062 
       
  3063 	EAP_UNREFERENCED_PARAMETER(status); // in release
       
  3064 	
       
  3065 	EAP_TRACE_DEBUG(
       
  3066 		m_am_tools, 
       
  3067 		TRACE_FLAGS_DEFAULT, 
       
  3068 		(EAPL("TIMER: %s, SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID cancelled status %d, this = 0x%08x.\n"),
       
  3069 		 (m_is_client == true ? "client": "server"),
       
  3070 		 status,
       
  3071 		 this));
       
  3072 
       
  3073 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3074 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3075 }
       
  3076 
       
  3077 //--------------------------------------------------
       
  3078 
       
  3079 //
       
  3080 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::initialize_M2D_received_timeout()
       
  3081 {
       
  3082 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3083 
       
  3084 	eap_status_e status(eap_status_ok);
       
  3085 
       
  3086 	if (m_M2D_received_timeout_active == false)
       
  3087 	{
       
  3088 		cancel_M2D_received_timeout();
       
  3089 
       
  3090 		status = get_type_partner()->set_timer(
       
  3091 			this,
       
  3092 			SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID,
       
  3093 			0,
       
  3094 			m_error_message_received_timeout);
       
  3095 
       
  3096 		if (status != eap_status_ok)
       
  3097 		{
       
  3098 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3099 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3100 		}
       
  3101 
       
  3102 		EAP_TRACE_DEBUG(
       
  3103 			m_am_tools, 
       
  3104 			TRACE_FLAGS_DEFAULT, 
       
  3105 			(EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID set %d ms, this = 0x%08x.\n"),
       
  3106 			 (m_is_client == true) ? "client": "server",
       
  3107 			 m_error_message_received_timeout,
       
  3108 			 this));
       
  3109 	}
       
  3110 	else
       
  3111 	{
       
  3112 		EAP_TRACE_DEBUG(
       
  3113 			m_am_tools, 
       
  3114 			TRACE_FLAGS_DEFAULT, 
       
  3115 			(EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID already set.\n"),
       
  3116 			 (m_is_client == true) ? "client": "server"));
       
  3117 	}
       
  3118 
       
  3119 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3120 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3121 }
       
  3122 
       
  3123 //--------------------------------------------------
       
  3124 
       
  3125 //
       
  3126 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::cancel_M2D_received_timeout()
       
  3127 {
       
  3128 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3129 
       
  3130 	eap_status_e status = get_type_partner()->cancel_timer(
       
  3131 		this,
       
  3132 		SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID);
       
  3133 
       
  3134 	m_M2D_received_timeout_active = false;
       
  3135 
       
  3136 	EAP_UNREFERENCED_PARAMETER(status); // in release
       
  3137 	
       
  3138 	EAP_TRACE_DEBUG(
       
  3139 		m_am_tools, 
       
  3140 		TRACE_FLAGS_DEFAULT, 
       
  3141 		(EAPL("TIMER: %s, SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID cancelled status %d, this = 0x%08x.\n"),
       
  3142 		 (m_is_client == true ? "client": "server"),
       
  3143 		 status,
       
  3144 		 this));
       
  3145 
       
  3146 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3147 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3148 }
       
  3149 
       
  3150 //--------------------------------------------------
       
  3151 
       
  3152 //
       
  3153 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::timer_expired(
       
  3154 	const u32_t id,
       
  3155 	void * data
       
  3156 	)
       
  3157 {
       
  3158 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3159 
       
  3160 	EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this.
       
  3161 	
       
  3162 	EAP_TRACE_DEBUG(
       
  3163 		m_am_tools,
       
  3164 		TRACE_FLAGS_DEFAULT,
       
  3165 		(EAPL("TIMER: [0x%08x]->simple_config_record_c::timer_expired(id 0x%02x, data 0x%08x)\n"),
       
  3166 		 this,
       
  3167 		 id,
       
  3168 		 data));
       
  3169 
       
  3170 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  3171 
       
  3172 	eap_status_e status = eap_status_process_general_error;
       
  3173 
       
  3174 	if (id == SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID)
       
  3175 	{
       
  3176 		EAP_TRACE_DEBUG(
       
  3177 			m_am_tools, 
       
  3178 			TRACE_FLAGS_DEFAULT, 
       
  3179 			(EAPL("TIMER: %s: SIMPLE_CONFIG_RECORD_ERROR_MESSAGE_RECEIVED_ID elapsed.\n"),
       
  3180 			 (m_is_client == true ? "client": "server")
       
  3181 			 ));
       
  3182 
       
  3183 		status = send_WSC_NACK();
       
  3184 		if (status != eap_status_ok)
       
  3185 		{
       
  3186 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3187 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3188 		}
       
  3189 
       
  3190 		status = check_sent_simple_config_message();
       
  3191 		if (status != eap_status_ok)
       
  3192 		{
       
  3193 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3194 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3195 		}
       
  3196 
       
  3197 		(void) send_error_notification(m_handshake_error);
       
  3198 
       
  3199 	}
       
  3200 	else if (id == SIMPLE_CONFIG_RECORD_M2D_RECEIVED_ID)
       
  3201 	{
       
  3202 		(void) m_am_simple_config_services->received_registrar_information(&m_M2D_payloads);
       
  3203 
       
  3204 		(void) send_error_notification(m_handshake_error);
       
  3205 
       
  3206 		m_M2D_received_timeout_active = false;
       
  3207 	}
       
  3208 	else
       
  3209 	{
       
  3210 		EAP_TRACE_DEBUG(
       
  3211 			m_am_tools, 
       
  3212 			TRACE_FLAGS_DEFAULT, 
       
  3213 			(EAPL("ERROR: TIMER: %s: unknown timer elapsed.\n"),
       
  3214 			 (m_is_client == true ? "client": "server")
       
  3215 			 ));
       
  3216 	}
       
  3217 
       
  3218 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3219 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3220 }
       
  3221 
       
  3222 //--------------------------------------------------
       
  3223 
       
  3224 //
       
  3225 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::timer_delete_data(
       
  3226 	const u32_t /*id*/,
       
  3227 	void * /*data*/
       
  3228 	)
       
  3229 {
       
  3230 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3231 
       
  3232 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3233 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3234 }
       
  3235 
       
  3236 //--------------------------------------------------
       
  3237 
       
  3238 //
       
  3239 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::verify_nonces_and_authenticator(
       
  3240 	const eap_variable_data_c * const auth_key,
       
  3241 	const eap_variable_data_c * const enrollee_nonce,
       
  3242 	const eap_variable_data_c * const registrar_nonce,
       
  3243 	const simple_config_payloads_c * const payloads,
       
  3244 	const bool check_enrollee_nonce,
       
  3245 	const bool check_registrar_nonce,
       
  3246 	const bool check_authenticator)
       
  3247 {
       
  3248 	EAP_TRACE_DEBUG(
       
  3249 		m_am_tools,
       
  3250 		TRACE_FLAGS_DEFAULT,
       
  3251 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::verify_authenticator()\n"),
       
  3252 		 (m_is_client == true ? "client": "server")));
       
  3253 
       
  3254 	if (check_enrollee_nonce == true)
       
  3255 	{
       
  3256 		// Verify Enrollee Nonce.
       
  3257 
       
  3258 		simple_config_variable_data_c * const enrollee_nonce_attribute
       
  3259 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Enrollee_Nonce);
       
  3260 		if (enrollee_nonce_attribute == 0)
       
  3261 		{
       
  3262 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3263 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  3264 		}
       
  3265 
       
  3266 		if (enrollee_nonce->compare(
       
  3267 				enrollee_nonce_attribute->get_data(enrollee_nonce_attribute->get_data_length()),
       
  3268 				enrollee_nonce_attribute->get_data_length()) != 0)
       
  3269 		{
       
  3270 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3271 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  3272 		}
       
  3273 	}
       
  3274 
       
  3275 	if (check_registrar_nonce == true)
       
  3276 	{
       
  3277 		// Verify Registrar Nonce.
       
  3278 
       
  3279 		simple_config_variable_data_c * const registrar_nonce_attribute
       
  3280 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Registrar_Nonce);
       
  3281 		if (registrar_nonce_attribute == 0)
       
  3282 		{
       
  3283 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3284 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  3285 		}
       
  3286 
       
  3287 		if (registrar_nonce->compare(
       
  3288 				registrar_nonce_attribute->get_data(registrar_nonce_attribute->get_data_length()),
       
  3289 				registrar_nonce_attribute->get_data_length()) != 0)
       
  3290 		{
       
  3291 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3292 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  3293 		}
       
  3294 	}
       
  3295 
       
  3296 	if (check_authenticator == true)
       
  3297 	{
       
  3298 		// Verify Authenticator.
       
  3299 		crypto_sha_256_c sha_256(m_am_tools);
       
  3300 		if (sha_256.get_is_valid() == false)
       
  3301 		{
       
  3302 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3303 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3304 		}
       
  3305 
       
  3306 		crypto_hmac_c hmac_sha_256(
       
  3307 			m_am_tools,
       
  3308 			&sha_256,
       
  3309 			false);
       
  3310 		if (hmac_sha_256.get_is_valid() == false)
       
  3311 		{
       
  3312 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3313 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3314 		}
       
  3315 
       
  3316 		EAP_TRACE_DATA_DEBUG(
       
  3317 			m_am_tools, 
       
  3318 			TRACE_FLAGS_DEFAULT, 
       
  3319 			(EAPL("SIMPLE_CONFIG authenticator auth_key"),
       
  3320 			 auth_key->get_data(),
       
  3321 			 auth_key->get_data_length()));
       
  3322 
       
  3323 		eap_status_e status = hmac_sha_256.hmac_set_key(auth_key);
       
  3324 		if (status != eap_status_ok)
       
  3325 		{
       
  3326 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3327 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3328 		}
       
  3329 
       
  3330 		EAP_TRACE_DATA_DEBUG(
       
  3331 			m_am_tools, 
       
  3332 			TRACE_FLAGS_DEFAULT, 
       
  3333 			(EAPL("SIMPLE_CONFIG authenticator data"),
       
  3334 			 m_previous_simple_config_message.get_simple_config_message_data()->get_data(),
       
  3335 			 m_previous_simple_config_message.get_simple_config_message_data()->get_data_length()));
       
  3336 
       
  3337 		status = hmac_sha_256.hmac_update(
       
  3338 			m_previous_simple_config_message.get_simple_config_message_data()->get_data(),
       
  3339 			m_previous_simple_config_message.get_simple_config_message_data()->get_data_length());
       
  3340 		if (status != eap_status_ok)
       
  3341 		{
       
  3342 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3343 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3344 		}
       
  3345 
       
  3346 		status = payloads->add_payloads_to_simple_config_authenticator(
       
  3347 			&hmac_sha_256,
       
  3348 			false);
       
  3349 		if (status != eap_status_ok)
       
  3350 		{
       
  3351 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3352 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3353 		}
       
  3354 
       
  3355 		{
       
  3356 			eap_variable_data_c authenticator(m_am_tools);
       
  3357 
       
  3358 			if (authenticator.get_is_valid() == false)
       
  3359 			{
       
  3360 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3361 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3362 			}
       
  3363 
       
  3364 			status = authenticator.set_buffer_length(hmac_sha_256.get_digest_length());
       
  3365 			if (status != eap_status_ok)
       
  3366 			{
       
  3367 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3368 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3369 			}
       
  3370 
       
  3371 			status = authenticator.set_data_length(hmac_sha_256.get_digest_length());
       
  3372 			if (status != eap_status_ok)
       
  3373 			{
       
  3374 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3375 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3376 			}
       
  3377 
       
  3378 			u32_t md_length(hmac_sha_256.get_digest_length());
       
  3379 			
       
  3380 			status = hmac_sha_256.hmac_final(
       
  3381 				authenticator.get_data(hmac_sha_256.get_digest_length()),
       
  3382 				&md_length);
       
  3383 			if (status != eap_status_ok)
       
  3384 			{
       
  3385 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3386 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3387 			}
       
  3388 
       
  3389 			EAP_TRACE_DATA_DEBUG(
       
  3390 				m_am_tools, 
       
  3391 				TRACE_FLAGS_DEFAULT, 
       
  3392 				(EAPL("SIMPLE_CONFIG authenticator"),
       
  3393 				 authenticator.get_data(),
       
  3394 				 authenticator.get_data_length()));
       
  3395 			
       
  3396 			status = authenticator.set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH);
       
  3397 			if (status != eap_status_ok)
       
  3398 			{
       
  3399 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3400 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3401 			}
       
  3402 			
       
  3403 			simple_config_variable_data_c * const received_authenticator
       
  3404 				= payloads->get_attribute_pointer(simple_config_Attribute_Type_Authenticator);
       
  3405 			if (received_authenticator == 0)
       
  3406 			{
       
  3407 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3408 				return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  3409 			}
       
  3410 
       
  3411 			if (authenticator.compare(
       
  3412 					received_authenticator->get_data(received_authenticator->get_data_length()),
       
  3413 					received_authenticator->get_data_length()) != 0)
       
  3414 			{
       
  3415 				EAP_TRACE_DATA_ERROR(
       
  3416 					m_am_tools, 
       
  3417 					TRACE_FLAGS_DEFAULT, 
       
  3418 					(EAPL("SIMPLE_CONFIG    local authenticator"),
       
  3419 					 authenticator.get_data(),
       
  3420 					 authenticator.get_data_length()));
       
  3421 
       
  3422 				EAP_TRACE_DATA_ERROR(
       
  3423 					m_am_tools, 
       
  3424 					TRACE_FLAGS_DEFAULT, 
       
  3425 					(EAPL("SIMPLE_CONFIG received authenticator"),
       
  3426 					 received_authenticator->get_data(received_authenticator->get_data_length()),
       
  3427 					 received_authenticator->get_data_length()));
       
  3428 				
       
  3429 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3430 				return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  3431 			}
       
  3432 			else
       
  3433 			{
       
  3434 				EAP_TRACE_DEBUG(
       
  3435 					m_am_tools,
       
  3436 					TRACE_FLAGS_DEFAULT,
       
  3437 					(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::verify_authenticator(): Authenticator OK\n"),
       
  3438 					 (m_is_client == true ? "client": "server")));
       
  3439 			}
       
  3440 		}
       
  3441 	}
       
  3442 
       
  3443 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3444 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3445 }
       
  3446 
       
  3447 //--------------------------------------------------
       
  3448 
       
  3449 //
       
  3450 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::start_simple_config_authentication(
       
  3451 	const eap_variable_data_c * const NAI ///< This is the full NAI of the client.
       
  3452 	)
       
  3453 {
       
  3454 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3455 
       
  3456 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3457 	EAP_TRACE_DEBUG(
       
  3458 		m_am_tools,
       
  3459 		TRACE_FLAGS_DEFAULT,
       
  3460 		(EAPL("SIMPLE_CONFIG: %s: message_function: start_simple_config_authentication()\n"),
       
  3461 		(m_is_client == true ? "client": "server")));
       
  3462 
       
  3463 	if (verify_state(simple_config_state_wait_simple_config_start) == false)
       
  3464 	{
       
  3465 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3466 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  3467 	}
       
  3468 
       
  3469 	set_state(simple_config_state_process_simple_config_start);
       
  3470 
       
  3471 	if (NAI == 0
       
  3472 		|| NAI->get_is_valid_data() == false)
       
  3473 	{
       
  3474 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3475 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  3476 	}
       
  3477 
       
  3478 	eap_status_e status = m_NAI.set_copy_of_buffer(NAI);
       
  3479 	if (status != eap_status_ok)
       
  3480 	{
       
  3481 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3482 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3483 	}
       
  3484 
       
  3485 	m_allow_message_send = false;
       
  3486 
       
  3487 	status = m_am_simple_config_services->query_network_and_device_parameters(get_state());
       
  3488 
       
  3489 	m_allow_message_send = true;
       
  3490 
       
  3491 	if (status == eap_status_pending_request)
       
  3492 	{
       
  3493 		// This is pending query, that will be completed by
       
  3494 		// complete_query_network_and_device_parameters() call.
       
  3495 		m_pending_query_network_and_device_parameters = true;
       
  3496 
       
  3497 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3498 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3499 	}
       
  3500 	else if (status == eap_status_completed_request)
       
  3501 	{
       
  3502 		// This is already completed by complete_query_network_and_device_parameters() call.
       
  3503 
       
  3504 		status = check_sent_simple_config_message();
       
  3505 
       
  3506 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3507 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3508 	}
       
  3509 	else if (status == eap_status_ok)
       
  3510 	{
       
  3511 		// This is also an error case, because this call is always completed on success. 
       
  3512 		status = eap_status_process_general_error;
       
  3513 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3514 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3515 	}
       
  3516 	else // All other status values means error, because this call is always completed on success.
       
  3517 	{
       
  3518 		// This is an error case.
       
  3519 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3520 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3521 	}
       
  3522 }
       
  3523 
       
  3524 //--------------------------------------------------
       
  3525 
       
  3526 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  3527 
       
  3528 static const simple_config_Attribute_Type_e needed_payloads_of_M1[]
       
  3529 	= {
       
  3530 		simple_config_Attribute_Type_Version,
       
  3531 		simple_config_Attribute_Type_Message_Type,
       
  3532 		simple_config_Attribute_Type_UUID_E,
       
  3533 		simple_config_Attribute_Type_MAC_Address,
       
  3534 		simple_config_Attribute_Type_Enrollee_Nonce,
       
  3535 		simple_config_Attribute_Type_Public_Key,
       
  3536 		simple_config_Attribute_Type_Authentication_Type_Flags,
       
  3537 		simple_config_Attribute_Type_Encryption_Type_Flags,
       
  3538 		simple_config_Attribute_Type_Connection_Type_Flags,
       
  3539 		simple_config_Attribute_Type_Config_Methods,
       
  3540 		simple_config_Attribute_Type_Simple_Config_State,
       
  3541 		simple_config_Attribute_Type_Manufacturer,
       
  3542 		simple_config_Attribute_Type_Model_Name,
       
  3543 		simple_config_Attribute_Type_Model_Number,
       
  3544 		simple_config_Attribute_Type_Serial_Number,
       
  3545 		simple_config_Attribute_Type_Primary_Device_Type,
       
  3546 		simple_config_Attribute_Type_Device_Name,
       
  3547 		simple_config_Attribute_Type_RF_Band,
       
  3548 		simple_config_Attribute_Type_Association_State,
       
  3549 		simple_config_Attribute_Type_Device_Password_ID,
       
  3550 		simple_config_Attribute_Type_Configuration_Error,
       
  3551 		simple_config_Attribute_Type_OS_Version,
       
  3552 	};
       
  3553 
       
  3554 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M1(
       
  3555 	const simple_config_payloads_c * const payloads)
       
  3556 {
       
  3557 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3558 
       
  3559 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3560 	EAP_TRACE_DEBUG(
       
  3561 		m_am_tools,
       
  3562 		TRACE_FLAGS_DEFAULT,
       
  3563 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M1()\n"),
       
  3564 		 (m_is_client == true ? "client": "server")));
       
  3565 
       
  3566 	if (verify_state(simple_config_state_wait_M1) == false)
       
  3567 	{
       
  3568 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3569 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  3570 	}
       
  3571 
       
  3572 	set_state(simple_config_state_process_M1);
       
  3573 
       
  3574 	eap_status_e status = payloads->check_payloads_existense(
       
  3575 		needed_payloads_of_M1, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  3576 		sizeof(needed_payloads_of_M1)/sizeof(needed_payloads_of_M1[0]));
       
  3577 	if (status != eap_status_ok)
       
  3578 	{
       
  3579 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3580 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3581 	}
       
  3582 
       
  3583 	// Save Enrollee Nonce.
       
  3584 	status = payloads->get_attribute_data(
       
  3585 		simple_config_Attribute_Type_Enrollee_Nonce,
       
  3586 		&m_enrollee_nonce);
       
  3587 	if (status != eap_status_ok)
       
  3588 	{
       
  3589 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3590 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3591 	}
       
  3592 
       
  3593 	// Save Enrollee MAC.
       
  3594 	status = payloads->get_attribute_data(
       
  3595 		simple_config_Attribute_Type_MAC_Address,
       
  3596 		&m_enrollee_mac);
       
  3597 	if (status != eap_status_ok)
       
  3598 	{
       
  3599 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3600 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3601 	}
       
  3602 
       
  3603 	// Save Public Key.
       
  3604 	status = payloads->get_attribute_data(
       
  3605 		simple_config_Attribute_Type_Public_Key,
       
  3606 		&m_peer_public_dhe_key);
       
  3607 	if (status != eap_status_ok)
       
  3608 	{
       
  3609 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3610 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3611 	}
       
  3612 
       
  3613 	{
       
  3614 		u16_t data(0ul);
       
  3615 
       
  3616 		status = payloads->get_attribute_data(
       
  3617 			simple_config_Attribute_Type_Device_Password_ID,
       
  3618 			&data);
       
  3619 		if (status != eap_status_ok)
       
  3620 		{
       
  3621 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3622 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3623 		}
       
  3624 
       
  3625 		if (status != eap_status_ok)
       
  3626 		{
       
  3627 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3628 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3629 		}
       
  3630 
       
  3631 		m_received_Device_Password_ID = static_cast<simple_config_Device_Password_ID_e>(data);
       
  3632 	}
       
  3633 
       
  3634 	eap_variable_data_c dhe_shared_secret(m_am_tools);
       
  3635 
       
  3636 	if (dhe_shared_secret.get_is_valid() == false)
       
  3637 	{
       
  3638 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3639 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3640 	}
       
  3641 
       
  3642 	status = generate_dhe_shared_secret(&m_peer_public_dhe_key, &dhe_shared_secret);
       
  3643 	if (status != eap_status_ok)
       
  3644 	{
       
  3645 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3646 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3647 	}
       
  3648 
       
  3649 	status = generate_kdk(
       
  3650 		&dhe_shared_secret,
       
  3651 		&m_enrollee_nonce,
       
  3652 		&m_enrollee_mac,
       
  3653 		&m_registrar_nonce,
       
  3654 		&m_kdk);
       
  3655 	if (status != eap_status_ok)
       
  3656 	{
       
  3657 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3658 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3659 	}
       
  3660 
       
  3661 	status = derive_additional_keys(
       
  3662 		&m_kdk,
       
  3663 		&m_auth_key,
       
  3664 		&m_key_wrap_key,
       
  3665 		&m_EMSK);
       
  3666 	if (status != eap_status_ok)
       
  3667 	{
       
  3668 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3669 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3670 	}
       
  3671 
       
  3672 	m_allow_message_send = false;
       
  3673 
       
  3674 	status = m_am_simple_config_services->query_network_and_device_parameters(get_state());
       
  3675 
       
  3676 	m_allow_message_send = true;
       
  3677 
       
  3678 	if (status == eap_status_pending_request)
       
  3679 	{
       
  3680 		// This is pending query, that will be completed by
       
  3681 		// complete_query_network_and_device_parameters() call.
       
  3682 		m_pending_query_network_and_device_parameters = true;
       
  3683 
       
  3684 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3685 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3686 	}
       
  3687 	else if (status == eap_status_completed_request)
       
  3688 	{
       
  3689 		// This is already completed by complete_query_network_and_device_parameters() call.
       
  3690 
       
  3691 		status = check_sent_simple_config_message();
       
  3692 
       
  3693 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3694 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3695 	}
       
  3696 	else if (status == eap_status_ok)
       
  3697 	{
       
  3698 		// This is also an error case, because this call is always completed on success. 
       
  3699 		status = eap_status_process_general_error;
       
  3700 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3701 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3702 	}
       
  3703 	else // All other status values means error, because this call is always completed on success.
       
  3704 	{
       
  3705 		// This is an error case.
       
  3706 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3707 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3708 	}
       
  3709 
       
  3710 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3711 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3712 }
       
  3713 
       
  3714 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  3715 
       
  3716 //--------------------------------------------------
       
  3717 
       
  3718 static const simple_config_Attribute_Type_e needed_payloads_of_M2[]
       
  3719 	= {
       
  3720 		simple_config_Attribute_Type_Version,
       
  3721 		simple_config_Attribute_Type_Message_Type,
       
  3722 		simple_config_Attribute_Type_Enrollee_Nonce,
       
  3723 		simple_config_Attribute_Type_Registrar_Nonce,
       
  3724 		simple_config_Attribute_Type_UUID_R,
       
  3725 		simple_config_Attribute_Type_Public_Key,
       
  3726 		simple_config_Attribute_Type_Authentication_Type_Flags,
       
  3727 		simple_config_Attribute_Type_Encryption_Type_Flags,
       
  3728 		simple_config_Attribute_Type_Connection_Type_Flags,
       
  3729 		simple_config_Attribute_Type_Config_Methods,
       
  3730 		simple_config_Attribute_Type_Manufacturer,
       
  3731 		simple_config_Attribute_Type_Model_Name,
       
  3732 		simple_config_Attribute_Type_Model_Number,
       
  3733 		simple_config_Attribute_Type_Serial_Number,
       
  3734 		simple_config_Attribute_Type_Primary_Device_Type,
       
  3735 		simple_config_Attribute_Type_Device_Name,
       
  3736 		simple_config_Attribute_Type_RF_Band,
       
  3737 		simple_config_Attribute_Type_Association_State,
       
  3738 		simple_config_Attribute_Type_Configuration_Error,
       
  3739 		simple_config_Attribute_Type_Device_Password_ID,
       
  3740 		simple_config_Attribute_Type_OS_Version,
       
  3741 		simple_config_Attribute_Type_Authenticator,
       
  3742 	};
       
  3743 
       
  3744 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M2(
       
  3745 	const simple_config_payloads_c * const payloads)
       
  3746 {
       
  3747 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3748 
       
  3749 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3750 	EAP_TRACE_DEBUG(
       
  3751 		m_am_tools,
       
  3752 		TRACE_FLAGS_DEFAULT,
       
  3753 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M2()\n"),
       
  3754 		 (m_is_client == true ? "client": "server")));
       
  3755 
       
  3756 	if (verify_state(simple_config_state_wait_M2) == false)
       
  3757 	{
       
  3758 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3759 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  3760 	}
       
  3761 
       
  3762 	eap_status_e status = payloads->check_payloads_existense(
       
  3763 		needed_payloads_of_M2, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  3764 		sizeof(needed_payloads_of_M2)/sizeof(needed_payloads_of_M2[0]));
       
  3765 	if (status != eap_status_ok)
       
  3766 	{
       
  3767 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3768 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3769 	}
       
  3770 
       
  3771 	{
       
  3772 		// Verify Enrollee Nonce.
       
  3773 		simple_config_variable_data_c * const enrollee_nonce
       
  3774 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Enrollee_Nonce);
       
  3775 		if (enrollee_nonce == 0)
       
  3776 		{
       
  3777 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3778 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  3779 		}
       
  3780 
       
  3781 		if (m_enrollee_nonce.compare(
       
  3782 				enrollee_nonce->get_data(enrollee_nonce->get_data_length()),
       
  3783 				enrollee_nonce->get_data_length()) != 0)
       
  3784 		{
       
  3785 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3786 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  3787 		}
       
  3788 	}
       
  3789 
       
  3790 
       
  3791 	eap_variable_data_c registrar_nonce_data(m_am_tools);
       
  3792 
       
  3793 	if (registrar_nonce_data.get_is_valid() == false)
       
  3794 	{
       
  3795 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3796 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3797 	}
       
  3798 
       
  3799 	status = payloads->get_attribute_data(
       
  3800 		simple_config_Attribute_Type_Registrar_Nonce,
       
  3801 		&registrar_nonce_data);
       
  3802 	if (status != eap_status_ok)
       
  3803 	{
       
  3804 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3805 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3806 	}
       
  3807 
       
  3808 
       
  3809 	eap_variable_data_c registrar_public_key_data(m_am_tools);
       
  3810 
       
  3811 	if (registrar_public_key_data.get_is_valid() == false)
       
  3812 	{
       
  3813 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3814 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3815 	}
       
  3816 
       
  3817 	eap_variable_data_c auth_key(m_am_tools);
       
  3818 
       
  3819 	if (auth_key.get_is_valid() == false)
       
  3820 	{
       
  3821 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3822 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3823 	}
       
  3824 
       
  3825 	eap_variable_data_c key_wrap_key(m_am_tools);
       
  3826 
       
  3827 	if (key_wrap_key.get_is_valid() == false)
       
  3828 	{
       
  3829 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3830 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3831 	}
       
  3832 
       
  3833 	eap_variable_data_c EMSK(m_am_tools);
       
  3834 
       
  3835 	if (EMSK.get_is_valid() == false)
       
  3836 	{
       
  3837 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3838 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3839 	}
       
  3840 
       
  3841 	{
       
  3842 		// Save Registrar Public Key.
       
  3843 		status = payloads->get_attribute_data(
       
  3844 			simple_config_Attribute_Type_Public_Key,
       
  3845 			&registrar_public_key_data);
       
  3846 		if (status != eap_status_ok)
       
  3847 		{
       
  3848 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3849 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3850 		}
       
  3851 
       
  3852 
       
  3853 		eap_variable_data_c dhe_shared_secret(m_am_tools);
       
  3854 
       
  3855 		if (dhe_shared_secret.get_is_valid() == false)
       
  3856 		{
       
  3857 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3858 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3859 		}
       
  3860 
       
  3861 		status = generate_dhe_shared_secret(&registrar_public_key_data, &dhe_shared_secret);
       
  3862 		if (status != eap_status_ok)
       
  3863 		{
       
  3864 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3865 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3866 		}
       
  3867 
       
  3868 		eap_variable_data_c kdk(m_am_tools);
       
  3869 
       
  3870 		if (kdk.get_is_valid() == false)
       
  3871 		{
       
  3872 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3873 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3874 		}
       
  3875 
       
  3876 		status = generate_kdk(
       
  3877 			&dhe_shared_secret,
       
  3878 			&m_enrollee_nonce,
       
  3879 			&m_enrollee_mac,
       
  3880 			&registrar_nonce_data,
       
  3881 			&kdk);
       
  3882 		if (status != eap_status_ok)
       
  3883 		{
       
  3884 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3885 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3886 		}
       
  3887 
       
  3888 		status = derive_additional_keys(
       
  3889 			&kdk,
       
  3890 			&auth_key,
       
  3891 			&key_wrap_key,
       
  3892 			&EMSK);
       
  3893 		if (status != eap_status_ok)
       
  3894 		{
       
  3895 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3896 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3897 		}
       
  3898 	}
       
  3899 
       
  3900 	status = verify_nonces_and_authenticator(
       
  3901 		&auth_key,
       
  3902 		&m_enrollee_nonce,
       
  3903 		&registrar_nonce_data,
       
  3904 		payloads,
       
  3905 		false, // No Enrolle Nonce
       
  3906 		true, // Check Registrar Nonce
       
  3907 		true); // Check Authenticator
       
  3908 	if (status != eap_status_ok)
       
  3909 	{
       
  3910 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3911 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3912 	}
       
  3913 
       
  3914 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3915 
       
  3916 	// Check Device Password ID.
       
  3917 
       
  3918 	{
       
  3919 		u16_t data(0ul);
       
  3920 
       
  3921 		status = payloads->get_attribute_data(
       
  3922 			simple_config_Attribute_Type_Device_Password_ID,
       
  3923 			&data);
       
  3924 		if (status != eap_status_ok)
       
  3925 		{
       
  3926 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3927 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3928 		}
       
  3929 
       
  3930 		m_received_Device_Password_ID = static_cast<simple_config_Device_Password_ID_e>(data);
       
  3931 
       
  3932 #if 0 // This is done to bypass some external registrar. We do not test Device Password ID.
       
  3933 		if (m_received_Device_Password_ID != m_local_Device_Password_ID)
       
  3934 		{
       
  3935 			// No matching Device Password ID.
       
  3936 			if (m_local_Device_Password_ID == simple_config_Device_Password_ID_Default_PIN)
       
  3937 			{
       
  3938 				m_handshake_error = eap_status_pin_code_authentication_not_supported;
       
  3939 			}
       
  3940 			else if (m_local_Device_Password_ID == simple_config_Device_Password_ID_PushButton)
       
  3941 			{
       
  3942 				m_handshake_error = eap_status_push_button_authentication_not_supported;
       
  3943 			}
       
  3944 			else
       
  3945 			{
       
  3946 				m_handshake_error = eap_status_network_authentication_failure;
       
  3947 			}
       
  3948 
       
  3949 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3950 			return EAP_STATUS_RETURN(m_am_tools, m_handshake_error);
       
  3951 		}
       
  3952 #endif
       
  3953 	}
       
  3954 
       
  3955 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3956 
       
  3957 	// Save Registrar Nonce.
       
  3958 	status = m_registrar_nonce.set_copy_of_buffer(&registrar_nonce_data);
       
  3959 	if (status != eap_status_ok)
       
  3960 	{
       
  3961 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3962 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3963 	}
       
  3964 
       
  3965 	// Save Registrar Public Key.
       
  3966 	status = m_peer_public_dhe_key.set_copy_of_buffer(&registrar_public_key_data);
       
  3967 	if (status != eap_status_ok)
       
  3968 	{
       
  3969 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3970 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3971 	}
       
  3972 
       
  3973 	// Save Authentication Key.
       
  3974 	status = m_auth_key.set_copy_of_buffer(&auth_key);
       
  3975 	if (status != eap_status_ok)
       
  3976 	{
       
  3977 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3978 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3979 	}
       
  3980 
       
  3981 	// Save Key Wrap Key.
       
  3982 	status = m_key_wrap_key.set_copy_of_buffer(&key_wrap_key);
       
  3983 	if (status != eap_status_ok)
       
  3984 	{
       
  3985 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3986 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3987 	}
       
  3988 
       
  3989 	// Save EMSK.
       
  3990 	status = m_EMSK.set_copy_of_buffer(&EMSK);
       
  3991 	if (status != eap_status_ok)
       
  3992 	{
       
  3993 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3994 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3995 	}
       
  3996 
       
  3997 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3998 
       
  3999 	status = cancel_M2D_received_timeout();
       
  4000 	if (status != eap_status_ok)
       
  4001 	{
       
  4002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4003 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4004 	}
       
  4005 
       
  4006 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4007 
       
  4008 	status = send_M3();
       
  4009 	if (status != eap_status_ok)
       
  4010 	{
       
  4011 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4012 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4013 	}
       
  4014 
       
  4015 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4016 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4017 }
       
  4018 
       
  4019 //--------------------------------------------------
       
  4020 
       
  4021 static const simple_config_Attribute_Type_e needed_payloads_of_M2D[]
       
  4022 	= {
       
  4023 		simple_config_Attribute_Type_Version,
       
  4024 		simple_config_Attribute_Type_Message_Type,
       
  4025 		simple_config_Attribute_Type_Enrollee_Nonce,
       
  4026 		simple_config_Attribute_Type_Registrar_Nonce,
       
  4027 		simple_config_Attribute_Type_UUID_R,
       
  4028 		simple_config_Attribute_Type_Authentication_Type_Flags,
       
  4029 		simple_config_Attribute_Type_Encryption_Type_Flags,
       
  4030 		simple_config_Attribute_Type_Connection_Type_Flags,
       
  4031 		simple_config_Attribute_Type_Config_Methods,
       
  4032 		simple_config_Attribute_Type_Manufacturer,
       
  4033 		simple_config_Attribute_Type_Model_Name,
       
  4034 		simple_config_Attribute_Type_Model_Number,
       
  4035 		simple_config_Attribute_Type_Serial_Number,
       
  4036 		simple_config_Attribute_Type_Primary_Device_Type,
       
  4037 		simple_config_Attribute_Type_Device_Name,
       
  4038 		simple_config_Attribute_Type_RF_Band,
       
  4039 		simple_config_Attribute_Type_Association_State,
       
  4040 		simple_config_Attribute_Type_Configuration_Error,
       
  4041 		simple_config_Attribute_Type_OS_Version,
       
  4042 	};
       
  4043 
       
  4044 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M2D(
       
  4045 	const simple_config_payloads_c * const payloads)
       
  4046 {
       
  4047 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4048 
       
  4049 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4050 	EAP_TRACE_DEBUG(
       
  4051 		m_am_tools,
       
  4052 		TRACE_FLAGS_DEFAULT,
       
  4053 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M2D()\n"),
       
  4054 		 (m_is_client == true ? "client": "server")));
       
  4055 
       
  4056 	if (verify_state(simple_config_state_wait_M2) == false)
       
  4057 	{
       
  4058 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4059 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4060 	}
       
  4061 
       
  4062 	eap_status_e status = payloads->check_payloads_existense(
       
  4063 		needed_payloads_of_M2D, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4064 		sizeof(needed_payloads_of_M2D)/sizeof(needed_payloads_of_M2D[0]));
       
  4065 	if (status != eap_status_ok)
       
  4066 	{
       
  4067 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4068 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4069 	}
       
  4070 
       
  4071 	// Save Registrar Nonce.
       
  4072 	status = payloads->get_attribute_data(
       
  4073 		simple_config_Attribute_Type_Registrar_Nonce,
       
  4074 		&m_registrar_nonce);
       
  4075 	if (status != eap_status_ok)
       
  4076 	{
       
  4077 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4078 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4079 	}
       
  4080 
       
  4081 	if (m_handshake_error == eap_status_ok
       
  4082 		|| m_handshake_error == eap_status_authentication_failure)
       
  4083 	{
       
  4084 		u8_t RF_Band(simple_config_RF_Bands_2_4_GHz);
       
  4085 
       
  4086 		status = payloads->get_attribute_data(
       
  4087 			simple_config_Attribute_Type_RF_Band,
       
  4088 			&RF_Band);
       
  4089 		if (status != eap_status_ok)
       
  4090 		{
       
  4091 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4092 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4093 		}
       
  4094 
       
  4095 		simple_config_RF_Bands_e received_bands = static_cast<simple_config_RF_Bands_e>(RF_Band);
       
  4096 
       
  4097 		if ((received_bands & m_Rf_Bands) == 0)
       
  4098 		{
       
  4099 			// No matching RF Band.
       
  4100 			if ((m_Rf_Bands & simple_config_RF_Bands_2_4_GHz) != 0)
       
  4101 			{
       
  4102 				m_handshake_error = eap_status_rf_band_2_4_ghz_not_supported;
       
  4103 			}
       
  4104 			else if ((m_Rf_Bands & simple_config_RF_Bands_5_0_GHz) != 0)
       
  4105 			{
       
  4106 				m_handshake_error = eap_status_rf_band_5_0_ghz_not_supported;
       
  4107 			}
       
  4108 		}
       
  4109 
       
  4110 	}
       
  4111 
       
  4112 	if (m_handshake_error == eap_status_ok
       
  4113 		|| m_handshake_error == eap_status_authentication_failure)
       
  4114 	{
       
  4115 		u16_t error(0ul);
       
  4116 
       
  4117 		status = payloads->get_attribute_data(
       
  4118 			simple_config_Attribute_Type_Configuration_Error,
       
  4119 			&error);
       
  4120 		if (status != eap_status_ok)
       
  4121 		{
       
  4122 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4123 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4124 		}
       
  4125 
       
  4126 		simple_config_Configuration_Error_e received_error = static_cast<simple_config_Configuration_Error_e>(error);
       
  4127 
       
  4128 		if (received_error != simple_config_Configuration_Error_No_Error)
       
  4129 		{
       
  4130 			if (received_error == simple_config_Configuration_Error_OOB_Interface_Read_Error)
       
  4131 			{
       
  4132 				m_handshake_error = eap_status_oob_interface_read_error;
       
  4133 			}
       
  4134 			else if (received_error == simple_config_Configuration_Error_Decryption_CRC_Failure)
       
  4135 			{
       
  4136 				m_handshake_error = eap_status_decryption_crc_failure;
       
  4137 			}
       
  4138 			else if (received_error == simple_config_Configuration_Error_2_4_channel_not_supported)
       
  4139 			{
       
  4140 				m_handshake_error = eap_status_rf_band_2_4_ghz_not_supported;
       
  4141 			}
       
  4142 			else if (received_error == simple_config_Configuration_Error_5_0_channel_not_supported)
       
  4143 			{
       
  4144 				m_handshake_error = eap_status_rf_band_5_0_ghz_not_supported;
       
  4145 			}
       
  4146 			else if (received_error == simple_config_Configuration_Error_Signal_too_weak)
       
  4147 			{
       
  4148 				m_handshake_error = eap_status_signal_too_weak;
       
  4149 			}
       
  4150 			else if (received_error == simple_config_Configuration_Error_Network_auth_failure)
       
  4151 			{
       
  4152 				m_handshake_error = eap_status_network_authentication_failure;
       
  4153 			}
       
  4154 			else if (received_error == simple_config_Configuration_Error_Network_association_failure)
       
  4155 			{
       
  4156 				m_handshake_error = eap_status_network_association_failure;
       
  4157 			}
       
  4158 			else if (received_error == simple_config_Configuration_Error_No_DHCP_response)
       
  4159 			{
       
  4160 				m_handshake_error = eap_status_no_dhcp_response;
       
  4161 			}
       
  4162 			else if (received_error == simple_config_Configuration_Error_Failed_DHCP_config)
       
  4163 			{
       
  4164 				m_handshake_error = eap_status_failed_dhcp_configure;
       
  4165 			}
       
  4166 			else if (received_error == simple_config_Configuration_Error_IP_address_conflict)
       
  4167 			{
       
  4168 				m_handshake_error = eap_status_ip_address_conflict;
       
  4169 			}
       
  4170 			else if (received_error == simple_config_Configuration_Error_Couldnt_connect_to_Registrar)
       
  4171 			{
       
  4172 				m_handshake_error = eap_status_could_not_connect_to_registrar;
       
  4173 			}
       
  4174 			else if (received_error == simple_config_Configuration_Error_Multiple_PBC_sessions_detected)
       
  4175 			{
       
  4176 				m_handshake_error = eap_status_multiple_pbc_sessions_detected;
       
  4177 			}
       
  4178 			else if (received_error == simple_config_Configuration_Error_Rogue_activity_suspected)
       
  4179 			{
       
  4180 				m_handshake_error = eap_status_rogue_activity_suspected;
       
  4181 			}
       
  4182 			else if (received_error == simple_config_Configuration_Error_Device_busy)
       
  4183 			{
       
  4184 				m_handshake_error = eap_status_device_busy;
       
  4185 			}
       
  4186 			else if (received_error == simple_config_Configuration_Error_Setup_locked)
       
  4187 			{
       
  4188 				m_handshake_error = eap_status_setup_locked;
       
  4189 			}
       
  4190 			else if (received_error == simple_config_Configuration_Error_Message_Timeout)
       
  4191 			{
       
  4192 				m_handshake_error = eap_status_message_timeout;
       
  4193 			}
       
  4194 			else if (received_error == simple_config_Configuration_Error_Registration_Session_Timeout)
       
  4195 			{
       
  4196 				m_handshake_error = eap_status_registration_session_timeout;
       
  4197 			}
       
  4198 			else if (received_error == simple_config_Configuration_Error_Device_Password_Auth_Failure)
       
  4199 			{
       
  4200 				m_handshake_error = eap_status_device_password_authentication_failure;
       
  4201 			}
       
  4202 		}
       
  4203 
       
  4204 	}
       
  4205 
       
  4206 	if (m_handshake_error == eap_status_ok)
       
  4207 	{
       
  4208 		m_handshake_error = eap_status_authentication_failure;
       
  4209 	}
       
  4210 
       
  4211 	status = initialize_M2D_received_timeout();
       
  4212 	if (status != eap_status_ok)
       
  4213 	{
       
  4214 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4215 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4216 	}
       
  4217 
       
  4218 	{
       
  4219 		simple_config_payloads_c * const copied_payloads = payloads->copy();
       
  4220 
       
  4221 		if (copied_payloads == 0
       
  4222 			|| copied_payloads->get_is_valid() == false)
       
  4223 		{
       
  4224 			delete copied_payloads;
       
  4225 
       
  4226 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4227 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4228 		}
       
  4229 
       
  4230 		status = m_M2D_payloads.add_object(copied_payloads, true);
       
  4231 		if (status != eap_status_ok)
       
  4232 		{
       
  4233 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4234 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4235 		}
       
  4236 	}
       
  4237 
       
  4238 	status = send_WSC_ACK();
       
  4239 	if (status != eap_status_ok)
       
  4240 	{
       
  4241 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4242 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4243 	}
       
  4244 
       
  4245 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4246 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4247 }
       
  4248 
       
  4249 //--------------------------------------------------
       
  4250 
       
  4251 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  4252 
       
  4253 static const simple_config_Attribute_Type_e needed_payloads_of_M3[]
       
  4254 	= {
       
  4255 		simple_config_Attribute_Type_Version,
       
  4256 		simple_config_Attribute_Type_Message_Type,
       
  4257 		simple_config_Attribute_Type_Registrar_Nonce,
       
  4258 		simple_config_Attribute_Type_E_Hash1,
       
  4259 		simple_config_Attribute_Type_E_Hash2,
       
  4260 		simple_config_Attribute_Type_Authenticator,
       
  4261 	};
       
  4262 
       
  4263 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M3(
       
  4264 	const simple_config_payloads_c * const payloads)
       
  4265 {
       
  4266 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4267 
       
  4268 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4269 	EAP_TRACE_DEBUG(
       
  4270 		m_am_tools,
       
  4271 		TRACE_FLAGS_DEFAULT,
       
  4272 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M3()\n"),
       
  4273 		 (m_is_client == true ? "client": "server")));
       
  4274 
       
  4275 	if (verify_state(simple_config_state_wait_M3) == false)
       
  4276 	{
       
  4277 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4278 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4279 	}
       
  4280 
       
  4281 	eap_status_e status = payloads->check_payloads_existense(
       
  4282 		needed_payloads_of_M3, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4283 		sizeof(needed_payloads_of_M3)/sizeof(needed_payloads_of_M3[0]));
       
  4284 	if (status != eap_status_ok)
       
  4285 	{
       
  4286 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4287 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4288 	}
       
  4289 
       
  4290 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4291 	// Save E-Hash1 and E-Hash2
       
  4292 
       
  4293 	status = payloads->get_attribute_data(
       
  4294 		simple_config_Attribute_Type_E_Hash1,
       
  4295 		&m_EHash1);
       
  4296 	if (status != eap_status_ok)
       
  4297 	{
       
  4298 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4299 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4300 	}
       
  4301 
       
  4302 	status = payloads->get_attribute_data(
       
  4303 		simple_config_Attribute_Type_E_Hash2,
       
  4304 		&m_EHash2);
       
  4305 	if (status != eap_status_ok)
       
  4306 	{
       
  4307 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4308 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4309 	}
       
  4310 
       
  4311 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4312 
       
  4313 	status = send_M4();
       
  4314 	if (status != eap_status_ok)
       
  4315 	{
       
  4316 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4317 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4318 	}
       
  4319 
       
  4320 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4321 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4322 }
       
  4323 
       
  4324 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  4325 
       
  4326 //--------------------------------------------------
       
  4327 
       
  4328 static const simple_config_Attribute_Type_e needed_payloads_of_M4[]
       
  4329 	= {
       
  4330 		simple_config_Attribute_Type_Version,
       
  4331 		simple_config_Attribute_Type_Message_Type,
       
  4332 		simple_config_Attribute_Type_Enrollee_Nonce,
       
  4333 		simple_config_Attribute_Type_R_Hash1,
       
  4334 		simple_config_Attribute_Type_R_Hash2,
       
  4335 		simple_config_Attribute_Type_Encrypted_Settings,
       
  4336 		simple_config_Attribute_Type_Authenticator,
       
  4337 	};
       
  4338 
       
  4339 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M4(
       
  4340 	const simple_config_payloads_c * const payloads)
       
  4341 {
       
  4342 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4343 
       
  4344 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4345 	EAP_TRACE_DEBUG(
       
  4346 		m_am_tools,
       
  4347 		TRACE_FLAGS_DEFAULT,
       
  4348 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M4()\n"),
       
  4349 		 (m_is_client == true ? "client": "server")));
       
  4350 
       
  4351 	if (verify_state(simple_config_state_wait_M4) == false)
       
  4352 	{
       
  4353 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4354 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4355 	}
       
  4356 
       
  4357 	eap_status_e status = payloads->check_payloads_existense(
       
  4358 		needed_payloads_of_M4, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4359 		sizeof(needed_payloads_of_M4)/sizeof(needed_payloads_of_M4[0]));
       
  4360 	if (status != eap_status_ok)
       
  4361 	{
       
  4362 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4363 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4364 	}
       
  4365 
       
  4366 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4367 	// Save R-Hash1 and R-Hash2
       
  4368 
       
  4369 	status = payloads->get_attribute_data(
       
  4370 		simple_config_Attribute_Type_R_Hash1,
       
  4371 		&m_RHash1);
       
  4372 	if (status != eap_status_ok)
       
  4373 	{
       
  4374 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4375 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4376 	}
       
  4377 
       
  4378 	status = payloads->get_attribute_data(
       
  4379 		simple_config_Attribute_Type_R_Hash2,
       
  4380 		&m_RHash2);
       
  4381 	if (status != eap_status_ok)
       
  4382 	{
       
  4383 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4384 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4385 	}
       
  4386 
       
  4387 	{
       
  4388 		// Decrypt Encrypted Settings.
       
  4389 		simple_config_variable_data_c * const Encrypted_Settings
       
  4390 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings);
       
  4391 		if (Encrypted_Settings == 0)
       
  4392 		{
       
  4393 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4394 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  4395 		}
       
  4396 
       
  4397 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  4398 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  4399 
       
  4400 		if (plaintext_payloads == 0
       
  4401 			|| plaintext_payloads->get_is_valid() == false)
       
  4402 		{
       
  4403 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4404 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4405 		}
       
  4406 
       
  4407 		status = decrypt_payloads(
       
  4408 			&m_auth_key,
       
  4409 			&m_key_wrap_key,
       
  4410 			Encrypted_Settings,
       
  4411 			plaintext_payloads);
       
  4412 		if (status != eap_status_ok)
       
  4413 		{
       
  4414 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4415 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4416 		}
       
  4417 
       
  4418 
       
  4419 		status = plaintext_payloads->get_attribute_data(
       
  4420 			simple_config_Attribute_Type_R_SNonce1,
       
  4421 			&m_R_SNonce1);
       
  4422 		if (status != eap_status_ok)
       
  4423 		{
       
  4424 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4425 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4426 		}
       
  4427 	}
       
  4428 
       
  4429 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4430 
       
  4431 	{
       
  4432 		eap_variable_data_c local_RHash1(m_am_tools);
       
  4433 
       
  4434 		if (local_RHash1.get_is_valid() == false)
       
  4435 		{
       
  4436 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4437 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4438 		}
       
  4439 
       
  4440 		// Verify m_R_SNonce1 and m_RHash1.
       
  4441 		status = generate_er_hashs(
       
  4442 			true,
       
  4443 			&m_device_password,
       
  4444 			&m_own_public_dhe_key,
       
  4445 			&m_peer_public_dhe_key,
       
  4446 			&m_PSK1,
       
  4447 			&m_R_SNonce1,
       
  4448 			&local_RHash1,
       
  4449 			0,
       
  4450 			0,
       
  4451 			0);
       
  4452 		if (status != eap_status_ok)
       
  4453 		{
       
  4454 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4455 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4456 		}
       
  4457 
       
  4458 		// Compare RHash1.
       
  4459 		if (local_RHash1.compare(&m_RHash1) != 0)
       
  4460 		{
       
  4461 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4462 			return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure);
       
  4463 		}
       
  4464 	}
       
  4465 
       
  4466 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4467 
       
  4468 	status = send_M5();
       
  4469 	if (status != eap_status_ok)
       
  4470 	{
       
  4471 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4472 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4473 	}
       
  4474 
       
  4475 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4476 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4477 }
       
  4478 
       
  4479 //--------------------------------------------------
       
  4480 
       
  4481 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  4482 
       
  4483 static const simple_config_Attribute_Type_e needed_payloads_of_M5[]
       
  4484 	= {
       
  4485 		simple_config_Attribute_Type_Version,
       
  4486 		simple_config_Attribute_Type_Message_Type,
       
  4487 		simple_config_Attribute_Type_Registrar_Nonce,
       
  4488 		simple_config_Attribute_Type_Encrypted_Settings,
       
  4489 		simple_config_Attribute_Type_Authenticator,
       
  4490 	};
       
  4491 
       
  4492 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M5(
       
  4493 	const simple_config_payloads_c * const payloads)
       
  4494 {
       
  4495 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4496 
       
  4497 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4498 	EAP_TRACE_DEBUG(
       
  4499 		m_am_tools,
       
  4500 		TRACE_FLAGS_DEFAULT,
       
  4501 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M5()\n"),
       
  4502 		 (m_is_client == true ? "client": "server")));
       
  4503 
       
  4504 	if (verify_state(simple_config_state_wait_M5) == false)
       
  4505 	{
       
  4506 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4507 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4508 	}
       
  4509 
       
  4510 	eap_status_e status = payloads->check_payloads_existense(
       
  4511 		needed_payloads_of_M5, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4512 		sizeof(needed_payloads_of_M5)/sizeof(needed_payloads_of_M5[0]));
       
  4513 	if (status != eap_status_ok)
       
  4514 	{
       
  4515 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4516 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4517 	}
       
  4518 
       
  4519 	{
       
  4520 		// Decrypt Encrypted Settings.
       
  4521 		simple_config_variable_data_c * const Encrypted_Settings
       
  4522 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings);
       
  4523 		if (Encrypted_Settings == 0)
       
  4524 		{
       
  4525 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4526 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  4527 		}
       
  4528 
       
  4529 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  4530 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  4531 
       
  4532 		if (plaintext_payloads == 0
       
  4533 			|| plaintext_payloads->get_is_valid() == false)
       
  4534 		{
       
  4535 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4536 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4537 		}
       
  4538 
       
  4539 		status = decrypt_payloads(
       
  4540 			&m_auth_key,
       
  4541 			&m_key_wrap_key,
       
  4542 			Encrypted_Settings,
       
  4543 			plaintext_payloads);
       
  4544 		if (status != eap_status_ok)
       
  4545 		{
       
  4546 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4547 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4548 		}
       
  4549 
       
  4550 
       
  4551 		status = plaintext_payloads->get_attribute_data(
       
  4552 			simple_config_Attribute_Type_E_SNonce1,
       
  4553 			&m_E_SNonce1);
       
  4554 		if (status != eap_status_ok)
       
  4555 		{
       
  4556 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4557 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4558 		}
       
  4559 	}
       
  4560 
       
  4561 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4562 
       
  4563 	{
       
  4564 		eap_variable_data_c local_EHash1(m_am_tools);
       
  4565 
       
  4566 		if (local_EHash1.get_is_valid() == false)
       
  4567 		{
       
  4568 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4569 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4570 		}
       
  4571 
       
  4572 		// Verify m_E_SNonce1 and m_EHash1.
       
  4573 		status = generate_er_hashs(
       
  4574 			true,
       
  4575 			&m_device_password,
       
  4576 			&m_peer_public_dhe_key,
       
  4577 			&m_own_public_dhe_key,
       
  4578 			&m_PSK1,
       
  4579 			&m_E_SNonce1,
       
  4580 			&local_EHash1,
       
  4581 			0,
       
  4582 			0,
       
  4583 			0);
       
  4584 		if (status != eap_status_ok)
       
  4585 		{
       
  4586 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4587 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4588 		}
       
  4589 
       
  4590 		// Compare EHash1.
       
  4591 		if (local_EHash1.compare(&m_EHash1) != 0)
       
  4592 		{
       
  4593 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4594 			return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure);
       
  4595 		}
       
  4596 	}
       
  4597 
       
  4598 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4599 
       
  4600 	status = send_M6();
       
  4601 	if (status != eap_status_ok)
       
  4602 	{
       
  4603 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4604 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4605 	}
       
  4606 
       
  4607 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4608 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4609 }
       
  4610 
       
  4611 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  4612 
       
  4613 //--------------------------------------------------
       
  4614 
       
  4615 static const simple_config_Attribute_Type_e needed_payloads_of_M6[]
       
  4616 	= {
       
  4617 		simple_config_Attribute_Type_Version,
       
  4618 		simple_config_Attribute_Type_Message_Type,
       
  4619 		simple_config_Attribute_Type_Enrollee_Nonce,
       
  4620 		simple_config_Attribute_Type_Encrypted_Settings,
       
  4621 		simple_config_Attribute_Type_Authenticator,
       
  4622 	};
       
  4623 
       
  4624 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M6(
       
  4625 	const simple_config_payloads_c * const payloads)
       
  4626 {
       
  4627 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4628 
       
  4629 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4630 	EAP_TRACE_DEBUG(
       
  4631 		m_am_tools,
       
  4632 		TRACE_FLAGS_DEFAULT,
       
  4633 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M6()\n"),
       
  4634 		 (m_is_client == true ? "client": "server")));
       
  4635 
       
  4636 	if (verify_state(simple_config_state_wait_M6) == false)
       
  4637 	{
       
  4638 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4639 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4640 	}
       
  4641 
       
  4642 	eap_status_e status = payloads->check_payloads_existense(
       
  4643 		needed_payloads_of_M6, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4644 		sizeof(needed_payloads_of_M6)/sizeof(needed_payloads_of_M6[0]));
       
  4645 	if (status != eap_status_ok)
       
  4646 	{
       
  4647 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4648 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4649 	}
       
  4650 
       
  4651 	{
       
  4652 		// Decrypt Encrypted Settings.
       
  4653 		simple_config_variable_data_c * const Encrypted_Settings
       
  4654 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings);
       
  4655 		if (Encrypted_Settings == 0)
       
  4656 		{
       
  4657 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4658 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  4659 		}
       
  4660 
       
  4661 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  4662 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  4663 
       
  4664 		if (plaintext_payloads == 0
       
  4665 			|| plaintext_payloads->get_is_valid() == false)
       
  4666 		{
       
  4667 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4668 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4669 		}
       
  4670 
       
  4671 		status = decrypt_payloads(
       
  4672 			&m_auth_key,
       
  4673 			&m_key_wrap_key,
       
  4674 			Encrypted_Settings,
       
  4675 			plaintext_payloads);
       
  4676 		if (status != eap_status_ok)
       
  4677 		{
       
  4678 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4679 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4680 		}
       
  4681 
       
  4682 
       
  4683 		status = plaintext_payloads->get_attribute_data(
       
  4684 			simple_config_Attribute_Type_R_SNonce2,
       
  4685 			&m_R_SNonce2);
       
  4686 		if (status != eap_status_ok)
       
  4687 		{
       
  4688 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4689 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4690 		}
       
  4691 	}
       
  4692 
       
  4693 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4694 
       
  4695 	{
       
  4696 		eap_variable_data_c local_RHash2(m_am_tools);
       
  4697 
       
  4698 		if (local_RHash2.get_is_valid() == false)
       
  4699 		{
       
  4700 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4701 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4702 		}
       
  4703 
       
  4704 		// Verify m_R_SNonce2 and m_RHash2.
       
  4705 		status = generate_er_hashs(
       
  4706 			true,
       
  4707 			&m_device_password,
       
  4708 			&m_own_public_dhe_key,
       
  4709 			&m_peer_public_dhe_key,
       
  4710 			0,
       
  4711 			0,
       
  4712 			0,
       
  4713 			&m_PSK2,
       
  4714 			&m_R_SNonce2,
       
  4715 			&local_RHash2);
       
  4716 		if (status != eap_status_ok)
       
  4717 		{
       
  4718 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4719 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4720 		}
       
  4721 
       
  4722 		// Compare RHash2.
       
  4723 		if (local_RHash2.compare(&m_RHash2) != 0)
       
  4724 		{
       
  4725 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4726 			return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure);
       
  4727 		}
       
  4728 	}
       
  4729 
       
  4730 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4731 
       
  4732 	status = send_M7();
       
  4733 	if (status != eap_status_ok)
       
  4734 	{
       
  4735 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4736 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4737 	}
       
  4738 
       
  4739 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4740 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4741 }
       
  4742 
       
  4743 //--------------------------------------------------
       
  4744 
       
  4745 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  4746 
       
  4747 static const simple_config_Attribute_Type_e needed_payloads_of_M7[]
       
  4748 	= {
       
  4749 		simple_config_Attribute_Type_Version,
       
  4750 		simple_config_Attribute_Type_Message_Type,
       
  4751 		simple_config_Attribute_Type_Registrar_Nonce,
       
  4752 		simple_config_Attribute_Type_Encrypted_Settings,
       
  4753 		simple_config_Attribute_Type_Authenticator,
       
  4754 	};
       
  4755 
       
  4756 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M7(
       
  4757 	const simple_config_payloads_c * const payloads)
       
  4758 {
       
  4759 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4760 
       
  4761 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4762 	EAP_TRACE_DEBUG(
       
  4763 		m_am_tools,
       
  4764 		TRACE_FLAGS_DEFAULT,
       
  4765 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M7()\n"),
       
  4766 		 (m_is_client == true ? "client": "server")));
       
  4767 
       
  4768 	if (verify_state(simple_config_state_wait_M7) == false)
       
  4769 	{
       
  4770 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4771 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4772 	}
       
  4773 
       
  4774 	eap_status_e status = payloads->check_payloads_existense(
       
  4775 		needed_payloads_of_M7, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4776 		sizeof(needed_payloads_of_M7)/sizeof(needed_payloads_of_M7[0]));
       
  4777 	if (status != eap_status_ok)
       
  4778 	{
       
  4779 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4780 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4781 	}
       
  4782 
       
  4783 	{
       
  4784 		// Decrypt Encrypted Settings.
       
  4785 		simple_config_variable_data_c * const Encrypted_Settings
       
  4786 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings);
       
  4787 		if (Encrypted_Settings == 0)
       
  4788 		{
       
  4789 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4790 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  4791 		}
       
  4792 
       
  4793 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  4794 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  4795 
       
  4796 		if (plaintext_payloads == 0
       
  4797 			|| plaintext_payloads->get_is_valid() == false)
       
  4798 		{
       
  4799 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4800 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4801 		}
       
  4802 
       
  4803 		status = decrypt_payloads(
       
  4804 			&m_auth_key,
       
  4805 			&m_key_wrap_key,
       
  4806 			Encrypted_Settings,
       
  4807 			plaintext_payloads);
       
  4808 		if (status != eap_status_ok)
       
  4809 		{
       
  4810 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4811 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4812 		}
       
  4813 
       
  4814 
       
  4815 		status = plaintext_payloads->get_attribute_data(
       
  4816 			simple_config_Attribute_Type_E_SNonce2,
       
  4817 			&m_E_SNonce2);
       
  4818 		if (status != eap_status_ok)
       
  4819 		{
       
  4820 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4821 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4822 		}
       
  4823 	}
       
  4824 
       
  4825 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4826 
       
  4827 	{
       
  4828 		eap_variable_data_c local_EHash2(m_am_tools);
       
  4829 
       
  4830 		if (local_EHash2.get_is_valid() == false)
       
  4831 		{
       
  4832 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4833 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4834 		}
       
  4835 
       
  4836 		// Verify m_E_SNonce2 and m_EHash2.
       
  4837 		status = generate_er_hashs(
       
  4838 			true,
       
  4839 			&m_device_password,
       
  4840 			&m_peer_public_dhe_key,
       
  4841 			&m_own_public_dhe_key,
       
  4842 			0,
       
  4843 			0,
       
  4844 			0,
       
  4845 			&m_PSK2,
       
  4846 			&m_E_SNonce2,
       
  4847 			&local_EHash2);
       
  4848 		if (status != eap_status_ok)
       
  4849 		{
       
  4850 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4851 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4852 		}
       
  4853 
       
  4854 		// Compare RHash2.
       
  4855 		if (local_EHash2.compare(&m_EHash2) != 0)
       
  4856 		{
       
  4857 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4858 			return EAP_STATUS_RETURN(m_am_tools, eap_status_device_password_authentication_failure);
       
  4859 		}
       
  4860 	}
       
  4861 
       
  4862 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4863 
       
  4864 	status = send_M8();
       
  4865 	if (status != eap_status_ok)
       
  4866 	{
       
  4867 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4868 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4869 	}
       
  4870 
       
  4871 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4872 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4873 }
       
  4874 
       
  4875 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  4876 
       
  4877 //--------------------------------------------------
       
  4878 
       
  4879 eap_status_e simple_config_record_c::fix_incorrect_network_key(
       
  4880 	eap_variable_data_c * const network_key, 
       
  4881 	const simple_config_Authentication_Type_e authentication_type)
       
  4882 {
       
  4883 	if (authentication_type == simple_config_Authentication_Type_WPAPSK
       
  4884 		|| authentication_type == simple_config_Authentication_Type_WPA2PSK)
       
  4885 	{
       
  4886 		// For example, Vista External Registar sends incorrect WPA(2)PSK that includes terminating NULL.
       
  4887 		// Check the PSK is passphrase <= 64 bytes in length and the last byte is 0x00.
       
  4888 		const u32_t ONE_CHARACTER_LENGTH = 1ul;
       
  4889 		const u8_t STRING_TERMINATING_NULL = 0x00;
       
  4890 
       
  4891 		if (network_key->get_data_length() > 0ul)
       
  4892 		{
       
  4893 			if (network_key->get_data_offset(network_key->get_data_length()-1ul, ONE_CHARACTER_LENGTH) != 0
       
  4894 			&& *(network_key->get_data_offset(network_key->get_data_length()-1ul, ONE_CHARACTER_LENGTH)) == STRING_TERMINATING_NULL)
       
  4895 			{
       
  4896 				// Check for passphrase characters. If it includes only passphrase characters and the last byte is NULL
       
  4897 				// we assume it is broken passphrase.
       
  4898 
       
  4899 				bool remove_terminating_null = true;
       
  4900 
       
  4901 				if (network_key->get_data_length() == 2ul*EAPOL_WPA_PSK_LENGTH_BYTES)
       
  4902 				{
       
  4903 					for (u32_t ind = 0; ind < network_key->get_data_length()-1ul; ind++)
       
  4904 					{
       
  4905 						u8_t * const character = network_key->get_data_offset(ind, 1);
       
  4906 						if (character == 0)
       
  4907 						{
       
  4908 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4909 							return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  4910 						}
       
  4911 
       
  4912 						if((*character < 32) || (126 < *character))
       
  4913 						{
       
  4914 							// This is not passphrase.
       
  4915 							remove_terminating_null = false;
       
  4916 							break;
       
  4917 						}
       
  4918 					}
       
  4919 				}
       
  4920 				else
       
  4921 				{
       
  4922 					// Because the length is less than 64 bytes, this is passprase, and we remove the terminating NULL.
       
  4923 				}
       
  4924 
       
  4925 				if (remove_terminating_null == true)
       
  4926 				{
       
  4927 					network_key->set_data_length(network_key->get_data_length()-1ul);
       
  4928 				}
       
  4929 			}
       
  4930 		}
       
  4931 	}
       
  4932 
       
  4933 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4934 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4935 }
       
  4936 
       
  4937 //--------------------------------------------------
       
  4938 
       
  4939 static const simple_config_Attribute_Type_e needed_payloads_of_M8[]
       
  4940 	= {
       
  4941 		simple_config_Attribute_Type_Version,
       
  4942 		simple_config_Attribute_Type_Message_Type,
       
  4943 	};
       
  4944 
       
  4945 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_M8(
       
  4946 	const simple_config_payloads_c * const payloads)
       
  4947 {
       
  4948 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4949 
       
  4950 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4951 	EAP_TRACE_DEBUG(
       
  4952 		m_am_tools,
       
  4953 		TRACE_FLAGS_DEFAULT,
       
  4954 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_M8()\n"),
       
  4955 		 (m_is_client == true ? "client": "server")));
       
  4956 
       
  4957 	if (verify_state(simple_config_state_wait_M8) == false)
       
  4958 	{
       
  4959 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4960 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  4961 	}
       
  4962 
       
  4963 	eap_status_e status = payloads->check_payloads_existense(
       
  4964 		needed_payloads_of_M8, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  4965 		sizeof(needed_payloads_of_M8)/sizeof(needed_payloads_of_M8[0]));
       
  4966 	if (status != eap_status_ok)
       
  4967 	{
       
  4968 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4969 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4970 	}
       
  4971 
       
  4972 
       
  4973 	simple_config_payloads_c * other_configuration = new simple_config_payloads_c(m_am_tools);
       
  4974 	eap_automatic_variable_c<simple_config_payloads_c> automatic_other_configuration(m_am_tools, other_configuration);
       
  4975 	
       
  4976 	if (other_configuration == 0
       
  4977 		|| other_configuration->get_is_valid() == false)
       
  4978 	{
       
  4979 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4980 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4981 	}
       
  4982 
       
  4983 	eap_array_c<simple_config_credential_c> * credential_array = new eap_array_c<simple_config_credential_c>(m_am_tools);
       
  4984 	eap_automatic_variable_c<eap_array_c<simple_config_credential_c> > automatic_credential_array(m_am_tools, credential_array);
       
  4985 
       
  4986 	if (credential_array == 0)
       
  4987 	{
       
  4988 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4989 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4990 	}
       
  4991 
       
  4992 	{
       
  4993 		// Decrypt Encrypted Settings.
       
  4994 		simple_config_variable_data_c * const Encrypted_Settings
       
  4995 			= payloads->get_attribute_pointer(simple_config_Attribute_Type_Encrypted_Settings);
       
  4996 		if (Encrypted_Settings == 0)
       
  4997 		{
       
  4998 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4999 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  5000 		}
       
  5001 
       
  5002 		simple_config_payloads_c * plaintext_payloads = new simple_config_payloads_c(m_am_tools);
       
  5003 		eap_automatic_variable_c<simple_config_payloads_c> automatic_plaintext_payloads(m_am_tools, plaintext_payloads);
       
  5004 
       
  5005 		if (plaintext_payloads == 0
       
  5006 			|| plaintext_payloads->get_is_valid() == false)
       
  5007 		{
       
  5008 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5009 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5010 		}
       
  5011 
       
  5012 		status = decrypt_payloads(
       
  5013 			&m_auth_key,
       
  5014 			&m_key_wrap_key,
       
  5015 			Encrypted_Settings,
       
  5016 			plaintext_payloads);
       
  5017 		if (status != eap_status_ok)
       
  5018 		{
       
  5019 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5020 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5021 		}
       
  5022 
       
  5023 
       
  5024 		simple_config_variable_data_c * Credential_Attribute
       
  5025 			= plaintext_payloads->get_attribute_pointer(simple_config_Attribute_Type_Credential);
       
  5026 		if (Credential_Attribute == 0)
       
  5027 		{
       
  5028 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5029 			return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  5030 		}
       
  5031 
       
  5032 		do
       
  5033 		{
       
  5034 			simple_config_credential_c * credential = new simple_config_credential_c(m_am_tools);
       
  5035 
       
  5036 			eap_automatic_variable_c<simple_config_credential_c> automatic_credential(m_am_tools, credential);
       
  5037 
       
  5038 			if (credential == 0
       
  5039 				|| credential->get_is_valid() == false)
       
  5040 			{
       
  5041 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5042 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5043 			}
       
  5044 
       
  5045 			simple_config_payloads_c * Credential_payloads = new simple_config_payloads_c(m_am_tools);
       
  5046 			eap_automatic_variable_c<simple_config_payloads_c> automatic_Credential_payloads(m_am_tools, Credential_payloads);
       
  5047 	
       
  5048 			if (Credential_payloads == 0
       
  5049 				|| Credential_payloads->get_is_valid() == false)
       
  5050 			{
       
  5051 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5052 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5053 			}
       
  5054 
       
  5055 			u32_t payload_length(Credential_Attribute->get_data_length());
       
  5056 			u32_t padding_length(0ul);
       
  5057 
       
  5058 			status = Credential_payloads->parse_simple_config_payloads(
       
  5059 				Credential_Attribute->get_data(Credential_Attribute->get_data_length()),
       
  5060 				&payload_length,
       
  5061 				&padding_length);
       
  5062 			if (status != eap_status_ok)
       
  5063 			{
       
  5064 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5065 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5066 			}
       
  5067 			
       
  5068 			{
       
  5069 				u8_t network_index(0ul);
       
  5070 
       
  5071 				status = Credential_payloads->get_attribute_data(
       
  5072 					simple_config_Attribute_Type_Network_Index,
       
  5073 					&network_index);
       
  5074 				if (status != eap_status_ok)
       
  5075 				{
       
  5076 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5077 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5078 				}
       
  5079 
       
  5080 				credential->set_network_index(network_index);
       
  5081 			}
       
  5082 
       
  5083 			status = Credential_payloads->get_attribute_data(
       
  5084 				simple_config_Attribute_Type_SSID,
       
  5085 				credential->get_SSID());
       
  5086 			if (status != eap_status_ok)
       
  5087 			{
       
  5088 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5089 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5090 			}
       
  5091 
       
  5092 			{
       
  5093 				u16_t data(0ul);
       
  5094 
       
  5095 				status = Credential_payloads->get_attribute_data(
       
  5096 					simple_config_Attribute_Type_Authentication_Type,
       
  5097 					&data);
       
  5098 				if (status != eap_status_ok)
       
  5099 				{
       
  5100 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5101 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5102 				}
       
  5103 
       
  5104 				credential->set_Authentication_Type(static_cast<simple_config_Authentication_Type_e>(data));
       
  5105 			}
       
  5106 
       
  5107 			{
       
  5108 				u16_t data(0ul);
       
  5109 
       
  5110 				status = Credential_payloads->get_attribute_data(
       
  5111 					simple_config_Attribute_Type_Encryption_Type,
       
  5112 					&data);
       
  5113 				if (status != eap_status_ok)
       
  5114 				{
       
  5115 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5116 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5117 				}
       
  5118 
       
  5119 				credential->set_Encryption_Type(static_cast<simple_config_Encryption_Type_e>(data));
       
  5120 			}
       
  5121 
       
  5122 			{
       
  5123 				simple_config_variable_data_c * Network_Key_Index
       
  5124 					= Credential_payloads->get_attribute_pointer(simple_config_Attribute_Type_Network_Key_Index);
       
  5125 				// NOTE, this is optional. Omitted Network_Key_Index defaults to 1.
       
  5126 
       
  5127 				simple_config_variable_data_c * Network_Key
       
  5128 					= Credential_payloads->get_attribute_pointer(simple_config_Attribute_Type_Network_Key);
       
  5129 
       
  5130 				
       
  5131 				if ( Network_Key == 0 
       
  5132 				        && (credential->get_Authentication_Type() != simple_config_Authentication_Type_Open 
       
  5133 				            || credential->get_Encryption_Type() != simple_config_Encryption_Type_None) )
       
  5134 				{
       
  5135 					// We fail since the required Network Key TLV is missing in a non-open mode.
       
  5136 				    EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5137 					return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  5138 				} 
       
  5139 				else if ( Network_Key == 0 )
       
  5140 				{
       
  5141                     // This is implemented for IOP reasons. The AP does not send the 
       
  5142                     // Network Key TLV (required TLV in the spec) in the Open security mode so we do not 
       
  5143                     // require it. The TLV in Open mode would be empty anyway (length would be zero).
       
  5144 				
       
  5145 		            EAP_TRACE_DEBUG(
       
  5146 		                    m_am_tools,
       
  5147 		                    TRACE_FLAGS_DEFAULT,
       
  5148 		                    (EAPL("simple_config_record_c::process_M8(): Network Key TLV missing but Open network. This is ok.\n")));
       
  5149 				
       
  5150 				    // Just add empty parameters
       
  5151 				    network_key_and_index_c * const obj = new network_key_and_index_c(m_am_tools);
       
  5152 				    if(obj != 0)
       
  5153 				    {                        
       
  5154                         status = credential->get_network_keys()->add_object(obj, true);
       
  5155                         if (status != eap_status_ok)
       
  5156                         {
       
  5157                             EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5158                             return EAP_STATUS_RETURN(m_am_tools, status);
       
  5159                         }
       
  5160 				    }
       
  5161 
       
  5162                 }
       
  5163 				else
       
  5164 				{
       
  5165 				    // Normal case, i.e Network Key TLV exists
       
  5166                     do
       
  5167     				{
       
  5168     					network_key_and_index_c * const obj = new network_key_and_index_c(m_am_tools);
       
  5169     
       
  5170     					if (obj != 0)
       
  5171     					{
       
  5172     						if (Network_Key_Index != 0)
       
  5173     						{
       
  5174     							const u8_t * const network_key_index = Network_Key_Index->get_header()->get_data(sizeof(u8_t));
       
  5175     							if (network_key_index == 0)
       
  5176     							{
       
  5177     								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5178     								return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  5179     							}
       
  5180     
       
  5181     							obj->set_network_key_index(*network_key_index);
       
  5182     						}
       
  5183     						else
       
  5184     						{
       
  5185     							obj->set_network_key_index(SIMPLE_CONFIG_DEFAULT_NETWORK_KEY_INDEX);
       
  5186     						}
       
  5187     
       
  5188     						status = obj->get_network_key()->set_copy_of_buffer(
       
  5189     							Network_Key->get_header()->get_data(
       
  5190     								Network_Key->get_header()->get_data_length()),
       
  5191     							Network_Key->get_header()->get_data_length());
       
  5192     						if (status != eap_status_ok)
       
  5193     						{
       
  5194     							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5195     							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5196     						}
       
  5197     
       
  5198     						// For example, Vista External Registar sends incorrect WPA(2)PSK that includes terminating NULL.
       
  5199     						status = fix_incorrect_network_key(obj->get_network_key(), credential->get_Authentication_Type());
       
  5200     						if (status != eap_status_ok)
       
  5201     						{
       
  5202     							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5203     							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5204     						}
       
  5205     
       
  5206     
       
  5207     						status = credential->get_network_keys()->add_object(obj, true);
       
  5208     						if (status != eap_status_ok)
       
  5209     						{
       
  5210     							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5211     							return EAP_STATUS_RETURN(m_am_tools, status);
       
  5212     						}
       
  5213     					}
       
  5214     
       
  5215     					if (Network_Key_Index != 0)
       
  5216     					{
       
  5217     						Network_Key_Index = Network_Key_Index->get_next_payload_with_same_attribute_type();
       
  5218     					}
       
  5219     
       
  5220     					Network_Key = Network_Key->get_next_payload_with_same_attribute_type();
       
  5221     				}
       
  5222     				while(Network_Key != 0);
       
  5223     			}
       
  5224 			}
       
  5225 
       
  5226 			status = Credential_payloads->get_attribute_data(
       
  5227 				simple_config_Attribute_Type_MAC_Address,
       
  5228 				credential->get_MAC_address());
       
  5229 			if (status != eap_status_ok)
       
  5230 			{
       
  5231 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5232 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5233 			}
       
  5234 
       
  5235 			automatic_credential.do_not_free_variable();
       
  5236 
       
  5237 			status = credential_array->add_object(credential, true);
       
  5238 
       
  5239 			Credential_Attribute = Credential_Attribute->get_next_payload_with_same_attribute_type();
       
  5240 		}
       
  5241 		while (Credential_Attribute != 0);
       
  5242 
       
  5243 		// This is optional attribute.
       
  5244 		if (plaintext_payloads->get_attribute_pointer(
       
  5245 			simple_config_Attribute_Type_New_Password) != 0)
       
  5246 		{
       
  5247 			status = plaintext_payloads->get_attribute_data(
       
  5248 				simple_config_Attribute_Type_New_Password,
       
  5249 				&m_new_password);
       
  5250 			if (status != eap_status_ok
       
  5251 				&& status != eap_status_missing_payload)
       
  5252 			{
       
  5253 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5254 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5255 			}
       
  5256 		}
       
  5257 
       
  5258 		if (plaintext_payloads->get_attribute_pointer(
       
  5259 			simple_config_Attribute_Type_Device_Password_ID) != 0)
       
  5260 		{
       
  5261 			u16_t data(0ul);
       
  5262 
       
  5263 			// This is optional attribute.
       
  5264 			status = plaintext_payloads->get_attribute_data(
       
  5265 				simple_config_Attribute_Type_Device_Password_ID,
       
  5266 				&data);
       
  5267 			if (status != eap_status_ok
       
  5268 				&& status != eap_status_missing_payload)
       
  5269 			{
       
  5270 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5271 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5272 			}
       
  5273 
       
  5274 			if (status == eap_status_ok)
       
  5275 			{
       
  5276 				m_new_Device_Password_ID = static_cast<simple_config_Device_Password_ID_e>(data);
       
  5277 			}
       
  5278 		}
       
  5279 	}
       
  5280 
       
  5281 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  5282 
       
  5283 	status = m_am_simple_config_services->save_simple_config_session(
       
  5284 		simple_config_state_simple_config_success,
       
  5285 		credential_array,
       
  5286 		&m_new_password,
       
  5287 		m_new_Device_Password_ID,
       
  5288 		other_configuration);
       
  5289 	if (status != eap_status_ok)
       
  5290 	{
       
  5291 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5292 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5293 	}
       
  5294 
       
  5295 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  5296 
       
  5297 	status = send_WSC_Done();
       
  5298 	if (status != eap_status_ok)
       
  5299 	{
       
  5300 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5301 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5302 	}
       
  5303 
       
  5304 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5305 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5306 }
       
  5307 
       
  5308 //--------------------------------------------------
       
  5309 
       
  5310 static const simple_config_Attribute_Type_e needed_payloads_of_WSC_ACK[]
       
  5311 	= {
       
  5312 		simple_config_Attribute_Type_Version,
       
  5313 		simple_config_Attribute_Type_Message_Type,
       
  5314 	};
       
  5315 
       
  5316 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_WSC_ACK(
       
  5317 	const simple_config_payloads_c * const payloads)
       
  5318 {
       
  5319 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5320 
       
  5321 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5322 	EAP_TRACE_DEBUG(
       
  5323 		m_am_tools,
       
  5324 		TRACE_FLAGS_DEFAULT,
       
  5325 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_WSC_ACK()\n"),
       
  5326 		 (m_is_client == true ? "client": "server")));
       
  5327 
       
  5328 	if (verify_state(simple_config_state_wait_WSC_ACK) == false)
       
  5329 	{
       
  5330 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5331 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  5332 	}
       
  5333 
       
  5334 	eap_status_e status = payloads->check_payloads_existense(
       
  5335 		needed_payloads_of_WSC_ACK, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  5336 		sizeof(needed_payloads_of_WSC_ACK)/sizeof(needed_payloads_of_WSC_ACK[0]));
       
  5337 	if (status != eap_status_ok)
       
  5338 	{
       
  5339 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5340 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5341 	}
       
  5342 
       
  5343 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5344 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5345 }
       
  5346 
       
  5347 //--------------------------------------------------
       
  5348 
       
  5349 static const simple_config_Attribute_Type_e needed_payloads_of_WSC_NACK[]
       
  5350 	= {
       
  5351 		simple_config_Attribute_Type_Version,
       
  5352 		simple_config_Attribute_Type_Message_Type,
       
  5353 	};
       
  5354 
       
  5355 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_WSC_NACK(
       
  5356 	const simple_config_payloads_c * const payloads)
       
  5357 {
       
  5358 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5359 
       
  5360 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5361 	EAP_TRACE_DEBUG(
       
  5362 		m_am_tools,
       
  5363 		TRACE_FLAGS_DEFAULT,
       
  5364 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_WSC_NACK()\n"),
       
  5365 		 (m_is_client == true ? "client": "server")));
       
  5366 
       
  5367 	eap_status_e status = payloads->check_payloads_existense(
       
  5368 		needed_payloads_of_WSC_NACK, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  5369 		sizeof(needed_payloads_of_WSC_NACK)/sizeof(needed_payloads_of_WSC_NACK[0]));
       
  5370 	if (status != eap_status_ok)
       
  5371 	{
       
  5372 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5373 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5374 	}
       
  5375 
       
  5376 	if (m_handshake_error != eap_status_ok)
       
  5377 	{
       
  5378 		(void) send_error_notification(m_handshake_error);
       
  5379 	}
       
  5380 
       
  5381 	set_state(simple_config_state_failure);
       
  5382 
       
  5383 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5384 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5385 }
       
  5386 
       
  5387 //--------------------------------------------------
       
  5388 
       
  5389 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  5390 
       
  5391 static const simple_config_Attribute_Type_e needed_payloads_of_WSC_DONE[]
       
  5392 	= {
       
  5393 		simple_config_Attribute_Type_Version,
       
  5394 		simple_config_Attribute_Type_Message_Type,
       
  5395 	};
       
  5396 
       
  5397 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_WSC_DONE(
       
  5398 	const simple_config_payloads_c * const payloads)
       
  5399 {
       
  5400 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5401 
       
  5402 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5403 	EAP_TRACE_DEBUG(
       
  5404 		m_am_tools,
       
  5405 		TRACE_FLAGS_DEFAULT,
       
  5406 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_WSC_DONE()\n"),
       
  5407 		 (m_is_client == true ? "client": "server")));
       
  5408 
       
  5409 	if (verify_state(simple_config_state_wait_WSC_DONE) == false)
       
  5410 	{
       
  5411 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5412 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  5413 	}
       
  5414 
       
  5415 	eap_status_e status = payloads->check_payloads_existense(
       
  5416 		needed_payloads_of_WSC_DONE, // const simple_config_Attribute_Type_e * const needed_payloads,
       
  5417 		sizeof(needed_payloads_of_WSC_DONE)/sizeof(needed_payloads_of_WSC_DONE[0]));
       
  5418 	if (status != eap_status_ok)
       
  5419 	{
       
  5420 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5421 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5422 	}
       
  5423 
       
  5424 	set_state(simple_config_state_simple_config_success);
       
  5425 
       
  5426 	{
       
  5427 		// Send state notification to lower layer.
       
  5428 		eap_state_notification_c notification(
       
  5429 			m_am_tools,
       
  5430 			&m_send_network_id,
       
  5431 			m_is_client,
       
  5432 			eap_state_notification_generic,
       
  5433 			eap_protocol_layer_eap,
       
  5434 			eap_type_none,
       
  5435 			eap_state_none,
       
  5436 			eap_state_authentication_finished_successfully,
       
  5437 			0ul,
       
  5438 			false);
       
  5439 		get_type_partner()->state_notification(&notification);
       
  5440 	}
       
  5441 
       
  5442 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5443 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5444 }
       
  5445 
       
  5446 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  5447 
       
  5448 //--------------------------------------------------
       
  5449 
       
  5450 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_simple_config_attributes(
       
  5451 	const simple_config_payloads_c * const payloads)
       
  5452 {
       
  5453 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5454 
       
  5455 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5456 	EAP_TRACE_DEBUG(
       
  5457 		m_am_tools,
       
  5458 		TRACE_FLAGS_DEFAULT,
       
  5459 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_simple_config_attributes()\n"),
       
  5460 		 (m_is_client == true ? "client": "server")));
       
  5461 
       
  5462 	simple_config_variable_data_c * const message_type_payload
       
  5463 		= payloads->get_attribute_pointer(simple_config_Attribute_Type_Message_Type);
       
  5464 	if (message_type_payload == 0)
       
  5465 	{
       
  5466 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5467 		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  5468 	}
       
  5469 
       
  5470 	u8_t * const Message_type_data = message_type_payload->get_header()->get_data(sizeof(u8_t));
       
  5471 	if (Message_type_data == 0)
       
  5472 	{
       
  5473 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5474 		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  5475 	}
       
  5476 
       
  5477 	const simple_config_Message_Type_e Message_type(static_cast<simple_config_Message_Type_e>(*Message_type_data));
       
  5478 
       
  5479 	eap_status_e status(eap_status_process_general_error);
       
  5480 
       
  5481 
       
  5482 	{
       
  5483 		eap_simple_config_trace_string_c trace_string;
       
  5484 		EAP_UNREFERENCED_PARAMETER(trace_string);			
       
  5485 
       
  5486 		EAP_TRACE_DEBUG(
       
  5487 			m_am_tools,
       
  5488 			TRACE_FLAGS_DEFAULT,
       
  5489 			(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_simple_config_attributes(): Received message %s=%d\n"),
       
  5490 			 (m_is_client == true ? "client": "server"),
       
  5491 			 trace_string.get_message_type_string(Message_type),
       
  5492 			 Message_type));
       
  5493 	}
       
  5494 
       
  5495 
       
  5496 	switch(Message_type)
       
  5497 	{
       
  5498 	case simple_config_Message_Type_M1:
       
  5499 	case simple_config_Message_Type_M2:
       
  5500 	case simple_config_Message_Type_M2D:
       
  5501 		// Check is done later inside correcponding function.
       
  5502 		break;
       
  5503 	case simple_config_Message_Type_M3:
       
  5504 	case simple_config_Message_Type_M5:
       
  5505 	case simple_config_Message_Type_M7:
       
  5506 
       
  5507 		status = verify_nonces_and_authenticator(
       
  5508 			&m_auth_key,
       
  5509 			&m_enrollee_nonce,
       
  5510 			&m_registrar_nonce,
       
  5511 			payloads,
       
  5512 			false, // No Enrolle Nonce
       
  5513 			true, // Check Registrar Nonce
       
  5514 			true); // Check Authenticator
       
  5515 		if (status != eap_status_ok)
       
  5516 		{
       
  5517 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5518 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5519 		}
       
  5520 		break;
       
  5521 	case simple_config_Message_Type_M4:
       
  5522 	case simple_config_Message_Type_M6:
       
  5523 	case simple_config_Message_Type_M8:
       
  5524 		status = verify_nonces_and_authenticator(
       
  5525 			&m_auth_key,
       
  5526 			&m_enrollee_nonce,
       
  5527 			&m_registrar_nonce,
       
  5528 			payloads,
       
  5529 			true, // Check Enrolle Nonce
       
  5530 			false, // No Registrar Nonce
       
  5531 			true); // Check Authenticator
       
  5532 		if (status != eap_status_ok)
       
  5533 		{
       
  5534 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5535 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5536 		}
       
  5537 		break;
       
  5538 	case simple_config_Message_Type_WSC_ACK:
       
  5539 	case simple_config_Message_Type_WSC_NACK:
       
  5540 	case simple_config_Message_Type_WSC_DONE:
       
  5541 		{
       
  5542 			bool check_enrollee_nonce(true);
       
  5543 			bool check_registrar_nonce(true);
       
  5544 
       
  5545 			if (get_state() == simple_config_state_wait_M1)
       
  5546 			{
       
  5547 				check_enrollee_nonce = false;
       
  5548 				check_registrar_nonce = false;
       
  5549 			}
       
  5550 
       
  5551 			if (get_state() == simple_config_state_wait_M2)
       
  5552 			{
       
  5553 				check_registrar_nonce = false;
       
  5554 			}
       
  5555 
       
  5556 			status = verify_nonces_and_authenticator(
       
  5557 				&m_auth_key,
       
  5558 				&m_enrollee_nonce,
       
  5559 				&m_registrar_nonce,
       
  5560 				payloads,
       
  5561 				check_enrollee_nonce,
       
  5562 				check_registrar_nonce,
       
  5563 				false); // No Authenticator
       
  5564 			if (status != eap_status_ok)
       
  5565 			{
       
  5566 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5567 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5568 			}
       
  5569 		}
       
  5570 		break;
       
  5571 	default:
       
  5572 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5573 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  5574 	};
       
  5575 
       
  5576 
       
  5577 	switch(Message_type)
       
  5578 	{
       
  5579 
       
  5580 	case simple_config_Message_Type_M2:
       
  5581 		status = process_M2(payloads);
       
  5582 		break;
       
  5583 	case simple_config_Message_Type_M2D:
       
  5584 		status = process_M2D(payloads);
       
  5585 		break;
       
  5586 	case simple_config_Message_Type_M4:
       
  5587 		status = process_M4(payloads);
       
  5588 		break;
       
  5589 	case simple_config_Message_Type_M6:
       
  5590 		status = process_M6(payloads);
       
  5591 		break;
       
  5592 	case simple_config_Message_Type_M8:
       
  5593 		status = process_M8(payloads);
       
  5594 		break;
       
  5595 	case simple_config_Message_Type_WSC_ACK:
       
  5596 		status = process_WSC_ACK(payloads);
       
  5597 		break;
       
  5598 	case simple_config_Message_Type_WSC_NACK:
       
  5599 		status = process_WSC_NACK(payloads);
       
  5600 		break;
       
  5601 
       
  5602 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  5603 
       
  5604 	case simple_config_Message_Type_M1:
       
  5605 		status = process_M1(payloads);
       
  5606 		break;
       
  5607 	case simple_config_Message_Type_M3:
       
  5608 		status = process_M3(payloads);
       
  5609 		break;
       
  5610 	case simple_config_Message_Type_M5:
       
  5611 		status = process_M5(payloads);
       
  5612 		break;
       
  5613 	case simple_config_Message_Type_M7:
       
  5614 		status = process_M7(payloads);
       
  5615 		break;
       
  5616 	case simple_config_Message_Type_WSC_DONE:
       
  5617 		status = process_WSC_DONE(payloads);
       
  5618 		break;
       
  5619 
       
  5620 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  5621 
       
  5622 	default:
       
  5623 		EAP_TRACE_DEBUG(
       
  5624 			m_am_tools,
       
  5625 			TRACE_FLAGS_DEFAULT,
       
  5626 			(EAPL("ERROR: SIMPLE_CONFIG: %s: parse_function: process_simple_config_attributes(): Unknown message 0x%08x\n"),
       
  5627 			 (m_is_client == true ? "client": "server"),
       
  5628 			 Message_type));
       
  5629 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  5630 	};
       
  5631 
       
  5632 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5633 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5634 }
       
  5635 
       
  5636 //--------------------------------------------------
       
  5637 
       
  5638 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::process_simple_config_message()
       
  5639 {
       
  5640 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5641 
       
  5642 	EAP_TRACE_DEBUG(
       
  5643 		m_am_tools, 
       
  5644 		TRACE_FLAGS_DEFAULT, 
       
  5645 		(EAPL("\n")));
       
  5646 	EAP_TRACE_DEBUG(
       
  5647 		m_am_tools, 
       
  5648 		TRACE_FLAGS_DEFAULT, 
       
  5649 		(EAPL("SIMPLE_CONFIG: %s: parse_function: simple_config_record_c::process_simple_config_message()\n"),
       
  5650 		 (m_is_client == true ? "client": "server")));
       
  5651 
       
  5652 	EAP_TRACE_DATA_DEBUG(
       
  5653 		m_am_tools, 
       
  5654 		TRACE_FLAGS_DEFAULT, 
       
  5655 		(EAPL("SIMPLE_CONFIG-message"),
       
  5656 		m_received_simple_config_message.get_simple_config_message_data()->get_data(
       
  5657 			m_received_simple_config_message.get_simple_config_message_data()->get_data_length()),
       
  5658 		m_received_simple_config_message.get_simple_config_message_data()->get_data_length()));
       
  5659 
       
  5660 	u32_t next_start_offset = 0ul;
       
  5661 	u32_t simple_config_packet_length = m_received_simple_config_message.get_simple_config_message_data()->get_data_length();
       
  5662 
       
  5663 	m_received_payloads.reset();
       
  5664 
       
  5665 	u32_t padding_length(0ul);
       
  5666 
       
  5667 	eap_status_e status = m_received_payloads.parse_simple_config_payloads(
       
  5668 		m_received_simple_config_message.get_simple_config_message_data()->get_data(
       
  5669 			m_received_simple_config_message.get_simple_config_message_data()->get_data_length()),
       
  5670 		&simple_config_packet_length,
       
  5671 		&padding_length);
       
  5672 	if (status != eap_status_ok)
       
  5673 	{
       
  5674 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5675 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5676 	}
       
  5677 
       
  5678 	if (next_start_offset != simple_config_packet_length)
       
  5679 	{
       
  5680 		// Parsed packet length does not match with received packet length.
       
  5681 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5682 		return EAP_STATUS_RETURN(
       
  5683 			m_am_tools,
       
  5684 			eap_status_process_illegal_packet_error);
       
  5685 	}
       
  5686 
       
  5687 
       
  5688 	status = process_simple_config_attributes(&m_received_payloads);
       
  5689 
       
  5690 	if (status == eap_status_ok)
       
  5691 	{
       
  5692 		status = cancel_error_message_timeout();
       
  5693 	}
       
  5694 	else
       
  5695 	{
       
  5696 		if (m_handshake_error == eap_status_ok)
       
  5697 		{
       
  5698 			// Save the first error.
       
  5699 			m_handshake_error = status;
       
  5700 		}
       
  5701 
       
  5702 		status = initalize_error_message_timeout();
       
  5703 	}
       
  5704 
       
  5705 
       
  5706 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5707 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5708 }
       
  5709 
       
  5710 //--------------------------------------------------
       
  5711 
       
  5712 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::are_pending_queries_completed()
       
  5713 {
       
  5714 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5715 
       
  5716 	eap_status_e status = eap_status_pending_request;
       
  5717 
       
  5718 	if (m_pending_query_network_and_device_parameters == false)
       
  5719 	{
       
  5720 		status = eap_status_ok;
       
  5721 	}
       
  5722 
       
  5723 	eap_status_string_c status_string;
       
  5724 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5725 	EAP_TRACE_DEBUG(
       
  5726 		m_am_tools,
       
  5727 		TRACE_FLAGS_DEFAULT,
       
  5728 		(EAPL("SIMPLE_CONFIG: %s: pending_function: are_pending_queries_completed(): %s\n"),
       
  5729 		(m_is_client == true ? "client": "server"),
       
  5730 		status_string.get_status_string(status)));
       
  5731 
       
  5732 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5733 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5734 }
       
  5735 
       
  5736 //--------------------------------------------------
       
  5737 
       
  5738 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::indicate_state_to_lower_layer(
       
  5739 	const simple_config_state_e indicated_state)
       
  5740 {
       
  5741 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5742 
       
  5743 	// Notify lower layer the state of SIMPLE_CONFIG.
       
  5744 
       
  5745 	eap_simple_config_trace_string_c state_string;
       
  5746 	EAP_TRACE_DEBUG(
       
  5747 		m_am_tools,
       
  5748 		TRACE_FLAGS_DEFAULT,
       
  5749 		(EAPL("SIMPLE_CONFIG: %s: state_function: indicate_state_to_lower_layer(): %s\n"),
       
  5750 		(m_is_client == true ? "client": "server"),
       
  5751 		state_string.get_state_string(indicated_state)));
       
  5752 
       
  5753 	eap_state_notification_c notification(
       
  5754 		m_am_tools,
       
  5755 		&m_send_network_id,
       
  5756 		m_is_client,
       
  5757 		eap_state_notification_generic,
       
  5758 		eap_protocol_layer_internal_type,
       
  5759 		eap_type_none,
       
  5760 		simple_config_state_none,
       
  5761 		indicated_state,
       
  5762 		0,
       
  5763 		false);
       
  5764 	get_type_partner()->state_notification(&notification);
       
  5765 
       
  5766 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5767 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5768 }
       
  5769 
       
  5770 //--------------------------------------------------
       
  5771 
       
  5772 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::indicate_messages_processed()
       
  5773 {
       
  5774 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5775 
       
  5776 	// Notify lower layer that SIMPLE_CONFIG-messages are processed.
       
  5777 
       
  5778 	eap_simple_config_trace_string_c state_string;
       
  5779 	EAP_TRACE_DEBUG(
       
  5780 		m_am_tools,
       
  5781 		TRACE_FLAGS_DEFAULT,
       
  5782 		(EAPL("SIMPLE_CONFIG: %s: state_function: indicate_messages_processed(): %s\n"),
       
  5783 		(m_is_client == true ? "client": "server"),
       
  5784 		state_string.get_state_string(m_simple_config_state)));
       
  5785 
       
  5786 	eap_state_notification_c notification(
       
  5787 		m_am_tools,
       
  5788 		&m_send_network_id,
       
  5789 		m_is_client,
       
  5790 		eap_state_notification_generic,
       
  5791 		eap_protocol_layer_internal_type,
       
  5792 		eap_type_none,
       
  5793 		simple_config_state_none,
       
  5794 		simple_config_state_pending_simple_config_messages_processed,
       
  5795 		0,
       
  5796 		false);
       
  5797 	get_type_partner()->state_notification(&notification);
       
  5798 
       
  5799 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5800 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5801 }
       
  5802 
       
  5803 //--------------------------------------------------
       
  5804 
       
  5805 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::send_simple_config_message()
       
  5806 {
       
  5807 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5808 	
       
  5809 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5810 	EAP_TRACE_DEBUG(
       
  5811 		m_am_tools,
       
  5812 		TRACE_FLAGS_DEFAULT,
       
  5813 		(EAPL("SIMPLE_CONFIG: %s: send_function: simple_config_record_c::send_simple_config_message()\n"),
       
  5814 		 (m_is_client == true ? "client": "server")));
       
  5815 
       
  5816 	eap_variable_data_c simple_config_message_buffer(m_am_tools);
       
  5817 
       
  5818 	if (simple_config_message_buffer.get_is_valid() == false)
       
  5819 	{
       
  5820 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5821 	}
       
  5822 
       
  5823 	// --------------------------------------------------------------------
       
  5824 
       
  5825 	eap_buf_chain_wr_c sent_packet(
       
  5826 		eap_write_buffer,
       
  5827 		m_am_tools,
       
  5828 		m_new_simple_config_message.get_simple_config_message_data()->get_data(simple_config_message_buffer.get_data_length()),
       
  5829 		m_new_simple_config_message.get_simple_config_message_data()->get_data_length(),
       
  5830 		false,
       
  5831 		false,
       
  5832 		0ul);
       
  5833 	if (sent_packet.get_is_valid() == false)
       
  5834 	{
       
  5835 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5836 	}
       
  5837 
       
  5838 	EAP_TRACE_DATA_DEBUG(
       
  5839 		m_am_tools,
       
  5840 		TRACE_FLAGS_DEFAULT,
       
  5841 		(EAPL("send SIMPLE_CONFIG-message"),
       
  5842 		 sent_packet.get_data(sent_packet.get_data_length()),
       
  5843 		 sent_packet.get_data_length()));
       
  5844 
       
  5845 	// --------------------------------------------------------------------
       
  5846 	
       
  5847     // Send message
       
  5848 	eap_status_e status = get_type_partner()->simple_config_packet_send(
       
  5849 		&sent_packet,
       
  5850 		m_current_simple_config_message_type);
       
  5851 	
       
  5852 	if (status != eap_status_ok)
       
  5853     {
       
  5854         EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5855         return EAP_STATUS_RETURN(m_am_tools, status);
       
  5856     }
       
  5857 
       
  5858 	status = m_previous_simple_config_message.get_simple_config_message_data()->set_copy_of_buffer(
       
  5859 		m_new_simple_config_message.get_simple_config_message_data());
       
  5860 	if (status != eap_status_ok)
       
  5861 	{
       
  5862 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5863 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5864 	}
       
  5865 
       
  5866 	m_new_simple_config_message.reset();
       
  5867 	
       
  5868 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5869 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5870 }
       
  5871 
       
  5872 //--------------------------------------------------
       
  5873 
       
  5874 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::check_sent_simple_config_message()
       
  5875 {
       
  5876 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5877 
       
  5878 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  5879 	EAP_TRACE_DEBUG(
       
  5880 		m_am_tools,
       
  5881 		TRACE_FLAGS_DEFAULT,
       
  5882 		(EAPL("SIMPLE_CONFIG: %s: send_function: simple_config_record_c::check_sent_simple_config_message()\n"),
       
  5883 		(m_is_client == true ? "client": "server")));
       
  5884 
       
  5885 	eap_status_e msg_status = eap_status_authentication_failure;
       
  5886 
       
  5887 	if (m_already_in_completion_action_check == true)
       
  5888 	{
       
  5889 		// This is recursive call. Do not process yet.
       
  5890 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5891 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5892 	}
       
  5893 
       
  5894 	if (m_force_simple_config_message_send == true)
       
  5895 	{
       
  5896 		// There may be an alert message pending.
       
  5897 		msg_status = send_simple_config_message();
       
  5898 	}
       
  5899 	else
       
  5900 	{
       
  5901 		msg_status = are_pending_queries_completed();
       
  5902 		if (msg_status == eap_status_ok)
       
  5903 		{
       
  5904 			eap_status_e compl_status = completion_action_check();
       
  5905 
       
  5906 			if (compl_status == eap_status_pending_request)
       
  5907 			{
       
  5908 				// Some asyncronous query is still pending.
       
  5909 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5910 				return EAP_STATUS_RETURN(m_am_tools, compl_status);
       
  5911 			}
       
  5912 			else if (compl_status != eap_status_ok)
       
  5913 			{
       
  5914 				// There may be Alert message to be sent.
       
  5915 				msg_status = compl_status;
       
  5916 			}
       
  5917 
       
  5918 
       
  5919 			if (m_allow_message_send == true)
       
  5920 			{
       
  5921 				if (msg_status == eap_status_ok
       
  5922 					&& m_new_simple_config_message.get_simple_config_message_data()->get_is_valid_data() == true)
       
  5923 				{
       
  5924 					// We could send the pending SIMPLE_CONFIG-messages.
       
  5925 					msg_status = send_simple_config_message();
       
  5926 				}
       
  5927 				else if (m_force_simple_config_message_send == true // There may be Alert message to be sent.
       
  5928 					&& m_new_simple_config_message.get_simple_config_message_data()->get_is_valid_data() == true)
       
  5929 				{
       
  5930 					// We could send the pending SIMPLE_CONFIG-messages.
       
  5931 					send_simple_config_message();
       
  5932 				}
       
  5933 				else
       
  5934 				{
       
  5935 					// No message to sent.
       
  5936 					EAP_TRACE_DEBUG(
       
  5937 						m_am_tools,
       
  5938 						TRACE_FLAGS_DEFAULT,
       
  5939 						(EAPL("SIMPLE_CONFIG: %s: send_function: simple_config_record_c::check_sent_simple_config_message(), ")
       
  5940 						 EAPL("No message to sent.\n"),
       
  5941 						(m_is_client == true ? "client": "server")));
       
  5942 				}
       
  5943 			}
       
  5944 
       
  5945 			if (msg_status == eap_status_ok
       
  5946 				&& m_allow_message_send == true)
       
  5947 			{
       
  5948 				eap_status_e indication_status = indicate_messages_processed();
       
  5949 				if (indication_status != eap_status_ok)
       
  5950 				{
       
  5951 					// This is an error case.
       
  5952 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5953 					return EAP_STATUS_RETURN(m_am_tools, indication_status);
       
  5954 				}
       
  5955 			}
       
  5956 		}
       
  5957 	}
       
  5958 
       
  5959 	if (get_state() == simple_config_state_simple_config_success)
       
  5960 	{
       
  5961 		// Notify lower layer that SIMPLE_CONFIG/PEAP ended successfully
       
  5962 
       
  5963 		eap_simple_config_trace_string_c simple_config_trace;
       
  5964 
       
  5965 		EAP_TRACE_DEBUG(
       
  5966 			m_am_tools,
       
  5967 			TRACE_FLAGS_DEFAULT,
       
  5968 			(EAPL("%s: SIMPLE_CONFIG/PEAP authentication ")
       
  5969 			 EAPL("SUCCESS: EAP-type %s\n"),
       
  5970 			 (m_is_client == true ? "client": "server"),
       
  5971 			 eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type())));
       
  5972 
       
  5973 		eap_status_e notification_status = indicate_state_to_lower_layer(get_state());
       
  5974 		if (notification_status != eap_status_ok)
       
  5975 		{
       
  5976 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5977 			return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
  5978 		}
       
  5979 	}
       
  5980 	else if (get_state() == simple_config_state_failure)
       
  5981 	{
       
  5982 		eap_simple_config_trace_string_c simple_config_trace;
       
  5983 
       
  5984 		EAP_TRACE_ERROR(
       
  5985 			m_am_tools,
       
  5986 			TRACE_FLAGS_DEFAULT,
       
  5987 			(EAPL("%s: SIMPLE_CONFIG/PEAP authentication ")
       
  5988 			 EAPL("FAILED: EAP-type %s\n"),
       
  5989 			 (m_is_client == true ? "client": "server"),
       
  5990 			 eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type())));
       
  5991 
       
  5992 		eap_status_e notification_status = indicate_state_to_lower_layer(get_state());
       
  5993 		if (notification_status != eap_status_ok)
       
  5994 		{
       
  5995 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5996 			return EAP_STATUS_RETURN(m_am_tools, notification_status);
       
  5997 		}
       
  5998 	}
       
  5999 
       
  6000 
       
  6001 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6002 	return EAP_STATUS_RETURN(m_am_tools, msg_status);
       
  6003 }
       
  6004 
       
  6005 //--------------------------------------------------
       
  6006 
       
  6007 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::packet_process(
       
  6008 	eap_variable_data_c * const simple_config_packet,
       
  6009 	const u8_t received_eap_identifier)
       
  6010 {
       
  6011 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6012 
       
  6013 	eap_simple_config_trace_string_c state_trace;
       
  6014 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6015 	EAP_TRACE_DEBUG(
       
  6016 		m_am_tools,
       
  6017 		TRACE_FLAGS_DEFAULT,
       
  6018 		(EAPL("SIMPLE_CONFIG: %s: message_function: packet_process(): state %s\n"),
       
  6019 		(m_is_client == true ? "client": "server"),
       
  6020 		state_trace.get_state_string(get_state())));
       
  6021 
       
  6022 	m_received_simple_config_message.reset();
       
  6023 
       
  6024 	eap_status_e status = m_received_simple_config_message.set_simple_config_message_data(
       
  6025 		simple_config_packet,
       
  6026 		received_eap_identifier);
       
  6027 	if (status != eap_status_ok)
       
  6028 	{
       
  6029 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6030 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6031 	}
       
  6032 
       
  6033 	eap_automatic_simple_value_c<bool> restore_allow_message_send(
       
  6034 		m_am_tools,
       
  6035 		&m_allow_message_send,
       
  6036 		true);
       
  6037 
       
  6038 	// Packet send is delayed until after the process_simple_config_message() function returns.
       
  6039 	m_allow_message_send = false;
       
  6040 
       
  6041 	status = process_simple_config_message();
       
  6042 
       
  6043 	m_allow_message_send = true;
       
  6044 
       
  6045 
       
  6046 	if (status != eap_status_pending_request)
       
  6047 	{
       
  6048 		// Note this call will return eap_status_pending_request if any asyncronous call is pending.
       
  6049 		eap_status_e send_status = check_sent_simple_config_message();
       
  6050 		if (send_status != eap_status_ok)
       
  6051 		{
       
  6052 			status = send_status;
       
  6053 		}
       
  6054 	}
       
  6055 
       
  6056 	if (get_state() == simple_config_state_simple_config_success)
       
  6057 	{
       
  6058 		// Send state notification to lower layer.
       
  6059 		eap_state_notification_c notification(
       
  6060 			m_am_tools,
       
  6061 			&m_send_network_id,
       
  6062 			m_is_client,
       
  6063 			eap_state_notification_generic,
       
  6064 			eap_protocol_layer_eap,
       
  6065 			eap_type_none,
       
  6066 			eap_state_none,
       
  6067 			eap_state_authentication_finished_successfully,
       
  6068 			0ul,
       
  6069 			false);
       
  6070 		get_type_partner()->state_notification(&notification);
       
  6071 	}
       
  6072 
       
  6073 
       
  6074 	if (status == eap_status_success
       
  6075 		&& get_state() != simple_config_state_simple_config_success)
       
  6076 	{
       
  6077 		status = eap_status_ok;
       
  6078 	}
       
  6079 
       
  6080 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6081 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6082 }
       
  6083 
       
  6084 //--------------------------------------------------
       
  6085 
       
  6086 EAP_FUNC_EXPORT bool simple_config_record_c::get_is_valid()
       
  6087 {
       
  6088 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6089 
       
  6090 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6091 	return m_is_valid;
       
  6092 }
       
  6093 
       
  6094 //--------------------------------------------------
       
  6095 
       
  6096 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::reset()
       
  6097 {
       
  6098 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6099 
       
  6100 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6101 	EAP_TRACE_DEBUG(
       
  6102 		m_am_tools,
       
  6103 		TRACE_FLAGS_DEFAULT,
       
  6104 		(EAPL("SIMPLE_CONFIG: %s: function: simple_config_record_c::reset(): this = 0x%08x\n"),
       
  6105 		(m_is_client == true ? "client": "server"),
       
  6106 		this));
       
  6107 
       
  6108 	completion_action_clenup();
       
  6109 
       
  6110 	m_M2D_payloads.reset();
       
  6111 
       
  6112 	m_handshake_error = eap_status_ok;
       
  6113 	m_Rf_Bands = simple_config_RF_Bands_2_4_GHz;
       
  6114 
       
  6115 	m_received_simple_config_message.reset();
       
  6116 	m_new_simple_config_message.reset();
       
  6117 	m_own_private_dhe_key.reset();
       
  6118 	m_own_public_dhe_key.reset();
       
  6119 	m_peer_public_dhe_key.reset();
       
  6120 	m_shared_dh_key.reset();
       
  6121 	m_dhe_prime.reset();
       
  6122 	m_dhe_group_generator.reset();
       
  6123 	m_signed_message_hash.reset();
       
  6124 	m_NAI.reset();
       
  6125 	m_NAI_realm.reset();
       
  6126 
       
  6127 	m_completion_queue.reset();
       
  6128 
       
  6129 	m_key_material_generated = false;
       
  6130 
       
  6131 	m_force_simple_config_message_send = false;
       
  6132 
       
  6133 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  6134 	if (m_is_client == false)
       
  6135 	{
       
  6136 		// Server
       
  6137 		// NOTE: set_state() function cannot reset state.
       
  6138 		m_simple_config_state = simple_config_state_wait_M1;
       
  6139 	}
       
  6140 	else
       
  6141 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  6142 	{
       
  6143 		// Client
       
  6144 		// NOTE: set_state() function cannot reset state.
       
  6145 		m_simple_config_state = simple_config_state_wait_simple_config_start;
       
  6146 	}
       
  6147 
       
  6148 	eap_status_e status = generate_dhe_keys();
       
  6149 	if (status != eap_status_ok)
       
  6150 	{
       
  6151 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6152 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6153 	}
       
  6154 
       
  6155 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6156 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6157 }
       
  6158 
       
  6159 //--------------------------------------------------
       
  6160 
       
  6161 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_dhe_keys()
       
  6162 {
       
  6163 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6164 
       
  6165 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6166 	EAP_TRACE_DEBUG(
       
  6167 		m_am_tools,
       
  6168 		TRACE_FLAGS_DEFAULT,
       
  6169 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_dhe_keys()\n"),
       
  6170 		(m_is_client == true ? "client": "server")));
       
  6171 
       
  6172 	eap_status_e status = eap_status_not_supported;
       
  6173 
       
  6174 	{
       
  6175 		m_dhe_prime.reset();
       
  6176 
       
  6177 		status = m_dhe_prime.add_data(SIMPLE_CONFIG_DIFFIE_HELLMAN_PRIME, sizeof(SIMPLE_CONFIG_DIFFIE_HELLMAN_PRIME));
       
  6178 		if (status != eap_status_ok)
       
  6179 		{
       
  6180 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6181 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6182 		}
       
  6183 
       
  6184 		m_dhe_group_generator.reset();
       
  6185 
       
  6186 		status = m_dhe_group_generator.add_data(SIMPLE_CONFIG_DIFFIE_HELLMAN_GROUP_GENERATOR, sizeof(SIMPLE_CONFIG_DIFFIE_HELLMAN_GROUP_GENERATOR));
       
  6187 		if (status != eap_status_ok)
       
  6188 		{
       
  6189 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6190 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6191 		}
       
  6192 
       
  6193 		crypto_ephemeral_diffie_hellman_c dhe(m_am_tools);
       
  6194 
       
  6195 		if (dhe.get_is_valid() == false)
       
  6196 		{
       
  6197 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6198 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6199 		}
       
  6200 
       
  6201 		EAP_TRACE_DEBUG(
       
  6202 			m_am_tools,
       
  6203 			TRACE_FLAGS_DEFAULT,
       
  6204 			(EAPL("SIMPLE_CONFIG: %s:     key_function: dhe.generate_diffie_hellman_keys()\n"),
       
  6205 			(m_is_client == true ? "client": "server")));
       
  6206 
       
  6207 		status = dhe.generate_diffie_hellman_keys(
       
  6208 			&m_own_private_dhe_key,
       
  6209 			&m_own_public_dhe_key,
       
  6210 			m_dhe_prime.get_data(m_dhe_prime.get_data_length()),
       
  6211 			m_dhe_prime.get_data_length(),
       
  6212 			m_dhe_group_generator.get_data(m_dhe_group_generator.get_data_length()),
       
  6213 			m_dhe_group_generator.get_data_length());
       
  6214 		if (status != eap_status_ok)
       
  6215 		{
       
  6216 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6217 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6218 		}
       
  6219 	}
       
  6220 
       
  6221 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6222 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6223 }
       
  6224 
       
  6225 //--------------------------------------------------
       
  6226 
       
  6227 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_dhe_shared_secret(
       
  6228 	const eap_variable_data_c * const peer_public_key_data,
       
  6229 	eap_variable_data_c * const dhe_shared_secret)
       
  6230 {
       
  6231 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6232 
       
  6233 	EAP_TRACE_DEBUG(
       
  6234 		m_am_tools,
       
  6235 		TRACE_FLAGS_DEFAULT,
       
  6236 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_dhe_shared_secret()\n"),
       
  6237 		(m_is_client == true ? "client": "server")));
       
  6238 
       
  6239 
       
  6240 	if (m_dhe_prime.get_is_valid_data() == false
       
  6241 		|| m_dhe_group_generator.get_is_valid_data() == false
       
  6242 		|| m_own_private_dhe_key.get_is_valid_data() == false
       
  6243 		|| peer_public_key_data->get_is_valid_data() == false)
       
  6244 	{
       
  6245 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6246 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  6247 	}
       
  6248 
       
  6249 	crypto_ephemeral_diffie_hellman_c dhe(m_am_tools);
       
  6250 
       
  6251 	if (dhe.get_is_valid() == false)
       
  6252 	{
       
  6253 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6254 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6255 	}
       
  6256 
       
  6257 	EAP_TRACE_DEBUG(
       
  6258 		m_am_tools,
       
  6259 		TRACE_FLAGS_DEFAULT,
       
  6260 		(EAPL("SIMPLE_CONFIG: %s:     key_function: dhe.generate_g_power_to_xy()\n"),
       
  6261 		(m_is_client == true ? "client": "server")));
       
  6262 
       
  6263 	eap_status_e status = dhe.generate_g_power_to_xy(
       
  6264 		&m_own_private_dhe_key,
       
  6265 		peer_public_key_data,
       
  6266 		dhe_shared_secret,
       
  6267 		m_dhe_prime.get_data(),
       
  6268 		m_dhe_prime.get_data_length(),
       
  6269 		m_dhe_group_generator.get_data(),
       
  6270 		m_dhe_group_generator.get_data_length());
       
  6271 	if (status != eap_status_ok)
       
  6272 	{
       
  6273 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6274 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6275 	}
       
  6276 
       
  6277 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SIMPLE_CONFIG: dhe_shared_secret"),
       
  6278 		dhe_shared_secret->get_data(dhe_shared_secret->get_data_length()),
       
  6279 		dhe_shared_secret->get_data_length()));
       
  6280 
       
  6281 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6282 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6283 }
       
  6284 
       
  6285 //--------------------------------------------------
       
  6286 
       
  6287 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_nonce(
       
  6288 	eap_variable_data_c * const nonce,
       
  6289 	const u32_t nonce_length)
       
  6290 {
       
  6291 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6292 
       
  6293 	EAP_TRACE_DEBUG(
       
  6294 		m_am_tools,
       
  6295 		TRACE_FLAGS_DEFAULT,
       
  6296 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_nonce()\n"),
       
  6297 		(m_is_client == true ? "client": "server")));
       
  6298 
       
  6299 	// Creates a Nonce.
       
  6300 	crypto_random_c rand(m_am_tools);
       
  6301 
       
  6302 	eap_status_e status = nonce->set_buffer_length(nonce_length);
       
  6303 	if (status != eap_status_ok)
       
  6304 	{
       
  6305 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6306 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6307 	}
       
  6308 
       
  6309 	status = nonce->set_data_length(nonce->get_buffer_length());
       
  6310 	if (status != eap_status_ok)
       
  6311 	{
       
  6312 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6313 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6314 	}
       
  6315 
       
  6316 	status = rand.get_rand_bytes(nonce->get_data(), nonce->get_data_length());
       
  6317 	if (status != eap_status_ok)
       
  6318 	{
       
  6319 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6320 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6321 	}
       
  6322 
       
  6323 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6324 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6325 }
       
  6326 
       
  6327 //--------------------------------------------------
       
  6328 
       
  6329 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_erhash(
       
  6330 	const bool verify,
       
  6331 	const eap_variable_data_c * const half_of_device_password,
       
  6332 	const eap_variable_data_c * const PKE,
       
  6333 	const eap_variable_data_c * const PKR,
       
  6334 	eap_variable_data_c * const PSKn,
       
  6335 	eap_variable_data_c * const ERSn,
       
  6336 	eap_variable_data_c * const ERHash)
       
  6337 {
       
  6338 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6339 
       
  6340 	EAP_TRACE_DEBUG(
       
  6341 		m_am_tools,
       
  6342 		TRACE_FLAGS_DEFAULT,
       
  6343 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_erhash()\n"),
       
  6344 		(m_is_client == true ? "client": "server")));
       
  6345 
       
  6346 	EAP_TRACE_DATA_DEBUG(
       
  6347 		m_am_tools,
       
  6348 		TRACE_FLAGS_DEFAULT,
       
  6349 		(EAPL("SIMPLE_CONFIG: PKE"),
       
  6350 		PKE->get_data(),
       
  6351 		PKE->get_data_length()));
       
  6352 
       
  6353 	EAP_TRACE_DATA_DEBUG(
       
  6354 		m_am_tools,
       
  6355 		TRACE_FLAGS_DEFAULT,
       
  6356 		(EAPL("SIMPLE_CONFIG: PKR"),
       
  6357 		PKR->get_data(),
       
  6358 		PKR->get_data_length()));
       
  6359 
       
  6360 	EAP_TRACE_DATA_DEBUG(
       
  6361 		m_am_tools,
       
  6362 		TRACE_FLAGS_DEFAULT,
       
  6363 		(EAPL("SIMPLE_CONFIG: half_of_device_password"),
       
  6364 		half_of_device_password->get_data(),
       
  6365 		half_of_device_password->get_data_length()));
       
  6366 
       
  6367 	eap_status_e status = keyed_hmac(&m_auth_key, half_of_device_password, PSKn);
       
  6368 	if (status != eap_status_ok)
       
  6369 	{
       
  6370 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6371 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6372 	}
       
  6373 
       
  6374 	status = PSKn->set_data_length(SIMPLE_CONFIG_PSKn_LENGTH);
       
  6375 	if (status != eap_status_ok)
       
  6376 	{
       
  6377 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6378 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6379 	}
       
  6380 
       
  6381 	EAP_TRACE_DATA_DEBUG(
       
  6382 		m_am_tools,
       
  6383 		TRACE_FLAGS_DEFAULT,
       
  6384 		(EAPL("SIMPLE_CONFIG: PSKn"),
       
  6385 		PSKn->get_data(),
       
  6386 		PSKn->get_data_length()));
       
  6387 
       
  6388 	if (verify == false)
       
  6389 	{
       
  6390 		status = generate_nonce(
       
  6391 			ERSn,
       
  6392 			SIMPLE_CONFIG_ESn_LENGTH);
       
  6393 		if (status != eap_status_ok)
       
  6394 		{
       
  6395 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6396 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6397 		}
       
  6398 	}
       
  6399 	else
       
  6400 	{
       
  6401 		EAP_TRACE_DEBUG(
       
  6402 			m_am_tools,
       
  6403 			TRACE_FLAGS_DEFAULT,
       
  6404 			(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_erhash(): No new nonce is generated,\n"),
       
  6405 			(m_is_client == true ? "client": "server")));
       
  6406 		EAP_ASSERT(ERSn != 0 && ERSn->get_is_valid_data() == true);
       
  6407 	}
       
  6408 
       
  6409 	EAP_TRACE_DATA_DEBUG(
       
  6410 		m_am_tools,
       
  6411 		TRACE_FLAGS_DEFAULT,
       
  6412 		(EAPL("SIMPLE_CONFIG: ERSn"),
       
  6413 		ERSn->get_data(),
       
  6414 		ERSn->get_data_length()));
       
  6415 
       
  6416 	{
       
  6417 		eap_variable_data_c hmac_input(m_am_tools);
       
  6418 
       
  6419 		if (hmac_input.get_is_valid() == false)
       
  6420 		{
       
  6421 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6422 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6423 		}
       
  6424 
       
  6425 		status = hmac_input.add_data(ERSn);
       
  6426 		if (status != eap_status_ok)
       
  6427 		{
       
  6428 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6429 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6430 		}
       
  6431 
       
  6432 		status = hmac_input.add_data(PSKn);
       
  6433 		if (status != eap_status_ok)
       
  6434 		{
       
  6435 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6436 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6437 		}
       
  6438 
       
  6439 		status = hmac_input.add_data(PKE);
       
  6440 		if (status != eap_status_ok)
       
  6441 		{
       
  6442 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6443 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6444 		}
       
  6445 
       
  6446 		status = hmac_input.add_data(PKR);
       
  6447 		if (status != eap_status_ok)
       
  6448 		{
       
  6449 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6450 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6451 		}
       
  6452 
       
  6453 		status = keyed_hmac(&m_auth_key, &hmac_input, ERHash);
       
  6454 		if (status != eap_status_ok)
       
  6455 		{
       
  6456 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6457 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6458 		}
       
  6459 	}
       
  6460 
       
  6461 	EAP_TRACE_DATA_DEBUG(
       
  6462 		m_am_tools,
       
  6463 		TRACE_FLAGS_DEFAULT,
       
  6464 		(EAPL("SIMPLE_CONFIG: ERHash"),
       
  6465 		ERHash->get_data(),
       
  6466 		ERHash->get_data_length()));
       
  6467 
       
  6468 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6469 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6470 }
       
  6471 
       
  6472 //--------------------------------------------------
       
  6473 
       
  6474 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_er_hashs(
       
  6475 	const bool verify,
       
  6476 	const eap_variable_data_c * const device_password,
       
  6477 	const eap_variable_data_c * const PKE,
       
  6478 	const eap_variable_data_c * const PKR,
       
  6479 	eap_variable_data_c * const PSK1,
       
  6480 	eap_variable_data_c * const ER_S1,
       
  6481 	eap_variable_data_c * const ER_Hash1,
       
  6482 	eap_variable_data_c * const PSK2,
       
  6483 	eap_variable_data_c * const ER_S2,
       
  6484 	eap_variable_data_c * const ER_Hash2)
       
  6485 {
       
  6486 
       
  6487 	eap_variable_data_c first_half_of_device_password(m_am_tools);
       
  6488 
       
  6489 	if (first_half_of_device_password.get_is_valid() == false)
       
  6490 	{
       
  6491 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6492 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6493 	}
       
  6494 
       
  6495 	eap_status_e status = first_half_of_device_password.set_buffer(device_password);
       
  6496 	if (status != eap_status_ok)
       
  6497 	{
       
  6498 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6499 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6500 	}
       
  6501 
       
  6502 	status = first_half_of_device_password.set_data_length((device_password->get_data_length() + 1ul) / 2ul);
       
  6503 	if (status != eap_status_ok)
       
  6504 	{
       
  6505 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6506 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6507 	}
       
  6508 
       
  6509 	if (ER_Hash1 != 0)
       
  6510 	{
       
  6511 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6512 		// Create E/R-Hash1.
       
  6513 
       
  6514 		status = generate_erhash(
       
  6515 			verify,
       
  6516 			&first_half_of_device_password,
       
  6517 			PKE,
       
  6518 			PKR,
       
  6519 			PSK1,
       
  6520 			ER_S1,
       
  6521 			ER_Hash1);
       
  6522 		if (status != eap_status_ok)
       
  6523 		{
       
  6524 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6525 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6526 		}
       
  6527 
       
  6528 		EAP_TRACE_DATA_DEBUG(
       
  6529 			m_am_tools,
       
  6530 			TRACE_FLAGS_DEFAULT,
       
  6531 			(EAPL("SIMPLE_CONFIG: ER_Hash1"),
       
  6532 			ER_Hash1->get_data(),
       
  6533 			ER_Hash1->get_data_length()));
       
  6534 	}
       
  6535 
       
  6536 	if (ER_Hash2 != 0)
       
  6537 	{
       
  6538 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6539 		// Create E/R-Hash2.
       
  6540 
       
  6541 		eap_variable_data_c second_half_of_device_password(m_am_tools);
       
  6542 
       
  6543 		if (second_half_of_device_password.get_is_valid() == false)
       
  6544 		{
       
  6545 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6546 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6547 		}
       
  6548 
       
  6549 		u32_t second_half_length(device_password->get_data_length() / 2ul);
       
  6550 
       
  6551 		eap_status_e status = second_half_of_device_password.set_buffer(
       
  6552 			device_password->get_data_offset(first_half_of_device_password.get_data_length(), second_half_length),
       
  6553 			second_half_length,
       
  6554 			false,
       
  6555 			false);
       
  6556 		if (status != eap_status_ok)
       
  6557 		{
       
  6558 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6559 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6560 		}
       
  6561 
       
  6562 		status = generate_erhash(
       
  6563 			verify,
       
  6564 			&second_half_of_device_password,
       
  6565 			PKE,
       
  6566 			PKR,
       
  6567 			PSK2,
       
  6568 			ER_S2,
       
  6569 			ER_Hash2);
       
  6570 		if (status != eap_status_ok)
       
  6571 		{
       
  6572 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6573 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6574 		}
       
  6575 
       
  6576 		EAP_TRACE_DATA_DEBUG(
       
  6577 			m_am_tools,
       
  6578 			TRACE_FLAGS_DEFAULT,
       
  6579 			(EAPL("SIMPLE_CONFIG: ER_Hash2"),
       
  6580 			ER_Hash2->get_data(),
       
  6581 			ER_Hash2->get_data_length()));
       
  6582 	}
       
  6583 
       
  6584 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  6585 
       
  6586 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6587 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6588 }
       
  6589 
       
  6590 //--------------------------------------------------
       
  6591 
       
  6592 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::keyed_hmac(
       
  6593 	const eap_variable_data_c * const key,
       
  6594 	const eap_variable_data_c * const input,
       
  6595 	eap_variable_data_c * const output)
       
  6596 {
       
  6597 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6598 
       
  6599 	EAP_TRACE_DEBUG(
       
  6600 		m_am_tools,
       
  6601 		TRACE_FLAGS_DEFAULT,
       
  6602 		(EAPL("SIMPLE_CONFIG: %s:     key_function: keyed_hmac()\n"),
       
  6603 		(m_is_client == true ? "client": "server")));
       
  6604 
       
  6605 	crypto_sha_256_c sha_256(m_am_tools);
       
  6606 	if (sha_256.get_is_valid() == false)
       
  6607 	{
       
  6608 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6609 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6610 	}
       
  6611 
       
  6612 	crypto_hmac_c hmac_sha_256(
       
  6613 		m_am_tools,
       
  6614 		&sha_256,
       
  6615 		false);
       
  6616 	if (hmac_sha_256.get_is_valid() == false)
       
  6617 	{
       
  6618 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6619 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6620 	}
       
  6621 
       
  6622 	EAP_TRACE_DATA_DEBUG(
       
  6623 		m_am_tools,
       
  6624 		TRACE_FLAGS_DEFAULT,
       
  6625 		(EAPL("SIMPLE_CONFIG: key"),
       
  6626 		key->get_data(),
       
  6627 		key->get_data_length()));
       
  6628 
       
  6629 	eap_status_e status = hmac_sha_256.hmac_set_key(key);
       
  6630 	if (status != eap_status_ok)
       
  6631 	{
       
  6632 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6633 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6634 	}
       
  6635 
       
  6636 	status = hmac_sha_256.hmac_update(
       
  6637 		input->get_data(),
       
  6638 		input->get_data_length());
       
  6639 	if (status != eap_status_ok)
       
  6640 	{
       
  6641 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6642 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6643 	}
       
  6644 
       
  6645 	status = output->set_buffer_length(hmac_sha_256.get_digest_length());
       
  6646 	if (status != eap_status_ok)
       
  6647 	{
       
  6648 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6649 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6650 	}
       
  6651 
       
  6652 	status = output->set_data_length(hmac_sha_256.get_digest_length());
       
  6653 	if (status != eap_status_ok)
       
  6654 	{
       
  6655 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6656 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6657 	}
       
  6658 
       
  6659 	u32_t md_length(hmac_sha_256.get_digest_length());
       
  6660 
       
  6661 	status = hmac_sha_256.hmac_final(
       
  6662 		output->get_data(hmac_sha_256.get_digest_length()),
       
  6663 		&md_length);
       
  6664 	if (status != eap_status_ok)
       
  6665 	{
       
  6666 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6667 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6668 	}
       
  6669 	
       
  6670 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6671 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6672 }
       
  6673 
       
  6674 //--------------------------------------------------
       
  6675 
       
  6676 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_kdk(
       
  6677 	const eap_variable_data_c * const dhe_shared_secret,
       
  6678 	const eap_variable_data_c * const nonce_1,
       
  6679 	const eap_variable_data_c * const enrollee_mac,
       
  6680 	const eap_variable_data_c * const nonce_2,
       
  6681 	eap_variable_data_c * const kdk
       
  6682 	)
       
  6683 {
       
  6684 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6685 
       
  6686 	EAP_TRACE_DEBUG(
       
  6687 		m_am_tools,
       
  6688 		TRACE_FLAGS_DEFAULT,
       
  6689 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_kdk()\n"),
       
  6690 		(m_is_client == true ? "client": "server")));
       
  6691 
       
  6692 	crypto_sha_256_c sha_256(m_am_tools);
       
  6693 	if (sha_256.get_is_valid() == false)
       
  6694 	{
       
  6695 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6696 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6697 	}
       
  6698 
       
  6699 	eap_status_e status = sha_256.hash_init();
       
  6700 	if (status != eap_status_ok)
       
  6701 	{
       
  6702 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6703 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6704 	}
       
  6705 
       
  6706 	EAP_TRACE_DATA_DEBUG(
       
  6707 		m_am_tools,
       
  6708 		TRACE_FLAGS_DEFAULT,
       
  6709 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): dhe_shared_secret"),
       
  6710 		dhe_shared_secret->get_data(),
       
  6711 		dhe_shared_secret->get_data_length()));
       
  6712 
       
  6713 	EAP_TRACE_DATA_DEBUG(
       
  6714 		m_am_tools,
       
  6715 		TRACE_FLAGS_DEFAULT,
       
  6716 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): nonce_1"),
       
  6717 		 nonce_1->get_data(),
       
  6718 		 nonce_1->get_data_length()));
       
  6719 
       
  6720 	EAP_TRACE_DATA_DEBUG(
       
  6721 		m_am_tools,
       
  6722 		TRACE_FLAGS_DEFAULT,
       
  6723 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): enrollee_mac"),
       
  6724 		 enrollee_mac->get_data(),
       
  6725 		 enrollee_mac->get_data_length()));
       
  6726 
       
  6727 	EAP_TRACE_DATA_DEBUG(
       
  6728 		m_am_tools,
       
  6729 		TRACE_FLAGS_DEFAULT,
       
  6730 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): nonce_2"),
       
  6731 		 nonce_2->get_data(),
       
  6732 		 nonce_2->get_data_length()));
       
  6733 
       
  6734 	status = sha_256.hash_update(
       
  6735 		dhe_shared_secret->get_data(),
       
  6736 		dhe_shared_secret->get_data_length());
       
  6737 	if (status != eap_status_ok)
       
  6738 	{
       
  6739 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6740 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6741 	}
       
  6742 
       
  6743 	eap_variable_data_c dh_key(m_am_tools);
       
  6744 	if (dh_key.get_is_valid() == false)
       
  6745 	{
       
  6746 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6747 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6748 	}
       
  6749 
       
  6750 	status = dh_key.set_buffer_length(sha_256.get_digest_length());
       
  6751 	if (status != eap_status_ok)
       
  6752 	{
       
  6753 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6754 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6755 	}
       
  6756 
       
  6757 	status = dh_key.set_data_length(sha_256.get_digest_length());
       
  6758 	if (status != eap_status_ok)
       
  6759 	{
       
  6760 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6761 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6762 	}
       
  6763 
       
  6764 	{
       
  6765 		u32_t md_length(sha_256.get_digest_length());
       
  6766 
       
  6767 		status = sha_256.hash_final(
       
  6768 			dh_key.get_data(sha_256.get_digest_length()),
       
  6769 			&md_length);
       
  6770 		if (status != eap_status_ok)
       
  6771 		{
       
  6772 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6773 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6774 		}
       
  6775 	}
       
  6776 
       
  6777 	EAP_TRACE_DATA_DEBUG(
       
  6778 		m_am_tools,
       
  6779 		TRACE_FLAGS_DEFAULT,
       
  6780 		(EAPL("SIMPLE_CONFIG: dh_key"),
       
  6781 		dh_key.get_data(),
       
  6782 		dh_key.get_data_length()));
       
  6783 
       
  6784 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  6785 
       
  6786 	sha_256.hash_cleanup();
       
  6787 	if (sha_256.get_is_valid() == false)
       
  6788 	{
       
  6789 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6790 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6791 	}
       
  6792 
       
  6793 	crypto_hmac_c hmac_sha_256(
       
  6794 		m_am_tools,
       
  6795 		&sha_256,
       
  6796 		false);
       
  6797 	if (hmac_sha_256.get_is_valid() == false)
       
  6798 	{
       
  6799 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6800 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6801 	}
       
  6802 
       
  6803 	status = hmac_sha_256.hmac_set_key(&dh_key);
       
  6804 	if (status != eap_status_ok)
       
  6805 	{
       
  6806 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6807 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6808 	}
       
  6809 
       
  6810 	status = hmac_sha_256.hmac_update(
       
  6811 		nonce_1->get_data(),
       
  6812 		nonce_1->get_data_length());
       
  6813 	if (status != eap_status_ok)
       
  6814 	{
       
  6815 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6816 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6817 	}
       
  6818 
       
  6819 	status = hmac_sha_256.hmac_update(
       
  6820 		enrollee_mac->get_data(),
       
  6821 		enrollee_mac->get_data_length());
       
  6822 	if (status != eap_status_ok)
       
  6823 	{
       
  6824 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6825 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6826 	}
       
  6827 
       
  6828 	status = hmac_sha_256.hmac_update(
       
  6829 		nonce_2->get_data(),
       
  6830 		nonce_2->get_data_length());
       
  6831 	if (status != eap_status_ok)
       
  6832 	{
       
  6833 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6834 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6835 	}
       
  6836 
       
  6837 
       
  6838 	status = kdk->set_buffer_length(hmac_sha_256.get_digest_length());
       
  6839 	if (status != eap_status_ok)
       
  6840 	{
       
  6841 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6842 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6843 	}
       
  6844 
       
  6845 	status = kdk->set_data_length(hmac_sha_256.get_digest_length());
       
  6846 	if (status != eap_status_ok)
       
  6847 	{
       
  6848 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6849 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6850 	}
       
  6851 
       
  6852 	{
       
  6853 		u32_t md_length(hmac_sha_256.get_digest_length());
       
  6854 
       
  6855 		status = hmac_sha_256.hmac_final(
       
  6856 			kdk->get_data(hmac_sha_256.get_digest_length()),
       
  6857 			&md_length);
       
  6858 		if (status != eap_status_ok)
       
  6859 		{
       
  6860 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6861 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6862 		}
       
  6863 
       
  6864 		EAP_TRACE_DATA_DEBUG(
       
  6865 			m_am_tools,
       
  6866 			TRACE_FLAGS_DEFAULT,
       
  6867 			(EAPL("SIMPLE_CONFIG: simple_config_record_c::generate_kdk(): kdk"),
       
  6868 			 kdk->get_data(),
       
  6869 			 kdk->get_data_length()));
       
  6870 	}
       
  6871 
       
  6872 
       
  6873 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6874 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6875 }
       
  6876 
       
  6877 //--------------------------------------------------
       
  6878 
       
  6879 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::key_derivation_function(
       
  6880 	const eap_variable_data_c * const key,
       
  6881 	const eap_variable_data_c * const personalization_string,
       
  6882 	const u32_t total_key_bits,
       
  6883 	eap_variable_data_c * const result
       
  6884 	)
       
  6885 {
       
  6886 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6887 
       
  6888 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  6889 	EAP_TRACE_DEBUG(
       
  6890 		m_am_tools,
       
  6891 		TRACE_FLAGS_DEFAULT,
       
  6892 		(EAPL("SIMPLE_CONFIG: %s:     key_function: key_derivation_function()\n"),
       
  6893 		(m_is_client == true ? "client": "server")));
       
  6894 
       
  6895 	result->reset();
       
  6896 
       
  6897 	crypto_sha_256_c sha_256(m_am_tools);
       
  6898 	if (sha_256.get_is_valid() == false)
       
  6899 	{
       
  6900 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6901 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6902 	}
       
  6903 
       
  6904 	crypto_hmac_c hmac_sha_256(
       
  6905 		m_am_tools,
       
  6906 		&sha_256,
       
  6907 		false);
       
  6908 	if (hmac_sha_256.get_is_valid() == false)
       
  6909 	{
       
  6910 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6911 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6912 	}
       
  6913 
       
  6914 	EAP_TRACE_DATA_DEBUG(
       
  6915 		m_am_tools,
       
  6916 		TRACE_FLAGS_DEFAULT,
       
  6917 		(EAPL("SIMPLE_CONFIG: key"),
       
  6918 		key->get_data(),
       
  6919 		key->get_data_length()));
       
  6920 
       
  6921 	EAP_TRACE_DATA_DEBUG(
       
  6922 		m_am_tools,
       
  6923 		TRACE_FLAGS_DEFAULT,
       
  6924 		(EAPL("SIMPLE_CONFIG: personalization_string"),
       
  6925 		personalization_string->get_data(),
       
  6926 		personalization_string->get_data_length()));
       
  6927 
       
  6928 	EAP_TRACE_DEBUG(
       
  6929 		m_am_tools,
       
  6930 		TRACE_FLAGS_DEFAULT,
       
  6931 		(EAPL("SIMPLE_CONFIG: total_key_bits %d\n"),
       
  6932 		total_key_bits));
       
  6933 
       
  6934 	u32_t prf_digest_size(hmac_sha_256.get_digest_length()*8ul);
       
  6935 	u32_t iterations((total_key_bits + prf_digest_size - 1) / prf_digest_size);
       
  6936 
       
  6937 	eap_status_e status = result->set_buffer_length(iterations * hmac_sha_256.get_digest_length());
       
  6938 	if (status != eap_status_ok)
       
  6939 	{
       
  6940 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6941 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6942 	}
       
  6943 
       
  6944 	status = result->set_data_length(iterations * hmac_sha_256.get_digest_length());
       
  6945 	if (status != eap_status_ok)
       
  6946 	{
       
  6947 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6948 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6949 	}
       
  6950 
       
  6951 	for (u32_t ind = 0ul; ind != iterations; ++ind)
       
  6952 	{
       
  6953 		status = hmac_sha_256.hmac_set_key(key);
       
  6954 		if (status != eap_status_ok)
       
  6955 		{
       
  6956 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6957 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6958 		}
       
  6959 
       
  6960 		{
       
  6961 			u32_t ind_network_order(eap_htonl(ind+1ul));
       
  6962 			status = hmac_sha_256.hmac_update(
       
  6963 				&ind_network_order,
       
  6964 				sizeof(ind_network_order));
       
  6965 			if (status != eap_status_ok)
       
  6966 			{
       
  6967 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6968 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6969 			}
       
  6970 		}
       
  6971 
       
  6972 		status = hmac_sha_256.hmac_update(
       
  6973 			personalization_string->get_data(),
       
  6974 			personalization_string->get_data_length());
       
  6975 		if (status != eap_status_ok)
       
  6976 		{
       
  6977 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6978 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6979 		}
       
  6980 
       
  6981 		{
       
  6982 			u32_t total_key_bits_network_order(eap_htonl(total_key_bits));
       
  6983 			status = hmac_sha_256.hmac_update(
       
  6984 				&total_key_bits_network_order,
       
  6985 				sizeof(total_key_bits_network_order));
       
  6986 			if (status != eap_status_ok)
       
  6987 			{
       
  6988 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6989 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  6990 			}
       
  6991 		}
       
  6992 
       
  6993 		u32_t md_length(hmac_sha_256.get_digest_length());
       
  6994 
       
  6995 		status = hmac_sha_256.hmac_final(
       
  6996 			result->get_data_offset(ind*hmac_sha_256.get_digest_length(), hmac_sha_256.get_digest_length()),
       
  6997 			&md_length);
       
  6998 		if (status != eap_status_ok)
       
  6999 		{
       
  7000 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7001 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7002 		}
       
  7003 	} // for()
       
  7004 
       
  7005 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7006 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7007 }
       
  7008 
       
  7009 //--------------------------------------------------
       
  7010 
       
  7011 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::derive_additional_keys(
       
  7012 	const eap_variable_data_c * const kdk,
       
  7013 	eap_variable_data_c * const auth_key,
       
  7014 	eap_variable_data_c * const key_wrap_key,
       
  7015 	eap_variable_data_c * const EMSK
       
  7016 	)
       
  7017 {
       
  7018 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7019 
       
  7020 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7021 	EAP_TRACE_DEBUG(
       
  7022 		m_am_tools,
       
  7023 		TRACE_FLAGS_DEFAULT,
       
  7024 		(EAPL("SIMPLE_CONFIG: %s:     key_function: derive_additional_keys()\n"),
       
  7025 		(m_is_client == true ? "client": "server")));
       
  7026 
       
  7027 	EAP_TRACE_DATA_DEBUG(
       
  7028 		m_am_tools, 
       
  7029 		TRACE_FLAGS_DEFAULT, 
       
  7030 		(EAPL("SIMPLE_CONFIG simple_config_record_c::derive_additional_keys(): kdk"),
       
  7031 		 kdk->get_data(),
       
  7032 		 kdk->get_data_length()));
       
  7033 
       
  7034 
       
  7035 	eap_variable_data_c personalization_string(m_am_tools);
       
  7036 
       
  7037 	if (personalization_string.get_is_valid() == false)
       
  7038 	{
       
  7039 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7040 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7041 	}
       
  7042 
       
  7043 	eap_status_e status = personalization_string.set_buffer(
       
  7044 		SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL,
       
  7045 		SIMPLE_CONFIG_SECURE_KEY_DERIVATION_LABEL_LENGTH,
       
  7046 		false,
       
  7047 		false);
       
  7048 	if (personalization_string.get_is_valid() == false)
       
  7049 	{
       
  7050 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7051 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7052 	}
       
  7053 
       
  7054 	eap_variable_data_c key_expansion(m_am_tools);
       
  7055 
       
  7056 	if (key_expansion.get_is_valid() == false)
       
  7057 	{
       
  7058 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7059 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7060 	}
       
  7061 
       
  7062 	u32_t key_bits(SIMPLE_CONFIG_AUTH_KEY_BITS + SIMPLE_CONFIG_KEY_WRAP_KEY_BITS + SIMPLE_CONFIG_EMSK_BITS);
       
  7063 	u32_t key_bytes((key_bits+7)/8);
       
  7064 
       
  7065 	status = key_derivation_function(
       
  7066 		kdk,
       
  7067 		&personalization_string,
       
  7068 		key_bits,
       
  7069 		&key_expansion);
       
  7070 
       
  7071 	if (key_expansion.get_is_valid_data() == false
       
  7072 		|| key_expansion.get_data_length() < key_bytes)
       
  7073 	{
       
  7074 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7075 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7076 	}
       
  7077 
       
  7078 
       
  7079 	u32_t key_offset(0ul);
       
  7080 
       
  7081 	u32_t key_length(SIMPLE_CONFIG_AUTH_KEY_BITS/8ul);
       
  7082 
       
  7083 	status = auth_key->set_copy_of_buffer(
       
  7084 		key_expansion.get_data_offset(key_offset, key_length),
       
  7085 		key_length);
       
  7086 	if (status != eap_status_ok)
       
  7087 	{
       
  7088 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7089 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7090 	}
       
  7091 	key_offset += key_length;
       
  7092 
       
  7093 	key_length = SIMPLE_CONFIG_KEY_WRAP_KEY_BITS/8ul;
       
  7094 
       
  7095 	status = key_wrap_key->set_copy_of_buffer(
       
  7096 		key_expansion.get_data_offset(key_offset, key_length),
       
  7097 		key_length);
       
  7098 	if (status != eap_status_ok)
       
  7099 	{
       
  7100 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7101 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7102 	}
       
  7103 	key_offset += key_length;
       
  7104 
       
  7105 	key_length = SIMPLE_CONFIG_EMSK_BITS/8ul;
       
  7106 
       
  7107 	status = EMSK->set_copy_of_buffer(
       
  7108 		key_expansion.get_data_offset(key_offset, key_length),
       
  7109 		key_length);
       
  7110 	if (status != eap_status_ok)
       
  7111 	{
       
  7112 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7113 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7114 	}
       
  7115 	key_offset += key_length;
       
  7116 
       
  7117 
       
  7118 	EAP_TRACE_DATA_DEBUG(
       
  7119 		m_am_tools,
       
  7120 		TRACE_FLAGS_DEFAULT,
       
  7121 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::derive_additional_keys():     auth_key"),
       
  7122 		 auth_key->get_data(),
       
  7123 		 auth_key->get_data_length()));
       
  7124 
       
  7125 	EAP_TRACE_DATA_DEBUG(
       
  7126 		m_am_tools,
       
  7127 		TRACE_FLAGS_DEFAULT,
       
  7128 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::derive_additional_keys(): key_wrap_key"),
       
  7129 		 key_wrap_key->get_data(),
       
  7130 		 key_wrap_key->get_data_length()));
       
  7131 
       
  7132 	EAP_TRACE_DATA_DEBUG(
       
  7133 		m_am_tools,
       
  7134 		TRACE_FLAGS_DEFAULT,
       
  7135 		(EAPL("SIMPLE_CONFIG: simple_config_record_c::derive_additional_keys():         EMSK"),
       
  7136 		 EMSK->get_data(),
       
  7137 		 EMSK->get_data_length()));
       
  7138 
       
  7139 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7140 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7141 }
       
  7142 
       
  7143 //--------------------------------------------------
       
  7144 
       
  7145 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::generate_authenticator(
       
  7146 	const eap_variable_data_c * const received_simple_config_message,
       
  7147 	const eap_variable_data_c * const new_simple_config_message_data_without_authenticator,
       
  7148 	eap_variable_data_c * const authenticator)
       
  7149 {
       
  7150 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7151 
       
  7152 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7153 	EAP_TRACE_DEBUG(
       
  7154 		m_am_tools,
       
  7155 		TRACE_FLAGS_DEFAULT,
       
  7156 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_authenticator()\n"),
       
  7157 		(m_is_client == true ? "client": "server")));
       
  7158 
       
  7159 	eap_status_e status = eap_status_not_supported;
       
  7160 
       
  7161 	crypto_sha_256_c sha_256(m_am_tools);
       
  7162 	if (sha_256.get_is_valid() == false)
       
  7163 	{
       
  7164 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7165 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7166 	}
       
  7167 
       
  7168 	crypto_hmac_c hmac_sha_256(
       
  7169 		m_am_tools,
       
  7170 		&sha_256,
       
  7171 		false);
       
  7172 	if (hmac_sha_256.get_is_valid() == false)
       
  7173 	{
       
  7174 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7175 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7176 	}
       
  7177 
       
  7178 	EAP_TRACE_DATA_DEBUG(
       
  7179 		m_am_tools, 
       
  7180 		TRACE_FLAGS_DEFAULT, 
       
  7181 		(EAPL("SIMPLE_CONFIG authenticator m_auth_key"),
       
  7182 		 m_auth_key.get_data(),
       
  7183 		 m_auth_key.get_data_length()));
       
  7184 
       
  7185 	status = hmac_sha_256.hmac_set_key(&m_auth_key);
       
  7186 	if (status != eap_status_ok)
       
  7187 	{
       
  7188 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7189 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7190 	}
       
  7191 
       
  7192 	EAP_TRACE_DATA_DEBUG(
       
  7193 		m_am_tools, 
       
  7194 		TRACE_FLAGS_DEFAULT, 
       
  7195 		(EAPL("SIMPLE_CONFIG authenticator data"),
       
  7196 		 received_simple_config_message->get_data(),
       
  7197 		 received_simple_config_message->get_data_length()));
       
  7198 
       
  7199 	status = hmac_sha_256.hmac_update(
       
  7200 		received_simple_config_message->get_data(),
       
  7201 		received_simple_config_message->get_data_length());
       
  7202 	if (status != eap_status_ok)
       
  7203 	{
       
  7204 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7205 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7206 	}
       
  7207 
       
  7208 	EAP_TRACE_DATA_DEBUG(
       
  7209 		m_am_tools, 
       
  7210 		TRACE_FLAGS_DEFAULT, 
       
  7211 		(EAPL("SIMPLE_CONFIG authenticator data"),
       
  7212 		 new_simple_config_message_data_without_authenticator->get_data(),
       
  7213 		 new_simple_config_message_data_without_authenticator->get_data_length()));
       
  7214 
       
  7215 	status = hmac_sha_256.hmac_update(
       
  7216 		new_simple_config_message_data_without_authenticator->get_data(),
       
  7217 		new_simple_config_message_data_without_authenticator->get_data_length());
       
  7218 	if (status != eap_status_ok)
       
  7219 	{
       
  7220 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7221 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7222 	}
       
  7223 
       
  7224 	status = authenticator->set_buffer_length(hmac_sha_256.get_digest_length());
       
  7225 	if (status != eap_status_ok)
       
  7226 	{
       
  7227 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7228 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7229 	}
       
  7230 
       
  7231 	status = authenticator->set_data_length(hmac_sha_256.get_digest_length());
       
  7232 	if (status != eap_status_ok)
       
  7233 	{
       
  7234 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7235 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7236 	}
       
  7237 
       
  7238 	{
       
  7239 		u32_t md_length(hmac_sha_256.get_digest_length());
       
  7240 
       
  7241 		status = hmac_sha_256.hmac_final(
       
  7242 			authenticator->get_data(hmac_sha_256.get_digest_length()),
       
  7243 			&md_length);
       
  7244 		if (status != eap_status_ok)
       
  7245 		{
       
  7246 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7247 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7248 		}
       
  7249 
       
  7250 		EAP_TRACE_DATA_DEBUG(
       
  7251 			m_am_tools, 
       
  7252 			TRACE_FLAGS_DEFAULT, 
       
  7253 			(EAPL("SIMPLE_CONFIG authenticator"),
       
  7254 			 authenticator->get_data(),
       
  7255 			 authenticator->get_data_length()));
       
  7256 
       
  7257 		status = authenticator->set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH);
       
  7258 		if (status != eap_status_ok)
       
  7259 		{
       
  7260 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7261 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7262 		}
       
  7263 	}
       
  7264 
       
  7265 	EAP_TRACE_DEBUG(
       
  7266 		m_am_tools,
       
  7267 		TRACE_FLAGS_DEFAULT,
       
  7268 		(EAPL("SIMPLE_CONFIG: %s:     key_function: generate_authenticator(): returns\n"),
       
  7269 		(m_is_client == true ? "client": "server")));
       
  7270 
       
  7271 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7272 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7273 }
       
  7274 
       
  7275 //--------------------------------------------------
       
  7276 
       
  7277 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::add_authenticator_attribute(
       
  7278 	simple_config_message_c * const received_simple_config_message,
       
  7279 	simple_config_message_c * const new_simple_config_message)
       
  7280 {
       
  7281 	EAP_TRACE_DEBUG(
       
  7282 		m_am_tools,
       
  7283 		TRACE_FLAGS_DEFAULT,
       
  7284 		(EAPL("SIMPLE_CONFIG: %s:     message_function: add_authenticator_attribute()\n"),
       
  7285 		(m_is_client == true ? "client": "server")));
       
  7286 
       
  7287 	eap_status_e status(eap_status_process_general_error);
       
  7288 
       
  7289 	simple_config_payloads_c * authenticator_payload = new simple_config_payloads_c(m_am_tools);
       
  7290 	eap_automatic_variable_c<simple_config_payloads_c> automatic_payloads(m_am_tools, authenticator_payload);
       
  7291 
       
  7292 	if (authenticator_payload == 0
       
  7293 		|| authenticator_payload->get_is_valid() == false)
       
  7294 	{
       
  7295 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7296 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7297 	}
       
  7298 
       
  7299 	{
       
  7300 		eap_variable_data_c authenticator(m_am_tools);
       
  7301 
       
  7302 		if (authenticator.get_is_valid() == false)
       
  7303 		{
       
  7304 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7305 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7306 		}
       
  7307 
       
  7308 		status = generate_authenticator(
       
  7309 			received_simple_config_message->get_simple_config_message_data(),
       
  7310 			new_simple_config_message->get_simple_config_message_data(),
       
  7311 			&authenticator);
       
  7312 		if (status != eap_status_ok)
       
  7313 		{
       
  7314 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7315 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7316 		}
       
  7317 
       
  7318 		status = authenticator_payload->copy_attribute_data(
       
  7319 			simple_config_Attribute_Type_Authenticator,
       
  7320 			true,
       
  7321 			authenticator.get_data(),
       
  7322 			authenticator.get_data_length());
       
  7323 		if (status != eap_status_ok)
       
  7324 		{
       
  7325 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7326 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7327 		}
       
  7328 	}
       
  7329 
       
  7330 	// Adds Authenticator attribute to the end of the message.
       
  7331 	status = authenticator_payload->create_simple_config_message(
       
  7332 		new_simple_config_message,
       
  7333 		true);
       
  7334 	if (status != eap_status_ok)
       
  7335 	{
       
  7336 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7337 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7338 	}
       
  7339 
       
  7340 	EAP_TRACE_DEBUG(
       
  7341 		m_am_tools,
       
  7342 		TRACE_FLAGS_DEFAULT,
       
  7343 		(EAPL("SIMPLE_CONFIG: %s:     message_function: add_authenticator_attribute(): returns\n"),
       
  7344 		(m_is_client == true ? "client": "server")));
       
  7345 
       
  7346 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7347 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7348 }
       
  7349 
       
  7350 //--------------------------------------------------
       
  7351 
       
  7352 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::encrypt_payloads(
       
  7353 	const eap_variable_data_c * const auth_key,
       
  7354 	const eap_variable_data_c * const key_wrap_key,
       
  7355 	simple_config_payloads_c * const plaintext_payloads,
       
  7356 	simple_config_variable_data_c * const encrypted_settings)
       
  7357 {
       
  7358 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7359 
       
  7360 	EAP_TRACE_DEBUG(
       
  7361 		m_am_tools,
       
  7362 		TRACE_FLAGS_DEFAULT,
       
  7363 		(EAPL("SIMPLE_CONFIG: %s: pki_function: encrypt_payloads()\n"),
       
  7364 		(m_is_client == true ? "client": "server")));
       
  7365 
       
  7366 	eap_status_e status(eap_status_process_general_error);
       
  7367 
       
  7368 	simple_config_message_c plaintext_data(
       
  7369 		m_am_tools,
       
  7370 		m_is_client);
       
  7371 
       
  7372 	status = plaintext_payloads->create_simple_config_message(
       
  7373 		&plaintext_data,
       
  7374 		false);
       
  7375 	if (status != eap_status_ok)
       
  7376 	{
       
  7377 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7378 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7379 	}
       
  7380 
       
  7381 
       
  7382 	eap_variable_data_c KWA(m_am_tools);
       
  7383 
       
  7384 	if (KWA.get_is_valid() == false)
       
  7385 	{
       
  7386 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7387 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7388 	}
       
  7389 
       
  7390 	{
       
  7391 		crypto_sha_256_c sha_256(m_am_tools);
       
  7392 		if (sha_256.get_is_valid() == false)
       
  7393 		{
       
  7394 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7395 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7396 		}
       
  7397 
       
  7398 		crypto_hmac_c hmac_sha_256(
       
  7399 			m_am_tools,
       
  7400 			&sha_256,
       
  7401 			false);
       
  7402 		if (hmac_sha_256.get_is_valid() == false)
       
  7403 		{
       
  7404 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7405 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7406 		}
       
  7407 
       
  7408 		EAP_TRACE_DATA_DEBUG(
       
  7409 			m_am_tools, 
       
  7410 			TRACE_FLAGS_DEFAULT, 
       
  7411 			(EAPL("SIMPLE_CONFIG auth_key"),
       
  7412 			auth_key->get_data(),
       
  7413 			auth_key->get_data_length()));
       
  7414 
       
  7415 		status = hmac_sha_256.hmac_set_key(auth_key);
       
  7416 		if (status != eap_status_ok)
       
  7417 		{
       
  7418 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7419 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7420 		}
       
  7421 
       
  7422 		EAP_TRACE_DATA_DEBUG(
       
  7423 			m_am_tools, 
       
  7424 			TRACE_FLAGS_DEFAULT, 
       
  7425 			(EAPL("SIMPLE_CONFIG plaintext_data"),
       
  7426 			plaintext_data.get_simple_config_message_data()->get_data(),
       
  7427 			plaintext_data.get_simple_config_message_data()->get_data_length()));
       
  7428 
       
  7429 		status = hmac_sha_256.hmac_update(
       
  7430 			plaintext_data.get_simple_config_message_data()->get_data(),
       
  7431 			plaintext_data.get_simple_config_message_data()->get_data_length());
       
  7432 		if (status != eap_status_ok)
       
  7433 		{
       
  7434 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7435 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7436 		}
       
  7437 
       
  7438 		status = KWA.set_buffer_length(hmac_sha_256.get_digest_length());
       
  7439 		if (status != eap_status_ok)
       
  7440 		{
       
  7441 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7442 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7443 		}
       
  7444 
       
  7445 		status = KWA.set_data_length(hmac_sha_256.get_digest_length());
       
  7446 		if (status != eap_status_ok)
       
  7447 		{
       
  7448 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7449 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7450 		}
       
  7451 
       
  7452 		{
       
  7453 			u32_t md_length(hmac_sha_256.get_digest_length());
       
  7454 
       
  7455 			status = hmac_sha_256.hmac_final(
       
  7456 				KWA.get_data(hmac_sha_256.get_digest_length()),
       
  7457 				&md_length);
       
  7458 			if (status != eap_status_ok)
       
  7459 			{
       
  7460 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7461 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7462 			}
       
  7463 
       
  7464 			EAP_TRACE_DATA_DEBUG(
       
  7465 				m_am_tools, 
       
  7466 				TRACE_FLAGS_DEFAULT, 
       
  7467 				(EAPL("SIMPLE_CONFIG KWA"),
       
  7468 				 KWA.get_data(),
       
  7469 				 KWA.get_data_length()));
       
  7470 
       
  7471 			status = KWA.set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH);
       
  7472 			if (status != eap_status_ok)
       
  7473 			{
       
  7474 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7475 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7476 			}
       
  7477 		}
       
  7478 	}
       
  7479 
       
  7480 	{
       
  7481 		status = plaintext_payloads->copy_attribute_data(
       
  7482 			simple_config_Attribute_Type_Key_Wrap_Authenticator,
       
  7483 			true,
       
  7484 			KWA.get_data(),
       
  7485 			KWA.get_data_length());
       
  7486 		if (status != eap_status_ok)
       
  7487 		{
       
  7488 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7489 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7490 		}
       
  7491 
       
  7492 		status = plaintext_payloads->create_simple_config_message(
       
  7493 			&plaintext_data,
       
  7494 			false);
       
  7495 		if (status != eap_status_ok)
       
  7496 		{
       
  7497 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7498 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7499 		}
       
  7500 	}
       
  7501 
       
  7502 	eap_variable_data_c IV(m_am_tools);
       
  7503 
       
  7504 	if (IV.get_is_valid() == false)
       
  7505 	{
       
  7506 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7507 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7508 	}
       
  7509 
       
  7510 	{
       
  7511 		// Creates Enrollee Nonce.
       
  7512 		status = generate_nonce(
       
  7513 			&IV,
       
  7514 			SIMPLE_CONFIG_KEY_WRAP_IV_SIZE);
       
  7515 		if (status != eap_status_ok)
       
  7516 		{
       
  7517 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7518 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7519 		}
       
  7520 	}
       
  7521 
       
  7522 
       
  7523 	{
       
  7524 		crypto_aes_c aes(m_am_tools);
       
  7525 
       
  7526 		crypto_cbc_c aes_cbc(
       
  7527 			m_am_tools,
       
  7528 			&aes,
       
  7529 			false);
       
  7530 
       
  7531 		if (aes_cbc.get_is_valid() == false)
       
  7532 		{
       
  7533 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7534 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7535 		}
       
  7536 
       
  7537 		EAP_TRACE_DATA_DEBUG(
       
  7538 			m_am_tools, 
       
  7539 			TRACE_FLAGS_DEFAULT, 
       
  7540 			(EAPL("SIMPLE_CONFIG key_wrap_key"),
       
  7541 			key_wrap_key->get_data(),
       
  7542 			key_wrap_key->get_data_length()));
       
  7543 
       
  7544 		EAP_TRACE_DATA_DEBUG(
       
  7545 			m_am_tools, 
       
  7546 			TRACE_FLAGS_DEFAULT, 
       
  7547 			(EAPL("SIMPLE_CONFIG IV"),
       
  7548 			IV.get_data(),
       
  7549 			IV.get_data_length()));
       
  7550 
       
  7551 		status = aes_cbc.set_encryption_key(
       
  7552 			IV.get_data(),
       
  7553 			IV.get_data_length(),
       
  7554 			key_wrap_key->get_data(),
       
  7555 			key_wrap_key->get_data_length());
       
  7556 		if (status != eap_status_ok)
       
  7557 		{
       
  7558 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7559 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7560 		}
       
  7561 
       
  7562 		status = plaintext_data.add_padding(aes_cbc.get_block_size());
       
  7563 		if (status != eap_status_ok)
       
  7564 		{
       
  7565 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7566 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7567 		}
       
  7568 
       
  7569 		EAP_TRACE_DATA_DEBUG(
       
  7570 			m_am_tools, 
       
  7571 			TRACE_FLAGS_DEFAULT, 
       
  7572 			(EAPL("SIMPLE_CONFIG plaintext data"),
       
  7573 			 plaintext_data.get_simple_config_message_data()->get_data(),
       
  7574 			 plaintext_data.get_simple_config_message_data()->get_data_length()));
       
  7575 
       
  7576 		status = aes_cbc.update_non_aligned(
       
  7577 			plaintext_data.get_simple_config_message_data()->get_data(),
       
  7578 			plaintext_data.get_simple_config_message_data()->get_data_length());
       
  7579 		if (status != eap_status_ok)
       
  7580 		{
       
  7581 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7582 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7583 		}
       
  7584 
       
  7585 		status = aes_cbc.finalize_non_aligned();
       
  7586 		if (status != eap_status_ok)
       
  7587 		{
       
  7588 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7589 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7590 		}
       
  7591 
       
  7592 		EAP_TRACE_DATA_DEBUG(
       
  7593 			m_am_tools, 
       
  7594 			TRACE_FLAGS_DEFAULT, 
       
  7595 			(EAPL("SIMPLE_CONFIG encrypted data"),
       
  7596 			 plaintext_data.get_simple_config_message_data()->get_data(),
       
  7597 			 plaintext_data.get_simple_config_message_data()->get_data_length()));
       
  7598 
       
  7599 
       
  7600 		status = encrypted_settings->set_copy_of_buffer(
       
  7601 			simple_config_Attribute_Type_Encrypted_Settings,
       
  7602 			true,
       
  7603 			IV.get_data(),
       
  7604 			IV.get_data_length());
       
  7605 		if (status != eap_status_ok)
       
  7606 		{
       
  7607 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7608 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7609 		}
       
  7610 
       
  7611 		status = encrypted_settings->add_data(
       
  7612 			plaintext_data.get_simple_config_message_data()->get_data(),
       
  7613 			plaintext_data.get_simple_config_message_data()->get_data_length());
       
  7614 		if (status != eap_status_ok)
       
  7615 		{
       
  7616 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7617 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7618 		}
       
  7619 
       
  7620 	}
       
  7621 
       
  7622 	EAP_TRACE_DEBUG(
       
  7623 		m_am_tools,
       
  7624 		TRACE_FLAGS_DEFAULT,
       
  7625 		(EAPL("SIMPLE_CONFIG: %s: pki_function: encrypt_payloads(): returns\n"),
       
  7626 		(m_is_client == true ? "client": "server")));
       
  7627 
       
  7628 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7629 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7630 }
       
  7631 
       
  7632 //--------------------------------------------------
       
  7633 
       
  7634 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::decrypt_payloads(
       
  7635 	const eap_variable_data_c * const auth_key,
       
  7636 	const eap_variable_data_c * const key_wrap_key,
       
  7637 	simple_config_variable_data_c * const encrypted_settings,
       
  7638 	simple_config_payloads_c * const plaintext_payloads)
       
  7639 {
       
  7640 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7641 
       
  7642 	EAP_TRACE_DEBUG(
       
  7643 		m_am_tools,
       
  7644 		TRACE_FLAGS_DEFAULT,
       
  7645 		(EAPL("SIMPLE_CONFIG: %s: pki_function: decrypt_payloads()\n"),
       
  7646 		(m_is_client == true ? "client": "server")));
       
  7647 
       
  7648 	eap_status_e status(eap_status_process_general_error);
       
  7649 
       
  7650 	eap_variable_data_c data_payload(m_am_tools);
       
  7651 
       
  7652 	if (data_payload.get_is_valid() == false)
       
  7653 	{
       
  7654 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7655 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7656 	}
       
  7657 
       
  7658 	status = data_payload.set_buffer(
       
  7659 		encrypted_settings->get_data(encrypted_settings->get_data_length()),
       
  7660 		encrypted_settings->get_data_length(),
       
  7661 		false,
       
  7662 		false);
       
  7663 	if (status != eap_status_ok)
       
  7664 	{
       
  7665 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7666 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7667 	}
       
  7668 
       
  7669 	if (data_payload.get_data_length() <= SIMPLE_CONFIG_KEY_WRAP_IV_SIZE)
       
  7670 	{
       
  7671 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7672 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  7673 	}
       
  7674 
       
  7675 
       
  7676 	eap_variable_data_c IV(m_am_tools);
       
  7677 
       
  7678 	if (IV.get_is_valid() == false)
       
  7679 	{
       
  7680 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7681 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7682 	}
       
  7683 
       
  7684 	status = IV.set_buffer(
       
  7685 		data_payload.get_data(SIMPLE_CONFIG_KEY_WRAP_IV_SIZE),
       
  7686 		SIMPLE_CONFIG_KEY_WRAP_IV_SIZE,
       
  7687 		false,
       
  7688 		false);
       
  7689 	if (status != eap_status_ok)
       
  7690 	{
       
  7691 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7692 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7693 	}
       
  7694 
       
  7695 
       
  7696 	eap_variable_data_c decrypted_data(m_am_tools);
       
  7697 
       
  7698 	if (decrypted_data.get_is_valid() == false)
       
  7699 	{
       
  7700 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7701 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7702 	}
       
  7703 
       
  7704 	const u32_t encrypted_data_length(
       
  7705 		data_payload.get_data_length()
       
  7706 		- SIMPLE_CONFIG_KEY_WRAP_IV_SIZE);
       
  7707 
       
  7708 	status = decrypted_data.set_buffer(
       
  7709 		data_payload.get_data_offset(
       
  7710 			SIMPLE_CONFIG_KEY_WRAP_IV_SIZE,
       
  7711 			encrypted_data_length),
       
  7712 		encrypted_data_length,
       
  7713 		false,
       
  7714 		false);
       
  7715 	if (status != eap_status_ok)
       
  7716 	{
       
  7717 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7718 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7719 	}
       
  7720 
       
  7721 	EAP_TRACE_DATA_DEBUG(
       
  7722 		m_am_tools, 
       
  7723 		TRACE_FLAGS_DEFAULT, 
       
  7724 		(EAPL("SIMPLE_CONFIG key_wrap_key"),
       
  7725 		key_wrap_key->get_data(),
       
  7726 		key_wrap_key->get_data_length()));
       
  7727 
       
  7728 	EAP_TRACE_DATA_DEBUG(
       
  7729 		m_am_tools, 
       
  7730 		TRACE_FLAGS_DEFAULT, 
       
  7731 		(EAPL("SIMPLE_CONFIG IV"),
       
  7732 		IV.get_data(),
       
  7733 		IV.get_data_length()));
       
  7734 
       
  7735 	EAP_TRACE_DATA_DEBUG(
       
  7736 		m_am_tools, 
       
  7737 		TRACE_FLAGS_DEFAULT, 
       
  7738 		(EAPL("SIMPLE_CONFIG encrypted data"),
       
  7739 		decrypted_data.get_data(),
       
  7740 		decrypted_data.get_data_length()));
       
  7741 
       
  7742 	{
       
  7743 		crypto_aes_c aes(m_am_tools);
       
  7744 
       
  7745 		crypto_cbc_c aes_cbc(
       
  7746 			m_am_tools,
       
  7747 			&aes,
       
  7748 			false);
       
  7749 
       
  7750 		if (aes_cbc.get_is_valid() == false)
       
  7751 		{
       
  7752 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7753 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7754 		}
       
  7755 
       
  7756 		status = aes_cbc.set_decryption_key(
       
  7757 			IV.get_data(),
       
  7758 			IV.get_data_length(),
       
  7759 			key_wrap_key->get_data(),
       
  7760 			key_wrap_key->get_data_length());
       
  7761 		if (status != eap_status_ok)
       
  7762 		{
       
  7763 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7764 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7765 		}
       
  7766 
       
  7767 		status = aes_cbc.update_non_aligned(
       
  7768 			decrypted_data.get_data(),
       
  7769 			decrypted_data.get_data_length());
       
  7770 		if (status != eap_status_ok)
       
  7771 		{
       
  7772 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7773 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7774 		}
       
  7775 
       
  7776 		status = aes_cbc.finalize_non_aligned();
       
  7777 		if (status != eap_status_ok)
       
  7778 		{
       
  7779 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7780 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7781 		}
       
  7782 
       
  7783 		EAP_TRACE_DATA_DEBUG(
       
  7784 			m_am_tools, 
       
  7785 			TRACE_FLAGS_DEFAULT, 
       
  7786 			(EAPL("SIMPLE_CONFIG plaintext data"),
       
  7787 			decrypted_data.get_data(),
       
  7788 			decrypted_data.get_data_length()));
       
  7789 	}
       
  7790 
       
  7791 
       
  7792 	u32_t data_length(decrypted_data.get_data_length());
       
  7793 	u32_t padding_length(0ul);
       
  7794 
       
  7795 	status = plaintext_payloads->parse_simple_config_payloads(
       
  7796 		decrypted_data.get_data(),
       
  7797 		&data_length,
       
  7798 		&padding_length);
       
  7799 	if (status != eap_status_ok)
       
  7800 	{
       
  7801 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7802 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7803 	}
       
  7804 
       
  7805 
       
  7806 	simple_config_variable_data_c * const received_KWA
       
  7807 		= plaintext_payloads->get_attribute_pointer(simple_config_Attribute_Type_Key_Wrap_Authenticator);
       
  7808 	if (received_KWA == 0)
       
  7809 	{
       
  7810 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7811 		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  7812 	}
       
  7813 
       
  7814 	EAP_TRACE_DATA_DEBUG(
       
  7815 		m_am_tools, 
       
  7816 		TRACE_FLAGS_DEFAULT, 
       
  7817 		(EAPL("SIMPLE_CONFIG received_KWA"),
       
  7818 		 received_KWA->get_data(received_KWA->get_data_length()),
       
  7819 		 received_KWA->get_data_length()));
       
  7820 
       
  7821 
       
  7822 	eap_variable_data_c plaintext_data(m_am_tools);
       
  7823 
       
  7824 	if (plaintext_data.get_is_valid() == false)
       
  7825 	{
       
  7826 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7827 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7828 	}
       
  7829 
       
  7830 	if (decrypted_data.get_data_length() < (received_KWA->get_header()->get_length()+padding_length))
       
  7831 	{
       
  7832 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7833 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  7834 	}
       
  7835 
       
  7836 	const u32_t plaintext_data_length(
       
  7837 		decrypted_data.get_data_length()
       
  7838 		- (received_KWA->get_header()->get_length()+padding_length));
       
  7839 
       
  7840 	status = plaintext_data.set_buffer(
       
  7841 		decrypted_data.get_data(plaintext_data_length),
       
  7842 		plaintext_data_length,
       
  7843 		false,
       
  7844 		false);
       
  7845 	if (status != eap_status_ok)
       
  7846 	{
       
  7847 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7848 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7849 	}
       
  7850 
       
  7851 	EAP_TRACE_DATA_DEBUG(
       
  7852 		m_am_tools, 
       
  7853 		TRACE_FLAGS_DEFAULT, 
       
  7854 		(EAPL("SIMPLE_CONFIG plaintext_data"),
       
  7855 		 plaintext_data.get_data(),
       
  7856 		 plaintext_data.get_data_length()));
       
  7857 
       
  7858 
       
  7859 	{
       
  7860 		crypto_sha_256_c sha_256(m_am_tools);
       
  7861 		if (sha_256.get_is_valid() == false)
       
  7862 		{
       
  7863 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7864 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7865 		}
       
  7866 
       
  7867 		crypto_hmac_c hmac_sha_256(
       
  7868 			m_am_tools,
       
  7869 			&sha_256,
       
  7870 			false);
       
  7871 		if (hmac_sha_256.get_is_valid() == false)
       
  7872 		{
       
  7873 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7874 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7875 		}
       
  7876 
       
  7877 		EAP_TRACE_DATA_DEBUG(
       
  7878 			m_am_tools, 
       
  7879 			TRACE_FLAGS_DEFAULT, 
       
  7880 			(EAPL("SIMPLE_CONFIG authenticator auth_key"),
       
  7881 			 auth_key->get_data(),
       
  7882 			 auth_key->get_data_length()));
       
  7883 
       
  7884 		status = hmac_sha_256.hmac_set_key(auth_key);
       
  7885 		if (status != eap_status_ok)
       
  7886 		{
       
  7887 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7888 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7889 		}
       
  7890 
       
  7891 		status = hmac_sha_256.hmac_update(
       
  7892 			plaintext_data.get_data(),
       
  7893 			plaintext_data.get_data_length());
       
  7894 		if (status != eap_status_ok)
       
  7895 		{
       
  7896 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7897 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7898 		}
       
  7899 
       
  7900 		eap_variable_data_c local_KWA(m_am_tools);
       
  7901 
       
  7902 		if (local_KWA.get_is_valid() == false)
       
  7903 		{
       
  7904 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7905 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7906 		}
       
  7907 
       
  7908 		status = local_KWA.set_buffer_length(hmac_sha_256.get_digest_length());
       
  7909 		if (status != eap_status_ok)
       
  7910 		{
       
  7911 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7912 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7913 		}
       
  7914 
       
  7915 		status = local_KWA.set_data_length(hmac_sha_256.get_digest_length());
       
  7916 		if (status != eap_status_ok)
       
  7917 		{
       
  7918 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7919 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7920 		}
       
  7921 
       
  7922 		{
       
  7923 			u32_t md_length(hmac_sha_256.get_digest_length());
       
  7924 
       
  7925 			status = hmac_sha_256.hmac_final(
       
  7926 				local_KWA.get_data(hmac_sha_256.get_digest_length()),
       
  7927 				&md_length);
       
  7928 			if (status != eap_status_ok)
       
  7929 			{
       
  7930 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7931 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7932 			}
       
  7933 
       
  7934 			EAP_TRACE_DATA_DEBUG(
       
  7935 				m_am_tools, 
       
  7936 				TRACE_FLAGS_DEFAULT, 
       
  7937 				(EAPL("SIMPLE_CONFIG local_KWA"),
       
  7938 				 local_KWA.get_data(),
       
  7939 				 local_KWA.get_data_length()));
       
  7940 
       
  7941 			status = local_KWA.set_data_length(SIMPLE_CONFIG_AUTHENTICATOR_LENGTH);
       
  7942 			if (status != eap_status_ok)
       
  7943 			{
       
  7944 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7945 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7946 			}
       
  7947 
       
  7948 			if (local_KWA.compare(
       
  7949 				received_KWA->get_data(received_KWA->get_data_length()),
       
  7950 				received_KWA->get_data_length()) != 0)
       
  7951 			{
       
  7952 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7953 				return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  7954 			}
       
  7955 		}
       
  7956 	}
       
  7957 
       
  7958 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7959 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7960 }
       
  7961 
       
  7962 //--------------------------------------------------
       
  7963 
       
  7964 EAP_FUNC_EXPORT eap_status_e simple_config_record_c::complete_query_network_and_device_parameters(
       
  7965 	const simple_config_state_e state,
       
  7966 	simple_config_payloads_c * const network_and_device_parameters,
       
  7967 	const eap_status_e p_completion_status)
       
  7968 {
       
  7969 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7970 
       
  7971 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  7972 	EAP_TRACE_DEBUG(
       
  7973 		m_am_tools,
       
  7974 		TRACE_FLAGS_DEFAULT,
       
  7975 		(EAPL("SIMPLE_CONFIG: %s: pki_function: complete_query_network_and_device_parameters()\n"),
       
  7976 		(m_is_client == true ? "client": "server")));
       
  7977 
       
  7978 	m_pending_query_network_and_device_parameters = false;
       
  7979 
       
  7980 	if (network_and_device_parameters == 0
       
  7981 		|| network_and_device_parameters->get_is_valid() == false)
       
  7982 	{
       
  7983 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7984 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  7985 	}
       
  7986 
       
  7987 	eap_status_e local_completion_status(p_completion_status);
       
  7988 	eap_status_e status(eap_status_process_general_error);
       
  7989 
       
  7990 
       
  7991 	{
       
  7992 		if (m_simple_config_state == simple_config_state_process_simple_config_start)
       
  7993 		{
       
  7994 			status = network_and_device_parameters->get_attribute_data(
       
  7995 				simple_config_Attribute_Type_UUID_E,
       
  7996 				&m_UUID_E);
       
  7997 			if (status != eap_status_ok)
       
  7998 			{
       
  7999 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8000 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8001 			}
       
  8002 
       
  8003 			{
       
  8004 				u16_t data(0ul);
       
  8005 
       
  8006 				status = network_and_device_parameters->get_attribute_data(
       
  8007 					simple_config_Attribute_Type_Device_Password_ID,
       
  8008 					&data);
       
  8009 				if (status != eap_status_ok)
       
  8010 				{
       
  8011 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8012 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  8013 				}
       
  8014 
       
  8015 				m_local_Device_Password_ID = static_cast<simple_config_Device_Password_ID_e>(data);
       
  8016 			}
       
  8017 
       
  8018 			{
       
  8019 				u8_t RF_Band(simple_config_RF_Bands_2_4_GHz);
       
  8020 
       
  8021 				status = network_and_device_parameters->get_attribute_data(
       
  8022 					simple_config_Attribute_Type_RF_Band,
       
  8023 					&RF_Band);
       
  8024 				if (status != eap_status_ok)
       
  8025 				{
       
  8026 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8027 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  8028 				}
       
  8029 
       
  8030 				m_Rf_Bands = static_cast<simple_config_RF_Bands_e>(RF_Band);
       
  8031 			}
       
  8032 		}
       
  8033 		else if (m_simple_config_state == simple_config_state_process_M1)
       
  8034 		{
       
  8035 			status = network_and_device_parameters->get_attribute_data(
       
  8036 				simple_config_Attribute_Type_UUID_R,
       
  8037 				&m_UUID_R);
       
  8038 			if (status != eap_status_ok)
       
  8039 			{
       
  8040 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8041 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8042 			}
       
  8043 
       
  8044 			status = network_and_device_parameters->get_attribute_data(
       
  8045 				simple_config_Attribute_Type_SSID,
       
  8046 				&m_SSID);
       
  8047 			if (status != eap_status_ok)
       
  8048 			{
       
  8049 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8050 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8051 			}
       
  8052 
       
  8053 			status = network_and_device_parameters->get_attribute_data(
       
  8054 				simple_config_Attribute_Type_MAC_Address,
       
  8055 				&m_MAC_address);
       
  8056 			if (status != eap_status_ok)
       
  8057 			{
       
  8058 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8059 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  8060 			}
       
  8061 
       
  8062 			{
       
  8063 				u16_t data(0ul);
       
  8064 
       
  8065 				status = network_and_device_parameters->get_attribute_data(
       
  8066 					simple_config_Attribute_Type_Device_Password_ID,
       
  8067 					&data);
       
  8068 				if (status != eap_status_ok)
       
  8069 				{
       
  8070 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8071 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  8072 				}
       
  8073 
       
  8074 				if (status == eap_status_ok)
       
  8075 				{
       
  8076 					m_local_Device_Password_ID = static_cast<simple_config_Device_Password_ID_e>(data);
       
  8077 				}
       
  8078 
       
  8079 				if (m_received_Device_Password_ID != m_local_Device_Password_ID)
       
  8080 				{
       
  8081 					// Registrar requires different Device_Password_ID.
       
  8082 					local_completion_status = eap_status_user_has_not_subscribed_to_the_requested_service;
       
  8083 
       
  8084 					bool add_new_attribute(false);
       
  8085 
       
  8086 					// Change the error attribute to simple_config_Configuration_Error_Network_auth_failure.
       
  8087 					simple_config_variable_data_c * Configuration_Error
       
  8088 						= network_and_device_parameters->get_attribute_pointer(simple_config_Attribute_Type_Configuration_Error);
       
  8089 					if (Configuration_Error == 0)
       
  8090 					{
       
  8091 						// Add a new simple_config_Attribute_Type_Configuration_Error attribute.
       
  8092 						Configuration_Error = new simple_config_variable_data_c(m_am_tools);
       
  8093 
       
  8094 						if (Configuration_Error != 0)
       
  8095 						{
       
  8096 							add_new_attribute = true;
       
  8097 						}
       
  8098 						else
       
  8099 						{
       
  8100 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8101 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  8102 						}
       
  8103 					}
       
  8104 
       
  8105 					if (Configuration_Error != 0)
       
  8106 					{
       
  8107 						u16_t error(simple_config_Configuration_Error_Network_auth_failure);
       
  8108 						u16_t network_order_error(eap_htons(error));
       
  8109 
       
  8110 						status = Configuration_Error->set_copy_of_buffer(
       
  8111 							simple_config_Attribute_Type_Configuration_Error,
       
  8112 							true,
       
  8113 							&network_order_error,
       
  8114 							sizeof(network_order_error));
       
  8115 						if (status != eap_status_ok)
       
  8116 						{
       
  8117 							if (add_new_attribute == true)
       
  8118 							{
       
  8119 								delete Configuration_Error;
       
  8120 								Configuration_Error = 0;
       
  8121 							}
       
  8122 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8123 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  8124 						}
       
  8125 
       
  8126 						if (add_new_attribute == true)
       
  8127 						{
       
  8128 							// Only the new object is added.
       
  8129 							status = network_and_device_parameters->add_attribute(Configuration_Error);
       
  8130 							if (status != eap_status_ok)
       
  8131 							{
       
  8132 								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8133 								return EAP_STATUS_RETURN(m_am_tools, status);
       
  8134 							}
       
  8135 						}
       
  8136 					}
       
  8137 					else
       
  8138 					{
       
  8139 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8140 						return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
       
  8141 					}
       
  8142 				}
       
  8143 			}
       
  8144 		}
       
  8145 	}
       
  8146 
       
  8147 
       
  8148 	if (m_local_Device_Password_ID == simple_config_Device_Password_ID_PushButton)
       
  8149 	{
       
  8150 		// Set m_device_password to all ascii zeroes SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN.
       
  8151 		status = m_device_password.set_copy_of_buffer(
       
  8152 			SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN,
       
  8153 			SIMPLE_CONFIG_PBC_DEVICE_PASSWORD_PIN_SIZE);
       
  8154 		if (status != eap_status_ok)
       
  8155 		{
       
  8156 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8157 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8158 		}
       
  8159 	}
       
  8160 
       
  8161 
       
  8162 	if (local_completion_status == eap_status_ok)
       
  8163 	{
       
  8164 		switch (state)
       
  8165 		{
       
  8166 
       
  8167 		case simple_config_state_process_simple_config_start:
       
  8168 			status = send_M1(network_and_device_parameters);
       
  8169 			break;
       
  8170 
       
  8171 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  8172 
       
  8173 		case simple_config_state_process_M1:
       
  8174 			status = send_M2(network_and_device_parameters);
       
  8175 			break;
       
  8176 
       
  8177 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  8178 
       
  8179 		default:
       
  8180 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8181 			return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  8182 
       
  8183 		} // switch (state)
       
  8184 	}
       
  8185 	else if (local_completion_status == eap_status_user_has_not_subscribed_to_the_requested_service)
       
  8186 	{
       
  8187 		switch (state)
       
  8188 		{
       
  8189 
       
  8190 		case simple_config_state_process_simple_config_start:
       
  8191 			status = send_WSC_NACK();
       
  8192 			break;
       
  8193 
       
  8194 #if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  8195 
       
  8196 		case simple_config_state_process_M1:
       
  8197 			status = send_M2D(network_and_device_parameters);
       
  8198 			break;
       
  8199 
       
  8200 #endif //#if defined(USE_EAP_TYPE_SERVER_SIMPLE_CONFIG)
       
  8201 
       
  8202 		default:
       
  8203 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8204 			return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  8205 
       
  8206 		} // switch(state)
       
  8207 	}
       
  8208 
       
  8209 	if (status == eap_status_ok)
       
  8210 	{
       
  8211 		status = check_sent_simple_config_message();
       
  8212 		if (status != eap_status_ok)
       
  8213 		{
       
  8214 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8215 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  8216 		}
       
  8217 
       
  8218 		status = eap_status_completed_request;
       
  8219 	}
       
  8220 
       
  8221 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  8222 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  8223 }
       
  8224 
       
  8225 //--------------------------------------------------
       
  8226 
       
  8227 #endif //#if defined(USE_EAP_SIMPLE_CONFIG)
       
  8228 
       
  8229 
       
  8230 // End.