eapol/eapol_framework/eapol_common/core/eapol_key_state_common.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 50 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 
       
    28 
       
    29 #include "eap_am_memory.h"
       
    30 #include "eapol_key_state.h"
       
    31 #include "eapol_key_header.h"
       
    32 #include "eap_crypto_api.h"
       
    33 #include "abs_eap_am_mutex.h"
       
    34 #include "eap_state_notification.h"
       
    35 #include "eap_automatic_variable.h"
       
    36 #include "eapol_rsna_key_data_gtk_header.h"
       
    37 #include "abs_eapol_core.h"
       
    38 #include "abs_eapol_key_state.h"
       
    39 #include "eap_core_retransmission.h"
       
    40 #include "eapol_rsna_key_data_payloads.h"
       
    41 #include "eap_buffer.h"
       
    42 #include "eapol_session_key.h"
       
    43 #include "eapol_key_state_string.h"
       
    44 
       
    45 //--------------------------------------------------
       
    46 
       
    47 // 
       
    48 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::save_parameters(
       
    49 	const eapol_key_authentication_type_e authentication_type,
       
    50 	const eap_variable_data_c * const authenticator_RSNA_IE,
       
    51 	const eap_variable_data_c * const supplicant_RSNA_IE,
       
    52 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
       
    53 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher)
       
    54 {
       
    55 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    56 
       
    57 	eap_status_e status(eap_status_process_general_error);
       
    58 
       
    59 	m_authentication_type = authentication_type;
       
    60 	m_eapol_pairwise_cipher = eapol_pairwise_cipher;
       
    61 	m_eapol_group_cipher = eapol_group_cipher;
       
    62 
       
    63 	eapol_key_state_string_c state_string;
       
    64 	EAP_TRACE_DEBUG(
       
    65 		m_am_tools, 
       
    66 		TRACE_FLAGS_DEFAULT, 
       
    67 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::save_parameters(): m_authentication_type=%s, ")
       
    68 		 EAPL("m_eapol_pairwise_cipher=%d, m_eapol_group_cipher=%d.\n"),
       
    69 		 (m_is_client == true) ? "client": "server",
       
    70 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type),
       
    71 		 m_eapol_pairwise_cipher,
       
    72 		 m_eapol_group_cipher));
       
    73 	
       
    74 
       
    75 	if (get_is_RSNA() == true
       
    76 		|| get_is_WPA() == true
       
    77 #if defined(EAP_USE_WPXM)
       
    78 		|| get_is_WPXM() == true
       
    79 #endif //#if defined(EAP_USE_WPXM)
       
    80 		)
       
    81 	{
       
    82 		if (authenticator_RSNA_IE->get_is_valid_data() == true)
       
    83 		{
       
    84 			status = m_authenticator_RSNA_IE.set_copy_of_buffer(
       
    85 				authenticator_RSNA_IE);
       
    86 			if (status != eap_status_ok)
       
    87 			{
       
    88 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    89 				return EAP_STATUS_RETURN(m_am_tools, status);
       
    90 			}
       
    91 
       
    92 			EAP_TRACE_DATA_DEBUG(
       
    93 				m_am_tools,
       
    94 				TRACE_FLAGS_DEFAULT,
       
    95 				(EAPL("Authenticator RSN IE"),
       
    96 				 get_authenticator_RSNA_IE()->get_data(
       
    97 					 get_authenticator_RSNA_IE()->get_data_length()),
       
    98 				 get_authenticator_RSNA_IE()->get_data_length()));
       
    99 		}
       
   100 		else
       
   101 		{
       
   102 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   103 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   104 		}
       
   105 
       
   106 		if (supplicant_RSNA_IE->get_is_valid_data() == true)
       
   107 		{
       
   108 			status = m_supplicant_RSNA_IE.set_copy_of_buffer(
       
   109 				supplicant_RSNA_IE);
       
   110 			if (status != eap_status_ok)
       
   111 			{
       
   112 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   113 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   114 			}
       
   115 
       
   116 			EAP_TRACE_DATA_DEBUG(
       
   117 				m_am_tools,
       
   118 				TRACE_FLAGS_DEFAULT,
       
   119 				(EAPL("Supplicant RSN IE"),
       
   120 				get_supplicant_RSNA_IE()->get_data(
       
   121 					get_supplicant_RSNA_IE()->get_data_length()),
       
   122 				get_supplicant_RSNA_IE()->get_data_length()));
       
   123 		}
       
   124 		else
       
   125 		{
       
   126 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   127 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   128 		}
       
   129 	}
       
   130 
       
   131 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   132 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   133 }
       
   134 
       
   135 //--------------------------------------------------
       
   136 
       
   137 // 
       
   138 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize(
       
   139 	const eap_am_network_id_c * const receive_network_id,
       
   140 	const eapol_key_authentication_type_e authentication_type,
       
   141 	const eap_variable_data_c * const authenticator_RSNA_IE,
       
   142 	const eap_variable_data_c * const supplicant_RSNA_IE,
       
   143 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
       
   144 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
       
   145 	const eap_variable_data_c * const pre_shared_key)
       
   146 {
       
   147 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   148 
       
   149 	eap_status_e status(eap_status_process_general_error);
       
   150 
       
   151 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   152 
       
   153 	status = save_parameters(
       
   154 		authentication_type,
       
   155 		authenticator_RSNA_IE,
       
   156 		supplicant_RSNA_IE,
       
   157 		eapol_pairwise_cipher,
       
   158 		eapol_group_cipher);
       
   159 	if (status != eap_status_ok)
       
   160 	{
       
   161 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   162 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   163 	}
       
   164 
       
   165 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   166 
       
   167 	if ((m_authentication_type == eapol_key_authentication_type_RSNA_PSK
       
   168 		 || m_authentication_type == eapol_key_authentication_type_WPA_PSK)
       
   169 		&& (pre_shared_key == 0
       
   170 			|| pre_shared_key->get_is_valid_data() == false
       
   171 			|| pre_shared_key->get_data_length() < EAPOL_RSNA_PMK_LENGTH_BYTES))
       
   172 	{
       
   173 		if (pre_shared_key != 0)
       
   174 		{
       
   175 			EAP_TRACE_ERROR(
       
   176 				m_am_tools, 
       
   177 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
   178 				(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pre shared key 0x%08x, PSK length %d.\n"),
       
   179 				 pre_shared_key->get_data(pre_shared_key->get_data_length()),
       
   180 				pre_shared_key->get_data_length()));
       
   181 		}
       
   182 
       
   183 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   184 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
   185 	}
       
   186 	else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP
       
   187 		&& (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none))
       
   188 	{
       
   189 		EAP_TRACE_ERROR(
       
   190 			m_am_tools, 
       
   191 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
   192 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pairwise cipher suite %d.\n"),
       
   193 			m_eapol_pairwise_cipher));
       
   194 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   195 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
   196 	}
       
   197 	else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP
       
   198 		&& (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none))
       
   199 	{
       
   200 		EAP_TRACE_ERROR(
       
   201 			m_am_tools, 
       
   202 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
   203 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal group cipher suite %d.\n"),
       
   204 			m_eapol_group_cipher));
       
   205 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   206 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
   207 	}
       
   208 	else if (m_authentication_type == eapol_key_authentication_type_WPA_EAP
       
   209 		&& (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none))
       
   210 	{
       
   211 		EAP_TRACE_ERROR(
       
   212 			m_am_tools, 
       
   213 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
   214 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal pairwise cipher suite %d.\n"),
       
   215 			m_eapol_pairwise_cipher));
       
   216 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   217 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
   218 	}
       
   219 	else if (m_authentication_type == eapol_key_authentication_type_WPA_EAP
       
   220 		&& (m_eapol_group_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_none))
       
   221 	{
       
   222 		EAP_TRACE_ERROR(
       
   223 			m_am_tools, 
       
   224 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
   225 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::initialize(): illegal group cipher suite %d.\n"),
       
   226 			m_eapol_group_cipher));
       
   227 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   228 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
   229 	}
       
   230 	else if (m_authentication_type == eapol_key_authentication_type_802_1X)
       
   231 	{
       
   232 		// OK, cannot check the pairwise and group ciphers.
       
   233 		// AP will tell these in the EAPOL RC4 Key message.
       
   234 	}
       
   235 
       
   236 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   237 
       
   238 	status = set_mac_addresses(receive_network_id);
       
   239 	if (status != eap_status_ok)
       
   240 	{
       
   241 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   242 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   243 	}
       
   244 
       
   245 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   246 
       
   247 	set_eapol_key_state(eapol_key_state_none);
       
   248 	m_eapol_key_handshake_type = eapol_key_handshake_type_none;
       
   249 
       
   250 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   251 
       
   252 	if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK
       
   253 		|| m_authentication_type == eapol_key_authentication_type_WPA_PSK)
       
   254 	{
       
   255 		// Here we swap the addresses.
       
   256 		eap_am_network_id_c send_network_id(
       
   257 			m_am_tools,
       
   258 			receive_network_id->get_destination_id(),
       
   259 			receive_network_id->get_source_id(),
       
   260 			receive_network_id->get_type());
       
   261 		if (send_network_id.get_is_valid_data() == false)
       
   262 		{
       
   263 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   264 		}
       
   265 
       
   266 		status = set_pairwise_PMK(
       
   267 			pre_shared_key,
       
   268 			&send_network_id);
       
   269 		if (status != eap_status_ok)
       
   270 		{
       
   271 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   272 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   273 		}
       
   274 	}
       
   275 
       
   276 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   277 	{
       
   278 		m_is_associated = true;
       
   279 
       
   280 		EAP_TRACE_DEBUG(
       
   281 			m_am_tools, 
       
   282 			TRACE_FLAGS_DEFAULT, 
       
   283 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize(): m_is_associated=%s.\n"),
       
   284 			 (m_is_client == true) ? "client": "server",
       
   285 			 (m_is_associated == true) ? "true": "false"));
       
   286 	}
       
   287 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   288 
       
   289 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   290 }
       
   291 
       
   292 //--------------------------------------------------
       
   293 
       
   294 #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   295 
       
   296 // 
       
   297 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize(
       
   298 	const eap_am_network_id_c * const receive_network_id,
       
   299 	const eapol_key_authentication_type_e authentication_type)
       
   300 {
       
   301 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   302 
       
   303 	eap_status_e status(eap_status_process_general_error);
       
   304 
       
   305 	reset();
       
   306 
       
   307 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   308 
       
   309 	m_authentication_type = authentication_type;
       
   310 
       
   311 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   312 
       
   313 	status = set_mac_addresses(receive_network_id);
       
   314 	if (status != eap_status_ok)
       
   315 	{
       
   316 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   317 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   318 	}
       
   319 
       
   320 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   321 
       
   322 	set_eapol_key_state(eapol_key_state_none);
       
   323 	m_eapol_key_handshake_type = eapol_key_handshake_type_none;
       
   324 
       
   325 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   326 
       
   327 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   328 	// Creates SNonce. This is done here in early phase of authentication.
       
   329 	// This will reduce the CPU load when time critical first message
       
   330 	// of 4-Way handshake is processed.
       
   331 	status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES);
       
   332 	if (status != eap_status_ok)
       
   333 	{
       
   334 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   335 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   336 	}
       
   337 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   338 
       
   339 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   340 
       
   341 
       
   342 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   343 }
       
   344 
       
   345 #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   346 
       
   347 //--------------------------------------------------
       
   348 
       
   349 // 
       
   350 eap_status_e eapol_key_state_c::set_mac_addresses(
       
   351 	const eap_am_network_id_c * const receive_network_id)
       
   352 {
       
   353 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   354 
       
   355 	eap_status_e status(eap_status_process_general_error);
       
   356 
       
   357 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   358 
       
   359 	{
       
   360 		const eap_variable_data_c * authenticator_MAC_address = 0;
       
   361 		const eap_variable_data_c * supplicant_MAC_address = 0;
       
   362 
       
   363 		if (m_is_client == true)
       
   364 		{
       
   365 			authenticator_MAC_address = receive_network_id->get_source_id();
       
   366 			supplicant_MAC_address = receive_network_id->get_destination_id();
       
   367 		}
       
   368 		else
       
   369 		{
       
   370 			authenticator_MAC_address = receive_network_id->get_destination_id();
       
   371 			supplicant_MAC_address = receive_network_id->get_source_id();
       
   372 		}
       
   373 
       
   374 
       
   375 		status = m_authenticator_MAC_address.set_copy_of_buffer(
       
   376 			authenticator_MAC_address);
       
   377 		if (status != eap_status_ok)
       
   378 		{
       
   379 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   380 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   381 		}
       
   382 
       
   383 		status = m_supplicant_MAC_address.set_copy_of_buffer(
       
   384 			supplicant_MAC_address);
       
   385 		if (status != eap_status_ok)
       
   386 		{
       
   387 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   388 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   389 		}
       
   390 	}
       
   391 
       
   392 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   393 
       
   394 	{
       
   395 		const eap_variable_data_c * destination = 0;
       
   396 		const eap_variable_data_c * source = 0;
       
   397 
       
   398 		if (m_is_client == true)
       
   399 		{
       
   400 			destination = &m_authenticator_MAC_address;
       
   401 			source = &m_supplicant_MAC_address;
       
   402 		}
       
   403 		else
       
   404 		{
       
   405 			destination = &m_supplicant_MAC_address;
       
   406 			source = &m_authenticator_MAC_address;
       
   407 		}
       
   408 
       
   409 
       
   410 		eap_am_network_id_c send_network_id(m_am_tools,
       
   411 			source,
       
   412 			destination,
       
   413 			eapol_ethernet_type_pae);
       
   414 
       
   415 		status = m_send_network_id.set_copy_of_network_id(&send_network_id);
       
   416 		if (status != eap_status_ok)
       
   417 		{
       
   418 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   419 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   420 		}
       
   421 	}
       
   422 
       
   423 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   424 
       
   425 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   426 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   427 }
       
   428 
       
   429 //--------------------------------------------------
       
   430 
       
   431 // 
       
   432 EAP_FUNC_EXPORT eapol_key_state_c::~eapol_key_state_c()
       
   433 {
       
   434 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   435 
       
   436 	EAP_TRACE_DEBUG(
       
   437 		m_am_tools, 
       
   438 		TRACE_FLAGS_DEFAULT, 
       
   439 		(EAPL("EAPOL_KEY: eapol_key_state_c::~eapol_key_state_c(): this = 0x%08x => 0x%08x.\n"),
       
   440 		this,
       
   441 		dynamic_cast<abs_eap_base_timer_c *>(this)));
       
   442 
       
   443 	EAP_ASSERT(m_shutdown_was_called == true);
       
   444 
       
   445 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   446 }
       
   447 
       
   448 //--------------------------------------------------
       
   449 
       
   450 // 
       
   451 EAP_FUNC_EXPORT eapol_key_state_c::eapol_key_state_c(
       
   452 	abs_eap_am_tools_c * const tools,
       
   453 	abs_eapol_key_state_c * const key_state_partner,
       
   454 	abs_eapol_core_c * const eapol_partner,
       
   455 	const bool is_client_when_true,
       
   456 	const eap_am_network_id_c * const receive_network_id,
       
   457 	const eapol_key_authentication_type_e authentication_type,
       
   458 	const eap_variable_data_c * const authenticator_RSNA_IE,
       
   459 	const eap_variable_data_c * const supplicant_RSNA_IE,
       
   460 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
       
   461 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
       
   462 	const eap_variable_data_c * const pre_shared_key)
       
   463 	: m_am_tools(tools)
       
   464 	, m_key_state_partner(key_state_partner)
       
   465 	, m_eapol_partner(eapol_partner)
       
   466 	, m_send_network_id(tools)
       
   467 	, m_authenticator_RSNA_IE(tools)
       
   468 	, m_unicast_cipher_suite_RSNA_IE(tools)
       
   469 	, m_supplicant_RSNA_IE(tools)
       
   470 	, m_received_PMKID(tools)
       
   471 	, m_supplicant_MAC_address(tools)
       
   472 	, m_authenticator_MAC_address(tools)
       
   473 	, m_ANonce(tools)
       
   474 	, m_SNonce(tools)
       
   475 	, m_EAPOL_key_IV(tools)
       
   476 	, m_pairwise_PMK_WPXK3(tools)
       
   477 	, m_PMKID(tools)
       
   478 	, m_transient_PTK(tools)
       
   479 	, m_confirmation_KCK(tools)
       
   480 	, m_encryption_KEK(tools)
       
   481 	, m_temporal_TK(tools)
       
   482 	, m_group_GTK(tools)
       
   483 #if defined(EAP_USE_WPXM)
       
   484 	, m_WPXM_WPXK1(tools)
       
   485 	, m_WPXM_WPXK2(tools)
       
   486 	, m_WPXM_WPXC(eapol_key_constant_wpxm_initial_wpxc_counter_value)
       
   487 #endif //#if defined(EAP_USE_WPXM)
       
   488 	, m_group_GTK_ID(0u)
       
   489 	, m_group_GTK_Tx_bit(false)
       
   490 	, m_eapol_header_offset(0ul)
       
   491 	, m_MTU(0ul)
       
   492 	, m_trailer_length(0ul)
       
   493 	, m_retransmission(0)
       
   494 	, m_retransmission_time(EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT)
       
   495 	, m_retransmission_counter(EAPOL_KEY_STATE_RETRANSMISSION_COUNTER)
       
   496 	, m_handshake_timeout(EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT)
       
   497 #if defined(EAP_USE_WPXM)
       
   498 	, m_wpxm_reassociate_timeout(EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT)
       
   499 	, m_EAPOL_WPXM_key_descriptor_type(eapol_key_descriptor_type_none)
       
   500 #endif //#if defined(EAP_USE_WPXM)
       
   501 	, m_authentication_type(authentication_type)
       
   502 	, m_eapol_pairwise_cipher(eapol_pairwise_cipher)
       
   503 	, m_eapol_group_cipher(eapol_group_cipher)
       
   504 	, m_eapol_key_state(eapol_key_state_none)
       
   505 	, m_eapol_key_handshake_type(eapol_key_handshake_type_none)
       
   506 	, m_create_key_failure(eapol_key_state_none)
       
   507 	, m_pmksa_caching_timeout(EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT)
       
   508 	, m_key_reply_counter(0ul)
       
   509 	, m_client_send_key_reply_counter(0ul)
       
   510 	, m_is_client(is_client_when_true)
       
   511 	, m_is_valid(false)
       
   512 	, m_marked_removed(false)
       
   513 	, m_shutdown_was_called(false)
       
   514 	, m_allow_missing_PMKID_in_message_1(false)
       
   515 	, m_skip_PMKID_key_data_in_message_1(false)
       
   516 	, m_allow_non_zero_mic_and_reserved_in_message_1(false)
       
   517 	, m_indicate_pmkid_to_lower_layer(false)
       
   518 	, m_handshake_timeout_set(false)
       
   519 	, m_server_TEST_group_key_update(false)
       
   520 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   521 	, m_is_associated(false)
       
   522 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   523 {
       
   524 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   525 
       
   526 	EAP_UNREFERENCED_PARAMETER(receive_network_id);
       
   527 	EAP_UNREFERENCED_PARAMETER(authenticator_RSNA_IE);
       
   528 	EAP_UNREFERENCED_PARAMETER(supplicant_RSNA_IE);
       
   529 	EAP_UNREFERENCED_PARAMETER(pre_shared_key);
       
   530 
       
   531 	EAP_TRACE_DEBUG(
       
   532 		m_am_tools,
       
   533 		TRACE_FLAGS_DEFAULT,
       
   534 		(EAPL("eapol_key_state_c::eapol_key_state_c(1): %s\n"),
       
   535 		 (m_is_client == true) ? "client": "server"));
       
   536 
       
   537 	for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++)
       
   538 	{
       
   539 		m_received_802_1x_keys[key_type] = false;
       
   540 	}
       
   541 
       
   542 
       
   543 	set_is_valid();
       
   544 
       
   545 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   546 }
       
   547 
       
   548 //--------------------------------------------------
       
   549 
       
   550 // 
       
   551 EAP_FUNC_EXPORT eapol_key_state_c::eapol_key_state_c(
       
   552 	abs_eap_am_tools_c * const tools,
       
   553 	abs_eapol_key_state_c * const key_state_partner,
       
   554 	abs_eapol_core_c * const eapol_partner,
       
   555 	const bool is_client_when_true,
       
   556 	const eap_am_network_id_c * const /* receive_network_id */,
       
   557 	const eapol_key_authentication_type_e authentication_type)
       
   558 	: m_am_tools(tools)
       
   559 	, m_key_state_partner(key_state_partner)
       
   560 	, m_eapol_partner(eapol_partner)
       
   561 	, m_send_network_id(tools)
       
   562 	, m_authenticator_RSNA_IE(tools)
       
   563 	, m_unicast_cipher_suite_RSNA_IE(tools)
       
   564 	, m_supplicant_RSNA_IE(tools)
       
   565 	, m_received_PMKID(tools)
       
   566 	, m_supplicant_MAC_address(tools)
       
   567 	, m_authenticator_MAC_address(tools)
       
   568 	, m_ANonce(tools)
       
   569 	, m_SNonce(tools)
       
   570 	, m_EAPOL_key_IV(tools)
       
   571 	, m_pairwise_PMK_WPXK3(tools)
       
   572 	, m_PMKID(tools)
       
   573 	, m_transient_PTK(tools)
       
   574 	, m_confirmation_KCK(tools)
       
   575 	, m_encryption_KEK(tools)
       
   576 	, m_temporal_TK(tools)
       
   577 	, m_group_GTK(tools)
       
   578 #if defined(EAP_USE_WPXM)
       
   579 	, m_WPXM_WPXK1(tools)
       
   580 	, m_WPXM_WPXK2(tools)
       
   581 	, m_WPXM_WPXC(eapol_key_constant_wpxm_initial_wpxc_counter_value)
       
   582 #endif //#if defined(EAP_USE_WPXM)
       
   583 	, m_group_GTK_ID(0u)
       
   584 	, m_group_GTK_Tx_bit(false)
       
   585 	, m_eapol_header_offset(0ul)
       
   586 	, m_MTU(0ul)
       
   587 	, m_trailer_length(0ul)
       
   588 	, m_retransmission(0)
       
   589 	, m_retransmission_time(EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT)
       
   590 	, m_retransmission_counter(EAPOL_KEY_STATE_RETRANSMISSION_COUNTER)
       
   591 	, m_handshake_timeout(EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_TIMEOUT)
       
   592 #if defined(EAP_USE_WPXM)
       
   593 	, m_wpxm_reassociate_timeout(EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT)
       
   594 	, m_EAPOL_WPXM_key_descriptor_type(eapol_key_descriptor_type_none)
       
   595 #endif //#if defined(EAP_USE_WPXM)
       
   596 	, m_authentication_type(authentication_type)
       
   597 	, m_eapol_pairwise_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)
       
   598 	, m_eapol_group_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)
       
   599 	, m_eapol_key_state(eapol_key_state_none)
       
   600 	, m_eapol_key_handshake_type(eapol_key_handshake_type_none)
       
   601 	, m_create_key_failure(eapol_key_state_none)
       
   602 	, m_pmksa_caching_timeout(EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT)
       
   603 	, m_key_reply_counter(0ul)
       
   604 	, m_client_send_key_reply_counter(0ul)
       
   605 	, m_is_client(is_client_when_true)
       
   606 	, m_is_valid(false)
       
   607 	, m_marked_removed(false)
       
   608 	, m_shutdown_was_called(false)
       
   609 	, m_allow_missing_PMKID_in_message_1(false)
       
   610 	, m_skip_PMKID_key_data_in_message_1(false)
       
   611 	, m_allow_non_zero_mic_and_reserved_in_message_1(false)
       
   612 	, m_indicate_pmkid_to_lower_layer(false)
       
   613 	, m_handshake_timeout_set(false)
       
   614 	, m_server_TEST_group_key_update(false)
       
   615 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   616 	, m_is_associated(false)
       
   617 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
   618 {
       
   619 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   620 
       
   621 	EAP_TRACE_DEBUG(
       
   622 		m_am_tools,
       
   623 		TRACE_FLAGS_DEFAULT,
       
   624 		(EAPL("eapol_key_state_c::eapol_key_state_c(2): %s\n"),
       
   625 		 (m_is_client == true) ? "client": "server"));
       
   626 
       
   627 	for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++)
       
   628 	{
       
   629 		m_received_802_1x_keys[key_type] = false;
       
   630 	}
       
   631 
       
   632 	set_is_valid();
       
   633 
       
   634 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   635 }
       
   636 
       
   637 //--------------------------------------------------
       
   638 
       
   639 //
       
   640 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::configure()
       
   641 {
       
   642 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   643 
       
   644 	EAP_TRACE_DEBUG(
       
   645 		m_am_tools,
       
   646 		TRACE_FLAGS_DEFAULT,
       
   647 		(EAPL("eapol_key_state_c::configure(): %s\n"),
       
   648 		 (m_is_client == true) ? "client": "server"));
       
   649 
       
   650 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
   651 
       
   652 	m_eapol_header_offset = m_eapol_partner->get_header_offset(&m_MTU, &m_trailer_length);
       
   653 
       
   654 	for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++)
       
   655 	{
       
   656 		m_received_802_1x_keys[key_type] = false;
       
   657 	}
       
   658 
       
   659 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   660 
       
   661 	if (m_is_client == false)
       
   662 	{
       
   663 		eap_variable_data_c retransmission_time(m_am_tools);
       
   664 
       
   665 		eap_status_e status = m_key_state_partner->read_configure(
       
   666 			cf_str_EAPOL_key_state_retransmission_time.get_field(),
       
   667 			&retransmission_time);
       
   668 		if (status == eap_status_ok
       
   669 			&& retransmission_time.get_is_valid_data() == true)
       
   670 		{
       
   671 			u32_t *retransmission_time_value = reinterpret_cast<u32_t *>(
       
   672 				retransmission_time.get_data(sizeof(u32_t)));
       
   673 			if (retransmission_time_value != 0)
       
   674 			{
       
   675 				m_retransmission_time = *retransmission_time_value;
       
   676 			}
       
   677 			else
       
   678 			{
       
   679 				m_retransmission_time = EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT;
       
   680 			}
       
   681 		}
       
   682 		else
       
   683 		{
       
   684 			m_retransmission_time = EAPOL_KEY_STATE_TIMER_RETRANSMISSION_TIMEOUT;
       
   685 		}
       
   686 	}
       
   687 
       
   688 	if (m_is_client == false)
       
   689 	{
       
   690 		eap_variable_data_c retransmission_counter(m_am_tools);
       
   691 
       
   692 		eap_status_e status = m_key_state_partner->read_configure(
       
   693 			cf_str_EAPOL_key_state_retransmission_counter.get_field(),
       
   694 			&retransmission_counter);
       
   695 		if (status == eap_status_ok
       
   696 			&& retransmission_counter.get_is_valid_data() == true)
       
   697 		{
       
   698 			u32_t *retransmission_counter_value = reinterpret_cast<u32_t *>(
       
   699 				retransmission_counter.get_data(sizeof(u32_t)));
       
   700 			if (retransmission_counter_value != 0)
       
   701 			{
       
   702 				m_retransmission_counter = *retransmission_counter_value;
       
   703 			}
       
   704 		}
       
   705 	}
       
   706 
       
   707 	
       
   708 	{
       
   709 		eap_variable_data_c session_timeout(m_am_tools);
       
   710 
       
   711 		eap_status_e status = m_key_state_partner->read_configure(
       
   712 			cf_str_EAPOL_key_state_handshake_timeout.get_field(),
       
   713 			&session_timeout);
       
   714 		if (status == eap_status_ok
       
   715 			&& session_timeout.get_is_valid_data() == true)
       
   716 		{
       
   717 			u32_t *handler_timeout = reinterpret_cast<u32_t *>(
       
   718 				session_timeout.get_data(sizeof(u32_t)));
       
   719 			if (handler_timeout != 0)
       
   720 			{
       
   721 				m_handshake_timeout = *handler_timeout;
       
   722 			}
       
   723 		}
       
   724 	}
       
   725 
       
   726 
       
   727 #if defined(EAP_USE_WPXM)
       
   728 
       
   729 	{
       
   730 		eap_variable_data_c wpxm_reassociation_timeout(m_am_tools);
       
   731 
       
   732 		eap_status_e status = m_key_state_partner->read_configure(
       
   733 			cf_str_EAPOL_key_state_wpxm_reassociate_timeout.get_field(),
       
   734 			&wpxm_reassociation_timeout);
       
   735 		if (status == eap_status_ok
       
   736 			&& wpxm_reassociation_timeout.get_is_valid_data() == true)
       
   737 		{
       
   738 			u32_t *handler_timeout = reinterpret_cast<u32_t *>(
       
   739 				wpxm_reassociation_timeout.get_data(sizeof(u32_t)));
       
   740 			if (handler_timeout != 0)
       
   741 			{
       
   742 				m_wpxm_reassociate_timeout = *handler_timeout;
       
   743 			}
       
   744 		}
       
   745 	}
       
   746 
       
   747 
       
   748 	if (m_is_client == false)
       
   749 	{
       
   750 		eap_variable_data_c EAPOL_WPXM_type(m_am_tools);
       
   751 
       
   752 		eap_status_e status = m_key_state_partner->read_configure(
       
   753 			cf_str_EAPOL_WPXM_type.get_field(),
       
   754 			&EAPOL_WPXM_type);
       
   755 		if (status == eap_status_ok
       
   756 			&& EAPOL_WPXM_type.get_is_valid() == true
       
   757 			&& EAPOL_WPXM_type.get_data_length() > 0ul
       
   758 			&& EAPOL_WPXM_type.get_data(
       
   759 				EAPOL_WPXM_type.get_data_length()) != 0)
       
   760 		{
       
   761 			if (cf_str_EAPOL_key_authentication_type_config_value_RSNA_EAP
       
   762 				.get_field()->compare(
       
   763 					m_am_tools,
       
   764 					&EAPOL_WPXM_type) == true)
       
   765 			{
       
   766 				m_EAPOL_WPXM_key_descriptor_type = eapol_key_descriptor_type_RSNA;
       
   767 			}
       
   768 			else if (cf_str_EAPOL_key_authentication_type_config_value_WPA_EAP
       
   769 					 .get_field()->compare(
       
   770 						 m_am_tools,
       
   771 						 &EAPOL_WPXM_type) == true)
       
   772 			{
       
   773 				m_EAPOL_WPXM_key_descriptor_type = eapol_key_descriptor_type_WPA;
       
   774 			}
       
   775 		}
       
   776 	}
       
   777 
       
   778 #endif //#if defined(EAP_USE_WPXM)
       
   779 
       
   780 
       
   781 	{
       
   782 		eap_variable_data_c pmksa_caching_timeout(m_am_tools);
       
   783 
       
   784 		eap_status_e status = m_key_state_partner->read_configure(
       
   785 			cf_str_EAPOL_key_state_pmksa_caching_timeout.get_field(),
       
   786 			&pmksa_caching_timeout);
       
   787 		if (status == eap_status_ok
       
   788 			&& pmksa_caching_timeout.get_is_valid_data() == true)
       
   789 		{
       
   790 			u32_t *handler_timeout = reinterpret_cast<u32_t *>(
       
   791 				pmksa_caching_timeout.get_data(sizeof(u32_t)));
       
   792 			if (handler_timeout != 0)
       
   793 			{
       
   794 				m_pmksa_caching_timeout = *handler_timeout;
       
   795 			}
       
   796 		}
       
   797 	}
       
   798 
       
   799 
       
   800 	if (m_is_client == true)
       
   801 	{
       
   802 		{
       
   803 			eap_variable_data_c allow_missing_PMKID_in_message_1(m_am_tools);
       
   804 
       
   805 			eap_status_e status = m_key_state_partner->read_configure(
       
   806 				cf_str_EAPOL_key_state_allow_missing_PMKID_in_message_1.get_field(),
       
   807 				&allow_missing_PMKID_in_message_1);
       
   808 			if (status == eap_status_ok
       
   809 				&& allow_missing_PMKID_in_message_1.get_is_valid_data() == true)
       
   810 			{
       
   811 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   812 					allow_missing_PMKID_in_message_1.get_data(sizeof(u32_t)));
       
   813 				if (flag != 0
       
   814 					&& *flag != 0)
       
   815 				{
       
   816 					m_allow_missing_PMKID_in_message_1 = true;
       
   817 				}
       
   818 			}
       
   819 		}
       
   820 
       
   821 		{
       
   822 			eap_variable_data_c allow_non_zero_mic_in_message_1(m_am_tools);
       
   823 
       
   824 			eap_status_e status = m_key_state_partner->read_configure(
       
   825 				cf_str_EAPOL_key_state_allow_non_zero_mic_in_message_1.get_field(),
       
   826 				&allow_non_zero_mic_in_message_1);
       
   827 			if (status == eap_status_ok
       
   828 				&& allow_non_zero_mic_in_message_1.get_is_valid_data() == true)
       
   829 			{
       
   830 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   831 					allow_non_zero_mic_in_message_1.get_data(sizeof(u32_t)));
       
   832 				if (flag != 0
       
   833 					&& *flag != 0)
       
   834 				{
       
   835 					m_allow_non_zero_mic_and_reserved_in_message_1 = true;
       
   836 				}
       
   837 			}
       
   838 		}
       
   839 
       
   840 		{
       
   841 			eap_variable_data_c indicate_pmkid_to_lower_layer(m_am_tools);
       
   842 
       
   843 			eap_status_e status = m_key_state_partner->read_configure(
       
   844 				cf_str_EAPOL_key_state_indicate_pmkid_to_lower_layer.get_field(),
       
   845 				&indicate_pmkid_to_lower_layer);
       
   846 			if (status == eap_status_ok
       
   847 				&& indicate_pmkid_to_lower_layer.get_is_valid_data() == true)
       
   848 			{
       
   849 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   850 					indicate_pmkid_to_lower_layer.get_data(sizeof(u32_t)));
       
   851 				if (flag != 0
       
   852 					&& *flag != 0)
       
   853 				{
       
   854 					m_indicate_pmkid_to_lower_layer = true;
       
   855 				}
       
   856 			}
       
   857 		}
       
   858 
       
   859 	}
       
   860 
       
   861 	if (m_is_client == false)
       
   862 	{
       
   863 		{
       
   864 			eap_variable_data_c skip_PMKID_key_data_in_message_1(m_am_tools);
       
   865 
       
   866 			eap_status_e status = m_key_state_partner->read_configure(
       
   867 				cf_str_EAPOL_key_state_skip_PMKID_key_data_in_message_1.get_field(),
       
   868 				&skip_PMKID_key_data_in_message_1);
       
   869 			if (status == eap_status_ok
       
   870 				&& skip_PMKID_key_data_in_message_1.get_is_valid_data() == true)
       
   871 			{
       
   872 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   873 					skip_PMKID_key_data_in_message_1.get_data(sizeof(u32_t)));
       
   874 				if (flag != 0
       
   875 					&& *flag != 0)
       
   876 				{
       
   877 					m_skip_PMKID_key_data_in_message_1 = true;
       
   878 				}
       
   879 			}
       
   880 		}
       
   881 
       
   882 		{
       
   883 			eap_variable_data_c EAPOL_key_state_TEST_group_key_update(m_am_tools);
       
   884 
       
   885 			eap_status_e status = m_key_state_partner->read_configure(
       
   886 				cf_str_EAPOL_key_state_TEST_group_key_update.get_field(),
       
   887 				&EAPOL_key_state_TEST_group_key_update);
       
   888 			if (status == eap_status_ok
       
   889 				&& EAPOL_key_state_TEST_group_key_update.get_is_valid_data() == true)
       
   890 			{
       
   891 				u32_t *flag = reinterpret_cast<u32_t *>(
       
   892 					EAPOL_key_state_TEST_group_key_update.get_data(sizeof(u32_t)));
       
   893 				if (flag != 0
       
   894 					&& *flag != 0)
       
   895 				{
       
   896 					m_server_TEST_group_key_update = true;
       
   897 				}
       
   898 			}
       
   899 		}
       
   900 
       
   901 	}
       
   902 
       
   903 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   904 
       
   905 	eap_status_e status(eap_status_ok);
       
   906 
       
   907 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
   908 
       
   909 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   910 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   911 }
       
   912 
       
   913 //--------------------------------------------------
       
   914 
       
   915 void eapol_key_state_c::send_error_notification(const eap_status_e error)
       
   916 {
       
   917 	// Notifies the lower level of an authentication error.
       
   918 	eap_state_notification_c notification(
       
   919 		m_am_tools,
       
   920 		&m_send_network_id,
       
   921 		m_is_client,
       
   922 		eap_state_notification_generic,
       
   923 		eap_protocol_layer_general,
       
   924 		eapol_key_handshake_type_none,
       
   925 		eap_state_none,
       
   926 		eap_general_state_authentication_error,
       
   927 		0,
       
   928 		false);
       
   929 
       
   930 	notification.set_authentication_error(error);
       
   931 
       
   932 	m_key_state_partner->state_notification(&notification);
       
   933 }
       
   934 
       
   935 //--------------------------------------------------
       
   936 
       
   937 //
       
   938 eap_status_e eapol_key_state_c::set_reassociation_parameters(
       
   939 	const eap_variable_data_c * const pairwise_PMK_WPXK3,
       
   940 	const eap_variable_data_c * const PMKID,
       
   941 	const eap_variable_data_c * const transient_PTK,
       
   942 	const eap_variable_data_c * const confirmation_KCK,
       
   943 	const eap_variable_data_c * const encryption_KEK,
       
   944 	const eap_variable_data_c * const temporal_TK,
       
   945 	const eap_variable_data_c * const WPXM_WPXK1,
       
   946 	const eap_variable_data_c * const WPXM_WPXK2,
       
   947 	const u32_t WPXM_WPXC,
       
   948 	const eapol_key_handshake_type_e eapol_key_handshake_type,
       
   949 	const eapol_key_authentication_type_e authentication_type
       
   950 	)
       
   951 {
       
   952 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   953 
       
   954 	eapol_key_state_string_c state_string;
       
   955 	EAP_TRACE_DEBUG(
       
   956 		m_am_tools, 
       
   957 		TRACE_FLAGS_DEFAULT, 
       
   958 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_reassociation_parameters(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
   959 		 (m_is_client == true) ? "client": "server",
       
   960 		 this,
       
   961 		 get_eapol_key_state(),
       
   962 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
   963 		 m_authentication_type,
       
   964 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
   965 
       
   966 	eap_status_e status = m_pairwise_PMK_WPXK3.set_copy_of_buffer(pairwise_PMK_WPXK3);
       
   967 	if (status != eap_status_ok)
       
   968 	{
       
   969 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   970 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   971 	}
       
   972 
       
   973 	status = m_PMKID.set_copy_of_buffer(PMKID);
       
   974 	if (status != eap_status_ok)
       
   975 	{
       
   976 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   977 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   978 	}
       
   979 
       
   980 	status = m_transient_PTK.set_copy_of_buffer(transient_PTK);
       
   981 	if (status != eap_status_ok)
       
   982 	{
       
   983 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   984 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   985 	}
       
   986 
       
   987 	status = m_confirmation_KCK.set_copy_of_buffer(confirmation_KCK);
       
   988 	if (status != eap_status_ok)
       
   989 	{
       
   990 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   991 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   992 	}
       
   993 
       
   994 	status = m_encryption_KEK.set_copy_of_buffer(encryption_KEK);
       
   995 	if (status != eap_status_ok)
       
   996 	{
       
   997 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   998 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   999 	}
       
  1000 
       
  1001 	status = m_temporal_TK.set_copy_of_buffer(temporal_TK);
       
  1002 	if (status != eap_status_ok)
       
  1003 	{
       
  1004 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1005 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1006 	}
       
  1007 
       
  1008 #if defined(EAP_USE_WPXM)
       
  1009 	status = m_WPXM_WPXK1.set_copy_of_buffer(WPXM_WPXK1);
       
  1010 	if (status != eap_status_ok)
       
  1011 	{
       
  1012 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1013 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1014 	}
       
  1015 
       
  1016 	status = m_WPXM_WPXK2.set_copy_of_buffer(WPXM_WPXK2);
       
  1017 	if (status != eap_status_ok)
       
  1018 	{
       
  1019 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1020 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1021 	}
       
  1022 
       
  1023 	m_WPXM_WPXC = WPXM_WPXC;
       
  1024 
       
  1025 	EAP_TRACE_DEBUG(
       
  1026 		m_am_tools, 
       
  1027 		TRACE_FLAGS_DEFAULT, 
       
  1028 		(EAPL("EAPOL_KEY: eapol_key_state_c::set_reassociation_parameters(): ")
       
  1029 		 EAPL("Set m_WPXM_WPXC=%d.\n"),
       
  1030 		 m_WPXM_WPXC));
       
  1031 
       
  1032 
       
  1033 	m_eapol_key_handshake_type = eapol_key_handshake_type;
       
  1034 	m_authentication_type = authentication_type;
       
  1035 #else
       
  1036 	EAP_UNREFERENCED_PARAMETER(WPXM_WPXK1);
       
  1037 	EAP_UNREFERENCED_PARAMETER(WPXM_WPXK2);
       
  1038 	EAP_UNREFERENCED_PARAMETER(WPXM_WPXC);
       
  1039 #endif //#if defined(EAP_USE_WPXM)
       
  1040 
       
  1041 	set_eapol_key_state(eapol_key_state_preauthenticated);
       
  1042 
       
  1043 	EAP_TRACE_DEBUG(
       
  1044 		m_am_tools, 
       
  1045 		TRACE_FLAGS_DEFAULT, 
       
  1046 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_reassociation_parameters(): m_authentication_type=%s, ")
       
  1047 		 EAPL("m_eapol_pairwise_cipher=%d, m_eapol_group_cipher=%d.\n"),
       
  1048 		 (m_is_client == true) ? "client": "server",
       
  1049 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type),
       
  1050 		 m_eapol_pairwise_cipher,
       
  1051 		 m_eapol_group_cipher));
       
  1052 	
       
  1053 
       
  1054 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1055 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1056 }
       
  1057 
       
  1058 //--------------------------------------------------
       
  1059 
       
  1060 //
       
  1061 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::started_eap_authentication()
       
  1062 {
       
  1063 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1064 
       
  1065 	EAP_TRACE_DEBUG(
       
  1066 		m_am_tools,
       
  1067 		TRACE_FLAGS_DEFAULT,
       
  1068 		(EAPL("eapol_key_state_c::started_eap_authentication(): %s\n"),
       
  1069 		 (m_is_client == true) ? "client": "server"));
       
  1070 
       
  1071 	(void) cancel_handshake_timeout();
       
  1072 	(void) cancel_reassociate_timeout();
       
  1073 	(void) cancel_pmksa_caching_timeout();
       
  1074 	(void) cancel_4_way_handshake_start_timeout();
       
  1075 
       
  1076 
       
  1077 	{
       
  1078 		// Indicates lower layers the EAP authentication is running.
       
  1079 		eap_state_notification_c * notification = new eap_state_notification_c(
       
  1080 			m_am_tools,
       
  1081 			&m_send_network_id,
       
  1082 			m_is_client,
       
  1083 			eap_state_notification_generic,
       
  1084 			eap_protocol_layer_eapol_key,
       
  1085 			eapol_key_handshake_type_none,
       
  1086 			eapol_key_state_eap_authentication_running,
       
  1087 			eapol_key_state_eap_authentication_running,
       
  1088 			0ul,
       
  1089 			false);
       
  1090 		if (notification == 0)
       
  1091 		{
       
  1092 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1093 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1094 		}
       
  1095 		m_key_state_partner->state_notification(notification);
       
  1096 
       
  1097 		delete notification;
       
  1098 	}
       
  1099 
       
  1100 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1101 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1102 }
       
  1103 
       
  1104 //--------------------------------------------------
       
  1105 
       
  1106 //
       
  1107 EAP_FUNC_EXPORT eapol_key_state_c *eapol_key_state_c::copy(const eap_am_network_id_c * const receive_network_id)
       
  1108 {
       
  1109 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1110 
       
  1111 	eapol_key_state_c * const new_state = new eapol_key_state_c(
       
  1112 		m_am_tools,
       
  1113 		m_key_state_partner,
       
  1114 		m_eapol_partner,
       
  1115 		m_is_client,
       
  1116 		receive_network_id,
       
  1117 		m_authentication_type,
       
  1118 		&m_authenticator_RSNA_IE,
       
  1119 		&m_supplicant_RSNA_IE,
       
  1120 		m_eapol_pairwise_cipher,
       
  1121 		m_eapol_group_cipher,
       
  1122 		&m_pairwise_PMK_WPXK3);
       
  1123 
       
  1124 	if (new_state == 0)
       
  1125 	{
       
  1126 		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1127 		return 0;
       
  1128 	}
       
  1129 
       
  1130 	if (new_state->get_is_valid() == false)
       
  1131 	{
       
  1132 		new_state->shutdown();
       
  1133 		delete new_state;
       
  1134 		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1135 		return 0;
       
  1136 	}
       
  1137 
       
  1138 	eap_status_e status = new_state->configure();
       
  1139 	if (status != eap_status_ok)
       
  1140 	{
       
  1141 		new_state->shutdown();
       
  1142 		delete new_state;
       
  1143 		(void) EAP_STATUS_RETURN(m_am_tools, status);
       
  1144 		return 0;
       
  1145 	}
       
  1146 
       
  1147 
       
  1148 #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  1149 
       
  1150 	status = new_state->initialize(
       
  1151 		receive_network_id,
       
  1152 		m_authentication_type);
       
  1153 	if (status != eap_status_ok)
       
  1154 	{
       
  1155 		new_state->shutdown();
       
  1156 		delete new_state;
       
  1157 		(void) EAP_STATUS_RETURN(m_am_tools, status);
       
  1158 		return 0;
       
  1159 	}
       
  1160 
       
  1161 #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  1162 
       
  1163 
       
  1164 	eapol_key_handshake_type_e eapol_key_handshake_type(m_eapol_key_handshake_type);
       
  1165 
       
  1166 	eapol_key_authentication_type_e authentication_type(m_authentication_type);
       
  1167 
       
  1168 #if defined(EAP_USE_WPXM)
       
  1169 	if (authentication_type == eapol_key_authentication_type_WPXM)
       
  1170 	{
       
  1171 		eapol_key_handshake_type = eapol_key_handshake_type_WPXM_reassociation;
       
  1172 	}
       
  1173 #endif //#if defined(EAP_USE_WPXM)
       
  1174 
       
  1175 
       
  1176 	status = new_state->set_reassociation_parameters(
       
  1177 		&m_pairwise_PMK_WPXK3,
       
  1178 		&m_PMKID,
       
  1179 		&m_transient_PTK,
       
  1180 		&m_confirmation_KCK,
       
  1181 		&m_encryption_KEK,
       
  1182 		&m_temporal_TK,
       
  1183 #if defined(EAP_USE_WPXM)
       
  1184 		&m_WPXM_WPXK1,
       
  1185 		&m_WPXM_WPXK2,
       
  1186 		m_WPXM_WPXC,
       
  1187 #else
       
  1188 		0,
       
  1189 		0,
       
  1190 		0ul,
       
  1191 #endif //#if defined(EAP_USE_WPXM)
       
  1192 		eapol_key_handshake_type,
       
  1193 		authentication_type
       
  1194 		);
       
  1195 	if (status != eap_status_ok)
       
  1196 	{
       
  1197 		new_state->shutdown();
       
  1198 		delete new_state;
       
  1199 		(void) EAP_STATUS_RETURN(m_am_tools, status);
       
  1200 		return 0;
       
  1201 	}
       
  1202 
       
  1203 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1204 	return new_state;
       
  1205 }
       
  1206 
       
  1207 //--------------------------------------------------
       
  1208 
       
  1209 //
       
  1210 eap_status_e eapol_key_state_c::handshake_failure_notification()
       
  1211 {
       
  1212 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1213 
       
  1214 	eapol_key_state_string_c eapol_key_state_string;
       
  1215 
       
  1216 	EAP_TRACE_DEBUG(
       
  1217 		m_am_tools,
       
  1218 		TRACE_FLAGS_DEFAULT,
       
  1219 		(EAPL("eapol_key_state_c::handshake_failure_notification(): %s, m_eapol_key_handshake_type=%s, get_eapol_key_state()=%s\n"),
       
  1220 		 (m_is_client == true) ? "client": "server",
       
  1221 		 eapol_key_state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type),
       
  1222 		 eapol_key_state_string.get_eapol_key_state_string(get_eapol_key_state())));
       
  1223 
       
  1224 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  1225 
       
  1226 	if (m_eapol_key_handshake_type == eapol_key_handshake_type_4_way_handshake)
       
  1227 	{
       
  1228 		if (get_eapol_key_state() == eapol_key_state_preauthenticated)
       
  1229 		{
       
  1230 			// Do not notify lower layer.
       
  1231 			EAP_TRACE_ALWAYS(
       
  1232 				m_am_tools,
       
  1233 				TRACE_FLAGS_DEFAULT,
       
  1234 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Does not notify pre-authenticated state.\n"),
       
  1235 				(m_is_client == true ? "client": "server")));
       
  1236 		}
       
  1237 		else if (get_eapol_key_state() == eapol_key_state_none)
       
  1238 		{
       
  1239 			EAP_TRACE_ALWAYS(
       
  1240 				m_am_tools,
       
  1241 				TRACE_FLAGS_DEFAULT,
       
  1242 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"),
       
  1243 				(m_is_client == true ? "client": "server")));
       
  1244 		}
       
  1245 		else if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull)
       
  1246 		{
       
  1247 			// This is notification to eapol_core_c object.
       
  1248 			// 4-Way Handshake terminated unsuccessfully.
       
  1249 			eap_state_notification_c notification(
       
  1250 				m_am_tools,
       
  1251 				&m_send_network_id,
       
  1252 				m_is_client,
       
  1253 				eap_state_notification_generic,
       
  1254 				eap_protocol_layer_eapol_key,
       
  1255 				eapol_key_handshake_type_4_way_handshake,
       
  1256 				eapol_key_state_4_way_handshake_failed,
       
  1257 				eapol_key_state_802_11i_authentication_terminated_unsuccessfull,
       
  1258 				0ul,
       
  1259 				false);
       
  1260 
       
  1261 			notification.set_authentication_error(eap_status_authentication_failure);
       
  1262 
       
  1263 			m_key_state_partner->state_notification(&notification);
       
  1264 
       
  1265 			set_eapol_key_state(eapol_key_state_4_way_handshake_failed);
       
  1266 
       
  1267 			EAP_TRACE_ALWAYS(
       
  1268 				m_am_tools,
       
  1269 				TRACE_FLAGS_DEFAULT,
       
  1270 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): 4-Way Handshake FAILED\n"),
       
  1271 				(m_is_client == true ? "client": "server")));
       
  1272 		}
       
  1273 	}
       
  1274 	else if (m_eapol_key_handshake_type == eapol_key_handshake_type_group_key_handshake)
       
  1275 	{
       
  1276 		if (get_eapol_key_state() == eapol_key_state_preauthenticated)
       
  1277 		{
       
  1278 			// Do not notify lower layer.
       
  1279 			EAP_TRACE_ALWAYS(
       
  1280 				m_am_tools,
       
  1281 				TRACE_FLAGS_DEFAULT,
       
  1282 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Does not notify pre-authenticated state.\n"),
       
  1283 				(m_is_client == true ? "client": "server")));
       
  1284 		}
       
  1285 		else if (get_eapol_key_state() == eapol_key_state_none)
       
  1286 		{
       
  1287 			EAP_TRACE_ALWAYS(
       
  1288 				m_am_tools,
       
  1289 				TRACE_FLAGS_DEFAULT,
       
  1290 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"),
       
  1291 				(m_is_client == true ? "client": "server")));
       
  1292 		}
       
  1293 		else if (get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull)
       
  1294 		{
       
  1295 			// This is notification to eapol_core_c object.
       
  1296 			// Group Key Handshake terminated unsuccessfully.
       
  1297 			eap_state_notification_c notification(
       
  1298 				m_am_tools,
       
  1299 				&m_send_network_id,
       
  1300 				m_is_client,
       
  1301 				eap_state_notification_generic,
       
  1302 				eap_protocol_layer_eapol_key,
       
  1303 				eapol_key_handshake_type_group_key_handshake,
       
  1304 				eapol_key_state_group_key_handshake_failed,
       
  1305 				eapol_key_state_802_11i_authentication_terminated_unsuccessfull,
       
  1306 				0ul,
       
  1307 				false);
       
  1308 
       
  1309 			notification.set_authentication_error(eap_status_authentication_failure);
       
  1310 
       
  1311 			m_key_state_partner->state_notification(&notification);
       
  1312 
       
  1313 			set_eapol_key_state(eapol_key_state_4_way_handshake_failed);
       
  1314 
       
  1315 			EAP_TRACE_ALWAYS(
       
  1316 				m_am_tools,
       
  1317 				TRACE_FLAGS_DEFAULT,
       
  1318 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Group Key Handshake FAILED\n"),
       
  1319 				(m_is_client == true ? "client": "server")));
       
  1320 		}
       
  1321 	}
       
  1322 	else if (m_eapol_key_handshake_type == eapol_key_handshake_type_none)
       
  1323 	{
       
  1324 		EAP_TRACE_ALWAYS(
       
  1325 			m_am_tools,
       
  1326 			TRACE_FLAGS_DEFAULT,
       
  1327 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unused EAPOL Key state.\n"),
       
  1328 			(m_is_client == true ? "client": "server")));
       
  1329 	}
       
  1330 	else
       
  1331 	{
       
  1332 		EAP_UNREFERENCED_PARAMETER(eapol_key_state_string);
       
  1333 
       
  1334 		set_eapol_key_state(eapol_key_state_4_way_handshake_failed);
       
  1335 
       
  1336 		EAP_TRACE_ALWAYS(
       
  1337 			m_am_tools,
       
  1338 			TRACE_FLAGS_DEFAULT,
       
  1339 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::handshake_failure_notification(): Unknown Handshake FAILED\n"),
       
  1340 			(m_is_client == true ? "client": "server")));
       
  1341 	}
       
  1342 
       
  1343 
       
  1344 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1345 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1346 }
       
  1347 
       
  1348 //--------------------------------------------------
       
  1349 
       
  1350 //
       
  1351 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::shutdown()
       
  1352 {
       
  1353 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1354 
       
  1355 	EAP_TRACE_DEBUG(
       
  1356 		m_am_tools,
       
  1357 		TRACE_FLAGS_DEFAULT,
       
  1358 		(EAPL("eapol_key_state_c::shutdown(): %s\n"),
       
  1359 		 (m_is_client == true) ? "client": "server"));
       
  1360 
       
  1361 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  1362 
       
  1363 	if (m_shutdown_was_called == true)
       
  1364 	{
       
  1365 		EAP_TRACE_DEBUG(
       
  1366 			m_am_tools,
       
  1367 			TRACE_FLAGS_DEFAULT,
       
  1368 			(EAPL("eapol_key_state_c::shutdown(): Already called.\n")));
       
  1369 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1370 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1371 	}
       
  1372 	m_shutdown_was_called = true;
       
  1373 
       
  1374 	// This will cancel all timers of this object.
       
  1375 	cancel_retransmission();
       
  1376 	cancel_handshake_timeout();
       
  1377 	cancel_pmksa_caching_timeout();
       
  1378 	cancel_reassociate_timeout();
       
  1379 	cancel_4_way_handshake_start_timeout();
       
  1380 
       
  1381 	eap_status_e status = handshake_failure_notification();
       
  1382 
       
  1383 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1384 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1385 }
       
  1386 
       
  1387 //--------------------------------------------------
       
  1388 
       
  1389 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_s_nonce(
       
  1390 	const eap_variable_data_c * const s_nonce)
       
  1391 {
       
  1392 	eap_status_e status = m_SNonce.set_copy_of_buffer(s_nonce);
       
  1393 
       
  1394 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1395 }
       
  1396 
       
  1397 //--------------------------------------------------
       
  1398 
       
  1399 //
       
  1400 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::check_pmksa_cache(
       
  1401 	const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
       
  1402 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
       
  1403 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite)
       
  1404 {
       
  1405 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1406 
       
  1407 	EAP_TRACE_DEBUG(
       
  1408 		m_am_tools,
       
  1409 		TRACE_FLAGS_DEFAULT,
       
  1410 		(EAPL("eapol_key_state_c::check_pmksa_cache(): %s\n"),
       
  1411 		 (m_is_client == true) ? "client": "server"));
       
  1412 
       
  1413 	eap_status_e status = eap_status_ok;
       
  1414 
       
  1415 	eapol_key_state_string_c state_string;
       
  1416 	EAP_TRACE_DEBUG(
       
  1417 		m_am_tools, 
       
  1418 		TRACE_FLAGS_DEFAULT, 
       
  1419 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::check_pmksa_cache(): this = 0x%08x, state %d=%s, selected_eapol_key_authentication_type %d=%s, m_authentication_type %d=%s.\n"),
       
  1420 		 (m_is_client == true) ? "client": "server",
       
  1421 		 this,
       
  1422 		 get_eapol_key_state(),
       
  1423 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  1424 		 selected_eapol_key_authentication_type,
       
  1425 		 state_string.get_eapol_key_authentication_type_string(selected_eapol_key_authentication_type),
       
  1426 		 m_authentication_type,
       
  1427 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  1428 
       
  1429 
       
  1430 	if (selected_eapol_key_authentication_type != eapol_key_authentication_type_RSNA_EAP
       
  1431 		&& selected_eapol_key_authentication_type != eapol_key_authentication_type_RSNA_PSK
       
  1432 		&& selected_eapol_key_authentication_type != eapol_key_authentication_type_WPXM)
       
  1433 	{
       
  1434 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
  1435 	}
       
  1436 	else if (selected_eapol_key_authentication_type != m_authentication_type
       
  1437 		|| pairwise_key_cipher_suite != m_eapol_pairwise_cipher
       
  1438 		|| group_key_cipher_suite != m_eapol_group_cipher)
       
  1439 	{
       
  1440 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_cipher_suite);
       
  1441 	}
       
  1442 
       
  1443 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1444 }
       
  1445 
       
  1446 //--------------------------------------------------
       
  1447 
       
  1448 // 
       
  1449 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::initialize_preauthentication(
       
  1450 	const eap_am_network_id_c * const receive_network_id,
       
  1451 	const eapol_key_authentication_type_e authentication_type)
       
  1452 {
       
  1453 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1454 
       
  1455 	eapol_key_state_string_c state_string;
       
  1456 	EAP_TRACE_DEBUG(
       
  1457 		m_am_tools, 
       
  1458 		TRACE_FLAGS_DEFAULT, 
       
  1459 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::initialize_preauthentication(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  1460 		 (m_is_client == true) ? "client": "server",
       
  1461 		 this,
       
  1462 		 get_eapol_key_state(),
       
  1463 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  1464 		 m_authentication_type,
       
  1465 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  1466 
       
  1467 	eap_status_e status(eap_status_process_general_error);
       
  1468 
       
  1469 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1470 
       
  1471 	if (m_authentication_type != authentication_type)
       
  1472 	{
       
  1473 		// Illegal authentication type, must be the same as previously used.
       
  1474 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1475 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1476 	}
       
  1477 
       
  1478 	if (m_authentication_type == eapol_key_authentication_type_none
       
  1479 		|| m_authentication_type == eapol_key_authentication_type_RSNA_PSK
       
  1480 		|| m_authentication_type == eapol_key_authentication_type_WPA_PSK
       
  1481 		|| m_authentication_type == eapol_key_authentication_type_802_1X)
       
  1482 	{
       
  1483 		// Illegal authentication type.
       
  1484 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1485 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1486 	}
       
  1487 
       
  1488 	set_eapol_key_state(eapol_key_state_none);
       
  1489 	m_eapol_key_handshake_type = eapol_key_handshake_type_none;
       
  1490 
       
  1491 	reset();
       
  1492 
       
  1493 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1494 
       
  1495 	status = set_mac_addresses(receive_network_id);
       
  1496 	if (status != eap_status_ok)
       
  1497 	{
       
  1498 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1499 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1500 	}
       
  1501 
       
  1502 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1503 
       
  1504 	set_eapol_key_state(eapol_key_state_none);
       
  1505 	m_eapol_key_handshake_type = eapol_key_handshake_type_none;
       
  1506 
       
  1507 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1508 }
       
  1509 
       
  1510 //--------------------------------------------------
       
  1511 
       
  1512 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::read_reassociation_parameters(
       
  1513 	const eap_am_network_id_c * const /* receive_network_id */, ///< source includes remote address, destination includes local address.
       
  1514 	const eapol_key_authentication_type_e required_authentication_type,
       
  1515 	eap_variable_data_c * const PMKID,
       
  1516 	const eap_variable_data_c * const received_WPA_ie,
       
  1517 	const eap_variable_data_c * const sent_WPA_ie)
       
  1518 {
       
  1519 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1520 
       
  1521 	eapol_key_state_string_c state_string;
       
  1522 	EAP_TRACE_DEBUG(
       
  1523 		m_am_tools, 
       
  1524 		TRACE_FLAGS_DEFAULT, 
       
  1525 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::read_reassociation_parameters(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  1526 		 (m_is_client == true) ? "client": "server",
       
  1527 		 this,
       
  1528 		 get_eapol_key_state(),
       
  1529 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  1530 		 m_authentication_type,
       
  1531 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  1532 
       
  1533 
       
  1534 	(void) cancel_pmksa_caching_timeout();
       
  1535 	(void) cancel_handshake_timeout();
       
  1536 	(void) cancel_reassociate_timeout();
       
  1537 	(void) cancel_4_way_handshake_start_timeout();
       
  1538 
       
  1539 	eap_status_e status(eap_status_process_general_error);
       
  1540 
       
  1541 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1542 
       
  1543 	if (received_WPA_ie != 0
       
  1544 		&& received_WPA_ie->get_is_valid_data() == true)
       
  1545 	{
       
  1546 		status = m_authenticator_RSNA_IE.set_copy_of_buffer(received_WPA_ie);
       
  1547 		if (status != eap_status_ok)
       
  1548 		{
       
  1549 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1550 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1551 		}
       
  1552 	}
       
  1553 
       
  1554 	if (sent_WPA_ie != 0
       
  1555 		&& sent_WPA_ie->get_is_valid_data() == true)
       
  1556 	{
       
  1557 		status = m_supplicant_RSNA_IE.set_copy_of_buffer(sent_WPA_ie);
       
  1558 		if (status != eap_status_ok)
       
  1559 		{
       
  1560 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1561 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1562 		}
       
  1563 	}
       
  1564 
       
  1565 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  1566 
       
  1567 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  1568 	// Creates SNonce. This is done here in early phase of authentication.
       
  1569 	// This will reduce the CPU load when time critical first message
       
  1570 	// of 4-Way handshake is processed.
       
  1571 	status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES);
       
  1572 	if (status != eap_status_ok)
       
  1573 	{
       
  1574 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1575 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1576 	}
       
  1577 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  1578 
       
  1579 	status = init_handshake_timeout(m_handshake_timeout);
       
  1580 	if (status != eap_status_ok)
       
  1581 	{
       
  1582 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1583 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1584 	}
       
  1585 
       
  1586 
       
  1587 	if (get_eapol_key_state() != eapol_key_state_preauthenticated
       
  1588 		|| m_authentication_type != required_authentication_type)
       
  1589 	{
       
  1590 		EAP_TRACE_DEBUG(
       
  1591 			m_am_tools, 
       
  1592 			TRACE_FLAGS_DEFAULT, 
       
  1593 			(EAPL("ERROR: EAPOL_KEY: %s: eapol_key_state_c::read_reassociation_parameters(): this = 0x%08x, (get_eapol_key_state()=%d=%s) != (eapol_key_state_preauthenticated)\n"),
       
  1594 			 (m_is_client == true) ? "client": "server",
       
  1595 			 this,
       
  1596 			 get_eapol_key_state(),
       
  1597 			 state_string.get_eapol_key_state_string(get_eapol_key_state())));
       
  1598 
       
  1599 		EAP_TRACE_DEBUG(
       
  1600 			m_am_tools, 
       
  1601 			TRACE_FLAGS_DEFAULT, 
       
  1602 			(EAPL("ERROR: EAPOL_KEY: %s: || (m_authentication_type=%d=%s) != (required_authentication_type=%d=%s)\n"),
       
  1603 			 (m_is_client == true) ? "client": "server",
       
  1604 			 m_authentication_type,
       
  1605 			 state_string.get_eapol_key_authentication_type_string(m_authentication_type),
       
  1606 			 required_authentication_type,
       
  1607 			 state_string.get_eapol_key_authentication_type_string(required_authentication_type)));
       
  1608 
       
  1609 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1610 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  1611 	}
       
  1612 
       
  1613 	if (get_is_RSNA() == true)
       
  1614 	{
       
  1615 		if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false)
       
  1616 		{
       
  1617 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1618 			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  1619 		}
       
  1620 
       
  1621 		status = create_PMKID();
       
  1622 		if (status != eap_status_ok)
       
  1623 		{
       
  1624 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1625 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1626 		}
       
  1627 
       
  1628 
       
  1629 		status = PMKID->set_copy_of_buffer(&m_PMKID);
       
  1630 		if (status != eap_status_ok)
       
  1631 		{
       
  1632 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1633 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1634 		}
       
  1635 	}
       
  1636 #if defined(EAP_USE_WPXM)
       
  1637 	else if (get_is_WPXM() == true)
       
  1638 	{
       
  1639 		// We need to create a new PTKn.
       
  1640 		++m_WPXM_WPXC;
       
  1641 
       
  1642 		EAP_TRACE_DEBUG(
       
  1643 			m_am_tools, 
       
  1644 			TRACE_FLAGS_DEFAULT, 
       
  1645 			(EAPL("EAPOL_KEY: eapol_key_state_c::read_reassociation_parameters(): ")
       
  1646 			 EAPL("m_WPXM_WPXC=%d.\n"),
       
  1647 			 m_WPXM_WPXC));		
       
  1648 		
       
  1649 		status = derive_WPXM_PTK(m_WPXM_WPXC);
       
  1650 		if (status != eap_status_ok)
       
  1651 		{
       
  1652 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1653 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1654 		}
       
  1655 
       
  1656 		status = init_reassociate_timeout(m_wpxm_reassociate_timeout);
       
  1657 		if (status != eap_status_ok)
       
  1658 		{
       
  1659 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1660 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1661 		}
       
  1662 
       
  1663 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1664 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1665 	}
       
  1666 #endif //#if defined(EAP_USE_WPXM)
       
  1667 	else
       
  1668 	{
       
  1669 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1670 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  1671 	}
       
  1672 
       
  1673 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1674 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1675 }
       
  1676 
       
  1677 //--------------------------------------------------
       
  1678 
       
  1679 //
       
  1680 eap_status_e eapol_key_state_c::complete_reassociation(
       
  1681 	const eapol_wlan_authentication_state_e reassociation_result,
       
  1682 	const eap_am_network_id_c * const /* receive_network_id */,
       
  1683 	const eapol_key_authentication_type_e authentication_type,
       
  1684 	const eap_variable_data_c * const received_WPA_IE,
       
  1685 	const eap_variable_data_c * const sent_WPA_IE,
       
  1686 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
       
  1687 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
       
  1688 	)
       
  1689 {
       
  1690 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1691 
       
  1692 	EAP_TRACE_DEBUG(
       
  1693 		m_am_tools,
       
  1694 		TRACE_FLAGS_DEFAULT,
       
  1695 		(EAPL("eapol_key_state_c::complete_reassociation(): %s\n"),
       
  1696 		 (m_is_client == true) ? "client": "server"));
       
  1697 
       
  1698 	eap_status_e status(eap_status_process_general_error);
       
  1699 
       
  1700 	if (get_eapol_key_state() != eapol_key_state_preauthenticated
       
  1701 		|| m_authentication_type != authentication_type)
       
  1702 	{
       
  1703 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1704 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  1705 	}
       
  1706 
       
  1707 	if (reassociation_result == eapol_wlan_authentication_state_association_ok)
       
  1708 	{
       
  1709 		if (get_is_RSNA() == true)
       
  1710 		{
       
  1711 			status = allow_4_way_handshake();
       
  1712 			if (status != eap_status_ok)
       
  1713 			{
       
  1714 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1715 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1716 			}
       
  1717 
       
  1718 			status = save_parameters(
       
  1719 				authentication_type,
       
  1720 				received_WPA_IE,
       
  1721 				sent_WPA_IE,
       
  1722 				pairwise_key_cipher_suite,
       
  1723 				group_key_cipher_suite);
       
  1724 			if (status != eap_status_ok)
       
  1725 			{
       
  1726 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1727 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1728 			}
       
  1729 		}
       
  1730 #if defined(EAP_USE_WPXM)
       
  1731 		else if (get_is_WPXM() == true)
       
  1732 		{
       
  1733 			// OK, nothing to do here.
       
  1734 			status = eap_status_ok;
       
  1735 		}
       
  1736 #endif //#if defined(EAP_USE_WPXM)
       
  1737 		else
       
  1738 		{
       
  1739 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1740 			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  1741 		}
       
  1742 
       
  1743 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  1744 		{
       
  1745 			m_is_associated = true;
       
  1746 
       
  1747 			EAP_TRACE_DEBUG(
       
  1748 				m_am_tools, 
       
  1749 				TRACE_FLAGS_DEFAULT, 
       
  1750 				(EAPL("EAPOL_KEY: %s: eapol_key_state_c::complete_reassociation(): m_is_associated=%s.\n"),
       
  1751 				 (m_is_client == true) ? "client": "server",
       
  1752 				 (m_is_associated == true) ? "true": "false"));
       
  1753 		}
       
  1754 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  1755 
       
  1756 	}
       
  1757 	else
       
  1758 	{
       
  1759 		// Reassociation failed, clean-up state.
       
  1760 		reset();
       
  1761 
       
  1762 		// Timeout value zero will remove state immediately.
       
  1763 		status = init_handshake_timeout(0ul);
       
  1764 		if (status != eap_status_ok)
       
  1765 		{
       
  1766 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1767 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1768 		}
       
  1769 	}
       
  1770 
       
  1771 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  1772 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1773 }
       
  1774 
       
  1775 //--------------------------------------------------
       
  1776 
       
  1777 //
       
  1778 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_RSNA()
       
  1779 {
       
  1780 	return (m_authentication_type == eapol_key_authentication_type_RSNA_EAP
       
  1781 		|| m_authentication_type == eapol_key_authentication_type_RSNA_PSK);
       
  1782 }
       
  1783 
       
  1784 //--------------------------------------------------
       
  1785 
       
  1786 //
       
  1787 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_WPA()
       
  1788 {
       
  1789 	return (m_authentication_type == eapol_key_authentication_type_WPA_EAP
       
  1790 		|| m_authentication_type == eapol_key_authentication_type_WPA_PSK);
       
  1791 }
       
  1792 
       
  1793 //--------------------------------------------------
       
  1794 
       
  1795 //
       
  1796 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::asynchronous_init_remove_eapol_key_state()
       
  1797 {
       
  1798 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1799 
       
  1800 	eap_status_e status = handshake_failure_notification();
       
  1801 	if (status != eap_status_ok)
       
  1802 	{
       
  1803 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1804 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1805 	}
       
  1806 
       
  1807 	status = m_key_state_partner->asynchronous_init_remove_eapol_key_state(
       
  1808 		&m_send_network_id);
       
  1809 
       
  1810 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1811 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1812 }
       
  1813 
       
  1814 //--------------------------------------------------
       
  1815 
       
  1816 //
       
  1817 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::timer_expired(
       
  1818 	const u32_t id, void *data)
       
  1819 {
       
  1820 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1821 	EAP_UNREFERENCED_PARAMETER(data);
       
  1822 
       
  1823 	eap_status_e status = eap_status_process_general_error;
       
  1824 
       
  1825 	EAP_TRACE_DEBUG(
       
  1826 		m_am_tools,
       
  1827 		TRACE_FLAGS_DEFAULT,
       
  1828 		(EAPL("TIMER: EAPOL_KEY: %s: [0x%08x]->eapol_key_state_c::timer_expired(id 0x%02x, data 0x%08x).\n"),
       
  1829 		 (m_is_client == true ? "client": "server"),
       
  1830 		 this,
       
  1831 		 id,
       
  1832 		 data));
       
  1833 
       
  1834 	if (id == EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID)
       
  1835 	{
       
  1836 		eapol_key_state_string_c state_string;
       
  1837 		EAP_TRACE_DEBUG(
       
  1838 			m_am_tools,
       
  1839 			TRACE_FLAGS_DEFAULT,
       
  1840 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID expired, eapol_key_state=%d=%s\n"),
       
  1841 			 (m_is_client == true ? "client": "server"),
       
  1842 			 get_eapol_key_state(),
       
  1843 			 state_string.get_eapol_key_state_string(get_eapol_key_state())));
       
  1844 
       
  1845 		if ((m_is_client == true
       
  1846 			&& get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_3)
       
  1847 			|| (m_is_client == false
       
  1848 				&& get_eapol_key_state() == eapol_key_state_wait_4_way_handshake_message_2))
       
  1849 		{
       
  1850 			if (m_authentication_type == eapol_key_authentication_type_RSNA_PSK
       
  1851 				|| m_authentication_type == eapol_key_authentication_type_WPA_PSK)
       
  1852 			{
       
  1853 				// Most propably the PSK is incorrect.
       
  1854 				// There could be other problems too.
       
  1855 				send_error_notification(eap_status_wrong_password);
       
  1856 			}
       
  1857 			else if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP
       
  1858 					|| m_authentication_type == eapol_key_authentication_type_WPA_EAP
       
  1859 					|| m_authentication_type == eapol_key_authentication_type_802_1X
       
  1860 					|| m_authentication_type == eapol_key_authentication_type_WPXM)
       
  1861 			{
       
  1862 				send_error_notification(eap_status_authentication_failure);
       
  1863 			}
       
  1864 		}
       
  1865 		else if (get_eapol_key_state() != eapol_key_state_none)
       
  1866 		{
       
  1867 			send_error_notification(eap_status_authentication_failure);
       
  1868 		}
       
  1869 
       
  1870 		// Terminate the session.
       
  1871 		status = asynchronous_init_remove_eapol_key_state();
       
  1872 	}
       
  1873 	else if (id == EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID)
       
  1874 	{
       
  1875 		EAP_TRACE_DEBUG(
       
  1876 			m_am_tools, 
       
  1877 			TRACE_FLAGS_DEFAULT, 
       
  1878 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID elapsed.\n"),
       
  1879 			 (m_is_client == true ? "client": "server")));
       
  1880 
       
  1881 		if (m_retransmission != 0
       
  1882 			&& m_retransmission->get_is_valid() == true
       
  1883 			&& m_retransmission->get_retransmission_counter() > 0)
       
  1884 		{
       
  1885 			EAP_TRACE_DEBUG(
       
  1886 				m_am_tools,
       
  1887 				TRACE_FLAGS_DEFAULT,
       
  1888 				(EAPL("TIMER: EAPOL_KEY: new retransmission, m_retransmission->get_is_valid()=%d, ")
       
  1889 				 EAPL("m_retransmission->get_retransmission_counter()=%d.\n"),
       
  1890 				m_retransmission->get_is_valid(),
       
  1891 				m_retransmission->get_retransmission_counter()));
       
  1892 
       
  1893 			// This packet send is initialized by timer event.
       
  1894 			status = resend_packet(
       
  1895 				m_retransmission->get_send_network_id(),
       
  1896 				m_retransmission->get_sent_packet(),
       
  1897 				m_retransmission->get_header_offset(),
       
  1898 				m_retransmission->get_data_length(),
       
  1899 				m_retransmission->get_buffer_size()
       
  1900 				);
       
  1901 
       
  1902 			if (status == eap_status_ok)
       
  1903 			{
       
  1904 				if (m_retransmission->get_retransmission_counter() > 0u)
       
  1905 				{
       
  1906 					// OK, initialize the next time to retransmit.
       
  1907 					u32_t next_retransmission_time(m_retransmission->get_next_retransmission_time());
       
  1908 
       
  1909 					status = m_key_state_partner->set_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, 0,
       
  1910 						next_retransmission_time);
       
  1911 					if (status != eap_status_ok)
       
  1912 					{
       
  1913 						delete m_retransmission;
       
  1914 						m_retransmission = 0;
       
  1915 					}
       
  1916 					else
       
  1917 					{
       
  1918 						m_retransmission->get_next_retransmission_counter(); // This decrements the counter.
       
  1919 
       
  1920 						EAP_TRACE_DEBUG(
       
  1921 							m_am_tools, 
       
  1922 							TRACE_FLAGS_DEFAULT, 
       
  1923 							(EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID set %d ms, retransmission_counter %d.\n"),
       
  1924 							next_retransmission_time,
       
  1925 							m_retransmission->get_retransmission_counter()));
       
  1926 					}
       
  1927 				}
       
  1928 
       
  1929 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1930 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1931 			}
       
  1932 			else
       
  1933 			{
       
  1934 				delete m_retransmission;
       
  1935 				m_retransmission = 0;
       
  1936 
       
  1937 				status = eap_status_ok;
       
  1938 
       
  1939 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1940 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1941 			}
       
  1942 		}
       
  1943 		else
       
  1944 		{
       
  1945 			EAP_TRACE_DEBUG(
       
  1946 				m_am_tools, 
       
  1947 				TRACE_FLAGS_DEFAULT, 
       
  1948 				(EAPL("TIMER: EAPOL_KEY: no retransmission, m_retransmission=0x%08x.\n"),
       
  1949 				m_retransmission));
       
  1950 			if (m_retransmission != 0)
       
  1951 			{
       
  1952 				EAP_TRACE_DEBUG(
       
  1953 					m_am_tools, 
       
  1954 					TRACE_FLAGS_DEFAULT, 
       
  1955 					(EAPL("TIMER: EAPOL_KEY: no retransmission, m_retransmission->get_is_valid()=%d, ")
       
  1956 					 EAPL("m_retransmission->get_retransmission_counter()=%d.\n"),
       
  1957 					m_retransmission->get_is_valid(),
       
  1958 					m_retransmission->get_retransmission_counter()));
       
  1959 			}
       
  1960 
       
  1961 			// No good EAPOL-Key-Response received to EAPOL-Key-Requests.
       
  1962 			// Terminate the session.
       
  1963 			status = asynchronous_init_remove_eapol_key_state();
       
  1964 		}
       
  1965 	}
       
  1966 	else if (id == EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID)
       
  1967 	{
       
  1968 		EAP_TRACE_DEBUG(
       
  1969 			m_am_tools,
       
  1970 			TRACE_FLAGS_DEFAULT,
       
  1971 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID expired.\n"),
       
  1972 			 (m_is_client == true ? "client": "server")));
       
  1973 
       
  1974 		// Caching timeout.
       
  1975 		// Remove the cached session.
       
  1976 		status = asynchronous_init_remove_eapol_key_state();
       
  1977 	}
       
  1978 #if defined(EAP_USE_WPXM)
       
  1979 	else if (id == EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID)
       
  1980 	{
       
  1981 		EAP_TRACE_DEBUG(
       
  1982 			m_am_tools,
       
  1983 			TRACE_FLAGS_DEFAULT,
       
  1984 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID expired.\n"),
       
  1985 			 (m_is_client == true ? "client": "server")));
       
  1986 
       
  1987 			eap_state_notification_c notification(
       
  1988 				m_am_tools,
       
  1989 				&m_send_network_id,
       
  1990 				m_is_client,
       
  1991 				eap_state_notification_generic,
       
  1992 				eap_protocol_layer_eapol_key,
       
  1993 				eapol_key_handshake_type_WPXM_reassociation,
       
  1994 				get_eapol_key_state(),
       
  1995 				eapol_key_state_reassociation_failed,
       
  1996 				0ul,
       
  1997 				false);
       
  1998 
       
  1999 			notification.set_authentication_error(eap_status_authentication_failure);
       
  2000 
       
  2001 			m_key_state_partner->state_notification(&notification);
       
  2002 
       
  2003 		// Remove the cached session.
       
  2004 		status = asynchronous_init_remove_eapol_key_state();
       
  2005 	}
       
  2006 #endif //#if defined(EAP_USE_WPXM)
       
  2007 	else if (id == EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID)
       
  2008 	{
       
  2009 		EAP_TRACE_DEBUG(
       
  2010 			m_am_tools,
       
  2011 			TRACE_FLAGS_DEFAULT,
       
  2012 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID expired.\n"),
       
  2013 			 (m_is_client == true ? "client": "server")));
       
  2014 		
       
  2015 		// Here we swap the addresses.
       
  2016 		eap_am_network_id_c receive_network_id(m_am_tools,
       
  2017 			m_send_network_id.get_destination_id(),
       
  2018 			m_send_network_id.get_source_id(),
       
  2019 			m_send_network_id.get_type());
       
  2020 		if (receive_network_id.get_is_valid_data() == false)
       
  2021 		{
       
  2022 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2023 		}
       
  2024 
       
  2025 		status = start_group_key_handshake(
       
  2026 			&receive_network_id,
       
  2027 			eapol_protocol_version_2,
       
  2028 #if defined(EAP_USE_WPXM)
       
  2029 			m_EAPOL_WPXM_key_descriptor_type
       
  2030 #else
       
  2031 			eapol_key_descriptor_type_RSNA
       
  2032 #endif //#if defined(EAP_USE_WPXM)
       
  2033 			);
       
  2034 		if (status != eap_status_ok)
       
  2035 		{
       
  2036 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2037 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2038 		}
       
  2039 	}
       
  2040 	else if (id == EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID)
       
  2041 	{
       
  2042 		EAP_TRACE_DEBUG(
       
  2043 			m_am_tools,
       
  2044 			TRACE_FLAGS_DEFAULT,
       
  2045 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID expired.\n"),
       
  2046 			 (m_is_client == true ? "client": "server")));
       
  2047 		
       
  2048 		// Here we swap the addresses.
       
  2049 		eap_am_network_id_c receive_network_id(m_am_tools,
       
  2050 			m_send_network_id.get_destination_id(),
       
  2051 			m_send_network_id.get_source_id(),
       
  2052 			m_send_network_id.get_type());
       
  2053 		if (receive_network_id.get_is_valid_data() == false)
       
  2054 		{
       
  2055 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2056 		}
       
  2057 
       
  2058 		status = initialize_4_way_handshake(
       
  2059 			&receive_network_id,
       
  2060 			eapol_protocol_version_2);
       
  2061 		if (status != eap_status_ok)
       
  2062 		{
       
  2063 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2064 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2065 		}
       
  2066 	}
       
  2067 
       
  2068 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2069 }
       
  2070 
       
  2071 //--------------------------------------------------
       
  2072 
       
  2073 //
       
  2074 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::timer_delete_data(
       
  2075 	const u32_t id, void *data)
       
  2076 {
       
  2077 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2078 	EAP_UNREFERENCED_PARAMETER(data);
       
  2079 
       
  2080 	EAP_TRACE_DEBUG(
       
  2081 		m_am_tools,
       
  2082 		TRACE_FLAGS_DEFAULT,
       
  2083 		(EAPL("TIMER: EAPOL_KEY: %s: [0x%08x]->eapol_key_state_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"),
       
  2084 		 (m_is_client == true) ? "client": "server",
       
  2085 		 this,
       
  2086 		 id,
       
  2087 		 data));
       
  2088 	
       
  2089 	if (id == EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID)
       
  2090 	{
       
  2091 		// Nothing to delete.
       
  2092 	}
       
  2093 	else if (id == EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID)
       
  2094 	{
       
  2095 		if (m_retransmission != 0
       
  2096 			&& m_retransmission->get_is_valid() == true
       
  2097 			&& m_retransmission->get_retransmission_counter() > 0)
       
  2098 		{
       
  2099 			// Do not delete yet.
       
  2100 			// cancel_retransmission() will delete m_retransmission.
       
  2101 		}
       
  2102 		else if (m_retransmission != 0)
       
  2103 		{
       
  2104 			delete m_retransmission;
       
  2105 			m_retransmission = 0;
       
  2106 		}
       
  2107 	}
       
  2108 
       
  2109 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2110 }
       
  2111 
       
  2112 //--------------------------------------------------
       
  2113 
       
  2114 
       
  2115 //
       
  2116 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::trace_eapol_key_message(
       
  2117 	const i8_t * const prefix,
       
  2118 	eapol_RSNA_key_header_c * const eapol_key_message)
       
  2119 {
       
  2120 	EAP_UNREFERENCED_PARAMETER(prefix);
       
  2121 	EAP_UNREFERENCED_PARAMETER(eapol_key_message);
       
  2122 
       
  2123 #if defined(USE_EAP_TRACE)
       
  2124 
       
  2125 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2126 
       
  2127 	u32_t  key_replay_counter_high = static_cast<u32_t>(eap_shift_right_64_bit(
       
  2128 		eapol_key_message->get_key_replay_counter(), 32));
       
  2129 	u32_t  key_replay_counter_low = static_cast<u32_t>(eapol_key_message->get_key_replay_counter());
       
  2130 
       
  2131 	EAP_UNREFERENCED_PARAMETER(key_replay_counter_high);
       
  2132 	EAP_UNREFERENCED_PARAMETER(key_replay_counter_low);
       
  2133 
       
  2134 	if (get_is_RSNA() == true)
       
  2135 	{
       
  2136 		EAP_TRACE_DEBUG(
       
  2137 			m_am_tools,
       
  2138 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2139 			(EAPL("EAPOL_KEY: %s (0x%08x): eapol version 0x%02x, eapol packet type 0x%02x, ")
       
  2140 			 EAPL("eapol packet body length 0x%04x\n"),
       
  2141 			 prefix,
       
  2142 			 (eapol_key_message),
       
  2143 			 (eapol_key_message)->get_eapol_protocol_version(),
       
  2144 			 (eapol_key_message)->get_eapol_packet_type(),
       
  2145 			 (eapol_key_message)->get_eapol_packet_body_length()
       
  2146 			 ));
       
  2147 
       
  2148 		EAP_TRACE_DEBUG(
       
  2149 			m_am_tools,
       
  2150 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2151 			(EAPL("EAPOL_KEY: %s (0x%08x): eapol key descriptor type 0x%02x, ")
       
  2152 			 EAPL("key information 0x%04x, ")
       
  2153 			 EAPL("key information key descriptor version 0x%01x\n"),
       
  2154 			 prefix,
       
  2155 			 (eapol_key_message),
       
  2156 			 (eapol_key_message)->get_key_descriptor_type(),
       
  2157 			 (eapol_key_message)->get_key_information(),
       
  2158 			 (eapol_key_message)->get_key_information_key_descriptor_version()
       
  2159 			 ));
       
  2160 
       
  2161 		EAP_TRACE_DEBUG(
       
  2162 			m_am_tools,
       
  2163 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2164 			(EAPL("EAPOL_KEY: %s (0x%08x): key information key type 0x%01x, ")
       
  2165 			 EAPL("key information reserved 0x%01x, ")
       
  2166 			 EAPL("key information install 0x%01x\n"),
       
  2167 			 prefix,
       
  2168 			 (eapol_key_message),
       
  2169 			 (eapol_key_message)->get_key_information_key_type(),
       
  2170 			 (eapol_key_message)->get_key_information_reserved_a(),
       
  2171 			 (eapol_key_message)->get_key_information_install()
       
  2172 			 ));
       
  2173 
       
  2174 		EAP_TRACE_DEBUG(
       
  2175 			m_am_tools,
       
  2176 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2177 			(EAPL("EAPOL_KEY: %s (0x%08x): key information key ack 0x%01x, ")
       
  2178 			 EAPL("key information key MIC 0x%01x, ")
       
  2179 			 EAPL("key information secure 0x%01x\n"),
       
  2180 			 prefix,
       
  2181 			 (eapol_key_message),
       
  2182 			 (eapol_key_message)->get_key_information_key_ack(),
       
  2183 			 (eapol_key_message)->get_key_information_key_MIC(),
       
  2184 			 (eapol_key_message)->get_key_information_secure()
       
  2185 			 ));
       
  2186 
       
  2187 		EAP_TRACE_DEBUG(
       
  2188 			m_am_tools,
       
  2189 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2190 			(EAPL("EAPOL_KEY: %s (0x%08x): key information error 0x%01x, ")
       
  2191 			 EAPL("key information request 0x%01x, ")
       
  2192 			 EAPL("key information encrypted key data 0x%01x\n"),
       
  2193 			 prefix,
       
  2194 			 (eapol_key_message),
       
  2195 			 (eapol_key_message)->get_key_information_error(),
       
  2196 			 (eapol_key_message)->get_key_information_request(),
       
  2197 			 (eapol_key_message)->get_key_information_encrypted_key_data()
       
  2198 			 ));
       
  2199 
       
  2200 		EAP_TRACE_DEBUG(
       
  2201 			m_am_tools,
       
  2202 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2203 			(EAPL("EAPOL_KEY: %s (0x%08x): key information reserved 0x%01x, ")
       
  2204 			 EAPL("key length 0x%04x, key reply counter 0x%08x%08x\n"),
       
  2205 			 prefix,
       
  2206 			 (eapol_key_message),
       
  2207 			 (eapol_key_message)->get_key_information_reserved_b(),
       
  2208 			 (eapol_key_message)->get_key_length(),
       
  2209 			 key_replay_counter_high,
       
  2210 			 key_replay_counter_low
       
  2211 			 ));
       
  2212 	}
       
  2213 	else if (get_is_WPA() == true
       
  2214 #if defined(EAP_USE_WPXM)
       
  2215 		|| get_is_WPXM() == true
       
  2216 #endif //#if defined(EAP_USE_WPXM)
       
  2217 		)
       
  2218 	{
       
  2219 		// According to 802.11i D3.0
       
  2220 
       
  2221 		EAP_TRACE_DEBUG(
       
  2222 			m_am_tools,
       
  2223 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2224 			(EAPL("EAPOL_KEY: %s (0x%08x): eapol version 0x%02x, eapol packet type 0x%02x, ")
       
  2225 			 EAPL("eapol packet body length 0x%04x\n"),
       
  2226 			 prefix,
       
  2227 			 (eapol_key_message),
       
  2228 			 (eapol_key_message)->get_eapol_protocol_version(),
       
  2229 			 (eapol_key_message)->get_eapol_packet_type(),
       
  2230 			 (eapol_key_message)->get_eapol_packet_body_length()
       
  2231 			 ));
       
  2232 
       
  2233 		EAP_TRACE_DEBUG(
       
  2234 			m_am_tools,
       
  2235 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2236 			(EAPL("EAPOL_KEY: %s (0x%08x): eapol key descriptor type 0x%02x, ")
       
  2237 			 EAPL("key information 0x%04x, ")
       
  2238 			 EAPL("key information key descriptor version 0x%01x\n"),
       
  2239 			 prefix,
       
  2240 			 (eapol_key_message),
       
  2241 			 (eapol_key_message)->get_key_descriptor_type(),
       
  2242 			 (eapol_key_message)->get_key_information(),
       
  2243 			 (eapol_key_message)->get_key_information_key_descriptor_version()
       
  2244 			 ));
       
  2245 
       
  2246 		EAP_TRACE_DEBUG(
       
  2247 			m_am_tools,
       
  2248 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2249 			(EAPL("EAPOL_KEY: %s (0x%08x): key information key type 0x%01x, ")
       
  2250 			 EAPL("key information key index 0x%01x, ")
       
  2251 			 EAPL("key information install 0x%01x\n"),
       
  2252 			 prefix,
       
  2253 			 (eapol_key_message),
       
  2254 			 (eapol_key_message)->get_key_information_key_type(),
       
  2255 			 (eapol_key_message)->get_key_information_key_index(),
       
  2256 			 (eapol_key_message)->get_key_information_install()
       
  2257 			 ));
       
  2258 
       
  2259 		EAP_TRACE_DEBUG(
       
  2260 			m_am_tools,
       
  2261 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2262 			(EAPL("EAPOL_KEY: %s (0x%08x): key information key ack 0x%01x, ")
       
  2263 			 EAPL("key information key MIC 0x%01x, ")
       
  2264 			 EAPL("key information secure 0x%01x\n"),
       
  2265 			 prefix,
       
  2266 			 (eapol_key_message),
       
  2267 			 (eapol_key_message)->get_key_information_key_ack(),
       
  2268 			 (eapol_key_message)->get_key_information_key_MIC(),
       
  2269 			 (eapol_key_message)->get_key_information_secure()
       
  2270 			 ));
       
  2271 
       
  2272 		EAP_TRACE_DEBUG(
       
  2273 			m_am_tools,
       
  2274 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2275 			(EAPL("EAPOL_KEY: %s (0x%08x): key information error 0x%01x, ")
       
  2276 			 EAPL("key information request 0x%01x, ")
       
  2277 			 EAPL("key information encrypted key data 0x%01x\n"),
       
  2278 			 prefix,
       
  2279 			 (eapol_key_message),
       
  2280 			 (eapol_key_message)->get_key_information_error(),
       
  2281 			 (eapol_key_message)->get_key_information_request(),
       
  2282 			 (eapol_key_message)->get_key_information_encrypted_key_data()
       
  2283 			 ));
       
  2284 
       
  2285 		EAP_TRACE_DEBUG(
       
  2286 			m_am_tools,
       
  2287 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2288 			(EAPL("EAPOL_KEY: %s (0x%08x): key information reserved 0x%02x, ")
       
  2289 			 EAPL("key length 0x%04x, key reply counter 0x%08x%08x\n"),
       
  2290 			 prefix,
       
  2291 			 (eapol_key_message),
       
  2292 			 (eapol_key_message)->get_key_information_reserved_b(),
       
  2293 			 (eapol_key_message)->get_key_length(),
       
  2294 			 key_replay_counter_high,
       
  2295 			 key_replay_counter_low
       
  2296 			 ));
       
  2297 	}
       
  2298 	else
       
  2299 	{
       
  2300 		// ERROR.
       
  2301 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2302 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  2303 	}
       
  2304 
       
  2305 	EAP_TRACE_DATA_DEBUG(
       
  2306 		m_am_tools,
       
  2307 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2308 		(EAPL("key nonce"),
       
  2309 		 (eapol_key_message)->get_key_NONCE(),
       
  2310 		 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_NONCE_SIZE));
       
  2311 
       
  2312 	EAP_TRACE_DATA_DEBUG(
       
  2313 		m_am_tools,
       
  2314 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2315 		(EAPL("EAPOL-Key IV"),
       
  2316 		 (eapol_key_message)->get_EAPOL_key_IV(),
       
  2317 		 eapol_RSNA_key_header_c::EAPOL_RSNA_EAPOL_KEY_IV_SIZE));
       
  2318 
       
  2319 	EAP_TRACE_DATA_DEBUG(
       
  2320 		m_am_tools,
       
  2321 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2322 		(EAPL("Key RSC"),
       
  2323 		 (eapol_key_message)->get_key_RSC(),
       
  2324 		 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RSC_SIZE));
       
  2325 
       
  2326 	EAP_TRACE_DATA_DEBUG(
       
  2327 		m_am_tools,
       
  2328 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2329 		(EAPL("STA MAC address"),
       
  2330 		 (eapol_key_message)->get_key_STA_MAC_address(),
       
  2331 		 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_STA_MAC_ADDRESS_SIZE));
       
  2332 
       
  2333 	EAP_TRACE_DATA_DEBUG(
       
  2334 		m_am_tools,
       
  2335 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2336 		(EAPL("reserved"),
       
  2337 		 (eapol_key_message)->get_key_reserved(),
       
  2338 		 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_RESERVED_SIZE));
       
  2339 
       
  2340 	EAP_TRACE_DATA_DEBUG(
       
  2341 		m_am_tools,
       
  2342 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2343 		(EAPL("Key MIC"),
       
  2344 		 (eapol_key_message)->get_key_MIC(),
       
  2345 		 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE));
       
  2346 
       
  2347 	EAP_TRACE_DATA_DEBUG(
       
  2348 		m_am_tools,
       
  2349 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2350 		(EAPL("Key Data"),
       
  2351 		 (eapol_key_message)->get_key_data((eapol_key_message)->get_key_data_length()),
       
  2352 		 (eapol_key_message)->get_key_data_length()));
       
  2353 
       
  2354 #endif //#if defined(USE_EAP_TRACE)
       
  2355 
       
  2356 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2357 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2358 }
       
  2359 
       
  2360 
       
  2361 //--------------------------------------------------
       
  2362 
       
  2363 
       
  2364 //
       
  2365 eap_status_e eapol_key_state_c::trace_eapol_rsna_key_data_payload(
       
  2366 	const bool is_RSNA,
       
  2367 	const bool is_WPXM,
       
  2368 	const eapol_key_descriptor_type_e eapol_key_descriptor_type,
       
  2369 	const i8_t * const prefix,
       
  2370 	const eapol_rsna_key_data_header_c * const key_data_payload,
       
  2371 	const u32_t buffer_length)
       
  2372 {
       
  2373 	EAP_UNREFERENCED_PARAMETER(is_RSNA);
       
  2374 	EAP_UNREFERENCED_PARAMETER(prefix);
       
  2375 	EAP_UNREFERENCED_PARAMETER(key_data_payload);
       
  2376 	EAP_UNREFERENCED_PARAMETER(buffer_length);
       
  2377 	EAP_UNREFERENCED_PARAMETER(is_WPXM);
       
  2378 	EAP_UNREFERENCED_PARAMETER(eapol_key_descriptor_type);
       
  2379 
       
  2380 #if defined(USE_EAP_TRACE)
       
  2381 
       
  2382 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2383 
       
  2384 	if ((is_RSNA == true
       
  2385 			|| (is_WPXM == true && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA))
       
  2386 		&& key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_RSN_key_data)
       
  2387 	{
       
  2388 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2389 			(EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s\n"),
       
  2390 			prefix,
       
  2391 			key_data_payload,
       
  2392 			key_data_payload->get_descriptor_type(),
       
  2393 			key_data_payload->get_descriptor_type_string()));
       
  2394 
       
  2395 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2396 			(EAPL("EAPOL_KEY: %s (0x%08x): key_data_payload 0x%04x=%s\n"),
       
  2397 			prefix,
       
  2398 			key_data_payload,
       
  2399 			key_data_payload->get_payload_type(),
       
  2400 			key_data_payload->get_payload_type_string()));
       
  2401 
       
  2402 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2403 			(EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x.\n"),
       
  2404 			prefix,
       
  2405 			key_data_payload,
       
  2406 			key_data_payload->get_header_and_body_length(),
       
  2407 			buffer_length));
       
  2408 
       
  2409 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2410 			(EAPL("EAPOL_KEY: key_data_payload"),
       
  2411 			(key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())),
       
  2412 			key_data_payload->get_header_buffer_length()));
       
  2413 	}
       
  2414 	else if ((is_RSNA == true
       
  2415 				|| (is_WPXM == true && eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA))
       
  2416 		&& key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_RSN_IE)
       
  2417 	{
       
  2418 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2419 			(EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"),
       
  2420 			prefix,
       
  2421 			key_data_payload,
       
  2422 			key_data_payload->get_descriptor_type(),
       
  2423 			key_data_payload->get_descriptor_type_string()));
       
  2424 
       
  2425 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2426 			(EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, RSN IE.\n"),
       
  2427 			prefix,
       
  2428 			key_data_payload,
       
  2429 			key_data_payload->get_header_and_body_length(),
       
  2430 			buffer_length));
       
  2431 
       
  2432 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2433 			(EAPL("EAPOL_KEY: RSN IE"),
       
  2434 			(key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())),
       
  2435 			key_data_payload->get_header_buffer_length()));
       
  2436 	}
       
  2437 	else if (key_data_payload->get_descriptor_type() == eapol_RSNA_key_data_type_WPA_IE
       
  2438 		&& eapol_key_descriptor_type == eapol_key_descriptor_type_WPA)
       
  2439 	{
       
  2440 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2441 			(EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"),
       
  2442 			prefix,
       
  2443 			key_data_payload,
       
  2444 			key_data_payload->get_descriptor_type(),
       
  2445 			key_data_payload->get_descriptor_type_string()));
       
  2446 
       
  2447 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2448 			(EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, WPA IE.\n"),
       
  2449 			prefix,
       
  2450 			key_data_payload,
       
  2451 			key_data_payload->get_header_and_body_length(),
       
  2452 			buffer_length));
       
  2453 
       
  2454 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2455 			(EAPL("EAPOL_KEY: WPA IE"),
       
  2456 			(key_data_payload->get_header_buffer(key_data_payload->get_header_buffer_length())),
       
  2457 			key_data_payload->get_header_buffer_length()));
       
  2458 	}
       
  2459 	else
       
  2460 	{
       
  2461 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2462 			(EAPL("EAPOL_KEY: %s (0x%08x): descriptor type 0x%04x=%s.\n"),
       
  2463 			prefix,
       
  2464 			key_data_payload,
       
  2465 			key_data_payload->get_descriptor_type(),
       
  2466 			key_data_payload->get_descriptor_type_string()));
       
  2467 
       
  2468 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2469 			(EAPL("EAPOL_KEY: %s (0x%08x): payload length 0x%04x, buffer length 0x%04x, Unknown data.\n"),
       
  2470 			prefix,
       
  2471 			key_data_payload,
       
  2472 			key_data_payload->get_header_and_body_length(),
       
  2473 			buffer_length));
       
  2474 
       
  2475 		u32_t max_length = (buffer_length < key_data_payload->get_header_buffer_length())
       
  2476 			? buffer_length : key_data_payload->get_header_buffer_length();
       
  2477 
       
  2478 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  2479 			(EAPL("EAPOL_KEY: Unknown data"),
       
  2480 			(key_data_payload->get_header_buffer(max_length)),
       
  2481 			max_length));
       
  2482 	}
       
  2483 
       
  2484 #endif //#if defined(USE_EAP_TRACE)
       
  2485 
       
  2486 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2487 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2488 }
       
  2489 
       
  2490 
       
  2491 //--------------------------------------------------
       
  2492 
       
  2493 // 
       
  2494 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_authenticator_RSNA_IE()
       
  2495 {
       
  2496 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2497 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2498 	return &m_authenticator_RSNA_IE;
       
  2499 }
       
  2500 
       
  2501 //--------------------------------------------------
       
  2502 
       
  2503 // 
       
  2504 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_unicast_cipher_suite_RSNA_IE()
       
  2505 {
       
  2506 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2507 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2508 	return &m_unicast_cipher_suite_RSNA_IE;
       
  2509 }
       
  2510 
       
  2511 //--------------------------------------------------
       
  2512 
       
  2513 // 
       
  2514 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_supplicant_RSNA_IE()
       
  2515 {
       
  2516 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2517 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2518 	return &m_supplicant_RSNA_IE;
       
  2519 }
       
  2520 
       
  2521 //--------------------------------------------------
       
  2522 
       
  2523 // 
       
  2524 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_received_PMKID()
       
  2525 {
       
  2526 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2527 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2528 	return &m_received_PMKID;
       
  2529 }
       
  2530 
       
  2531 //--------------------------------------------------
       
  2532 
       
  2533 // 
       
  2534 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_supplicant_MAC_address()
       
  2535 {
       
  2536 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2537 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2538 	return &m_supplicant_MAC_address;
       
  2539 }
       
  2540 
       
  2541 //--------------------------------------------------
       
  2542 
       
  2543 // 
       
  2544 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_authenticator_MAC_address()
       
  2545 {
       
  2546 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2547 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2548 	return &m_authenticator_MAC_address;
       
  2549 }
       
  2550 
       
  2551 //--------------------------------------------------
       
  2552 
       
  2553 // 
       
  2554 EAP_FUNC_EXPORT u64_t eapol_key_state_c::get_key_reply_counter()
       
  2555 {
       
  2556 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2557 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2558 	return m_key_reply_counter;
       
  2559 }
       
  2560 
       
  2561 //--------------------------------------------------
       
  2562 
       
  2563 // 
       
  2564 EAP_FUNC_EXPORT void eapol_key_state_c::increase_key_reply_counter()
       
  2565 {
       
  2566 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2567 
       
  2568 	++m_key_reply_counter;
       
  2569 
       
  2570 	EAP_TRACE_DATA_DEBUG(
       
  2571 		m_am_tools,
       
  2572 		TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2573 		(EAPL("Incresed Local Reply Counter"),
       
  2574 		&m_key_reply_counter,
       
  2575 		sizeof(m_key_reply_counter)));
       
  2576 
       
  2577 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2578 }
       
  2579 
       
  2580 //--------------------------------------------------
       
  2581 
       
  2582 // 
       
  2583 EAP_FUNC_EXPORT void eapol_key_state_c::set_key_reply_counter(const u64_t reply_counter)
       
  2584 {
       
  2585 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2586 
       
  2587 	m_key_reply_counter = reply_counter;
       
  2588 
       
  2589 	EAP_TRACE_DATA_DEBUG(
       
  2590 		m_am_tools,
       
  2591 		TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2592 		(EAPL("Set Local Reply Counter"),
       
  2593 		&m_key_reply_counter,
       
  2594 		sizeof(m_key_reply_counter)));
       
  2595 
       
  2596 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2597 }
       
  2598 
       
  2599 //--------------------------------------------------
       
  2600 
       
  2601 // 
       
  2602 EAP_FUNC_EXPORT u64_t eapol_key_state_c::get_client_send_key_reply_counter()
       
  2603 {
       
  2604 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2605 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2606 	return m_client_send_key_reply_counter;
       
  2607 }
       
  2608 
       
  2609 //--------------------------------------------------
       
  2610 
       
  2611 // 
       
  2612 EAP_FUNC_EXPORT void eapol_key_state_c::increase_client_send_key_reply_counter()
       
  2613 {
       
  2614 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2615 
       
  2616 	++m_client_send_key_reply_counter;
       
  2617 
       
  2618 	EAP_TRACE_DATA_DEBUG(
       
  2619 		m_am_tools,
       
  2620 		TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2621 		(EAPL("Increased Client Send Reply Counter"),
       
  2622 		&m_client_send_key_reply_counter,
       
  2623 		sizeof(m_client_send_key_reply_counter)));
       
  2624 
       
  2625 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2626 }
       
  2627 
       
  2628 //--------------------------------------------------
       
  2629 
       
  2630 // 
       
  2631 EAP_FUNC_EXPORT void eapol_key_state_c::set_client_send_key_reply_counter(const u64_t reply_counter)
       
  2632 {
       
  2633 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2634 
       
  2635 	m_client_send_key_reply_counter = reply_counter;
       
  2636 
       
  2637 	EAP_TRACE_DATA_DEBUG(
       
  2638 		m_am_tools,
       
  2639 		TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2640 		(EAPL("Set Client Send Reply Counter"),
       
  2641 		&m_client_send_key_reply_counter,
       
  2642 		sizeof(m_client_send_key_reply_counter)));
       
  2643 
       
  2644 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2645 }
       
  2646 
       
  2647 //--------------------------------------------------
       
  2648 
       
  2649 // 
       
  2650 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_ANonce()
       
  2651 {
       
  2652 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2653 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2654 	return &m_ANonce;
       
  2655 }
       
  2656 
       
  2657 //--------------------------------------------------
       
  2658 
       
  2659 // 
       
  2660 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_SNonce()
       
  2661 {
       
  2662 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2663 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2664 	return &m_SNonce;
       
  2665 }
       
  2666 
       
  2667 //--------------------------------------------------
       
  2668 
       
  2669 // 
       
  2670 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_confirmation_KCK()
       
  2671 {
       
  2672 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2673 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2674 	return &m_confirmation_KCK;
       
  2675 }
       
  2676 
       
  2677 //--------------------------------------------------
       
  2678 
       
  2679 // 
       
  2680 EAP_FUNC_EXPORT eap_variable_data_c * eapol_key_state_c::get_encryption_KEK()
       
  2681 {
       
  2682 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2683 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2684 	return &m_encryption_KEK;
       
  2685 }
       
  2686 
       
  2687 //--------------------------------------------------
       
  2688 
       
  2689 // 
       
  2690 eap_status_e eapol_key_state_c::check_is_aes_key_wrap_padding(
       
  2691 	const eapol_RSNA_key_descriptor_type_e /* current_key_data_type */,
       
  2692 	eapol_rsna_key_data_header_c * const key_data_payload,
       
  2693 	const u32_t key_data_max_length
       
  2694 	)
       
  2695 {
       
  2696 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2697 
       
  2698 	if (key_data_max_length > 1ul)
       
  2699 	{
       
  2700 		u8_t * const data = key_data_payload->get_header_buffer(key_data_max_length);
       
  2701 
       
  2702 		// The first byte is eapol_RSNA_key_data_type_RSN_key_data.
       
  2703 		// The following padding bytes are zero bytes.
       
  2704 		for (u32_t ind = 1ul; ind < key_data_max_length; ind++)
       
  2705 		{
       
  2706 			if (data[ind] != 0ul)
       
  2707 			{
       
  2708 				// Padding must be zero byte.
       
  2709 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2710 				return eap_status_illegal_padding;
       
  2711 			}
       
  2712 		} // for()
       
  2713 	}
       
  2714 
       
  2715 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2716 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2717 }
       
  2718 
       
  2719 //--------------------------------------------------
       
  2720 
       
  2721 // 
       
  2722 eap_status_e eapol_key_state_c::parse_generic_key_data_payload(
       
  2723 	const eapol_key_descriptor_type_e eapol_key_descriptor_type,
       
  2724 	const eapol_RSNA_key_descriptor_type_e current_key_descriptor_type,
       
  2725 	eapol_rsna_key_data_header_c * const key_data_payload,
       
  2726 	u32_t * const key_data_max_length,
       
  2727 	eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads,
       
  2728 	const eapol_key_state_e expected_key_message)
       
  2729 {
       
  2730 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2731 
       
  2732 	EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(
       
  2733 		get_is_RSNA(),
       
  2734 		get_is_WPXM(),
       
  2735 		eapol_key_descriptor_type,
       
  2736 		"eapol_key_state_c::parse_generic_key_data_payload(): Parsing EAPOL Key Data key_data_payload",
       
  2737 		key_data_payload,
       
  2738 		*key_data_max_length);
       
  2739 
       
  2740 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::parse_generic_key_data_payload()");
       
  2741 
       
  2742 	{
       
  2743 		eapol_key_state_string_c debug_string;
       
  2744 		EAP_UNREFERENCED_PARAMETER(debug_string);
       
  2745 
       
  2746 		EAP_TRACE_DEBUG(
       
  2747 			m_am_tools,
       
  2748 			TRACE_FLAGS_DEFAULT,
       
  2749 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2750 			 EAPL("current key_data_payload_type 0x%04x=%s.\n"),
       
  2751 			 key_data_payload,
       
  2752 			 current_key_descriptor_type,
       
  2753 			 key_data_payload->get_descriptor_type_string()));
       
  2754 
       
  2755 		EAP_TRACE_DEBUG(
       
  2756 			m_am_tools,
       
  2757 			TRACE_FLAGS_DEFAULT,
       
  2758 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2759 			 EAPL("eapol_key_descriptor_type 0x%02x=%s.\n"),
       
  2760 			 key_data_payload,
       
  2761 			 eapol_key_descriptor_type,
       
  2762 			 debug_string.get_eapol_key_descriptor_type_string(eapol_key_descriptor_type)));
       
  2763 
       
  2764 		EAP_TRACE_DEBUG(
       
  2765 			m_am_tools,
       
  2766 			TRACE_FLAGS_DEFAULT,
       
  2767 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2768 			 EAPL("payload length is 0x%04x, key_data_max_length is 0x%08x.\n"),
       
  2769 			 key_data_payload,
       
  2770 			 key_data_payload->get_header_and_body_length(),
       
  2771 			 *key_data_max_length));
       
  2772 
       
  2773 		EAP_TRACE_DEBUG(
       
  2774 			m_am_tools,
       
  2775 			TRACE_FLAGS_DEFAULT,
       
  2776 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2777 			 EAPL("expected_key_message = %s = 0x%08x.\n"),
       
  2778 			 key_data_payload,
       
  2779 			 debug_string.get_eapol_key_state_string(expected_key_message),
       
  2780 			 expected_key_message));
       
  2781 	}
       
  2782 
       
  2783 	if (get_is_RSNA() == true
       
  2784 		&& eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA
       
  2785 		&& current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_key_data
       
  2786 		&& check_is_aes_key_wrap_padding(
       
  2787 			current_key_descriptor_type,
       
  2788 			key_data_payload,
       
  2789 			*key_data_max_length) == eap_status_ok)
       
  2790 	{
       
  2791 		EAP_TRACE_DEBUG(
       
  2792 			m_am_tools,
       
  2793 			TRACE_FLAGS_DEFAULT,
       
  2794 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): AES key wrapping padding\n"),
       
  2795 			 key_data_payload));
       
  2796 
       
  2797 		// This is AES key wrap padding.
       
  2798 		*key_data_max_length = 0ul;
       
  2799 
       
  2800 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2801 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  2802 	}
       
  2803 	else if (*key_data_max_length < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE
       
  2804 		|| key_data_payload->get_header_and_body_length() == 0)
       
  2805 	{
       
  2806 		EAP_TRACE_ERROR(
       
  2807 			m_am_tools,
       
  2808 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2809 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2810 			 EAPL("current key_data_payload_type 0x%04x=%s, payload length is 0x%04x, key_data_max_length is 0x%08x.\n"),
       
  2811 			 key_data_payload,
       
  2812 			 current_key_descriptor_type,
       
  2813 			 key_data_payload->get_descriptor_type_string(),
       
  2814 			 key_data_payload->get_header_and_body_length(),
       
  2815 			 *key_data_max_length));
       
  2816 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2817 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);		
       
  2818 	}
       
  2819 
       
  2820 
       
  2821 	if ((get_is_RSNA() == true
       
  2822 			|| get_is_WPXM() == true)
       
  2823 		&& eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA
       
  2824 		&& current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_key_data)
       
  2825 	{
       
  2826 		eapol_RSNA_key_payload_type_e current_key_data_type = key_data_payload->get_payload_type();
       
  2827 
       
  2828 		EAP_TRACE_DEBUG(
       
  2829 			m_am_tools,
       
  2830 			TRACE_FLAGS_DEFAULT,
       
  2831 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): current_key_data_type = %s = 0x%02x\n"),
       
  2832 			 key_data_payload,
       
  2833 			 key_data_payload->get_payload_type_string(),
       
  2834 			 current_key_data_type));
       
  2835 
       
  2836 		if (current_key_data_type == eapol_RSNA_key_payload_type_group_key_and_id
       
  2837 			&& m_is_client == true
       
  2838 			&& (expected_key_message == eapol_key_state_wait_4_way_handshake_message_3
       
  2839 				|| expected_key_message == eapol_key_state_wait_group_key_handshake_message_1))
       
  2840 		{
       
  2841 			EAP_TRACE_DEBUG(
       
  2842 				m_am_tools,
       
  2843 				TRACE_FLAGS_DEFAULT,
       
  2844 				(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): Key ID and Group Key\n"),
       
  2845 				 key_data_payload));
       
  2846 
       
  2847 			/*  Key ID and Group Key:
       
  2848 			 *  0                   1                   2                   3
       
  2849 			 *  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
       
  2850 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2851 			 * | Type = 0xdd   | Length        | OUI 3 octets               ...|
       
  2852 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2853 			 * | ... OUI       | Data Type 1   | Key ID and Tx | Reserved 0    |
       
  2854 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2855 			 * | GTK (Length - 6) octets                                       |
       
  2856 			 * +-                                                             -+
       
  2857 			 * :                                                               :
       
  2858 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2859 			 */
       
  2860 			if (key_data_payload->get_key_data_payload_length()
       
  2861 				< eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_MINIMUM_SIZE)
       
  2862 			{
       
  2863 				EAP_TRACE_ERROR(
       
  2864 					m_am_tools,
       
  2865 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2866 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2867 					 EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
  2868 					 key_data_payload,
       
  2869 					 current_key_data_type,
       
  2870 					 key_data_payload->get_descriptor_type_string(),
       
  2871 					 key_data_payload->get_key_data_payload_length()));
       
  2872 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2873 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2874 			}
       
  2875 
       
  2876 
       
  2877 			const u32_t buffer_length = key_data_payload->get_key_data_payload_length();
       
  2878 
       
  2879 			u8_t * const buffer
       
  2880 				= static_cast<u8_t *>(key_data_payload->get_key_data_payload(buffer_length));
       
  2881 
       
  2882 			if (buffer == 0)
       
  2883 			{
       
  2884 				EAP_TRACE_ERROR(
       
  2885 					m_am_tools, 
       
  2886 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
  2887 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2888 					 EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2889 					 key_data_payload,
       
  2890 					 current_key_data_type,
       
  2891 					 key_data_payload->get_payload_type_string(),
       
  2892 					 key_data_payload->get_key_data_payload_length()));
       
  2893 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2894 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2895 			}
       
  2896 
       
  2897 
       
  2898 			eapol_rsna_key_data_gtk_header_c gtk_header(
       
  2899 				m_am_tools,
       
  2900 				buffer,
       
  2901 				buffer_length);
       
  2902 			if (gtk_header.get_is_valid() == false)
       
  2903 			{
       
  2904 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2905 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2906 			}
       
  2907 
       
  2908 			eap_status_e status = gtk_header.check_header();
       
  2909 			if (status != eap_status_ok)
       
  2910 			{
       
  2911 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2912 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2913 			}
       
  2914 
       
  2915 			p_rsna_key_data_payloads->set_group_key_id(gtk_header.get_key_index());
       
  2916 			p_rsna_key_data_payloads->set_group_key_tx(gtk_header.get_tx_bit());
       
  2917 
       
  2918 			u32_t group_key_header_length = eapol_rsna_key_data_gtk_header_c::get_header_length();
       
  2919 
       
  2920 			// Note here we get a reference to the data bytes of the received packet.
       
  2921 			status = p_rsna_key_data_payloads->get_group_key()->set_buffer(
       
  2922 				key_data_payload,
       
  2923 				gtk_header.get_gtk(key_data_payload->get_key_data_payload_length()-group_key_header_length),
       
  2924 				key_data_payload->get_key_data_payload_length()-group_key_header_length,
       
  2925 				false,
       
  2926 				false);
       
  2927 			if (status != eap_status_ok)
       
  2928 			{
       
  2929 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2930 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2931 			}
       
  2932 
       
  2933 			EAP_TRACE_DEBUG(
       
  2934 				m_am_tools,
       
  2935 				TRACE_FLAGS_DEFAULT,
       
  2936 				(EAPL("received RSN Group Key ID %d, Tx %d\n"),
       
  2937 				 p_rsna_key_data_payloads->get_group_key_id(),
       
  2938 				 p_rsna_key_data_payloads->get_group_key_tx()));
       
  2939 
       
  2940 			EAP_TRACE_DATA_DEBUG(
       
  2941 				m_am_tools,
       
  2942 				TRACE_FLAGS_DEFAULT,
       
  2943 				(EAPL("received RSN Group Key"),
       
  2944 				 p_rsna_key_data_payloads->get_group_key()->get_data(
       
  2945 					 p_rsna_key_data_payloads->get_group_key()->get_data_length()),
       
  2946 				 p_rsna_key_data_payloads->get_group_key()->get_data_length()));
       
  2947 		}
       
  2948 		else if (current_key_data_type == eapol_RSNA_key_payload_type_sta_key)
       
  2949 		{
       
  2950 			EAP_TRACE_DEBUG(
       
  2951 				m_am_tools,
       
  2952 				TRACE_FLAGS_DEFAULT,
       
  2953 				(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): STAKey\n"),
       
  2954 				 key_data_payload));
       
  2955 
       
  2956 			/*  STAKey:
       
  2957 			 *  0                   1                   2                   3
       
  2958 			 *  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
       
  2959 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2960 			 * | Type = 0xdd   | Length        | OUI 3 octets               ...|
       
  2961 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2962 			 * | ... OUI       | Data Type 2   | Ecrypted STAKey               |
       
  2963 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-                             -+
       
  2964 			 * :      (Length - 4) octets                                      :
       
  2965 			 * +-                                                             -+
       
  2966 			 * |                                                               |
       
  2967 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2968 			 */
       
  2969 			if (key_data_payload->get_key_data_payload_length() < eapol_rsna_key_data_header_c::EAPOL_RSNA_STAKEY_MINIMUM_SIZE)
       
  2970 			{
       
  2971 				EAP_TRACE_ERROR(
       
  2972 					m_am_tools,
       
  2973 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  2974 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2975 					 EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
  2976 					 key_data_payload, current_key_data_type, key_data_payload->get_payload_type_string(),
       
  2977 					 key_data_payload->get_key_data_payload_length()));
       
  2978 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2979 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2980 			}
       
  2981 
       
  2982 			u8_t * buffer
       
  2983 				= static_cast<u8_t *>(key_data_payload->get_key_data_payload(
       
  2984 										  key_data_payload->get_key_data_payload_length()));
       
  2985 
       
  2986 			if (buffer == 0)
       
  2987 			{
       
  2988 				EAP_TRACE_ERROR(
       
  2989 					m_am_tools, 
       
  2990 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
  2991 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  2992 					 EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  2993 					 key_data_payload,
       
  2994 					 current_key_data_type,
       
  2995 					 key_data_payload->get_payload_type_string(),
       
  2996 					 key_data_payload->get_key_data_payload_length()));
       
  2997 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2998 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2999 			}
       
  3000 
       
  3001 			// Note here we get a reference to the data bytes of the received packet.
       
  3002 			eap_status_e status = p_rsna_key_data_payloads->get_STAKey()->set_buffer(
       
  3003 				key_data_payload, buffer, key_data_payload->get_key_data_payload_length(), false, false);
       
  3004 			if (status != eap_status_ok)
       
  3005 			{
       
  3006 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3007 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3008 			}
       
  3009 		}
       
  3010 		else if (current_key_data_type == eapol_RSNA_key_payload_type_pmkid)
       
  3011 		{
       
  3012 			EAP_TRACE_DEBUG(
       
  3013 				m_am_tools,
       
  3014 				TRACE_FLAGS_DEFAULT,
       
  3015 				(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): PMKID\n"),
       
  3016 				 key_data_payload));
       
  3017 
       
  3018 			/*  PMKID:
       
  3019 			 *  0                   1                   2                   3
       
  3020 			 *  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
       
  3021 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3022 			 * | Type = 0xdd   | Length        | OUI 3 octets               ...|
       
  3023 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3024 			 * | ... OUI       | Data Type 3   | PMKID  plaintext              |
       
  3025 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-                             -+
       
  3026 			 * :      (Length - 4) octets                                      :
       
  3027 			 * +-                                                             -+
       
  3028 			 * |                                                               |
       
  3029 			 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  3030 			 */
       
  3031 			if (key_data_payload->get_key_data_payload_length() < eapol_rsna_key_data_header_c::EAPOL_RSNA_PMKID_MINIMUM_SIZE)
       
  3032 			{
       
  3033 				EAP_TRACE_ERROR(
       
  3034 					m_am_tools,
       
  3035 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3036 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3037 					 EAPL("current key_data_payload 0x%04x=%s, data length incorrect 0x%04x.\n"),
       
  3038 					 key_data_payload, current_key_data_type, key_data_payload->get_payload_type_string(),
       
  3039 					 key_data_payload->get_key_data_payload_length()));
       
  3040 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3041 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3042 			}
       
  3043 
       
  3044 			u8_t * buffer
       
  3045 				= static_cast<u8_t *>(key_data_payload->get_key_data_payload(
       
  3046 										  key_data_payload->get_key_data_payload_length()));
       
  3047 
       
  3048 			if (buffer == 0)
       
  3049 			{
       
  3050 				EAP_TRACE_ERROR(
       
  3051 					m_am_tools, 
       
  3052 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
  3053 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3054 					 EAPL("current key_data_payload 0x%04x=%s, length 0x%04x, data buffer incorrect.\n"),
       
  3055 					 key_data_payload,
       
  3056 					 current_key_data_type,
       
  3057 					 key_data_payload->get_payload_type_string(),
       
  3058 					 key_data_payload->get_key_data_payload_length()));
       
  3059 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3060 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3061 			}
       
  3062 
       
  3063 			// Note here we get a reference to the data bytes of the received packet.
       
  3064 			eap_status_e status = p_rsna_key_data_payloads->get_PMKID()->set_buffer(
       
  3065 				key_data_payload, buffer, key_data_payload->get_key_data_payload_length(), false, false);
       
  3066 			if (status != eap_status_ok)
       
  3067 			{
       
  3068 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3069 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3070 			}
       
  3071 		}
       
  3072 		else if (current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE
       
  3073 			&& key_data_payload->get_header_and_body_length() >= eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)
       
  3074 		{
       
  3075 			EAP_TRACE_DEBUG(
       
  3076 				m_am_tools,
       
  3077 				TRACE_FLAGS_DEFAULT,
       
  3078 				(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): WPA Information element\n"),
       
  3079 				 key_data_payload));
       
  3080 
       
  3081 			/* This is WPA Information element. NOTE the 2 first bytes match with
       
  3082 			 * EAPOL Key Data Encapsulation format.
       
  3083 			 * 
       
  3084 			 *      0       1       2       3       4       5       6       7
       
  3085 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3086 			 *  |     Element ID 48=0x30 (WPA 221=0xdd)   1 octet               |
       
  3087 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3088 			 *  |                           Length        1 octet               |
       
  3089 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3090 			 *  |                         Version 2 octets                      |
       
  3091 			 *  +-                                                             -+
       
  3092 			 *  |                                                               |
       
  3093 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3094 			 *  |  Group Key Cipher Suite  4 octets                             |
       
  3095 			 *  +-                                                             -+
       
  3096 			 *  |                   optional                                    |
       
  3097 			 *  +-                                                             -+
       
  3098 			 *  |                                                               |
       
  3099 			 *  +-                                                             -+
       
  3100 			 *  |                                                               |
       
  3101 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3102 			 *  |  Pairwise Key Cipher Suite Count (m) 2 octets                 |
       
  3103 			 *  +-                                                             -+
       
  3104 			 *  |                    optional                                   |
       
  3105 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3106 			 *  |  Pairwise Key Cipher Suite List m*4 octets                    |
       
  3107 			 *  +-                                                             -+
       
  3108 			 *  |                    optional                                   |
       
  3109 			 *  +-                                                             -+
       
  3110 			 *  |                                                               |
       
  3111 			 *  +-                                                             -+
       
  3112 			 *  |                                                               |
       
  3113 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3114 			 *  |  Authentication and Key Management Suite Count (n) 2 octets   |
       
  3115 			 *  +-                                                             -+
       
  3116 			 *  |                    optional                                   |
       
  3117 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3118 			 *  |  Authentication and Key Management Suite List n*4 octets      |
       
  3119 			 *  +-                                                             -+
       
  3120 			 *  |                    optional                                   |
       
  3121 			 *  +-                                                             -+
       
  3122 			 *  |                                                               |
       
  3123 			 *  +-                                                             -+
       
  3124 			 *  |                                                               |
       
  3125 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3126 			 *  |  RSN Capabilities 2 octets                                    |
       
  3127 			 *  +-                                                             -+
       
  3128 			 *  |                    optional                                   |
       
  3129 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3130 			 *  |  PMKID Count (s) 2 octets                                     |
       
  3131 			 *  +-                                                             -+
       
  3132 			 *  |                    optional                                   |
       
  3133 			 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3134 			 *  |  PMKID List s*16 octets                                       |
       
  3135 			 *  +-                                                             -+
       
  3136 			 *  :                    optional                                   :
       
  3137 			 *  +-                                                             -+
       
  3138 			 *  |                                                               |
       
  3139 			 *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
       
  3140 			 */
       
  3141 
       
  3142 			// The second byte is the length of the RSN IE. Also the Type and Length fields are included.
       
  3143 			const u32_t length_of_the_RSN_IE = key_data_payload->get_header_and_body_length();
       
  3144 
       
  3145 			if (length_of_the_RSN_IE < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)
       
  3146 			{
       
  3147 				EAP_TRACE_ERROR(
       
  3148 					m_am_tools,
       
  3149 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3150 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3151 					 EAPL("RSN IE length 0x%04x too less, at least 0x%04x bytes required.\n"),
       
  3152 					 key_data_payload,
       
  3153 					 length_of_the_RSN_IE,
       
  3154 					 eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE));
       
  3155 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3156 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3157 			}
       
  3158 
       
  3159 
       
  3160 			// RSN IE is the whole key_data_payload.
       
  3161 			u8_t * buffer = reinterpret_cast<u8_t *>(key_data_payload->get_header_buffer(length_of_the_RSN_IE));
       
  3162 
       
  3163 			if (buffer == 0)
       
  3164 			{
       
  3165 				EAP_TRACE_ERROR(
       
  3166 					m_am_tools, 
       
  3167 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
  3168 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3169 					 EAPL("current key_data_payload length 0x%04x data buffer incorrect.\n"),
       
  3170 					key_data_payload,
       
  3171 					length_of_the_RSN_IE));
       
  3172 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3173 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3174 			}
       
  3175 
       
  3176 			eap_variable_data_c * const rsn_ie = new eap_variable_data_c(m_am_tools);
       
  3177 			if (rsn_ie == 0)
       
  3178 			{
       
  3179 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3180 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3181 			}
       
  3182 
       
  3183 			EAP_TRACE_DATA_DEBUG(
       
  3184 				m_am_tools,
       
  3185 				TRACE_FLAGS_DEFAULT,
       
  3186 				(EAPL("Parsed WPA IE"),
       
  3187 				buffer,
       
  3188 				length_of_the_RSN_IE));
       
  3189 
       
  3190 			// Note here we get a reference to the data bytes of the received packet.
       
  3191 			eap_status_e status = rsn_ie->set_buffer(
       
  3192 				buffer,
       
  3193 				length_of_the_RSN_IE,
       
  3194 				false,
       
  3195 				false);
       
  3196 			if (status != eap_status_ok)
       
  3197 			{
       
  3198 				delete rsn_ie;
       
  3199 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3200 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3201 			}
       
  3202 
       
  3203 			// eap_array_c object will free rsn_ie.
       
  3204 			status = p_rsna_key_data_payloads->get_RSN_IE()->add_object(rsn_ie, true);
       
  3205 			if (status != eap_status_ok)
       
  3206 			{
       
  3207 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3208 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3209 			}
       
  3210 		}
       
  3211 		else
       
  3212 		{
       
  3213 			// Unknown payloads are quietly ignored.
       
  3214 			EAP_TRACE_ERROR(
       
  3215 				m_am_tools, 
       
  3216 				TRACE_FLAGS_DEFAULT, 
       
  3217 				(EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(): ")
       
  3218 				 EAPL("Ignores unknown EAPOL Key Data type %d=0x%08x and payload %d=0x%08x, length %d.\n"),
       
  3219 				current_key_descriptor_type,
       
  3220 				current_key_descriptor_type,
       
  3221 				current_key_data_type,
       
  3222 				current_key_data_type,
       
  3223 				key_data_payload->get_header_and_body_length()));
       
  3224 		}
       
  3225 
       
  3226 		*key_data_max_length -= key_data_payload->get_header_and_body_length();
       
  3227 
       
  3228 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3229 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3230 	}
       
  3231 	else if (get_is_WPA() == true
       
  3232 		&& eapol_key_descriptor_type == eapol_key_descriptor_type_WPA
       
  3233 		&& expected_key_message == eapol_key_state_wait_group_key_handshake_message_1)
       
  3234 	{
       
  3235 		EAP_TRACE_DEBUG(
       
  3236 			m_am_tools,
       
  3237 			TRACE_FLAGS_DEFAULT,
       
  3238 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): GTK\n"),
       
  3239 			 key_data_payload));
       
  3240 
       
  3241 		// Data includes GTK.
       
  3242 		// key_data_payload points to the GTK of length (*key_data_max_length).
       
  3243 
       
  3244 		u8_t * const buffer
       
  3245 			= reinterpret_cast<u8_t *>(key_data_payload);
       
  3246 
       
  3247 		if (buffer == 0)
       
  3248 		{
       
  3249 			EAP_TRACE_ERROR(
       
  3250 				m_am_tools, 
       
  3251 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
  3252 				(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3253 				 EAPL("length 0x%04x, data buffer incorrect.\n"),
       
  3254 				 key_data_payload,
       
  3255 				 *key_data_max_length));
       
  3256 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3257 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3258 		}
       
  3259 
       
  3260 		// Note here we get a reference to the data bytes of the received packet.
       
  3261 		eap_status_e status = p_rsna_key_data_payloads->get_group_key()->set_buffer(
       
  3262 			key_data_payload, buffer,
       
  3263 			*key_data_max_length, false, false);
       
  3264 		if (status != eap_status_ok)
       
  3265 		{
       
  3266 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3267 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3268 		}
       
  3269 
       
  3270 		EAP_TRACE_DATA_DEBUG(
       
  3271 			m_am_tools,
       
  3272 			TRACE_FLAGS_DEFAULT,
       
  3273 			(EAPL("received WPA Group Key"),
       
  3274 			 p_rsna_key_data_payloads->get_group_key()->get_data(
       
  3275 				 p_rsna_key_data_payloads->get_group_key()->get_data_length()),
       
  3276 			 p_rsna_key_data_payloads->get_group_key()->get_data_length()));
       
  3277 
       
  3278 		*key_data_max_length = 0ul;
       
  3279 
       
  3280 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3281 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3282 	}
       
  3283 	else if ((get_is_RSNA() == true
       
  3284 			&& eapol_key_descriptor_type == eapol_key_descriptor_type_RSNA
       
  3285 			&& current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_IE)
       
  3286 		|| (get_is_WPA() == true
       
  3287 				&& eapol_key_descriptor_type == eapol_key_descriptor_type_WPA
       
  3288 				&& current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE)
       
  3289 #if defined(EAP_USE_WPXM)
       
  3290 		|| (get_is_WPXM() == true
       
  3291 			&& (current_key_descriptor_type == eapol_RSNA_key_data_type_RSN_IE
       
  3292 				|| current_key_descriptor_type == eapol_RSNA_key_data_type_WPA_IE))
       
  3293 #endif //#if defined(EAP_USE_WPXM)
       
  3294 			)
       
  3295 	{
       
  3296 		EAP_TRACE_DEBUG(
       
  3297 			m_am_tools,
       
  3298 			TRACE_FLAGS_DEFAULT,
       
  3299 			(EAPL("EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): RSN Information element\n"),
       
  3300 			 key_data_payload));
       
  3301 
       
  3302 		/* This is RSN or WPA Information element. NOTE the 2 first bytes match with
       
  3303 		 * EAPOL Key Data Encapsulation format.
       
  3304 		 * 
       
  3305 		 *      0       1       2       3       4       5       6       7
       
  3306 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3307 		 *  |     Element ID 48=0x30 (WPA 221=0xdd)   1 octet               |
       
  3308 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3309 		 *  |                           Length        1 octet               |
       
  3310 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3311 		 *  |                         Version 2 octets                      |
       
  3312 		 *  +-                                                             -+
       
  3313 		 *  |                                                               |
       
  3314 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3315 		 *  |  Group Key Cipher Suite  4 octets                             |
       
  3316 		 *  +-                                                             -+
       
  3317 		 *  |                   optional                                    |
       
  3318 		 *  +-                                                             -+
       
  3319 		 *  |                                                               |
       
  3320 		 *  +-                                                             -+
       
  3321 		 *  |                                                               |
       
  3322 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3323 		 *  |  Pairwise Key Cipher Suite Count (m) 2 octets                 |
       
  3324 		 *  +-                                                             -+
       
  3325 		 *  |                    optional                                   |
       
  3326 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3327 		 *  |  Pairwise Key Cipher Suite List m*4 octets                    |
       
  3328 		 *  +-                                                             -+
       
  3329 		 *  |                    optional                                   |
       
  3330 		 *  +-                                                             -+
       
  3331 		 *  |                                                               |
       
  3332 		 *  +-                                                             -+
       
  3333 		 *  |                                                               |
       
  3334 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3335 		 *  |  Authentication and Key Management Suite Count (n) 2 octets   |
       
  3336 		 *  +-                                                             -+
       
  3337 		 *  |                    optional                                   |
       
  3338 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3339 		 *  |  Authentication and Key Management Suite List n*4 octets      |
       
  3340 		 *  +-                                                             -+
       
  3341 		 *  |                    optional                                   |
       
  3342 		 *  +-                                                             -+
       
  3343 		 *  |                                                               |
       
  3344 		 *  +-                                                             -+
       
  3345 		 *  |                                                               |
       
  3346 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3347 		 *  |  RSN Capabilities 2 octets                                    |
       
  3348 		 *  +-                                                             -+
       
  3349 		 *  |                    optional                                   |
       
  3350 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3351 		 *  |  PMKID Count (s) 2 octets                                     |
       
  3352 		 *  +-                                                             -+
       
  3353 		 *  |                    optional                                   |
       
  3354 		 *  +-------+-------+-------+-------+-------+-------+-------+-------+
       
  3355 		 *  |  PMKID List s*16 octets                                       |
       
  3356 		 *  +-                                                             -+
       
  3357 		 *  :                    optional                                   :
       
  3358 		 *  +-                                                             -+
       
  3359 		 *  |                                                               |
       
  3360 		 *  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
       
  3361 		 */
       
  3362 
       
  3363 		// The second byte is the length of the RSN IE. Also the Type and Length fields are included.
       
  3364 		const u32_t length_of_the_RSN_IE = key_data_payload->get_header_and_body_length();
       
  3365 
       
  3366 		if (length_of_the_RSN_IE < eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE)
       
  3367 		{
       
  3368 			EAP_TRACE_ERROR(
       
  3369 				m_am_tools,
       
  3370 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3371 				(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3372 				 EAPL("RSN IE length 0x%04x too less, at least 0x%04x bytes required.\n"),
       
  3373 				 key_data_payload,
       
  3374 				 length_of_the_RSN_IE,
       
  3375 				 eapol_rsna_key_data_header_c::EAPOL_RSNA_IE_MINIMUM_SIZE));
       
  3376 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3377 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3378 		}
       
  3379 
       
  3380 
       
  3381 		// RSN IE is the whole key_data_payload.
       
  3382 		u8_t * buffer = reinterpret_cast<u8_t *>(key_data_payload->get_header_buffer(length_of_the_RSN_IE));
       
  3383 
       
  3384 		if (buffer == 0)
       
  3385 		{
       
  3386 			EAP_TRACE_ERROR(
       
  3387 				m_am_tools, 
       
  3388 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR, 
       
  3389 				(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(0x%08x): ")
       
  3390 				 EAPL("current key_data_payload length 0x%04x data buffer incorrect.\n"),
       
  3391 				key_data_payload,
       
  3392 				length_of_the_RSN_IE));
       
  3393 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3394 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3395 		}
       
  3396 
       
  3397 		eap_variable_data_c * const rsn_ie = new eap_variable_data_c(m_am_tools);
       
  3398 		if (rsn_ie == 0)
       
  3399 		{
       
  3400 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3401 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3402 		}
       
  3403 
       
  3404 		EAP_TRACE_DATA_DEBUG(
       
  3405 			m_am_tools,
       
  3406 			TRACE_FLAGS_DEFAULT,
       
  3407 			(EAPL("Parsed RSN IE"),
       
  3408 			buffer,
       
  3409 			length_of_the_RSN_IE));
       
  3410 
       
  3411 		// Note here we get a reference to the data bytes of the received packet.
       
  3412 		eap_status_e status = rsn_ie->set_buffer(
       
  3413 			buffer,
       
  3414 			length_of_the_RSN_IE,
       
  3415 			false,
       
  3416 			false);
       
  3417 		if (status != eap_status_ok)
       
  3418 		{
       
  3419 			delete rsn_ie;
       
  3420 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3421 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3422 		}
       
  3423 
       
  3424 		// eap_array_c object will free rsn_ie.
       
  3425 		status = p_rsna_key_data_payloads->get_RSN_IE()->add_object(rsn_ie, true);
       
  3426 		if (status != eap_status_ok)
       
  3427 		{
       
  3428 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3429 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3430 		}
       
  3431 		
       
  3432 		buffer += length_of_the_RSN_IE;
       
  3433 
       
  3434 		*key_data_max_length -= length_of_the_RSN_IE;
       
  3435 
       
  3436 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3437 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3438 	}
       
  3439 	else
       
  3440 	{
       
  3441 		// Unknown payloads are quietly ignored.
       
  3442 		eapol_RSNA_key_payload_type_e current_key_data_type = key_data_payload->get_payload_type();
       
  3443 		EAP_UNREFERENCED_PARAMETER(current_key_data_type);
       
  3444 
       
  3445 		EAP_TRACE_ERROR(
       
  3446 			m_am_tools, 
       
  3447 			TRACE_FLAGS_DEFAULT, 
       
  3448 			(EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::parse_generic_key_data_payload(): ")
       
  3449 			 EAPL("Unknown EAPOL Key Data type %d=0x%08x and payload %d=0x%08x, length %d.\n"),
       
  3450 			current_key_descriptor_type,
       
  3451 			current_key_descriptor_type,
       
  3452 			current_key_data_type,
       
  3453 			current_key_data_type,
       
  3454 			key_data_payload->get_header_and_body_length()));
       
  3455 
       
  3456 		*key_data_max_length -= key_data_payload->get_header_and_body_length();
       
  3457 
       
  3458 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3459 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3460 	}
       
  3461 }
       
  3462 
       
  3463 //--------------------------------------------------
       
  3464 
       
  3465 //
       
  3466 eap_status_e eapol_key_state_c::parse_key_data(
       
  3467 	const eapol_key_descriptor_type_e eapol_key_descriptor_type,
       
  3468 	const eapol_rsna_key_data_header_c * const p_payload,
       
  3469 	u32_t * const buffer_length,
       
  3470 	eapol_rsna_key_data_payloads_c * const p_rsna_key_data_payloads,
       
  3471 	const eapol_key_state_e expected_key_message,
       
  3472 	const eapol_RSNA_key_header_c::key_descriptor_version_e key_descriptor_version)
       
  3473 {
       
  3474 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3475 
       
  3476 	EAP_TRACE_DEBUG(
       
  3477 		m_am_tools,
       
  3478 		TRACE_FLAGS_DEFAULT,
       
  3479 		(EAPL("EAPOL_KEY: eapol_key_state_c::parse_key_data()\n")));
       
  3480 
       
  3481 	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_key_state_c::parse_key_data()");
       
  3482 
       
  3483 	eapol_rsna_key_data_header_c payload(
       
  3484 		m_am_tools,
       
  3485 		get_is_RSNA(),
       
  3486 		get_is_WPXM(),
       
  3487 		p_payload->get_header_buffer(*buffer_length),
       
  3488 		*buffer_length); // Const correctness is gone.
       
  3489 
       
  3490 	eapol_RSNA_key_descriptor_type_e current_payload = payload.get_descriptor_type();
       
  3491 
       
  3492 	eap_status_e status = eap_status_header_corrupted;
       
  3493 
       
  3494 	if (payload.get_is_valid() == true
       
  3495 		&& current_payload != eapol_RSNA_key_data_type_none)
       
  3496 	{
       
  3497 
       
  3498 		if (get_is_RSNA() == true
       
  3499 			|| expected_key_message != eapol_key_state_wait_group_key_handshake_message_1 // WPA must check the expected message.
       
  3500 			)
       
  3501 		{
       
  3502 			if (*buffer_length < payload.get_header_and_body_length())
       
  3503 			{
       
  3504 				EAP_TRACE_ERROR(
       
  3505 					m_am_tools,
       
  3506 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3507 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(0x%08x): ")
       
  3508 					 EAPL("current payload 0x%04x=%s, payload length 0x%04x, buffer length 0x%04x.\n"),
       
  3509 					 payload.get_header_buffer(0ul),
       
  3510 					 current_payload,
       
  3511 					 payload.get_payload_type_string(),
       
  3512 					 payload.get_header_and_body_length(),
       
  3513 					 *buffer_length));
       
  3514 				EAP_TRACE_ERROR(
       
  3515 					m_am_tools,
       
  3516 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3517 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ")
       
  3518 					 EAPL("EAPOl Key Data-payload header is corrupted.\n")));
       
  3519 				EAP_TRACE_DATA_ERROR(
       
  3520 					m_am_tools,
       
  3521 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3522 					(EAPL("payload"),
       
  3523 					payload.get_header_buffer(*buffer_length),
       
  3524 					*buffer_length));
       
  3525 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3526 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3527 			}
       
  3528 		}
       
  3529 
       
  3530 		status = parse_generic_key_data_payload(
       
  3531 			eapol_key_descriptor_type,
       
  3532 			current_payload,
       
  3533 			&payload,
       
  3534 			buffer_length,
       
  3535 			p_rsna_key_data_payloads,
       
  3536 			expected_key_message);
       
  3537 		if (status != eap_status_ok)
       
  3538 		{
       
  3539 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3540 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3541 		}
       
  3542 
       
  3543 
       
  3544 		while(*buffer_length >= payload.get_header_length()
       
  3545 			&& payload.get_is_valid() == true
       
  3546 			&& payload.get_header_buffer_length()
       
  3547 			  >= (payload.get_header_and_body_length()))
       
  3548 		{
       
  3549 			payload.set_header_buffer(
       
  3550 					payload.get_next_header(),
       
  3551 					payload.get_header_buffer_length()
       
  3552 					-(payload.get_header_and_body_length()));
       
  3553 			if (payload.get_is_valid() == false)
       
  3554 			{
       
  3555 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3556 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3557 			}
       
  3558 
       
  3559 			current_payload = payload.get_descriptor_type();
       
  3560 
       
  3561 			if (*buffer_length < payload.get_header_and_body_length())
       
  3562 			{
       
  3563 				EAP_TRACE_ERROR(
       
  3564 					m_am_tools,
       
  3565 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3566 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(0x%08x): ")
       
  3567 					 EAPL("current payload 0x%04x=%s, payload length 0x%04x, buffer length 0x%04x.\n"),
       
  3568 					 payload.get_header_buffer(0ul),
       
  3569 					 current_payload,
       
  3570 					 payload.get_payload_type_string(),
       
  3571 					 payload.get_header_and_body_length(),
       
  3572 					 *buffer_length));
       
  3573 				EAP_TRACE_ERROR(
       
  3574 					m_am_tools,
       
  3575 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3576 					(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ")
       
  3577 					 EAPL("EAPOl Key Data-payload header is corrupted.\n")));
       
  3578 				EAP_TRACE_DATA_ERROR(
       
  3579 					m_am_tools,
       
  3580 					TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3581 					(EAPL("payload"),
       
  3582 					payload.get_header_buffer(*buffer_length),
       
  3583 					*buffer_length));
       
  3584 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3585 				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3586 			}
       
  3587 
       
  3588 			status = parse_generic_key_data_payload(
       
  3589 				eapol_key_descriptor_type,
       
  3590 				current_payload,
       
  3591 				&payload,
       
  3592 				buffer_length,
       
  3593 				p_rsna_key_data_payloads,
       
  3594 				expected_key_message);
       
  3595 			if (status != eap_status_ok)
       
  3596 			{
       
  3597 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3598 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3599 			}
       
  3600 		}
       
  3601 	}
       
  3602 
       
  3603 	if (*buffer_length != 0u)
       
  3604 	{
       
  3605 		if (key_descriptor_version == eapol_RSNA_key_header_c::m_key_descriptor_version_1)
       
  3606 		{
       
  3607 			EAP_TRACE_ERROR(
       
  3608 				m_am_tools,
       
  3609 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3610 				(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::parse_key_data(): ")
       
  3611 				 EAPL("EAPOl Key Data-header is corrupted. Buffer length ")
       
  3612 				 EAPL("and payload length does not match. %lu illegal bytes.\n"),
       
  3613 				 *buffer_length));
       
  3614 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3615 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3616 		}
       
  3617 	}
       
  3618 
       
  3619 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3620 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3621 }
       
  3622 
       
  3623 //--------------------------------------------------
       
  3624 
       
  3625 //
       
  3626 eap_status_e eapol_key_state_c::rsna_prf(
       
  3627 	const eap_variable_data_c * const key_K,
       
  3628 	const eap_variable_data_c * const label_A,
       
  3629 	const eap_variable_data_c * const input_B,
       
  3630 	const u32_t output_length_bits,
       
  3631 	eap_variable_data_c * const output
       
  3632 	)
       
  3633 {
       
  3634 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3635 	eap_status_e status = eap_status_process_general_error;
       
  3636 
       
  3637 	crypto_sha1_c sha1(m_am_tools);
       
  3638 	status = sha1.hash_init();
       
  3639 	if (status != eap_status_ok)
       
  3640 	{
       
  3641 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3642 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3643 	}
       
  3644 
       
  3645 	crypto_hmac_c hmac(m_am_tools, &sha1, false);
       
  3646 
       
  3647 	if (hmac.get_is_valid() == false)
       
  3648 	{
       
  3649 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3650 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3651 	}
       
  3652 
       
  3653 	u32_t required_digest_count = (output_length_bits+159)/160;
       
  3654 	u32_t required_buffer_length = hmac.get_digest_length()*required_digest_count;
       
  3655 	u32_t required_octet_count = output_length_bits/8ul;
       
  3656 
       
  3657 	output->reset();
       
  3658 	status = output->set_buffer_length(required_buffer_length);
       
  3659 	if (status != eap_status_ok)
       
  3660 	{
       
  3661 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3662 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3663 	}
       
  3664 	output->set_data_length(output->get_buffer_length());
       
  3665 
       
  3666 	eap_variable_data_c input(m_am_tools);
       
  3667 	if (input.get_is_valid() == false)
       
  3668 	{
       
  3669 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3670 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3671 	}
       
  3672 
       
  3673 	u8_t zero = 0ul;
       
  3674 
       
  3675 	status = input.set_buffer_length(
       
  3676 		label_A->get_data_length()
       
  3677 		+ sizeof(zero)
       
  3678 		+ input_B->get_data_length()
       
  3679 		+ sizeof(u8_t));
       
  3680 	if (status != eap_status_ok)
       
  3681 	{
       
  3682 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3683 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3684 	}
       
  3685 
       
  3686 	for (u8_t ind = 0ul; ind < required_digest_count; ind++)
       
  3687 	{
       
  3688 		status = input.reset_start_offset_and_data_length();
       
  3689 		if (status != eap_status_ok)
       
  3690 		{
       
  3691 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3692 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3693 		}
       
  3694 
       
  3695 		status = hmac.hmac_set_key(key_K);
       
  3696 		if (status != eap_status_ok)
       
  3697 		{
       
  3698 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3699 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3700 		}
       
  3701 
       
  3702 		if (label_A->get_is_valid_data() == true)
       
  3703 		{
       
  3704 			status = input.add_data(label_A);
       
  3705 			if (status != eap_status_ok)
       
  3706 			{
       
  3707 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3708 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3709 			}
       
  3710 
       
  3711 			status = input.add_data(&zero, sizeof(zero));
       
  3712 			if (status != eap_status_ok)
       
  3713 			{
       
  3714 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3715 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  3716 			}
       
  3717 		}
       
  3718 
       
  3719 		status = input.add_data(input_B);
       
  3720 		if (status != eap_status_ok)
       
  3721 		{
       
  3722 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3723 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3724 		}
       
  3725 
       
  3726 		status = input.add_data(&ind, sizeof(ind));
       
  3727 		if (status != eap_status_ok)
       
  3728 		{
       
  3729 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3730 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3731 		}
       
  3732 
       
  3733 		status = hmac.hmac_update(
       
  3734 			input.get_data(input.get_data_length()),
       
  3735 			input.get_data_length());
       
  3736 		if (status != eap_status_ok)
       
  3737 		{
       
  3738 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3739 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3740 		}
       
  3741 
       
  3742 		u32_t md_length = hmac.get_digest_length();
       
  3743 
       
  3744 		status = hmac.hmac_final(
       
  3745 			output->get_data_offset(
       
  3746 				ind*hmac.get_digest_length(),
       
  3747 				hmac.get_digest_length()),
       
  3748 			&md_length);
       
  3749 		if (status != eap_status_ok)
       
  3750 		{
       
  3751 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3752 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3753 		}
       
  3754 		
       
  3755 	} // for()
       
  3756 
       
  3757 	output->set_data_length(required_octet_count);
       
  3758 
       
  3759 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3760 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3761 }
       
  3762 
       
  3763 //--------------------------------------------------
       
  3764 
       
  3765 //
       
  3766 eap_status_e eapol_key_state_c::select_minimum(
       
  3767 	const eap_variable_data_c * const input_a,
       
  3768 	const eap_variable_data_c * const input_b,
       
  3769 	const eap_variable_data_c ** const minimum,
       
  3770 	const eap_variable_data_c ** const maximum)
       
  3771 {
       
  3772 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3773 
       
  3774 	if (input_a == 0
       
  3775 		|| input_b == 0
       
  3776 		|| minimum == 0
       
  3777 		|| maximum == 0)
       
  3778 	{
       
  3779 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3780 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3781 	}
       
  3782 
       
  3783 	if (input_a->get_data_length() > input_b->get_data_length())
       
  3784 	{
       
  3785 		*minimum = input_b;
       
  3786 		*maximum = input_a;
       
  3787 	}
       
  3788 	else if (input_a->get_data_length() < input_b->get_data_length())
       
  3789 	{
       
  3790 		*minimum = input_a;
       
  3791 		*maximum = input_b;
       
  3792 	}
       
  3793 	else
       
  3794 	{
       
  3795 		const i32_t cmp = input_a->compare(input_b);
       
  3796 		if (cmp < 0)
       
  3797 		{
       
  3798 			*minimum = input_a;
       
  3799 			*maximum = input_b;
       
  3800 		}
       
  3801 		else // if (cmp >= 0) NOTE this includes equal case too.
       
  3802 		{
       
  3803 			*minimum = input_b;
       
  3804 			*maximum = input_a;
       
  3805 		}
       
  3806 	}
       
  3807 
       
  3808 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3809 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3810 }
       
  3811 
       
  3812 //--------------------------------------------------
       
  3813 
       
  3814 //
       
  3815 eap_status_e eapol_key_state_c::derive_PTK()
       
  3816 {
       
  3817 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3818 
       
  3819 	EAP_TRACE_DEBUG(
       
  3820 		m_am_tools,
       
  3821 		TRACE_FLAGS_DEFAULT,
       
  3822 		(EAPL("eapol_key_state_c::derive_PTK(): %s\n"),
       
  3823 		 (m_is_client == true) ? "client": "server"));
       
  3824 
       
  3825 	eap_status_e status = eap_status_process_general_error;
       
  3826 
       
  3827 	if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false)
       
  3828 	{
       
  3829 		EAP_TRACE_ERROR(
       
  3830 			m_am_tools,
       
  3831 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3832 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ")
       
  3833 			 EAPL("Pairwise Master Key (PMK) is missing.\n")));
       
  3834 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3835 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3836 	}
       
  3837 
       
  3838 	if (m_supplicant_MAC_address.get_is_valid_data() == false)
       
  3839 	{
       
  3840 		EAP_TRACE_ERROR(
       
  3841 			m_am_tools,
       
  3842 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3843 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ")
       
  3844 			 EAPL("Supplicant MAC address is missing.\n")));
       
  3845 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3846 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3847 	}
       
  3848 
       
  3849 	if (m_authenticator_MAC_address.get_is_valid_data() == false)
       
  3850 	{
       
  3851 		EAP_TRACE_ERROR(
       
  3852 			m_am_tools,
       
  3853 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3854 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ")
       
  3855 			 EAPL("Authenticator MAC address is missing.\n")));
       
  3856 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3857 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3858 	}
       
  3859 
       
  3860 	if (m_ANonce.get_is_valid_data() == false)
       
  3861 	{
       
  3862 		EAP_TRACE_ERROR(
       
  3863 			m_am_tools,
       
  3864 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3865 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ")
       
  3866 			 EAPL("Authenticator nonce (ANonce) is missing.\n")));
       
  3867 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3868 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3869 	}
       
  3870 
       
  3871 	if (m_SNonce.get_is_valid_data() == false)
       
  3872 	{
       
  3873 		EAP_TRACE_ERROR(
       
  3874 			m_am_tools,
       
  3875 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  3876 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::derive_PTK(): ")
       
  3877 			 EAPL("Supplicant nonce (m_SNonce) is missing.\n")));
       
  3878 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3879 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3880 	}
       
  3881 
       
  3882 	EAP_TRACE_DATA_DEBUG(
       
  3883 		m_am_tools,
       
  3884 		TRACE_FLAGS_DEFAULT,
       
  3885 		(EAPL("EAPOL-Key m_supplicant_MAC_address"),
       
  3886 		 m_supplicant_MAC_address.get_data(m_supplicant_MAC_address.get_data_length()),
       
  3887 		 m_supplicant_MAC_address.get_data_length()));
       
  3888 
       
  3889 	EAP_TRACE_DATA_DEBUG(
       
  3890 		m_am_tools,
       
  3891 		TRACE_FLAGS_DEFAULT,
       
  3892 		(EAPL("EAPOL-Key m_authenticator_MAC_address"),
       
  3893 		 m_authenticator_MAC_address.get_data(m_authenticator_MAC_address.get_data_length()),
       
  3894 		 m_authenticator_MAC_address.get_data_length()));
       
  3895 
       
  3896 	EAP_TRACE_DATA_DEBUG(
       
  3897 		m_am_tools,
       
  3898 		TRACE_FLAGS_DEFAULT,
       
  3899 		(EAPL("EAPOL-Key m_SNonce"),
       
  3900 		 m_SNonce.get_data(m_SNonce.get_data_length()),
       
  3901 		 m_SNonce.get_data_length()));
       
  3902 
       
  3903 	EAP_TRACE_DATA_DEBUG(
       
  3904 		m_am_tools,
       
  3905 		TRACE_FLAGS_DEFAULT,
       
  3906 		(EAPL("EAPOL-Key m_ANonce"),
       
  3907 		 m_ANonce.get_data(m_ANonce.get_data_length()),
       
  3908 		 m_ANonce.get_data_length()));
       
  3909 
       
  3910 	EAP_TRACE_DATA_DEBUG(
       
  3911 		m_am_tools,
       
  3912 		TRACE_FLAGS_DEFAULT,
       
  3913 		(EAPL("EAPOL-Key m_pairwise_PMK_WPXK3"),
       
  3914 		 m_pairwise_PMK_WPXK3.get_data(m_pairwise_PMK_WPXK3.get_data_length()),
       
  3915 		 m_pairwise_PMK_WPXK3.get_data_length()));
       
  3916 
       
  3917 
       
  3918 	const eap_variable_data_c * minimum_MAC_address = 0;
       
  3919 	const eap_variable_data_c * maximum_MAC_address = 0;
       
  3920 	const eap_variable_data_c * minimum_nonce = 0;
       
  3921 	const eap_variable_data_c * maximum_nonce = 0;
       
  3922 
       
  3923 	status = select_minimum(
       
  3924 		&m_supplicant_MAC_address,
       
  3925 		&m_authenticator_MAC_address,
       
  3926 		&minimum_MAC_address,
       
  3927 		&maximum_MAC_address);
       
  3928 	if (status != eap_status_ok)
       
  3929 	{
       
  3930 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3931 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3932 	}
       
  3933 
       
  3934 	status = select_minimum(
       
  3935 		&m_ANonce,
       
  3936 		&m_SNonce,
       
  3937 		&minimum_nonce,
       
  3938 		&maximum_nonce);
       
  3939 	if (status != eap_status_ok)
       
  3940 	{
       
  3941 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3942 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3943 	}
       
  3944 
       
  3945 
       
  3946 
       
  3947 	eap_variable_data_c input(m_am_tools);
       
  3948 
       
  3949 	status = input.set_buffer_length(
       
  3950 		minimum_MAC_address->get_data_length()
       
  3951 		+ maximum_MAC_address->get_data_length()
       
  3952 		+ minimum_nonce->get_data_length()
       
  3953 		+ maximum_nonce->get_data_length());
       
  3954 	if (status != eap_status_ok)
       
  3955 	{
       
  3956 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3957 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3958 	}
       
  3959 
       
  3960 	status = input.add_data(minimum_MAC_address);
       
  3961 	if (status != eap_status_ok)
       
  3962 	{
       
  3963 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3964 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3965 	}
       
  3966 
       
  3967 	status = input.add_data(maximum_MAC_address);
       
  3968 	if (status != eap_status_ok)
       
  3969 	{
       
  3970 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3971 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3972 	}
       
  3973 
       
  3974 	status = input.add_data(minimum_nonce);
       
  3975 	if (status != eap_status_ok)
       
  3976 	{
       
  3977 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3978 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3979 	}
       
  3980 
       
  3981 	status = input.add_data(maximum_nonce);
       
  3982 	if (status != eap_status_ok)
       
  3983 	{
       
  3984 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3985 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3986 	}
       
  3987 
       
  3988 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  3989 
       
  3990 	// Default is TKIP.
       
  3991 	u32_t PTK_length = EAPOL_RSNA_TKIP_PTK_LENGTH_BITS;
       
  3992 	u32_t tk_length_bytes = EAPOL_RSNA_TKIP_TK_LENGTH_BYTES;
       
  3993 
       
  3994 	if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP)
       
  3995 	{
       
  3996 		PTK_length = EAPOL_RSNA_CCMP_PTK_LENGTH_BITS;
       
  3997 		tk_length_bytes = EAPOL_RSNA_CCMP_TK_LENGTH_BYTES;
       
  3998 	}
       
  3999 	else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40)
       
  4000 	{
       
  4001 		tk_length_bytes = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_40;
       
  4002 	}
       
  4003 	else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104)
       
  4004 	{
       
  4005 		tk_length_bytes = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_104;
       
  4006 	}
       
  4007 
       
  4008 	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       
  4009 
       
  4010 	eap_variable_data_c label(m_am_tools);
       
  4011 
       
  4012 	status = label.set_copy_of_buffer(
       
  4013 			EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL,
       
  4014 			EAPOL_RSNA_PAIRWISE_KEY_EXPANSION_LABEL_LENGTH);
       
  4015 	if (status != eap_status_ok)
       
  4016 	{
       
  4017 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4018 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4019 	}
       
  4020 
       
  4021 	status = rsna_prf(
       
  4022 		&m_pairwise_PMK_WPXK3,
       
  4023 		&label,
       
  4024 		&input,
       
  4025 		PTK_length,
       
  4026 		&m_transient_PTK);
       
  4027 	if (status != eap_status_ok)
       
  4028 	{
       
  4029 		m_transient_PTK.reset();
       
  4030 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4031 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4032 	}
       
  4033 
       
  4034 	// Split PTK to KCK, KEK and TK.
       
  4035 	status = m_confirmation_KCK.set_buffer(
       
  4036 		m_transient_PTK.get_data_offset(EAPOL_RSNA_KCK_OFFSET_BYTES, EAPOL_RSNA_KCK_LENGTH_BYTES),
       
  4037 		EAPOL_RSNA_KCK_LENGTH_BYTES,
       
  4038 		false,
       
  4039 		false);
       
  4040 	if (status != eap_status_ok)
       
  4041 	{
       
  4042 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4043 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4044 	}
       
  4045 
       
  4046 	status = m_encryption_KEK.set_buffer(
       
  4047 		m_transient_PTK.get_data_offset(EAPOL_RSNA_KEK_OFFSET_BYTES, EAPOL_RSNA_KEK_LENGTH_BYTES),
       
  4048 		EAPOL_RSNA_KEK_LENGTH_BYTES,
       
  4049 		false,
       
  4050 		false);
       
  4051 	if (status != eap_status_ok)
       
  4052 	{
       
  4053 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4054 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4055 	}
       
  4056 
       
  4057 	status = m_temporal_TK.set_buffer(
       
  4058 		m_transient_PTK.get_data_offset(EAPOL_RSNA_TK_OFFSET_BYTES, tk_length_bytes),
       
  4059 		tk_length_bytes,
       
  4060 		false,
       
  4061 		false);
       
  4062 	if (status != eap_status_ok)
       
  4063 	{
       
  4064 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4065 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4066 	}
       
  4067 
       
  4068 
       
  4069 	EAP_TRACE_DATA_DEBUG(
       
  4070 		m_am_tools,
       
  4071 		TRACE_FLAGS_DEFAULT,
       
  4072 		(EAPL("EAPOL-Key KCK"),
       
  4073 		 m_confirmation_KCK.get_data(m_confirmation_KCK.get_data_length()),
       
  4074 		 m_confirmation_KCK.get_data_length()));
       
  4075 
       
  4076 	EAP_TRACE_DATA_DEBUG(
       
  4077 		m_am_tools,
       
  4078 		TRACE_FLAGS_DEFAULT,
       
  4079 		(EAPL("EAPOL-Key KEK"),
       
  4080 		 m_encryption_KEK.get_data(m_encryption_KEK.get_data_length()),
       
  4081 		 m_encryption_KEK.get_data_length()));
       
  4082 
       
  4083 	EAP_TRACE_DATA_DEBUG(
       
  4084 		m_am_tools,
       
  4085 		TRACE_FLAGS_DEFAULT,
       
  4086 		(EAPL("EAPOL-Key TK"),
       
  4087 		 m_temporal_TK.get_data(m_temporal_TK.get_data_length()),
       
  4088 		 m_temporal_TK.get_data_length()));
       
  4089 
       
  4090 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4091 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4092 }
       
  4093 
       
  4094 //--------------------------------------------------
       
  4095 
       
  4096 //
       
  4097 eap_status_e eapol_key_state_c::create_nonce(
       
  4098 	eap_variable_data_c * const nonce,	const u32_t nonce_length)
       
  4099 {
       
  4100 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4101 
       
  4102 	EAP_TRACE_DEBUG(
       
  4103 		m_am_tools,
       
  4104 		TRACE_FLAGS_DEFAULT,
       
  4105 		(EAPL("eapol_key_state_c::create_nonce(): %s\n"),
       
  4106 		 (m_is_client == true) ? "client": "server"));
       
  4107 
       
  4108 	eap_status_e status = eap_status_process_general_error;
       
  4109 
       
  4110 	status = nonce->set_buffer_length(nonce_length);
       
  4111 	if (status != eap_status_ok)
       
  4112 	{
       
  4113 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4114 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4115 	}
       
  4116 	nonce->set_data_length(nonce_length);
       
  4117 
       
  4118 	crypto_random_c rand(m_am_tools);
       
  4119 
       
  4120 	if (rand.get_is_valid() == false)
       
  4121 	{
       
  4122 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4123 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4124 	}
       
  4125 
       
  4126 	status = rand.get_rand_bytes(
       
  4127 		nonce->get_data(nonce->get_data_length()),
       
  4128 		nonce->get_data_length());
       
  4129 	if (status != eap_status_ok)
       
  4130 	{
       
  4131 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4132 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4133 	}
       
  4134 
       
  4135 	EAP_TRACE_DATA_DEBUG(
       
  4136 		m_am_tools,
       
  4137 		TRACE_FLAGS_DEFAULT,
       
  4138 		(EAPL("EAPOL-Key new nonce"),
       
  4139 		 nonce->get_data(nonce->get_data_length()),
       
  4140 		 nonce->get_data_length()));
       
  4141 
       
  4142 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4143 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4144 }
       
  4145 
       
  4146 //--------------------------------------------------
       
  4147 
       
  4148 //
       
  4149 eap_status_e eapol_key_state_c::create_PMKID()
       
  4150 {
       
  4151 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4152 	eap_status_e status = eap_status_process_general_error;
       
  4153 
       
  4154 	if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false)
       
  4155 	{
       
  4156 		EAP_TRACE_ERROR(
       
  4157 			m_am_tools,
       
  4158 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4159 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ")
       
  4160 			 EAPL("Pairwise Master Key (PMK) is missing.\n")));
       
  4161 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4162 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4163 	}
       
  4164 
       
  4165 	if (m_supplicant_MAC_address.get_is_valid_data() == false)
       
  4166 	{
       
  4167 		EAP_TRACE_ERROR(
       
  4168 			m_am_tools,
       
  4169 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4170 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ")
       
  4171 			 EAPL("Supplicant MAC address is missing.\n")));
       
  4172 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4173 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4174 	}
       
  4175 
       
  4176 	if (m_authenticator_MAC_address.get_is_valid_data() == false)
       
  4177 	{
       
  4178 		EAP_TRACE_ERROR(
       
  4179 			m_am_tools,
       
  4180 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4181 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_PMKID(): ")
       
  4182 			 EAPL("Authenticator MAC address is missing.\n")));
       
  4183 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4184 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4185 	}
       
  4186 
       
  4187 
       
  4188 	crypto_sha1_c sha1(m_am_tools);
       
  4189 
       
  4190 	status = sha1.hash_init();
       
  4191 	if (status != eap_status_ok)
       
  4192 	{
       
  4193 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4194 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4195 	}
       
  4196 
       
  4197 	crypto_hmac_c hmac(m_am_tools, &sha1, false);
       
  4198 
       
  4199 	if (hmac.get_is_valid() == false)
       
  4200 	{
       
  4201 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4202 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4203 	}
       
  4204 
       
  4205 	status = hmac.hmac_set_key(&m_pairwise_PMK_WPXK3);
       
  4206 	if (status != eap_status_ok)
       
  4207 	{
       
  4208 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4209 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4210 	}
       
  4211 
       
  4212 	status = hmac.hmac_update(
       
  4213 		EAPOL_RSNA_PMK_NAME_LABEL,
       
  4214 		EAPOL_RSNA_PMK_NAME_LABEL_LENGTH);
       
  4215 	if (status != eap_status_ok)
       
  4216 	{
       
  4217 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4218 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4219 	}
       
  4220 
       
  4221 	status = hmac.hmac_update(
       
  4222 		m_authenticator_MAC_address.get_data(m_authenticator_MAC_address.get_data_length()),
       
  4223 		m_authenticator_MAC_address.get_data_length());
       
  4224 	if (status != eap_status_ok)
       
  4225 	{
       
  4226 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4227 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4228 	}
       
  4229 
       
  4230 	status = hmac.hmac_update(
       
  4231 		m_supplicant_MAC_address.get_data(m_supplicant_MAC_address.get_data_length()),
       
  4232 		m_supplicant_MAC_address.get_data_length());
       
  4233 	if (status != eap_status_ok)
       
  4234 	{
       
  4235 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4236 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4237 	}
       
  4238 
       
  4239 
       
  4240 	{
       
  4241 		m_PMKID.reset();
       
  4242 
       
  4243 		status = m_PMKID.set_buffer_length(hmac.get_digest_length());
       
  4244 		if (status != eap_status_ok)
       
  4245 		{
       
  4246 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4247 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4248 		}
       
  4249 		m_PMKID.set_data_length(hmac.get_digest_length());
       
  4250 
       
  4251 		u32_t md_length = hmac.get_digest_length();
       
  4252 
       
  4253 		status = hmac.hmac_final(
       
  4254 			m_PMKID.get_data(hmac.get_digest_length()),
       
  4255 			&md_length);
       
  4256 		if (status != eap_status_ok)
       
  4257 		{
       
  4258 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4259 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4260 		}
       
  4261 
       
  4262 		if (md_length < eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE)
       
  4263 		{
       
  4264 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4265 			return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
       
  4266 		}
       
  4267 
       
  4268 		// This cuts the PMKID to 128 bits.
       
  4269 		m_PMKID.set_data_length(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_DATA_PMKID_SIZE);
       
  4270 
       
  4271 		EAP_TRACE_DATA_DEBUG(
       
  4272 			m_am_tools,
       
  4273 			TRACE_FLAGS_DEFAULT,
       
  4274 			(EAPL("EAPOL-Key PMKID"),
       
  4275 			 m_PMKID.get_data(),
       
  4276 			 m_PMKID.get_data_length()));
       
  4277 	}
       
  4278 
       
  4279 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4280 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4281 }
       
  4282 
       
  4283 //--------------------------------------------------
       
  4284 
       
  4285 //
       
  4286 eap_status_e eapol_key_state_c::encrypt_key_data(
       
  4287 	eapol_RSNA_key_header_c * const eapol_key_message)
       
  4288 {
       
  4289 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4290 	eap_status_e status = eap_status_process_general_error;
       
  4291 
       
  4292 	if (m_encryption_KEK.get_is_valid_data() == false
       
  4293 		|| m_encryption_KEK.get_data_length() == 0ul)
       
  4294 	{
       
  4295 		EAP_TRACE_ERROR(
       
  4296 			m_am_tools,
       
  4297 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4298 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::encrypt_key_data(): ")
       
  4299 			 EAPL("m_encryption_KEK is missing or corrupted.\n")));
       
  4300 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4301 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4302 	}
       
  4303 
       
  4304 
       
  4305 	if (m_eapol_pairwise_cipher
       
  4306 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP
       
  4307 		|| m_eapol_group_cipher
       
  4308 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP)
       
  4309 	{
       
  4310 		EAP_TRACE_DEBUG(
       
  4311 			m_am_tools,
       
  4312 			TRACE_FLAGS_DEFAULT,
       
  4313 			(EAPL("EAPOL_KEY: AES-WRAP encryption algorithm.\n")));
       
  4314 
       
  4315 		crypto_aes_wrap_c aes_wrap(m_am_tools);
       
  4316 
       
  4317 		if (aes_wrap.get_is_valid() == false)
       
  4318 		{
       
  4319 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4320 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4321 		}
       
  4322 
       
  4323 		status = aes_wrap.set_encryption_key(
       
  4324 			m_encryption_KEK.get_data(),
       
  4325 			m_encryption_KEK.get_data_length());
       
  4326 		if (status != eap_status_ok)
       
  4327 		{
       
  4328 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4329 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4330 		}
       
  4331 
       
  4332 		u32_t padding_length(0ul);
       
  4333 		u32_t min_key_data_length = 2ul * aes_wrap.get_block_size();
       
  4334 
       
  4335 		if (eapol_key_message->get_key_data_length() < min_key_data_length)
       
  4336 		{
       
  4337 			padding_length = min_key_data_length - eapol_key_message->get_key_data_length();
       
  4338 		}
       
  4339 		else if ((eapol_key_message->get_key_data_length() % aes_wrap.get_block_size()) != 0)
       
  4340 		{
       
  4341 			padding_length = aes_wrap.get_block_size()
       
  4342 				- (eapol_key_message->get_key_data_length() % aes_wrap.get_block_size());
       
  4343 		}
       
  4344 
       
  4345 		u32_t padding_offset = eapol_key_message->get_key_data_length();
       
  4346 
       
  4347 		// AES-Wrap increases message length with one block.
       
  4348 		status = eapol_key_message->set_key_data_length(
       
  4349 			static_cast<u16_t>(eapol_key_message->get_key_data_length()
       
  4350 			+ padding_length
       
  4351 			+ aes_wrap.get_block_size()));
       
  4352 		if (status != eap_status_ok)
       
  4353 		{
       
  4354 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4355 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4356 		}
       
  4357 
       
  4358 		if (padding_length > 0ul)
       
  4359 		{
       
  4360 			aes_wrap.add_padding_bytes(
       
  4361 				eapol_key_message->get_key_data_offset(
       
  4362 					padding_offset,
       
  4363 					padding_length),
       
  4364 				padding_length);
       
  4365 		}
       
  4366 
       
  4367 		if (eapol_key_message->get_key_data_length() < aes_wrap.get_block_size())
       
  4368 		{
       
  4369 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4370 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4371 		}
       
  4372 
       
  4373 		status = aes_wrap.encrypt_block(
       
  4374 			eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4375 			eapol_key_message->get_key_data_length()-aes_wrap.get_block_size(),
       
  4376 			eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4377 			eapol_key_message->get_key_data_length());
       
  4378 
       
  4379 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4380 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4381 	}
       
  4382 	else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP
       
  4383 			 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40
       
  4384 			 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104)
       
  4385 	{
       
  4386 		EAP_TRACE_DEBUG(
       
  4387 			m_am_tools,
       
  4388 			TRACE_FLAGS_DEFAULT,
       
  4389 			(EAPL("EAPOL_KEY: RC4 encryption algorithm.\n")));
       
  4390 
       
  4391 		if (m_EAPOL_key_IV.get_is_valid_data() == false
       
  4392 			|| m_EAPOL_key_IV.get_data_length() == 0ul)
       
  4393 		{
       
  4394 			EAP_TRACE_ERROR(
       
  4395 				m_am_tools,
       
  4396 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4397 				(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::encrypt_key_data(): ")
       
  4398 				 EAPL("m_EAPOL_key_IV is missing or corrupted.\n")));
       
  4399 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4400 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4401 		}
       
  4402 
       
  4403 		abs_crypto_stream_algorithm_c * const rc4 = new crypto_rc4_c(m_am_tools);
       
  4404 		eap_automatic_variable_c<abs_crypto_stream_algorithm_c> automatic_rc4(m_am_tools, rc4);
       
  4405 
       
  4406 		if (rc4 == 0
       
  4407 			|| rc4->get_is_valid() == false)
       
  4408 		{
       
  4409 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4410 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4411 		}
       
  4412 
       
  4413 		eap_variable_data_c key(m_am_tools);
       
  4414 
       
  4415 		status = key.set_copy_of_buffer(&m_EAPOL_key_IV);
       
  4416 		if (status != eap_status_ok)
       
  4417 		{
       
  4418 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4419 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4420 		}
       
  4421 
       
  4422 		status = key.add_data(&m_encryption_KEK);
       
  4423 		if (status != eap_status_ok)
       
  4424 		{
       
  4425 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4426 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4427 		}
       
  4428 
       
  4429 		EAP_TRACE_DATA_DEBUG(
       
  4430 			m_am_tools,
       
  4431 			TRACE_FLAGS_DEFAULT,
       
  4432 			(EAPL("EAPOL-Key encrypt key"),
       
  4433 			 key.get_data(key.get_data_length()),
       
  4434 			 key.get_data_length()));
       
  4435 
       
  4436 		status = rc4->set_key(&key);
       
  4437 		if (status != eap_status_ok)
       
  4438 		{
       
  4439 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4440 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4441 		}
       
  4442 
       
  4443 		// The first 256 octets of RC4 key stream are discarded.
       
  4444 		status = rc4->discard_stream(EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_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 		EAP_TRACE_DATA_DEBUG(
       
  4452 			m_am_tools,
       
  4453 			TRACE_FLAGS_DEFAULT,
       
  4454 			(EAPL("EAPOL-Key plaintext data"),
       
  4455 			 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4456 			 eapol_key_message->get_key_data_length()));
       
  4457 
       
  4458 		status = rc4->encrypt_data(
       
  4459 			eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4460 			eapol_key_message->get_key_data_length());
       
  4461 		if (status != eap_status_ok)
       
  4462 		{
       
  4463 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4464 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4465 		}
       
  4466 
       
  4467 		EAP_TRACE_DATA_DEBUG(
       
  4468 			m_am_tools,
       
  4469 			TRACE_FLAGS_DEFAULT,
       
  4470 			(EAPL("EAPOL-Key encrypted data"),
       
  4471 			 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4472 			 eapol_key_message->get_key_data_length()));
       
  4473 
       
  4474 	}
       
  4475 	else
       
  4476 	{
       
  4477 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4478 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  4479 	}
       
  4480 
       
  4481 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4482 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4483 }
       
  4484 
       
  4485 //--------------------------------------------------
       
  4486 
       
  4487 //
       
  4488 eap_status_e eapol_key_state_c::decrypt_key_data(
       
  4489 	eapol_RSNA_key_header_c * const eapol_key_message)
       
  4490 {
       
  4491 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4492 	eap_status_e status = eap_status_process_general_error;
       
  4493 
       
  4494 
       
  4495 	if (m_eapol_pairwise_cipher
       
  4496 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP
       
  4497 		|| m_eapol_group_cipher
       
  4498 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP)
       
  4499 	{
       
  4500 		EAP_TRACE_DEBUG(
       
  4501 			m_am_tools,
       
  4502 			TRACE_FLAGS_DEFAULT,
       
  4503 			(EAPL("EAPOL_KEY: AES-WRAP decryption algorithm.\n")));
       
  4504 
       
  4505 		crypto_aes_wrap_c aes_wrap(m_am_tools);
       
  4506 
       
  4507 		if (aes_wrap.get_is_valid() == false)
       
  4508 		{
       
  4509 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4510 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4511 		}
       
  4512 
       
  4513 		status = aes_wrap.set_decryption_key(
       
  4514 			m_encryption_KEK.get_data(),
       
  4515 			m_encryption_KEK.get_data_length());
       
  4516 		if (status != eap_status_ok)
       
  4517 		{
       
  4518 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4519 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4520 		}
       
  4521 
       
  4522 		status = aes_wrap.decrypt_block(
       
  4523 			eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4524 			eapol_key_message->get_key_data_length(),
       
  4525 			eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4526 			eapol_key_message->get_key_data_length());
       
  4527 		if (status != eap_status_ok)
       
  4528 		{
       
  4529 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4530 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4531 		}
       
  4532 
       
  4533 		// AES-Wrap increases message length with one block.
       
  4534 		// Here we remove the block.
       
  4535 		status = eapol_key_message->set_key_data_length(
       
  4536 			static_cast<u16_t>(eapol_key_message->get_key_data_length()
       
  4537 			- aes_wrap.get_block_size()));
       
  4538 
       
  4539 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4540 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4541 	}
       
  4542 	else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP
       
  4543 			 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40
       
  4544 			 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104)
       
  4545 	{
       
  4546 		EAP_TRACE_DEBUG(
       
  4547 			m_am_tools,
       
  4548 			TRACE_FLAGS_DEFAULT,
       
  4549 			(EAPL("EAPOL_KEY: RC4 decryption algorithm.\n")));
       
  4550 
       
  4551 		abs_crypto_stream_algorithm_c * const rc4 = new crypto_rc4_c(m_am_tools);
       
  4552 		eap_automatic_variable_c<abs_crypto_stream_algorithm_c> automatic_rc4(m_am_tools, rc4);
       
  4553 
       
  4554 		if (rc4 == 0
       
  4555 			|| rc4->get_is_valid() == false)
       
  4556 		{
       
  4557 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4558 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4559 		}
       
  4560 
       
  4561 		eap_variable_data_c key(m_am_tools);
       
  4562 
       
  4563 		status = key.set_copy_of_buffer(&m_EAPOL_key_IV);
       
  4564 		if (status != eap_status_ok)
       
  4565 		{
       
  4566 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4567 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4568 		}
       
  4569 
       
  4570 		status = key.add_data(&m_encryption_KEK);
       
  4571 		if (status != eap_status_ok)
       
  4572 		{
       
  4573 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4574 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4575 		}
       
  4576 
       
  4577 		EAP_TRACE_DATA_DEBUG(
       
  4578 			m_am_tools,
       
  4579 			TRACE_FLAGS_DEFAULT,
       
  4580 			(EAPL("EAPOL-Key decrypt key"),
       
  4581 			 key.get_data(key.get_data_length()),
       
  4582 			 key.get_data_length()));
       
  4583 
       
  4584 		status = rc4->set_key(&key);
       
  4585 		if (status != eap_status_ok)
       
  4586 		{
       
  4587 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4588 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4589 		}
       
  4590 
       
  4591 		// The first 256 octets of RC4 key stream are discarded.
       
  4592 		status = rc4->discard_stream(EAPOL_RSNA_RC4_KEY_STREAM_DISCARD_LENGTH);
       
  4593 		if (status != eap_status_ok)
       
  4594 		{
       
  4595 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4596 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4597 		}
       
  4598 
       
  4599 		EAP_TRACE_DATA_DEBUG(
       
  4600 			m_am_tools,
       
  4601 			TRACE_FLAGS_DEFAULT,
       
  4602 			(EAPL("EAPOL-Key encrypted data"),
       
  4603 			 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4604 			 eapol_key_message->get_key_data_length()));
       
  4605 
       
  4606 		status = rc4->decrypt_data(
       
  4607 			eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4608 			eapol_key_message->get_key_data_length());
       
  4609 		if (status != eap_status_ok)
       
  4610 		{
       
  4611 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4612 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4613 		}
       
  4614 
       
  4615 		EAP_TRACE_DATA_DEBUG(
       
  4616 			m_am_tools,
       
  4617 			TRACE_FLAGS_DEFAULT,
       
  4618 			(EAPL("EAPOL-Key plaintext data"),
       
  4619 			 eapol_key_message->get_key_data(eapol_key_message->get_key_data_length()),
       
  4620 			 eapol_key_message->get_key_data_length()));
       
  4621 
       
  4622 	}
       
  4623 	else
       
  4624 	{
       
  4625 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4626 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  4627 	}
       
  4628 
       
  4629 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4630 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4631 }
       
  4632 
       
  4633 //--------------------------------------------------
       
  4634 
       
  4635 
       
  4636 //
       
  4637 eap_status_e eapol_key_state_c::create_key_mic(
       
  4638 	eapol_RSNA_key_header_c * const eapol_key_message,
       
  4639 	const eap_variable_data_c * const confirmation_key)
       
  4640 {
       
  4641 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4642 	eap_status_e status = eap_status_process_general_error;
       
  4643 
       
  4644 	if (eapol_key_message == 0)
       
  4645 	{
       
  4646 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4647 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4648 	}
       
  4649 
       
  4650 	if (confirmation_key->get_is_valid_data() == false
       
  4651 		|| confirmation_key->get_data_length() == 0ul)
       
  4652 	{
       
  4653 		EAP_TRACE_ERROR(
       
  4654 			m_am_tools,
       
  4655 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4656 			(EAPL("ERROR: EAPOL_KEY: eapol_key_state_c::create_key_mic(): ")
       
  4657 			 EAPL("confirmation_key is missing or corrupted.\n")));
       
  4658 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4659 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4660 	}
       
  4661 
       
  4662 	status = eapol_key_message->zero_key_MIC(m_am_tools);
       
  4663 	if (status != eap_status_ok)
       
  4664 	{
       
  4665 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4666 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4667 	}
       
  4668 
       
  4669 	crypto_hmac_c * hmac = 0;
       
  4670 	abs_crypto_hash_algorithm_c * hash = 0;
       
  4671 
       
  4672 	if (m_eapol_pairwise_cipher
       
  4673 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP
       
  4674 		|| m_eapol_group_cipher
       
  4675 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP)
       
  4676 	{
       
  4677 		EAP_TRACE_DEBUG(
       
  4678 			m_am_tools,
       
  4679 			TRACE_FLAGS_DEFAULT,
       
  4680 			(EAPL("EAPOL_KEY: HMAC-SHA1 MIC algorithm.\n")));
       
  4681 
       
  4682 		hash = new crypto_sha1_c(m_am_tools);
       
  4683 	}
       
  4684 	else if (m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP
       
  4685 			 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40
       
  4686 			 || m_eapol_pairwise_cipher == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104)
       
  4687 	{		
       
  4688 		EAP_TRACE_DEBUG(
       
  4689 			m_am_tools,
       
  4690 			TRACE_FLAGS_DEFAULT,
       
  4691 			(EAPL("EAPOL_KEY: HMAC-MD5 MIC algorithm.\n")));
       
  4692 
       
  4693 		hash = new crypto_md5_c(m_am_tools);
       
  4694 	}
       
  4695 	else
       
  4696 	{
       
  4697 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4698 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  4699 	}
       
  4700 
       
  4701 	eap_automatic_variable_c<abs_crypto_hash_algorithm_c> automatic_hash(m_am_tools, hash);
       
  4702 
       
  4703 	if (hash == 0
       
  4704 		|| hash->get_is_valid() == false)
       
  4705 	{
       
  4706 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4707 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4708 	}
       
  4709 
       
  4710 	hmac = new crypto_hmac_c(m_am_tools, hash, true);
       
  4711 	automatic_hash.do_not_free_variable();
       
  4712 	eap_automatic_variable_c<crypto_hmac_c> automatic_hmac(m_am_tools, hmac);
       
  4713 	if (hmac == 0
       
  4714 		|| hmac->get_is_valid() == false)
       
  4715 	{
       
  4716 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4717 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4718 	}
       
  4719 
       
  4720 
       
  4721 	EAP_TRACE_DATA_DEBUG(
       
  4722 		m_am_tools,
       
  4723 		TRACE_FLAGS_DEFAULT,
       
  4724 		(EAPL("EAPOL-Key MIC key"),
       
  4725 		 confirmation_key->get_data(),
       
  4726 		 confirmation_key->get_data_length()));
       
  4727 
       
  4728 	status = hmac->hmac_set_key(confirmation_key);
       
  4729 	if (status != eap_status_ok)
       
  4730 	{
       
  4731 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4732 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4733 	}
       
  4734 
       
  4735 	// MIC is calculated over the whole EAPOL-Key message.
       
  4736 	status = hmac->hmac_update(
       
  4737 		eapol_key_message->get_header_buffer(
       
  4738 			eapol_key_message->get_header_buffer_length()),
       
  4739 		eapol_key_message->get_eapol_packet_length());
       
  4740 	if (status != eap_status_ok)
       
  4741 	{
       
  4742 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4743 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4744 	}
       
  4745 
       
  4746 	EAP_TRACE_DATA_DEBUG(
       
  4747 		m_am_tools,
       
  4748 		TRACE_FLAGS_DEFAULT,
       
  4749 		(EAPL("EAPOL-Key MIC data"),
       
  4750 		eapol_key_message->get_header_buffer(
       
  4751 			eapol_key_message->get_header_buffer_length()),
       
  4752 		eapol_key_message->get_eapol_packet_length()));
       
  4753 
       
  4754 
       
  4755 	{
       
  4756 		eap_variable_data_c mic(m_am_tools);
       
  4757 
       
  4758 		status = mic.set_buffer_length(hmac->get_digest_length());
       
  4759 		if (status != eap_status_ok)
       
  4760 		{
       
  4761 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4762 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4763 		}
       
  4764 		mic.set_data_length(hmac->get_digest_length());
       
  4765 
       
  4766 		u32_t md_length = hmac->get_digest_length();
       
  4767 
       
  4768 		status = hmac->hmac_final(
       
  4769 			mic.get_data(hmac->get_digest_length()),
       
  4770 			&md_length);
       
  4771 		if (status != eap_status_ok)
       
  4772 		{
       
  4773 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4774 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4775 		}
       
  4776 
       
  4777 		if (md_length < eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE)
       
  4778 		{
       
  4779 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4780 			return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
       
  4781 		}
       
  4782 
       
  4783 		// This cuts the PMKID to 128 bits.
       
  4784 		mic.set_data_length(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE);
       
  4785 
       
  4786 		// Copy MIC to EAPOL-Key message.
       
  4787 		m_am_tools->memmove(
       
  4788 			eapol_key_message->get_key_MIC(),
       
  4789 			mic.get_data(eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE),
       
  4790 			eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE);
       
  4791 
       
  4792 		EAP_TRACE_DATA_DEBUG(
       
  4793 			m_am_tools,
       
  4794 			TRACE_FLAGS_DEFAULT,
       
  4795 			(EAPL("EAPOL-Key message"),
       
  4796 			 eapol_key_message->get_header_buffer(
       
  4797 				 eapol_key_message->get_header_buffer_length()),
       
  4798 			 eapol_key_message->get_eapol_packet_length()));
       
  4799 	}
       
  4800 	
       
  4801 
       
  4802 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4803 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  4804 }
       
  4805 
       
  4806 //--------------------------------------------------
       
  4807 
       
  4808 //
       
  4809 eap_status_e eapol_key_state_c::verify_key_mic(
       
  4810 	eapol_RSNA_key_header_c * const eapol_key_message,
       
  4811 	const eap_variable_data_c * const confirmation_key)
       
  4812 {
       
  4813 	eap_variable_data_c original_MIC(m_am_tools);
       
  4814 
       
  4815 	// Here we save the original received MIC.
       
  4816 	eap_status_e status = original_MIC.set_copy_of_buffer(
       
  4817 		eapol_key_message->get_key_MIC(),
       
  4818 		eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE);
       
  4819 	if (status != eap_status_ok)
       
  4820 	{
       
  4821 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4822 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4823 	}
       
  4824 
       
  4825 	// This function writes a new MIC to message.
       
  4826 	status = create_key_mic(
       
  4827 		eapol_key_message,
       
  4828 		confirmation_key);
       
  4829 	if (status != eap_status_ok)
       
  4830 	{
       
  4831 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4832 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4833 	}
       
  4834 
       
  4835 	// This will compare the saved original MIC and new created MIC are the same.
       
  4836 	if (m_am_tools->memcmp(
       
  4837 		original_MIC.get_data(original_MIC.get_data_length()),
       
  4838 		eapol_key_message->get_key_MIC(),
       
  4839 		eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE) != 0)
       
  4840 	{
       
  4841 		// MIC failure.
       
  4842 		EAP_TRACE_ERROR(
       
  4843 			m_am_tools,
       
  4844 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4845 			(EAPL("ERROR: EAPOL_KEY: MIC failed.\n")));
       
  4846 		EAP_TRACE_DATA_ERROR(
       
  4847 			m_am_tools,
       
  4848 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4849 			(EAPL("Received MIC"),
       
  4850 			 original_MIC.get_data(original_MIC.get_data_length()),
       
  4851 			 original_MIC.get_data_length()));
       
  4852 		EAP_TRACE_DATA_ERROR(
       
  4853 			m_am_tools,
       
  4854 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  4855 			(EAPL("   Local MIC"),
       
  4856 			 eapol_key_message->get_key_MIC(),
       
  4857 			 eapol_RSNA_key_header_c::EAPOL_RSNA_KEY_MIC_SIZE));
       
  4858 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4859 		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
       
  4860 	}
       
  4861 	else
       
  4862 	{
       
  4863 		EAP_TRACE_DEBUG(
       
  4864 			m_am_tools,
       
  4865 			TRACE_FLAGS_DEFAULT,
       
  4866 			(EAPL("EAPOL_KEY: MIC OK.\n")));
       
  4867 	}
       
  4868 
       
  4869 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4870 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  4871 }
       
  4872 
       
  4873 //--------------------------------------------------
       
  4874 
       
  4875 //
       
  4876 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::add_RSN_GTK_payload(
       
  4877 	const eapol_RSNA_key_header_c * const eapol_key_message,
       
  4878 	eap_variable_data_c * const group_GTK,
       
  4879 	u32_t * const eapol_data_length)
       
  4880 {
       
  4881 	// Add GTK to Key Data.
       
  4882 
       
  4883 	if (eapol_key_message == 0
       
  4884 		|| eapol_key_message->get_is_valid() == false
       
  4885 		|| group_GTK == 0
       
  4886 		|| group_GTK->get_is_valid_data() == false
       
  4887 		|| eapol_data_length == 0)
       
  4888 	{
       
  4889 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4890 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  4891 	}
       
  4892 
       
  4893 	u32_t GTK_length = group_GTK->get_data_length();
       
  4894 
       
  4895 	u32_t gtk_data_length =
       
  4896 		eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_ID_AND_GROUP_KEY_HEADER_SIZE
       
  4897 		+ GTK_length;
       
  4898 
       
  4899 	u32_t key_data_buffer_length =
       
  4900 		eapol_rsna_key_data_header_c::EAPOL_RSNA_KEY_HEADER_LENGTH
       
  4901 		+ gtk_data_length;
       
  4902 
       
  4903 	eapol_rsna_key_data_header_c key_data_header(
       
  4904 		m_am_tools,
       
  4905 		get_is_RSNA(),
       
  4906 		get_is_WPXM(),
       
  4907 		eapol_key_message->get_key_data_offset(*eapol_data_length, key_data_buffer_length),
       
  4908 		key_data_buffer_length);
       
  4909 	if (key_data_header.get_is_valid() == false)
       
  4910 	{
       
  4911 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4912 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4913 	}
       
  4914 
       
  4915 	eap_status_e status = key_data_header.reset_header();
       
  4916 	if (status != eap_status_ok)
       
  4917 	{
       
  4918 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4919 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4920 	}
       
  4921 
       
  4922 	{
       
  4923 		// Here Type and Length fields are NOT included.
       
  4924 		u32_t key_data_length =
       
  4925 			key_data_buffer_length
       
  4926 			- 2ul;
       
  4927 
       
  4928 		if (key_data_length > 0xff)
       
  4929 		{
       
  4930 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4931 			return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
       
  4932 		}
       
  4933 
       
  4934 		status = key_data_header.set_length(
       
  4935 			static_cast<u8_t>(key_data_length));
       
  4936 		if (status != eap_status_ok)
       
  4937 		{
       
  4938 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4939 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4940 		}
       
  4941 	}
       
  4942 
       
  4943 	status = key_data_header.set_payload_type(eapol_RSNA_key_payload_type_group_key_and_id);
       
  4944 	if (status != eap_status_ok)
       
  4945 	{
       
  4946 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4947 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  4948 	}
       
  4949 
       
  4950 	EAP_TRACE_DATA_DEBUG(
       
  4951 		m_am_tools,
       
  4952 		TRACE_FLAGS_DEFAULT,
       
  4953 		(EAPL("RSN Group Key"),
       
  4954 		 group_GTK->get_data(GTK_length),
       
  4955 		GTK_length));
       
  4956 
       
  4957 	if (gtk_data_length == GTK_length + eapol_rsna_key_data_gtk_header_c::get_header_length())
       
  4958 	{
       
  4959 		// Add authenticator GTK to Key Data.
       
  4960 		eapol_rsna_key_data_gtk_header_c gtk_header(
       
  4961 			m_am_tools,
       
  4962 			key_data_header.get_key_data_payload(gtk_data_length),
       
  4963 			gtk_data_length);
       
  4964 		if (gtk_header.get_is_valid() == false)
       
  4965 		{
       
  4966 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4967 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4968 		}
       
  4969 
       
  4970 		status = gtk_header.reset_header();
       
  4971 		if (status != eap_status_ok)
       
  4972 		{
       
  4973 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4974 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4975 		}
       
  4976 
       
  4977 		m_group_GTK_ID = 1ul;
       
  4978 		status = gtk_header.set_key_index(m_group_GTK_ID);
       
  4979 		if (status != eap_status_ok)
       
  4980 		{
       
  4981 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4982 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  4983 		}
       
  4984 
       
  4985 		m_group_GTK_Tx_bit = true;
       
  4986 		status = gtk_header.set_tx(m_group_GTK_Tx_bit);
       
  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 		u8_t * data_field_of_GTK
       
  4994 			= gtk_header.get_gtk(GTK_length);
       
  4995 		if (data_field_of_GTK == 0)
       
  4996 		{
       
  4997 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  4998 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  4999 		}
       
  5000 
       
  5001 		m_am_tools->memmove(
       
  5002 			data_field_of_GTK,
       
  5003 			group_GTK->get_data(GTK_length),
       
  5004 			GTK_length);
       
  5005 
       
  5006 		EAP_TRACE_DEBUG(
       
  5007 			m_am_tools,
       
  5008 			TRACE_FLAGS_DEFAULT,
       
  5009 			(EAPL("send RSN Group Key ID %d, Tx %d\n"),
       
  5010 			 gtk_header.get_key_index(),
       
  5011 			 gtk_header.get_tx_bit()));
       
  5012 
       
  5013 		EAP_TRACE_DATA_DEBUG(
       
  5014 			m_am_tools,
       
  5015 			TRACE_FLAGS_DEFAULT,
       
  5016 			(EAPL("send RSN Group Key payload"),
       
  5017 			 gtk_header.get_header_buffer(gtk_header.get_header_buffer_length()),
       
  5018 			 gtk_header.get_header_buffer_length()));
       
  5019 	}
       
  5020 	else
       
  5021 	{
       
  5022 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5023 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5024 	}
       
  5025 
       
  5026 	*eapol_data_length += key_data_buffer_length;
       
  5027 
       
  5028 	EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(
       
  5029 		get_is_RSNA(),
       
  5030 		get_is_WPXM(),
       
  5031 		eapol_key_message->get_key_descriptor_type(),
       
  5032 		"Added EAPOL Key Data key_data_payload",
       
  5033 		&key_data_header,
       
  5034 		*eapol_data_length);
       
  5035 
       
  5036 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5037 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5038 }
       
  5039 
       
  5040 //--------------------------------------------------
       
  5041 
       
  5042 //
       
  5043 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::add_RSN_IE_payload(
       
  5044 	const eapol_RSNA_key_header_c * const eapol_key_message,
       
  5045 	eap_variable_data_c * const RSNA_IE,
       
  5046 	u32_t * const eapol_data_length)
       
  5047 {
       
  5048 	// Add RSN IE to Key Data.
       
  5049 
       
  5050 	if (eapol_key_message == 0
       
  5051 		|| eapol_key_message->get_is_valid() == false
       
  5052 		|| RSNA_IE == 0
       
  5053 		|| RSNA_IE->get_is_valid_data() == false
       
  5054 		|| eapol_data_length == 0)
       
  5055 	{
       
  5056 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5057 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  5058 	}
       
  5059 
       
  5060 	u32_t rsn_ie_data_length(RSNA_IE->get_data_length());
       
  5061 
       
  5062 	u8_t * const data_field_of_RSN_IE
       
  5063 		= reinterpret_cast<u8_t *>(
       
  5064 			eapol_key_message->get_key_data_offset(*eapol_data_length, rsn_ie_data_length));
       
  5065 	if (data_field_of_RSN_IE == 0)
       
  5066 	{
       
  5067 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5068 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5069 	}
       
  5070 
       
  5071 	m_am_tools->memmove(
       
  5072 		data_field_of_RSN_IE,
       
  5073 		RSNA_IE->get_data(rsn_ie_data_length),
       
  5074 		rsn_ie_data_length);
       
  5075 
       
  5076 	// NOTE, only two first bytes of RSN IE match with EAPOL Key Data.
       
  5077 	eapol_rsna_key_data_header_c key_data_header(
       
  5078 		m_am_tools,
       
  5079 		get_is_RSNA(),
       
  5080 		get_is_WPXM(),
       
  5081 		data_field_of_RSN_IE,
       
  5082 		rsn_ie_data_length);
       
  5083 	if (key_data_header.get_is_valid() == false)
       
  5084 	{
       
  5085 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5086 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5087 	}
       
  5088 
       
  5089 	*eapol_data_length += rsn_ie_data_length;
       
  5090 
       
  5091 	EAPOL_RSNA_KEY_DATA_TRACE_PAYLOAD(
       
  5092 		get_is_RSNA(),
       
  5093 		get_is_WPXM(),
       
  5094 		eapol_key_message->get_key_descriptor_type(),
       
  5095 		"Added EAPOL RSN IE",
       
  5096 		&key_data_header,
       
  5097 		*eapol_data_length);
       
  5098 
       
  5099 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5100 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5101 }
       
  5102 
       
  5103 //--------------------------------------------------
       
  5104 
       
  5105 // 
       
  5106 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::process_eapol_key_frame(
       
  5107 	const eap_am_network_id_c * const receive_network_id,
       
  5108 	eap_general_header_base_c * const packet_data,
       
  5109 	const u32_t packet_length)
       
  5110 {
       
  5111 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5112 
       
  5113 	eap_status_e status = eap_status_not_supported;
       
  5114 
       
  5115 	if (packet_length < eapol_header_wr_c::get_header_length()
       
  5116 		|| packet_data->get_header_buffer_length() < eapol_header_wr_c::get_header_length()
       
  5117 		|| packet_data->get_header_buffer_length() < packet_length)
       
  5118 	{
       
  5119 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5120 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  5121 	}
       
  5122 
       
  5123 	if (m_pairwise_PMK_WPXK3.get_is_valid_data() == false)
       
  5124 	{
       
  5125 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, 
       
  5126 				(EAPL("EAPOL_KEY: eapol_key_state_c: process_eapol_key_frame(): m_pairwise_PMK_WPXK3 is not valid.\n")));
       
  5127 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5128 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
       
  5129 	}
       
  5130 
       
  5131 	eapol_header_wr_c eapol_header(
       
  5132 		m_am_tools,
       
  5133 		packet_data->get_header_buffer(packet_data->get_header_buffer_length()),
       
  5134 		packet_data->get_header_buffer_length());
       
  5135 	if (eapol_header.get_is_valid() == false)
       
  5136 	{
       
  5137 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5138 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  5139 	}
       
  5140 	else if (eapol_header.check_header() != eap_status_ok)
       
  5141 	{
       
  5142 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5143 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5144 	}
       
  5145 
       
  5146 	// Data length must be at least size of Descriptor Type.
       
  5147 	const u32_t EAPOL_DESCRIPTOR_TYPE_LENGTH = sizeof(u8_t);
       
  5148 	if (eapol_header.get_data_length() < EAPOL_DESCRIPTOR_TYPE_LENGTH)
       
  5149 	{
       
  5150 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5151 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5152 	}
       
  5153 
       
  5154 	const u8_t * const descriptor_type = eapol_header.get_data(EAPOL_DESCRIPTOR_TYPE_LENGTH);
       
  5155 	if (descriptor_type == 0)
       
  5156 	{
       
  5157 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5158 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  5159 	}
       
  5160 
       
  5161 	switch(static_cast<eapol_key_descriptor_type_e>(*descriptor_type))
       
  5162 	{
       
  5163 	case eapol_key_descriptor_type_RC4:
       
  5164 		status = process_RC4_key_descriptor(receive_network_id, packet_data, packet_length);
       
  5165 		break;
       
  5166 	case eapol_key_descriptor_type_RSNA:
       
  5167 	case eapol_key_descriptor_type_WPA:
       
  5168 		status = process_RSNA_key_descriptor(receive_network_id, packet_data, packet_length);
       
  5169 		break;
       
  5170 	default:
       
  5171 		status = eap_status_not_supported;
       
  5172 		break;
       
  5173 	}
       
  5174 
       
  5175 	if (status == eap_status_ok)
       
  5176 	{
       
  5177 		EAP_GENERAL_HEADER_SET_ERROR_DETECTED(packet_data, false);
       
  5178 	}
       
  5179 
       
  5180 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5181 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5182 }
       
  5183 
       
  5184 //--------------------------------------------------
       
  5185 
       
  5186 //
       
  5187 EAP_FUNC_EXPORT void eapol_key_state_c::set_is_valid()
       
  5188 {
       
  5189 	m_is_valid = true;
       
  5190 }
       
  5191 
       
  5192 //--------------------------------------------------
       
  5193 
       
  5194 //
       
  5195 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_valid()
       
  5196 {
       
  5197 	return m_is_valid;
       
  5198 }
       
  5199 
       
  5200 //--------------------------------------------------
       
  5201 
       
  5202 EAP_FUNC_EXPORT void eapol_key_state_c::object_increase_reference_count()
       
  5203 {
       
  5204 	// Do nothing.
       
  5205 }
       
  5206 
       
  5207 //--------------------------------------------------
       
  5208 
       
  5209 EAP_FUNC_EXPORT u32_t eapol_key_state_c::object_decrease_reference_count()
       
  5210 {
       
  5211 	// Do nothing.
       
  5212 	return 0ul;
       
  5213 }
       
  5214 
       
  5215 
       
  5216 //--------------------------------------------------
       
  5217 
       
  5218 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_encryption_on()
       
  5219 {
       
  5220 	/**
       
  5221 	 * @{ Add functionality of get_is_encryption_on() function }
       
  5222 	 */
       
  5223 	return false;
       
  5224 }
       
  5225 
       
  5226 //--------------------------------------------------
       
  5227 
       
  5228 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  5229 
       
  5230 EAP_FUNC_EXPORT bool eapol_key_state_c::get_is_associated()
       
  5231 {
       
  5232 	EAP_TRACE_DEBUG(
       
  5233 		m_am_tools, 
       
  5234 		TRACE_FLAGS_DEFAULT, 
       
  5235 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::get_is_associated(): m_is_associated=%s.\n"),
       
  5236 		 (m_is_client == true) ? "client": "server",
       
  5237 		 (m_is_associated == true) ? "true": "false"));
       
  5238 
       
  5239 	return m_is_associated;
       
  5240 }
       
  5241 
       
  5242 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  5243 
       
  5244 //--------------------------------------------------
       
  5245 
       
  5246 EAP_FUNC_EXPORT void eapol_key_state_c::set_eapol_key_state(const eapol_key_state_e state)
       
  5247 {
       
  5248 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5249 
       
  5250 	eapol_key_state_string_c state_string;
       
  5251 
       
  5252 	EAP_TRACE_DEBUG(
       
  5253 		m_am_tools,
       
  5254 		TRACE_FLAGS_DEFAULT,
       
  5255 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::set_eapol_key_state(): set_eapol_key_state() from %s to %s\n"),
       
  5256 		(m_is_client == true ? "client": "server"),
       
  5257 		state_string.get_eapol_key_state_string(m_eapol_key_state),
       
  5258 		state_string.get_eapol_key_state_string(state)));
       
  5259 
       
  5260 	m_eapol_key_state = state;
       
  5261 
       
  5262 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5263 }
       
  5264 
       
  5265 //--------------------------------------------------
       
  5266 
       
  5267 EAP_FUNC_EXPORT eapol_key_state_e eapol_key_state_c::get_eapol_key_state() const
       
  5268 {
       
  5269 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5270 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5271 	return m_eapol_key_state;
       
  5272 }
       
  5273 
       
  5274 //--------------------------------------------------
       
  5275 
       
  5276 //
       
  5277 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::packet_send(
       
  5278 	const eap_am_network_id_c * const send_network_id,
       
  5279 	eap_buf_chain_wr_c * const sent_packet,
       
  5280 	const u32_t header_offset,
       
  5281 	const u32_t data_length,
       
  5282 	const u32_t buffer_length)
       
  5283 {
       
  5284 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5285 
       
  5286 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5287 
       
  5288 	cancel_retransmission();
       
  5289 
       
  5290 	if (m_is_client == false
       
  5291 		&& sent_packet->get_do_packet_retransmission() == true)
       
  5292 	{
       
  5293 		// Only EAPOL-server initializes re-transmission.
       
  5294 		// EAPOL-server will re-transmit the packet when timer elapses and no response is received.
       
  5295 		init_retransmission(
       
  5296 			send_network_id,
       
  5297 			sent_packet,
       
  5298 			header_offset,
       
  5299 			data_length,
       
  5300 			eap_code_none,
       
  5301 			0ul,
       
  5302 			eap_type_none);
       
  5303 	}
       
  5304 
       
  5305 
       
  5306 	// NOTE: send packet directly to partner object of eapol_core_c object.
       
  5307 	eap_status_e status = m_eapol_partner->packet_send(
       
  5308 		send_network_id,
       
  5309 		sent_packet,
       
  5310 		header_offset,
       
  5311 		data_length,
       
  5312 		buffer_length);
       
  5313 
       
  5314 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5315 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5316 }
       
  5317 
       
  5318 //--------------------------------------------------
       
  5319 
       
  5320 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::resend_packet(
       
  5321 	const eap_am_network_id_c * const send_network_id,
       
  5322 	eap_buf_chain_wr_c * const sent_packet,
       
  5323 	const u32_t header_offset,
       
  5324 	const u32_t data_length,
       
  5325 	const u32_t buffer_length)
       
  5326 {
       
  5327 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5328 	EAP_TRACE_DEBUG(
       
  5329 		m_am_tools, 
       
  5330 		TRACE_FLAGS_DEFAULT, 
       
  5331 		(EAPL("<- EAPOL_KEY: %s: eapol_key_state_c::resend_packet().\n"),
       
  5332 		 (m_is_client == true) ? "client": "server"));
       
  5333 
       
  5334 	// We make a copy because random error test may corrupt the data.
       
  5335 	eap_buf_chain_wr_c * const copy_packet = sent_packet->copy();
       
  5336 
       
  5337 	if (copy_packet == 0)
       
  5338 	{
       
  5339 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5340 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5341 	}
       
  5342 
       
  5343 	EAP_ASSERT(m_eapol_header_offset < sent_packet->get_data_length());
       
  5344 	EAP_ASSERT(data_length <= sent_packet->get_data_length());
       
  5345 	EAP_ASSERT(sent_packet->get_data_length() <= buffer_length);
       
  5346 
       
  5347 	// NOTE: send packet directly to partner object of eapol_core_c object.
       
  5348 	// This will skip initialization of re-transmission for re-transmitted packet.
       
  5349 	eap_status_e status = m_eapol_partner->packet_send(
       
  5350 		send_network_id, 
       
  5351 		copy_packet, 
       
  5352 		header_offset, 
       
  5353 		data_length,
       
  5354 		buffer_length
       
  5355 		);
       
  5356 
       
  5357 	delete copy_packet;
       
  5358 
       
  5359 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5360 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5361 }
       
  5362 
       
  5363 //--------------------------------------------------
       
  5364 
       
  5365 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_handshake_timeout()
       
  5366 {
       
  5367 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5368 
       
  5369 	m_handshake_timeout_set = false;
       
  5370 
       
  5371 	EAP_TRACE_DEBUG(
       
  5372 		m_am_tools, 
       
  5373 		TRACE_FLAGS_DEFAULT, 
       
  5374 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_handshake_timeout(): this = 0x%08x.\n"),
       
  5375 		 (m_is_client == true) ? "client": "server",
       
  5376 		 this));
       
  5377 
       
  5378 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5379 
       
  5380 	m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID);
       
  5381 
       
  5382 	EAP_TRACE_DEBUG(
       
  5383 		m_am_tools,
       
  5384 		TRACE_FLAGS_DEFAULT,
       
  5385 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID cancelled.\n"),
       
  5386 		 (m_is_client == true ? "client": "server")));
       
  5387 
       
  5388 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5389 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5390 }
       
  5391 
       
  5392 //--------------------------------------------------
       
  5393 
       
  5394 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_handshake_timeout(
       
  5395 	const u32_t timeout)
       
  5396 {
       
  5397 	eapol_key_state_string_c state_string;
       
  5398 	EAP_TRACE_DEBUG(
       
  5399 		m_am_tools, 
       
  5400 		TRACE_FLAGS_DEFAULT, 
       
  5401 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_handshake_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5402 		 (m_is_client == true) ? "client": "server",
       
  5403 		 this,
       
  5404 		 get_eapol_key_state(),
       
  5405 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5406 		 m_authentication_type,
       
  5407 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5408 
       
  5409 	if (m_handshake_timeout_set == true)
       
  5410 	{
       
  5411 		EAP_TRACE_DEBUG(
       
  5412 			m_am_tools, 
       
  5413 			TRACE_FLAGS_DEFAULT, 
       
  5414 			(EAPL("WARNING: EAPOL_KEY: eapol_key_state_c::init_handshake_timeout(): Already active.\n")));
       
  5415 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5416 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5417 	}
       
  5418 
       
  5419 	m_handshake_timeout_set = true;
       
  5420 
       
  5421 	eap_status_e status = m_key_state_partner->set_timer(
       
  5422 		this,
       
  5423 		EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID, 
       
  5424 		0,
       
  5425 		timeout);
       
  5426 	if (status != eap_status_ok)
       
  5427 	{
       
  5428 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5429 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5430 	}
       
  5431 
       
  5432 	EAP_TRACE_DEBUG(
       
  5433 		m_am_tools,
       
  5434 		TRACE_FLAGS_DEFAULT,
       
  5435 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_HANDSHAKE_TIMEOUT_ID set %d ms.\n"),
       
  5436 		 (m_is_client == true ? "client": "server"),
       
  5437 		 timeout));
       
  5438 
       
  5439 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5440 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5441 }
       
  5442 
       
  5443 //--------------------------------------------------
       
  5444 
       
  5445 eap_status_e eapol_key_state_c::cancel_reassociate_timeout()
       
  5446 {
       
  5447 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5448 
       
  5449 	EAP_TRACE_DEBUG(
       
  5450 		m_am_tools, 
       
  5451 		TRACE_FLAGS_DEFAULT, 
       
  5452 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_reassociate_timeout(): this = 0x%08x.\n"),
       
  5453 		 (m_is_client == true) ? "client": "server",
       
  5454 		 this));
       
  5455 
       
  5456 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5457 
       
  5458 	m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID);
       
  5459 
       
  5460 	EAP_TRACE_DEBUG(
       
  5461 		m_am_tools,
       
  5462 		TRACE_FLAGS_DEFAULT,
       
  5463 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID cancelled.\n"),
       
  5464 		 (m_is_client == true ? "client": "server")));
       
  5465 
       
  5466 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5467 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5468 }
       
  5469 
       
  5470 //--------------------------------------------------
       
  5471 
       
  5472 eap_status_e eapol_key_state_c::init_reassociate_timeout(
       
  5473 	const u32_t timeout)
       
  5474 {
       
  5475 	eapol_key_state_string_c state_string;
       
  5476 	EAP_TRACE_DEBUG(
       
  5477 		m_am_tools, 
       
  5478 		TRACE_FLAGS_DEFAULT, 
       
  5479 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_reassociate_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5480 		 (m_is_client == true) ? "client": "server",
       
  5481 		 this,
       
  5482 		 get_eapol_key_state(),
       
  5483 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5484 		 m_authentication_type,
       
  5485 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5486 
       
  5487 	eap_status_e status = m_key_state_partner->set_timer(
       
  5488 		this,
       
  5489 		EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID, 
       
  5490 		0,
       
  5491 		timeout);
       
  5492 	if (status != eap_status_ok)
       
  5493 	{
       
  5494 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5495 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5496 	}
       
  5497 
       
  5498 	EAP_TRACE_DEBUG(
       
  5499 		m_am_tools,
       
  5500 		TRACE_FLAGS_DEFAULT,
       
  5501 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_REASSOCIATE_TIMEOUT_ID set %d ms.\n"),
       
  5502 		 (m_is_client == true ? "client": "server"),
       
  5503 		 timeout));
       
  5504 
       
  5505 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5506 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5507 }
       
  5508 
       
  5509 //--------------------------------------------------
       
  5510 
       
  5511 eap_status_e eapol_key_state_c::cancel_4_way_handshake_start_timeout()
       
  5512 {
       
  5513 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5514 
       
  5515 	EAP_TRACE_DEBUG(
       
  5516 		m_am_tools, 
       
  5517 		TRACE_FLAGS_DEFAULT, 
       
  5518 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_4_way_handshake_start_timeout(): this = 0x%08x.\n"),
       
  5519 		 (m_is_client == true) ? "client": "server",
       
  5520 		 this));
       
  5521 
       
  5522 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5523 
       
  5524 	m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID);
       
  5525 
       
  5526 	EAP_TRACE_DEBUG(
       
  5527 		m_am_tools,
       
  5528 		TRACE_FLAGS_DEFAULT,
       
  5529 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID cancelled.\n"),
       
  5530 		 (m_is_client == true ? "client": "server")));
       
  5531 
       
  5532 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5533 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5534 }
       
  5535 
       
  5536 //--------------------------------------------------
       
  5537 
       
  5538 eap_status_e eapol_key_state_c::init_4_way_handshake_start_timeout()
       
  5539 {
       
  5540 	eapol_key_state_string_c state_string;
       
  5541 	EAP_TRACE_DEBUG(
       
  5542 		m_am_tools, 
       
  5543 		TRACE_FLAGS_DEFAULT, 
       
  5544 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_4_way_handshake_start_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5545 		 (m_is_client == true) ? "client": "server",
       
  5546 		 this,
       
  5547 		 get_eapol_key_state(),
       
  5548 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5549 		 m_authentication_type,
       
  5550 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5551 
       
  5552 	eap_status_e status = m_key_state_partner->set_timer(
       
  5553 		this,
       
  5554 		EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID, 
       
  5555 		0,
       
  5556 		EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT);
       
  5557 	if (status != eap_status_ok)
       
  5558 	{
       
  5559 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5560 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5561 	}
       
  5562 
       
  5563 	EAP_TRACE_DEBUG(
       
  5564 		m_am_tools,
       
  5565 		TRACE_FLAGS_DEFAULT,
       
  5566 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT_ID set %d ms.\n"),
       
  5567 		 (m_is_client == true ? "client": "server"),
       
  5568 		 EAPOL_KEY_STATE_TIMER_INITIALIZE_4_WAY_HANDSHAKE_TIMEOUT));
       
  5569 
       
  5570 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5571 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5572 }
       
  5573 
       
  5574 //--------------------------------------------------
       
  5575 
       
  5576 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_pmksa_caching_timeout()
       
  5577 {
       
  5578 	EAP_TRACE_DEBUG(
       
  5579 		m_am_tools, 
       
  5580 		TRACE_FLAGS_DEFAULT, 
       
  5581 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_pmksa_caching_timeout(): this = 0x%08x.\n"),
       
  5582 		 (m_is_client == true) ? "client": "server",
       
  5583 		 this));
       
  5584 
       
  5585 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5586 
       
  5587 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5588 
       
  5589 	m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID);
       
  5590 
       
  5591 	EAP_TRACE_DEBUG(
       
  5592 		m_am_tools,
       
  5593 		TRACE_FLAGS_DEFAULT,
       
  5594 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID cancelled.\n"),
       
  5595 		 (m_is_client == true ? "client": "server")));
       
  5596 
       
  5597 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5598 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5599 }
       
  5600 
       
  5601 //--------------------------------------------------
       
  5602 
       
  5603 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_authentication_session()
       
  5604 {
       
  5605 	eapol_key_state_string_c state_string;
       
  5606 	EAP_TRACE_DEBUG(
       
  5607 		m_am_tools, 
       
  5608 		TRACE_FLAGS_DEFAULT, 
       
  5609 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_authentication_session(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5610 		 (m_is_client == true) ? "client": "server",
       
  5611 		 this,
       
  5612 		 get_eapol_key_state(),
       
  5613 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5614 		 m_authentication_type,
       
  5615 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5616 
       
  5617 	eap_status_e status(eap_status_process_general_error);
       
  5618 
       
  5619 	// RSNA could cache the current PMKSA.
       
  5620 	status = init_pmksa_caching_timeout();
       
  5621 
       
  5622 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5623 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5624 }
       
  5625 
       
  5626 //--------------------------------------------------
       
  5627 
       
  5628 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_pmksa_caching_timeout()
       
  5629 {
       
  5630 	eapol_key_state_string_c state_string;
       
  5631 	EAP_TRACE_DEBUG(
       
  5632 		m_am_tools, 
       
  5633 		TRACE_FLAGS_DEFAULT, 
       
  5634 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_pmksa_caching_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5635 		 (m_is_client == true) ? "client": "server",
       
  5636 		 this,
       
  5637 		 get_eapol_key_state(),
       
  5638 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5639 		 m_authentication_type,
       
  5640 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5641 
       
  5642 	eap_status_e status(eap_status_process_general_error);
       
  5643 
       
  5644 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  5645 	{
       
  5646 		m_is_associated = false;
       
  5647 
       
  5648 		EAP_TRACE_DEBUG(
       
  5649 			m_am_tools, 
       
  5650 			TRACE_FLAGS_DEFAULT, 
       
  5651 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_pmksa_caching_timeout(): m_is_associated=%s.\n"),
       
  5652 			 (m_is_client == true) ? "client": "server",
       
  5653 			 (m_is_associated == true) ? "true": "false"));
       
  5654 	}
       
  5655 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  5656 
       
  5657 	if ((m_authentication_type == eapol_key_authentication_type_RSNA_EAP
       
  5658 #if defined(EAP_USE_WPXM)
       
  5659 			|| get_is_WPXM() == true
       
  5660 #endif //#if defined(EAP_USE_WPXM)
       
  5661 			)
       
  5662 		&& (get_eapol_key_state() == eapol_key_state_4_way_handshake_successfull
       
  5663 			|| get_eapol_key_state() == eapol_key_state_group_key_handshake_successfull
       
  5664 			|| get_eapol_key_state() == eapol_key_state_preauthenticated
       
  5665 #if defined(EAP_USE_WPXM)
       
  5666 			|| get_eapol_key_state() == eapol_key_state_wpxm_reassociation_finished_successfull
       
  5667 #endif //#if defined(EAP_USE_WPXM)
       
  5668 			))
       
  5669 	{
       
  5670 		set_eapol_key_state(eapol_key_state_preauthenticated);
       
  5671 		reset_cached_pmksa();
       
  5672 
       
  5673 		u32_t timeout(m_pmksa_caching_timeout);
       
  5674 
       
  5675 #if defined(EAP_USE_WPXM)
       
  5676 		if (get_is_WPXM() == true)
       
  5677 		{
       
  5678 			timeout = EAPOL_KEY_STATE_TIMER_WPXM_CACHE_TIMEOUT;
       
  5679 		}
       
  5680 #endif //#if defined(EAP_USE_WPXM)
       
  5681 
       
  5682 		status = m_key_state_partner->set_timer(
       
  5683 			this,
       
  5684 			EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID, 
       
  5685 			0,
       
  5686 			timeout);
       
  5687 		if (status != eap_status_ok)
       
  5688 		{
       
  5689 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5690 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5691 		}
       
  5692 
       
  5693 		EAP_TRACE_DEBUG(
       
  5694 			m_am_tools,
       
  5695 			TRACE_FLAGS_DEFAULT,
       
  5696 			(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_PMKSA_CACHING_TIMEOUT_ID set %d ms.\n"),
       
  5697 			 (m_is_client == true ? "client": "server"),
       
  5698 			 m_pmksa_caching_timeout));
       
  5699 
       
  5700 		set_eapol_key_state(eapol_key_state_preauthenticated);
       
  5701 	}
       
  5702 	else
       
  5703 	{
       
  5704 		EAP_TRACE_DEBUG(
       
  5705 			m_am_tools,
       
  5706 			TRACE_FLAGS_DEFAULT,
       
  5707 			(EAPL("%s: Removes PMKSA cache\n"),
       
  5708 			 (m_is_client == true ? "client": "server")));
       
  5709 
       
  5710 		// Other authentication modes do not use PMKSA cache, clean-up state.
       
  5711 		reset();
       
  5712 
       
  5713 		// Timeout value zero will remove state immediately.
       
  5714 		status = init_handshake_timeout(0ul);
       
  5715 		if (status != eap_status_ok)
       
  5716 		{
       
  5717 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5718 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5719 		}
       
  5720 	}
       
  5721 
       
  5722 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5723 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5724 }
       
  5725 
       
  5726 //--------------------------------------------------
       
  5727 
       
  5728 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_retransmission()
       
  5729 {
       
  5730 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5731 
       
  5732 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5733 
       
  5734 	if (m_is_client == false)
       
  5735 	{
       
  5736 		// Only EAP-server uses timer to re-transmits EAP-packets.
       
  5737 		m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID);
       
  5738 	}
       
  5739 
       
  5740 	if (m_retransmission != 0)
       
  5741 	{
       
  5742 		EAP_TRACE_DEBUG(
       
  5743 			m_am_tools, 
       
  5744 			TRACE_FLAGS_DEFAULT, 
       
  5745 			(EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID cancelled.\n")));
       
  5746 
       
  5747 		if (m_retransmission != 0)
       
  5748 		{
       
  5749 			delete m_retransmission;
       
  5750 			m_retransmission = 0;
       
  5751 		}
       
  5752 	}
       
  5753 
       
  5754 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5755 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5756 }
       
  5757 
       
  5758 //--------------------------------------------------
       
  5759 
       
  5760 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_retransmission(
       
  5761 	const eap_am_network_id_c * const send_network_id,
       
  5762 	eap_buf_chain_wr_c * const sent_packet,
       
  5763 	const u32_t header_offset,
       
  5764 	const u32_t data_length,
       
  5765 	const eap_code_value_e eap_code,
       
  5766 	const u8_t eap_identifier,
       
  5767 	const eap_type_value_e eap_type
       
  5768 	)
       
  5769 {
       
  5770 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5771 
       
  5772 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5773 
       
  5774 	if (m_retransmission_time == 0u
       
  5775 		|| m_retransmission_counter == 0u)
       
  5776 	{
       
  5777 		// No retransmission.
       
  5778 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5779 	}
       
  5780 
       
  5781 	EAP_ASSERT(send_network_id->get_source() != 0);
       
  5782 	EAP_ASSERT(send_network_id->get_destination() != 0);
       
  5783 
       
  5784 	if (m_is_client == false)
       
  5785 	{
       
  5786 		// Only EAP-server uses timer to re-transmits EAP-packets.
       
  5787 		m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID);
       
  5788 	}
       
  5789 
       
  5790 	if (m_retransmission != 0)
       
  5791 	{
       
  5792 		delete m_retransmission;
       
  5793 		m_retransmission = 0;
       
  5794 	}
       
  5795 
       
  5796 	m_retransmission = new eap_core_retransmission_c(
       
  5797 		m_am_tools, 
       
  5798 		send_network_id, 
       
  5799 		sent_packet, 
       
  5800 		header_offset, 
       
  5801 		data_length, 
       
  5802 		m_retransmission_time, 
       
  5803 		m_retransmission_counter,
       
  5804 		eap_code,
       
  5805 		eap_identifier,
       
  5806 		eap_type
       
  5807 		);
       
  5808 
       
  5809 	if (m_retransmission == 0)
       
  5810 	{
       
  5811 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5812 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5813 	}
       
  5814 
       
  5815 	if (m_retransmission->get_is_valid() == true)
       
  5816 	{
       
  5817 		// Because this object do re-transmission other layers must not do re-transmission of this packet.
       
  5818 		sent_packet->set_do_packet_retransmission(false);
       
  5819 
       
  5820 		if (m_is_client == false)
       
  5821 		{
       
  5822 			// Only EAP-server uses timer to re-transmits EAP-packets.
       
  5823 			u32_t next_retransmission_time(m_retransmission->get_next_retransmission_time());
       
  5824 
       
  5825 			eap_status_e status = m_key_state_partner->set_timer(this, EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID, 0,
       
  5826 				next_retransmission_time);
       
  5827 			if (status != eap_status_ok)
       
  5828 			{
       
  5829 				delete m_retransmission;
       
  5830 				m_retransmission = 0;
       
  5831 			}
       
  5832 
       
  5833 			EAP_TRACE_DEBUG(
       
  5834 				m_am_tools, 
       
  5835 				TRACE_FLAGS_DEFAULT, 
       
  5836 				(EAPL("TIMER: EAPOL_KEY: EAPOL_KEY_STATE_TIMER_RETRANSMISSION_ID set %d ms.\n"),
       
  5837 				next_retransmission_time));
       
  5838 
       
  5839 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5840 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  5841 		}
       
  5842 		else
       
  5843 		{
       
  5844 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5845 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5846 		}
       
  5847 	}
       
  5848 	else
       
  5849 	{
       
  5850 		delete m_retransmission;
       
  5851 		m_retransmission = 0;
       
  5852 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5853 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  5854 	}
       
  5855 
       
  5856 }
       
  5857 
       
  5858 //--------------------------------------------------
       
  5859 
       
  5860 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::cancel_group_key_update_timeout()
       
  5861 {
       
  5862 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5863 
       
  5864 	EAP_TRACE_DEBUG(
       
  5865 		m_am_tools, 
       
  5866 		TRACE_FLAGS_DEFAULT, 
       
  5867 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::cancel_group_key_update_timeout(): this = 0x%08x.\n"),
       
  5868 		 (m_is_client == true) ? "client": "server",
       
  5869 		 this));
       
  5870 
       
  5871 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
       
  5872 
       
  5873 	m_key_state_partner->cancel_timer(this, EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID);
       
  5874 
       
  5875 	EAP_TRACE_DEBUG(
       
  5876 		m_am_tools,
       
  5877 		TRACE_FLAGS_DEFAULT,
       
  5878 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID cancelled.\n"),
       
  5879 		 (m_is_client == true ? "client": "server")));
       
  5880 
       
  5881 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5882 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  5883 }
       
  5884 
       
  5885 //--------------------------------------------------
       
  5886 
       
  5887 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::init_group_key_update_timeout(
       
  5888 	const u32_t timeout)
       
  5889 {
       
  5890 	eapol_key_state_string_c state_string;
       
  5891 	EAP_TRACE_DEBUG(
       
  5892 		m_am_tools, 
       
  5893 		TRACE_FLAGS_DEFAULT, 
       
  5894 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::init_group_key_update_timeout(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5895 		 (m_is_client == true) ? "client": "server",
       
  5896 		 this,
       
  5897 		 get_eapol_key_state(),
       
  5898 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5899 		 m_authentication_type,
       
  5900 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5901 
       
  5902 	eap_status_e status = m_key_state_partner->set_timer(
       
  5903 		this,
       
  5904 		EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID, 
       
  5905 		0,
       
  5906 		timeout);
       
  5907 	if (status != eap_status_ok)
       
  5908 	{
       
  5909 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5910 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  5911 	}
       
  5912 
       
  5913 	EAP_TRACE_DEBUG(
       
  5914 		m_am_tools,
       
  5915 		TRACE_FLAGS_DEFAULT,
       
  5916 		(EAPL("TIMER: EAPOL_KEY: %s: EAPOL_KEY_STATE_TIMER_GROUP_KEY_UPDATE_TIMEOUT_ID set %d ms.\n"),
       
  5917 		 (m_is_client == true ? "client": "server"),
       
  5918 		 timeout));
       
  5919 
       
  5920 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5921 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  5922 }
       
  5923 
       
  5924 //--------------------------------------------------
       
  5925 
       
  5926 //
       
  5927 EAP_FUNC_EXPORT bool eapol_key_state_c::get_marked_removed()
       
  5928 {
       
  5929 	return m_marked_removed;
       
  5930 }
       
  5931 
       
  5932 //--------------------------------------------------
       
  5933 
       
  5934 //
       
  5935 EAP_FUNC_EXPORT void eapol_key_state_c::set_marked_removed()
       
  5936 {
       
  5937 	m_marked_removed = true;
       
  5938 }
       
  5939 
       
  5940 //--------------------------------------------------
       
  5941 
       
  5942 //
       
  5943 EAP_FUNC_EXPORT void eapol_key_state_c::unset_marked_removed()
       
  5944 {
       
  5945 	m_marked_removed = false;
       
  5946 }
       
  5947 
       
  5948 //--------------------------------------------------
       
  5949 
       
  5950 //
       
  5951 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::reset_cached_pmksa()
       
  5952 {
       
  5953 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  5954 
       
  5955 	eapol_key_state_string_c state_string;
       
  5956 	EAP_TRACE_DEBUG(
       
  5957 		m_am_tools, 
       
  5958 		TRACE_FLAGS_DEFAULT, 
       
  5959 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): this = 0x%08x, state %d=%s, m_authentication_type %d=%s.\n"),
       
  5960 		 (m_is_client == true) ? "client": "server",
       
  5961 		 this,
       
  5962 		 get_eapol_key_state(),
       
  5963 		 state_string.get_eapol_key_state_string(get_eapol_key_state()),
       
  5964 		 m_authentication_type,
       
  5965 		 state_string.get_eapol_key_authentication_type_string(m_authentication_type)));
       
  5966 
       
  5967 	eap_status_e status = eap_status_ok;
       
  5968 
       
  5969 	for (u32_t key_type = 0ul; key_type < eapol_key_type_last_type; key_type++)
       
  5970 	{
       
  5971 		m_received_802_1x_keys[key_type] = false;
       
  5972 	}
       
  5973 
       
  5974 	(void) cancel_retransmission();
       
  5975 	(void) cancel_handshake_timeout();
       
  5976 	(void) cancel_pmksa_caching_timeout();
       
  5977 	(void) cancel_reassociate_timeout();
       
  5978 	(void) cancel_4_way_handshake_start_timeout();
       
  5979 
       
  5980 	if (get_eapol_key_state() == eapol_key_state_preauthenticated)
       
  5981 	{
       
  5982 		// We must save the preauthenticated PMK and authentication type.
       
  5983 		EAP_TRACE_DEBUG(
       
  5984 			m_am_tools, 
       
  5985 			TRACE_FLAGS_DEFAULT, 
       
  5986 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): OK save PMKSA.\n"),
       
  5987 			 (m_is_client == true) ? "client": "server"));
       
  5988 	}
       
  5989 	else
       
  5990 	{
       
  5991 		// In other states PMK and authentication type is reset.
       
  5992 		EAP_TRACE_DEBUG(
       
  5993 			m_am_tools, 
       
  5994 			TRACE_FLAGS_DEFAULT, 
       
  5995 			(EAPL("WARNING: EAPOL_KEY: %s: eapol_key_state_c::reset_cached_pmksa(): removes PMKSA.\n"),
       
  5996 			 (m_is_client == true) ? "client": "server"));
       
  5997 
       
  5998 		if (m_is_client == true)
       
  5999 		{
       
  6000 			// Only client resets these pameters, test server will need these parameters.
       
  6001 
       
  6002 			m_pairwise_PMK_WPXK3.reset();
       
  6003 
       
  6004 			// Cannot reset m_authentication_type and m_eapol_key_state. These are needed later when possible error notification is send to lower layer.
       
  6005 
       
  6006 			m_supplicant_MAC_address.reset();
       
  6007 			m_authenticator_MAC_address.reset();
       
  6008 
       
  6009 			m_eapol_pairwise_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none;
       
  6010 			m_eapol_group_cipher = eapol_RSNA_key_header_c::eapol_RSNA_cipher_none;
       
  6011 
       
  6012 			m_authenticator_RSNA_IE.reset();
       
  6013 			m_supplicant_RSNA_IE.reset();
       
  6014 
       
  6015 #if defined(EAP_USE_WPXM)
       
  6016 			m_WPXM_WPXK1.reset();
       
  6017 			m_WPXM_WPXK2.reset();
       
  6018 			m_WPXM_WPXC = eapol_key_constant_wpxm_initial_wpxc_counter_value;
       
  6019 
       
  6020 			EAP_TRACE_DEBUG(
       
  6021 				m_am_tools, 
       
  6022 				TRACE_FLAGS_DEFAULT, 
       
  6023 				(EAPL("EAPOL_KEY: eapol_key_state_c::reset_cached_pmksa(): ")
       
  6024 				 EAPL("Reset m_WPXM_WPXC=%d.\n"),
       
  6025 				 m_WPXM_WPXC));
       
  6026 #endif //#if defined(EAP_USE_WPXM)
       
  6027 
       
  6028 		}
       
  6029 		else
       
  6030 		{
       
  6031 			set_eapol_key_state(eapol_key_state_none);
       
  6032 		}
       
  6033 
       
  6034 		m_PMKID.reset();
       
  6035 		m_transient_PTK.reset();
       
  6036 		m_confirmation_KCK.reset();
       
  6037 		m_encryption_KEK.reset();
       
  6038 		m_temporal_TK.reset();
       
  6039 
       
  6040 		// Cannot remove m_send_network_id because it is used
       
  6041 		// as a reference of this eapol_key_state_c object.
       
  6042 
       
  6043 		m_ANonce.reset();
       
  6044 		m_SNonce.reset();
       
  6045 
       
  6046 	}
       
  6047 
       
  6048 	m_received_PMKID.reset();
       
  6049 	m_unicast_cipher_suite_RSNA_IE.reset();
       
  6050 	m_EAPOL_key_IV.reset();
       
  6051 
       
  6052 	if (m_is_client == true)
       
  6053 	{
       
  6054 		set_key_reply_counter(0ul);
       
  6055 		set_client_send_key_reply_counter(0ul);
       
  6056 
       
  6057 		// Cannot reset m_eapol_key_handshake_type. This is needed later when possible error notification is send to lower layer.
       
  6058 	}
       
  6059 	else
       
  6060 	{
       
  6061 		m_eapol_key_handshake_type = eapol_key_handshake_type_none;
       
  6062 	}
       
  6063 
       
  6064 
       
  6065 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6066 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6067 }
       
  6068 
       
  6069 //--------------------------------------------------
       
  6070 
       
  6071 //
       
  6072 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::reset()
       
  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("EAPOL_KEY: %s: eapol_key_state_c::reset(): this = 0x%08x.\n"),
       
  6080 		 (m_is_client == true) ? "client": "server",
       
  6081 		 this));
       
  6082 
       
  6083 	eap_status_e status = reset_cached_pmksa();
       
  6084 
       
  6085 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6086 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6087 }
       
  6088 
       
  6089 //--------------------------------------------------
       
  6090 
       
  6091 //
       
  6092 eap_status_e eapol_key_state_c::create_tkip_mic_failure_message(
       
  6093 	eap_buf_chain_wr_c * const sent_packet,
       
  6094 	const u32_t eapol_header_offset,
       
  6095 	u32_t * const data_length,
       
  6096 	u32_t * const buffer_length,
       
  6097 	const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type,
       
  6098 	const eapol_protocol_version_e received_eapol_version)
       
  6099 {
       
  6100 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6101 	eap_status_e status = eap_status_process_general_error;
       
  6102 
       
  6103 	EAP_TRACE_DEBUG(
       
  6104 		m_am_tools, 
       
  6105 		TRACE_FLAGS_DEFAULT, 
       
  6106 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::create_tkip_mic_failure_message()\n"),
       
  6107 		(m_is_client == true ? "client": "server")));
       
  6108 
       
  6109 	// Only client (Supplicant) could create TKIP MIC failure message.
       
  6110 	EAP_ASSERT_ALWAYS(m_is_client == true);
       
  6111 
       
  6112 	u32_t eapol_key_data_length
       
  6113 		= eapol_RSNA_key_header_c::get_header_length();
       
  6114 
       
  6115 	*buffer_length
       
  6116 		= eapol_header_offset
       
  6117 		+ eapol_key_data_length;
       
  6118 
       
  6119 	status = sent_packet->set_buffer_length(
       
  6120 		*buffer_length);
       
  6121 	if (status != eap_status_ok)
       
  6122 	{
       
  6123 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6124 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6125 	}
       
  6126 	sent_packet->set_data_length(
       
  6127 		sent_packet->get_buffer_length());
       
  6128 
       
  6129 	eapol_RSNA_key_header_c eapol_key_message(
       
  6130 		m_am_tools,
       
  6131 		get_is_RSNA(),
       
  6132 		get_is_WPXM(),
       
  6133 		sent_packet->get_data_offset(eapol_header_offset, eapol_key_data_length),
       
  6134 		sent_packet->get_data_length());
       
  6135 
       
  6136 	if (eapol_key_message.get_is_valid() == false)
       
  6137 	{
       
  6138 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6139 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6140 	}
       
  6141 
       
  6142 	bool pairwise_key = true;
       
  6143 	if (tkip_mic_failure_type == eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_group_key)
       
  6144 	{
       
  6145 		pairwise_key = false;
       
  6146 	}
       
  6147 
       
  6148 	status = eapol_key_message.reset_header(
       
  6149 		0ul,
       
  6150 		m_authentication_type,
       
  6151 		m_eapol_pairwise_cipher,
       
  6152 		get_client_send_key_reply_counter(),
       
  6153 		pairwise_key, // Pairwise key type bit.
       
  6154 		false, // Install bit is NOT set.
       
  6155 		false, // Key Ack bit is NOT set.
       
  6156 		true, // Key MIC bit is on.
       
  6157 		false, // Secure bit is NOT set.
       
  6158 		true, // Error bit is on.
       
  6159 		true, // Request bit is on.
       
  6160 		false, // STAKey bit is NOT set.
       
  6161 		false, // Encrypted Key Data bit is NOT set.
       
  6162 		received_eapol_version,
       
  6163 		eapol_key_descriptor_type_none);
       
  6164 	if (status != eap_status_ok)
       
  6165 	{
       
  6166 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6167 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6168 	}
       
  6169 
       
  6170 	increase_client_send_key_reply_counter();
       
  6171 
       
  6172 	status = eapol_key_message.set_key_data_length(0ul);
       
  6173 	if (status != eap_status_ok)
       
  6174 	{
       
  6175 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6176 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6177 	}
       
  6178 
       
  6179 	*data_length
       
  6180 		= eapol_key_message.get_header_length()
       
  6181 		+ eapol_key_message.get_key_data_length();
       
  6182 
       
  6183 	status = eapol_key_message.set_eapol_packet_body_length(
       
  6184 		static_cast<u16_t>(*data_length - eapol_header_base_c::get_header_length()));
       
  6185 	if (status != eap_status_ok)
       
  6186 	{
       
  6187 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6188 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6189 	}
       
  6190 
       
  6191 	status = create_key_mic(&eapol_key_message, &m_confirmation_KCK);
       
  6192 	if (status != eap_status_ok)
       
  6193 	{
       
  6194 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6195 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6196 	}
       
  6197 
       
  6198 	sent_packet->set_data_length(
       
  6199 		eapol_header_offset + *data_length);
       
  6200 
       
  6201 	TRACE_EAPOL_KEY_MESSAGE(
       
  6202 		"Send TKIP MIC failure Message",
       
  6203 		&eapol_key_message);
       
  6204 
       
  6205 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6206 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6207 }
       
  6208 
       
  6209 //--------------------------------------------------
       
  6210 
       
  6211 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::tkip_mic_failure(
       
  6212 	const bool fatal_failure_when_true,
       
  6213 	const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type)
       
  6214 {
       
  6215 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6216 
       
  6217 	EAP_UNREFERENCED_PARAMETER(fatal_failure_when_true);
       
  6218 
       
  6219 	EAP_TRACE_DEBUG(
       
  6220 		m_am_tools,
       
  6221 		TRACE_FLAGS_DEFAULT,
       
  6222 		(EAPL("eapol_am_core_symbian_c::tkip_mic_failure(%d, %d).\n"),
       
  6223 		fatal_failure_when_true,
       
  6224 		tkip_mic_failure_type));
       
  6225 
       
  6226 	eap_status_e status = eap_status_not_supported;
       
  6227 
       
  6228 	eap_buf_chain_wr_c sent_packet(
       
  6229 		eap_write_buffer,
       
  6230 		m_am_tools);
       
  6231 
       
  6232 	if (sent_packet.get_is_valid() == false)
       
  6233 	{
       
  6234 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6235 	}
       
  6236 
       
  6237 	u32_t send_data_length = 0ul;
       
  6238 	u32_t send_buffer_length = 0ul;
       
  6239 
       
  6240 	status = create_tkip_mic_failure_message(
       
  6241 		&sent_packet,
       
  6242 		m_eapol_header_offset,
       
  6243 		&send_data_length,
       
  6244 		&send_buffer_length,
       
  6245 		tkip_mic_failure_type,
       
  6246 		eapol_protocol_version_2);
       
  6247 	if (status != eap_status_ok)
       
  6248 	{
       
  6249 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6250 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6251 	}
       
  6252 
       
  6253 
       
  6254 	status = packet_send(
       
  6255 		&m_send_network_id,
       
  6256 		&sent_packet,
       
  6257 		m_eapol_header_offset,
       
  6258 		send_data_length,
       
  6259 		send_buffer_length);
       
  6260 	if (status != eap_status_ok)
       
  6261 	{
       
  6262 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6263 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6264 	}
       
  6265 
       
  6266 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6267 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6268 }
       
  6269 
       
  6270 //--------------------------------------------------
       
  6271 
       
  6272 //
       
  6273 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::set_pairwise_PMK(
       
  6274 	const eap_variable_data_c * const key,
       
  6275 	const eap_am_network_id_c * const send_network_id)
       
  6276 {
       
  6277 	if (key == 0
       
  6278 		|| key->get_is_valid_data() == false
       
  6279 		|| key->get_data_length() == 0ul)
       
  6280 	{
       
  6281 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6282 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  6283 	}
       
  6284 
       
  6285 	u32_t pmk_key_length = key->get_data_length();
       
  6286 
       
  6287 	if (m_authentication_type == eapol_key_authentication_type_none)
       
  6288 	{
       
  6289 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6290 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  6291 	}
       
  6292 	else if (m_authentication_type != eapol_key_authentication_type_802_1X)
       
  6293 	{
       
  6294 		// Truncate PMK only in WPA and RSN case
       
  6295 		if (pmk_key_length > EAPOL_RSNA_PMK_LENGTH_BYTES)
       
  6296 		{
       
  6297 			pmk_key_length = EAPOL_RSNA_PMK_LENGTH_BYTES;
       
  6298 		}
       
  6299 		else if (pmk_key_length < EAPOL_RSNA_PMK_LENGTH_BYTES)
       
  6300 		{
       
  6301 			// No need to expand key. The short key is used as is.
       
  6302 		}
       
  6303 	}
       
  6304 
       
  6305 
       
  6306 	if (send_network_id->get_type() == eapol_ethernet_type_preauthentication)
       
  6307 	{
       
  6308 		set_eapol_key_state(eapol_key_state_preauthenticated);
       
  6309 	}
       
  6310 
       
  6311 
       
  6312 	EAP_TRACE_DATA_DEBUG(
       
  6313 		m_am_tools,
       
  6314 		TRACE_FLAGS_DEFAULT,
       
  6315 		(EAPL("eapol_key_state_c::set_pairwise_PMK(): key"),
       
  6316 		key->get_data(pmk_key_length),
       
  6317 		pmk_key_length));
       
  6318 
       
  6319 	eap_status_e status = m_pairwise_PMK_WPXK3.set_copy_of_buffer(
       
  6320 		key->get_data(pmk_key_length),
       
  6321 		pmk_key_length);
       
  6322 
       
  6323 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6324 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6325 }
       
  6326 
       
  6327 //--------------------------------------------------
       
  6328 
       
  6329 //
       
  6330 EAP_FUNC_EXPORT eap_status_e eapol_key_state_c::verify_field_is_zero(
       
  6331 		const u8_t * const field,
       
  6332 		const u32_t field_length)
       
  6333 {
       
  6334 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6335 
       
  6336 	eap_status_e status = eap_status_ok;
       
  6337 
       
  6338 	for (u32_t ind = 0ul; ind < field_length; ind++)
       
  6339 	{
       
  6340 		if (field[ind] != 0)
       
  6341 		{
       
  6342 			status = eap_status_illegal_padding;
       
  6343 			break;
       
  6344 		}
       
  6345 	}
       
  6346 
       
  6347 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6348 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6349 }
       
  6350 
       
  6351 //--------------------------------------------------
       
  6352 
       
  6353 //
       
  6354 eap_status_e eapol_key_state_c::packet_data_session_key(
       
  6355 	eap_variable_data_c * const key, ///< Here is the key.
       
  6356 	const eapol_key_type_e key_type, ///< This the type of the key.
       
  6357 	const u32_t key_index, ///< This is the index of the key.
       
  6358 	const bool key_tx_bit, ///< This is the TX bit of the key.
       
  6359 	const u8_t * const key_RSC, ///< This is the RSC counter
       
  6360 	const u32_t key_RSC_size ///< This is the size of RSC counter
       
  6361 	)
       
  6362 {
       
  6363 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6364 
       
  6365 	eapol_session_key_c * eapol_session_key = new eapol_session_key_c(
       
  6366 		m_am_tools,
       
  6367 		key,
       
  6368 		key_type,
       
  6369 		key_index,
       
  6370 		key_tx_bit,
       
  6371 		key_RSC,
       
  6372 		key_RSC_size
       
  6373 		);
       
  6374 	if (eapol_session_key == 0)
       
  6375 	{
       
  6376 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6377 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6378 	}
       
  6379 
       
  6380 	if (eapol_session_key->get_is_valid() == false)
       
  6381 	{
       
  6382 		delete eapol_session_key;
       
  6383 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6384 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6385 	}
       
  6386 
       
  6387 
       
  6388 	eap_status_e status = m_key_state_partner->packet_data_session_key(
       
  6389 		&m_send_network_id,
       
  6390 		eapol_session_key);
       
  6391 
       
  6392 	delete eapol_session_key;
       
  6393 
       
  6394 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6395 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6396 }
       
  6397 
       
  6398 //--------------------------------------------------
       
  6399 
       
  6400 //
       
  6401 eap_status_e eapol_key_state_c::allow_4_way_handshake()
       
  6402 {
       
  6403 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6404 	eap_status_e status = eap_status_process_general_error;
       
  6405 
       
  6406 	EAP_TRACE_DEBUG(
       
  6407 		m_am_tools, 
       
  6408 		TRACE_FLAGS_DEFAULT, 
       
  6409 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake()\n"),
       
  6410 		(m_is_client == true ? "client": "server")));
       
  6411 
       
  6412 	// Only client (supplicant) could allow 4-Way Handshake.
       
  6413 	EAP_ASSERT_ALWAYS(m_is_client == true);
       
  6414 	
       
  6415 	// First check do we need 4-Way Handshake.
       
  6416 	if (get_is_RSNA() == true
       
  6417 		|| get_is_WPA() == true
       
  6418 #if defined(EAP_USE_WPXM)
       
  6419 		|| get_is_WPXM() == true
       
  6420 #endif //#if defined(EAP_USE_WPXM)
       
  6421 		)
       
  6422 	{
       
  6423 		// OK, we need 4-Way Handshake.
       
  6424 		EAP_TRACE_DEBUG(
       
  6425 			m_am_tools, 
       
  6426 			TRACE_FLAGS_DEFAULT, 
       
  6427 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ")
       
  6428 			 EAPL("Allow 4-Way Handshake, m_authentication_type=%d\n"),
       
  6429 			(m_is_client == true ? "client": "server"),
       
  6430 			m_authentication_type));
       
  6431 
       
  6432 		m_eapol_key_handshake_type = eapol_key_handshake_type_4_way_handshake;
       
  6433 		m_eapol_key_state = eapol_key_state_wait_4_way_handshake_message_1;
       
  6434 	}
       
  6435 	else if (m_authentication_type == eapol_key_authentication_type_802_1X)
       
  6436 	{
       
  6437 		// No 4-Way Handshake needed.
       
  6438 		// AP will send unicast and broad cast keys in EAPOL key messages.
       
  6439 		EAP_TRACE_DEBUG(
       
  6440 			m_am_tools, 
       
  6441 			TRACE_FLAGS_DEFAULT, 
       
  6442 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ")
       
  6443 			 EAPL("Dynamic WEP, m_authentication_type=%d\n"),
       
  6444 			(m_is_client == true ? "client": "server"),
       
  6445 			m_authentication_type));
       
  6446 
       
  6447 		m_eapol_key_handshake_type = eapol_key_handshake_type_dynamic_WEP;
       
  6448 		m_eapol_key_state = eapol_key_state_wait_rc4_key_message;
       
  6449 
       
  6450 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6451 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6452 	}
       
  6453 	else
       
  6454 	{
       
  6455 		// No 4-Way Handshake needed.
       
  6456 		EAP_TRACE_DEBUG(
       
  6457 			m_am_tools, 
       
  6458 			TRACE_FLAGS_DEFAULT, 
       
  6459 			(EAPL("EAPOL_KEY: %s: eapol_key_state_c::allow_4_way_handshake(): ")
       
  6460 			 EAPL("No 4-Way Handshake, m_authentication_type=%d\n"),
       
  6461 			(m_is_client == true ? "client": "server"),
       
  6462 			m_authentication_type));
       
  6463 
       
  6464 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6465 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6466 	}
       
  6467 	
       
  6468 #if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  6469 	// Creates SNonce. This is done here in early phase of authentication.
       
  6470 	// This will reduce the CPU load when time critical first message
       
  6471 	// of 4-Way handshake is processed.
       
  6472 	status = create_nonce(&m_SNonce, EAPOL_RSNA_NONCE_LENGTH_BYTES);
       
  6473 	if (status != eap_status_ok)
       
  6474 	{
       
  6475 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6476 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6477 	}
       
  6478 #endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE)
       
  6479 
       
  6480 	status = init_handshake_timeout(m_handshake_timeout);
       
  6481 	if (status != eap_status_ok)
       
  6482 	{
       
  6483 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6484 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6485 	}
       
  6486 
       
  6487 #if defined(USE_EAPOL_KEY_TEST_FAILURES)
       
  6488 	#pragma message ( "WARNING: USE_EAPOL_KEY_TEST_FAILURES compiler flag used. This is test code, NOT for final release." )
       
  6489 	m_create_key_failure = eapol_key_state_wait_4_way_handshake_message_3;
       
  6490 #endif //#if defined(USE_EAPOL_KEY_TEST_FAILURES)
       
  6491 
       
  6492 	status = eap_status_ok;
       
  6493 
       
  6494 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6495 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6496 }
       
  6497 
       
  6498 //--------------------------------------------------
       
  6499 
       
  6500 //
       
  6501 eap_status_e eapol_key_state_c::start_group_key_handshake(
       
  6502 	const eap_am_network_id_c * const receive_network_id,
       
  6503 	const eapol_protocol_version_e received_eapol_version,
       
  6504 	const eapol_key_descriptor_type_e received_key_descriptor_type)
       
  6505 {
       
  6506 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6507 	EAP_UNREFERENCED_PARAMETER(receive_network_id);
       
  6508 
       
  6509 	eap_status_e status = eap_status_process_general_error;
       
  6510 
       
  6511 	// server and client could call this.
       
  6512 
       
  6513 	EAP_TRACE_DEBUG(
       
  6514 		m_am_tools, 
       
  6515 		TRACE_FLAGS_DEFAULT, 
       
  6516 		(EAPL("EAPOL_KEY: %s: eapol_key_state_c::start_group_key_handshake()\n"),
       
  6517 		(m_is_client == true ? "client": "server")));
       
  6518 
       
  6519 	if (m_eapol_key_handshake_type != eapol_key_handshake_type_none
       
  6520 		&& m_eapol_key_handshake_type != eapol_key_handshake_type_group_key_handshake
       
  6521 		&& m_eapol_key_handshake_type != eapol_key_handshake_type_4_way_handshake)
       
  6522 	{
       
  6523 		eapol_key_state_string_c state_string;
       
  6524 		EAP_TRACE_ERROR(
       
  6525 			m_am_tools,
       
  6526 			TRACE_FLAGS_DEFAULT,
       
  6527 			(EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong handshake type %s\n"),
       
  6528 			(m_is_client == true ? "client": "server"),
       
  6529 			state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type)));
       
  6530 
       
  6531 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6532 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  6533 	}
       
  6534 
       
  6535 	if (get_eapol_key_state() != eapol_key_state_4_way_handshake_successfull
       
  6536 		&& get_eapol_key_state() != eapol_key_state_group_key_handshake_successfull)
       
  6537 	{
       
  6538 		eapol_key_state_string_c state_string;
       
  6539 		EAP_TRACE_ERROR(
       
  6540 			m_am_tools,
       
  6541 			TRACE_FLAGS_DEFAULT,
       
  6542 			(EAPL("WARNING: EAPOL_KEY: %s: start_group_key_handshake(): wrong state %s\n"),
       
  6543 			(m_is_client == true ? "client": "server"),
       
  6544 			state_string.get_eapol_key_state_string(get_eapol_key_state())));
       
  6545 
       
  6546 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6547 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  6548 	}
       
  6549 
       
  6550 	eap_buf_chain_wr_c sent_packet(
       
  6551 		eap_write_buffer,
       
  6552 		m_am_tools);
       
  6553 
       
  6554 	if (sent_packet.get_is_valid() == false)
       
  6555 	{
       
  6556 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  6557 	}
       
  6558 
       
  6559 	u32_t send_data_length = 0ul;
       
  6560 	u32_t send_buffer_length = 0ul;
       
  6561 	eapol_key_state_e next_state = eapol_key_state_group_key_handshake_failed;
       
  6562 
       
  6563 	if (m_is_client == true)
       
  6564 	{
       
  6565 		status = create_eapol_key_handshake_message_0(
       
  6566 			false,
       
  6567 			&sent_packet,
       
  6568 			m_eapol_header_offset,
       
  6569 			&send_data_length,
       
  6570 			&send_buffer_length,
       
  6571 			0ul,
       
  6572 			received_eapol_version);
       
  6573 		if (status != eap_status_ok)
       
  6574 		{
       
  6575 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6576 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6577 		}
       
  6578 
       
  6579 		next_state = eapol_key_state_wait_group_key_handshake_message_1;
       
  6580 	}
       
  6581 	else
       
  6582 	{
       
  6583 
       
  6584 #if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6585 
       
  6586 		increase_key_reply_counter();
       
  6587 
       
  6588 		status = create_group_key_handshake_message_1(
       
  6589 			&sent_packet,
       
  6590 			m_eapol_header_offset,
       
  6591 			&send_data_length,
       
  6592 			&send_buffer_length,
       
  6593 			received_eapol_version,
       
  6594 			received_key_descriptor_type);
       
  6595 		if (status != eap_status_ok)
       
  6596 		{
       
  6597 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6598 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  6599 		}
       
  6600 
       
  6601 		next_state = eapol_key_state_wait_group_key_handshake_message_2;
       
  6602 #else
       
  6603 
       
  6604 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6605 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  6606 
       
  6607 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6608 	
       
  6609 	}
       
  6610 
       
  6611 	status = packet_send(
       
  6612 		&m_send_network_id,
       
  6613 		&sent_packet,
       
  6614 		m_eapol_header_offset,
       
  6615 		send_data_length,
       
  6616 		send_buffer_length);
       
  6617 	if (status != eap_status_ok)
       
  6618 	{
       
  6619 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6620 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6621 	}
       
  6622 		
       
  6623 	set_eapol_key_state(next_state);
       
  6624 
       
  6625 	m_eapol_key_handshake_type = eapol_key_handshake_type_group_key_handshake;
       
  6626 
       
  6627 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6628 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6629 }
       
  6630 
       
  6631 //--------------------------------------------------
       
  6632 
       
  6633 //
       
  6634 eap_status_e eapol_key_state_c::get_key_length(
       
  6635 	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e cipher,
       
  6636 	u16_t * const key_length)
       
  6637 {
       
  6638 	if (cipher
       
  6639 		== eapol_RSNA_key_header_c::eapol_RSNA_cipher_CCMP)
       
  6640 	{
       
  6641 		*key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_CCMP;
       
  6642 	}
       
  6643 	else if (cipher
       
  6644 			 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_TKIP)
       
  6645 	{
       
  6646 		*key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_TKIP;
       
  6647 	}
       
  6648 	else if (cipher
       
  6649 			 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_40)
       
  6650 	{
       
  6651 		*key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_40;
       
  6652 	}
       
  6653 	else if (cipher
       
  6654 			 == eapol_RSNA_key_header_c::eapol_RSNA_cipher_WEP_104)
       
  6655 	{
       
  6656 		*key_length = eapol_RSNA_key_header_c::eapol_RSNA_cipher_key_length_WEP_104;
       
  6657 	}
       
  6658 	else
       
  6659 	{
       
  6660 		*key_length = 0ul;
       
  6661 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6662 		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version);
       
  6663 	}
       
  6664 
       
  6665 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6666 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  6667 }
       
  6668 
       
  6669 //--------------------------------------------------
       
  6670 
       
  6671 //
       
  6672 eap_status_e eapol_key_state_c::process_4_way_handshake_message(
       
  6673 	const eap_am_network_id_c * const receive_network_id,
       
  6674 	eapol_RSNA_key_header_c * const eapol_key_message,
       
  6675 	const u32_t packet_length)
       
  6676 {
       
  6677 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6678 	eap_status_e status = eap_status_process_general_error;
       
  6679 
       
  6680 	
       
  6681 
       
  6682 #if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6683 	if (m_is_client == false
       
  6684 		&& eapol_key_message->get_key_information_request() == true
       
  6685 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6686 		&& eapol_key_message->get_key_information_key_ack() == false
       
  6687 		&& eapol_key_message->get_key_information_install() == false
       
  6688 		&& eapol_key_message->get_key_data_length() == 0ul)
       
  6689 	{
       
  6690 		// Message 0 to start 4-Way Handshake. Only server handles this.
       
  6691 		status = process_4_way_handshake_message_0(
       
  6692 			receive_network_id,
       
  6693 			eapol_key_message,
       
  6694 			packet_length);
       
  6695 	}
       
  6696 	else
       
  6697 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6698 	if (m_is_client == true
       
  6699 		&& eapol_key_message->get_key_information_key_MIC() == false
       
  6700 		&& eapol_key_message->get_key_information_key_ack() == true
       
  6701 		&& eapol_key_message->get_key_information_install() == false)
       
  6702 	{
       
  6703 		// Message 1 of 4-Way Handshake. Only client handles this.
       
  6704 		status = process_4_way_handshake_message_1(
       
  6705 			receive_network_id,
       
  6706 			eapol_key_message,
       
  6707 			packet_length);
       
  6708 	}
       
  6709 	else
       
  6710 #if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6711 	if (m_is_client == false
       
  6712 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6713 		&& eapol_key_message->get_key_information_key_ack() == false
       
  6714 		&& eapol_key_message->get_key_information_install() == false
       
  6715 		&& eapol_key_message->get_key_data_length() != 0ul)
       
  6716 	{
       
  6717 		// Message 2 of 4-Way Handshake. Only server handles this.
       
  6718 		status = process_4_way_handshake_message_2(
       
  6719 			receive_network_id,
       
  6720 			eapol_key_message,
       
  6721 			packet_length);
       
  6722 	}
       
  6723 	else
       
  6724 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6725 	if (m_is_client == true
       
  6726 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6727 		&& eapol_key_message->get_key_information_key_ack() == true
       
  6728 		&& eapol_key_message->get_key_information_install() == true
       
  6729 		&& eapol_key_message->get_key_data_length() != 0ul)
       
  6730 	{
       
  6731 		// Message 3 of 4-Way Handshake. Only client handles this.
       
  6732 		status = process_4_way_handshake_message_3(
       
  6733 			receive_network_id,
       
  6734 			eapol_key_message,
       
  6735 			packet_length);
       
  6736 	}
       
  6737 	else
       
  6738 #if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6739 	if (m_is_client == false
       
  6740 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6741 		&& eapol_key_message->get_key_information_key_ack() == false
       
  6742 		&& eapol_key_message->get_key_information_install() == false
       
  6743 		&& eapol_key_message->get_key_data_length() == 0ul)
       
  6744 	{
       
  6745 		// Message 4 of 4-Way Handshake. Only server handles this.
       
  6746 		status = process_4_way_handshake_message_4(
       
  6747 			receive_network_id,
       
  6748 			eapol_key_message,
       
  6749 			packet_length);
       
  6750 	}
       
  6751 	else
       
  6752 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6753 	{
       
  6754 		// ERROR. Drop packet.
       
  6755 		EAP_TRACE_ERROR(
       
  6756 			m_am_tools,
       
  6757 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6758 			(EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key 4-Way Handshake frame: ")
       
  6759 			 EAPL("IsClient: %d MIC %d, Key Ack %d, Install %d, Key Length %d\n"),
       
  6760 			m_is_client,
       
  6761 			eapol_key_message->get_key_information_key_MIC(),
       
  6762 			eapol_key_message->get_key_information_key_ack(),
       
  6763 			eapol_key_message->get_key_information_install(),
       
  6764 			eapol_key_message->get_key_data_length()));
       
  6765 		
       
  6766 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6767 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  6768 	}
       
  6769 
       
  6770 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6771 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6772 }
       
  6773 
       
  6774 //--------------------------------------------------
       
  6775 
       
  6776 //
       
  6777 eap_status_e eapol_key_state_c::process_group_key_handshake_message(
       
  6778 	const eap_am_network_id_c * const receive_network_id,
       
  6779 	eapol_RSNA_key_header_c * const eapol_key_message,
       
  6780 	const u32_t packet_length)
       
  6781 {
       
  6782 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6783 	eap_status_e status = eap_status_process_general_error;
       
  6784 
       
  6785 #if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6786 	if (m_is_client == false
       
  6787 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6788 		&& eapol_key_message->get_key_information_key_ack() == false
       
  6789 		&& eapol_key_message->get_key_information_request() == true)
       
  6790 	{
       
  6791 		// Message 0 of Group Key Handshake. Only server handles this.
       
  6792 		status = process_group_key_handshake_message_0(
       
  6793 			receive_network_id,
       
  6794 			eapol_key_message,
       
  6795 			packet_length);
       
  6796 	}
       
  6797 	else
       
  6798 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6799 	if (m_is_client == true
       
  6800 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6801 		&& eapol_key_message->get_key_information_key_ack() == true
       
  6802 		&& eapol_key_message->get_key_information_request() == false)
       
  6803 	{
       
  6804 		// Message 1 of Group Key Handshake. Only client handles this.
       
  6805 		status = process_group_key_handshake_message_1(
       
  6806 			receive_network_id,
       
  6807 			eapol_key_message,
       
  6808 			packet_length);
       
  6809 	}
       
  6810 	else
       
  6811 #if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6812 	if (m_is_client == false
       
  6813 		&& eapol_key_message->get_key_information_key_MIC() == true
       
  6814 		&& eapol_key_message->get_key_information_key_ack() == false
       
  6815 		&& eapol_key_message->get_key_information_request() == false)
       
  6816 	{
       
  6817 		// Message 2 of Group Key Handshake. Only server handles this.
       
  6818 		status = process_group_key_handshake_message_2(
       
  6819 			receive_network_id,
       
  6820 			eapol_key_message,
       
  6821 			packet_length);
       
  6822 	}
       
  6823 	else
       
  6824 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER)
       
  6825 	{
       
  6826 		// ERROR. Drop packet.
       
  6827 		EAP_TRACE_ERROR(
       
  6828 			m_am_tools,
       
  6829 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6830 			(EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key Group Key Handshake frame: ")
       
  6831 			 EAPL("MIC %d, Key Ack %d, Request %d\n"),
       
  6832 			eapol_key_message->get_key_information_key_MIC(),
       
  6833 			eapol_key_message->get_key_information_key_ack(),
       
  6834 			eapol_key_message->get_key_information_request()));
       
  6835 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6836 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  6837 	}
       
  6838 
       
  6839 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6840 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  6841 }
       
  6842 
       
  6843 //--------------------------------------------------
       
  6844 
       
  6845 //
       
  6846 eap_status_e eapol_key_state_c::process_RSNA_key_descriptor(
       
  6847 	const eap_am_network_id_c * const receive_network_id,
       
  6848 	eap_general_header_base_c * const packet_data,
       
  6849 	const u32_t packet_length)
       
  6850 {
       
  6851 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6852 	eap_status_e status = eap_status_process_general_error;
       
  6853 
       
  6854 	if (packet_length < eapol_RSNA_key_header_c::get_header_length())
       
  6855 	{
       
  6856 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6857 		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
       
  6858 	}
       
  6859 
       
  6860 	eapol_RSNA_key_header_c eapol_key_message(
       
  6861 		m_am_tools,
       
  6862 		get_is_RSNA(),
       
  6863 		get_is_WPXM(),
       
  6864 		packet_data->get_header_buffer(packet_data->get_header_buffer_length()),
       
  6865 		packet_data->get_header_buffer_length());
       
  6866 	if (eapol_key_message.get_is_valid() == false)
       
  6867 	{
       
  6868 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6869 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  6870 	}
       
  6871 
       
  6872 	status = eapol_key_message.check_header();
       
  6873 	if (status != eap_status_ok)
       
  6874 	{
       
  6875 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6876 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  6877 	}
       
  6878 
       
  6879 	TRACE_EAPOL_KEY_MESSAGE(
       
  6880 		"Received EAPOL Handshake Message",
       
  6881 		&eapol_key_message);
       
  6882 
       
  6883 	u64_t packet_reply_counter = eapol_key_message.get_key_replay_counter();
       
  6884 
       
  6885 	// compare_u64() function is used because in some platforms
       
  6886 	// unsigned 64-bit comparison is actually signed 64-bit comparison,
       
  6887 	// because unsigned 64-bit integer is implemented as a signed 64-bit integer.
       
  6888 	// This causes failures in test if broken AP sends Key Replay Counter with
       
  6889 	// highest bit set 1.
       
  6890 	i32_t comparison(m_am_tools->compare_u64(get_key_reply_counter(), packet_reply_counter));
       
  6891 
       
  6892 	if (m_is_client == true)
       
  6893 	{
       
  6894 		// On client Key Reply Counter must be bigger
       
  6895 		// than on any other previous frame.
       
  6896 		//if (get_key_reply_counter() > packet_reply_counter)
       
  6897 		if (comparison > 0)
       
  6898 		{
       
  6899 			// ERROR. Drop packet.
       
  6900 			EAP_TRACE_ERROR(
       
  6901 				m_am_tools,
       
  6902 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6903 				(EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter\n")));
       
  6904 			EAP_TRACE_DATA_ERROR(
       
  6905 				m_am_tools,
       
  6906 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6907 				(EAPL("Local Reply Counter"),
       
  6908 				&m_key_reply_counter,
       
  6909 				sizeof(m_key_reply_counter)));
       
  6910 			EAP_TRACE_DATA_ERROR(
       
  6911 				m_am_tools,
       
  6912 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6913 				(EAPL("Packet Reply Counter"),
       
  6914 				&packet_reply_counter,
       
  6915 				sizeof(packet_reply_counter)));
       
  6916 
       
  6917 			if (get_is_WPXM() == true)
       
  6918 			{
       
  6919 				// Here we must ignore the Reply Counter failure.
       
  6920 				// WPXM seems to work against RSN specification that says
       
  6921 				// every packet must be sent with new Reply Counter.
       
  6922 				// WPXM starts Group Key Handshake with Reply Counter 0 after successfull
       
  6923 				// 4-Way Handshake.
       
  6924 				EAP_TRACE_DEBUG(
       
  6925 					m_am_tools,
       
  6926 					TRACE_FLAGS_DEFAULT,
       
  6927 					(EAPL("WARNING: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter in WPXM.\n")));
       
  6928 			}
       
  6929 			else
       
  6930 			{
       
  6931 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6932 				return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  6933 			}
       
  6934 		}
       
  6935 		else if (comparison == 0)
       
  6936 		{
       
  6937 			// This may be re-transmitted request.
       
  6938 			// Send the saved previous response
       
  6939 			// or process this message again.
       
  6940 			EAP_TRACE_DEBUG(
       
  6941 				m_am_tools,
       
  6942 				TRACE_FLAGS_DEFAULT,
       
  6943 				(EAPL("WARNING: EAPOL_KEY: EAPOL-Key frame Reply Counter same as previous request.\n")));
       
  6944 			EAP_TRACE_DATA_DEBUG(
       
  6945 				m_am_tools,
       
  6946 				TRACE_FLAGS_DEFAULT,
       
  6947 				(EAPL("WARNING: Local Reply Counter"),
       
  6948 				&m_key_reply_counter,
       
  6949 				sizeof(m_key_reply_counter)));
       
  6950 			EAP_TRACE_DATA_DEBUG(
       
  6951 				m_am_tools,
       
  6952 				TRACE_FLAGS_DEFAULT,
       
  6953 				(EAPL("WARNING: Packet Reply Counter"),
       
  6954 				&packet_reply_counter,
       
  6955 				sizeof(packet_reply_counter)));
       
  6956 		}
       
  6957 	}
       
  6958 	else
       
  6959 	{
       
  6960 		if (eapol_key_message.get_key_information_request() == true)
       
  6961 		{
       
  6962 			// Reply Counter of request packets are not checked.
       
  6963 			comparison = 0;
       
  6964 		}
       
  6965 
       
  6966 		// On server Key Reply Counter must be same
       
  6967 		// as the sent request frame.
       
  6968 		if (comparison != 0)
       
  6969 		{
       
  6970 			// ERROR. Drop packet.
       
  6971 			EAP_TRACE_ERROR(
       
  6972 				m_am_tools,
       
  6973 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6974 				(EAPL("ERROR: EAPOL_KEY: Illegal EAPOL-Key frame Reply Counter\n")));
       
  6975 			EAP_TRACE_DATA_ERROR(
       
  6976 				m_am_tools,
       
  6977 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6978 				(EAPL("Local Reply Counter"),
       
  6979 				&m_key_reply_counter,
       
  6980 				sizeof(m_key_reply_counter)));
       
  6981 			EAP_TRACE_DATA_ERROR(
       
  6982 				m_am_tools,
       
  6983 				TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  6984 				(EAPL("Packet Reply Counter"),
       
  6985 				&packet_reply_counter,
       
  6986 				sizeof(packet_reply_counter)));
       
  6987 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  6988 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  6989 		}
       
  6990 	}
       
  6991 
       
  6992 
       
  6993 	if (eapol_key_message.get_key_information_key_type() == true)
       
  6994 	{
       
  6995 		// 4-Way Handshake message.
       
  6996 		status = process_4_way_handshake_message(
       
  6997 			receive_network_id,
       
  6998 			&eapol_key_message,
       
  6999 			packet_length);
       
  7000 	}
       
  7001 	else if (eapol_key_message.get_key_information_key_type() == false)
       
  7002 	{
       
  7003 		// Group Key Handshake message.
       
  7004 		status = process_group_key_handshake_message(
       
  7005 			receive_network_id,
       
  7006 			&eapol_key_message,
       
  7007 			packet_length);
       
  7008 	}
       
  7009 	else
       
  7010 	{
       
  7011 		// Unknown message received and dropped quietly.
       
  7012 		eapol_key_state_string_c state_string;
       
  7013 		EAP_TRACE_ERROR(
       
  7014 			m_am_tools,
       
  7015 			TRACE_FLAGS_EAPOL_KEY_DATA_ERROR,
       
  7016 			(EAPL("WARNING: EAPOL_KEY: Handshake in NOT supported in m_eapol_key_handshake_type %s.\n"),
       
  7017 			state_string.get_eapol_key_handshake_type_string(m_eapol_key_handshake_type)));
       
  7018 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7019 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  7020 	}
       
  7021 
       
  7022 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  7023 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  7024 }
       
  7025 
       
  7026 //--------------------------------------------------
       
  7027 
       
  7028 // End.