eapol/eapol_framework/eapol_common/type/tls_peap/tls/src/tls_application_eap_core.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 124 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 
       
    28 #include "eap_am_memory.h"
       
    29 #include "eap_tools.h"
       
    30 #include "eap_am_tools.h"
       
    31 #include "eap_core.h"
       
    32 #include "eap_type_tls_peap_types.h"
       
    33 #include "tls_record_header.h"
       
    34 #include "abs_tls_base_application.h"
       
    35 #include "tls_application_eap_core.h"
       
    36 #include "tls_peap_types.h"
       
    37 #include "tls_peap_tlv_header.h"
       
    38 #include "eap_diameter_avp_header.h"
       
    39 #include "eap_state_notification.h"
       
    40 #include "eap_crypto_api.h"
       
    41 #include "eap_header_string.h"
       
    42 #include "abs_eap_am_mutex.h"
       
    43 #include "eap_config.h"
       
    44 #include "eapol_header.h"
       
    45 #include "eap_network_id_selector.h"
       
    46 #include "eap_tlv_message_data.h"
       
    47 #include "eap_array_algorithms.h"
       
    48 #include "eap_automatic_variable.h"
       
    49 #include "eap_base_type.h"
       
    50 
       
    51 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
    52 	#include "eap_type_mschapv2_types.h"
       
    53 	#include "eap_type_mschapv2_header.h"
       
    54 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
    55 
       
    56 const u32_t TLV_NONCE_LENGTH = 32ul;
       
    57 const u32_t TLV_MAC_LENGTH = 16ul;
       
    58 
       
    59 const u32_t TLV_NONCE_OFFSET = 4ul;
       
    60 const u32_t TLV_MAC_OFFSET = TLV_NONCE_OFFSET + TLV_NONCE_LENGTH;
       
    61 
       
    62 const u32_t TLS_PEAP_V2_TK_OFFSET = 32ul;
       
    63 const u32_t TLS_PEAP_V2_TK_LENGTH = 32ul;
       
    64 
       
    65 const u32_t TLS_PEAP_V2_COMPOUND_MAC_KEY_LENGTH = 20ul;
       
    66 
       
    67 const u32_t TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH = 128ul;
       
    68 
       
    69 //-----------------------------------------------------------------------------------------
       
    70 
       
    71 /// This is pseudo Ethernet and EAPOL header.
       
    72 /// This is used in trace of tunneled EAP-packet.
       
    73 const u8_t EAP_PSEUDO_ETHERNET_HEADER[] =
       
    74 {
       
    75 	0x50, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x68, 0x65,
       
    76 	0x61, 0x64, 0x65, 0x72, 0x88, 0x8e, 0x01, 0x00,
       
    77 	0x00, 0x00
       
    78 };
       
    79 
       
    80 const u32_t EAP_PSEUDO_EAPOL_HEADER_OFFSET = 14ul;
       
    81 
       
    82 //--------------------------------------------------
       
    83 
       
    84 EAP_FUNC_EXPORT tls_application_eap_core_c::~tls_application_eap_core_c()
       
    85 {
       
    86 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    87 
       
    88 	EAP_TRACE_DEBUG(
       
    89 		m_am_tools,
       
    90 		TRACE_FLAGS_DEFAULT,
       
    91 		(EAPL("%s: function: tls_application_eap_core_c::~tls_application_eap_core_c(): ")
       
    92 		 EAPL("this = 0x%08x, m_eap_core")
       
    93 		 EAPL(" = 0x%08x (validity %d).\n"),
       
    94 		 (m_is_client == true ? "client": "server"),
       
    95 		 this,
       
    96 		 m_eap_core,
       
    97 		 ((m_eap_core != 0) ? m_eap_core->get_is_valid(): true)));
       
    98 
       
    99 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::~tls_application_eap_core_c()");
       
   100 
       
   101 	EAP_ASSERT(m_shutdown_was_called == true);
       
   102 
       
   103 	if (m_free_eap_core == true)
       
   104 	{
       
   105 		delete m_eap_core;
       
   106 	}
       
   107 	m_eap_core = 0;
       
   108 
       
   109 	m_application_partner = 0;
       
   110 
       
   111 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   112 }
       
   113 
       
   114 //--------------------------------------------------
       
   115 
       
   116 EAP_FUNC_EXPORT tls_application_eap_core_c::tls_application_eap_core_c(
       
   117 	abs_eap_am_tools_c * const tools,
       
   118 	eap_core_c * const eap_core,
       
   119 	const bool free_eap_core,
       
   120 	const bool is_client_when_true,
       
   121 	const eap_type_value_e eap_type,
       
   122 	const eap_am_network_id_c * const receive_network_id)
       
   123 	: m_am_tools(tools)
       
   124 	, m_eap_core(eap_core)
       
   125 	, m_free_eap_core(free_eap_core)
       
   126 	, m_application_partner(0)
       
   127 	, m_receive_network_id(tools)
       
   128 	, m_eap_type(eap_type)
       
   129 	, m_peap_version(peap_version_none)
       
   130 	, m_peap_tunneled_eap_type(eap_type_none)
       
   131 	, m_tunneled_eap_type_authentication_state(eap_state_none)
       
   132 	, m_peapv2_tlv_payloads(tools)
       
   133 	, m_peap_v2_client_nonce(tools)
       
   134 	, m_peap_v2_server_nonce(tools)
       
   135 	, m_peap_v2_IPMKn(tools)
       
   136 	, m_peap_v2_ISKn(tools)
       
   137 	, m_peap_v2_CMK_B1_server(tools)
       
   138 	, m_peap_v2_CMK_B2_client(tools)
       
   139 	, m_peap_v2_CSK(tools, eap_type)
       
   140 	, m_accepted_tunneled_eap_types(tools)
       
   141 	, m_pseudo_ethernet_header(tools)
       
   142 	, m_ttls_received_payloads(tools)
       
   143 	, m_ttls_message_type(eap_ttls_tunneled_message_type_none)
       
   144 	, m_ttls_sent_eap_packet(tools)
       
   145 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
   146 	, m_ttls_user_name(tools)
       
   147 	, m_ttls_implicit_challenge(tools)
       
   148 	, m_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_none)
       
   149 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
   150 	, m_error_probability(0UL)
       
   151 	, m_received_eap_identifier(0u)
       
   152 	, m_enable_random_errors(false)
       
   153 	, m_manipulate_only_tunneled_messages(false)
       
   154 	, m_is_valid(false)
       
   155 	, m_is_client(is_client_when_true)
       
   156 	, m_shutdown_was_called(false)
       
   157 	, m_tls_session_type(tls_session_type_none)
       
   158 	, m_peap_allow_tunneled_session_resumption(true)
       
   159 	, m_use_tppd_tls_peap(true)
       
   160 	, m_use_tppd_peapv1_acknowledge_hack(false)
       
   161 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
   162 	, m_server_use_peapv1_extensions_request(false)
       
   163 	, m_client_send_peapv1_extensions_response(false)
       
   164 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
   165 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
   166 	, m_tunneled_eap_in_ttls(true)
       
   167 	, m_ttls_plain_ms_chap_v2_eap_identifier(0ul)
       
   168 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
   169 	, m_use_eap_expanded_type(false)
       
   170 	, m_wait_plain_eap_success(true)
       
   171 {
       
   172 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   173 
       
   174 	EAP_TRACE_DEBUG(
       
   175 		m_am_tools,
       
   176 		TRACE_FLAGS_DEFAULT,
       
   177 		(EAPL("PEAP: %s: function: tls_application_eap_core_c::tls_application_eap_core_c(): ")
       
   178 		 EAPL("this = 0x%08x\n"),
       
   179 		 (m_is_client == true ? "client": "server"),
       
   180 		 this));
       
   181 
       
   182 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::tls_application_eap_core_c()");
       
   183 
       
   184 	if (m_eap_core == 0
       
   185 		|| m_eap_core->get_is_valid() == false)
       
   186 	{
       
   187 		EAP_TRACE_ERROR(
       
   188 			m_am_tools,
       
   189 			TRACE_FLAGS_TLS_PEAP_ERROR,
       
   190 			(EAPL("ERROR: %s: function: tls_application_eap_core_c() failed, ")
       
   191 			 EAPL("m_eap_core is invalid.\n"),
       
   192 						 (m_is_client == true ? "client": "server")));
       
   193 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   194 		return;
       
   195 	}
       
   196 
       
   197 	m_eap_core->set_partner(this);
       
   198 
       
   199 	eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id);
       
   200 	if (status != eap_status_ok)
       
   201 	{
       
   202 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   203 		return;
       
   204 	}
       
   205 
       
   206 
       
   207 	status = m_pseudo_ethernet_header.set_copy_of_buffer(
       
   208 		EAP_PSEUDO_ETHERNET_HEADER,
       
   209 		sizeof(EAP_PSEUDO_ETHERNET_HEADER));
       
   210 	if (status != eap_status_ok)
       
   211 	{
       
   212 		// Do not care of this error.
       
   213 		// User will check the validity of m_pseudo_ethernet_header.
       
   214 	}
       
   215 
       
   216 	set_is_valid();
       
   217 
       
   218 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   219 }
       
   220 
       
   221 //--------------------------------------------------
       
   222 
       
   223 EAP_FUNC_EXPORT void tls_application_eap_core_c::set_is_valid()
       
   224 {
       
   225 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   226 
       
   227 	m_is_valid = true;
       
   228 
       
   229 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   230 }
       
   231 
       
   232 //--------------------------------------------------
       
   233 
       
   234 EAP_FUNC_EXPORT void tls_application_eap_core_c::set_peap_version(
       
   235 	const peap_version_e peap_version,
       
   236 	const bool use_tppd_tls_peap,
       
   237 	const bool use_tppd_peapv1_acknowledge_hack)
       
   238 {
       
   239 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   240 
       
   241 	EAP_TRACE_DEBUG(
       
   242 		m_am_tools,
       
   243 		TRACE_FLAGS_DEFAULT,
       
   244 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::set_peap_version()\n"),
       
   245 		(m_is_client == true ? "client": "server")));
       
   246 
       
   247 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_peap_version()");
       
   248 
       
   249 	m_peap_version = peap_version;
       
   250 
       
   251 	m_use_tppd_tls_peap = use_tppd_tls_peap;
       
   252 
       
   253 	m_use_tppd_peapv1_acknowledge_hack = use_tppd_peapv1_acknowledge_hack;
       
   254 
       
   255 
       
   256 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   257 }
       
   258 
       
   259 //--------------------------------------------------
       
   260 
       
   261 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::configure()
       
   262 {
       
   263 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   264 
       
   265 	EAP_TRACE_DEBUG(
       
   266 		m_am_tools,
       
   267 		TRACE_FLAGS_DEFAULT,
       
   268 		(EAPL("PEAP: %s: function: tls_application_eap_core_c::configure(): ")
       
   269 		 EAPL("this = 0x%08x\n"),
       
   270 		 (m_is_client == true ? "client": "server"),
       
   271 		 this));
       
   272 
       
   273 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::configure()");
       
   274 
       
   275 	eap_status_e status = eap_status_process_general_error;
       
   276 
       
   277 	//----------------------------------------------------------
       
   278 
       
   279 	{
       
   280 		eap_variable_data_c tunneled_eap_type(m_am_tools);
       
   281 
       
   282 		if (m_is_client == true)
       
   283 		{
       
   284 			status = get_application_partner()->read_configure(
       
   285 				cf_str_PEAP_tunneled_eap_type_hex_data.get_field(),
       
   286 				&tunneled_eap_type);
       
   287 			if (status == eap_status_illegal_configure_type)
       
   288 			{
       
   289 				status = get_application_partner()->read_configure(
       
   290 					cf_str_PEAP_tunneled_eap_type_u32_t.get_field(),
       
   291 					&tunneled_eap_type);
       
   292 			}
       
   293 		}
       
   294 #if defined(USE_EAP_CORE_SERVER)
       
   295 		else
       
   296 		{
       
   297 			status = get_application_partner()->read_configure(
       
   298 				cf_str_PEAP_server_tunneled_eap_type_hex_data.get_field(),
       
   299 				&tunneled_eap_type);
       
   300 			if (status == eap_status_illegal_configure_type)
       
   301 			{
       
   302 				status = get_application_partner()->read_configure(
       
   303 					cf_str_PEAP_server_tunneled_eap_type_u32_t.get_field(),
       
   304 					&tunneled_eap_type);
       
   305 			}
       
   306 		}
       
   307 #endif //#if defined(USE_EAP_CORE_SERVER)
       
   308 
       
   309 		if (status != eap_status_ok)
       
   310 		{
       
   311 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   312 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   313 		}
       
   314 		else if (tunneled_eap_type.get_data_length() == sizeof(u32_t)
       
   315 			&& tunneled_eap_type.get_data(sizeof(u32_t)) != 0)
       
   316 		{
       
   317 			u32_t *p_eap_type = reinterpret_cast<u32_t *>(
       
   318 				tunneled_eap_type.get_data(sizeof(u32_t)));
       
   319 			if (p_eap_type != 0)
       
   320 			{
       
   321 				m_peap_tunneled_eap_type = static_cast<eap_type_ietf_values_e>(*p_eap_type);
       
   322 			}
       
   323 			else
       
   324 			{
       
   325 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   326 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
   327 			}
       
   328 		}
       
   329 //#if defined(USE_EAP_EXPANDED_TYPES)
       
   330 		else if (tunneled_eap_type.get_data_length()
       
   331 				 == eap_expanded_type_c::get_eap_expanded_type_size()
       
   332 			&& tunneled_eap_type.get_data(tunneled_eap_type.get_data_length()) != 0)
       
   333 		{
       
   334 			eap_expanded_type_c eap_type(eap_type_none);
       
   335 
       
   336 			status = eap_type.set_expanded_type_data(
       
   337 				m_am_tools,
       
   338 				&tunneled_eap_type);
       
   339 			if (status != eap_status_ok)
       
   340 			{
       
   341 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   342 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   343 			}
       
   344 
       
   345 			status = eap_type.get_type_data(
       
   346 				m_am_tools,
       
   347 				&m_peap_tunneled_eap_type);
       
   348 			if (status != eap_status_ok)
       
   349 			{
       
   350 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   351 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   352 			}
       
   353 		}
       
   354 //#endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
   355 		else
       
   356 		{
       
   357 			EAP_TRACE_DEBUG(
       
   358 				m_am_tools, 
       
   359 				TRACE_FLAGS_DEFAULT, 
       
   360 				(EAPL("ERROR: %s: No tunneled EAP-type configured, %s.\n"),
       
   361 				 (m_is_client == true ? "client": "server"),
       
   362 				 cf_str_EAP_default_type_hex_data.get_field()->get_field()));
       
   363 			
       
   364 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   365 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
   366 		}
       
   367 
       
   368 
       
   369 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
   370 		if (
       
   371 #if defined(USE_EAP_EXPANDED_TYPES)
       
   372 			m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type()
       
   373 #else
       
   374 			m_peap_tunneled_eap_type == eap_type_plain_mschapv2
       
   375 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
   376 			)
       
   377 		{
       
   378 			// This is special case.
       
   379 			// We must tell to inner EAP-stack to use EAP-MsChapv2.
       
   380 			m_tunneled_eap_in_ttls = false;
       
   381 		}
       
   382 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
   383 
       
   384 	}
       
   385 
       
   386 	//----------------------------------------------------------
       
   387 
       
   388 	{
       
   389 		eap_variable_data_c allowed_eap_types(m_am_tools);
       
   390 
       
   391 		const eap_configuration_field_c * field
       
   392 			= cf_str_PEAP_accepted_tunneled_client_types_hex_data.get_field();
       
   393 		if (m_is_client == false)
       
   394 		{
       
   395 			field = cf_str_PEAP_accepted_tunneled_server_types_hex_data.get_field();
       
   396 		}
       
   397 
       
   398 		eap_status_e status = read_configure(
       
   399 			field,
       
   400 			&allowed_eap_types);
       
   401 		if (status == eap_status_ok
       
   402 			&& allowed_eap_types.get_is_valid_data() == true)
       
   403 		{
       
   404 			// OK read.
       
   405 			u32_t type_count = allowed_eap_types.get_data_length()
       
   406 				/eap_expanded_type_c::get_eap_expanded_type_size();
       
   407 			
       
   408 			EAP_TRACE_DEBUG(
       
   409 				m_am_tools, 
       
   410 				TRACE_FLAGS_DEFAULT, 
       
   411 				(EAPL("%s: tls_application_eap_core_c::configure(): Tunneled EAP-type count %d, hex data.\n"),
       
   412 				 (m_is_client == true ? "client": "server"),
       
   413 				 type_count));
       
   414 
       
   415 			for (u32_t ind = 0ul; ind < type_count; ind++)
       
   416 			{
       
   417 				eap_type_value_e * const eap_type = new eap_type_value_e(eap_type_none);
       
   418 				if (eap_type == 0)
       
   419 				{
       
   420 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   421 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   422 				}
       
   423 
       
   424 				status = eap_expanded_type_c::read_type(
       
   425 					m_am_tools,
       
   426 					ind,
       
   427 					allowed_eap_types.get_data(allowed_eap_types.get_data_length()),
       
   428 					allowed_eap_types.get_data_length(),
       
   429 					eap_type);
       
   430 				if (status != eap_status_ok)
       
   431 				{
       
   432 					delete eap_type;
       
   433 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   434 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   435 				}
       
   436 
       
   437 				EAP_TRACE_DEBUG(
       
   438 					m_am_tools, 
       
   439 					TRACE_FLAGS_DEFAULT, 
       
   440 					(EAPL("%s: tls_application_eap_core_c::configure(): allowed EAP-type %d.\n"),
       
   441 					 (m_is_client == true ? "client": "server"),
       
   442 					 convert_eap_type_to_u32_t(*eap_type)));
       
   443 
       
   444 				status = m_accepted_tunneled_eap_types.add_object(eap_type, true);
       
   445 				if (status != eap_status_ok)
       
   446 				{
       
   447 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   448 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   449 				}
       
   450 			} // for()
       
   451 		}
       
   452 		else
       
   453 		{
       
   454 			// Try different configuration type.
       
   455 
       
   456 			const eap_configuration_field_c * field
       
   457 				= cf_str_PEAP_accepted_tunneled_client_types_u32array.get_field();
       
   458 			if (m_is_client == false)
       
   459 			{
       
   460 				field = cf_str_PEAP_accepted_tunneled_server_types_u32array.get_field();
       
   461 			}
       
   462 
       
   463 			status = read_configure(
       
   464 				field,
       
   465 				&allowed_eap_types);
       
   466 			if (status == eap_status_ok
       
   467 				&& allowed_eap_types.get_is_valid_data() == true)
       
   468 			{
       
   469 				// OK read.
       
   470 				u32_t type_count = allowed_eap_types.get_data_length()
       
   471 					/ sizeof(u32_t);
       
   472 
       
   473 				u32_t * const array = reinterpret_cast<u32_t *>(
       
   474 					allowed_eap_types.get_data(type_count*sizeof(u32_t)));
       
   475 				
       
   476 				EAP_TRACE_DEBUG(
       
   477 					m_am_tools, 
       
   478 					TRACE_FLAGS_DEFAULT, 
       
   479 					(EAPL("%s: tls_application_eap_core_c::configure(): Tunneled EAP-type count %d, u32array.\n"),
       
   480 					 (m_is_client == true ? "client": "server"),
       
   481 					 type_count));
       
   482 
       
   483 				for (u32_t ind = 0ul; ind < type_count; ind++)
       
   484 				{
       
   485 					eap_type_value_e * const eap_type = new eap_type_value_e(eap_type_none);
       
   486 					if (eap_type == 0)
       
   487 					{
       
   488 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   489 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   490 					}
       
   491 
       
   492 					*eap_type = static_cast<eap_type_ietf_values_e>(array[ind]);
       
   493 
       
   494 					EAP_TRACE_DEBUG(
       
   495 						m_am_tools, 
       
   496 						TRACE_FLAGS_DEFAULT, 
       
   497 						(EAPL("%s: tls_application_eap_core_c::configure(): allowed EAP-type %d.\n"),
       
   498 						 (m_is_client == true ? "client": "server"),
       
   499 						 convert_eap_type_to_u32_t(*eap_type)));
       
   500 
       
   501 					status = m_accepted_tunneled_eap_types.add_object(eap_type, true);
       
   502 					if (status != eap_status_ok)
       
   503 					{
       
   504 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   505 						return EAP_STATUS_RETURN(m_am_tools, status);
       
   506 					}
       
   507 				} // for()
       
   508 			}
       
   509 		}
       
   510 	}
       
   511 
       
   512 	//----------------------------------------------------------
       
   513 
       
   514 	{
       
   515 		// Client and server configuration.
       
   516 		eap_variable_data_c allow_tunneled_session_resumption(m_am_tools);
       
   517 
       
   518 		status = read_configure(
       
   519 			cf_str_PEAP_allow_tunneled_session_resumption.get_field(),
       
   520 			&allow_tunneled_session_resumption);
       
   521 		if (status == eap_status_ok
       
   522 			&& allow_tunneled_session_resumption.get_is_valid_data() == true
       
   523 			&& allow_tunneled_session_resumption.get_data_length() == sizeof(u32_t)
       
   524 			&& allow_tunneled_session_resumption.get_data(sizeof(u32_t)) != 0)
       
   525 		{
       
   526 			// This is optional value.
       
   527 			u32_t *flag = reinterpret_cast<u32_t *>(
       
   528 				allow_tunneled_session_resumption.get_data(sizeof(u32_t)));
       
   529 			if (flag != 0)
       
   530 			{
       
   531 				if (*flag == 0)
       
   532 				{
       
   533 					m_peap_allow_tunneled_session_resumption = false;
       
   534 				}
       
   535 				else
       
   536 				{
       
   537 					m_peap_allow_tunneled_session_resumption = true;
       
   538 				}
       
   539 			}
       
   540 		}
       
   541 
       
   542 		status = eap_status_ok;
       
   543 	}
       
   544 
       
   545 
       
   546 	if (m_is_client == false)
       
   547 	{
       
   548 		{
       
   549 			// Server only configuration.
       
   550 			// This configuration allows different actions to server and client.
       
   551 			eap_variable_data_c allow_tunneled_session_resumption(m_am_tools);
       
   552 
       
   553 			status = read_configure(
       
   554 				cf_str_PEAP_server_allow_tunneled_session_resumption.get_field(),
       
   555 				&allow_tunneled_session_resumption);
       
   556 			if (status == eap_status_ok
       
   557 				&& allow_tunneled_session_resumption.get_is_valid_data() == true
       
   558 				&& allow_tunneled_session_resumption.get_data_length() == sizeof(u32_t)
       
   559 				&& allow_tunneled_session_resumption.get_data(sizeof(u32_t)) != 0)
       
   560 			{
       
   561 				// This is optional value.
       
   562 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   563 					allow_tunneled_session_resumption.get_data(sizeof(u32_t)));
       
   564 				if (flag != 0)
       
   565 				{
       
   566 					if (*flag == 0)
       
   567 					{
       
   568 						m_peap_allow_tunneled_session_resumption = false;
       
   569 					}
       
   570 					else
       
   571 					{
       
   572 						m_peap_allow_tunneled_session_resumption = true;
       
   573 					}
       
   574 				}
       
   575 			}
       
   576 
       
   577 			status = eap_status_ok;
       
   578 		}
       
   579 
       
   580 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
   581 		{
       
   582 			// Server only configuration.
       
   583 			eap_variable_data_c server_use_peapv1_extensions_request(m_am_tools);
       
   584 
       
   585 			status = read_configure(
       
   586 				cf_str_PEAPv1_server_use_extensions_request.get_field(),
       
   587 				&server_use_peapv1_extensions_request);
       
   588 			if (status == eap_status_ok
       
   589 				&& server_use_peapv1_extensions_request.get_is_valid_data() == true
       
   590 				&& server_use_peapv1_extensions_request.get_data_length() == sizeof(u32_t)
       
   591 				&& server_use_peapv1_extensions_request.get_data(sizeof(u32_t)) != 0)
       
   592 			{
       
   593 				// This is optional value.
       
   594 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   595 					server_use_peapv1_extensions_request.get_data(sizeof(u32_t)));
       
   596 				if (flag != 0)
       
   597 				{
       
   598 					if (*flag == 0)
       
   599 					{
       
   600 						m_server_use_peapv1_extensions_request = false;
       
   601 					}
       
   602 					else
       
   603 					{
       
   604 						m_server_use_peapv1_extensions_request = true;
       
   605 					}
       
   606 				}
       
   607 			}
       
   608 
       
   609 			status = eap_status_ok;
       
   610 
       
   611 		}
       
   612 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
   613 
       
   614 	}
       
   615 
       
   616 
       
   617 	//----------------------------------------------------------
       
   618 
       
   619 #if defined(USE_EAP_ERROR_TESTS)
       
   620 
       
   621 	{
       
   622 		eap_variable_data_c EAP_ERROR_TEST_enable_random_errors(m_am_tools);
       
   623 			
       
   624 		status = read_configure(
       
   625 			cf_str_EAP_ERROR_TEST_enable_random_errors.get_field(),
       
   626 			&EAP_ERROR_TEST_enable_random_errors);
       
   627 		if (status == eap_status_ok
       
   628 			&& EAP_ERROR_TEST_enable_random_errors.get_is_valid_data() == true)
       
   629 		{
       
   630 			u32_t *enable_random_errors = reinterpret_cast<u32_t *>(
       
   631 				EAP_ERROR_TEST_enable_random_errors.get_data(sizeof(u32_t)));
       
   632 			if (enable_random_errors != 0
       
   633 				&& *enable_random_errors != 0)
       
   634 			{
       
   635 				m_enable_random_errors = true;
       
   636 			}
       
   637 		}
       
   638 	}
       
   639 	
       
   640 	if (m_enable_random_errors == true)
       
   641 	{
       
   642 		eap_variable_data_c manipulate_only_tunneled_messages(m_am_tools);
       
   643 
       
   644 		eap_status_e status = read_configure(
       
   645 			cf_str_EAP_ERROR_TEST_manipulate_only_tunneled_messages.get_field(),
       
   646 			&manipulate_only_tunneled_messages);
       
   647 		if (status == eap_status_ok
       
   648 			&& manipulate_only_tunneled_messages.get_is_valid_data() == true)
       
   649 		{
       
   650 			// NOTE this is optional.
       
   651 			u32_t * const flag = reinterpret_cast<u32_t *>(
       
   652 				manipulate_only_tunneled_messages.get_data(sizeof(u32_t)));
       
   653 			if (flag != 0
       
   654 				&& *flag != 0)
       
   655 			{
       
   656 				m_manipulate_only_tunneled_messages = true;
       
   657 			}
       
   658 		}
       
   659 	}
       
   660 
       
   661 	{
       
   662 		eap_variable_data_c EAP_ERROR_TEST_error_probability(m_am_tools);
       
   663 
       
   664 		status = read_configure(
       
   665 			cf_str_EAP_ERROR_TEST_error_probability.get_field(),
       
   666 			&EAP_ERROR_TEST_error_probability);
       
   667 		if (status == eap_status_ok
       
   668 			&& EAP_ERROR_TEST_error_probability.get_is_valid_data() == true)
       
   669 		{
       
   670 			u32_t *error_probability = reinterpret_cast<u32_t *>(
       
   671 				EAP_ERROR_TEST_error_probability.get_data(sizeof(u32_t)));
       
   672 			if (error_probability != 0)
       
   673 			{
       
   674 				m_error_probability = *error_probability;
       
   675 			}
       
   676 		}
       
   677 	}
       
   678 
       
   679 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
   680 
       
   681 	//----------------------------------------------------------
       
   682 
       
   683 #if defined(USE_EAP_EXPANDED_TYPES) && 0
       
   684 	{
       
   685 		eap_variable_data_c use_eap_expanded_type(m_am_tools);
       
   686 
       
   687 		eap_status_e status = read_configure(
       
   688 			cf_str_EAP_TLS_PEAP_use_eap_expanded_type.get_field(),
       
   689 			&use_eap_expanded_type);
       
   690 
       
   691 		if (status != eap_status_ok)
       
   692 		{
       
   693 			status = read_configure(
       
   694 				cf_str_EAP_CORE_use_eap_expanded_type.get_field(),
       
   695 				&use_eap_expanded_type);
       
   696 		}
       
   697 
       
   698 		if (status == eap_status_ok
       
   699 			&& use_eap_expanded_type.get_data_length() == sizeof(u32_t)
       
   700 			&& use_eap_expanded_type.get_data() != 0)
       
   701 		{
       
   702 			u32_t *flag = reinterpret_cast<u32_t *>(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length()));
       
   703 
       
   704 			if (flag != 0)
       
   705 			{
       
   706 				if ((*flag) != 0ul)
       
   707 				{
       
   708 					m_use_eap_expanded_type = true;
       
   709 				}
       
   710 				else
       
   711 				{
       
   712 					m_use_eap_expanded_type = false;
       
   713 				}
       
   714 			}
       
   715 		}
       
   716 	}
       
   717 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
   718 
       
   719 	//----------------------------------------------------------
       
   720 
       
   721 	status = m_eap_core->configure();
       
   722 
       
   723 	if (m_peap_tunneled_eap_type == eap_type_ttls_plain_pap)
       
   724 	{
       
   725 		if (m_free_eap_core == true)
       
   726 		{
       
   727 			m_eap_core->ignore_notifications();
       
   728 
       
   729 			(void) m_eap_core->shutdown();
       
   730 
       
   731 			delete m_eap_core;
       
   732 		}
       
   733 		m_eap_core = 0;
       
   734 	}
       
   735 
       
   736 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   737 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   738 }
       
   739 
       
   740 //--------------------------------------------------
       
   741 
       
   742 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::shutdown()
       
   743 {
       
   744 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   745 
       
   746 	EAP_TRACE_DEBUG(
       
   747 		m_am_tools,
       
   748 		TRACE_FLAGS_DEFAULT,
       
   749 		(EAPL("%s: tls_application_eap_core_c::shutdown(), m_shutdown_was_called=%d\n"),
       
   750 		(m_is_client == true) ? "client": "server",
       
   751 		m_shutdown_was_called));
       
   752 
       
   753 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::shutdown()");
       
   754 
       
   755 	if (m_shutdown_was_called == true)
       
   756 	{
       
   757 		// Shutdown function was called already.
       
   758 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   759 	}
       
   760 	m_shutdown_was_called = true;
       
   761 
       
   762 	eap_status_e status(eap_status_ok);
       
   763 
       
   764 	if (m_eap_core != 0)
       
   765 	{
       
   766 		status = m_eap_core->shutdown();
       
   767 	}
       
   768 
       
   769 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   770 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   771 }
       
   772 
       
   773 //--------------------------------------------------
       
   774 
       
   775 EAP_FUNC_EXPORT void tls_application_eap_core_c::trace_tunneled_packet(
       
   776 	eap_const_string prefix,
       
   777 	const eap_header_wr_c * const eap_packet)
       
   778 {
       
   779 	if (eap_packet == 0
       
   780 		|| eap_packet->get_is_valid() == false)
       
   781 	{
       
   782 		EAP_UNREFERENCED_PARAMETER(prefix);
       
   783 		// ERROR: Cannot trace invalid packet.
       
   784 		EAP_TRACE_ALWAYS(
       
   785 			m_am_tools,
       
   786 			TRACE_FLAGS_DEFAULT,
       
   787 			(EAPL("ERROR: %s: %s: Cannot trace invalid packet.\n"),
       
   788 			 prefix,
       
   789 			 (m_is_client == true) ? "client": "server"));
       
   790 		return;
       
   791 	}
       
   792 
       
   793 	if ((m_am_tools->get_trace_mask() & TRACE_FLAGS_DEFAULT)
       
   794 		&& m_pseudo_ethernet_header.get_is_valid_data() == true
       
   795 		&& m_pseudo_ethernet_header.get_data_length() >= sizeof(EAP_PSEUDO_ETHERNET_HEADER))
       
   796 	{
       
   797 		m_pseudo_ethernet_header.set_data_length(sizeof(EAP_PSEUDO_ETHERNET_HEADER));
       
   798 
       
   799 		u32_t eap_packet_length = eap_packet->get_length();
       
   800 		if (eap_packet->get_header_buffer_length() < eap_packet_length)
       
   801 		{
       
   802 			eap_packet_length = eap_packet->get_header_buffer_length();
       
   803 		}
       
   804 
       
   805 		eap_status_e status = m_pseudo_ethernet_header.add_data_to_offset(
       
   806 			sizeof(EAP_PSEUDO_ETHERNET_HEADER),
       
   807 			eap_packet->get_header_buffer(eap_packet_length),
       
   808 			eap_packet_length);
       
   809 
       
   810 		if (status == eap_status_ok)
       
   811 		{
       
   812 			m_pseudo_ethernet_header.set_data_length(
       
   813 				sizeof(EAP_PSEUDO_ETHERNET_HEADER) + eap_packet_length);
       
   814 
       
   815 			// Sets the EAPOL packet data length.
       
   816 			eapol_header_wr_c eapol(
       
   817 				m_am_tools,
       
   818 				m_pseudo_ethernet_header.get_data_offset(
       
   819 					EAP_PSEUDO_EAPOL_HEADER_OFFSET,
       
   820 					m_pseudo_ethernet_header.get_data_length()-EAP_PSEUDO_EAPOL_HEADER_OFFSET),
       
   821 				m_pseudo_ethernet_header.get_data_length()-EAP_PSEUDO_EAPOL_HEADER_OFFSET);
       
   822 
       
   823 			if (eapol.get_is_valid() == true)
       
   824 			{
       
   825 				eapol.set_data_length(static_cast<u16_t>(eap_packet_length));
       
   826 
       
   827 				EAP_TRACE_ALWAYS(
       
   828 					m_am_tools,
       
   829 					TRACE_FLAGS_DEFAULT,
       
   830 					(EAPL("%s: %s: type=0x%08x, eap_length 0x%04x\n"),
       
   831 					 prefix,
       
   832 					 (m_is_client == true) ? "client": "server",
       
   833 					 convert_eap_type_to_u32_t(eap_packet->get_type()),
       
   834 					 eap_packet->get_length())); // NOTE, this will trace the values from the header of the EAP-packet.
       
   835 
       
   836 				EAP_TRACE_DATA_ALWAYS(
       
   837 					m_am_tools,
       
   838 					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
       
   839 					(prefix,
       
   840 					m_pseudo_ethernet_header.get_data(m_pseudo_ethernet_header.get_data_length()),
       
   841 					m_pseudo_ethernet_header.get_data_length()));
       
   842 			}
       
   843 		}
       
   844 	}
       
   845 }
       
   846 
       
   847 //--------------------------------------------------
       
   848 
       
   849 //
       
   850 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::parse_generic_payload(
       
   851 	const tls_peap_tlv_type_e current_payload,
       
   852 	const tls_peap_tlv_header_c * const payload,
       
   853 	peap_tlv_payloads_c * const p_peap_tlv_payloads)
       
   854 {
       
   855 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   856 
       
   857 	EAP_TRACE_DEBUG(
       
   858 		m_am_tools,
       
   859 		TRACE_FLAGS_DEFAULT,
       
   860 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::parse_generic_payload()\n"),
       
   861 		(m_is_client == true ? "client": "server")));
       
   862 
       
   863 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::parse_generic_payload()");
       
   864 
       
   865 	EAP_TLS_PEAP_TRACE_PAYLOAD("Parsing payload", payload, m_is_client);
       
   866 
       
   867 	if (payload->get_data_length() == 0)
       
   868 	{
       
   869 		EAP_TRACE_ERROR(
       
   870 			m_am_tools,
       
   871 			TRACE_FLAGS_TLS_PEAP_ERROR,
       
   872 			(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
   873 			 EAPL("current payload 0x%04x=%s, length is 0x%04x.\n"),
       
   874 			payload, current_payload, payload->get_tlv_type_string(), payload->get_data_length()));
       
   875 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   876 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);		
       
   877 	}
       
   878 
       
   879 
       
   880 	if (current_payload == tls_peap_tlv_type_result)
       
   881 	{
       
   882 		/*  Result TLV:
       
   883 		 *  0                   1                   2                   3   
       
   884 		 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
   885 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   886 		 * |M|R|  TLV Type (AVP Type)      |            Length             |
       
   887 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   888 		 * |            Status             |
       
   889 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   890 		 */
       
   891 		const u32_t PEAP_TLV_STATUS_LENGTH = sizeof(u16_t);
       
   892 
       
   893 		if (payload->get_data_length() != PEAP_TLV_STATUS_LENGTH)
       
   894 		{
       
   895 			EAP_TRACE_ERROR(
       
   896 				m_am_tools,
       
   897 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
   898 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
   899 				 EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
   900 				 payload, current_payload, payload->get_tlv_type_string(),
       
   901 				 payload->get_data_length()));
       
   902 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   903 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
   904 		}
       
   905 
       
   906 		u8_t * buffer
       
   907 			= static_cast<u8_t *>(payload->get_data(PEAP_TLV_STATUS_LENGTH));
       
   908 
       
   909 		if (buffer == 0)
       
   910 		{
       
   911 			EAP_TRACE_ERROR(
       
   912 				m_am_tools, 
       
   913 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
   914 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
   915 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
   916 				 payload,
       
   917 				 current_payload,
       
   918 				 payload->get_tlv_type_string(),
       
   919 				 payload->get_data_length()));
       
   920 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   921 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
   922 		}
       
   923 
       
   924 		// Note here we get a reference to the data bytes of the received packet.
       
   925 		eap_status_e status = p_peap_tlv_payloads->get_result_tlv()->set_copy_of_buffer(
       
   926 			payload);
       
   927 
       
   928 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   929 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   930 	}
       
   931 	else if (current_payload == tls_peap_tlv_type_nak)
       
   932 	{
       
   933 		/*  NAK TLV:
       
   934 		 * 0                   1                   2                   3    
       
   935 		 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1  
       
   936 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   937 		 * |M|R|         TLV Type          |            Length             |
       
   938 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   939 		 * |                          Vendor-Id                            |
       
   940 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   941 		 * |      TLV Type number      | TLVs                              |
       
   942 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   943 		 */
       
   944 		const u32_t PEAP_TLV_NAK_MINIMUM_LENGTH = 6ul*sizeof(u8_t);
       
   945 
       
   946 		if (payload->get_data_length() < PEAP_TLV_NAK_MINIMUM_LENGTH)
       
   947 		{
       
   948 			EAP_TRACE_ERROR(
       
   949 				m_am_tools,
       
   950 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
   951 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
   952 				 EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
   953 				 payload, current_payload, payload->get_tlv_type_string(),
       
   954 				 payload->get_data_length()));
       
   955 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   956 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
   957 		}
       
   958 
       
   959 		u8_t * buffer
       
   960 			= static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
   961 
       
   962 		if (buffer == 0)
       
   963 		{
       
   964 			EAP_TRACE_ERROR(
       
   965 				m_am_tools, 
       
   966 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
   967 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
   968 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
   969 				 payload,
       
   970 				 current_payload,
       
   971 				 payload->get_tlv_type_string(),
       
   972 				 payload->get_data_length()));
       
   973 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   974 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
   975 		}
       
   976 
       
   977 		// Note here we get a reference to the data bytes of the received packet.
       
   978 		eap_status_e status = p_peap_tlv_payloads->get_nak_tlv()->set_copy_of_buffer(
       
   979 			payload);
       
   980 
       
   981 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   982 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   983 	}
       
   984 	else if (current_payload == tls_peap_tlv_type_crypto_binding)
       
   985 	{
       
   986 		/*  Crypto binding TLV:
       
   987 		 * 0                   1                   2                   3    
       
   988 		 * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7  
       
   989 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   990 		 * |M|R|         TLV Type          |            Length             |
       
   991 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   992 		 * | Version       |Received Ver.  |           SubType             |
       
   993 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   994 		 * |                                                               |
       
   995 		 * +                           NONCE                               +
       
   996 		 * |                                                               |
       
   997 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   998 		 * |                                                               |
       
   999 		 * +                          Compound MAC                         +
       
  1000 		 * |                                                               |
       
  1001 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1002 		 */
       
  1003 		const u32_t PEAP_TLV_CRYPTO_BINDING_LENGTH = sizeof(u16_t)+sizeof(u16_t)+32ul+16ul;
       
  1004 
       
  1005 		if (payload->get_data_length() != PEAP_TLV_CRYPTO_BINDING_LENGTH)
       
  1006 		{
       
  1007 			EAP_TRACE_ERROR(
       
  1008 				m_am_tools,
       
  1009 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1010 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
  1011 				 EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
  1012 				 payload, current_payload, payload->get_tlv_type_string(),
       
  1013 				 payload->get_data_length()));
       
  1014 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1015 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1016 		}
       
  1017 
       
  1018 		u8_t * buffer
       
  1019 			= static_cast<u8_t *>(payload->get_data(PEAP_TLV_CRYPTO_BINDING_LENGTH));
       
  1020 
       
  1021 		if (buffer == 0)
       
  1022 		{
       
  1023 			EAP_TRACE_ERROR(
       
  1024 				m_am_tools, 
       
  1025 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  1026 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
  1027 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  1028 				 payload,
       
  1029 				 current_payload,
       
  1030 				 payload->get_tlv_type_string(),
       
  1031 				 payload->get_data_length()));
       
  1032 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1033 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1034 		}
       
  1035 
       
  1036 		// Note here we get a reference to the data bytes of the received packet.
       
  1037 		eap_status_e status = p_peap_tlv_payloads->get_crypto_binding_tlv()->set_copy_of_buffer(
       
  1038 			payload);
       
  1039 
       
  1040 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1041 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1042 	}
       
  1043 	else if (current_payload == tls_peap_tlv_eap_payload)
       
  1044 	{
       
  1045 		/*  EAP-Payload TLV:
       
  1046 		 *  0                   1                   2                   3
       
  1047 		 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  1048 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1049 		 * |M|R|         TLV Type          |            Length             |
       
  1050 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1051 		 * |                          EAP packet...
       
  1052 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1053 		 * |                             TLVs...
       
  1054 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1055 		 */
       
  1056 		const u32_t PEAP_TLV_EAP_PAYLOAD_MINIMUM_LENGTH = 4ul*sizeof(u8_t);
       
  1057 
       
  1058 		if (payload->get_data_length() < PEAP_TLV_EAP_PAYLOAD_MINIMUM_LENGTH)
       
  1059 		{
       
  1060 			EAP_TRACE_ERROR(
       
  1061 				m_am_tools,
       
  1062 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1063 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
  1064 				 EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
  1065 				 payload, current_payload, payload->get_tlv_type_string(),
       
  1066 				 payload->get_data_length()));
       
  1067 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1068 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1069 		}
       
  1070 
       
  1071 		u8_t * buffer
       
  1072 			= static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  1073 
       
  1074 		if (buffer == 0)
       
  1075 		{
       
  1076 			EAP_TRACE_ERROR(
       
  1077 				m_am_tools, 
       
  1078 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  1079 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
  1080 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  1081 				 payload,
       
  1082 				 current_payload,
       
  1083 				 payload->get_tlv_type_string(),
       
  1084 				 payload->get_data_length()));
       
  1085 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1086 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1087 		}
       
  1088 
       
  1089 		// Note here we get a reference to the data bytes of the received packet.
       
  1090 		eap_status_e status = p_peap_tlv_payloads->get_eap_payload_tlv()->set_copy_of_buffer(
       
  1091 			payload);
       
  1092 
       
  1093 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1094 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1095 	}
       
  1096 	else if (current_payload == tls_peap_tlv_type_intermediate_result)
       
  1097 	{
       
  1098 		/*  Intermediate Result TLV:
       
  1099 		 *  0                   1                   2                   3   
       
  1100 		 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
  1101 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1102 		 * |M|R|  TLV Type (AVP Type)      |            Length             |
       
  1103 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1104 		 * |            Status             |        TLVs...
       
  1105 		 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1106 		 */
       
  1107 		const u32_t PEAP_TLV_INTERMEDIATE_RESULTMINIMUM_LENGTH = 2ul*sizeof(u8_t);
       
  1108 
       
  1109 		if (payload->get_data_length() < PEAP_TLV_INTERMEDIATE_RESULTMINIMUM_LENGTH)
       
  1110 		{
       
  1111 			EAP_TRACE_ERROR(
       
  1112 				m_am_tools,
       
  1113 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1114 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
  1115 				 EAPL("current payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
  1116 				 payload, current_payload, payload->get_tlv_type_string(),
       
  1117 				 payload->get_data_length()));
       
  1118 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1119 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1120 		}
       
  1121 
       
  1122 		u8_t * buffer
       
  1123 			= static_cast<u8_t *>(payload->get_data(payload->get_data_length()));
       
  1124 
       
  1125 		if (buffer == 0)
       
  1126 		{
       
  1127 			EAP_TRACE_ERROR(
       
  1128 				m_am_tools, 
       
  1129 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  1130 				(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(0x%08x): ")
       
  1131 				 EAPL("current payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  1132 				 payload,
       
  1133 				 current_payload,
       
  1134 				 payload->get_tlv_type_string(),
       
  1135 				 payload->get_data_length()));
       
  1136 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1137 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1138 		}
       
  1139 
       
  1140 		// Note here we get a reference to the data bytes of the received packet.
       
  1141 		eap_status_e status = p_peap_tlv_payloads->get_intermediate_result_tlv()
       
  1142 			->set_copy_of_buffer(payload);
       
  1143 
       
  1144 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1145 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1146 	}
       
  1147 	else if (payload->get_flag_mandatory_tlv() == false)
       
  1148 	{
       
  1149 		// Silently ignore this optional payload.
       
  1150 		EAP_TRACE_DEBUG(
       
  1151 			m_am_tools, 
       
  1152 			TRACE_FLAGS_DEFAULT, 
       
  1153 			(EAPL("IGNORED: tls_application_eap_core_c::parse_generic_payload(): ")
       
  1154 			 EAPL("Ignored PEAP_TLV-payload %d=0x%04x.\n"),
       
  1155 			current_payload,
       
  1156 			current_payload));
       
  1157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1158 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1159 	}
       
  1160 	else
       
  1161 	{
       
  1162 		/**
       
  1163 		 * @{ Add creation and sending of message with NAK TLV. }
       
  1164 		 */
       
  1165 		EAP_TRACE_ERROR(
       
  1166 			m_am_tools, 
       
  1167 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  1168 			(EAPL("ERROR: tls_application_eap_core_c::parse_generic_payload(): ")
       
  1169 			 EAPL("Unknown PEAP_TLV-payload %d.\n"),
       
  1170 			current_payload));
       
  1171 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1172 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
       
  1173 	}
       
  1174 }
       
  1175 
       
  1176 //--------------------------------------------------
       
  1177 
       
  1178 //
       
  1179 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::parse_peap_tlv_payload(
       
  1180 	u8_t * const buffer,
       
  1181 	u32_t * const buffer_length,
       
  1182 	peap_tlv_payloads_c * const p_peap_tlv_payloads)
       
  1183 {
       
  1184 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1185 
       
  1186 	EAP_TRACE_DEBUG(
       
  1187 		m_am_tools,
       
  1188 		TRACE_FLAGS_DEFAULT,
       
  1189 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::parse_peap_tlv_payload()\n"),
       
  1190 		(m_is_client == true ? "client": "server")));
       
  1191 
       
  1192 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::parse_peap_tlv_payload()");
       
  1193 
       
  1194 	u32_t buffer_offset = 0ul;
       
  1195 
       
  1196 	tls_peap_tlv_header_c payload(
       
  1197 		m_am_tools,
       
  1198 		buffer+buffer_offset,
       
  1199 		*buffer_length); // Const correctness is gone.
       
  1200 
       
  1201 	tls_peap_tlv_type_e current_payload = payload.get_flag_tlv_type();
       
  1202 
       
  1203 	eap_status_e status = eap_status_header_corrupted;
       
  1204 
       
  1205 	if (payload.get_is_valid() == true
       
  1206 		&& current_payload != tls_peap_tlv_type_none)
       
  1207 	{
       
  1208 		status = payload.check_header();
       
  1209 		if (status != eap_status_ok)
       
  1210 		{
       
  1211 			EAP_TRACE_ERROR(
       
  1212 				m_am_tools, 
       
  1213 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  1214 				(EAPL("ERROR: TLV header corrupted.\n")));
       
  1215 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1216 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1217 		}
       
  1218 
       
  1219 		if (*buffer_length < payload.get_header_length()+payload.get_data_length())
       
  1220 		{
       
  1221 			EAP_TRACE_ERROR(
       
  1222 				m_am_tools,
       
  1223 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1224 				(EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(0x%08x): ")
       
  1225 				 EAPL("current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"),
       
  1226 				 payload.get_header_buffer(0ul),
       
  1227 				 current_payload,
       
  1228 				 payload.get_tlv_type_string(),
       
  1229 				 payload.get_data_length(),
       
  1230 				 *buffer_length));
       
  1231 			EAP_TRACE_ERROR(
       
  1232 				m_am_tools,
       
  1233 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1234 				(EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(): ")
       
  1235 				 EAPL("PEAP_TLV-payload header is corrupted.\n")));
       
  1236 			EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
       
  1237 				payload.get_header_buffer(*buffer_length),
       
  1238 				*buffer_length));
       
  1239 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1240 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1241 		}
       
  1242 
       
  1243 		status = parse_generic_payload(current_payload, &payload, p_peap_tlv_payloads);
       
  1244 		if (status != eap_status_ok)
       
  1245 		{
       
  1246 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1247 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1248 		}
       
  1249 
       
  1250 		if (*buffer_length < payload.get_header_length()+payload.get_data_length())
       
  1251 		{
       
  1252 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1253 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  1254 		}
       
  1255 
       
  1256 		buffer_offset += payload.get_header_length()+payload.get_data_length();
       
  1257 		*buffer_length -= payload.get_header_length()+payload.get_data_length();
       
  1258 
       
  1259 		while(*buffer_length >= payload.get_header_length()
       
  1260 			&& payload.get_is_valid() == true)
       
  1261 		{
       
  1262 			// Sets payload point to the next TLV header.
       
  1263 			payload.set_header_buffer(
       
  1264 					buffer+buffer_offset,
       
  1265 					*buffer_length);
       
  1266 			if (payload.get_is_valid() == false)
       
  1267 			{
       
  1268 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1269 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1270 			}
       
  1271 
       
  1272 			current_payload = payload.get_flag_tlv_type();
       
  1273 
       
  1274 			if (*buffer_length < payload.get_header_length()+payload.get_data_length())
       
  1275 			{
       
  1276 				EAP_TRACE_ERROR(
       
  1277 					m_am_tools,
       
  1278 					TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1279 					(EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(0x%08x): ")
       
  1280 					 EAPL("current payload 0x%04x=%s, data length 0x%04x, buffer length 0x%04x.\n"),
       
  1281 					 payload.get_header_buffer(0ul),
       
  1282 					 current_payload,
       
  1283 					 payload.get_tlv_type_string(),
       
  1284 					 payload.get_data_length(),
       
  1285 					 *buffer_length));
       
  1286 				EAP_TRACE_ERROR(
       
  1287 					m_am_tools,
       
  1288 					TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1289 					(EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(): ")
       
  1290 					 EAPL("PEAP_TLV-payload header is corrupted.\n")));
       
  1291 				EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
       
  1292 					payload.get_header_buffer(*buffer_length),
       
  1293 					*buffer_length));
       
  1294 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1295 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1296 			}
       
  1297 
       
  1298 			status = parse_generic_payload(current_payload, &payload, p_peap_tlv_payloads);
       
  1299 			if (status != eap_status_ok)
       
  1300 			{
       
  1301 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1302 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1303 			}
       
  1304 
       
  1305 			if (*buffer_length < payload.get_header_length()+payload.get_data_length())
       
  1306 			{
       
  1307 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1308 				return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  1309 			}
       
  1310 
       
  1311 			buffer_offset += payload.get_header_length()+payload.get_data_length();
       
  1312 			*buffer_length -= payload.get_header_length()+payload.get_data_length();
       
  1313 		}
       
  1314 	}
       
  1315 
       
  1316 	if (*buffer_length != 0u)
       
  1317 	{
       
  1318 		EAP_TRACE_ERROR(
       
  1319 			m_am_tools,
       
  1320 			TRACE_FLAGS_TLS_PEAP_ERROR,
       
  1321 			(EAPL("ERROR: tls_application_eap_core_c::parse_peap_tlv_payload(): ")
       
  1322 			 EAPL("PEAP_TLV-header is corrupted. Buffer length and payload ")
       
  1323 			 EAPL("length does not match. %lu illegal bytes.\n"),
       
  1324 			 *buffer_length));
       
  1325 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1326 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1327 	}
       
  1328 
       
  1329 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1330 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1331 }
       
  1332 
       
  1333 //--------------------------------------------------
       
  1334 
       
  1335 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::start_ttls_tunneled_authentication(
       
  1336 	const eap_am_network_id_c * const /*receive_network_id*/,
       
  1337 	const u8_t received_eap_identifier)
       
  1338 {
       
  1339 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1340 
       
  1341 	EAP_TRACE_DEBUG(
       
  1342 		m_am_tools,
       
  1343 		TRACE_FLAGS_DEFAULT,
       
  1344 		(EAPL("TTLS: %s: tls_application_eap_core_c::start_ttls_tunneled_authentication()\n"),
       
  1345 		(m_is_client == true ? "client": "server")));
       
  1346 
       
  1347 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::start_ttls_tunneled_authentication()");
       
  1348 
       
  1349 	if (m_eap_type != eap_type_ttls)
       
  1350 	{
       
  1351 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1352 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type);
       
  1353 	}
       
  1354 
       
  1355 	eap_status_e status(eap_status_process_general_error);
       
  1356 
       
  1357 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1358 
       
  1359 	if (
       
  1360 #if defined(USE_EAP_EXPANDED_TYPES)
       
  1361 		m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_pap.get_type()
       
  1362 #else
       
  1363 		m_peap_tunneled_eap_type == eap_type_ttls_plain_pap
       
  1364 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
  1365 		)
       
  1366 	{
       
  1367 		// Query PAP username and password.
       
  1368 		status = m_application_partner->query_ttls_pap_username_and_password(0);
       
  1369 		if (status != eap_status_ok)
       
  1370 		{
       
  1371 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1372 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1373 		}
       
  1374 	}
       
  1375 	else
       
  1376 	{
       
  1377 		eap_variable_data_c forwarded_packet_buffer(m_am_tools);
       
  1378 
       
  1379 		status = forwarded_packet_buffer.set_buffer_length(EAP_CORE_PACKET_BUFFER_LENGTH);
       
  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 		forwarded_packet_buffer.set_data_length(
       
  1387 			forwarded_packet_buffer.get_buffer_length());
       
  1388 
       
  1389 		eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  1390 
       
  1391 		forwarded_eap_packet.set_header_buffer(
       
  1392 			forwarded_packet_buffer.get_data(),
       
  1393 			forwarded_packet_buffer.get_buffer_length());
       
  1394 		if (forwarded_eap_packet.get_is_valid() == false)
       
  1395 		{
       
  1396 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1397 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1398 		}
       
  1399 
       
  1400 		u32_t packet_length = eap_header_wr_c::get_header_length() + 1ul;
       
  1401 
       
  1402 		forwarded_eap_packet.reset_header(
       
  1403 			static_cast<u16_t>(packet_length),
       
  1404 			m_use_eap_expanded_type);
       
  1405 		forwarded_eap_packet.set_identifier(received_eap_identifier);
       
  1406 		forwarded_eap_packet.set_code(eap_code_request);
       
  1407 		forwarded_eap_packet.set_length(
       
  1408 			static_cast<u16_t>(packet_length),
       
  1409 			m_use_eap_expanded_type);
       
  1410 		forwarded_eap_packet.set_type(
       
  1411 			eap_type_identity,
       
  1412 			m_use_eap_expanded_type);
       
  1413 
       
  1414 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1415 		if (m_tunneled_eap_in_ttls == false)
       
  1416 		{
       
  1417 			set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_identity_request);
       
  1418 		}
       
  1419 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1420 
       
  1421 		status = packet_forward_to_tunnel(
       
  1422 			&m_receive_network_id,
       
  1423 			&forwarded_eap_packet,
       
  1424 			forwarded_eap_packet.get_length());
       
  1425 
       
  1426 		{
       
  1427 			eap_status_string_c status_string;
       
  1428 			EAP_UNREFERENCED_PARAMETER(status_string);
       
  1429 
       
  1430 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1431 				bool tmp_tunneled_eap_in_ttls(m_tunneled_eap_in_ttls);
       
  1432 #else
       
  1433 				bool tmp_tunneled_eap_in_ttls(false);
       
  1434 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1435 
       
  1436 			EAP_UNREFERENCED_PARAMETER(tmp_tunneled_eap_in_ttls);
       
  1437 			EAP_TRACE_DEBUG(
       
  1438 				m_am_tools,
       
  1439 				TRACE_FLAGS_DEFAULT,
       
  1440 				(EAPL("TTLS: %s: tls_application_eap_core_c::start_ttls_tunneled_authentication() returns status=%d=%s, m_tunneled_eap_in_ttls=%d\n"),
       
  1441 				(m_is_client == true ? "client": "server"),
       
  1442 				status,
       
  1443 				status_string.get_status_string(status),
       
  1444 				tmp_tunneled_eap_in_ttls));
       
  1445 		}
       
  1446 
       
  1447 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1448 		if (m_tunneled_eap_in_ttls == false
       
  1449 			&& status == eap_status_pending_request)
       
  1450 		{
       
  1451 			set_ttls_tunneled_message_state(eap_ttls_tunneled_message_state_process_identity_request_pending);
       
  1452 		}
       
  1453 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1454 		
       
  1455 		if (status != eap_status_ok)
       
  1456 		{
       
  1457 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1458 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1459 		}
       
  1460 
       
  1461 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1462 
       
  1463 		// NOTE, here we process client send packets separately to 
       
  1464 		// reduce stack consumption.
       
  1465 
       
  1466 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1467 		if (m_eap_type == eap_type_ttls
       
  1468 #if defined(USE_EAP_EXPANDED_TYPES)
       
  1469 			&& m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type()
       
  1470 #else
       
  1471 			&& m_peap_tunneled_eap_type == eap_type_plain_mschapv2
       
  1472 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
  1473 			)
       
  1474 		{
       
  1475 			eap_header_wr_c sent_eap_packet(
       
  1476 				m_am_tools,
       
  1477 				m_ttls_sent_eap_packet.get_data(),
       
  1478 				m_ttls_sent_eap_packet.get_data_length());
       
  1479 
       
  1480 			if (m_ttls_sent_eap_packet.get_data_length() > 0ul
       
  1481 				&& sent_eap_packet.get_data_length() > 0ul
       
  1482 				&& sent_eap_packet.get_type() == eap_type_identity
       
  1483 				&& get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_identity_request)
       
  1484 			{
       
  1485 				// Client sent EAP-Response/Identity.
       
  1486 				// This message should include username.
       
  1487 
       
  1488 				status = ttls_tunneled_message_state_process_identity_request(&sent_eap_packet);
       
  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 			else
       
  1496 			{
       
  1497 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1498 				return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  1499 			}
       
  1500 		}
       
  1501 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1502 
       
  1503 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1504 
       
  1505 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1506 		if (m_eap_type == eap_type_ttls
       
  1507 #if defined(USE_EAP_EXPANDED_TYPES)
       
  1508 			&& m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type()
       
  1509 #else
       
  1510 			&& m_peap_tunneled_eap_type == eap_type_plain_mschapv2
       
  1511 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
  1512 			)
       
  1513 		{
       
  1514 			eap_header_wr_c sent_eap_packet(
       
  1515 				m_am_tools,
       
  1516 				m_ttls_sent_eap_packet.get_data(),
       
  1517 				m_ttls_sent_eap_packet.get_data_length());
       
  1518 
       
  1519 			if (m_ttls_sent_eap_packet.get_data_length() > 0ul
       
  1520 				&& sent_eap_packet.get_data_length() > 0ul
       
  1521 				&& sent_eap_packet.get_type() == eap_type_mschapv2
       
  1522 				&& get_ttls_tunneled_message_state() == eap_ttls_tunneled_message_state_process_challenge_request)
       
  1523 			{
       
  1524 				// This message shoud include MS-CHAP-V2 Response.
       
  1525 				status = ttls_tunneled_message_state_process_challenge_request(&sent_eap_packet);
       
  1526 				if (status != eap_status_ok)
       
  1527 				{
       
  1528 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1529 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  1530 				}
       
  1531 			}
       
  1532 			else
       
  1533 			{
       
  1534 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1535 				return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  1536 			}
       
  1537 		}
       
  1538 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1539 	}
       
  1540 
       
  1541 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1542 
       
  1543 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1544 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1545 }
       
  1546 
       
  1547 //--------------------------------------------------
       
  1548 
       
  1549 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_eap_success_failure_in_forward_to_tunnel(
       
  1550 	const eap_am_network_id_c * const /*receive_network_id*/,
       
  1551 	const eap_code_value_e forwarded_eap_code,
       
  1552 	const u8_t received_eap_identifier)
       
  1553 {
       
  1554 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1555 	eap_variable_data_c forwarded_packet_buffer(m_am_tools);
       
  1556 
       
  1557 	EAP_TRACE_DEBUG(
       
  1558 		m_am_tools,
       
  1559 		TRACE_FLAGS_DEFAULT,
       
  1560 		(EAPL("TTLS: %s: tls_application_eap_core_c::create_eap_success_failure_in_forward_to_tunnel()\n"),
       
  1561 		(m_is_client == true ? "client": "server")));
       
  1562 
       
  1563 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_eap_success_failure_in_forward_to_tunnel()");
       
  1564 
       
  1565 	eap_status_e status = forwarded_packet_buffer.set_buffer_length(EAP_CORE_PACKET_BUFFER_LENGTH);
       
  1566 	if (status != eap_status_ok)
       
  1567 	{
       
  1568 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1569 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1570 	}
       
  1571 
       
  1572 	forwarded_packet_buffer.set_data_length(
       
  1573 		forwarded_packet_buffer.get_buffer_length());
       
  1574 
       
  1575 	eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  1576 
       
  1577 	forwarded_eap_packet.set_header_buffer(
       
  1578 		forwarded_packet_buffer.get_data(),
       
  1579 		forwarded_packet_buffer.get_buffer_length());
       
  1580 	if (forwarded_eap_packet.get_is_valid() == false)
       
  1581 	{
       
  1582 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1583 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1584 	}
       
  1585 
       
  1586 	forwarded_eap_packet.reset_header(
       
  1587 		static_cast<u16_t>(eap_header_wr_c::get_header_length()),
       
  1588 		m_use_eap_expanded_type);
       
  1589 	forwarded_eap_packet.set_identifier(received_eap_identifier);
       
  1590 	forwarded_eap_packet.set_code(forwarded_eap_code);
       
  1591 	forwarded_eap_packet.set_length(
       
  1592 		static_cast<u16_t>(eap_header_wr_c::get_header_length()),
       
  1593 		m_use_eap_expanded_type);
       
  1594 
       
  1595 	status = packet_forward_to_tunnel(
       
  1596 		&m_receive_network_id,
       
  1597 		&forwarded_eap_packet,
       
  1598 		forwarded_eap_packet.get_length());
       
  1599 
       
  1600 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1601 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1602 }
       
  1603 
       
  1604 //--------------------------------------------------
       
  1605 
       
  1606 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_ttls_eap_payloads(
       
  1607 	eap_diameter_payloads_c * const payloads,
       
  1608 	eap_ttls_tunneled_message_type_e * const message_type)
       
  1609 {
       
  1610 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1611 
       
  1612 	EAP_TRACE_DEBUG(
       
  1613 		m_am_tools,
       
  1614 		TRACE_FLAGS_DEFAULT,
       
  1615 		(EAPL("TTLS: %s: tls_application_eap_core_c::check_ttls_eap_payloads()\n"),
       
  1616 		(m_is_client == true ? "client": "server")));
       
  1617 
       
  1618 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_ttls_eap_payloads()");
       
  1619 
       
  1620 	*message_type = eap_ttls_tunneled_message_type_none;
       
  1621 
       
  1622 	eap_array_c<eap_diameter_avp_code_c> needed_payloads(m_am_tools);
       
  1623 
       
  1624 	eap_diameter_avp_code_c code_eap_message(eap_diameter_avp_code_eap_message);
       
  1625 
       
  1626 	eap_status_e status = needed_payloads.add_object(&code_eap_message, false);
       
  1627 	if (status != eap_status_ok)
       
  1628 	{
       
  1629 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1630 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1631 	}
       
  1632 		
       
  1633 	// Test the required attribute.
       
  1634 	status = payloads->check_payloads_existense(
       
  1635 		&needed_payloads);
       
  1636 	if (status != eap_status_ok)
       
  1637 	{
       
  1638 		// No required payloads.
       
  1639 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1640 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1641 	}
       
  1642 
       
  1643 	// This packet includes EAP-Message AVP.
       
  1644 
       
  1645 	status = payloads->check_mandatory_payloads(
       
  1646 		&needed_payloads);
       
  1647 	if (status != eap_status_ok)
       
  1648 	{
       
  1649 		// Some mandatory payload is not used here.
       
  1650 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1651 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1652 	}
       
  1653 
       
  1654 	*message_type = eap_ttls_tunneled_message_type_eap;
       
  1655 
       
  1656 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1657 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1658 }
       
  1659 
       
  1660 //--------------------------------------------------
       
  1661 
       
  1662 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_ttls(
       
  1663 	eap_variable_data_c * const received_eap_message,
       
  1664 	const u8_t received_eap_identifier,
       
  1665 	u32_t * const eap_packet_length)
       
  1666 {
       
  1667 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1668 
       
  1669 	EAP_TRACE_DEBUG(
       
  1670 		m_am_tools,
       
  1671 		TRACE_FLAGS_DEFAULT,
       
  1672 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_process_ttls()\n"),
       
  1673 		(m_is_client == true ? "client": "server")));
       
  1674 
       
  1675 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_ttls()");
       
  1676 
       
  1677 	eap_status_e status = eap_status_process_general_error;
       
  1678 
       
  1679 
       
  1680 	u32_t payload_length = received_eap_message->get_data_length();
       
  1681 
       
  1682 	if (payload_length == 0u)
       
  1683 	{
       
  1684 		// No payload in this packet.
       
  1685 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1686 	}
       
  1687 
       
  1688 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1689 
       
  1690 	m_ttls_received_payloads.reset();
       
  1691 
       
  1692 	{
       
  1693 		eap_diameter_avp_header_c received_avp(
       
  1694 			m_am_tools,
       
  1695 			received_eap_message->get_data(received_eap_message->get_data_length()),
       
  1696 			received_eap_message->get_data_length());
       
  1697 		if (received_avp.get_is_valid() == false)
       
  1698 		{
       
  1699 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1700 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1701 		}
       
  1702 		
       
  1703 		status = m_ttls_received_payloads.parse_diameter_payloads(
       
  1704 			&received_avp,
       
  1705 			&payload_length);
       
  1706 	}
       
  1707 
       
  1708 	if (status != eap_status_ok)
       
  1709 	{
       
  1710 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1711 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1712 	}
       
  1713 	else if (payload_length != 0u)
       
  1714 	{
       
  1715 		EAP_TRACE_ERROR(
       
  1716 			m_am_tools,
       
  1717 			TRACE_FLAGS_DIAMETER_ERROR,
       
  1718 			(EAPL("ERROR: eap_radius_payloads_c::parse_radius_packet(): ")
       
  1719 			 EAPL("RADIUS-header is corrupted. Buffer length and payload ")
       
  1720 			 EAPL("length does not match. Illegal byte count %lu\n"),
       
  1721 			 payload_length));
       
  1722 
       
  1723 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1724 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1725 	}
       
  1726 
       
  1727 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1728 
       
  1729 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1730 	m_ttls_message_type = eap_ttls_tunneled_message_type_none;
       
  1731 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1732 
       
  1733 
       
  1734 	if (check_ttls_eap_payloads(&m_ttls_received_payloads, &m_ttls_message_type)
       
  1735 		== eap_status_ok)
       
  1736 	{
       
  1737 		// This packet includes EAP-Message AVP.
       
  1738 
       
  1739 		eap_diameter_variable_data_c * const eap_message_payload
       
  1740 			= m_ttls_received_payloads.get_payload(eap_diameter_avp_code_eap_message);
       
  1741 
       
  1742 		if (eap_message_payload == 0)
       
  1743 		{
       
  1744 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1745 		}
       
  1746 
       
  1747 		eap_variable_data_c * const eap_message
       
  1748 			= eap_message_payload->get_payload_buffer();
       
  1749 
       
  1750 		if (eap_message == 0
       
  1751 			|| eap_message->get_is_valid_data() == false)
       
  1752 		{
       
  1753 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1754 		}
       
  1755 
       
  1756 		if (eap_message->get_data_length() < eap_header_base_c::get_header_length())
       
  1757 		{
       
  1758 			// Not enough payload in this packet.
       
  1759 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1760 		}
       
  1761 
       
  1762 		*eap_packet_length = eap_message->get_data_length();
       
  1763 		
       
  1764 		u8_t * const eap_payload
       
  1765 			= eap_message->get_data(*eap_packet_length);
       
  1766 		if (eap_payload == 0)
       
  1767 		{
       
  1768 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1769 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1770 		}
       
  1771 
       
  1772 		eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  1773 
       
  1774 		// We must forward this EAP-packet to tunneled EAP-type.
       
  1775 		forwarded_eap_packet.set_header_buffer(
       
  1776 			eap_payload,
       
  1777 			*eap_packet_length);
       
  1778 		if (forwarded_eap_packet.get_is_valid() == false)
       
  1779 		{
       
  1780 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1781 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1782 		}
       
  1783 
       
  1784 		status = packet_forward_to_tunnel(
       
  1785 			&m_receive_network_id,
       
  1786 			&forwarded_eap_packet,
       
  1787 			*eap_packet_length);
       
  1788 
       
  1789 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1790 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1791 	}
       
  1792 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1793 	else if (check_ttls_plain_mschapv2_payloads(&m_ttls_received_payloads, &m_ttls_message_type)
       
  1794 		== eap_status_ok)
       
  1795 	{
       
  1796 		status = handle_ttls_plain_mschapv2_payloads(
       
  1797 			&m_ttls_received_payloads,
       
  1798 			m_ttls_message_type,
       
  1799 			received_eap_identifier);
       
  1800 
       
  1801 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1802 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1803 	}
       
  1804 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  1805 
       
  1806 	else if (check_ttls_plain_pap_payloads(&m_ttls_received_payloads, &m_ttls_message_type)
       
  1807 		== eap_status_ok)
       
  1808 	{
       
  1809 		status = handle_ttls_plain_pap_payloads(
       
  1810 			&m_ttls_received_payloads,
       
  1811 			m_ttls_message_type,
       
  1812 			received_eap_identifier);
       
  1813 
       
  1814 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1815 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1816 	}
       
  1817 
       
  1818 	else
       
  1819 	{
       
  1820 		// Not correct AVP-payloads are included.
       
  1821 		EAP_TRACE_ERROR(
       
  1822 			m_am_tools, 
       
  1823 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  1824 			(EAPL("ERROR: tls_application_eap_core_c::packet_process_ttls(): ")
       
  1825 			 EAPL("Not correct AVP-payloads are included in eap_state_variable_e %d.\n"),
       
  1826 			 m_tunneled_eap_type_authentication_state));
       
  1827 
       
  1828 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1829 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1830 	}
       
  1831 }
       
  1832 
       
  1833 //--------------------------------------------------
       
  1834 
       
  1835 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_xp_peap_v0(
       
  1836 	eap_variable_data_c * const packet,
       
  1837 	const u8_t received_eap_identifier,
       
  1838 	u32_t * const eap_packet_length)
       
  1839 {
       
  1840 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1841 
       
  1842 	EAP_TRACE_DEBUG(
       
  1843 		m_am_tools,
       
  1844 		TRACE_FLAGS_DEFAULT,
       
  1845 		(EAPL("TTLS: %s: tls_application_eap_core_c::packet_process_xp_peap_v0()\n"),
       
  1846 		(m_is_client == true ? "client": "server")));
       
  1847 
       
  1848 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_xp_peap_v0()");
       
  1849 
       
  1850 	// XP PEAPv0 does not include EAP-header (code, identifier and length).
       
  1851 	// Here we must create those attributes.
       
  1852 	// Exception to this rule is, EAP-success and EAP-failure are sent in "Extensions Request Packet"
       
  1853 	// or "Extensions Response Packet".
       
  1854 	// The whole EAP-header is included
       
  1855 	// to "Extensions Request Packet" and "Extensions Response Packet".
       
  1856 	// See draft-kamath-pppext-peapv0-00.txt.
       
  1857 	// 
       
  1858 	// EAP-packet without code, identifier and length:
       
  1859 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1860 	// |  EAP-type     |  EAP-data ...                                                                  
       
  1861 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1862 	// EAP-packet with "Extensions Request Packet" or "Extensions Response Packet":
       
  1863 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1864 	// |  EAP-code     |EAP-identifier | EAP-length                    | EAP-type      |  EAP-data ...  
       
  1865 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1866 	// 
       
  1867 	// EAP-code of "Extensions Request Packet" is 1 which is same as EAP-type of EAP-identity.
       
  1868 	// EAP-code of "Extensions Response Packet" is 2 which is same as EAP-type of EAP-notification.
       
  1869 
       
  1870 	eap_status_e status = eap_status_process_general_error;
       
  1871 
       
  1872 	u32_t received_eap_packet_length = packet->get_data_length();
       
  1873 	if (received_eap_packet_length == 0ul)
       
  1874 	{
       
  1875 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1876 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1877 	}
       
  1878 
       
  1879 	
       
  1880 	eap_type_value_e received_eap_type_or_code(eap_type_none);
       
  1881 
       
  1882 	const u8_t * const p_received_eap_type_or_code
       
  1883 		= static_cast<const u8_t *>(packet->get_data(sizeof(u8_t)));
       
  1884 
       
  1885 	if (p_received_eap_type_or_code == 0)
       
  1886 	{
       
  1887 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1888 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1889 	}
       
  1890 	else if (*p_received_eap_type_or_code == eap_type_expanded_type)
       
  1891 	{
       
  1892 		status = eap_expanded_type_c::read_type(
       
  1893 			m_am_tools,
       
  1894 			0ul,
       
  1895 			p_received_eap_type_or_code,
       
  1896 			received_eap_packet_length,
       
  1897 			&received_eap_type_or_code);
       
  1898 		if (status != eap_status_ok)
       
  1899 		{
       
  1900 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1901 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1902 		}
       
  1903 	}
       
  1904 	else
       
  1905 	{
       
  1906 		received_eap_type_or_code = static_cast<eap_type_ietf_values_e>(*p_received_eap_type_or_code);
       
  1907 	}
       
  1908 
       
  1909 	EAP_TRACE_ALWAYS(
       
  1910 		m_am_tools,
       
  1911 		TRACE_FLAGS_DEFAULT,
       
  1912 		(EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 %s, tunneled eap_type_or_code %d, ")
       
  1913 		 EAPL("eap_packet_length %d, m_tunneled_eap_type_authentication_state %d, ")
       
  1914 		 EAPL("m_tls_session_type %d.\n"),
       
  1915 		 (m_is_client == true ? "client": "server"),
       
  1916 		 convert_eap_type_to_u32_t(received_eap_type_or_code),
       
  1917 		 received_eap_packet_length,
       
  1918 		 m_tunneled_eap_type_authentication_state,
       
  1919 		 m_tls_session_type));
       
  1920 
       
  1921 	bool probably_is_extensions_packet = false;
       
  1922 
       
  1923 	const u32_t EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH = sizeof(u16_t);
       
  1924 	const u32_t EAP_PEAP_V0_EXTENSIONS_PACKET_LENGTH
       
  1925 		= eap_header_wr_c::get_header_length()
       
  1926 		+ eap_header_wr_c::get_ietf_type_field_length()
       
  1927 		+ tls_peap_tlv_header_c::get_header_length()
       
  1928 		+ EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH;
       
  1929 
       
  1930 	if (received_eap_packet_length >= EAP_PEAP_V0_EXTENSIONS_PACKET_LENGTH)
       
  1931 	{
       
  1932 		eap_header_wr_c possible_extensions_eap_packet(
       
  1933 			m_am_tools,
       
  1934 			packet->get_data(packet->get_data_length()),
       
  1935 			packet->get_data_length());
       
  1936 
       
  1937 		if (possible_extensions_eap_packet.get_is_valid() == true
       
  1938 			&& possible_extensions_eap_packet.check_header() == eap_status_ok)
       
  1939 		{
       
  1940 			if (m_is_client == true
       
  1941 				&& possible_extensions_eap_packet.get_code() == eap_code_request
       
  1942 				&& possible_extensions_eap_packet.get_type() == eap_type_tlv_extensions)
       
  1943 			{
       
  1944 				// This is "Extensions Request Packet".
       
  1945 				probably_is_extensions_packet = true;
       
  1946 			}
       
  1947 			else if (m_is_client == false
       
  1948 				&& possible_extensions_eap_packet.get_code() == eap_code_response
       
  1949 				&& possible_extensions_eap_packet.get_type() == eap_type_tlv_extensions)
       
  1950 			{
       
  1951 				// This is "Extensions Response Packet".
       
  1952 				probably_is_extensions_packet = true;
       
  1953 			}
       
  1954 		}
       
  1955 	}
       
  1956 
       
  1957 
       
  1958 	eap_code_value_e forwarded_eap_code = eap_code_none;
       
  1959 	eap_variable_data_c forwarded_packet_buffer(m_am_tools);
       
  1960 
       
  1961 	// In the first phase we will check first byte as a EAP-type field.
       
  1962 	if (probably_is_extensions_packet == false
       
  1963 		&& ((m_tunneled_eap_type_authentication_state == eap_state_none
       
  1964 			&& received_eap_type_or_code == eap_type_identity)
       
  1965 		|| (m_tunneled_eap_type_authentication_state == eap_state_identity_request_received
       
  1966 			&& (received_eap_type_or_code != eap_type_none
       
  1967 				&& received_eap_type_or_code != eap_type_identity)
       
  1968 			)))
       
  1969 	{
       
  1970 		EAP_TRACE_ALWAYS(
       
  1971 			m_am_tools, 
       
  1972 			TRACE_FLAGS_DEFAULT, 
       
  1973 			(EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 tunneled eap_type %d, ")
       
  1974 			 EAPL("m_tunneled_eap_type_authentication_state %d.\n"),
       
  1975 			 convert_eap_type_to_u32_t(received_eap_type_or_code),
       
  1976 			 m_tunneled_eap_type_authentication_state));
       
  1977 		
       
  1978 		if (m_tunneled_eap_type_authentication_state == eap_state_none
       
  1979 			&& received_eap_type_or_code == eap_type_identity)
       
  1980 		{
       
  1981 			m_tunneled_eap_type_authentication_state = eap_state_identity_request_received;
       
  1982 		}
       
  1983 
       
  1984 		*eap_packet_length = eap_header_base_c::get_header_length()+packet->get_data_length();
       
  1985 
       
  1986 		status = forwarded_packet_buffer.set_buffer_length(*eap_packet_length);
       
  1987 		if (status != eap_status_ok)
       
  1988 		{
       
  1989 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1990 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1991 		}
       
  1992 		forwarded_packet_buffer.set_data_length(*eap_packet_length);
       
  1993 
       
  1994 		status = forwarded_packet_buffer.add_data_to_offset(
       
  1995 			eap_header_base_c::get_header_length(),
       
  1996 			packet->get_data(packet->get_data_length()),
       
  1997 			packet->get_data_length());
       
  1998 		if (status != eap_status_ok)
       
  1999 		{
       
  2000 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2001 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2002 		}
       
  2003 
       
  2004 		if (m_is_client == true)
       
  2005 		{
       
  2006 			forwarded_eap_code = eap_code_request;
       
  2007 		}
       
  2008 		else
       
  2009 		{
       
  2010 			forwarded_eap_code = eap_code_response;
       
  2011 		}
       
  2012 	}
       
  2013 	else if (probably_is_extensions_packet == true
       
  2014 			  // The first case will allow sessions resumption without tunneled EAP-authentication
       
  2015 			 && ((m_tunneled_eap_type_authentication_state
       
  2016 				  == eap_state_none && m_peap_allow_tunneled_session_resumption == true)
       
  2017 				 || m_tunneled_eap_type_authentication_state == eap_state_identity_request_received
       
  2018 				 || m_tunneled_eap_type_authentication_state
       
  2019 				 == eap_state_authentication_finished_successfully
       
  2020 				 || m_tunneled_eap_type_authentication_state
       
  2021 				 == eap_state_authentication_terminated_unsuccessfully))
       
  2022 	{
       
  2023 		// In the second phase we will check first byte as a EAP-code field
       
  2024 
       
  2025 		EAP_TRACE_ALWAYS(
       
  2026 			m_am_tools, 
       
  2027 			TRACE_FLAGS_DEFAULT, 
       
  2028 			(EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 tunneled eap_code %d, ")
       
  2029 			 EAPL("m_tunneled_eap_type_authentication_state %d.\n"),
       
  2030 			 convert_eap_type_to_u32_t(received_eap_type_or_code),
       
  2031 			 m_tunneled_eap_type_authentication_state));
       
  2032 		
       
  2033 		eap_header_wr_c final_eap_packet(
       
  2034 			m_am_tools,
       
  2035 			packet->get_data(packet->get_data_length()),
       
  2036 			packet->get_data_length());
       
  2037 		if (final_eap_packet.get_is_valid() == false)
       
  2038 		{
       
  2039 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2040 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2041 		}
       
  2042 
       
  2043 		status = final_eap_packet.check_header();
       
  2044 		if (status != eap_status_ok)
       
  2045 		{
       
  2046 			EAP_TRACE_ERROR(
       
  2047 				m_am_tools, 
       
  2048 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2049 				(EAPL("ERROR: EAP-header corrupted.\n")));
       
  2050 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2051 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2052 		}
       
  2053 
       
  2054 		u32_t parsed_eap_data_length = final_eap_packet.get_type_data_length();
       
  2055 
       
  2056 		if (parsed_eap_data_length == 0u)
       
  2057 		{
       
  2058 			// No payload in this packet.
       
  2059 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2060 		}
       
  2061 
       
  2062 		if (final_eap_packet.get_header_length()+parsed_eap_data_length > packet->get_data_length())
       
  2063 		{
       
  2064 			// Corrupted length in EAP-header.
       
  2065 			EAP_TRACE_ERROR(
       
  2066 				m_am_tools, 
       
  2067 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2068 				(EAPL("ERROR: EAP-header corrupted.\n")));
       
  2069 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2070 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2071 		}
       
  2072 
       
  2073 
       
  2074 		if (m_is_client == true)
       
  2075 		{
       
  2076 			trace_tunneled_packet(EAPL("-> TUNNELED packet client"), &final_eap_packet);
       
  2077 		}
       
  2078 		else
       
  2079 		{
       
  2080 			trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &final_eap_packet);
       
  2081 		}
       
  2082 
       
  2083 
       
  2084 		peap_tlv_payloads_c * peap_tlv_payloads = new peap_tlv_payloads_c(m_am_tools);
       
  2085 		eap_automatic_variable_c<peap_tlv_payloads_c> automatic_peap_tlv_payloads(m_am_tools, peap_tlv_payloads);
       
  2086 
       
  2087 		if (peap_tlv_payloads == 0
       
  2088 			|| peap_tlv_payloads->get_is_valid() == false)
       
  2089 		{
       
  2090 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2091 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2092 		}
       
  2093 
       
  2094 		tls_peap_tlv_header_c tlv(
       
  2095 			m_am_tools,
       
  2096 			final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()),
       
  2097 			parsed_eap_data_length);
       
  2098 		if (tlv.get_is_valid() == false)
       
  2099 		{
       
  2100 			EAP_TRACE_ERROR(
       
  2101 				m_am_tools, 
       
  2102 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2103 				(EAPL("ERROR: No peap_tlv_payloads_c.\n")));
       
  2104 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2105 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2106 		}
       
  2107 
       
  2108 		status = tlv.check_header();
       
  2109 		if (status != eap_status_ok)
       
  2110 		{
       
  2111 			EAP_TRACE_ERROR(
       
  2112 				m_am_tools, 
       
  2113 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2114 				(EAPL("ERROR: TLV header corrupted.\n")));
       
  2115 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2116 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2117 		}
       
  2118 
       
  2119 		status = parse_peap_tlv_payload(
       
  2120 			final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()),
       
  2121 			&parsed_eap_data_length,
       
  2122 			peap_tlv_payloads);
       
  2123 
       
  2124 		if (status != eap_status_ok)
       
  2125 		{
       
  2126 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2127 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2128 		}
       
  2129 		else if (parsed_eap_data_length != 0u)
       
  2130 		{
       
  2131 			EAP_TRACE_ERROR(
       
  2132 				m_am_tools,
       
  2133 				TRACE_FLAGS_TLS_PEAP_ERROR,
       
  2134 				(EAPL("ERROR: tls_application_eap_core_c::packet_process_xp_peap_v0(): ")
       
  2135 				 EAPL("PEAP-header is corrupted. Buffer length and payload ")
       
  2136 				 EAPL("length does not match. Illegal byte count %lu\n"),
       
  2137 				 parsed_eap_data_length));
       
  2138 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2139 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2140 		}
       
  2141 
       
  2142 		// Checks the payloads existence.
       
  2143 		if (peap_tlv_payloads->check_payloads(
       
  2144 				peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv
       
  2145 				peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv
       
  2146 				peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // crypto_binding_tlv
       
  2147 				peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv
       
  2148 				peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be  // intermediate_result_tlv
       
  2149 				) == true
       
  2150 			)
       
  2151 		{
       
  2152 			// OK.
       
  2153 
       
  2154 			if (peap_tlv_payloads->get_result_tlv()->get_data_length()
       
  2155 				< EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH)
       
  2156 			{
       
  2157 				EAP_TRACE_ERROR(
       
  2158 					m_am_tools, 
       
  2159 					TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2160 					(EAPL("ERROR: TLV-result payload too short.\n")));
       
  2161 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2162 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2163 			}
       
  2164 
       
  2165 			u8_t * const tlv_status_network_order
       
  2166 				= reinterpret_cast<u8_t *>(
       
  2167 					peap_tlv_payloads->get_result_tlv()->get_data(
       
  2168 						EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH));
       
  2169 			if (tlv_status_network_order == 0)
       
  2170 			{
       
  2171 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2172 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2173 			}
       
  2174 
       
  2175 			EAP_ASSERT(EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH == sizeof(u16_t));
       
  2176 
       
  2177 			u16_t tlv_status_host_order
       
  2178 				= eap_read_u16_t_network_order(
       
  2179 					tlv_status_network_order,
       
  2180 					EAP_PEAP_V0_RESULT_AVP_STATUS_LENGTH);
       
  2181 
       
  2182 			if (tlv_status_host_order == tls_peap_tlv_status_success)
       
  2183 			{
       
  2184 				forwarded_eap_code = eap_code_success;
       
  2185 			}
       
  2186 			else
       
  2187 			{
       
  2188 				// All other EAP-codes are assumed EAP-Failure.
       
  2189 				forwarded_eap_code = eap_code_failure;
       
  2190 			}
       
  2191 
       
  2192 			eap_header_string_c eap_string;
       
  2193 			EAP_UNREFERENCED_PARAMETER(eap_string);
       
  2194 
       
  2195 			EAP_TRACE_ALWAYS(
       
  2196 				m_am_tools, 
       
  2197 				TRACE_FLAGS_DEFAULT, 
       
  2198 				(EAPL("packet_process_xp_peap_v0(): XP-PEAPv0 tunneled %s received.\n"),
       
  2199 				 eap_string.get_eap_code_string(forwarded_eap_code)));
       
  2200 
       
  2201 			// Here we swap the addresses.
       
  2202 			eap_am_network_id_c send_network_id(
       
  2203 				m_am_tools,
       
  2204 				m_receive_network_id.get_destination_id(),
       
  2205 				m_receive_network_id.get_source_id(),
       
  2206 				m_receive_network_id.get_type());
       
  2207 
       
  2208 
       
  2209 			if (m_is_client == true)
       
  2210 			{
       
  2211 				if ((m_tls_session_type == tls_session_type_original_session_resumption
       
  2212 						|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2213 					&& m_tunneled_eap_type_authentication_state == eap_state_none
       
  2214 					&& forwarded_eap_code == eap_code_success)
       
  2215 				{
       
  2216 					// Send tunneled EAP-Success acknowledge.
       
  2217 					eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  2218 						eap_code_success,
       
  2219 						received_eap_identifier);
       
  2220 					if (status != eap_status_ok)
       
  2221 					{
       
  2222 						m_tunneled_eap_type_authentication_state
       
  2223 							= eap_state_authentication_terminated_unsuccessfully;
       
  2224 					}
       
  2225 					else
       
  2226 					{
       
  2227 						// Send state notification to lower layer.
       
  2228 
       
  2229 						eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2230 							m_am_tools,
       
  2231 							&send_network_id,
       
  2232 							m_is_client,
       
  2233 							eap_state_notification_eap,
       
  2234 							eap_protocol_layer_eap,
       
  2235 							m_peap_tunneled_eap_type,
       
  2236 							eap_state_none,
       
  2237 							eap_state_authentication_finished_successfully,
       
  2238 							received_eap_identifier,
       
  2239 							false);
       
  2240 
       
  2241 						eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2242 
       
  2243 						if (notification == 0)
       
  2244 						{
       
  2245 							m_tunneled_eap_type_authentication_state
       
  2246 								= eap_state_authentication_terminated_unsuccessfully;
       
  2247 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2248 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2249 						}
       
  2250 
       
  2251 						get_application_partner()->state_notification(notification);
       
  2252 
       
  2253 						status = eap_status_success;
       
  2254 					}
       
  2255 
       
  2256 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2257 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2258 				}
       
  2259 				else if ((m_tls_session_type == tls_session_type_original_session_resumption
       
  2260 							|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2261 					&& m_tunneled_eap_type_authentication_state == eap_state_none
       
  2262 					&& forwarded_eap_code == eap_code_failure)
       
  2263 				{
       
  2264 					// Send tunneled EAP-Failure acknowledge.
       
  2265 					eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  2266 						eap_code_failure,
       
  2267 						received_eap_identifier);
       
  2268 
       
  2269 					m_tunneled_eap_type_authentication_state
       
  2270 						= eap_state_authentication_terminated_unsuccessfully;
       
  2271 
       
  2272 						// Send state notification to lower layer.
       
  2273 					eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2274 						m_am_tools,
       
  2275 						&send_network_id,
       
  2276 						m_is_client,
       
  2277 						eap_state_notification_eap,
       
  2278 						eap_protocol_layer_eap,
       
  2279 						m_peap_tunneled_eap_type,
       
  2280 						eap_state_none,
       
  2281 						eap_state_authentication_terminated_unsuccessfully,
       
  2282 						received_eap_identifier,
       
  2283 						false);
       
  2284 
       
  2285 					eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2286 
       
  2287 					if (notification == 0)
       
  2288 					{
       
  2289 						m_tunneled_eap_type_authentication_state
       
  2290 							= eap_state_authentication_terminated_unsuccessfully;
       
  2291 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2292 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2293 					}
       
  2294 
       
  2295 					notification->set_authentication_error(eap_status_authentication_failure);
       
  2296 
       
  2297 					get_application_partner()->state_notification(notification);
       
  2298 					
       
  2299 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2300 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2301 				}
       
  2302 				else
       
  2303 				{
       
  2304 					// Client must forward this EAP-packet to tunneled EAP-type.
       
  2305 					*eap_packet_length = eap_header_base_c::get_header_length();
       
  2306 
       
  2307 					status = forwarded_packet_buffer.set_buffer_length(*eap_packet_length);
       
  2308 					if (status != eap_status_ok)
       
  2309 					{
       
  2310 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2311 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2312 					}
       
  2313 					forwarded_packet_buffer.set_data_length(*eap_packet_length);
       
  2314 				}
       
  2315 			}
       
  2316 			else
       
  2317 			{
       
  2318 				status = eap_status_authentication_failure;
       
  2319 
       
  2320 				// This is server.
       
  2321 				// Client sent a acknowledge.
       
  2322 				if (forwarded_eap_code == eap_code_success
       
  2323 					&& (m_tunneled_eap_type_authentication_state
       
  2324 						== eap_state_authentication_finished_successfully
       
  2325 						|| ((m_tls_session_type == tls_session_type_original_session_resumption
       
  2326 								|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2327 							&& m_tunneled_eap_type_authentication_state == eap_state_none)))
       
  2328 				{
       
  2329 					// XP-PEAP Authentication OK.
       
  2330 
       
  2331 					eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2332 						m_am_tools,
       
  2333 						&send_network_id,
       
  2334 						m_is_client,
       
  2335 						eap_state_notification_eap,
       
  2336 						eap_protocol_layer_eap,
       
  2337 						m_peap_tunneled_eap_type,
       
  2338 						eap_state_none,
       
  2339 						eap_state_authentication_finished_successfully,
       
  2340 						received_eap_identifier,
       
  2341 						false);
       
  2342 
       
  2343 					eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2344 
       
  2345 					if (notification == 0)
       
  2346 					{
       
  2347 						m_tunneled_eap_type_authentication_state
       
  2348 							= eap_state_authentication_terminated_unsuccessfully;
       
  2349 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2350 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2351 					}
       
  2352 
       
  2353 					get_application_partner()->state_notification(notification);
       
  2354 
       
  2355 					status = eap_status_success;
       
  2356 				}
       
  2357 				else
       
  2358 				{
       
  2359 					// Authentication failed.
       
  2360 					eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2361 						m_am_tools,
       
  2362 						&send_network_id,
       
  2363 						m_is_client,
       
  2364 						eap_state_notification_eap,
       
  2365 						eap_protocol_layer_eap,
       
  2366 						m_peap_tunneled_eap_type,
       
  2367 						eap_state_none,
       
  2368 						eap_state_authentication_terminated_unsuccessfully,
       
  2369 						received_eap_identifier,
       
  2370 						false);
       
  2371 
       
  2372 					eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2373 
       
  2374 					if (notification == 0)
       
  2375 					{
       
  2376 						m_tunneled_eap_type_authentication_state
       
  2377 							= eap_state_authentication_terminated_unsuccessfully;
       
  2378 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2379 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2380 					}
       
  2381 
       
  2382 					notification->set_authentication_error(eap_status_authentication_failure);
       
  2383 
       
  2384 					get_application_partner()->state_notification(notification);
       
  2385 
       
  2386 					status = eap_status_authentication_failure;
       
  2387 				}
       
  2388 
       
  2389 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2390 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2391 			}
       
  2392 		}
       
  2393 		else
       
  2394 		{
       
  2395 			// Not correct PEAP_TLV-payloads are included.
       
  2396 			EAP_TRACE_ERROR(
       
  2397 				m_am_tools, 
       
  2398 				TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2399 				(EAPL("ERROR: tls_application_eap_core_c::packet_process_xp_peap_v0(): ")
       
  2400 				 EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"),
       
  2401 				 m_tunneled_eap_type_authentication_state));
       
  2402 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2403 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2404 		}
       
  2405 
       
  2406 	}
       
  2407 	else
       
  2408 	{
       
  2409 		status = eap_status_unexpected_message;
       
  2410 
       
  2411 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2412 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2413 	}
       
  2414 
       
  2415 	eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  2416 
       
  2417 	forwarded_eap_packet.set_header_buffer(
       
  2418 		forwarded_packet_buffer.get_data(*eap_packet_length),
       
  2419 		*eap_packet_length);
       
  2420 	if (forwarded_eap_packet.get_is_valid() == false)
       
  2421 	{
       
  2422 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2423 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2424 	}
       
  2425 
       
  2426 	forwarded_eap_packet.reset_header(
       
  2427 		static_cast<u16_t>(*eap_packet_length),
       
  2428 		m_use_eap_expanded_type);
       
  2429 	forwarded_eap_packet.set_identifier(received_eap_identifier);
       
  2430 	forwarded_eap_packet.set_code(forwarded_eap_code);
       
  2431 	forwarded_eap_packet.set_length(
       
  2432 		static_cast<u16_t>(*eap_packet_length),
       
  2433 		m_use_eap_expanded_type);
       
  2434 
       
  2435 	status = packet_forward_to_tunnel(
       
  2436 		&m_receive_network_id,
       
  2437 		&forwarded_eap_packet,
       
  2438 		*eap_packet_length);
       
  2439 
       
  2440 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2441 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2442 }
       
  2443 
       
  2444 //--------------------------------------------------
       
  2445 
       
  2446 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_peap_v1(
       
  2447 	eap_variable_data_c * const received_eap_message,
       
  2448 	const u8_t received_eap_identifier,
       
  2449 	u32_t * const eap_packet_length)
       
  2450 {
       
  2451 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2452 
       
  2453 	EAP_TRACE_DEBUG(
       
  2454 		m_am_tools,
       
  2455 		TRACE_FLAGS_DEFAULT,
       
  2456 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_process_peap_v1()\n"),
       
  2457 		(m_is_client == true ? "client": "server")));
       
  2458 
       
  2459 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_peap_v1()");
       
  2460 
       
  2461 	eap_status_e status = eap_status_process_general_error;
       
  2462 
       
  2463 
       
  2464 	eap_header_wr_c received_eap_header(
       
  2465 		m_am_tools,
       
  2466 		received_eap_message->get_data(received_eap_message->get_data_length()),
       
  2467 		received_eap_message->get_data_length());
       
  2468 	if (received_eap_header.get_is_valid() == false)
       
  2469 	{
       
  2470 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2471 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2472 	}
       
  2473 
       
  2474 	status = received_eap_header.check_header();
       
  2475 	if (status != eap_status_ok)
       
  2476 	{
       
  2477 		EAP_TRACE_ERROR(
       
  2478 			m_am_tools, 
       
  2479 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2480 			(EAPL("ERROR: EAP-header corrupted.\n")));
       
  2481 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2482 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2483 	}
       
  2484 
       
  2485 	u32_t parsed_eap_data_length = received_eap_header.get_type_data_length();
       
  2486 
       
  2487 	if (received_eap_header.get_header_length()+parsed_eap_data_length
       
  2488 		> received_eap_message->get_data_length())
       
  2489 	{
       
  2490 		// Corrupted length in EAP-header.
       
  2491 		EAP_TRACE_ERROR(
       
  2492 			m_am_tools, 
       
  2493 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2494 			(EAPL("ERROR: EAP-header corrupted.\n")));
       
  2495 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2496 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2497 	}
       
  2498 
       
  2499 
       
  2500 	// This is plain EAP-packet.
       
  2501 	*eap_packet_length = received_eap_message->get_data_length();
       
  2502 
       
  2503 	eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  2504 
       
  2505 	forwarded_eap_packet.set_header_buffer(
       
  2506 		received_eap_message->get_data(*eap_packet_length),
       
  2507 		*eap_packet_length);
       
  2508 
       
  2509 	eap_code_value_e received_eap_code = received_eap_header.get_code();
       
  2510 
       
  2511 	// Here we swap the addresses.
       
  2512 	eap_am_network_id_c send_network_id(
       
  2513 		m_am_tools,
       
  2514 		m_receive_network_id.get_destination_id(),
       
  2515 		m_receive_network_id.get_source_id(),
       
  2516 		m_receive_network_id.get_type());
       
  2517 
       
  2518 	if (
       
  2519 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  2520 		m_is_client == false
       
  2521 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  2522 		&& m_server_use_peapv1_extensions_request == false
       
  2523 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  2524 		&&
       
  2525 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  2526 		m_use_tppd_tls_peap == true
       
  2527 		&& (m_tunneled_eap_type_authentication_state
       
  2528 			== eap_state_authentication_finished_successfully
       
  2529 		|| m_tunneled_eap_type_authentication_state
       
  2530 			== eap_state_authentication_terminated_unsuccessfully))
       
  2531 	{
       
  2532 		status = eap_status_authentication_failure;
       
  2533 
       
  2534 		// This is server.
       
  2535 		// Client sent a acknowledge.
       
  2536 		if (m_tunneled_eap_type_authentication_state
       
  2537 			== eap_state_authentication_finished_successfully
       
  2538 			&& forwarded_eap_packet.get_type() == eap_type_peap
       
  2539 			&& forwarded_eap_packet.get_type_data_length() == sizeof(u8_t) // There is only flags and version
       
  2540 			&& forwarded_eap_packet.get_type_data(sizeof(u8_t)) != 0
       
  2541 			&& *(forwarded_eap_packet.get_type_data(sizeof(u8_t))) == peap_version_1)
       
  2542 		{
       
  2543 			// PEAPv1 Authentication OK.
       
  2544 
       
  2545 			eap_state_notification_c notification(
       
  2546 				m_am_tools,
       
  2547 				&send_network_id,
       
  2548 				m_is_client,
       
  2549 				eap_state_notification_eap,
       
  2550 				eap_protocol_layer_eap,
       
  2551 				m_peap_tunneled_eap_type,
       
  2552 				eap_state_none,
       
  2553 				eap_state_authentication_finished_successfully,
       
  2554 				received_eap_identifier,
       
  2555 				false);
       
  2556 			get_application_partner()->state_notification(&notification);
       
  2557 
       
  2558 			status = eap_status_success;
       
  2559 		}
       
  2560 		else
       
  2561 		{
       
  2562 			// PEAPv1 Authentication failed.
       
  2563 			eap_state_notification_c notification(
       
  2564 				m_am_tools,
       
  2565 				&send_network_id,
       
  2566 				m_is_client,
       
  2567 				eap_state_notification_eap,
       
  2568 				eap_protocol_layer_eap,
       
  2569 				m_peap_tunneled_eap_type,
       
  2570 				eap_state_none,
       
  2571 				eap_state_authentication_terminated_unsuccessfully,
       
  2572 				received_eap_identifier,
       
  2573 				false);
       
  2574 
       
  2575 			notification.set_authentication_error(eap_status_authentication_failure);
       
  2576 
       
  2577 			get_application_partner()->state_notification(&notification);
       
  2578 
       
  2579 			status = eap_status_authentication_failure;
       
  2580 		}
       
  2581 
       
  2582 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2583 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2584 	}
       
  2585 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  2586 	else if (m_is_client == true
       
  2587 		&& m_use_tppd_tls_peap == true
       
  2588 		&& (m_tls_session_type == tls_session_type_original_session_resumption
       
  2589 			|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2590 		&& m_tunneled_eap_type_authentication_state == eap_state_none
       
  2591 		&& received_eap_code == eap_code_success)
       
  2592 	{
       
  2593 		// Received tunneled EAP-Success.
       
  2594 		// This will tell client the tunneled
       
  2595 		// EAP-session was also restored.
       
  2596 
       
  2597 		if (m_is_client == true)
       
  2598 		{
       
  2599 			trace_tunneled_packet(EAPL("-> TUNNELED packet client"), &forwarded_eap_packet);
       
  2600 		}
       
  2601 		else
       
  2602 		{
       
  2603 			trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &forwarded_eap_packet);
       
  2604 		}
       
  2605 
       
  2606 		m_tunneled_eap_type_authentication_state = eap_state_authentication_finished_successfully;
       
  2607 
       
  2608 		eap_state_notification_c notification(
       
  2609 			m_am_tools,
       
  2610 			&send_network_id,
       
  2611 			m_is_client,
       
  2612 			eap_state_notification_eap,
       
  2613 			eap_protocol_layer_eap,
       
  2614 			m_peap_tunneled_eap_type,
       
  2615 			eap_state_none,
       
  2616 			eap_state_tppd_peapv1_authentication_finished_successfully_with_tunneled_eap_success,
       
  2617 			received_eap_identifier,
       
  2618 			false);
       
  2619 		get_application_partner()->state_notification(&notification);
       
  2620 
       
  2621 		status = eap_status_success;
       
  2622 	}
       
  2623 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  2624 	else
       
  2625 	{
       
  2626 
       
  2627 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  2628 		if ((m_is_client == true
       
  2629 				&& forwarded_eap_packet.get_code() == eap_code_request
       
  2630 				&& forwarded_eap_packet.get_type() == eap_type_tlv_extensions)
       
  2631 #if defined(USE_EAP_CORE_SERVER)
       
  2632 			|| (m_is_client == false
       
  2633 				&& forwarded_eap_packet.get_code() == eap_code_response
       
  2634 				&& forwarded_eap_packet.get_type() == eap_type_tlv_extensions)
       
  2635 #endif //#if defined(USE_EAP_CORE_SERVER)
       
  2636 			)
       
  2637 		{
       
  2638 			if (m_is_client == true)
       
  2639 			{
       
  2640 				trace_tunneled_packet(EAPL("-> TUNNELED packet client"), &forwarded_eap_packet);
       
  2641 			}
       
  2642 			else
       
  2643 			{
       
  2644 				trace_tunneled_packet(EAPL("-> TUNNELED packet server"), &forwarded_eap_packet);
       
  2645 			}
       
  2646 
       
  2647 
       
  2648 			peap_tlv_payloads_c * peap_tlv_payloads = new peap_tlv_payloads_c(m_am_tools);
       
  2649 			eap_automatic_variable_c<peap_tlv_payloads_c> automatic_peap_tlv_payloads(m_am_tools, peap_tlv_payloads);
       
  2650 
       
  2651 			if (peap_tlv_payloads == 0
       
  2652 				|| peap_tlv_payloads->get_is_valid() == false)
       
  2653 			{
       
  2654 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2655 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2656 			}
       
  2657 
       
  2658 			tls_peap_tlv_header_c tlv(
       
  2659 				m_am_tools,
       
  2660 				forwarded_eap_packet.get_type_data(forwarded_eap_packet.get_type_data_length()),
       
  2661 				parsed_eap_data_length);
       
  2662 			if (tlv.get_is_valid() == false)
       
  2663 			{
       
  2664 				EAP_TRACE_ERROR(
       
  2665 					m_am_tools, 
       
  2666 					TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2667 					(EAPL("ERROR: No peap_tlv_payloads_c.\n")));
       
  2668 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2669 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2670 			}
       
  2671 
       
  2672 			status = tlv.check_header();
       
  2673 			if (status != eap_status_ok)
       
  2674 			{
       
  2675 				EAP_TRACE_ERROR(
       
  2676 					m_am_tools, 
       
  2677 					TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2678 					(EAPL("ERROR: TLV header corrupted.\n")));
       
  2679 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2680 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2681 			}
       
  2682 
       
  2683 			status = parse_peap_tlv_payload(
       
  2684 				forwarded_eap_packet.get_type_data(forwarded_eap_packet.get_type_data_length()),
       
  2685 				&parsed_eap_data_length,
       
  2686 				peap_tlv_payloads);
       
  2687 
       
  2688 			if (status != eap_status_ok)
       
  2689 			{
       
  2690 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2691 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2692 			}
       
  2693 			else if (parsed_eap_data_length != 0u)
       
  2694 			{
       
  2695 				EAP_TRACE_ERROR(
       
  2696 					m_am_tools,
       
  2697 					TRACE_FLAGS_TLS_PEAP_ERROR,
       
  2698 					(EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v1(): ")
       
  2699 					 EAPL("PEAP-header is corrupted. Buffer length and payload ")
       
  2700 					 EAPL("length does not match. Illegal byte count %lu\n"),
       
  2701 					 parsed_eap_data_length));
       
  2702 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2703 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2704 			}
       
  2705 
       
  2706 			// Checks the payloads existence.
       
  2707 			if (peap_tlv_payloads->check_payloads(
       
  2708 					peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv
       
  2709 					peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv
       
  2710 					peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // crypto_binding_tlv
       
  2711 					peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv
       
  2712 					peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be  // intermediate_result_tlv
       
  2713 					) == true
       
  2714 				)
       
  2715 			{
       
  2716 				// OK.
       
  2717 
       
  2718 				const u32_t EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH = sizeof(u16_t);
       
  2719 
       
  2720 				if (peap_tlv_payloads->get_result_tlv()->get_data_length()
       
  2721 					< EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH)
       
  2722 				{
       
  2723 					EAP_TRACE_ERROR(
       
  2724 						m_am_tools, 
       
  2725 						TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  2726 						(EAPL("ERROR: TLV-result payload too short.\n")));
       
  2727 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2728 					return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2729 				}
       
  2730 
       
  2731 				u8_t * const tlv_status_network_order
       
  2732 					= reinterpret_cast<u8_t *>(
       
  2733 						peap_tlv_payloads->get_result_tlv()->get_data(
       
  2734 							EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH));
       
  2735 				if (tlv_status_network_order == 0)
       
  2736 				{
       
  2737 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2738 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2739 				}
       
  2740 
       
  2741 				EAP_ASSERT(EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH == sizeof(u16_t));
       
  2742 
       
  2743 				u16_t tlv_status_host_order
       
  2744 					= eap_read_u16_t_network_order(
       
  2745 						tlv_status_network_order,
       
  2746 						EAP_PEAP_V1_RESULT_AVP_STATUS_LENGTH);
       
  2747 
       
  2748 				eap_code_value_e forwarded_eap_code(eap_code_none);
       
  2749 
       
  2750 				if (tlv_status_host_order == tls_peap_tlv_status_success)
       
  2751 				{
       
  2752 					forwarded_eap_code = eap_code_success;
       
  2753 				}
       
  2754 				else
       
  2755 				{
       
  2756 					// All other EAP-codes are assumed EAP-Failure.
       
  2757 					forwarded_eap_code = eap_code_failure;
       
  2758 				}
       
  2759 
       
  2760 				eap_header_string_c eap_string;
       
  2761 				EAP_UNREFERENCED_PARAMETER(eap_string);
       
  2762 
       
  2763 				EAP_TRACE_ALWAYS(
       
  2764 					m_am_tools, 
       
  2765 					TRACE_FLAGS_DEFAULT, 
       
  2766 					(EAPL("tls_application_eap_core_c::packet_process_peap_v1(): PEAPv1 tunneled %s received.\n"),
       
  2767 					 eap_string.get_eap_code_string(forwarded_eap_code)));
       
  2768 
       
  2769 				// Here we swap the addresses.
       
  2770 				eap_am_network_id_c send_network_id(
       
  2771 					m_am_tools,
       
  2772 					m_receive_network_id.get_destination_id(),
       
  2773 					m_receive_network_id.get_source_id(),
       
  2774 					m_receive_network_id.get_type());
       
  2775 
       
  2776 
       
  2777 				if (m_is_client == true)
       
  2778 				{
       
  2779 					if ((m_tls_session_type == tls_session_type_original_session_resumption
       
  2780 							|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2781 						&& m_tunneled_eap_type_authentication_state == eap_state_none
       
  2782 						&& forwarded_eap_code == eap_code_success)
       
  2783 					{
       
  2784 						// Send tunneled EAP-Success acknowledge.
       
  2785 						status = send_tunneled_acknowledge_xp_peap_v0(
       
  2786 							eap_code_success,
       
  2787 							received_eap_identifier);
       
  2788 						if (status != eap_status_ok)
       
  2789 						{
       
  2790 							m_tunneled_eap_type_authentication_state
       
  2791 								= eap_state_authentication_terminated_unsuccessfully;
       
  2792 						}
       
  2793 						else
       
  2794 						{
       
  2795 							// Send state notification to lower layer.
       
  2796 
       
  2797 							eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2798 								m_am_tools,
       
  2799 								&send_network_id,
       
  2800 								m_is_client,
       
  2801 								eap_state_notification_eap,
       
  2802 								eap_protocol_layer_eap,
       
  2803 								m_peap_tunneled_eap_type,
       
  2804 								eap_state_none,
       
  2805 								eap_state_authentication_finished_successfully,
       
  2806 								received_eap_identifier,
       
  2807 								false);
       
  2808 
       
  2809 							eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2810 
       
  2811 							if (notification == 0)
       
  2812 							{
       
  2813 								m_tunneled_eap_type_authentication_state
       
  2814 									= eap_state_authentication_terminated_unsuccessfully;
       
  2815 								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2816 								return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2817 							}
       
  2818 
       
  2819 							get_application_partner()->state_notification(notification);
       
  2820 
       
  2821 							status = eap_status_success;
       
  2822 						}
       
  2823 
       
  2824 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2825 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2826 					}
       
  2827 					else if ((m_tls_session_type == tls_session_type_original_session_resumption
       
  2828 								|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2829 						&& m_tunneled_eap_type_authentication_state == eap_state_none
       
  2830 						&& forwarded_eap_code == eap_code_failure)
       
  2831 					{
       
  2832 						// Send tunneled EAP-Failure acknowledge.
       
  2833 						eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  2834 							eap_code_failure,
       
  2835 							received_eap_identifier);
       
  2836 
       
  2837 						m_tunneled_eap_type_authentication_state
       
  2838 							= eap_state_authentication_terminated_unsuccessfully;
       
  2839 
       
  2840 							// Send state notification to lower layer.
       
  2841 						eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2842 							m_am_tools,
       
  2843 							&send_network_id,
       
  2844 							m_is_client,
       
  2845 							eap_state_notification_eap,
       
  2846 							eap_protocol_layer_eap,
       
  2847 							m_peap_tunneled_eap_type,
       
  2848 							eap_state_none,
       
  2849 							eap_state_authentication_terminated_unsuccessfully,
       
  2850 							received_eap_identifier,
       
  2851 							false);
       
  2852 
       
  2853 						eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2854 
       
  2855 						if (notification == 0)
       
  2856 						{
       
  2857 							m_tunneled_eap_type_authentication_state
       
  2858 								= eap_state_authentication_terminated_unsuccessfully;
       
  2859 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2860 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2861 						}
       
  2862 
       
  2863 						notification->set_authentication_error(eap_status_authentication_failure);
       
  2864 
       
  2865 						get_application_partner()->state_notification(notification);
       
  2866 						
       
  2867 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2868 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2869 					}
       
  2870 					else
       
  2871 					{
       
  2872 						// Client must forward this EAP-packet to tunneled EAP-type.
       
  2873 
       
  2874 						m_client_send_peapv1_extensions_response = true;
       
  2875 
       
  2876 						eap_variable_data_c forwarded_packet_buffer(m_am_tools);
       
  2877 						if (forwarded_packet_buffer.get_is_valid() == false)
       
  2878 						{
       
  2879 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2880 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2881 						}
       
  2882 
       
  2883 						*eap_packet_length = eap_header_base_c::get_header_length();
       
  2884 
       
  2885 						status = forwarded_packet_buffer.set_buffer_length(*eap_packet_length);
       
  2886 						if (status != eap_status_ok)
       
  2887 						{
       
  2888 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2889 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2890 						}
       
  2891 
       
  2892 						status = forwarded_packet_buffer.set_data_length(*eap_packet_length);
       
  2893 						if (status != eap_status_ok)
       
  2894 						{
       
  2895 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2896 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2897 						}
       
  2898 
       
  2899 						{
       
  2900 							eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  2901 
       
  2902 							forwarded_eap_packet.set_header_buffer(
       
  2903 								forwarded_packet_buffer.get_data(*eap_packet_length),
       
  2904 								*eap_packet_length);
       
  2905 							if (forwarded_eap_packet.get_is_valid() == false)
       
  2906 							{
       
  2907 								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2908 								return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2909 							}
       
  2910 
       
  2911 							forwarded_eap_packet.reset_header(
       
  2912 								static_cast<u16_t>(*eap_packet_length),
       
  2913 								m_use_eap_expanded_type);
       
  2914 							forwarded_eap_packet.set_identifier(received_eap_identifier);
       
  2915 							forwarded_eap_packet.set_code(forwarded_eap_code);
       
  2916 							forwarded_eap_packet.set_length(
       
  2917 								static_cast<u16_t>(*eap_packet_length),
       
  2918 								m_use_eap_expanded_type);
       
  2919 
       
  2920 							// Forward packet to upper layer.
       
  2921 							status = packet_forward_to_tunnel(
       
  2922 								&m_receive_network_id,
       
  2923 								&forwarded_eap_packet,
       
  2924 								*eap_packet_length);
       
  2925 						}
       
  2926 					}
       
  2927 				}
       
  2928 				else
       
  2929 				{
       
  2930 					status = eap_status_authentication_failure;
       
  2931 
       
  2932 					// This is server.
       
  2933 					// Client sent a acknowledge.
       
  2934 					if (forwarded_eap_code == eap_code_success
       
  2935 						&& (m_tunneled_eap_type_authentication_state
       
  2936 							== eap_state_authentication_finished_successfully
       
  2937 							|| ((m_tls_session_type == tls_session_type_original_session_resumption
       
  2938 									|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  2939 								&& m_tunneled_eap_type_authentication_state == eap_state_none)))
       
  2940 					{
       
  2941 						// PEAPv1 Authentication OK.
       
  2942 
       
  2943 						eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2944 							m_am_tools,
       
  2945 							&send_network_id,
       
  2946 							m_is_client,
       
  2947 							eap_state_notification_eap,
       
  2948 							eap_protocol_layer_eap,
       
  2949 							m_peap_tunneled_eap_type,
       
  2950 							eap_state_none,
       
  2951 							eap_state_authentication_finished_successfully_peapv1_extension,
       
  2952 							received_eap_identifier,
       
  2953 							false);
       
  2954 
       
  2955 						eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2956 
       
  2957 						if (notification == 0)
       
  2958 						{
       
  2959 							m_tunneled_eap_type_authentication_state
       
  2960 								= eap_state_authentication_terminated_unsuccessfully;
       
  2961 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2962 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2963 						}
       
  2964 
       
  2965 						get_application_partner()->state_notification(notification);
       
  2966 
       
  2967 						status = eap_status_success;
       
  2968 					}
       
  2969 					else
       
  2970 					{
       
  2971 						// Authentication failed.
       
  2972 						eap_state_notification_c * const notification = new eap_state_notification_c(
       
  2973 							m_am_tools,
       
  2974 							&send_network_id,
       
  2975 							m_is_client,
       
  2976 							eap_state_notification_eap,
       
  2977 							eap_protocol_layer_eap,
       
  2978 							m_peap_tunneled_eap_type,
       
  2979 							eap_state_none,
       
  2980 							eap_state_authentication_terminated_unsuccessfully_peapv1_extension,
       
  2981 							received_eap_identifier,
       
  2982 							false);
       
  2983 
       
  2984 						eap_automatic_variable_c<eap_state_notification_c> automatic_notification(m_am_tools, notification);
       
  2985 
       
  2986 						if (notification == 0)
       
  2987 						{
       
  2988 							m_tunneled_eap_type_authentication_state
       
  2989 								= eap_state_authentication_terminated_unsuccessfully;
       
  2990 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2991 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2992 						}
       
  2993 
       
  2994 						notification->set_authentication_error(eap_status_authentication_failure);
       
  2995 
       
  2996 						get_application_partner()->state_notification(notification);
       
  2997 
       
  2998 						status = eap_status_authentication_failure;
       
  2999 					}
       
  3000 
       
  3001 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3002 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  3003 				}
       
  3004 			}
       
  3005 			else
       
  3006 			{
       
  3007 				// Not correct PEAP_TLV-payloads are included.
       
  3008 				EAP_TRACE_ERROR(
       
  3009 					m_am_tools, 
       
  3010 					TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3011 					(EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v1(): ")
       
  3012 					 EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"),
       
  3013 					 m_tunneled_eap_type_authentication_state));
       
  3014 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3015 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3016 			}
       
  3017 		}
       
  3018 		else
       
  3019 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  3020 		{
       
  3021 			// Forward packet to upper layer.
       
  3022 			status = packet_forward_to_tunnel(
       
  3023 				&m_receive_network_id,
       
  3024 				&forwarded_eap_packet,
       
  3025 				*eap_packet_length);
       
  3026 		}
       
  3027 	}
       
  3028 
       
  3029 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3030 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3031 }
       
  3032 
       
  3033 //--------------------------------------------------
       
  3034 
       
  3035 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::finish_successfull_authentication_peap_v2(
       
  3036 	const u8_t received_eap_identifier)
       
  3037 {
       
  3038 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3039 
       
  3040 	EAP_TRACE_DEBUG(
       
  3041 		m_am_tools,
       
  3042 		TRACE_FLAGS_DEFAULT,
       
  3043 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::finish_successfull_authentication_peap_v2()\n"),
       
  3044 		(m_is_client == true ? "client": "server")));
       
  3045 
       
  3046 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::finish_successfull_authentication_peap_v2()");
       
  3047 
       
  3048 	eap_status_e status = eap_status_process_general_error;
       
  3049 
       
  3050 	if (m_tunneled_eap_type_authentication_state == eap_state_authentication_finished_successfully)
       
  3051 	{
       
  3052 		// PEAPv2 Authentication OK.
       
  3053 
       
  3054 		// Here we swap the addresses.
       
  3055 		eap_am_network_id_c send_network_id(m_am_tools,
       
  3056 			m_receive_network_id.get_destination_id(),
       
  3057 			m_receive_network_id.get_source_id(),
       
  3058 			m_receive_network_id.get_type());
       
  3059 
       
  3060 		status = create_compound_session_key_peap_v2();
       
  3061 		if (status != eap_status_ok)
       
  3062 		{
       
  3063 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3064 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3065 		}
       
  3066 
       
  3067 		status = get_application_partner()->packet_data_crypto_keys(
       
  3068 			&send_network_id,
       
  3069 			&m_peap_v2_CSK
       
  3070 			);
       
  3071 		if (status != eap_status_ok)
       
  3072 		{
       
  3073 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3074 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3075 		}
       
  3076 
       
  3077 		eap_state_notification_c notification(
       
  3078 			m_am_tools,
       
  3079 			&send_network_id,
       
  3080 			m_is_client,
       
  3081 			eap_state_notification_eap,
       
  3082 			eap_protocol_layer_eap,
       
  3083 			m_peap_tunneled_eap_type,
       
  3084 			eap_state_none,
       
  3085 			eap_state_authentication_finished_successfully,
       
  3086 			received_eap_identifier,
       
  3087 			false);
       
  3088 		get_application_partner()->state_notification(&notification);
       
  3089 
       
  3090 		status = eap_status_success;
       
  3091 	}
       
  3092 
       
  3093 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3094 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3095 }
       
  3096 
       
  3097 //--------------------------------------------------
       
  3098 
       
  3099 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::store_nonce_peap_v2(
       
  3100 	const bool is_client_when_true,
       
  3101 	peap_tlv_payloads_c * const peapv2_tlv_payloads)
       
  3102 {
       
  3103 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3104 
       
  3105 	EAP_TRACE_DEBUG(
       
  3106 		m_am_tools,
       
  3107 		TRACE_FLAGS_DEFAULT,
       
  3108 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::store_nonce_peap_v2()\n"),
       
  3109 		(m_is_client == true ? "client": "server")));
       
  3110 
       
  3111 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::store_nonce_peap_v2()");
       
  3112 
       
  3113 	eap_status_e status = eap_status_process_general_error;
       
  3114 
       
  3115 	u8_t * const nonce = reinterpret_cast<u8_t *>(
       
  3116 		peapv2_tlv_payloads->get_crypto_binding_tlv()->get_data_offset(
       
  3117 			TLV_NONCE_OFFSET,
       
  3118 			TLV_NONCE_LENGTH));
       
  3119 	if (nonce == 0)
       
  3120 	{
       
  3121 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3122 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3123 	}
       
  3124 
       
  3125 	if (is_client_when_true == true)
       
  3126 	{
       
  3127 		status = m_peap_v2_server_nonce.set_copy_of_buffer(
       
  3128 			nonce,
       
  3129 			TLV_NONCE_LENGTH);
       
  3130 	}
       
  3131 	else
       
  3132 	{
       
  3133 		status = m_peap_v2_client_nonce.set_copy_of_buffer(
       
  3134 			nonce,
       
  3135 			TLV_NONCE_LENGTH);
       
  3136 	}
       
  3137 
       
  3138 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3139 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3140 }
       
  3141 
       
  3142 //--------------------------------------------------
       
  3143 
       
  3144 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process_peap_v2(
       
  3145 	eap_variable_data_c * const received_eap_message,
       
  3146 	const u8_t received_eap_identifier,
       
  3147 	u32_t * const eap_packet_length)
       
  3148 {
       
  3149 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3150 
       
  3151 	EAP_TRACE_DEBUG(
       
  3152 		m_am_tools,
       
  3153 		TRACE_FLAGS_DEFAULT,
       
  3154 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_process_peap_v2()\n"),
       
  3155 		(m_is_client == true ? "client": "server")));
       
  3156 
       
  3157 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process_peap_v2()");
       
  3158 
       
  3159 	eap_status_e status = eap_status_process_general_error;
       
  3160 	eap_code_value_e forwarded_eap_code = eap_code_none;
       
  3161 
       
  3162 
       
  3163 	eap_header_wr_c received_eap_header(
       
  3164 		m_am_tools,
       
  3165 		received_eap_message->get_data(received_eap_message->get_data_length()),
       
  3166 		received_eap_message->get_data_length());
       
  3167 	if (received_eap_header.get_is_valid() == false)
       
  3168 	{
       
  3169 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3170 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3171 	}
       
  3172 
       
  3173 	status = received_eap_header.check_header();
       
  3174 	if (status != eap_status_ok)
       
  3175 	{
       
  3176 		EAP_TRACE_ERROR(
       
  3177 			m_am_tools, 
       
  3178 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3179 			(EAPL("ERROR: EAP-header corrupted.\n")));
       
  3180 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3181 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3182 	}
       
  3183 
       
  3184 	u32_t parsed_eap_data_length = received_eap_header.get_type_data_length();
       
  3185 
       
  3186 	if (parsed_eap_data_length < sizeof(u8_t))
       
  3187 	{
       
  3188 		// Not enough payload in this packet.
       
  3189 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3190 	}
       
  3191 
       
  3192 	if (received_eap_header.get_header_length()+parsed_eap_data_length
       
  3193 		> received_eap_message->get_data_length())
       
  3194 	{
       
  3195 		// Corrupted length in EAP-header.
       
  3196 		EAP_TRACE_ERROR(
       
  3197 			m_am_tools, 
       
  3198 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3199 			(EAPL("ERROR: EAP-header corrupted.\n")));
       
  3200 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3201 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3202 	}
       
  3203 
       
  3204 	if (received_eap_header.get_type() != eap_type_tlv_extensions)
       
  3205 	{
       
  3206 		// Not enough payload in this packet.
       
  3207 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3208 	}
       
  3209 
       
  3210 
       
  3211 	tls_peap_tlv_header_c tlv(
       
  3212 		m_am_tools,
       
  3213 		received_eap_header.get_type_data(received_eap_header.get_type_data_length()),
       
  3214 		parsed_eap_data_length);
       
  3215 	if (tlv.get_is_valid() == false)
       
  3216 	{
       
  3217 		EAP_TRACE_ERROR(
       
  3218 			m_am_tools, 
       
  3219 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3220 			(EAPL("ERROR: No peap_tlv_payloads_c.\n")));
       
  3221 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3222 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3223 	}
       
  3224 
       
  3225 	status = tlv.check_header();
       
  3226 	if (status != eap_status_ok)
       
  3227 	{
       
  3228 		EAP_TRACE_ERROR(
       
  3229 			m_am_tools, 
       
  3230 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3231 			(EAPL("ERROR: TLV header corrupted.\n")));
       
  3232 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3233 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3234 	}
       
  3235 
       
  3236 	m_peapv2_tlv_payloads.reset();
       
  3237 
       
  3238 	status = parse_peap_tlv_payload(
       
  3239 		received_eap_header.get_type_data(received_eap_header.get_type_data_length()),
       
  3240 		&parsed_eap_data_length,
       
  3241 		&m_peapv2_tlv_payloads);
       
  3242 
       
  3243 	if (status != eap_status_ok)
       
  3244 	{
       
  3245 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3246 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3247 	}
       
  3248 	else if (parsed_eap_data_length != 0u)
       
  3249 	{
       
  3250 		EAP_TRACE_ERROR(
       
  3251 			m_am_tools,
       
  3252 			TRACE_FLAGS_TLS_PEAP_ERROR,
       
  3253 			(EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v2(): ")
       
  3254 			 EAPL("PEAP-header is corrupted. Buffer length and payload ")
       
  3255 			 EAPL("length does not match. Illegal byte count %lu\n"),
       
  3256 			 parsed_eap_data_length));
       
  3257 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3258 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3259 	}
       
  3260 
       
  3261 
       
  3262 	// EAP-Identifier is used later in verify_tunneled_acknowledge_peap_v2().
       
  3263 	m_received_eap_identifier = received_eap_identifier;
       
  3264 
       
  3265 	// Checks the payloads existence.
       
  3266 	if (m_peapv2_tlv_payloads.check_payloads(
       
  3267 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // result_tlv
       
  3268 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv
       
  3269 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // crypto_binding_tlv
       
  3270 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // eap_payload_tlv
       
  3271 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be  // intermediate_result_tlv
       
  3272 			) == true
       
  3273 		)
       
  3274 	{
       
  3275 		// This packet includes EAP-Payload TLV.
       
  3276 
       
  3277 		*eap_packet_length = m_peapv2_tlv_payloads.get_eap_payload_tlv()->get_data_length();
       
  3278 		
       
  3279 		u8_t * const eap_payload
       
  3280 			= reinterpret_cast<u8_t *>(
       
  3281 				m_peapv2_tlv_payloads.get_eap_payload_tlv()->get_data(
       
  3282 					*eap_packet_length));
       
  3283 		if (eap_payload == 0)
       
  3284 		{
       
  3285 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3286 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3287 		}
       
  3288 
       
  3289 		eap_header_wr_c forwarded_eap_packet(m_am_tools, 0, 0ul);
       
  3290 
       
  3291 		// We must forward this EAP-packet to tunneled EAP-type.
       
  3292 		forwarded_eap_packet.set_header_buffer(
       
  3293 			eap_payload,
       
  3294 			*eap_packet_length);
       
  3295 		if (forwarded_eap_packet.get_is_valid() == false)
       
  3296 		{
       
  3297 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3298 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3299 		}
       
  3300 
       
  3301 		status = packet_forward_to_tunnel(
       
  3302 			&m_receive_network_id,
       
  3303 			&forwarded_eap_packet,
       
  3304 			*eap_packet_length);
       
  3305 
       
  3306 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3307 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3308 	}
       
  3309 	else if (m_peapv2_tlv_payloads.check_payloads(
       
  3310 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv
       
  3311 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv
       
  3312 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // crypto_binding_tlv
       
  3313 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv
       
  3314 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be  // intermediate_result_tlv
       
  3315 			) == true
       
  3316 		)
       
  3317 	{
       
  3318 		// This is Protected termination.
       
  3319 
       
  3320 		{
       
  3321 			u8_t * const tlv_status_network_order = reinterpret_cast<u8_t *>(
       
  3322 				m_peapv2_tlv_payloads.get_result_tlv()->get_data(sizeof(u16_t)));
       
  3323 			if (tlv_status_network_order == 0)
       
  3324 			{
       
  3325 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3326 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3327 			}
       
  3328 
       
  3329 			u16_t tlv_status_host_order
       
  3330 				= eap_read_u16_t_network_order(tlv_status_network_order, sizeof(u16_t));
       
  3331 
       
  3332 			if (tlv_status_host_order == tls_peap_tlv_status_success)
       
  3333 			{
       
  3334 				forwarded_eap_code = eap_code_success;
       
  3335 			}
       
  3336 			else
       
  3337 			{
       
  3338 				// All other EAP-codes are assumed EAP-Failure.
       
  3339 				forwarded_eap_code = eap_code_failure;
       
  3340 			}
       
  3341 
       
  3342 			eap_header_string_c eap_string;
       
  3343 			EAP_UNREFERENCED_PARAMETER(eap_string);
       
  3344 
       
  3345 			EAP_TRACE_DEBUG(
       
  3346 				m_am_tools, 
       
  3347 				TRACE_FLAGS_DEFAULT, 
       
  3348 				(EAPL("packet_process_peap_v2(): PEAPv2 tunneled %s received.\n"),
       
  3349 				 eap_string.get_eap_code_string(forwarded_eap_code)));
       
  3350 		}
       
  3351 
       
  3352 
       
  3353 		if (m_is_client == true)
       
  3354 		{
       
  3355 			// Client must forward created EAP-Success or EAP-Failure to tunneled EAP-type.
       
  3356 			// Result TLV, Crypto Binding TLV and Intermediate Result TLV
       
  3357 			// are checked within the state_notification() function
       
  3358 			// by the verify_tunneled_acknowledge_peap_v2() function
       
  3359 			// when eap_state_authentication_finished_successfully or
       
  3360 			// eap_state_authentication_terminated_unsuccessfully indication
       
  3361 			// is received.
       
  3362 
       
  3363 			// Client stores the received server nonce. This is used later in key generation.
       
  3364 			status = store_nonce_peap_v2(m_is_client, &m_peapv2_tlv_payloads);
       
  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 = create_eap_success_failure_in_forward_to_tunnel(
       
  3372 				&m_receive_network_id,
       
  3373 				forwarded_eap_code,
       
  3374 				received_eap_identifier);
       
  3375 
       
  3376 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3377 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3378 		}
       
  3379 		else
       
  3380 		{
       
  3381 			// Server checks the received TLVs immediately.
       
  3382 
       
  3383 			status = store_nonce_peap_v2(m_is_client, &m_peapv2_tlv_payloads);
       
  3384 			if (status != eap_status_ok)
       
  3385 			{
       
  3386 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3387 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3388 			}
       
  3389 
       
  3390 			eap_variable_data_c saved_mac(m_am_tools);
       
  3391 
       
  3392 			{
       
  3393 				u8_t * const mac = reinterpret_cast<u8_t *>(
       
  3394 					m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_data_offset(
       
  3395 						TLV_MAC_OFFSET,
       
  3396 						TLV_MAC_LENGTH));
       
  3397 				if (mac == 0)
       
  3398 				{
       
  3399 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3400 					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3401 				}
       
  3402 
       
  3403 				status = saved_mac.set_copy_of_buffer(
       
  3404 					mac,
       
  3405 					TLV_MAC_LENGTH);
       
  3406 				if (status != eap_status_ok)
       
  3407 				{
       
  3408 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3409 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  3410 				}
       
  3411 
       
  3412 				m_am_tools->memset(mac, 0, TLV_MAC_LENGTH);
       
  3413 			}
       
  3414 
       
  3415 			// Intermediate Combined Key is stored to m_peap_v2_IPMKn.
       
  3416 			// Compound MAC Key is stored to m_peap_v2_CMK_Bn.
       
  3417 			status = create_compound_mac_key_peap_v2(true);
       
  3418 			if (status != eap_status_ok)
       
  3419 			{
       
  3420 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3421 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3422 			}
       
  3423 
       
  3424 			// Client uses server CMK B1 key
       
  3425 			// to check the message server sent.
       
  3426 			eap_variable_data_c * mac_key = &m_peap_v2_CMK_B1_server;
       
  3427 			if (m_is_client == false)
       
  3428 			{
       
  3429 				// Server uses Client CMK B2 key
       
  3430 				// to check the message client sent.
       
  3431 				mac_key = &m_peap_v2_CMK_B2_client;
       
  3432 			}
       
  3433 
       
  3434 			eap_variable_data_c mac_data(m_am_tools);
       
  3435 
       
  3436 			status = create_crypto_binding_compound_mac(
       
  3437 				mac_key,
       
  3438 				m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_original_header(),
       
  3439 				&mac_data);
       
  3440 			if (status != eap_status_ok)
       
  3441 			{
       
  3442 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3443 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3444 			}
       
  3445 
       
  3446 			EAP_TRACE_DATA_DEBUG(
       
  3447 				m_am_tools,
       
  3448 				TRACE_FLAGS_DEFAULT,
       
  3449 				(EAPL("verify TLV MAC"),
       
  3450 				 saved_mac.get_data(saved_mac.get_data_length()),
       
  3451 				 saved_mac.get_data_length()));
       
  3452 
       
  3453 			// Here we check only saved_mac.get_data_length() bytes.
       
  3454 			// HMAC-SHA1 generates more than 128 bits used MAC.
       
  3455 			if (saved_mac.get_data_length() > mac_data.get_data_length()
       
  3456  				|| m_am_tools->memcmp(
       
  3457 					saved_mac.get_data(saved_mac.get_data_length()),
       
  3458 					mac_data.get_data(mac_data.get_data_length()),
       
  3459 					saved_mac.get_data_length()) != 0)
       
  3460 			{
       
  3461 				EAP_TRACE_ERROR(
       
  3462 					m_am_tools,
       
  3463 					TRACE_FLAGS_DEFAULT,
       
  3464 					(EAPL("PEAPv2: ERROR: %s: receive_function: ")
       
  3465 					 EAPL("packet_process_peap_v2(): MAC failed\n"),
       
  3466 					 (m_is_client == true ? "client": "server")));
       
  3467 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3468 				return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  3469 			}
       
  3470 			else
       
  3471 			{
       
  3472 				EAP_TRACE_DEBUG(
       
  3473 					m_am_tools,
       
  3474 					TRACE_FLAGS_DEFAULT,
       
  3475 					(EAPL("PEAPv2: %s: MAC OK\n"),
       
  3476 					 (m_is_client == true ? "client": "server")));
       
  3477 			}
       
  3478 
       
  3479 
       
  3480 			/**
       
  3481 			 * @{ Check Intermediate Result TLV. }
       
  3482 			 */
       
  3483 
       
  3484 			status = eap_status_authentication_failure;
       
  3485 
       
  3486 			// This is server.
       
  3487 			// Client sent an acknowledge.
       
  3488 			if (forwarded_eap_code == eap_code_success
       
  3489 				&& m_tunneled_eap_type_authentication_state
       
  3490 				== eap_state_authentication_finished_successfully)
       
  3491 			{
       
  3492 				// PEAPv2 Authentication OK.
       
  3493 
       
  3494 				status = finish_successfull_authentication_peap_v2(
       
  3495 					received_eap_identifier);
       
  3496 				if (status != eap_status_ok)
       
  3497 				{
       
  3498 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3499 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  3500 				}
       
  3501 			}
       
  3502 			else
       
  3503 			{
       
  3504 				// Authentication failed.
       
  3505 				status = eap_status_authentication_failure;
       
  3506 			}
       
  3507 
       
  3508 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3509 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3510 		}
       
  3511 	}
       
  3512 	else
       
  3513 	{
       
  3514 		// Not correct PEAP_TLV-payloads are included.
       
  3515 		EAP_TRACE_ERROR(
       
  3516 			m_am_tools, 
       
  3517 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3518 			(EAPL("ERROR: tls_application_eap_core_c::packet_process_peap_v2(): ")
       
  3519 			 EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"),
       
  3520 			 m_tunneled_eap_type_authentication_state));
       
  3521 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3522 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3523 	}
       
  3524 }
       
  3525 
       
  3526 //--------------------------------------------------
       
  3527 
       
  3528 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2()
       
  3529 {
       
  3530 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3531 
       
  3532 	EAP_TRACE_DEBUG(
       
  3533 		m_am_tools,
       
  3534 		TRACE_FLAGS_DEFAULT,
       
  3535 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2(): ")
       
  3536 		 EAPL("this = 0x%08x\n"),
       
  3537 		 (m_is_client == true ? "client": "server"),
       
  3538 		 this));
       
  3539 
       
  3540 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2()");
       
  3541 
       
  3542 	eap_status_e status = eap_status_process_general_error;
       
  3543 	eap_code_value_e forwarded_eap_code = eap_code_none;
       
  3544 
       
  3545 
       
  3546 	// Checks the payloads existence.
       
  3547 	if (m_peapv2_tlv_payloads.check_payloads(
       
  3548 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // result_tlv
       
  3549 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // nak_tlv
       
  3550 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be, // crypto_binding_tlv
       
  3551 			peap_tlv_payloads_c::peap_tlv_payload_status_must_not_be, // eap_payload_tlv
       
  3552 			peap_tlv_payloads_c::peap_tlv_payload_status_must_be  // intermediate_result_tlv
       
  3553 			) == true
       
  3554 		)
       
  3555 	{
       
  3556 		// This is Protected termination.
       
  3557 
       
  3558 		{
       
  3559 			u8_t * const tlv_status_network_order = reinterpret_cast<u8_t *>(
       
  3560 				m_peapv2_tlv_payloads.get_result_tlv()->get_data(sizeof(u16_t)));
       
  3561 			if (tlv_status_network_order == 0)
       
  3562 			{
       
  3563 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3564 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3565 			}
       
  3566 
       
  3567 			u16_t tlv_status_host_order
       
  3568 				= eap_read_u16_t_network_order(tlv_status_network_order, sizeof(u16_t));
       
  3569 
       
  3570 			if (tlv_status_host_order == tls_peap_tlv_status_success)
       
  3571 			{
       
  3572 				forwarded_eap_code = eap_code_success;
       
  3573 			}
       
  3574 			else
       
  3575 			{
       
  3576 				// All other EAP-codes are assumed EAP-Failure.
       
  3577 				forwarded_eap_code = eap_code_failure;
       
  3578 			}
       
  3579 		}
       
  3580 
       
  3581 
       
  3582 		// Client and server checks the received TLVs.
       
  3583 
       
  3584 		status = store_nonce_peap_v2(m_is_client, &m_peapv2_tlv_payloads);
       
  3585 		if (status != eap_status_ok)
       
  3586 		{
       
  3587 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3588 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3589 		}
       
  3590 
       
  3591 		eap_variable_data_c saved_mac(m_am_tools);
       
  3592 
       
  3593 		{
       
  3594 			u8_t * const mac = reinterpret_cast<u8_t *>(
       
  3595 				m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_data_offset(
       
  3596 					TLV_MAC_OFFSET,
       
  3597 					TLV_MAC_LENGTH));
       
  3598 			if (mac == 0)
       
  3599 			{
       
  3600 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3601 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3602 			}
       
  3603 
       
  3604 			status = saved_mac.set_copy_of_buffer(
       
  3605 				mac,
       
  3606 				TLV_MAC_LENGTH);
       
  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 			m_am_tools->memset(mac, 0, TLV_MAC_LENGTH);
       
  3614 		}
       
  3615 
       
  3616 		// Client uses server CMK B1 key
       
  3617 		// to check the message server sent.
       
  3618 		eap_variable_data_c * mac_key = &m_peap_v2_CMK_B1_server;
       
  3619 		if (m_is_client == false)
       
  3620 		{
       
  3621 			// Server uses Client CMK B2 key
       
  3622 			// to check the message client sent.
       
  3623 			mac_key = &m_peap_v2_CMK_B2_client;
       
  3624 		}
       
  3625 
       
  3626 		eap_variable_data_c mac_data(m_am_tools);
       
  3627 
       
  3628 		status = create_crypto_binding_compound_mac(
       
  3629 			mac_key,
       
  3630 			m_peapv2_tlv_payloads.get_crypto_binding_tlv()->get_original_header(),
       
  3631 			&mac_data);
       
  3632 		if (status != eap_status_ok)
       
  3633 		{
       
  3634 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3635 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3636 		}
       
  3637 
       
  3638 		EAP_TRACE_DATA_DEBUG(
       
  3639 			m_am_tools,
       
  3640 			TRACE_FLAGS_DEFAULT,
       
  3641 			(EAPL("verify TLV MAC"),
       
  3642 			 saved_mac.get_data(saved_mac.get_data_length()),
       
  3643 			 saved_mac.get_data_length()));
       
  3644 
       
  3645 		// Here we check only saved_mac.get_data_length() bytes.
       
  3646 		// HMAC-SHA1 generates more than 128 bits used MAC.
       
  3647 		if (saved_mac.get_data_length() > mac_data.get_data_length()
       
  3648 			|| m_am_tools->memcmp(
       
  3649 				saved_mac.get_data(saved_mac.get_data_length()),
       
  3650 				mac_data.get_data(mac_data.get_data_length()),
       
  3651 				saved_mac.get_data_length()) != 0)
       
  3652 		{
       
  3653 			EAP_TRACE_ERROR(
       
  3654 				m_am_tools,
       
  3655 				TRACE_FLAGS_DEFAULT,
       
  3656 				(EAPL("PEAPv2: ERROR: %s: receive_function: ")
       
  3657 				 EAPL("packet_process_peap_v2(): MAC failed\n"),
       
  3658 				 (m_is_client == true ? "client": "server")));
       
  3659 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3660 			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  3661 		}
       
  3662 		else
       
  3663 		{
       
  3664 			EAP_TRACE_DEBUG(
       
  3665 				m_am_tools,
       
  3666 				TRACE_FLAGS_DEFAULT,
       
  3667 				(EAPL("PEAPv2: %s: MAC OK\n"),
       
  3668 				 (m_is_client == true ? "client": "server")));
       
  3669 		}
       
  3670 
       
  3671 
       
  3672 		/**
       
  3673 		 * @{ Check Intermediate Result TLV. }
       
  3674 		 */
       
  3675 
       
  3676 		status = eap_status_authentication_failure;
       
  3677 
       
  3678 		// This is server.
       
  3679 		// Client sent a acknowledge.
       
  3680 		if (forwarded_eap_code == eap_code_success
       
  3681 			&& m_tunneled_eap_type_authentication_state
       
  3682 			== eap_state_authentication_finished_successfully)
       
  3683 		{
       
  3684 			// PEAPv2 Authentication OK.
       
  3685 
       
  3686 			if (m_is_client == false)
       
  3687 			{
       
  3688 				status = finish_successfull_authentication_peap_v2(
       
  3689 					m_received_eap_identifier);
       
  3690 				if (status != eap_status_ok)
       
  3691 				{
       
  3692 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3693 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  3694 				}
       
  3695 			}
       
  3696 			else
       
  3697 			{
       
  3698 				// Server does nothing here.
       
  3699 				status = eap_status_success;
       
  3700 			}
       
  3701 
       
  3702 		}
       
  3703 		else
       
  3704 		{
       
  3705 			// Authentication failed.
       
  3706 			status = eap_status_authentication_failure;
       
  3707 		}
       
  3708 
       
  3709 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3710 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3711 	}
       
  3712 	else
       
  3713 	{
       
  3714 		// Not correct PEAP_TLV-payloads are included.
       
  3715 		EAP_TRACE_ERROR(
       
  3716 			m_am_tools, 
       
  3717 			TRACE_FLAGS_TLS_PEAP_ERROR, 
       
  3718 			(EAPL("ERROR: tls_application_eap_core_c::verify_tunneled_acknowledge_peap_v2(): ")
       
  3719 			 EAPL("Not correct PEAP_TLV-payloads are included in eap_state_variable_e %d.\n"),
       
  3720 			 m_tunneled_eap_type_authentication_state));
       
  3721 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3722 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3723 	}
       
  3724 }
       
  3725 
       
  3726 //--------------------------------------------------
       
  3727 
       
  3728 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_forward_to_tunnel(
       
  3729 	const eap_am_network_id_c * const /*receive_network_id*/,
       
  3730 	eap_header_wr_c * const forwarded_eap_packet,
       
  3731 	const u32_t eap_packet_length)
       
  3732 {
       
  3733 	EAP_TRACE_DEBUG(
       
  3734 		m_am_tools,
       
  3735 		TRACE_FLAGS_DEFAULT,
       
  3736 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::packet_forward_to_tunnel(): ")
       
  3737 		 EAPL("this = 0x%08x\n"),
       
  3738 		 (m_is_client == true ? "client": "server"),
       
  3739 		 this));
       
  3740 
       
  3741 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_forward_to_tunnel()");
       
  3742 
       
  3743 	if (m_is_client == true)
       
  3744 	{
       
  3745 		trace_tunneled_packet(EAPL("-> TUNNELED packet client"), forwarded_eap_packet);
       
  3746 	}
       
  3747 	else
       
  3748 	{
       
  3749 		trace_tunneled_packet(EAPL("-> TUNNELED packet server"), forwarded_eap_packet);
       
  3750 	}
       
  3751 
       
  3752 	eap_status_e status(eap_status_drop_packet_quietly);
       
  3753 
       
  3754 	if (m_eap_core != 0)
       
  3755 	{
       
  3756 		status = m_eap_core->packet_process(
       
  3757 			&m_receive_network_id,
       
  3758 			forwarded_eap_packet,
       
  3759 			eap_packet_length);
       
  3760 	}
       
  3761 
       
  3762 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3763 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3764 }
       
  3765 
       
  3766 //--------------------------------------------------
       
  3767 
       
  3768 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_process(
       
  3769 	eap_variable_data_c * const received_eap_message,
       
  3770 	const u8_t received_eap_identifier)
       
  3771 {
       
  3772 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3773 
       
  3774 	u32_t eap_packet_length = 0ul;
       
  3775 
       
  3776 	eap_status_e status = eap_status_process_general_error;
       
  3777 
       
  3778 	EAP_TRACE_DATA_DEBUG(
       
  3779 		m_am_tools,
       
  3780 		TRACE_FLAGS_DEFAULT,
       
  3781 		(EAPL("tls_application_eap_core_c::packet_process(): received tunneled data:"),
       
  3782 		 received_eap_message->get_data(received_eap_message->get_data_length()),
       
  3783 		 received_eap_message->get_data_length()));
       
  3784 
       
  3785 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_process()");
       
  3786 
       
  3787 	// At least EAP-type or EAP-code field is needed.
       
  3788 	if (received_eap_message->get_data_length() < sizeof(u8_t))
       
  3789 	{
       
  3790 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3791 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  3792 	}
       
  3793 
       
  3794 	if (received_eap_message->get_data_length() > received_eap_message->get_buffer_length())
       
  3795 	{
       
  3796 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3797 		return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
       
  3798 	}
       
  3799 
       
  3800 	if (m_eap_type == eap_type_peap)
       
  3801 	{
       
  3802 		if (m_peap_version == peap_version_0_xp)
       
  3803 		{
       
  3804 			status = packet_process_xp_peap_v0(
       
  3805 				received_eap_message,
       
  3806 				received_eap_identifier,
       
  3807 				&eap_packet_length);
       
  3808 			if (status != eap_status_ok)
       
  3809 			{
       
  3810 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3811 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3812 			}
       
  3813 
       
  3814 			if ((m_tls_session_type == tls_session_type_original_session_resumption
       
  3815 					|| m_tls_session_type == tls_session_type_stateless_session_resumption)
       
  3816 				&& m_tunneled_eap_type_authentication_state
       
  3817 				== eap_state_authentication_finished_successfully)
       
  3818 			{
       
  3819 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3820 				return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3821 			}
       
  3822 		}
       
  3823 		else if (m_peap_version == peap_version_1)
       
  3824 		{
       
  3825 			status = packet_process_peap_v1(
       
  3826 				received_eap_message,
       
  3827 				received_eap_identifier,
       
  3828 				&eap_packet_length);
       
  3829 			if (status != eap_status_ok)
       
  3830 			{
       
  3831 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3832 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3833 			}
       
  3834 		}
       
  3835 		else if (m_peap_version == peap_version_2)
       
  3836 		{
       
  3837 			status = packet_process_peap_v2(
       
  3838 				received_eap_message,
       
  3839 				received_eap_identifier,
       
  3840 				&eap_packet_length);
       
  3841 			if (status != eap_status_ok)
       
  3842 			{
       
  3843 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3844 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3845 			}
       
  3846 		}
       
  3847 		else
       
  3848 		{
       
  3849 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3850 			return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  3851 		}
       
  3852 	}
       
  3853 	else if (m_eap_type == eap_type_ttls)
       
  3854 	{
       
  3855 		status = packet_process_ttls(
       
  3856 			received_eap_message,
       
  3857 			received_eap_identifier,
       
  3858 			&eap_packet_length);
       
  3859 		if (status != eap_status_ok)
       
  3860 		{
       
  3861 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3862 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3863 		}
       
  3864 	}
       
  3865 	else
       
  3866 	{
       
  3867 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3868 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  3869 	}
       
  3870 
       
  3871 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3872 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3873 }
       
  3874 
       
  3875 //--------------------------------------------------
       
  3876 
       
  3877 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::plain_eap_success_failure_packet_received(
       
  3878 	const eap_am_network_id_c * const receive_network_id,
       
  3879 	const eap_code_value_e received_eap_code,
       
  3880 	const u8_t received_eap_identifier)
       
  3881 {
       
  3882 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3883 
       
  3884 	eap_tls_trace_string_c state_trace;
       
  3885 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  3886 	EAP_TRACE_DEBUG(
       
  3887 		m_am_tools,
       
  3888 		TRACE_FLAGS_DEFAULT,
       
  3889 		(EAPL("TLS: %s: message_function: plain_eap_success_failure_packet_received(): m_wait_plain_eap_success=%d, EAP-Code=%d, m_tls_session_type=%s, m_eap_core=0x%08x\n"),
       
  3890 		(m_is_client == true ? "client": "server"),
       
  3891 		m_wait_plain_eap_success,
       
  3892 		received_eap_code,
       
  3893 		eap_tls_trace_string_c::get_tls_session_type_string(m_tls_session_type),
       
  3894 		m_eap_core));
       
  3895 
       
  3896 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::plain_eap_success_failure_packet_received()");
       
  3897 
       
  3898 	eap_status_e status(eap_status_ok);
       
  3899 
       
  3900 	if (m_eap_core != 0
       
  3901 		&& m_tls_session_type != tls_session_type_original_session_resumption
       
  3902 		&& m_tls_session_type != tls_session_type_stateless_session_resumption)
       
  3903 	{
       
  3904 		status = create_eap_success_failure_in_forward_to_tunnel(
       
  3905 			receive_network_id,
       
  3906 			received_eap_code,
       
  3907 			received_eap_identifier);
       
  3908 		if (status != eap_status_ok
       
  3909 			&& status != eap_status_drop_packet_quietly)
       
  3910 		{
       
  3911 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3912 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3913 		}
       
  3914 	}
       
  3915 
       
  3916 	// This object might wait EAP-Success, too.
       
  3917 	if (m_wait_plain_eap_success == true
       
  3918 		&& received_eap_code == eap_code_success)
       
  3919 	{
       
  3920 		// Here we swap the addresses.
       
  3921 		eap_am_network_id_c send_network_id(
       
  3922 			m_am_tools,
       
  3923 			m_receive_network_id.get_destination_id(),
       
  3924 			m_receive_network_id.get_source_id(),
       
  3925 			m_receive_network_id.get_type());
       
  3926 
       
  3927 		eap_state_notification_c notification(
       
  3928 			m_am_tools,
       
  3929 			&send_network_id,
       
  3930 			m_is_client,
       
  3931 			eap_state_notification_eap,
       
  3932 			eap_protocol_layer_eap,
       
  3933 			m_eap_type,
       
  3934 			eap_state_none,
       
  3935 			eap_state_authentication_finished_successfully,
       
  3936 			m_received_eap_identifier,
       
  3937 			true);
       
  3938 		m_application_partner->state_notification(&notification);
       
  3939 
       
  3940 		status = eap_status_ok;
       
  3941 	}
       
  3942 
       
  3943 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3944 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3945 }
       
  3946 
       
  3947 //--------------------------------------------------
       
  3948 
       
  3949 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::empty_ack_packet_received(
       
  3950 	const eap_am_network_id_c * const /* receive_network_id */,
       
  3951 	const u8_t /* received_eap_identifier */)
       
  3952 {
       
  3953 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3954 
       
  3955 	EAP_TRACE_DEBUG(
       
  3956 		m_am_tools,
       
  3957 		TRACE_FLAGS_DEFAULT,
       
  3958 		(EAPL("TLS: %s: message_function: empty_ack_packet_received()\n"),
       
  3959 		(m_is_client == true ? "client": "server")));
       
  3960 
       
  3961 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::empty_ack_packet_received()");
       
  3962 
       
  3963 	eap_status_e status(eap_status_not_found);
       
  3964 
       
  3965 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  3966 
       
  3967 	if (m_is_client == false
       
  3968 		&& m_tunneled_eap_in_ttls == false
       
  3969 		&& m_eap_type == eap_type_ttls)
       
  3970 	{
       
  3971 		u32_t eap_length
       
  3972 			= EAP_MSCHAPV2_OPCODE_SIZE // OpCode is the only payload
       
  3973 			+ eap_header_base_c::get_type_data_start_offset(m_use_eap_expanded_type);
       
  3974 
       
  3975 		eap_buf_chain_wr_c eap_packet_buffer(
       
  3976 			eap_write_buffer,
       
  3977 			m_am_tools,
       
  3978 			eap_length);
       
  3979 		if (eap_packet_buffer.get_is_valid() == false)
       
  3980 		{
       
  3981 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3982 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3983 		}
       
  3984 
       
  3985 		eap_header_wr_c forwarded_eap_packet(
       
  3986 			m_am_tools,
       
  3987 			eap_packet_buffer.get_data(eap_length),
       
  3988 			eap_length);
       
  3989 
       
  3990 		if (forwarded_eap_packet.get_is_valid() == false)
       
  3991 		{
       
  3992 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3993 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3994 		}
       
  3995 
       
  3996 		forwarded_eap_packet.reset_header(
       
  3997 			static_cast<u16_t>(eap_length),
       
  3998 			m_use_eap_expanded_type);
       
  3999 		forwarded_eap_packet.set_identifier(m_ttls_plain_ms_chap_v2_eap_identifier);
       
  4000 		forwarded_eap_packet.set_code(eap_code_response);
       
  4001 		forwarded_eap_packet.set_length(
       
  4002 			static_cast<u16_t>(eap_length),
       
  4003 			m_use_eap_expanded_type);
       
  4004 		forwarded_eap_packet.set_type(
       
  4005 			eap_type_mschapv2,
       
  4006 			m_use_eap_expanded_type);
       
  4007 
       
  4008 		mschapv2_header_c mschapv2_header(
       
  4009 			m_am_tools,
       
  4010 			forwarded_eap_packet.get_type_data_offset(
       
  4011 				0,
       
  4012 				forwarded_eap_packet.get_type_data_length()),
       
  4013 			forwarded_eap_packet.get_type_data_length());
       
  4014 
       
  4015 		mschapv2_header.set_opcode(mschapv2_opcode_success);
       
  4016 
       
  4017 		status = packet_forward_to_tunnel(
       
  4018 			&m_receive_network_id,
       
  4019 			&forwarded_eap_packet,
       
  4020 			eap_length);
       
  4021 		if (status != eap_status_ok)
       
  4022 		{
       
  4023 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4024 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4025 		}
       
  4026 	}
       
  4027 
       
  4028 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  4029 
       
  4030 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4031 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4032 }
       
  4033 
       
  4034 //--------------------------------------------------
       
  4035 
       
  4036 EAP_FUNC_EXPORT bool tls_application_eap_core_c::get_is_valid()
       
  4037 {
       
  4038 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4039 
       
  4040 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4041 	return m_is_valid;
       
  4042 }
       
  4043 
       
  4044 //--------------------------------------------------
       
  4045 
       
  4046 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::reset()
       
  4047 {
       
  4048 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4049 
       
  4050 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  4051 	EAP_TRACE_DEBUG(
       
  4052 		m_am_tools,
       
  4053 		TRACE_FLAGS_DEFAULT,
       
  4054 		(EAPL("TLS: %s: function: tls_application_eap_core_c::reset(): this = 0x%08x\n"),
       
  4055 		 (m_is_client == true ? "client": "server"),
       
  4056 		 this));
       
  4057 
       
  4058 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::reset()");
       
  4059 
       
  4060 	m_tunneled_eap_type_authentication_state = eap_state_none;
       
  4061 	m_tls_session_type = tls_session_type_none;
       
  4062 	m_use_tppd_tls_peap = false;
       
  4063 	m_use_tppd_peapv1_acknowledge_hack = false;
       
  4064 
       
  4065 	eap_status_e status(eap_status_ok);
       
  4066 
       
  4067 	if (m_eap_core != 0)
       
  4068 	{
       
  4069 		status = m_eap_core->reset();
       
  4070 	}
       
  4071 
       
  4072 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4073 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4074 }
       
  4075 
       
  4076 
       
  4077 //--------------------------------------------------
       
  4078 
       
  4079 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_result_tlv_message(
       
  4080 	eap_buf_chain_wr_c * const packet,
       
  4081 	const eap_code_value_e result_eap_code,
       
  4082 	const u8_t eap_identifier,
       
  4083 	const tls_peap_tlv_type_e tlv_type)
       
  4084 {
       
  4085 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4086 
       
  4087 	EAP_TRACE_DEBUG(
       
  4088 		m_am_tools,
       
  4089 		TRACE_FLAGS_DEFAULT,
       
  4090 		(EAPL("TLS: %s: message_function: create_result_tlv_message()\n"),
       
  4091 		(m_is_client == true ? "client": "server")));
       
  4092 
       
  4093 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_result_tlv_message()");
       
  4094 
       
  4095 	if (packet->get_is_valid() == false)
       
  4096 	{
       
  4097 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4098 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4099 	}
       
  4100 
       
  4101 	u32_t final_packet_length
       
  4102 		= eap_header_wr_c::get_header_length()
       
  4103 		+ sizeof(u8_t) // EAP-type field
       
  4104 		+tls_peap_tlv_header_c::get_header_length()
       
  4105 		+sizeof(u16_t);
       
  4106 
       
  4107 	eap_status_e status = packet->set_buffer_length(final_packet_length);
       
  4108 	if (status != eap_status_ok)
       
  4109 	{
       
  4110 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4111 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4112 	}
       
  4113 
       
  4114 	if (packet->get_is_valid_data() == false)
       
  4115 	{
       
  4116 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4117 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4118 	}
       
  4119 
       
  4120 	status = packet->set_data_length(final_packet_length);
       
  4121 	if (status != eap_status_ok)
       
  4122 	{
       
  4123 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4124 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4125 	}
       
  4126 
       
  4127 	eap_header_wr_c final_eap_packet(
       
  4128 		m_am_tools,
       
  4129 		packet->get_data(packet->get_data_length()),
       
  4130 		packet->get_data_length());
       
  4131 	if (final_eap_packet.get_is_valid() == false)
       
  4132 	{
       
  4133 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4134 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4135 	}
       
  4136 
       
  4137 	final_eap_packet.reset_header(
       
  4138 		static_cast<u16_t>(final_packet_length),
       
  4139 		m_use_eap_expanded_type);
       
  4140 	final_eap_packet.set_identifier(eap_identifier);
       
  4141 	if (m_is_client == true)
       
  4142 	{
       
  4143 		final_eap_packet.set_code(eap_code_response);
       
  4144 	}
       
  4145 	else
       
  4146 	{
       
  4147 		final_eap_packet.set_code(eap_code_request);
       
  4148 	}
       
  4149 	final_eap_packet.set_length(
       
  4150 		static_cast<u16_t>(final_packet_length),
       
  4151 		m_use_eap_expanded_type);
       
  4152 	final_eap_packet.set_type(
       
  4153 		eap_type_tlv_extensions,
       
  4154 		m_use_eap_expanded_type);
       
  4155 
       
  4156 	tls_peap_tlv_header_c tlv(
       
  4157 		m_am_tools,
       
  4158 		final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()),
       
  4159 		final_eap_packet.get_type_data_length());
       
  4160 	if (tlv.get_is_valid() == false)
       
  4161 	{
       
  4162 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4163 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4164 	}
       
  4165 
       
  4166 	/*  Result TLV:
       
  4167 	 *  0                   1                   2                   3   
       
  4168 	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
  4169 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4170 	 * |M|R|  TLV Type (AVP Type)      |            Length             |
       
  4171 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4172 	 * |            Status             |
       
  4173 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4174 	 */
       
  4175 	tlv.reset_header(static_cast<u16_t>(sizeof(u16_t)));
       
  4176 	tlv.set_flag_tlv_type(tlv_type);
       
  4177 	tlv.set_flag_mandatory_tlv(true);
       
  4178 
       
  4179 	u16_t * const tlv_status = reinterpret_cast<u16_t *>(tlv.get_data(sizeof(u16_t)));
       
  4180 	if (tlv_status == 0)
       
  4181 	{
       
  4182 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4183 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4184 	}
       
  4185 
       
  4186 	u16_t tlv_status_network_order = 0ul;
       
  4187 
       
  4188 	if (result_eap_code == eap_code_success)
       
  4189 	{
       
  4190 		tlv_status_network_order = eap_htons(static_cast<u16_t>(tls_peap_tlv_status_success));
       
  4191 	}
       
  4192 	else
       
  4193 	{
       
  4194 		tlv_status_network_order = eap_htons(static_cast<u16_t>(tls_peap_tlv_status_failure));
       
  4195 	}
       
  4196 
       
  4197 	m_am_tools->memmove(tlv_status, &tlv_status_network_order, sizeof(tlv_status_network_order));
       
  4198 
       
  4199 	EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &tlv, m_is_client);
       
  4200 
       
  4201 
       
  4202 	if (m_is_client == true)
       
  4203 	{
       
  4204 		trace_tunneled_packet(EAPL("<- TUNNELED packet client"), &final_eap_packet);
       
  4205 	}
       
  4206 	else
       
  4207 	{
       
  4208 		trace_tunneled_packet(EAPL("<- TUNNELED packet client"), &final_eap_packet);
       
  4209 	}
       
  4210 
       
  4211 
       
  4212 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4213 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4214 }
       
  4215 
       
  4216 //--------------------------------------------------
       
  4217 
       
  4218 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_intermediate_result_tlv_message(
       
  4219 	eap_buf_chain_wr_c * const packet,
       
  4220 	const eap_code_value_e result_eap_code,
       
  4221 	const u8_t eap_identifier)
       
  4222 {
       
  4223 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4224 
       
  4225 	EAP_TRACE_DEBUG(
       
  4226 		m_am_tools,
       
  4227 		TRACE_FLAGS_DEFAULT,
       
  4228 		(EAPL("TLS: %s: message_function: create_intermediate_result_tlv_message()\n"),
       
  4229 		(m_is_client == true ? "client": "server")));
       
  4230 
       
  4231 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_intermediate_result_tlv_message()");
       
  4232 
       
  4233 	/*  Intermediate Result TLV:
       
  4234 	 *  0                   1                   2                   3   
       
  4235 	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
  4236 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4237 	 * |M|R|  TLV Type (AVP Type)      |            Length             |
       
  4238 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4239 	 * |            Status             |        TLVs...
       
  4240 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4241 	 *
       
  4242 	 * Now we do not support any included TLVs.
       
  4243 	 * This means Intermediate Result TLV is the same as Result TLV.
       
  4244 	 */
       
  4245 
       
  4246 	eap_status_e status = create_result_tlv_message(
       
  4247 		packet,
       
  4248 		result_eap_code,
       
  4249 		eap_identifier,
       
  4250 		tls_peap_tlv_type_intermediate_result);
       
  4251 
       
  4252 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4253 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4254 }
       
  4255 
       
  4256 //--------------------------------------------------
       
  4257 
       
  4258 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_eap_payload_tlv_message(
       
  4259 	eap_buf_chain_wr_c * const packet,
       
  4260 	const eap_header_wr_c * const sent_eap_packet,
       
  4261 	const u8_t eap_identifier)
       
  4262 {
       
  4263 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4264 
       
  4265 	EAP_TRACE_DEBUG(
       
  4266 		m_am_tools,
       
  4267 		TRACE_FLAGS_DEFAULT,
       
  4268 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_eap_payload_tlv_message()\n"),
       
  4269 		(m_is_client == true ? "client": "server")));
       
  4270 
       
  4271 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_eap_payload_tlv_message()");
       
  4272 
       
  4273 	if (packet->get_is_valid() == false)
       
  4274 	{
       
  4275 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4276 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4277 	}
       
  4278 
       
  4279 	const u32_t tlv_payload_length
       
  4280 		= sent_eap_packet->get_length();
       
  4281 
       
  4282 	const u32_t final_packet_length
       
  4283 		= eap_header_wr_c::get_header_length()
       
  4284 		+ sizeof(u8_t) // EAP-type field
       
  4285 		+ tls_peap_tlv_header_c::get_header_length()
       
  4286 		+ tlv_payload_length;
       
  4287 
       
  4288 	eap_status_e status = packet->set_buffer_length(final_packet_length);
       
  4289 	if (status != eap_status_ok)
       
  4290 	{
       
  4291 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4292 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4293 	}
       
  4294 
       
  4295 	if (packet->get_is_valid_data() == false)
       
  4296 	{
       
  4297 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4298 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4299 	}
       
  4300 
       
  4301 	status = packet->set_data_length(final_packet_length);
       
  4302 	if (status != eap_status_ok)
       
  4303 	{
       
  4304 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4305 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4306 	}
       
  4307 
       
  4308 	eap_header_wr_c final_eap_packet(
       
  4309 		m_am_tools,
       
  4310 		packet->get_data(packet->get_data_length()),
       
  4311 		packet->get_data_length());
       
  4312 	if (final_eap_packet.get_is_valid() == false)
       
  4313 	{
       
  4314 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4315 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4316 	}
       
  4317 
       
  4318 	final_eap_packet.reset_header(
       
  4319 		static_cast<u16_t>(final_packet_length),
       
  4320 		m_use_eap_expanded_type);
       
  4321 	final_eap_packet.set_identifier(eap_identifier);
       
  4322 	if (m_is_client == true)
       
  4323 	{
       
  4324 		final_eap_packet.set_code(eap_code_response);
       
  4325 	}
       
  4326 	else
       
  4327 	{
       
  4328 		final_eap_packet.set_code(eap_code_request);
       
  4329 	}
       
  4330 	final_eap_packet.set_length(
       
  4331 		static_cast<u16_t>(final_packet_length),
       
  4332 		m_use_eap_expanded_type);
       
  4333 	final_eap_packet.set_type(
       
  4334 		eap_type_tlv_extensions,
       
  4335 		m_use_eap_expanded_type);
       
  4336 
       
  4337 	tls_peap_tlv_header_c tlv(
       
  4338 		m_am_tools,
       
  4339 		final_eap_packet.get_type_data(final_eap_packet.get_type_data_length()),
       
  4340 		final_eap_packet.get_type_data_length());
       
  4341 	if (tlv.get_is_valid() == false)
       
  4342 	{
       
  4343 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4344 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4345 	}
       
  4346 
       
  4347 	// EAP-Payload TLV:
       
  4348 	//  0                   1                   2                   3
       
  4349 	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  4350 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4351 	// |M|R|         TLV Type          |            Length             |
       
  4352 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4353 	// |                          EAP packet...
       
  4354 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4355 	// |                             TLVs...
       
  4356 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4357 	//
       
  4358 	// We do not support any included TLVs.
       
  4359 	//
       
  4360 	tlv.reset_header(static_cast<u16_t>(tlv_payload_length));
       
  4361 	tlv.set_flag_tlv_type(tls_peap_tlv_eap_payload);
       
  4362 	tlv.set_flag_mandatory_tlv(true);
       
  4363 
       
  4364 
       
  4365 	{
       
  4366 		// Adds EAP-Packet as a payload to EAP-Payload TLV.
       
  4367 		u16_t * const eap_packet_payload = reinterpret_cast<u16_t *>(
       
  4368 			tlv.get_data_offset(0ul, sent_eap_packet->get_length()));
       
  4369 		if (eap_packet_payload == 0)
       
  4370 		{
       
  4371 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4372 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4373 		}
       
  4374 
       
  4375 		m_am_tools->memmove(
       
  4376 			eap_packet_payload,
       
  4377 			sent_eap_packet->get_header_buffer(sent_eap_packet->get_length()),
       
  4378 			sent_eap_packet->get_length());
       
  4379 	}
       
  4380 
       
  4381 	EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &tlv, m_is_client);
       
  4382 
       
  4383 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4384 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4385 }
       
  4386 
       
  4387 //--------------------------------------------------
       
  4388 
       
  4389 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_crypto_binding_tlv_message(
       
  4390 	eap_buf_chain_wr_c * const packet,
       
  4391 	const eap_code_value_e result_eap_code,
       
  4392 	const u8_t eap_identifier,
       
  4393 	const eap_variable_data_c * const nonce,
       
  4394 	const u8_t received_version)
       
  4395 {
       
  4396 	EAP_UNREFERENCED_PARAMETER(result_eap_code);
       
  4397 
       
  4398 	EAP_TRACE_DEBUG(
       
  4399 		m_am_tools,
       
  4400 		TRACE_FLAGS_DEFAULT,
       
  4401 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_crypto_binding_tlv_message()\n"),
       
  4402 		(m_is_client == true ? "client": "server")));
       
  4403 
       
  4404 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_crypto_binding_tlv_message()");
       
  4405 
       
  4406 	if (packet->get_is_valid() == false)
       
  4407 	{
       
  4408 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4409 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4410 	}
       
  4411 
       
  4412 	const u32_t result_tlv_payload_length
       
  4413 		= sizeof(u16_t);
       
  4414 
       
  4415 	const u32_t result_tlv_length
       
  4416 		= tls_peap_tlv_header_c::get_header_length()
       
  4417 		+ result_tlv_payload_length;
       
  4418 
       
  4419 	const u32_t crypto_binding_tlv_payload_length
       
  4420 		= sizeof(u8_t)
       
  4421 		+ sizeof(u8_t)
       
  4422 		+ sizeof(u16_t)
       
  4423 		+ TLV_NONCE_LENGTH
       
  4424 		+ TLV_MAC_LENGTH;
       
  4425 
       
  4426 	const u32_t crypto_binding_tlv_length
       
  4427 		= tls_peap_tlv_header_c::get_header_length()
       
  4428 		+ crypto_binding_tlv_payload_length;
       
  4429 
       
  4430 	const u32_t intermediate_result_tlv_payload_length
       
  4431 		= sizeof(u16_t);
       
  4432 
       
  4433 	const u32_t intermediate_result_tlv_length
       
  4434 		= tls_peap_tlv_header_c::get_header_length()
       
  4435 		+ intermediate_result_tlv_payload_length;
       
  4436 
       
  4437 	const u32_t final_packet_length
       
  4438 		= eap_header_wr_c::get_header_length()
       
  4439 		+ sizeof(u8_t) // EAP-type field
       
  4440 		+ result_tlv_length
       
  4441 		+ crypto_binding_tlv_length
       
  4442 		+ intermediate_result_tlv_length;
       
  4443 
       
  4444 	eap_status_e status = packet->set_buffer_length(final_packet_length);
       
  4445 	if (status != eap_status_ok)
       
  4446 	{
       
  4447 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4448 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4449 	}
       
  4450 
       
  4451 	if (packet->get_is_valid_data() == false)
       
  4452 	{
       
  4453 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4454 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4455 	}
       
  4456 
       
  4457 	status = packet->set_data_length(final_packet_length);
       
  4458 	if (status != eap_status_ok)
       
  4459 	{
       
  4460 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4461 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4462 	}
       
  4463 
       
  4464 	eap_header_wr_c final_eap_packet(
       
  4465 		m_am_tools,
       
  4466 		packet->get_data(packet->get_data_length()),
       
  4467 		packet->get_data_length());
       
  4468 	if (final_eap_packet.get_is_valid() == false)
       
  4469 	{
       
  4470 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4471 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4472 	}
       
  4473 
       
  4474 	final_eap_packet.reset_header(
       
  4475 		static_cast<u16_t>(final_packet_length),
       
  4476 		m_use_eap_expanded_type);
       
  4477 	final_eap_packet.set_identifier(eap_identifier);
       
  4478 	if (m_is_client == true)
       
  4479 	{
       
  4480 		final_eap_packet.set_code(eap_code_response);
       
  4481 	}
       
  4482 	else
       
  4483 	{
       
  4484 		final_eap_packet.set_code(eap_code_request);
       
  4485 	}
       
  4486 	final_eap_packet.set_length(
       
  4487 		static_cast<u16_t>(final_packet_length),
       
  4488 		m_use_eap_expanded_type);
       
  4489 	final_eap_packet.set_type(
       
  4490 		eap_type_tlv_extensions,
       
  4491 		m_use_eap_expanded_type);
       
  4492 
       
  4493 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4494 
       
  4495 	u32_t tlv_offset = 0ul;
       
  4496 
       
  4497 	{
       
  4498 		// Data includes Result TLV:
       
  4499 		//  0                   1                   2                   3
       
  4500 		//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  4501 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4502 		// |M|R|         TLV Type          |            Length             |
       
  4503 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4504 		// |             Status            |        TLVs...
       
  4505 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4506 		//
       
  4507 		// We do not support included TLVs.
       
  4508 		// 
       
  4509 
       
  4510 		tls_peap_tlv_header_c result_tlv(
       
  4511 			m_am_tools,
       
  4512 			final_eap_packet.get_type_data_offset(tlv_offset, result_tlv_length),
       
  4513 			final_eap_packet.get_type_data_length());
       
  4514 		if (result_tlv.get_is_valid() == false)
       
  4515 		{
       
  4516 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4517 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4518 		}
       
  4519 
       
  4520 		tlv_offset += result_tlv_length;
       
  4521 
       
  4522 		result_tlv.reset_header(static_cast<u16_t>(result_tlv_payload_length));
       
  4523 		result_tlv.set_flag_tlv_type(tls_peap_tlv_type_result);
       
  4524 		result_tlv.set_flag_mandatory_tlv(true);
       
  4525 		
       
  4526 
       
  4527 		{
       
  4528 			u16_t * const tlv_status = reinterpret_cast<u16_t *>(
       
  4529 				result_tlv.get_data_offset(0ul, sizeof(u16_t)));
       
  4530 			if (tlv_status == 0)
       
  4531 			{
       
  4532 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4533 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4534 			}
       
  4535 
       
  4536 			u16_t tlv_status_value = 0ul;
       
  4537 			if (result_eap_code == eap_code_success)
       
  4538 			{
       
  4539 				tlv_status_value = static_cast<u16_t>(tls_peap_tlv_status_success);
       
  4540 			}
       
  4541 			else
       
  4542 			{
       
  4543 				tlv_status_value = static_cast<u16_t>(tls_peap_tlv_status_failure);
       
  4544 			}
       
  4545 
       
  4546 			status = eap_write_u16_t_network_order(
       
  4547 				tlv_status,
       
  4548 				sizeof(*tlv_status),
       
  4549 				tlv_status_value);
       
  4550 			if (status != eap_status_ok)
       
  4551 			{
       
  4552 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4553 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4554 			}
       
  4555 		}
       
  4556 
       
  4557 		EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &result_tlv, m_is_client);
       
  4558 	}
       
  4559 
       
  4560 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4561 
       
  4562 	{
       
  4563 		// Data includes Crypto Binding TLV:
       
  4564 		//  0                   1                   2                   3
       
  4565 		//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  4566 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4567 		// |M|R|         TLV Type          |            Length             |
       
  4568 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4569 		// |    Version    |Received Ver.  |         Sub-Type              |
       
  4570 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4571 		// |                                                               |
       
  4572 		// ~                             Nonce                             ~
       
  4573 		// |                                                               |
       
  4574 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4575 		// |                                                               |
       
  4576 		// ~                          Compound MAC                         ~
       
  4577 		// |                                                               |
       
  4578 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4579 		// 
       
  4580 
       
  4581 		tls_peap_tlv_header_c crypto_binding_tlv(
       
  4582 			m_am_tools,
       
  4583 			final_eap_packet.get_type_data_offset(tlv_offset, crypto_binding_tlv_length),
       
  4584 			final_eap_packet.get_type_data_length());
       
  4585 		if (crypto_binding_tlv.get_is_valid() == false)
       
  4586 		{
       
  4587 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4588 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4589 		}
       
  4590 
       
  4591 		tlv_offset += crypto_binding_tlv_length;
       
  4592 
       
  4593 		crypto_binding_tlv.reset_header(static_cast<u16_t>(crypto_binding_tlv_payload_length));
       
  4594 		crypto_binding_tlv.set_flag_tlv_type(tls_peap_tlv_type_crypto_binding);
       
  4595 		crypto_binding_tlv.set_flag_mandatory_tlv(true);
       
  4596 
       
  4597 		u32_t tlv_data_offset = 0ul;
       
  4598 
       
  4599 		{
       
  4600 			u8_t * const tlv_version = reinterpret_cast<u8_t *>(
       
  4601 				crypto_binding_tlv.get_data_offset(tlv_data_offset, sizeof(u8_t)));
       
  4602 			if (tlv_version == 0)
       
  4603 			{
       
  4604 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4605 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4606 			}
       
  4607 			
       
  4608 			*tlv_version = static_cast<u8_t>(0ul);
       
  4609 
       
  4610 			tlv_data_offset += sizeof(u8_t);
       
  4611 		}
       
  4612 
       
  4613 
       
  4614 		{
       
  4615 			u8_t * const tlv_received_version = reinterpret_cast<u8_t *>(
       
  4616 				crypto_binding_tlv.get_data_offset(tlv_data_offset, sizeof(u8_t)));
       
  4617 			if (tlv_received_version == 0)
       
  4618 			{
       
  4619 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4620 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4621 			}
       
  4622 			
       
  4623 			*tlv_received_version = static_cast<u8_t>(received_version);
       
  4624 
       
  4625 			tlv_data_offset += sizeof(u8_t);
       
  4626 		}
       
  4627 
       
  4628 
       
  4629 		{
       
  4630 			u16_t * const tlv_sub_type = reinterpret_cast<u16_t *>(
       
  4631 				crypto_binding_tlv.get_data_offset(tlv_data_offset, sizeof(u16_t)));
       
  4632 			if (tlv_sub_type == 0)
       
  4633 			{
       
  4634 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4635 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4636 			}
       
  4637 
       
  4638 			u16_t tlv_sub_type_network_order = 0ul;
       
  4639 			if (m_is_client == true)
       
  4640 			{
       
  4641 				tlv_sub_type_network_order = eap_htons(
       
  4642 					static_cast<u16_t>(tls_peap_tlv_type_crypto_binding_request));
       
  4643 			}
       
  4644 			else
       
  4645 			{
       
  4646 				tlv_sub_type_network_order = eap_htons(
       
  4647 					static_cast<u16_t>(tls_peap_tlv_type_crypto_binding_response));
       
  4648 			}
       
  4649 			
       
  4650 			m_am_tools->memmove(
       
  4651 				tlv_sub_type,
       
  4652 				&tlv_sub_type_network_order,
       
  4653 				sizeof(tlv_sub_type_network_order));
       
  4654 
       
  4655 			tlv_data_offset += sizeof(u16_t);
       
  4656 		}
       
  4657 
       
  4658 
       
  4659 		if (nonce->get_data_length() == TLV_NONCE_LENGTH)
       
  4660 		{
       
  4661 			u16_t * const tlv_nonce = reinterpret_cast<u16_t *>(
       
  4662 				crypto_binding_tlv.get_data_offset(tlv_data_offset, TLV_NONCE_LENGTH));
       
  4663 			if (tlv_nonce == 0)
       
  4664 			{
       
  4665 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4666 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4667 			}
       
  4668 			
       
  4669 			m_am_tools->memmove(tlv_nonce, nonce->get_data(TLV_NONCE_LENGTH), TLV_NONCE_LENGTH);
       
  4670 
       
  4671 			tlv_data_offset += TLV_NONCE_LENGTH;
       
  4672 		}
       
  4673 		else
       
  4674 		{
       
  4675 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4676 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4677 		}
       
  4678 
       
  4679 
       
  4680 		{
       
  4681 			u8_t * const tlv_mac = reinterpret_cast<u8_t *>(
       
  4682 				crypto_binding_tlv.get_data_offset(tlv_data_offset, TLV_MAC_LENGTH));
       
  4683 			if (tlv_mac == 0)
       
  4684 			{
       
  4685 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4686 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4687 			}
       
  4688 			
       
  4689 			m_am_tools->memset(tlv_mac, 0, TLV_MAC_LENGTH);
       
  4690 
       
  4691 			eap_variable_data_c * mac_key = &m_peap_v2_CMK_B1_server;
       
  4692 			if (m_is_client == true)
       
  4693 			{
       
  4694 				mac_key = &m_peap_v2_CMK_B2_client;
       
  4695 			}
       
  4696 
       
  4697 			eap_variable_data_c mac_data(m_am_tools);
       
  4698 
       
  4699 			status = create_crypto_binding_compound_mac(
       
  4700 				mac_key,
       
  4701 				&crypto_binding_tlv,
       
  4702 				&mac_data);
       
  4703 			if (status != eap_status_ok)
       
  4704 			{
       
  4705 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4706 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  4707 			}
       
  4708 			
       
  4709 			m_am_tools->memmove(
       
  4710 				tlv_mac,
       
  4711 				mac_data.get_data(mac_data.get_data_length()),
       
  4712 				TLV_MAC_LENGTH);
       
  4713 
       
  4714 			tlv_data_offset += TLV_MAC_LENGTH;
       
  4715 		}
       
  4716 
       
  4717 		EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &crypto_binding_tlv, m_is_client);
       
  4718 	}
       
  4719 
       
  4720 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4721 
       
  4722 	{
       
  4723 		// Data includes Intermediate Result TLV:
       
  4724 		//  0                   1                   2                   3
       
  4725 		//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  4726 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4727 		// |M|R|         TLV Type          |            Length             |
       
  4728 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4729 		// |             Status            |        TLVs...
       
  4730 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4731 		// 
       
  4732 		// We do not support included TLVs.
       
  4733 		// 
       
  4734 
       
  4735 		tls_peap_tlv_header_c intermediate_result_tlv(
       
  4736 			m_am_tools,
       
  4737 			final_eap_packet.get_type_data_offset(tlv_offset, intermediate_result_tlv_length),
       
  4738 			final_eap_packet.get_type_data_length());
       
  4739 		if (intermediate_result_tlv.get_is_valid() == false)
       
  4740 		{
       
  4741 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4742 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4743 		}
       
  4744 
       
  4745 		tlv_offset += intermediate_result_tlv_length;
       
  4746 
       
  4747 		intermediate_result_tlv.reset_header(
       
  4748 			static_cast<u16_t>(intermediate_result_tlv_payload_length));
       
  4749 		intermediate_result_tlv.set_flag_tlv_type(tls_peap_tlv_type_intermediate_result);
       
  4750 		intermediate_result_tlv.set_flag_mandatory_tlv(true);
       
  4751 		
       
  4752 
       
  4753 		{
       
  4754 			u16_t * const tlv_intermediate_status
       
  4755 				= reinterpret_cast<u16_t *>(
       
  4756 					intermediate_result_tlv.get_data_offset(0ul, sizeof(u16_t)));
       
  4757 			if (tlv_intermediate_status == 0)
       
  4758 			{
       
  4759 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4760 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4761 			}
       
  4762 
       
  4763 			u16_t tlv_intermediate_status_value = 0ul;
       
  4764 			if (result_eap_code == eap_code_success)
       
  4765 			{
       
  4766 				tlv_intermediate_status_value = static_cast<u16_t>(tls_peap_tlv_status_success);
       
  4767 			}
       
  4768 			else
       
  4769 			{
       
  4770 				tlv_intermediate_status_value = static_cast<u16_t>(tls_peap_tlv_status_failure);
       
  4771 			}
       
  4772 
       
  4773 			status = eap_write_u16_t_network_order(
       
  4774 				tlv_intermediate_status,
       
  4775 				sizeof(*tlv_intermediate_status),
       
  4776 				tlv_intermediate_status_value);
       
  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 		EAP_TLS_PEAP_TRACE_PAYLOAD("Add TLV payload", &intermediate_result_tlv, m_is_client);
       
  4785 	}
       
  4786 
       
  4787 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4788 
       
  4789 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4790 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4791 }
       
  4792 
       
  4793 //--------------------------------------------------
       
  4794 
       
  4795 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_eap_diameter_avp_message(
       
  4796 	eap_buf_chain_wr_c * const packet,
       
  4797 	const eap_header_wr_c * const sent_eap_packet,
       
  4798 	const u8_t /* eap_identifier */)
       
  4799 {
       
  4800 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4801 
       
  4802 	EAP_TRACE_DEBUG(
       
  4803 		m_am_tools,
       
  4804 		TRACE_FLAGS_DEFAULT,
       
  4805 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::create_eap_diameter_avp_message()\n"),
       
  4806 		(m_is_client == true ? "client": "server")));
       
  4807 
       
  4808 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_eap_diameter_avp_message()");
       
  4809 
       
  4810 	if (packet->get_is_valid() == false)
       
  4811 	{
       
  4812 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4813 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4814 	}
       
  4815 
       
  4816 	const u32_t tlv_payload_length
       
  4817 		= sent_eap_packet->get_length();
       
  4818 
       
  4819 	const u32_t final_packet_length
       
  4820 		= eap_diameter_avp_header_c::get_header_length(false)
       
  4821 		+ tlv_payload_length;
       
  4822 
       
  4823 	eap_status_e status = packet->set_buffer_length(final_packet_length);
       
  4824 	if (status != eap_status_ok)
       
  4825 	{
       
  4826 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4827 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4828 	}
       
  4829 
       
  4830 	if (packet->get_is_valid_data() == 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 	status = packet->set_data_length(final_packet_length);
       
  4837 	if (status != eap_status_ok)
       
  4838 	{
       
  4839 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4840 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4841 	}
       
  4842 
       
  4843 	eap_diameter_avp_header_c avp(
       
  4844 		m_am_tools,
       
  4845 		packet->get_data(packet->get_data_length()),
       
  4846 		packet->get_data_length());
       
  4847 	if (avp.get_is_valid() == false)
       
  4848 	{
       
  4849 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4850 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4851 	}
       
  4852 
       
  4853 	// These packets are encapsulated to AVP.
       
  4854 	//  0                   1                   2                   3   
       
  4855 	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
  4856 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4857 	// |                           AVP Code                            |
       
  4858 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4859 	// |V|M|r r r r r r|                  AVP Length                   |
       
  4860 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4861 	// |                      Vendor-ID (optional)                     |
       
  4862 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4863 	// |                   Data includes EAP-packet ...
       
  4864 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  4865 
       
  4866 	status = avp.reset_header(static_cast<u16_t>(final_packet_length));
       
  4867 	if (status != eap_status_ok)
       
  4868 	{
       
  4869 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4870 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4871 	}
       
  4872 
       
  4873 	status = avp.set_avp_code(eap_diameter_avp_code_eap_message);
       
  4874 	if (status != eap_status_ok)
       
  4875 	{
       
  4876 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4877 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4878 	}
       
  4879 
       
  4880 	status = avp.set_avp_flag_mandatory_avp(false);
       
  4881 	if (status != eap_status_ok)
       
  4882 	{
       
  4883 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4884 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4885 	}
       
  4886 
       
  4887 
       
  4888 	{
       
  4889 		// Adds EAP-Packet as a payload to AVP.
       
  4890 		u16_t * const eap_packet_payload = reinterpret_cast<u16_t *>(
       
  4891 			avp.get_data_offset(0ul, sent_eap_packet->get_length()));
       
  4892 		if (eap_packet_payload == 0)
       
  4893 		{
       
  4894 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4895 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4896 		}
       
  4897 
       
  4898 		m_am_tools->memmove(
       
  4899 			eap_packet_payload,
       
  4900 			sent_eap_packet->get_header_buffer(sent_eap_packet->get_length()),
       
  4901 			sent_eap_packet->get_length());
       
  4902 	}
       
  4903 
       
  4904 	EAP_TLS_PEAP_TRACE_TTLS_PAYLOAD("Send TTLS AVP payload", &avp, m_is_client);
       
  4905 
       
  4906 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4907 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4908 }
       
  4909 
       
  4910 //--------------------------------------------------
       
  4911 
       
  4912 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_nonce(
       
  4913 	eap_variable_data_c * const nonce)
       
  4914 {
       
  4915 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4916 
       
  4917 	EAP_TRACE_DEBUG(
       
  4918 		m_am_tools,
       
  4919 		TRACE_FLAGS_DEFAULT,
       
  4920 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_nonce(): ")
       
  4921 		 EAPL("this = 0x%08x\n"),
       
  4922 		 (m_is_client == true ? "client": "server"),
       
  4923 		 this));
       
  4924 
       
  4925 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_nonce()");
       
  4926 
       
  4927 	eap_status_e status = nonce->set_buffer_length(TLV_NONCE_LENGTH);
       
  4928 	if (status != eap_status_ok)
       
  4929 	{
       
  4930 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4931 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4932 	}
       
  4933 	nonce->set_data_length(nonce->get_buffer_length());
       
  4934 
       
  4935 	crypto_random_c rand(m_am_tools);
       
  4936 	if (rand.get_is_valid() == false)
       
  4937 	{
       
  4938 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4939 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4940 	}
       
  4941 
       
  4942 	status = rand.get_rand_bytes(
       
  4943 		nonce->get_data(nonce->get_data_length()),
       
  4944 		nonce->get_data_length());
       
  4945 	if (status != eap_status_ok)
       
  4946 	{
       
  4947 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4948 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4949 	}
       
  4950 
       
  4951 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4952 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4953 }
       
  4954 
       
  4955 //--------------------------------------------------
       
  4956 
       
  4957 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_nonce_peap_v2(
       
  4958 	const bool create_client_nonce_when_true)
       
  4959 {
       
  4960 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4961 
       
  4962 	EAP_TRACE_DEBUG(
       
  4963 		m_am_tools,
       
  4964 		TRACE_FLAGS_DEFAULT,
       
  4965 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_nonce_peap_v2(%s): ")
       
  4966 		 EAPL("this = 0x%08x\n"),
       
  4967 		 (m_is_client == true ? "client": "server"),
       
  4968 		 (create_client_nonce_when_true == true ? "client": "server"),
       
  4969 		 this));
       
  4970 
       
  4971 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_nonce_peap_v2()");
       
  4972 
       
  4973 	eap_status_e status = eap_status_process_general_error;
       
  4974 
       
  4975 	eap_variable_data_c * nonce = 0;
       
  4976 
       
  4977 	if (create_client_nonce_when_true == true)
       
  4978 	{
       
  4979 		nonce = &m_peap_v2_client_nonce;
       
  4980 	}
       
  4981 	else
       
  4982 	{
       
  4983 		nonce = &m_peap_v2_server_nonce;
       
  4984 	}
       
  4985 
       
  4986 	status = create_nonce(nonce);
       
  4987 	if (status != eap_status_ok)
       
  4988 	{
       
  4989 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4990 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4991 	}
       
  4992 
       
  4993 
       
  4994 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4995 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4996 }
       
  4997 
       
  4998 //--------------------------------------------------
       
  4999 
       
  5000 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_compound_mac_key_peap_v2(
       
  5001 	const bool create_client_CMK_when_true)
       
  5002 {
       
  5003 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5004 
       
  5005 	EAP_TRACE_DEBUG(
       
  5006 		m_am_tools,
       
  5007 		TRACE_FLAGS_DEFAULT,
       
  5008 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_compound_mac_key_peap_v2(%s): ")
       
  5009 		 EAPL("this = 0x%08x\n"),
       
  5010 		 (m_is_client == true ? "client": "server"),
       
  5011 		 (create_client_CMK_when_true == true ? "client": "server"),
       
  5012 		 this));
       
  5013 
       
  5014 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_compound_mac_key_peap_v2()");
       
  5015 
       
  5016 	eap_status_e status = eap_status_process_general_error;
       
  5017 
       
  5018 	if (m_peap_v2_IPMKn.get_is_valid_data() == false
       
  5019 		|| m_peap_v2_IPMKn.get_data_length() != TLS_PEAP_V2_TK_LENGTH)
       
  5020 	{
       
  5021 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5022 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5023 	}
       
  5024 
       
  5025 	if (m_peap_v2_ISKn.get_is_valid_data() == false)
       
  5026 	{
       
  5027 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5028 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5029 	}
       
  5030 
       
  5031 	EAP_TRACE_DATA_DEBUG(
       
  5032 		m_am_tools,
       
  5033 		TRACE_FLAGS_DEFAULT,
       
  5034 		(EAPL("m_peap_v2_IPMKn"),
       
  5035 		 m_peap_v2_IPMKn.get_data(m_peap_v2_IPMKn.get_data_length()),
       
  5036 		 m_peap_v2_IPMKn.get_data_length()));
       
  5037 
       
  5038 	EAP_TRACE_DATA_DEBUG(
       
  5039 		m_am_tools,
       
  5040 		TRACE_FLAGS_DEFAULT,
       
  5041 		(EAPL("m_peap_v2_ISKn"),
       
  5042 		 m_peap_v2_ISKn.get_data(m_peap_v2_ISKn.get_data_length()),
       
  5043 		 m_peap_v2_ISKn.get_data_length()));
       
  5044 
       
  5045 	{
       
  5046 		eap_variable_data_c label(m_am_tools);
       
  5047 
       
  5048 		status = label.set_copy_of_buffer(
       
  5049 			TLS_INTERMEDIATE_COMBINED_KEY_LABEL,
       
  5050 			TLS_INTERMEDIATE_COMBINED_KEY_LABEL_LENGTH);
       
  5051 		if (status != eap_status_ok)
       
  5052 		{
       
  5053 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5054 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5055 		}
       
  5056 
       
  5057 		crypto_tls_sha1_prf_c tls_sha1_prf(m_am_tools);
       
  5058 
       
  5059 		status = tls_sha1_prf.tls_prf_init(
       
  5060 			&m_peap_v2_IPMKn,
       
  5061 			&label,
       
  5062 			&m_peap_v2_ISKn);
       
  5063 		if (status != eap_status_ok)
       
  5064 		{
       
  5065 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5066 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5067 		}
       
  5068 
       
  5069 		if (tls_sha1_prf.get_is_valid() == false)
       
  5070 		{
       
  5071 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5072 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5073 		}
       
  5074 
       
  5075 		status = tls_sha1_prf.tls_prf_output(
       
  5076 			m_peap_v2_IPMKn.get_data(m_peap_v2_IPMKn.get_data_length()),
       
  5077 			m_peap_v2_IPMKn.get_data_length());
       
  5078 		if (status != eap_status_ok)
       
  5079 		{
       
  5080 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5081 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5082 		}
       
  5083 
       
  5084 		EAP_TRACE_DATA_DEBUG(
       
  5085 			m_am_tools,
       
  5086 			TRACE_FLAGS_DEFAULT,
       
  5087 			(EAPL("m_peap_v2_IPMKn"),
       
  5088 			 m_peap_v2_IPMKn.get_data(m_peap_v2_IPMKn.get_data_length()),
       
  5089 			 m_peap_v2_IPMKn.get_data_length()));
       
  5090 	}
       
  5091 
       
  5092 	{
       
  5093 		eap_variable_data_c label(m_am_tools);
       
  5094 
       
  5095 		if (create_client_CMK_when_true == true)
       
  5096 		{
       
  5097 			status = label.set_copy_of_buffer(
       
  5098 				TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL,
       
  5099 				TLS_INTERMEDIATE_COMPOUND_CLIENT_MAC_KEY_LABEL_LENGTH);
       
  5100 		}
       
  5101 		else
       
  5102 		{
       
  5103 			status = label.set_copy_of_buffer(
       
  5104 				TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL,
       
  5105 				TLS_INTERMEDIATE_COMPOUND_SERVER_MAC_KEY_LABEL_LENGTH);
       
  5106 		}
       
  5107 
       
  5108 		if (status != eap_status_ok)
       
  5109 		{
       
  5110 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5111 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5112 		}
       
  5113 
       
  5114 		crypto_tls_sha1_prf_c tls_sha1_prf(m_am_tools);
       
  5115 
       
  5116 		EAP_TRACE_DATA_DEBUG(
       
  5117 			m_am_tools,
       
  5118 			TRACE_FLAGS_DEFAULT,
       
  5119 			(EAPL("m_peap_v2_server_nonce"),
       
  5120 			 m_peap_v2_server_nonce.get_data(m_peap_v2_server_nonce.get_data_length()),
       
  5121 			 m_peap_v2_server_nonce.get_data_length()));
       
  5122 
       
  5123 		if (create_client_CMK_when_true == true)
       
  5124 		{
       
  5125 			eap_variable_data_c client_server_nonce(m_am_tools);
       
  5126 
       
  5127 			EAP_TRACE_DATA_DEBUG(
       
  5128 				m_am_tools,
       
  5129 				TRACE_FLAGS_DEFAULT,
       
  5130 				(EAPL("m_peap_v2_client_nonce"),
       
  5131 				 m_peap_v2_client_nonce.get_data(m_peap_v2_client_nonce.get_data_length()),
       
  5132 				 m_peap_v2_client_nonce.get_data_length()));
       
  5133 
       
  5134 			status = client_server_nonce.set_copy_of_buffer(
       
  5135 				&m_peap_v2_client_nonce);
       
  5136 			if (status != eap_status_ok)
       
  5137 			{
       
  5138 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5139 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5140 			}
       
  5141 
       
  5142 			status = client_server_nonce.add_data(
       
  5143 				&m_peap_v2_server_nonce);
       
  5144 			if (status != eap_status_ok)
       
  5145 			{
       
  5146 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5147 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  5148 			}
       
  5149 
       
  5150 			status = tls_sha1_prf.tls_prf_init(
       
  5151 				&m_peap_v2_IPMKn,
       
  5152 				&label,
       
  5153 				&client_server_nonce);
       
  5154 		}
       
  5155 		else
       
  5156 		{
       
  5157 			status = tls_sha1_prf.tls_prf_init(
       
  5158 				&m_peap_v2_IPMKn,
       
  5159 				&label,
       
  5160 				&m_peap_v2_server_nonce);
       
  5161 		}
       
  5162 
       
  5163 		if (status != eap_status_ok)
       
  5164 		{
       
  5165 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5166 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5167 		}
       
  5168 
       
  5169 		if (tls_sha1_prf.get_is_valid() == false)
       
  5170 		{
       
  5171 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5172 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5173 		}
       
  5174 
       
  5175 		eap_variable_data_c * cmk = &m_peap_v2_CMK_B1_server;
       
  5176 
       
  5177 		if (create_client_CMK_when_true == true)
       
  5178 		{
       
  5179 			cmk = &m_peap_v2_CMK_B2_client;
       
  5180 		}
       
  5181 
       
  5182 		status = cmk->set_buffer_length(TLS_PEAP_V2_COMPOUND_MAC_KEY_LENGTH);
       
  5183 		if (status != eap_status_ok)
       
  5184 		{
       
  5185 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5186 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5187 		}
       
  5188 		cmk->set_data_length(TLS_PEAP_V2_COMPOUND_MAC_KEY_LENGTH);
       
  5189 
       
  5190 		status = tls_sha1_prf.tls_prf_output(
       
  5191 			cmk->get_data(cmk->get_data_length()),
       
  5192 			cmk->get_data_length());
       
  5193 
       
  5194 		if (status != eap_status_ok)
       
  5195 		{
       
  5196 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5197 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5198 		}
       
  5199 
       
  5200 		EAP_TRACE_DATA_DEBUG(
       
  5201 			m_am_tools,
       
  5202 			TRACE_FLAGS_DEFAULT,
       
  5203 			(EAPL("TLV MAC key CMK"),
       
  5204 			 cmk->get_data(cmk->get_data_length()),
       
  5205 			 cmk->get_data_length()));
       
  5206 	}
       
  5207 
       
  5208 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5209 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5210 }
       
  5211 
       
  5212 //--------------------------------------------------
       
  5213 
       
  5214 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_compound_session_key_peap_v2()
       
  5215 {
       
  5216 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5217 
       
  5218 	EAP_TRACE_DEBUG(
       
  5219 		m_am_tools,
       
  5220 		TRACE_FLAGS_DEFAULT,
       
  5221 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_compound_session_key_peap_v2(): ")
       
  5222 		 EAPL("this = 0x%08x\n"),
       
  5223 		 (m_is_client == true ? "client": "server"),
       
  5224 		 this));
       
  5225 
       
  5226 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_compound_session_key_peap_v2()");
       
  5227 
       
  5228 	eap_status_e status = eap_status_process_general_error;
       
  5229 
       
  5230 	if (m_peap_v2_IPMKn.get_is_valid_data() == false
       
  5231 		|| m_peap_v2_IPMKn.get_data_length() != TLS_PEAP_V2_TK_LENGTH)
       
  5232 	{
       
  5233 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5234 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5235 	}
       
  5236 
       
  5237 	{
       
  5238 		eap_variable_data_c label(m_am_tools);
       
  5239 
       
  5240 		status = label.set_copy_of_buffer(
       
  5241 			TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL,
       
  5242 			TLS_INTERMEDIATE_COMPOUND_SESSION_KEY_LABEL_LENGTH);
       
  5243 		if (status != eap_status_ok)
       
  5244 		{
       
  5245 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5246 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5247 		}
       
  5248 
       
  5249 		crypto_tls_sha1_prf_c tls_sha1_prf(m_am_tools);
       
  5250 
       
  5251 		eap_variable_data_c client_server_nonce_outputlength(m_am_tools);
       
  5252 
       
  5253 		status = client_server_nonce_outputlength.set_copy_of_buffer(
       
  5254 			&m_peap_v2_client_nonce);
       
  5255 		if (status != eap_status_ok)
       
  5256 		{
       
  5257 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5258 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5259 		}
       
  5260 
       
  5261 		status = client_server_nonce_outputlength.add_data(
       
  5262 			&m_peap_v2_server_nonce);
       
  5263 		if (status != eap_status_ok)
       
  5264 		{
       
  5265 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5266 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5267 		}
       
  5268 
       
  5269 		/* @{ What is the sizeof the OutputLength? } */
       
  5270 		
       
  5271 		u8_t OutputLength = TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH;
       
  5272 
       
  5273 		status = client_server_nonce_outputlength.add_data(
       
  5274 			&OutputLength,
       
  5275 			sizeof(OutputLength));
       
  5276 		if (status != eap_status_ok)
       
  5277 		{
       
  5278 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5279 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5280 		}
       
  5281 
       
  5282 		status = tls_sha1_prf.tls_prf_init(
       
  5283 			&m_peap_v2_IPMKn,
       
  5284 			&label,
       
  5285 			&client_server_nonce_outputlength);
       
  5286 
       
  5287 		if (status != eap_status_ok)
       
  5288 		{
       
  5289 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5290 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5291 		}
       
  5292 
       
  5293 		if (tls_sha1_prf.get_is_valid() == false)
       
  5294 		{
       
  5295 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5296 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5297 		}
       
  5298 
       
  5299 		status = m_peap_v2_CSK.set_buffer_length(TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH);
       
  5300 		if (status != eap_status_ok)
       
  5301 		{
       
  5302 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5303 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5304 		}
       
  5305 		m_peap_v2_CSK.set_data_length(TLS_PEAP_V2_COMPOUND_SESSION_KEY_LENGTH);
       
  5306 
       
  5307 		status = tls_sha1_prf.tls_prf_output(
       
  5308 			m_peap_v2_CSK.get_data(m_peap_v2_CSK.get_data_length()),
       
  5309 			m_peap_v2_CSK.get_data_length());
       
  5310 
       
  5311 		if (status != eap_status_ok)
       
  5312 		{
       
  5313 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5314 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5315 		}
       
  5316 	}
       
  5317 
       
  5318 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5319 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5320 }
       
  5321 
       
  5322 //--------------------------------------------------
       
  5323 
       
  5324 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::create_crypto_binding_compound_mac(
       
  5325 	const eap_variable_data_c * const peap_v2_CMK,
       
  5326 	const tls_peap_tlv_header_c * const crypto_binding_tlv,
       
  5327 	eap_variable_data_c * const mac_data)
       
  5328 {
       
  5329 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5330 
       
  5331 	eap_status_e status = eap_status_process_general_error;
       
  5332 
       
  5333 	EAP_TRACE_DEBUG(
       
  5334 		m_am_tools,
       
  5335 		TRACE_FLAGS_DEFAULT,
       
  5336 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::create_crypto_binding_compound_mac(): ")
       
  5337 		 EAPL("this = 0x%08x\n"),
       
  5338 		 (m_is_client == true ? "client": "server"),
       
  5339 		 this));
       
  5340 
       
  5341 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::create_crypto_binding_compound_mac()");
       
  5342 
       
  5343 	EAP_TLS_PEAP_TRACE_PAYLOAD("Create TLV MAC", crypto_binding_tlv, m_is_client);
       
  5344 
       
  5345 	crypto_sha1_c sha1(m_am_tools);
       
  5346 	crypto_hmac_c hmac(m_am_tools, &sha1, false);
       
  5347 
       
  5348 	EAP_TRACE_DATA_DEBUG(
       
  5349 		m_am_tools,
       
  5350 		TRACE_FLAGS_DEFAULT,
       
  5351 		(EAPL("TLV MAC key CMK"),
       
  5352 		 peap_v2_CMK->get_data(peap_v2_CMK->get_data_length()),
       
  5353 		 peap_v2_CMK->get_data_length()));
       
  5354 
       
  5355 	status = hmac.hmac_set_key(peap_v2_CMK);
       
  5356 	if (status != eap_status_ok)
       
  5357 	{
       
  5358 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5359 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5360 	}
       
  5361 
       
  5362 	if (hmac.get_is_valid() == false)
       
  5363 	{
       
  5364 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5365 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  5366 	}
       
  5367 
       
  5368 	EAP_TRACE_DATA_DEBUG(
       
  5369 		m_am_tools,
       
  5370 		TRACE_FLAGS_DEFAULT,
       
  5371 		(EAPL("TLV MAC data"),
       
  5372 		crypto_binding_tlv->get_header_buffer(
       
  5373 			crypto_binding_tlv->get_header_length()
       
  5374 			+ crypto_binding_tlv->get_data_length()),
       
  5375 		crypto_binding_tlv->get_header_length()
       
  5376 		+ crypto_binding_tlv->get_data_length()));
       
  5377 
       
  5378 	status = hmac.hmac_update(
       
  5379 		crypto_binding_tlv->get_header_buffer(
       
  5380 			crypto_binding_tlv->get_header_length()
       
  5381 			+ crypto_binding_tlv->get_data_length()),
       
  5382 		crypto_binding_tlv->get_header_length()
       
  5383 		+ crypto_binding_tlv->get_data_length());
       
  5384 	if (status != eap_status_ok)
       
  5385 	{
       
  5386 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5387 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5388 	}
       
  5389 
       
  5390 	status = mac_data->set_buffer_length(hmac.get_digest_length());
       
  5391 	if (status != eap_status_ok)
       
  5392 	{
       
  5393 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5394 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5395 	}
       
  5396 	mac_data->set_data_length(hmac.get_digest_length());
       
  5397 		
       
  5398 	u32_t mac_length = hmac.get_digest_length();
       
  5399 
       
  5400 	status = hmac.hmac_final(
       
  5401 		mac_data->get_data(mac_data->get_data_length()),
       
  5402 		&mac_length);
       
  5403 	if (status != eap_status_ok)
       
  5404 	{
       
  5405 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5406 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5407 	}
       
  5408 	else if (mac_length != hmac.get_digest_length())
       
  5409 	{
       
  5410 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5411 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5412 	}
       
  5413 
       
  5414 	EAP_TRACE_DATA_DEBUG(
       
  5415 		m_am_tools,
       
  5416 		TRACE_FLAGS_DEFAULT,
       
  5417 		(EAPL("PEAPv2 Compound MAC"),
       
  5418 		 mac_data->get_data(mac_data->get_data_length()),
       
  5419 		 mac_data->get_data_length()));
       
  5420 
       
  5421 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5422 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5423 }
       
  5424 
       
  5425 //--------------------------------------------------
       
  5426 
       
  5427 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_send(
       
  5428 	const eap_am_network_id_c * const /*network_id*/,
       
  5429 	eap_buf_chain_wr_c * const sent_packet,
       
  5430 	const u32_t header_offset,
       
  5431 	const u32_t data_length,
       
  5432 	const u32_t buffer_length)
       
  5433 {
       
  5434 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5435 
       
  5436 	EAP_TRACE_DEBUG(
       
  5437 		m_am_tools,
       
  5438 		TRACE_FLAGS_DEFAULT,
       
  5439 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::packet_send(): ")
       
  5440 		 EAPL("this = 0x%08x\n"),
       
  5441 		 (m_is_client == true ? "client": "server"),
       
  5442 		 this));
       
  5443 
       
  5444 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_send()");
       
  5445 
       
  5446 	eap_buf_chain_wr_c * forwarded_packet = sent_packet;
       
  5447 	u32_t forwarded_data_length = data_length;
       
  5448 	u32_t forwarded_buffer_length = buffer_length;
       
  5449 	u32_t forwaded_header_offset = header_offset;
       
  5450 
       
  5451 	eap_status_e status = eap_status_process_general_error;
       
  5452 
       
  5453 	eap_buf_chain_wr_c tmp_packet(
       
  5454 		eap_write_buffer,
       
  5455 		m_am_tools);
       
  5456 	if (tmp_packet.get_is_valid() == false)
       
  5457 	{
       
  5458 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5459 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5460 	}
       
  5461 
       
  5462 	const u32_t eap_packet_length = sent_packet->get_data_length();
       
  5463 
       
  5464 	eap_header_wr_c sent_eap_packet(
       
  5465 		m_am_tools,
       
  5466 		sent_packet->get_data(eap_packet_length),
       
  5467 		eap_packet_length);
       
  5468 	if (sent_eap_packet.get_is_valid() == false)
       
  5469 	{
       
  5470 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5471 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5472 	}
       
  5473 
       
  5474 
       
  5475 	if (m_is_client == true)
       
  5476 	{
       
  5477 		trace_tunneled_packet(EAPL("<- TUNNELED packet client"), &sent_eap_packet);
       
  5478 	}
       
  5479 	else
       
  5480 	{
       
  5481 		trace_tunneled_packet(EAPL("<- TUNNELED packet server"), &sent_eap_packet);
       
  5482 	}
       
  5483 
       
  5484 
       
  5485 	if (m_eap_type == eap_type_peap)
       
  5486 	{
       
  5487 		if (m_peap_version == peap_version_0_xp)
       
  5488 		{
       
  5489 			// XP PEAP does not include EAP-header (code, identifier and length).
       
  5490 			// Here we must remove those attributes.
       
  5491 			// See draft-kamath-pppext-peapv0-00.txt.
       
  5492 
       
  5493 			if (sent_eap_packet.get_code() == eap_code_request
       
  5494 				|| sent_eap_packet.get_code() == eap_code_response)
       
  5495 			{
       
  5496 				forwaded_header_offset += eap_header_base_c::get_header_length();
       
  5497 			}
       
  5498 			else if (sent_eap_packet.get_code() == eap_code_success
       
  5499 				|| sent_eap_packet.get_code() == eap_code_failure)
       
  5500 			{
       
  5501 				if (m_is_client == true)
       
  5502 				{
       
  5503 					// Client does not send these packets.
       
  5504 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5505 					return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5506 				}
       
  5507 
       
  5508 				// XP PEAPv0 does not include EAP-header (code, identifier and length).
       
  5509 				// Here we must create those attributes.
       
  5510 				// Exception to this rule is, EAP-success and EAP-failure are sent in "Extensions Request Packet"
       
  5511 				// or "Extensions Response Packet".
       
  5512 				// The whole EAP-header is included
       
  5513 				// to "Extensions Request Packet" and "Extensions Response Packet".
       
  5514 				// See draft-kamath-pppext-peapv0-00.txt.
       
  5515 				// 
       
  5516 				// EAP-packet without code, identifier and length:
       
  5517 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5518 				// |  EAP-type     |  EAP-data ...                                                                  
       
  5519 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5520 				// EAP-packet with "Extensions Request Packet" or "Extensions Response Packet":
       
  5521 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5522 				// |  EAP-code     |EAP-identifier | EAP-length                    | EAP-type      |  EAP-data ...  
       
  5523 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5524 				// 
       
  5525 				// EAP-code of "Extensions Request Packet" is 1 which is same as EAP-type of EAP-identity.
       
  5526 				// EAP-code of "Extensions Response Packet" is 2 which is same as EAP-type of EAP-notification.
       
  5527 
       
  5528 				u8_t send_eap_identifier = sent_eap_packet.get_identifier();
       
  5529 				if (m_is_client == false)
       
  5530 				{
       
  5531 					++send_eap_identifier;
       
  5532 				}
       
  5533 
       
  5534 				status = create_result_tlv_message(
       
  5535 					&tmp_packet,
       
  5536 					sent_eap_packet.get_code(),
       
  5537 					send_eap_identifier,
       
  5538 					tls_peap_tlv_type_result);
       
  5539 				if (status != eap_status_ok)
       
  5540 				{
       
  5541 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5542 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5543 				}
       
  5544 
       
  5545 				forwarded_packet = &tmp_packet;
       
  5546 
       
  5547 				forwarded_data_length = tmp_packet.get_data_length();
       
  5548 				forwarded_buffer_length = tmp_packet.get_buffer_length();
       
  5549 				forwaded_header_offset = 0;
       
  5550 
       
  5551 				eap_header_string_c eap_string;
       
  5552 				EAP_UNREFERENCED_PARAMETER(eap_string);
       
  5553 
       
  5554 				EAP_TRACE_ALWAYS(
       
  5555 					m_am_tools, 
       
  5556 					TRACE_FLAGS_DEFAULT, 
       
  5557 					(EAPL("packet_send(): XP-PEAPv0 tunneled %s send.\n"),
       
  5558 					 eap_string.get_eap_code_string(sent_eap_packet.get_code())));
       
  5559 			}
       
  5560 		}
       
  5561 		else if (m_peap_version == peap_version_1)
       
  5562 		{
       
  5563 			// This version does not change packet.
       
  5564 
       
  5565 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  5566 			if (m_is_client == false
       
  5567 				&& m_server_use_peapv1_extensions_request == true
       
  5568 				&& (sent_eap_packet.get_code() == eap_code_success
       
  5569 					|| sent_eap_packet.get_code() == eap_code_failure))
       
  5570 			{
       
  5571 				u8_t send_eap_identifier = sent_eap_packet.get_identifier();
       
  5572 				if (m_is_client == false)
       
  5573 				{
       
  5574 					++send_eap_identifier;
       
  5575 				}
       
  5576 
       
  5577 				status = create_result_tlv_message(
       
  5578 					&tmp_packet,
       
  5579 					sent_eap_packet.get_code(),
       
  5580 					send_eap_identifier,
       
  5581 					tls_peap_tlv_type_result);
       
  5582 				if (status != eap_status_ok)
       
  5583 				{
       
  5584 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5585 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5586 				}
       
  5587 
       
  5588 				forwarded_packet = &tmp_packet;
       
  5589 
       
  5590 				forwarded_data_length = tmp_packet.get_data_length();
       
  5591 				forwarded_buffer_length = tmp_packet.get_buffer_length();
       
  5592 				forwaded_header_offset = 0;
       
  5593 
       
  5594 				eap_header_string_c eap_string;
       
  5595 				EAP_UNREFERENCED_PARAMETER(eap_string);
       
  5596 
       
  5597 				EAP_TRACE_ALWAYS(
       
  5598 					m_am_tools, 
       
  5599 					TRACE_FLAGS_DEFAULT, 
       
  5600 					(EAPL("packet_send(): PEAPv1 tunneled %s send.\n"),
       
  5601 					 eap_string.get_eap_code_string(sent_eap_packet.get_code())));
       
  5602 			}
       
  5603 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  5604 
       
  5605 		}
       
  5606 		else if (m_peap_version == peap_version_2)
       
  5607 		{
       
  5608 			if (sent_eap_packet.get_code() == eap_code_request
       
  5609 				|| sent_eap_packet.get_code() == eap_code_response)
       
  5610 			{
       
  5611 				// These packets are encapsulated to EAP-TLV packet.
       
  5612 				//  0                   1                   2                   3
       
  5613 				//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  5614 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5615 				// |     Code      |   Identifier  |            Length             |
       
  5616 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5617 				// |     Type      |                  Data....
       
  5618 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5619 				// 
       
  5620 				// Data includes EAP-Payload TLV:
       
  5621 				//  0                   1                   2                   3
       
  5622 				//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  5623 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5624 				// |M|R|         TLV Type          |            Length             |
       
  5625 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5626 				// |                          EAP packet...
       
  5627 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5628 				// |                             TLVs...
       
  5629 				// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5630 
       
  5631 				status = create_eap_payload_tlv_message(
       
  5632 					&tmp_packet,
       
  5633 					&sent_eap_packet,
       
  5634 					sent_eap_packet.get_identifier());
       
  5635 				if (status != eap_status_ok)
       
  5636 				{
       
  5637 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5638 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5639 				}
       
  5640 
       
  5641 				forwarded_packet = &tmp_packet;
       
  5642 
       
  5643 				forwarded_data_length = tmp_packet.get_data_length();
       
  5644 				forwarded_buffer_length = tmp_packet.get_buffer_length();
       
  5645 				forwaded_header_offset = 0;
       
  5646 			}
       
  5647 			else if (sent_eap_packet.get_code() == eap_code_success
       
  5648 				|| sent_eap_packet.get_code() == eap_code_failure)
       
  5649 			{
       
  5650 				if (m_is_client == true)
       
  5651 				{
       
  5652 					// Client does not send these packets.
       
  5653 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5654 					return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5655 				}
       
  5656 
       
  5657 				// Server blocks the EAP-Success packet.
       
  5658 				// Result TLV, Crypto Binding TLV and Intermediate Result TLV
       
  5659 				// are created and sent within the state_notification() function
       
  5660 				// by the send_tunneled_acknowledge_peap_v2() function
       
  5661 				// when eap_state_authentication_finished_successfully or
       
  5662 				// eap_state_authentication_terminated_unsuccessfully indication
       
  5663 				// is received.
       
  5664 				EAP_TRACE_DEBUG(
       
  5665 					m_am_tools,
       
  5666 					TRACE_FLAGS_DEFAULT,
       
  5667 					(EAPL("TLS: %s: message_function: tls_application_eap_core_c::")
       
  5668 					 EAPL("packet_send(), server blocks tunneled EAP-Success and EAP-Failure\n"),
       
  5669 					(m_is_client == true ? "client": "server")));
       
  5670 
       
  5671 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5672 				return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5673 
       
  5674 			}
       
  5675 		}
       
  5676 		else
       
  5677 		{
       
  5678 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5679 			return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  5680 		}
       
  5681 	}
       
  5682 	else if (m_eap_type == eap_type_ttls)
       
  5683 	{
       
  5684 
       
  5685 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  5686 		if (m_tunneled_eap_in_ttls == true)
       
  5687 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  5688 		{
       
  5689 			// These packets are encapsulated to AVP.
       
  5690 			//  0                   1                   2                   3   
       
  5691 			//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
  5692 			// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5693 			// |                           AVP Code                            |
       
  5694 			// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5695 			// |V|M|r r r r r r|                  AVP Length                   |
       
  5696 			// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5697 			// |                      Vendor-ID (optional)                     |
       
  5698 			// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5699 			// |                   Data includes EAP-packet ...
       
  5700 			// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  5701 
       
  5702 			if (sent_eap_packet.get_code() == eap_code_success
       
  5703 				|| sent_eap_packet.get_code() == eap_code_failure)
       
  5704 			{
       
  5705 				if (m_is_client == true)
       
  5706 				{
       
  5707 					// Client does not send these packets.
       
  5708 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5709 					return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  5710 				}
       
  5711 
       
  5712 				// Server blocks the tunneled EAP-Success packet.
       
  5713 				EAP_TRACE_DEBUG(
       
  5714 					m_am_tools,
       
  5715 					TRACE_FLAGS_DEFAULT,
       
  5716 					(EAPL("TLS: %s: message_function: tls_application_eap_core_c::")
       
  5717 					 EAPL("packet_send(), server blocks tunneled EAP-Success and EAP-Failure\n"),
       
  5718 					(m_is_client == true ? "client": "server")));
       
  5719 
       
  5720 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5721 				return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5722 
       
  5723 			}
       
  5724 			else
       
  5725 			{
       
  5726 				status = create_eap_diameter_avp_message(
       
  5727 					&tmp_packet,
       
  5728 					&sent_eap_packet,
       
  5729 					sent_eap_packet.get_identifier());
       
  5730 				if (status != eap_status_ok)
       
  5731 				{
       
  5732 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5733 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  5734 				}
       
  5735 				
       
  5736 				forwarded_packet = &tmp_packet;
       
  5737 				
       
  5738 				forwarded_data_length = tmp_packet.get_data_length();
       
  5739 				forwarded_buffer_length = tmp_packet.get_buffer_length();
       
  5740 				forwaded_header_offset = 0;
       
  5741 			}
       
  5742 		}
       
  5743 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  5744 		else
       
  5745 		{
       
  5746 			// This is plain MsChapv2 tunneled in EAP-TTLS.
       
  5747 			status = send_ttls_ms_chapv2_packet(&sent_eap_packet);
       
  5748 
       
  5749 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5750 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5751 		}
       
  5752 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  5753 
       
  5754 	}
       
  5755 	else
       
  5756 	{
       
  5757 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5758 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  5759 	}
       
  5760 
       
  5761 
       
  5762 	EAP_TRACE_DATA_DEBUG(
       
  5763 		m_am_tools,
       
  5764 		TRACE_FLAGS_DEFAULT,
       
  5765 		(EAPL("sent tunneled data:"),
       
  5766 		 forwarded_packet->get_data_offset(
       
  5767 			 forwaded_header_offset,
       
  5768 			 forwarded_packet->get_data_length()-forwaded_header_offset),
       
  5769 		 forwarded_packet->get_data_length()-forwaded_header_offset));
       
  5770 
       
  5771 
       
  5772 #if defined(USE_EAP_ERROR_TESTS)
       
  5773 	if (m_enable_random_errors == true
       
  5774 		&& m_manipulate_only_tunneled_messages == true)
       
  5775 	{
       
  5776 		status = m_am_tools->generate_random_error(
       
  5777 			forwarded_packet,
       
  5778 			false,
       
  5779 			m_am_tools->get_packet_index(),
       
  5780 			0UL,
       
  5781 			m_error_probability,
       
  5782 			0UL);
       
  5783 		if (status != eap_status_ok)
       
  5784 		{
       
  5785 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5786 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5787 		}
       
  5788 	}
       
  5789 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  5790 
       
  5791 
       
  5792 	status = get_application_partner()->packet_send(
       
  5793 		forwarded_packet,
       
  5794 		forwaded_header_offset,
       
  5795 		forwarded_data_length,
       
  5796 		forwarded_buffer_length);
       
  5797 
       
  5798 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5799 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5800 }
       
  5801 
       
  5802 //--------------------------------------------------
       
  5803 
       
  5804 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0(
       
  5805 	const eap_code_value_e result_eap_code,
       
  5806 	const u8_t eap_identifier)
       
  5807 {
       
  5808 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5809 
       
  5810 	EAP_TRACE_DEBUG(
       
  5811 		m_am_tools,
       
  5812 		TRACE_FLAGS_DEFAULT,
       
  5813 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0(): ")
       
  5814 		 EAPL("this = 0x%08x\n"),
       
  5815 		 (m_is_client == true ? "client": "server"),
       
  5816 		 this));
       
  5817 
       
  5818 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0()");
       
  5819 
       
  5820 	eap_buf_chain_wr_c eap_ack_packet(
       
  5821 		eap_write_buffer, 
       
  5822 		m_am_tools);
       
  5823 
       
  5824 	if (eap_ack_packet.get_is_valid() == false)
       
  5825 	{
       
  5826 		EAP_TRACE_ERROR(
       
  5827 			m_am_tools,
       
  5828 			TRACE_FLAGS_DEFAULT,
       
  5829 			(EAPL("tls_application_eap_core_c::send_tunneled_acknowledge_xp_peap_v0(): ")
       
  5830 			 EAPL("packet buffer corrupted.\n")));
       
  5831 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5832 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5833 	}
       
  5834 
       
  5835 	eap_status_e status = create_result_tlv_message(
       
  5836 		&eap_ack_packet,
       
  5837 		result_eap_code,
       
  5838 		eap_identifier,
       
  5839 		tls_peap_tlv_type_result);
       
  5840 
       
  5841 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5842 
       
  5843 	eap_header_string_c eap_string;
       
  5844 	EAP_UNREFERENCED_PARAMETER(eap_string);
       
  5845 
       
  5846 	EAP_TRACE_ALWAYS(
       
  5847 		m_am_tools, 
       
  5848 		TRACE_FLAGS_DEFAULT, 
       
  5849 		(EAPL("send_tunneled_acknowledge_xp_peap_v0(): XP-PEAPv0 tunneled %s acknowledge send.\n"),
       
  5850 		 eap_string.get_eap_code_string(result_eap_code)));
       
  5851 
       
  5852 	EAP_TRACE_DATA_ALWAYS(
       
  5853 		m_am_tools,
       
  5854 		TRACE_FLAGS_DEFAULT,
       
  5855 		(EAPL("    send: XP-PEAPv0 EAP acknowledge packet"),
       
  5856 		eap_ack_packet.get_data(eap_ack_packet.get_data_length()),
       
  5857 		eap_ack_packet.get_data_length()));
       
  5858 
       
  5859 
       
  5860 #if defined(USE_EAP_ERROR_TESTS)
       
  5861 	if (m_enable_random_errors == true
       
  5862 		&& m_manipulate_only_tunneled_messages == true)
       
  5863 	{
       
  5864 		status = m_am_tools->generate_random_error(
       
  5865 			&eap_ack_packet,
       
  5866 			false,
       
  5867 			m_am_tools->get_packet_index(),
       
  5868 			0UL,
       
  5869 			m_error_probability,
       
  5870 			0UL);
       
  5871 		if (status != eap_status_ok)
       
  5872 		{
       
  5873 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5874 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5875 		}
       
  5876 	}
       
  5877 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  5878 
       
  5879 	status = get_application_partner()->packet_send(
       
  5880 		&eap_ack_packet,
       
  5881 		0ul,
       
  5882 		eap_ack_packet.get_data_length(),
       
  5883 		EAP_CORE_PACKET_BUFFER_LENGTH
       
  5884 		);
       
  5885 
       
  5886 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5887 
       
  5888 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5889 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5890 }
       
  5891 
       
  5892 //--------------------------------------------------
       
  5893 
       
  5894 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2(
       
  5895 	const eap_code_value_e result_eap_code,
       
  5896 	const u8_t eap_identifier)
       
  5897 {
       
  5898 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5899 
       
  5900 	EAP_TRACE_DEBUG(
       
  5901 		m_am_tools,
       
  5902 		TRACE_FLAGS_DEFAULT,
       
  5903 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2()\n"),
       
  5904 		(m_is_client == true ? "client": "server")));
       
  5905 
       
  5906 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2()");
       
  5907 
       
  5908 	eap_variable_data_c *peap_v2_nonce = &m_peap_v2_client_nonce;
       
  5909 	if (m_is_client == false)
       
  5910 	{
       
  5911 		peap_v2_nonce = &m_peap_v2_server_nonce;
       
  5912 	}
       
  5913 
       
  5914 	if (peap_v2_nonce->get_is_valid_data() == false)
       
  5915 	{
       
  5916 		EAP_TRACE_ERROR(
       
  5917 			m_am_tools,
       
  5918 			TRACE_FLAGS_DEFAULT,
       
  5919 			(EAPL("tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2(): ")
       
  5920 			 EAPL("peap_v2_nonce invalid.\n")));
       
  5921 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5922 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5923 	}
       
  5924 
       
  5925 	eap_buf_chain_wr_c eap_ack_packet(
       
  5926 		eap_write_buffer, 
       
  5927 		m_am_tools);
       
  5928 
       
  5929 	if (eap_ack_packet.get_is_valid() == false)
       
  5930 	{
       
  5931 		EAP_TRACE_ERROR(
       
  5932 			m_am_tools,
       
  5933 			TRACE_FLAGS_DEFAULT,
       
  5934 			(EAPL("tls_application_eap_core_c::send_tunneled_acknowledge_peap_v2(): ")
       
  5935 			 EAPL("packet buffer corrupted.\n")));
       
  5936 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5937 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5938 	}
       
  5939 
       
  5940 	eap_status_e status = create_crypto_binding_tlv_message(
       
  5941 		&eap_ack_packet,
       
  5942 		result_eap_code,
       
  5943 		eap_identifier,
       
  5944 		peap_v2_nonce,
       
  5945 		static_cast<u8_t>(m_peap_version));
       
  5946 	if (status != eap_status_ok)
       
  5947 	{
       
  5948 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5949 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5950 	}
       
  5951 
       
  5952 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5953 
       
  5954 	eap_header_string_c eap_string;
       
  5955 	EAP_UNREFERENCED_PARAMETER(eap_string);
       
  5956 
       
  5957 	EAP_TRACE_ALWAYS(
       
  5958 		m_am_tools, 
       
  5959 		TRACE_FLAGS_DEFAULT, 
       
  5960 		(EAPL("send_tunneled_acknowledge_peap_v2(): PEAPv2 tunneled %s acknowledge send.\n"),
       
  5961 		 eap_string.get_eap_code_string(result_eap_code)));
       
  5962 
       
  5963 	EAP_TRACE_DATA_ALWAYS(
       
  5964 		m_am_tools,
       
  5965 		TRACE_FLAGS_DEFAULT,
       
  5966 		(EAPL("    send: PEAPv2 EAP acknowledge packet"),
       
  5967 		eap_ack_packet.get_data(eap_ack_packet.get_data_length()),
       
  5968 		eap_ack_packet.get_data_length()));
       
  5969 
       
  5970 #if defined(USE_EAP_ERROR_TESTS)
       
  5971 	if (m_enable_random_errors == true
       
  5972 		&& m_manipulate_only_tunneled_messages == true)
       
  5973 	{
       
  5974 		status = m_am_tools->generate_random_error(
       
  5975 			&eap_ack_packet,
       
  5976 			false,
       
  5977 			m_am_tools->get_packet_index(),
       
  5978 			0UL,
       
  5979 			m_error_probability,
       
  5980 			0UL);
       
  5981 		if (status != eap_status_ok)
       
  5982 		{
       
  5983 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5984 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5985 		}
       
  5986 	}
       
  5987 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  5988 
       
  5989 	status = get_application_partner()->packet_send(
       
  5990 		&eap_ack_packet,
       
  5991 		0ul,
       
  5992 		eap_ack_packet.get_data_length(),
       
  5993 		EAP_CORE_PACKET_BUFFER_LENGTH
       
  5994 		);
       
  5995 
       
  5996 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  5997 
       
  5998 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5999 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6000 }
       
  6001 
       
  6002 //--------------------------------------------------
       
  6003 
       
  6004 EAP_FUNC_EXPORT u32_t tls_application_eap_core_c::get_header_offset(
       
  6005 	u32_t * const MTU,
       
  6006 	u32_t * const trailer_length)
       
  6007 {
       
  6008 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6009 
       
  6010 	u32_t offset = get_application_partner()->get_header_offset(
       
  6011 		MTU,
       
  6012 		trailer_length);
       
  6013 
       
  6014 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6015 	return offset;
       
  6016 }
       
  6017 
       
  6018 //--------------------------------------------------
       
  6019 
       
  6020 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::load_module(
       
  6021 	const eap_type_value_e type,
       
  6022 	const eap_type_value_e tunneling_type,
       
  6023 	abs_eap_base_type_c * const partner,
       
  6024 	eap_base_type_c ** const eap_type,
       
  6025 	const bool is_client_when_true,
       
  6026 	const eap_am_network_id_c * const receive_network_id)
       
  6027 {
       
  6028 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6029 
       
  6030 	if (tunneling_type != eap_type_none)
       
  6031 	{
       
  6032 		EAP_TRACE_ERROR(
       
  6033 			m_am_tools,
       
  6034 			TRACE_FLAGS_DEFAULT,
       
  6035 			(EAPL("TLS: %s: message_function: tls_application_eap_core_c::load_module(), ")
       
  6036 			 EAPL("tunneling_type is not eap_type_none, it is 0x%08x=%s\n"),
       
  6037 			(m_is_client == true ? "client": "server"),
       
  6038 			convert_eap_type_to_u32_t(tunneling_type),
       
  6039 			eap_header_string_c::get_eap_type_string(tunneling_type)));
       
  6040 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6041 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  6042 	}
       
  6043 
       
  6044 	eap_status_e status = get_application_partner()->load_module(
       
  6045 		type,
       
  6046 		m_eap_type, // This is the tunneling EAP-type.
       
  6047 		partner,
       
  6048 		eap_type,
       
  6049 		is_client_when_true,
       
  6050 		receive_network_id);
       
  6051 
       
  6052 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6053 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6054 }
       
  6055 
       
  6056 //--------------------------------------------------
       
  6057 
       
  6058 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::unload_module(
       
  6059 	const eap_type_value_e type)
       
  6060 {
       
  6061 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6062 
       
  6063 	eap_status_e status = get_application_partner()->unload_module(
       
  6064 		type);
       
  6065 
       
  6066 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6067 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6068 }
       
  6069 
       
  6070 //--------------------------------------------------
       
  6071 
       
  6072 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::peap_tunnel_ready()
       
  6073 {
       
  6074 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6075 
       
  6076 	EAP_TRACE_DEBUG(
       
  6077 		m_am_tools,
       
  6078 		TRACE_FLAGS_DEFAULT,
       
  6079 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::peap_tunnel_ready()\n"),
       
  6080 		(m_is_client == true ? "client": "server")));
       
  6081 
       
  6082 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::peap_tunnel_ready()");
       
  6083 
       
  6084 	eap_status_e status = eap_status_ok;
       
  6085 
       
  6086 	if (m_peap_version == peap_version_2)
       
  6087 	{
       
  6088 		eap_variable_data_c eap_tls_master_session_key(m_am_tools);
       
  6089 
       
  6090 		status = get_application_partner()->get_eap_tls_master_session_key(
       
  6091 			&eap_tls_master_session_key,
       
  6092 			0);
       
  6093 		if (status != eap_status_ok)
       
  6094 		{
       
  6095 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6096 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6097 		}
       
  6098 
       
  6099 		if (eap_tls_master_session_key.get_data_length()
       
  6100 			< TLS_PEAP_V2_TK_OFFSET + TLS_PEAP_V2_TK_LENGTH)
       
  6101 		{
       
  6102 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6103 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_encryption_parameter_size);
       
  6104 		}
       
  6105 
       
  6106 		status = m_peap_v2_IPMKn.set_copy_of_buffer(
       
  6107 			eap_tls_master_session_key.get_data_offset(
       
  6108 				TLS_PEAP_V2_TK_OFFSET, TLS_PEAP_V2_TK_LENGTH),
       
  6109 			TLS_PEAP_V2_TK_LENGTH);
       
  6110 		if (status != eap_status_ok)
       
  6111 		{
       
  6112 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6113 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6114 		}
       
  6115 	}
       
  6116 
       
  6117 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6118 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6119 }
       
  6120 
       
  6121 //--------------------------------------------------
       
  6122 
       
  6123 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::start_peap_tunneled_authentication(
       
  6124 	const eap_am_network_id_c * const receive_network_id,
       
  6125 	const bool is_client_when_true,
       
  6126 	const u8_t received_eap_identifier,
       
  6127 	const tls_session_type_e tls_session_type,
       
  6128 	const bool /* tls_peap_server_authenticates_client_action */)
       
  6129 {
       
  6130 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6131 
       
  6132 	EAP_TRACE_DEBUG(
       
  6133 		m_am_tools,
       
  6134 		TRACE_FLAGS_DEFAULT,
       
  6135 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::start_peap_tunneled_authentication(): ")
       
  6136 		 EAPL("this = 0x%08x\n"),
       
  6137 		 (m_is_client == true ? "client": "server"),
       
  6138 		 this));
       
  6139 
       
  6140 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::start_peap_tunneled_authentication()");
       
  6141 
       
  6142 	eap_status_e status = eap_status_process_general_error;
       
  6143 
       
  6144 
       
  6145 #if defined(USE_EAP_CORE_SERVER)
       
  6146 
       
  6147 	if (m_is_client == false)
       
  6148 	{
       
  6149 		// Server
       
  6150 
       
  6151 		if (m_eap_type == eap_type_peap
       
  6152 			&& (tls_session_type == tls_session_type_original_session_resumption
       
  6153 				|| tls_session_type == tls_session_type_stateless_session_resumption)
       
  6154 			&& m_peap_allow_tunneled_session_resumption == true
       
  6155 #if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  6156 			&& m_peap_version == peap_version_0_xp
       
  6157 #endif //#if !defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  6158 			)
       
  6159 		{
       
  6160 			if (m_peap_version == peap_version_0_xp)
       
  6161 			{
       
  6162 				if (is_client_when_true == false)
       
  6163 				{
       
  6164 					// Server sends tunneled EAP-Success.
       
  6165 
       
  6166 					eap_buf_chain_wr_c forwarded_packet(
       
  6167 						eap_write_buffer,
       
  6168 						m_am_tools);
       
  6169 					if (forwarded_packet.get_is_valid() == false)
       
  6170 					{
       
  6171 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6172 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6173 					}
       
  6174 
       
  6175 					status = create_result_tlv_message(
       
  6176 						&forwarded_packet,
       
  6177 						eap_code_success,
       
  6178 						static_cast<u8_t>(received_eap_identifier+1ul),
       
  6179 						tls_peap_tlv_type_result);
       
  6180 					if (status != eap_status_ok)
       
  6181 					{
       
  6182 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6183 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  6184 					}
       
  6185 
       
  6186 					u32_t forwarded_data_length = forwarded_packet.get_data_length();
       
  6187 					u32_t forwarded_buffer_length = forwarded_packet.get_buffer_length();
       
  6188 					u32_t forwaded_header_offset = 0;
       
  6189 
       
  6190 					eap_header_string_c eap_string;
       
  6191 					EAP_UNREFERENCED_PARAMETER(eap_string);
       
  6192 
       
  6193 					EAP_TRACE_ALWAYS(
       
  6194 						m_am_tools, 
       
  6195 						TRACE_FLAGS_DEFAULT, 
       
  6196 						(EAPL("packet_send(): XP-PEAPv0 tunneled %s send.\n"),
       
  6197 						 eap_string.get_eap_code_string(eap_code_success)));
       
  6198 
       
  6199 #if defined(USE_EAP_ERROR_TESTS)
       
  6200 					if (m_enable_random_errors == true
       
  6201 						&& m_manipulate_only_tunneled_messages == true)
       
  6202 					{
       
  6203 						status = m_am_tools->generate_random_error(
       
  6204 							&forwarded_packet,
       
  6205 							false,
       
  6206 							m_am_tools->get_packet_index(),
       
  6207 							0UL,
       
  6208 							m_error_probability,
       
  6209 							0UL);
       
  6210 						if (status != eap_status_ok)
       
  6211 						{
       
  6212 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6213 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  6214 						}
       
  6215 					}
       
  6216 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  6217 
       
  6218 
       
  6219 					status = get_application_partner()->packet_send(
       
  6220 						&forwarded_packet,
       
  6221 						forwaded_header_offset,
       
  6222 						forwarded_data_length,
       
  6223 						forwarded_buffer_length);
       
  6224 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  6225 					if (status != eap_status_ok)
       
  6226 					{
       
  6227 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6228 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  6229 					}
       
  6230 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  6231 				}
       
  6232 			}
       
  6233 			else if (m_peap_version == peap_version_1)
       
  6234 			{
       
  6235 
       
  6236 #if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  6237 
       
  6238 				// Send tunneled EAP-Success.
       
  6239 				// This will tell client the tunneled
       
  6240 				// EAP-session was also restored.
       
  6241 
       
  6242 				// Here we swap the addresses.
       
  6243 				eap_am_network_id_c send_network_id(
       
  6244 					m_am_tools,
       
  6245 					receive_network_id->get_destination_id(),
       
  6246 					receive_network_id->get_source_id(),
       
  6247 					receive_network_id->get_type());
       
  6248 
       
  6249 				if (m_use_tppd_tls_peap == true
       
  6250 					&& m_use_tppd_peapv1_acknowledge_hack == true)
       
  6251 				{
       
  6252 					// This case does not send tunneled EAP-Success
       
  6253 					// instead it sends plain EAP-Success.
       
  6254 
       
  6255 					m_tunneled_eap_type_authentication_state
       
  6256 						= eap_state_authentication_wait_tppd_peapv1_empty_acknowledge;
       
  6257 
       
  6258 					eap_state_notification_c notification(
       
  6259 						m_am_tools,
       
  6260 						&send_network_id,
       
  6261 						m_is_client,
       
  6262 						eap_state_notification_eap,
       
  6263 						eap_protocol_layer_eap,
       
  6264 						m_eap_type,
       
  6265 						eap_state_none,
       
  6266 						m_tunneled_eap_type_authentication_state,
       
  6267 						received_eap_identifier,
       
  6268 						true);
       
  6269 					get_application_partner()->state_notification(&notification);
       
  6270 
       
  6271 					status = eap_status_ok;
       
  6272 				}
       
  6273 				else
       
  6274 				{
       
  6275 					if (m_eap_core == 0)
       
  6276 					{
       
  6277 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6278 						return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  6279 					}
       
  6280 
       
  6281 					status = m_eap_core->send_eap_success(
       
  6282 						&send_network_id,
       
  6283 						received_eap_identifier);
       
  6284 					if (status != eap_status_ok)
       
  6285 					{
       
  6286 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6287 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  6288 					}
       
  6289 
       
  6290 					m_tunneled_eap_type_authentication_state
       
  6291 						= eap_state_authentication_finished_successfully;
       
  6292 
       
  6293 					eap_state_notification_c notification(
       
  6294 						m_am_tools,
       
  6295 						&send_network_id,
       
  6296 						m_is_client,
       
  6297 						eap_state_notification_eap,
       
  6298 						eap_protocol_layer_eap,
       
  6299 						m_peap_tunneled_eap_type,
       
  6300 						eap_state_none,
       
  6301 						m_tunneled_eap_type_authentication_state,
       
  6302 						received_eap_identifier,
       
  6303 						false);
       
  6304 					get_application_partner()->state_notification(&notification);
       
  6305 
       
  6306 					status = eap_status_success;
       
  6307 				}
       
  6308 
       
  6309 #else
       
  6310 
       
  6311 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6312 				return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  6313 
       
  6314 #endif //#if defined(USE_EAP_TLS_PEAP_TPPD_PEAP_V1_NEW_FIXES)
       
  6315 
       
  6316 			}
       
  6317 			else if (m_peap_version == peap_version_2)
       
  6318 			{
       
  6319 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6320 				return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  6321 			}
       
  6322 		}
       
  6323 		else
       
  6324 		{
       
  6325 			if (m_eap_core == 0)
       
  6326 			{
       
  6327 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6328 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  6329 			}
       
  6330 
       
  6331 			status = m_eap_core->send_eap_identity_request(
       
  6332 				receive_network_id);
       
  6333 		}
       
  6334 	}
       
  6335 	else
       
  6336 #endif //#if defined(USE_EAP_CORE_SERVER)
       
  6337 	{
       
  6338 		// Client
       
  6339 
       
  6340 		status = eap_status_ok;
       
  6341 	}
       
  6342 
       
  6343 
       
  6344 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6345 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6346 }
       
  6347 
       
  6348 //--------------------------------------------------
       
  6349 
       
  6350 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::restart_authentication(
       
  6351 	const eap_am_network_id_c * const /*receive_network_id*/,
       
  6352 	const bool /*is_client_when_true*/,
       
  6353 	const bool /*force_clean_restart*/,
       
  6354 	const bool /*from_timer*/)
       
  6355 {
       
  6356 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6357 
       
  6358 	// NOTE, we do not allow tunneled EAP-type restart authentication.
       
  6359 	eap_status_e status = eap_status_ok;
       
  6360 
       
  6361 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6362 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6363 }
       
  6364 
       
  6365 //--------------------------------------------------
       
  6366 
       
  6367 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::packet_data_crypto_keys(
       
  6368 	const eap_am_network_id_c * const /*send_network_id*/,
       
  6369 	const eap_master_session_key_c * const master_session_key
       
  6370 	)
       
  6371 {
       
  6372 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6373 
       
  6374 	EAP_TRACE_DEBUG(
       
  6375 		m_am_tools,
       
  6376 		TRACE_FLAGS_DEFAULT,
       
  6377 		(EAPL("TLS: %s: message_function: tls_application_eap_core_c::packet_data_crypto_keys()\n"),
       
  6378 		(m_is_client == true ? "client": "server")));
       
  6379 
       
  6380 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::packet_data_crypto_keys()");
       
  6381 
       
  6382 	eap_status_e status = eap_status_process_general_error;
       
  6383 
       
  6384 	if (m_peap_version == peap_version_2)
       
  6385 	{
       
  6386 		status = m_peap_v2_ISKn.set_copy_of_buffer(
       
  6387 			master_session_key);
       
  6388 	}
       
  6389 	else
       
  6390 	{
       
  6391 		// Note older PEAP version does not use keys generated by tunneled EAP-type.
       
  6392 		// This is sad but true.
       
  6393 		status = eap_status_ok;
       
  6394 	}
       
  6395 
       
  6396 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6397 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6398 }
       
  6399 
       
  6400 //--------------------------------------------------
       
  6401 
       
  6402 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::read_configure(
       
  6403 	const eap_configuration_field_c * const field,
       
  6404 	eap_variable_data_c * const data)
       
  6405 {
       
  6406 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6407 
       
  6408 	eap_status_e status = eap_status_process_general_error;
       
  6409 
       
  6410 	if (field == 0
       
  6411 		|| data == 0)
       
  6412 	{
       
  6413 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6414 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  6415 	}
       
  6416 
       
  6417 	if (cf_str_EAP_default_type_hex_data.get_field()->compare(
       
  6418 			m_am_tools,
       
  6419 			field) == true
       
  6420 		|| cf_str_EAP_server_default_type_hex_data.get_field()->compare(
       
  6421 			m_am_tools,
       
  6422 			field) == true)
       
  6423 	{
       
  6424 		eap_type_value_e tunneled_type = m_peap_tunneled_eap_type;
       
  6425 
       
  6426 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  6427 		if (m_tunneled_eap_in_ttls == false
       
  6428 			&& (
       
  6429 #if defined(USE_EAP_EXPANDED_TYPES)
       
  6430 				m_peap_tunneled_eap_type == eap_expanded_type_ttls_plain_mschapv2.get_type()
       
  6431 #else
       
  6432 				m_peap_tunneled_eap_type == eap_type_plain_mschapv2
       
  6433 #endif //#if defined(USE_EAP_EXPANDED_TYPES)
       
  6434 			))
       
  6435 		{
       
  6436 			tunneled_type = eap_type_mschapv2;
       
  6437 		}
       
  6438 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  6439 
       
  6440 		if (field->get_type() == eap_configure_type_u32_t)
       
  6441 		{
       
  6442 			u32_t tunneled_eap_type = convert_eap_type_to_u32_t(tunneled_type);
       
  6443 			status = data->set_copy_of_buffer(&tunneled_eap_type, sizeof(tunneled_eap_type));
       
  6444 		}
       
  6445 		else if (field->get_type() == eap_configure_type_hex_data)
       
  6446 		{
       
  6447 			eap_expanded_type_c default_type(tunneled_type);
       
  6448 			status = default_type.get_expanded_type_data(m_am_tools, data);
       
  6449 		}
       
  6450 		else
       
  6451 		{
       
  6452 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6453 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_type);
       
  6454 		}
       
  6455 
       
  6456 	}
       
  6457 	else if (cf_str_EAP_CORE_retransmission_counter.get_field()->compare(
       
  6458 				 m_am_tools,
       
  6459 				 field) == true)
       
  6460 	{
       
  6461 		// We do not allow inner EAP Core to re-transmit packets.
       
  6462 		u32_t retransmission_counter = 0ul;
       
  6463 		status = data->set_copy_of_buffer(&retransmission_counter, sizeof(retransmission_counter));
       
  6464 	}
       
  6465 	else if (cf_str_EAP_CORE_process_EAP_Nak_immediately.get_field()->compare(
       
  6466 				 m_am_tools,
       
  6467 				 field) == true)
       
  6468 	{
       
  6469 		// We do not allow inner EAP Core to delay EAP-Nak processing.
       
  6470 		u32_t EAP_CORE_process_EAP_Nak_immediately = 1ul; // This is true value.
       
  6471 		status = data->set_copy_of_buffer(
       
  6472 			&EAP_CORE_process_EAP_Nak_immediately,
       
  6473 			sizeof(EAP_CORE_process_EAP_Nak_immediately));
       
  6474 	}
       
  6475 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  6476 	else if (m_tunneled_eap_in_ttls == false
       
  6477 		&& cf_str_EAP_MSCHAPV2_use_implicit_challenge.get_field()->compare(
       
  6478 				 m_am_tools,
       
  6479 				 field) == true)
       
  6480 	{
       
  6481 		u32_t use_implicit_challenge = 1ul;
       
  6482 		status = data->set_copy_of_buffer(&use_implicit_challenge, sizeof(use_implicit_challenge));
       
  6483 	}
       
  6484 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  6485 	else if (m_is_client == false
       
  6486 		&& m_eap_type == eap_type_peap
       
  6487 		&& m_peap_version == peap_version_0_xp
       
  6488 		&& cf_str_EAP_TLS_PEAP_check_identifier_of_eap_identity_response.get_field()->compare(
       
  6489 				 m_am_tools,
       
  6490 				 field) == true)
       
  6491 	{
       
  6492 		// Tunneled type on PEAPv0 server cannot check EAP-Identity exactly.
       
  6493 		u32_t check_identifier_of_eap_identity_response = 0ul;
       
  6494 		status = data->set_copy_of_buffer(&check_identifier_of_eap_identity_response, sizeof(check_identifier_of_eap_identity_response));
       
  6495 	}
       
  6496 	else
       
  6497 	{
       
  6498 		status = get_application_partner()->read_configure(
       
  6499 			field,
       
  6500 			data);
       
  6501 	}
       
  6502 
       
  6503 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6504 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6505 }
       
  6506 
       
  6507 //--------------------------------------------------
       
  6508 
       
  6509 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::write_configure(
       
  6510 	const eap_configuration_field_c * const field,
       
  6511 	eap_variable_data_c * const data)
       
  6512 {
       
  6513 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6514 
       
  6515 	eap_status_e status = get_application_partner()->write_configure(
       
  6516 		field,
       
  6517 		data);
       
  6518 
       
  6519 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6520 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6521 }
       
  6522 
       
  6523 //--------------------------------------------------
       
  6524 
       
  6525 EAP_FUNC_EXPORT void tls_application_eap_core_c::set_tunneled_state(
       
  6526 	const tls_session_type_e tls_session_type)
       
  6527 {
       
  6528 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6529 
       
  6530 	EAP_TRACE_DEBUG(
       
  6531 		m_am_tools,
       
  6532 		TRACE_FLAGS_DEFAULT,
       
  6533 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::set_tunneled_state(): ")
       
  6534 		 EAPL("this = 0x%08x\n"),
       
  6535 		 (m_is_client == true ? "client": "server"),
       
  6536 		 this));
       
  6537 
       
  6538 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_tunneled_state()");
       
  6539 
       
  6540 	m_tls_session_type = tls_session_type;
       
  6541 
       
  6542 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6543 }
       
  6544 
       
  6545 //--------------------------------------------------
       
  6546 
       
  6547 EAP_FUNC_EXPORT void tls_application_eap_core_c::state_notification(
       
  6548 	const abs_eap_state_notification_c * const state)
       
  6549 {
       
  6550 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6551 
       
  6552 	EAP_TRACE_DEBUG(
       
  6553 		m_am_tools,
       
  6554 		TRACE_FLAGS_DEFAULT,
       
  6555 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): notification state=%s")
       
  6556 		 EAPL("this = 0x%08x\n"),
       
  6557 		 (m_is_client == true ? "client": "server"),
       
  6558 		 eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()),
       
  6559 		 this));
       
  6560 
       
  6561 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::state_notification()");
       
  6562 
       
  6563 
       
  6564 	const abs_eap_state_notification_c * notification = state;
       
  6565 	eap_automatic_variable_c<const abs_eap_state_notification_c> automatic_notification(m_am_tools, 0);
       
  6566 
       
  6567 	if (state->get_protocol_layer() == eap_protocol_layer_eap)
       
  6568 	{
       
  6569 		EAP_TRACE_DEBUG(
       
  6570 			m_am_tools,
       
  6571 			TRACE_FLAGS_DEFAULT,
       
  6572 			(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): eap_protocol_layer_eap: state = %s")
       
  6573 			 EAPL("this = 0x%08x\n"),
       
  6574 			 (m_is_client == true ? "client": "server"),
       
  6575 			 eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()),
       
  6576 			 this));
       
  6577 
       
  6578 		if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully)
       
  6579 		{
       
  6580 			// Tunneled EAP-type terminated unsuccessfully.
       
  6581 			m_tunneled_eap_type_authentication_state = static_cast<eap_state_variable_e>(
       
  6582 				state->get_current_state());
       
  6583 			if (m_is_client == true
       
  6584 				&& m_eap_type == eap_type_peap)
       
  6585 			{
       
  6586 				if (m_peap_version == peap_version_0_xp)
       
  6587 				{
       
  6588 					// Send tunneled EAP-Success acknowledge.
       
  6589 					eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  6590 						eap_code_failure,
       
  6591 						state->get_eap_identifier());
       
  6592 					if (status != eap_status_ok)
       
  6593 					{
       
  6594 						m_tunneled_eap_type_authentication_state
       
  6595 							= eap_state_authentication_terminated_unsuccessfully;
       
  6596 					}
       
  6597 					// XP-PEAPv0 Authentication FAILED.
       
  6598 				}
       
  6599 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  6600 				else if (m_peap_version == peap_version_1
       
  6601 					&& m_client_send_peapv1_extensions_response == true)
       
  6602 				{
       
  6603 					// Send tunneled EAP-Success acknowledge.
       
  6604 					eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  6605 						eap_code_failure,
       
  6606 						state->get_eap_identifier());
       
  6607 					if (status != eap_status_ok)
       
  6608 					{
       
  6609 						m_tunneled_eap_type_authentication_state
       
  6610 							= eap_state_authentication_terminated_unsuccessfully;
       
  6611 					}
       
  6612 					// PEAPv1 Authentication FAILED.
       
  6613 
       
  6614 					notification = new eap_state_notification_c(
       
  6615 						m_am_tools,
       
  6616 						state->get_send_network_id(),
       
  6617 						state->get_is_client(),
       
  6618 						eap_state_notification_eap,
       
  6619 						state->get_protocol_layer(),
       
  6620 						state->get_eap_type(),
       
  6621 						state->get_previous_state(),
       
  6622 						eap_state_authentication_terminated_unsuccessfully_peapv1_extension,
       
  6623 						state->get_eap_identifier(),
       
  6624 						state->get_allow_send_eap_success());
       
  6625 
       
  6626 					automatic_notification.set_variable(notification);
       
  6627 
       
  6628 					if (notification == 0)
       
  6629 					{
       
  6630 						m_tunneled_eap_type_authentication_state
       
  6631 							= eap_state_authentication_terminated_unsuccessfully;
       
  6632 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6633 						(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6634 						return;
       
  6635 					}
       
  6636 				}
       
  6637 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  6638 				else if (m_peap_version == peap_version_2)
       
  6639 				{
       
  6640 					// Send tunneled EAP-Success acknowledge.
       
  6641 					eap_status_e status = send_tunneled_acknowledge_peap_v2(
       
  6642 						eap_code_failure,
       
  6643 						state->get_eap_identifier());
       
  6644 					if (status != eap_status_ok)
       
  6645 					{
       
  6646 						m_tunneled_eap_type_authentication_state
       
  6647 							= eap_state_authentication_terminated_unsuccessfully;
       
  6648 					}
       
  6649 					// PEAPv2 Authentication FAILED.
       
  6650 				}
       
  6651 			}
       
  6652 			else if (m_eap_type == eap_type_peap)
       
  6653 			{
       
  6654 				// Server
       
  6655 				if (m_peap_version == peap_version_0_xp)
       
  6656 				{
       
  6657 					// Does nothing special.
       
  6658 					// Server waits the EAP Response of Type=Extensions
       
  6659 					// acknowled packet from client.
       
  6660 					return;
       
  6661 				}
       
  6662 				else if (m_peap_version == peap_version_2)
       
  6663 				{
       
  6664 					// Does nothing special.
       
  6665 					// Server waits the EAP Response of Type=Extensions
       
  6666 					// acknowled packet from client.
       
  6667 					return;
       
  6668 				}
       
  6669 			}
       
  6670 		}
       
  6671 		else if (state->get_current_state() == eap_state_authentication_finished_successfully)
       
  6672 		{
       
  6673 			// Tunneled EAP-type finished successfully.
       
  6674 			m_tunneled_eap_type_authentication_state = static_cast<eap_state_variable_e>(
       
  6675 				state->get_current_state());
       
  6676 
       
  6677 			if (m_is_client == true
       
  6678 				&& m_eap_type == eap_type_peap)
       
  6679 			{
       
  6680 				if (m_peap_version == peap_version_0_xp)
       
  6681 				{
       
  6682 					// Send tunneled EAP-Success acknowledge.
       
  6683 					eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  6684 						eap_code_success,
       
  6685 						state->get_eap_identifier());
       
  6686 					if (status != eap_status_ok)
       
  6687 					{
       
  6688 						m_tunneled_eap_type_authentication_state
       
  6689 							= eap_state_authentication_terminated_unsuccessfully;
       
  6690 					}
       
  6691 
       
  6692 					// XP-PEAPv0 Authentication OK.
       
  6693 				}
       
  6694 #if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  6695 				else if (m_peap_version == peap_version_1
       
  6696 					&& m_client_send_peapv1_extensions_response == true)
       
  6697 				{
       
  6698 					// Send tunneled EAP-Success acknowledge.
       
  6699 					eap_status_e status = send_tunneled_acknowledge_xp_peap_v0(
       
  6700 						eap_code_success,
       
  6701 						state->get_eap_identifier());
       
  6702 					if (status != eap_status_ok)
       
  6703 					{
       
  6704 						m_tunneled_eap_type_authentication_state
       
  6705 							= eap_state_authentication_terminated_unsuccessfully;
       
  6706 					}
       
  6707 					// PEAPv1 Authentication OK.
       
  6708 
       
  6709 					notification = new eap_state_notification_c(
       
  6710 						m_am_tools,
       
  6711 						state->get_send_network_id(),
       
  6712 						state->get_is_client(),
       
  6713 						eap_state_notification_eap,
       
  6714 						state->get_protocol_layer(),
       
  6715 						state->get_eap_type(),
       
  6716 						state->get_previous_state(),
       
  6717 						eap_state_authentication_finished_successfully_peapv1_extension,
       
  6718 						state->get_eap_identifier(),
       
  6719 						state->get_allow_send_eap_success());
       
  6720 
       
  6721 					automatic_notification.set_variable(notification);
       
  6722 
       
  6723 					if (notification == 0)
       
  6724 					{
       
  6725 						m_tunneled_eap_type_authentication_state
       
  6726 							= eap_state_authentication_terminated_unsuccessfully;
       
  6727 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6728 						(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6729 						return;
       
  6730 					}
       
  6731 				}
       
  6732 #endif //#if defined(USE_EAP_PEAPV1_EXTENSIONS)
       
  6733 				else if (m_peap_version == peap_version_2)
       
  6734 				{
       
  6735 					// Send tunneled EAP-Success acknowledge.
       
  6736 
       
  6737 					eap_status_e status = create_nonce_peap_v2(m_is_client);
       
  6738 					if (status != eap_status_ok)
       
  6739 					{
       
  6740 						m_tunneled_eap_type_authentication_state
       
  6741 							= eap_state_authentication_terminated_unsuccessfully;
       
  6742 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6743 						return;
       
  6744 					}
       
  6745 
       
  6746 					// Intermediate Combined Key is stored to m_peap_v2_IPMKn.
       
  6747 					// Compound MAC Key is stored to m_peap_v2_CMK_Bn.
       
  6748 					status = create_compound_mac_key_peap_v2(false);
       
  6749 					if (status != eap_status_ok)
       
  6750 					{
       
  6751 						m_tunneled_eap_type_authentication_state
       
  6752 							= eap_state_authentication_terminated_unsuccessfully;
       
  6753 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6754 						return;
       
  6755 					}
       
  6756 
       
  6757 					status = create_compound_mac_key_peap_v2(true);
       
  6758 					if (status != eap_status_ok)
       
  6759 					{
       
  6760 						m_tunneled_eap_type_authentication_state
       
  6761 							= eap_state_authentication_terminated_unsuccessfully;
       
  6762 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6763 						return;
       
  6764 					}
       
  6765 
       
  6766 					// First we must verify the received TLVs and B1 MAC.
       
  6767 					status = verify_tunneled_acknowledge_peap_v2();
       
  6768 					if (status != eap_status_success)
       
  6769 					{
       
  6770 						m_tunneled_eap_type_authentication_state
       
  6771 							= eap_state_authentication_terminated_unsuccessfully;
       
  6772 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6773 						return;
       
  6774 					}
       
  6775 
       
  6776 					status = send_tunneled_acknowledge_peap_v2(
       
  6777 						eap_code_success,
       
  6778 						state->get_eap_identifier());
       
  6779 					if (status != eap_status_ok)
       
  6780 					{
       
  6781 						m_tunneled_eap_type_authentication_state
       
  6782 							= eap_state_authentication_terminated_unsuccessfully;
       
  6783 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6784 						return;
       
  6785 					}
       
  6786 
       
  6787 					status = finish_successfull_authentication_peap_v2(
       
  6788 						m_received_eap_identifier);
       
  6789 					if (status != eap_status_ok)
       
  6790 					{
       
  6791 						m_tunneled_eap_type_authentication_state
       
  6792 							= eap_state_authentication_terminated_unsuccessfully;
       
  6793 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6794 						return;
       
  6795 					}
       
  6796 
       
  6797 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6798 					return;
       
  6799 
       
  6800 					// PEAPv2 Authentication OK.
       
  6801 				}
       
  6802 			}
       
  6803 			else if (m_eap_type == eap_type_peap)
       
  6804 			{
       
  6805 				// Server
       
  6806 				if (m_peap_version == peap_version_0_xp)
       
  6807 				{
       
  6808 					// Does nothing special.
       
  6809 					// Server waits the EAP Response of Type=Extensions acknowled packet from client.
       
  6810 					return;
       
  6811 				}
       
  6812 				else if (m_peap_version == peap_version_2)
       
  6813 				{
       
  6814 					eap_status_e status = create_nonce_peap_v2(m_is_client);
       
  6815 					if (status != eap_status_ok)
       
  6816 					{
       
  6817 						m_tunneled_eap_type_authentication_state
       
  6818 							= eap_state_authentication_finished_successfully;
       
  6819 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6820 						return;
       
  6821 					}
       
  6822 
       
  6823 					// Intermediate Combined Key is stored to m_peap_v2_IPMKn.
       
  6824 					// Compound MAC Key is stored to m_peap_v2_CMK_Bn.
       
  6825 					status = create_compound_mac_key_peap_v2(m_is_client);
       
  6826 					if (status != eap_status_ok)
       
  6827 					{
       
  6828 						m_tunneled_eap_type_authentication_state
       
  6829 							= eap_state_authentication_finished_successfully;
       
  6830 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6831 						return;
       
  6832 					}
       
  6833 
       
  6834 					status = send_tunneled_acknowledge_peap_v2(
       
  6835 						eap_code_success,
       
  6836 						state->get_eap_identifier());
       
  6837 					if (status != eap_status_ok)
       
  6838 					{
       
  6839 						m_tunneled_eap_type_authentication_state
       
  6840 							= eap_state_authentication_finished_successfully;
       
  6841 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6842 						return;
       
  6843 					}
       
  6844 
       
  6845 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6846 					return;
       
  6847 				}
       
  6848 			}
       
  6849 			else if (m_eap_type == eap_type_ttls)
       
  6850 			{
       
  6851 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  6852 				if (m_tunneled_eap_in_ttls == true)
       
  6853 				{
       
  6854 					// TTLS with tunneled EAP.
       
  6855 					EAP_TRACE_DEBUG(
       
  6856 						m_am_tools,
       
  6857 						TRACE_FLAGS_DEFAULT,
       
  6858 						(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): notification state=%s")
       
  6859 						 EAPL("this = 0x%08x, TTLS with tunneled EAP.\n"),
       
  6860 						 (m_is_client == true ? "client": "server"),
       
  6861 						 eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()),
       
  6862 						 this));
       
  6863 				}
       
  6864 				else if (m_tunneled_eap_in_ttls == false)
       
  6865 				{
       
  6866 					// TTLS with plain MsChapv2.
       
  6867 					EAP_TRACE_DEBUG(
       
  6868 						m_am_tools,
       
  6869 						TRACE_FLAGS_DEFAULT,
       
  6870 						(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::state_notification(): notification state=%s")
       
  6871 						 EAPL("this = 0x%08x, TTLS with plain MsChapv2.\n"),
       
  6872 						 (m_is_client == true ? "client": "server"),
       
  6873 						 eap_state_notification_c::get_state_string(state->get_protocol_layer(), state->get_current_state()),
       
  6874 						 this));
       
  6875 				}
       
  6876 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK)
       
  6877 			}
       
  6878 		}
       
  6879 	}
       
  6880 
       
  6881 	get_application_partner()->state_notification(notification);
       
  6882 
       
  6883 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6884 }
       
  6885 
       
  6886 //--------------------------------------------------
       
  6887 
       
  6888 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::asynchronous_init_remove_eap_session(
       
  6889 	const eap_am_network_id_c * const /* send_network_id */)
       
  6890 {
       
  6891 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6892 
       
  6893 	// Here we do not want to remove the session yet. It is removed after PEAP session finishes.
       
  6894 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6895 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6896 }
       
  6897 
       
  6898 //--------------------------------------------------
       
  6899 
       
  6900 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::set_timer(
       
  6901 	abs_eap_base_timer_c * const initializer, 
       
  6902 	const u32_t id, 
       
  6903 	void * const data,
       
  6904 	const u32_t p_time_ms)
       
  6905 {
       
  6906 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6907 
       
  6908 	eap_status_e status = get_application_partner()->set_timer(
       
  6909 		initializer, 
       
  6910 		id, 
       
  6911 		data,
       
  6912 		p_time_ms);
       
  6913 
       
  6914 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6915 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6916 }
       
  6917 
       
  6918 //--------------------------------------------------
       
  6919 
       
  6920 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::cancel_timer(
       
  6921 	abs_eap_base_timer_c * const initializer, 
       
  6922 	const u32_t id)
       
  6923 {
       
  6924 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6925 	eap_status_e status = eap_status_process_general_error;
       
  6926 	abs_tls_base_application_c * partner = get_application_partner();
       
  6927 	if (partner != 0)
       
  6928 	{
       
  6929 		status = partner->cancel_timer(
       
  6930 			initializer, 
       
  6931 			id);
       
  6932 	}
       
  6933 
       
  6934 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6935 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6936 }
       
  6937 
       
  6938 //--------------------------------------------------
       
  6939 
       
  6940 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::cancel_all_timers()
       
  6941 {
       
  6942 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6943 	eap_status_e status = eap_status_process_general_error;
       
  6944 	abs_tls_base_application_c * partner = get_application_partner();
       
  6945 	if (partner != 0)
       
  6946 	{
       
  6947 		status = partner->cancel_all_timers();
       
  6948 	}
       
  6949 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6950 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6951 }
       
  6952 
       
  6953 //--------------------------------------------------
       
  6954 
       
  6955 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_is_valid_eap_type(
       
  6956 	const eap_type_value_e eap_type)
       
  6957 {
       
  6958 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6959 
       
  6960 	eap_header_string_c eap_string;
       
  6961 	EAP_UNREFERENCED_PARAMETER(eap_string);
       
  6962 
       
  6963 	EAP_TRACE_DEBUG(
       
  6964 		m_am_tools,
       
  6965 		TRACE_FLAGS_DEFAULT,
       
  6966 		(EAPL("tls_application_eap_core_c::check_is_valid_eap_type(): EAP-type=0x%08x=%s\n"),
       
  6967 		convert_eap_type_to_u32_t(eap_type),
       
  6968 		eap_string.get_eap_type_string(eap_type)));
       
  6969 
       
  6970 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_is_valid_eap_type()");
       
  6971 
       
  6972 	if (m_accepted_tunneled_eap_types.get_object_count() > 0ul)
       
  6973 	{
       
  6974 		bool allow_this_eap_type = false;
       
  6975 
       
  6976 		eap_type_value_e * type = 0;
       
  6977 
       
  6978 		for (u32_t ind = 0ul; ind < m_accepted_tunneled_eap_types.get_object_count(); ind++)
       
  6979 		{
       
  6980 			type = m_accepted_tunneled_eap_types.get_object(ind);
       
  6981 
       
  6982 			if (type != 0)
       
  6983 			{
       
  6984 				EAP_TRACE_DEBUG(
       
  6985 					m_am_tools, 
       
  6986 					TRACE_FLAGS_DEFAULT, 
       
  6987 					(EAPL("%s: tls_application_eap_core_c::check_is_valid_eap_type(): allowed EAP-type %d.\n"),
       
  6988 					 (m_is_client == true ? "client": "server"),
       
  6989 					 convert_eap_type_to_u32_t(*type)));
       
  6990 			}
       
  6991 
       
  6992 			if (type != 0
       
  6993 				&& eap_type == *type)
       
  6994 			{
       
  6995 				allow_this_eap_type = true;
       
  6996 				break;
       
  6997 			}
       
  6998 		} // for()
       
  6999 
       
  7000 		if (allow_this_eap_type == false)
       
  7001 		{
       
  7002 			// Not allowed EAP-type inside PEAP.
       
  7003 			EAP_TRACE_DEBUG(
       
  7004 				m_am_tools,
       
  7005 				TRACE_FLAGS_DEFAULT,
       
  7006 				(EAPL("ERROR: tls_application_eap_core_c::check_is_valid_eap_type(): No allowed EAP-type=0x%08x=%s\n"),
       
  7007 				convert_eap_type_to_u32_t(eap_type),
       
  7008 				eap_string.get_eap_type_string(eap_type)));
       
  7009 
       
  7010 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type);
       
  7011 		}
       
  7012 		else
       
  7013 		{
       
  7014 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7015 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7016 		}
       
  7017 	}
       
  7018 	else
       
  7019 	{
       
  7020 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7021 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type);
       
  7022 	}
       
  7023 }
       
  7024 
       
  7025 //--------------------------------------------------
       
  7026 
       
  7027 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::get_eap_type_list(
       
  7028 	eap_array_c<eap_type_value_e> * const eap_type_list)
       
  7029 {
       
  7030 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7031 
       
  7032 	EAP_TRACE_DEBUG(
       
  7033 		m_am_tools,
       
  7034 		TRACE_FLAGS_DEFAULT,
       
  7035 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::get_eap_type_list(): ")
       
  7036 		 EAPL("this = 0x%08x\n"),
       
  7037 		 (m_is_client == true ? "client": "server"),
       
  7038 		 this));
       
  7039 
       
  7040 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::get_eap_type_list()");
       
  7041 
       
  7042 	for (u32_t ind = 0ul; ind < m_accepted_tunneled_eap_types.get_object_count(); ind++)
       
  7043 	{
       
  7044 		const eap_type_value_e * const type = m_accepted_tunneled_eap_types.get_object(ind);
       
  7045 
       
  7046 		if (type != 0)
       
  7047 		{
       
  7048 			EAP_TRACE_DEBUG(
       
  7049 				m_am_tools, 
       
  7050 				TRACE_FLAGS_DEFAULT, 
       
  7051 				(EAPL("%s: tls_application_eap_core_c::get_eap_type_list(): allowed EAP-type %d.\n"),
       
  7052 				 (m_is_client == true ? "client": "server"),
       
  7053 				 convert_eap_type_to_u32_t(*type)));
       
  7054 		}
       
  7055 	}
       
  7056 
       
  7057 	eap_status_e status = copy_simple<eap_type_value_e>(
       
  7058 		&m_accepted_tunneled_eap_types,
       
  7059 		eap_type_list,
       
  7060 		m_am_tools,
       
  7061 		false);
       
  7062 
       
  7063 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7064 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7065 }
       
  7066 
       
  7067 //--------------------------------------------------
       
  7068 
       
  7069 EAP_FUNC_EXPORT abs_tls_base_application_c * tls_application_eap_core_c::get_application_partner()
       
  7070 {
       
  7071 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7072 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7073 	return m_application_partner;
       
  7074 }
       
  7075 
       
  7076 //--------------------------------------------------
       
  7077 
       
  7078 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::set_application_partner(
       
  7079 	abs_tls_base_application_c * const partner)
       
  7080 {
       
  7081 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7082 
       
  7083 	EAP_TRACE_DEBUG(
       
  7084 		m_am_tools,
       
  7085 		TRACE_FLAGS_DEFAULT,
       
  7086 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::set_application_partner(): ")
       
  7087 		 EAPL("this = 0x%08x\n"),
       
  7088 		 (m_is_client == true ? "client": "server"),
       
  7089 		 this));
       
  7090 
       
  7091 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_application_partner()");
       
  7092 
       
  7093 	m_application_partner = partner;
       
  7094 
       
  7095 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7096 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7097 }
       
  7098 
       
  7099 //--------------------------------------------------
       
  7100 
       
  7101 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::add_rogue_ap(
       
  7102 	eap_array_c<eap_rogue_ap_entry_c> & rogue_ap_list)
       
  7103 {
       
  7104 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7105 
       
  7106 	eap_status_e status = get_application_partner()->add_rogue_ap(rogue_ap_list);
       
  7107 
       
  7108 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7109 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7110 }
       
  7111 
       
  7112 //--------------------------------------------------
       
  7113 
       
  7114 //
       
  7115 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::set_session_timeout(
       
  7116 	const u32_t session_timeout_ms)
       
  7117 {
       
  7118 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7119 
       
  7120 	EAP_TRACE_DEBUG(
       
  7121 		m_am_tools,
       
  7122 		TRACE_FLAGS_DEFAULT,
       
  7123 		(EAPL("PEAP: %s: crypto_function: tls_application_eap_core_c::set_session_timeout(): ")
       
  7124 		 EAPL("this = 0x%08x\n"),
       
  7125 		 (m_is_client == true ? "client": "server"),
       
  7126 		 this));
       
  7127 
       
  7128 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::set_session_timeout()");
       
  7129 
       
  7130 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  7131 
       
  7132 	eap_status_e status = get_application_partner()->set_session_timeout(session_timeout_ms);
       
  7133 	if (status != eap_status_ok)
       
  7134 	{
       
  7135 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7136 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7137 	}
       
  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 tls_application_eap_core_c::read_authority_identity(eap_variable_data_c * const /* authority_identity_payload*/)
       
  7146 {
       
  7147 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  7148 }
       
  7149 
       
  7150 //--------------------------------------------------
       
  7151 
       
  7152 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::save_user_authorization_pac_opaque(const tls_extension_c * const /* extension */)
       
  7153 {
       
  7154 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  7155 }
       
  7156 
       
  7157 //--------------------------------------------------
       
  7158 
       
  7159 // This is commented in tls_base_record_c::query_tunnel_PAC().
       
  7160 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::query_tunnel_PAC(
       
  7161 	const eap_fast_variable_data_c * const /* in_A_ID_TLV */)
       
  7162 {
       
  7163 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  7164 }
       
  7165 
       
  7166 //--------------------------------------------------
       
  7167 
       
  7168 // This is commented in tls_base_record_c::cancel_query_tunnel_PAC().
       
  7169 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::cancel_query_tunnel_PAC()
       
  7170 {
       
  7171 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  7172 }
       
  7173 
       
  7174 //--------------------------------------------------
       
  7175 
       
  7176 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::complete_query_ttls_pap_username_and_password(
       
  7177 	const eap_variable_data_c * const ttls_pap_username,
       
  7178 	const eap_variable_data_c * const ttls_pap_password,
       
  7179 	const eap_status_e query_result)
       
  7180 {
       
  7181 	eap_status_e status(eap_status_process_general_error);
       
  7182 
       
  7183 	EAP_TRACE_DEBUG(
       
  7184 		m_am_tools,
       
  7185 		TRACE_FLAGS_DEFAULT,
       
  7186 		(EAPL("TTLS: %s: tls_application_eap_core_c::complete_query_ttls_pap_username_and_password()\n"),
       
  7187 		(m_is_client == true ? "client": "server")));
       
  7188 
       
  7189 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::complete_query_ttls_pap_username_and_password()");
       
  7190 
       
  7191 	// Here we swap the addresses.
       
  7192 	eap_am_network_id_c send_network_id(
       
  7193 		m_am_tools,
       
  7194 		m_receive_network_id.get_destination_id(),
       
  7195 		m_receive_network_id.get_source_id(),
       
  7196 		m_receive_network_id.get_type());
       
  7197 
       
  7198 	if (query_result != eap_status_ok)
       
  7199 	{
       
  7200 		{
       
  7201 			eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error);
       
  7202 
       
  7203 			if (query_result == eap_status_user_cancel_authentication)
       
  7204 			{
       
  7205 				general_state_variable = eap_general_state_authentication_cancelled;
       
  7206 			}
       
  7207 
       
  7208 			eap_state_notification_c notification(
       
  7209 				m_am_tools,
       
  7210 				&send_network_id,
       
  7211 				true,
       
  7212 				eap_state_notification_eap,
       
  7213 				eap_protocol_layer_general,
       
  7214 				m_peap_tunneled_eap_type,
       
  7215 				eap_state_none,
       
  7216 				general_state_variable,
       
  7217 				m_received_eap_identifier,
       
  7218 				false);
       
  7219 
       
  7220 			notification.set_authentication_error(query_result);
       
  7221 
       
  7222 			m_application_partner->state_notification(&notification);
       
  7223 		}
       
  7224 
       
  7225 		{
       
  7226 			eap_state_notification_c notification(
       
  7227 				m_am_tools,
       
  7228 				&send_network_id,
       
  7229 				m_is_client,
       
  7230 				eap_state_notification_eap,
       
  7231 				eap_protocol_layer_eap,
       
  7232 				m_peap_tunneled_eap_type,
       
  7233 				eap_state_none,
       
  7234 				eap_state_authentication_terminated_unsuccessfully,
       
  7235 				m_received_eap_identifier,
       
  7236 				true);
       
  7237 			m_application_partner->state_notification(&notification);
       
  7238 		}
       
  7239 	}
       
  7240 	else
       
  7241 	{
       
  7242 		if (ttls_pap_username == 0
       
  7243 			|| ttls_pap_username->get_is_valid_data() == false)
       
  7244 		{
       
  7245 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7246 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  7247 		}
       
  7248 
       
  7249 		if (ttls_pap_password == 0
       
  7250 			|| ttls_pap_password->get_is_valid_data() == false)
       
  7251 		{
       
  7252 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7253 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  7254 		}
       
  7255 
       
  7256 		eap_variable_data_c tunneled_data(m_am_tools);
       
  7257 		eap_variable_data_c avp(m_am_tools);
       
  7258 
       
  7259 		{
       
  7260 			status = create_ttls_diameter_avp(
       
  7261 				&avp,
       
  7262 				ttls_pap_username,
       
  7263 				eap_diameter_avp_code_user_name,
       
  7264 				false);
       
  7265 			if (status != eap_status_ok)
       
  7266 			{
       
  7267 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7268 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7269 			}
       
  7270 
       
  7271 			status = tunneled_data.add_data(&avp);
       
  7272 			if (status != eap_status_ok)
       
  7273 			{
       
  7274 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7275 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7276 			}
       
  7277 		}
       
  7278 
       
  7279 		{
       
  7280 			eap_variable_data_c padded_password(m_am_tools);
       
  7281 
       
  7282 			status = padded_password.set_copy_of_buffer(ttls_pap_password);
       
  7283 			if (status != eap_status_ok)
       
  7284 			{
       
  7285 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7286 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7287 			}
       
  7288 
       
  7289 			const u32_t PADDING_LENGTH_MULTIPLIER(16ul);
       
  7290 
       
  7291 			const u32_t padding_length((PADDING_LENGTH_MULTIPLIER - (padded_password.get_data_length() % PADDING_LENGTH_MULTIPLIER)) % PADDING_LENGTH_MULTIPLIER);
       
  7292 
       
  7293 			if (padding_length > 0ul)
       
  7294 			{
       
  7295 				const u8_t PADDING[] = {
       
  7296 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       
  7297 					0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
       
  7298 
       
  7299 				status = padded_password.add_data_to_offset(padded_password.get_data_length(), PADDING, padding_length);
       
  7300 				if (status != eap_status_ok)
       
  7301 				{
       
  7302 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7303 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7304 				}
       
  7305 			}
       
  7306 
       
  7307 			status = create_ttls_diameter_avp(
       
  7308 				&avp,
       
  7309 				&padded_password,
       
  7310 				eap_diameter_avp_code_user_password,
       
  7311 				false);
       
  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 = tunneled_data.add_data(&avp);
       
  7319 			if (status != eap_status_ok)
       
  7320 			{
       
  7321 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7322 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7323 			}
       
  7324 		}
       
  7325 
       
  7326 		eap_buf_chain_wr_c forwarded_packet(
       
  7327 			eap_write_buffer,
       
  7328 			m_am_tools,
       
  7329 			tunneled_data.get_data(),
       
  7330 			tunneled_data.get_data_length(),
       
  7331 			false,
       
  7332 			false,
       
  7333 			0ul);
       
  7334 		if (forwarded_packet.get_is_valid() == false)
       
  7335 		{
       
  7336 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7337 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7338 		}
       
  7339 
       
  7340 		status = get_application_partner()->packet_send(
       
  7341 			&forwarded_packet,
       
  7342 			0ul,
       
  7343 			forwarded_packet.get_data_length(),
       
  7344 			forwarded_packet.get_buffer_length());
       
  7345 	}
       
  7346 
       
  7347 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7348 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7349 }
       
  7350 
       
  7351 
       
  7352 //--------------------------------------------------
       
  7353 
       
  7354 
       
  7355 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::check_ttls_plain_pap_payloads(
       
  7356 	eap_diameter_payloads_c * const payloads,
       
  7357 	eap_ttls_tunneled_message_type_e * const message_type)
       
  7358 {
       
  7359 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7360 
       
  7361 	EAP_TRACE_DEBUG(
       
  7362 		m_am_tools,
       
  7363 		TRACE_FLAGS_DEFAULT,
       
  7364 		(EAPL("TTLS: %s: tls_application_eap_core_c::check_ttls_plain_pap_payloads()\n"),
       
  7365 		(m_is_client == true ? "client": "server")));
       
  7366 
       
  7367 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::check_ttls_plain_pap_payloads()");
       
  7368 
       
  7369 	*message_type = eap_ttls_tunneled_message_type_none;
       
  7370 
       
  7371 	eap_status_e status(eap_status_not_found);
       
  7372 
       
  7373 	eap_array_c<eap_diameter_avp_code_c> needed_payloads(m_am_tools);
       
  7374 
       
  7375 	needed_payloads.reset();
       
  7376 
       
  7377 	if (m_is_client == false)
       
  7378 	{
       
  7379 		// First check are there User-Name and User-Password AVPs.
       
  7380 
       
  7381 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7382 
       
  7383 		eap_diameter_avp_code_c code_user_name(
       
  7384 			eap_diameter_avp_code_user_name);
       
  7385 
       
  7386 		status = needed_payloads.add_object(&code_user_name, false);
       
  7387 		if (status != eap_status_ok)
       
  7388 		{
       
  7389 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7390 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7391 		}
       
  7392 
       
  7393 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7394 
       
  7395 		eap_diameter_avp_code_c code_user_password(
       
  7396 			eap_diameter_avp_code_user_password);
       
  7397 
       
  7398 		status = needed_payloads.add_object(&code_user_password, false);
       
  7399 		if (status != eap_status_ok)
       
  7400 		{
       
  7401 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7402 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7403 		}
       
  7404 		
       
  7405 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7406 
       
  7407 		// Test the required attribute.
       
  7408 		status = payloads->check_payloads_existense(
       
  7409 			&needed_payloads);
       
  7410 		if (status == eap_status_ok)
       
  7411 		{
       
  7412 			// This packet includes required AVPs.
       
  7413 
       
  7414 			status = payloads->check_mandatory_payloads(
       
  7415 				&needed_payloads);
       
  7416 			if (status == eap_status_ok)
       
  7417 			{
       
  7418 				// All mandatory AVPs are included.
       
  7419 
       
  7420 				*message_type = eap_ttls_tunneled_message_type_pap_response;
       
  7421 
       
  7422 				EAP_TRACE_DEBUG(
       
  7423 					m_am_tools, 
       
  7424 					TRACE_FLAGS_DEFAULT, 
       
  7425 					(EAPL("Match User-Name and User-Password AVPs.\n")));
       
  7426 
       
  7427 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7428 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7429 			}
       
  7430 		}
       
  7431 	}
       
  7432 	else //if (m_is_client == true)
       
  7433 	{
       
  7434 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7435 		// First check is there Reply-Message AVP.
       
  7436 		
       
  7437 		eap_diameter_avp_code_c code_reply_message(
       
  7438 			eap_diameter_avp_code_reply_message);
       
  7439 
       
  7440 		status = needed_payloads.add_object(&code_reply_message, false);
       
  7441 		if (status != eap_status_ok)
       
  7442 		{
       
  7443 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7444 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  7445 		}
       
  7446 
       
  7447 		// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  7448 
       
  7449 		// Test the required attribute.
       
  7450 		status = payloads->check_payloads_existense(
       
  7451 			&needed_payloads);
       
  7452 		if (status == eap_status_ok)
       
  7453 		{
       
  7454 			// This packet includes required AVPs.
       
  7455 
       
  7456 			status = payloads->check_mandatory_payloads(
       
  7457 				&needed_payloads);
       
  7458 			if (status == eap_status_ok)
       
  7459 			{
       
  7460 				// All mandatory AVPs are included.
       
  7461 
       
  7462 				*message_type = eap_ttls_tunneled_message_type_pap_reply_message;
       
  7463 
       
  7464 				EAP_TRACE_DEBUG(
       
  7465 					m_am_tools, 
       
  7466 					TRACE_FLAGS_DEFAULT, 
       
  7467 					(EAPL("Match Reply-Message AVP.\n")));
       
  7468 
       
  7469 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7470 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7471 			}
       
  7472 		}
       
  7473 	}
       
  7474 
       
  7475 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7476 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7477 }
       
  7478 
       
  7479 
       
  7480 //--------------------------------------------------
       
  7481 
       
  7482 
       
  7483 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_pap_response(
       
  7484 	eap_diameter_payloads_c * const /* payloads */,
       
  7485 	const u8_t /* received_eap_identifier */)
       
  7486 {
       
  7487 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7488 
       
  7489 	EAP_TRACE_DEBUG(
       
  7490 		m_am_tools,
       
  7491 		TRACE_FLAGS_DEFAULT,
       
  7492 		(EAPL("TTLS: %s: tls_application_eap_core_c::ttls_server_handles_pap_response()\n"),
       
  7493 		(m_is_client == true ? "client": "server")));
       
  7494 
       
  7495 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_pap_response()");
       
  7496 
       
  7497 	eap_status_e status(eap_status_not_found);
       
  7498 
       
  7499 	eap_diameter_variable_data_c * const user_name_payload
       
  7500 		= m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_name);
       
  7501 
       
  7502 	if (user_name_payload == 0)
       
  7503 	{
       
  7504 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  7505 	}
       
  7506 
       
  7507 	eap_diameter_variable_data_c * const user_password_payload
       
  7508 		= m_ttls_received_payloads.get_payload(eap_diameter_avp_code_user_password);
       
  7509 
       
  7510 	if (user_password_payload == 0)
       
  7511 	{
       
  7512 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  7513 	}
       
  7514 
       
  7515 	eap_variable_data_c * const password = user_password_payload->get_payload_buffer();
       
  7516 
       
  7517 	// Remove possible padding of user_password_payload.
       
  7518 	while(true)
       
  7519 	{
       
  7520 		if (password->get_data_length() < 1ul)
       
  7521 		{
       
  7522 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  7523 		}
       
  7524 
       
  7525 		u8_t * last_char = password->get_data_offset(password->get_data_length()-1ul, 1ul) ;
       
  7526 
       
  7527 		if (last_char != 0
       
  7528 			&& *last_char == 0x00)
       
  7529 		{
       
  7530 			status = password->set_data_length(password->get_data_length()-1ul);
       
  7531 			if (status != eap_status_ok)
       
  7532 			{
       
  7533 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7534 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  7535 			}
       
  7536 		}
       
  7537 		else
       
  7538 		{
       
  7539 			break;
       
  7540 		}
       
  7541 	}
       
  7542 
       
  7543 	status = m_application_partner->verify_ttls_pap_username_and_password(
       
  7544 		user_name_payload->get_payload_buffer(),
       
  7545 		password);
       
  7546 	if (status != eap_status_ok)
       
  7547 	{
       
  7548 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7549 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  7550 	}
       
  7551 
       
  7552 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7553 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7554 }
       
  7555 
       
  7556 
       
  7557 //--------------------------------------------------
       
  7558 
       
  7559 
       
  7560 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::ttls_server_handles_pap_reply_message(
       
  7561 	eap_diameter_payloads_c * const /* payloads */,
       
  7562 	const u8_t /* received_eap_identifier */)
       
  7563 {
       
  7564 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7565 
       
  7566 	EAP_TRACE_DEBUG(
       
  7567 		m_am_tools,
       
  7568 		TRACE_FLAGS_DEFAULT,
       
  7569 		(EAPL("TTLS: %s: tls_application_eap_core_c::ttls_server_handles_pap_reply_message()\n"),
       
  7570 		(m_is_client == true ? "client": "server")));
       
  7571 
       
  7572 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::ttls_server_handles_pap_reply_message()");
       
  7573 
       
  7574 	eap_status_e status(eap_status_not_found);
       
  7575 
       
  7576 	eap_diameter_variable_data_c * const reply_message_payload
       
  7577 		= m_ttls_received_payloads.get_payload(eap_diameter_avp_code_reply_message);
       
  7578 
       
  7579 	if (reply_message_payload == 0)
       
  7580 	{
       
  7581 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  7582 	}
       
  7583 
       
  7584 	status = m_application_partner->query_ttls_pap_username_and_password(
       
  7585 		reply_message_payload->get_payload_buffer());
       
  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_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7593 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7594 }
       
  7595 
       
  7596 
       
  7597 //--------------------------------------------------
       
  7598 
       
  7599 
       
  7600 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::handle_ttls_plain_pap_payloads(
       
  7601 	eap_diameter_payloads_c * const payloads,
       
  7602 	const eap_ttls_tunneled_message_type_e message_type,
       
  7603 	const u8_t received_eap_identifier)
       
  7604 {
       
  7605 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7606 
       
  7607 	EAP_TRACE_DEBUG(
       
  7608 		m_am_tools,
       
  7609 		TRACE_FLAGS_DEFAULT,
       
  7610 		(EAPL("TTLS: %s: tls_application_eap_core_c::handle_ttls_plain_pap_payloads()\n"),
       
  7611 		(m_is_client == true ? "client": "server")));
       
  7612 
       
  7613 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::handle_ttls_plain_pap_payloads()");
       
  7614 
       
  7615 	eap_status_e status(eap_status_not_found);
       
  7616 
       
  7617 	switch(message_type)
       
  7618 	{
       
  7619 	case eap_ttls_tunneled_message_type_pap_response:
       
  7620 		// Here are included User-Name, User-Password AVPs.
       
  7621 		status = ttls_server_handles_pap_response(payloads, received_eap_identifier);
       
  7622 		break;
       
  7623 	case eap_ttls_tunneled_message_type_pap_reply_message:
       
  7624 		// Here are included Reply-Message AVP.
       
  7625 		status = ttls_server_handles_pap_reply_message(payloads, received_eap_identifier);
       
  7626 		break;
       
  7627 	default:
       
  7628 		status = eap_status_unexpected_message;
       
  7629 		break;
       
  7630 	}
       
  7631 
       
  7632 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7633 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7634 }
       
  7635 
       
  7636 
       
  7637 //--------------------------------------------------
       
  7638 
       
  7639 
       
  7640 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::complete_verify_ttls_pap_username_and_password(
       
  7641 	const eap_status_e authentication_result,
       
  7642 	const eap_variable_data_c * const ttls_pap_reply_message)
       
  7643 {
       
  7644 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7645 
       
  7646 	EAP_TRACE_DEBUG(
       
  7647 		m_am_tools,
       
  7648 		TRACE_FLAGS_DEFAULT,
       
  7649 		(EAPL("TTLS: %s: tls_application_eap_core_c::complete_verify_ttls_pap_username_and_password()\n"),
       
  7650 		(m_is_client == true ? "client": "server")));
       
  7651 
       
  7652 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: tls_application_eap_core_c::complete_verify_ttls_pap_username_and_password()");
       
  7653 
       
  7654 	eap_status_e status(eap_status_not_found);
       
  7655 
       
  7656 	// Here we swap the addresses.
       
  7657 	eap_am_network_id_c send_network_id(
       
  7658 		m_am_tools,
       
  7659 		m_receive_network_id.get_destination_id(),
       
  7660 		m_receive_network_id.get_source_id(),
       
  7661 		m_receive_network_id.get_type());
       
  7662 
       
  7663 	status = authentication_result;
       
  7664 
       
  7665 	if (authentication_result == eap_status_ok)
       
  7666 	{
       
  7667 		eap_state_notification_c notification(
       
  7668 			m_am_tools,
       
  7669 			&send_network_id,
       
  7670 			m_is_client,
       
  7671 			eap_state_notification_eap,
       
  7672 			eap_protocol_layer_eap,
       
  7673 			m_peap_tunneled_eap_type,
       
  7674 			eap_state_none,
       
  7675 			eap_state_authentication_finished_successfully,
       
  7676 			m_received_eap_identifier,
       
  7677 			true);
       
  7678 		m_application_partner->state_notification(&notification);
       
  7679 	}
       
  7680 	else
       
  7681 	{
       
  7682 		if (ttls_pap_reply_message != 0
       
  7683 			&& ttls_pap_reply_message->get_is_valid_data() == true)
       
  7684 		{
       
  7685 			eap_variable_data_c tunneled_data(m_am_tools);
       
  7686 			eap_variable_data_c avp(m_am_tools);
       
  7687 
       
  7688 			{
       
  7689 				status = create_ttls_diameter_avp(
       
  7690 					&avp,
       
  7691 					ttls_pap_reply_message,
       
  7692 					eap_diameter_avp_code_reply_message,
       
  7693 					false);
       
  7694 				if (status != eap_status_ok)
       
  7695 				{
       
  7696 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7697 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7698 				}
       
  7699 
       
  7700 				status = tunneled_data.add_data(&avp);
       
  7701 				if (status != eap_status_ok)
       
  7702 				{
       
  7703 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7704 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  7705 				}
       
  7706 			}
       
  7707 
       
  7708 			eap_buf_chain_wr_c forwarded_packet(
       
  7709 				eap_write_buffer,
       
  7710 				m_am_tools,
       
  7711 				tunneled_data.get_data(),
       
  7712 				tunneled_data.get_data_length(),
       
  7713 				false,
       
  7714 				false,
       
  7715 				0ul);
       
  7716 			if (forwarded_packet.get_is_valid() == false)
       
  7717 			{
       
  7718 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7719 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  7720 			}
       
  7721 
       
  7722 			status = get_application_partner()->packet_send(
       
  7723 				&forwarded_packet,
       
  7724 				0ul,
       
  7725 				forwarded_packet.get_data_length(),
       
  7726 				forwarded_packet.get_buffer_length());
       
  7727 		}
       
  7728 		else
       
  7729 		{
       
  7730 			eap_state_notification_c notification(
       
  7731 				m_am_tools,
       
  7732 				&send_network_id,
       
  7733 				m_is_client,
       
  7734 				eap_state_notification_eap,
       
  7735 				eap_protocol_layer_eap,
       
  7736 				m_peap_tunneled_eap_type,
       
  7737 				eap_state_none,
       
  7738 				eap_state_authentication_terminated_unsuccessfully,
       
  7739 				m_received_eap_identifier,
       
  7740 				true);
       
  7741 			m_application_partner->state_notification(&notification);
       
  7742 		}
       
  7743 	}
       
  7744 
       
  7745 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7746 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7747 }
       
  7748 
       
  7749 
       
  7750 //--------------------------------------------------
       
  7751 
       
  7752 EAP_FUNC_EXPORT eap_status_e tls_application_eap_core_c::alert_received(
       
  7753 	const tls_alert_level_e alert_level,
       
  7754 	const tls_alert_description_e alert_description)
       
  7755 {
       
  7756 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7757 
       
  7758 	EAP_UNREFERENCED_PARAMETER(alert_level);
       
  7759 	EAP_UNREFERENCED_PARAMETER(alert_description);
       
  7760 
       
  7761 	eap_tls_trace_string_c tls_trace;
       
  7762 
       
  7763 	EAP_TRACE_DEBUG(
       
  7764 		m_am_tools,
       
  7765 		TRACE_FLAGS_DEFAULT,
       
  7766 		(EAPL("ERROR: %s: tls_application_eap_core_c::alert_received(), level %d=%s, description %d=%s\n"),
       
  7767 		 (m_is_client == true ? "client": "server"),
       
  7768 		 alert_level,
       
  7769 		 tls_trace.get_alert_level_string(alert_level),
       
  7770 		 alert_description,
       
  7771 		 tls_trace.get_alert_description_string(alert_description)));
       
  7772 
       
  7773 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7774 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  7775 }
       
  7776 
       
  7777 //--------------------------------------------------
       
  7778 
       
  7779 // End.