eapol/eapol_framework/eapol_symbian/am/type/gsmsim/symbian/eap_am_type_gsmsim_symbian_simulator.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 194 
       
    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 #define EAP_AM_MEMORY_GUARD
       
    30 	#include "eap_am_memory.h"
       
    31 #undef EAP_AM_MEMORY_GUARD
       
    32 
       
    33 #include "eap_tools.h"
       
    34 #include "eap_am_type_gsmsim_symbian_simulator.h"
       
    35 #include "eap_am_crypto.h"
       
    36 #include "abs_eap_am_mutex.h"
       
    37 
       
    38 const u32_t SIM_IMSI_LENGTH = 15u;
       
    39 
       
    40 //--------------------------------------------------
       
    41 
       
    42 // 
       
    43 EAP_FUNC_EXPORT eap_am_type_gsmsim_simulator_c::~eap_am_type_gsmsim_simulator_c()
       
    44 {
       
    45 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    46 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    47 }
       
    48 
       
    49 //--------------------------------------------------
       
    50 
       
    51 // 
       
    52 EAP_FUNC_EXPORT eap_am_type_gsmsim_simulator_c::eap_am_type_gsmsim_simulator_c(
       
    53 	abs_eap_am_tools_c * const tools,
       
    54 	abs_eap_base_type_c * const partner,
       
    55 	const CEapPluginInterface::TIndexType aIndexType,
       
    56 	const TInt aIndex)
       
    57 : eap_am_type_gsmsim_c(tools)
       
    58 , m_am_tools(tools)
       
    59 , m_partner(partner)
       
    60 , saved_pseudonym(tools)
       
    61 , m_is_valid(eap_boolean_true)
       
    62 {
       
    63 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    64 	EAP_UNREFERENCED_PARAMETER(aIndexType);
       
    65 	EAP_UNREFERENCED_PARAMETER(aIndex);
       
    66 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    67 }
       
    68 
       
    69 //--------------------------------------------------
       
    70 
       
    71 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::store_reauth_keys(
       
    72 	const eap_variable_data_c * const XKEY,
       
    73 	const eap_variable_data_c * const K_aut,
       
    74 	const eap_variable_data_c * const K_encr)
       
    75 {
       
    76 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    77 
       
    78 	EAP_UNREFERENCED_PARAMETER(XKEY);
       
    79 	EAP_UNREFERENCED_PARAMETER(K_aut);
       
    80 	EAP_UNREFERENCED_PARAMETER(K_encr);
       
    81 
       
    82 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    83 	return eap_status_ok;
       
    84 }
       
    85 
       
    86 //--------------------------------------------------
       
    87 
       
    88 const eap_status_e eap_am_type_gsmsim_simulator_c::authentication_finished(
       
    89 	const eap_boolean_e true_when_successfull,
       
    90 	const eap_gsmsim_authentication_type_e authentication_type)
       
    91 {
       
    92 	EAP_UNREFERENCED_PARAMETER(true_when_successfull);
       
    93 	EAP_UNREFERENCED_PARAMETER(authentication_type);
       
    94 
       
    95     eap_status_e status = eap_status_ok;
       
    96 	return status;
       
    97 }
       
    98 
       
    99 //--------------------------------------------------
       
   100 
       
   101 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_reauth_parameters(
       
   102 	eap_variable_data_c * const reauth_XKEY,
       
   103 	eap_variable_data_c * const reauth_K_aut,
       
   104 	eap_variable_data_c * const reauth_K_encr,
       
   105 	u32_t * const reauth_counter)
       
   106 {
       
   107 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   108 
       
   109 	EAP_UNREFERENCED_PARAMETER(reauth_XKEY);
       
   110 	EAP_UNREFERENCED_PARAMETER(reauth_K_aut);
       
   111 	EAP_UNREFERENCED_PARAMETER(reauth_K_encr);
       
   112 	EAP_UNREFERENCED_PARAMETER(reauth_counter);
       
   113 
       
   114 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   115 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   116 }
       
   117 
       
   118 //--------------------------------------------------
       
   119 
       
   120 //
       
   121 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::increase_reauth_counter()
       
   122 {
       
   123 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   124 
       
   125 	eap_status_e status = eap_status_not_supported;
       
   126 
       
   127 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   128 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   129 }
       
   130 
       
   131 //--------------------------------------------------
       
   132 
       
   133 EAP_FUNC_EXPORT const eap_status_e eap_am_type_gsmsim_simulator_c::configure()
       
   134 {
       
   135 	return eap_status_ok;
       
   136 }
       
   137 
       
   138 //--------------------------------------------------
       
   139 
       
   140 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_imsi(
       
   141 	u8_t * const imsi, const u32_t max_length, u32_t * const imsi_length)
       
   142 {
       
   143 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   144 
       
   145 	const char tmp_imsi[] = "244070100000001";
       
   146 	*imsi_length = m_am_tools->strlen(tmp_imsi);
       
   147 	if (*imsi_length > max_length)
       
   148 	{
       
   149 		// ERROR, too short buffer.
       
   150 		*imsi_length = 0u;
       
   151 		return eap_status_allocation_error;
       
   152 	}
       
   153 	m_am_tools->memcpy(imsi, tmp_imsi, m_am_tools->strlen(tmp_imsi));
       
   154 
       
   155 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   156 	return eap_status_ok;
       
   157 }
       
   158 
       
   159 //--------------------------------------------------
       
   160 
       
   161 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::store_pseudonym_id(
       
   162 	const eap_am_network_id_c * const /*network_id*/,
       
   163 	const eap_variable_data_c * const pseudonym)
       
   164 {
       
   165 	return saved_pseudonym.set_copy_of_buffer(pseudonym);
       
   166 }
       
   167 
       
   168 //--------------------------------------------------
       
   169 
       
   170 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::store_reauthentication_id(
       
   171 	const eap_am_network_id_c * const /*network_id*/,
       
   172 	const eap_variable_data_c * const /* reauthentication_id */)
       
   173 {
       
   174 	return eap_status_ok;
       
   175 }
       
   176 
       
   177 //--------------------------------------------------
       
   178 
       
   179 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_IMSI_or_pseudonym_or_reauthentication_id(
       
   180 	const eap_boolean_e must_be_synchronous,
       
   181 	eap_variable_data_c * const IMSI,
       
   182 	eap_variable_data_c * const pseudonym_identity,
       
   183 	eap_variable_data_c * const /* reauthentication_identity */)
       
   184 {
       
   185 	EAP_UNREFERENCED_PARAMETER(must_be_synchronous);
       
   186 
       
   187 	eap_status_e status = eap_status_process_general_error;
       
   188 
       
   189 	if (IMSI == 0
       
   190 		|| pseudonym_identity == 0)
       
   191 	{
       
   192 		// Something is really wrong.
       
   193 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   194 		return eap_status_process_general_error;
       
   195 	}
       
   196 
       
   197 	if (IMSI->get_is_valid() == eap_boolean_false
       
   198 		|| IMSI->get_buffer_length() < SIM_IMSI_LENGTH)
       
   199 	{
       
   200 		IMSI->init(SIM_IMSI_LENGTH);
       
   201 		IMSI->set_is_valid();
       
   202 	}
       
   203 
       
   204 	if (saved_pseudonym.get_is_valid() == eap_boolean_true)
       
   205 	{
       
   206 		// We have stored pseudonym_identity.
       
   207 		if (pseudonym_identity == 0)
       
   208 		{
       
   209 			// Something is really wrong.
       
   210 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   211 			return eap_status_process_general_error;
       
   212 		}
       
   213 		pseudonym_identity->set_copy_of_buffer(&saved_pseudonym);
       
   214 	}
       
   215 
       
   216 
       
   217 	{
       
   218 		u32_t imsi_length = 0u;
       
   219 
       
   220 		status = query_SIM_imsi(
       
   221 			IMSI->get_data(SIM_IMSI_LENGTH),
       
   222 			SIM_IMSI_LENGTH,
       
   223 			&imsi_length);
       
   224 
       
   225 		if (status != eap_status_ok
       
   226 			|| imsi_length != SIM_IMSI_LENGTH)
       
   227 		{
       
   228 			return status;
       
   229 		}
       
   230 
       
   231 		IMSI->set_data_length(imsi_length);
       
   232 	}
       
   233 
       
   234 	if (must_be_synchronous == eap_boolean_false)
       
   235 	{
       
   236 		status = get_am_partner()->complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(
       
   237 			IMSI,
       
   238 			pseudonym_identity,
       
   239 			0);
       
   240 
       
   241 		if (status == eap_status_ok)
       
   242 		{
       
   243 			status = eap_status_completed_request;
       
   244 		}
       
   245 	}
       
   246 
       
   247 	return status;
       
   248 }
       
   249 
       
   250 //--------------------------------------------------
       
   251 
       
   252 //
       
   253 eap_status_e eap_am_type_gsmsim_simulator_c::cancel_SIM_IMSI_or_pseudonym_or_reauthentication_id_query()
       
   254 {
       
   255 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   256 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   257 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   258 }
       
   259 
       
   260 //--------------------------------------------------
       
   261 
       
   262 //
       
   263 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_kc_and_sres(
       
   264 	const u8_t * const /* imsi */, const u32_t /* imsi_length */,
       
   265 	const u8_t * const rand, const u32_t rand_length,
       
   266 	u8_t * const kc, u32_t * const kc_length,
       
   267 	u8_t * const sres, u32_t * const sres_length)
       
   268 {
       
   269 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   270 
       
   271 	EAP_UNREFERENCED_PARAMETER(rand_length);
       
   272 
       
   273 	EAP_ASSERT_ALWAYS(rand_length == SIM_RAND_LENGTH);
       
   274 	EAP_ASSERT_ALWAYS(*kc_length == SIM_KC_LENGTH);
       
   275 	EAP_ASSERT_ALWAYS(*sres_length == SIM_SRES_LENGTH);
       
   276 	
       
   277 	const u8_t test_Ki[SIM_RAND_LENGTH] = {0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5};
       
   278 
       
   279 	u8_t tmp[SIM_KC_LENGTH + SIM_SRES_LENGTH];
       
   280 	m_am_tools->memset(tmp, 0, sizeof(tmp));
       
   281 
       
   282 	u32_t i = 0;
       
   283 
       
   284 	for(i = 0; i < (SIM_KC_LENGTH + SIM_SRES_LENGTH); i++)
       
   285 	{
       
   286 		tmp[i] = (u8_t)(rand[i] ^ test_Ki[i]);
       
   287 	}
       
   288 
       
   289 	m_am_tools->memcpy(sres, tmp, *sres_length);
       
   290 	m_am_tools->memcpy(kc, tmp + *sres_length, *kc_length);
       
   291 
       
   292 
       
   293 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   294 	return eap_status_ok;
       
   295 }
       
   296 
       
   297 //--------------------------------------------------
       
   298 
       
   299 //
       
   300 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::handle_gsmsim_notification(
       
   301 	eap_gsmsim_triplet_status_e /* gsmsim_notification_code */)
       
   302 {
       
   303 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   304 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   305 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   306 }
       
   307 
       
   308 //--------------------------------------------------
       
   309 
       
   310 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
   311 
       
   312 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_triplets(
       
   313 	const eap_boolean_e must_be_synchronous,
       
   314 	const eap_variable_data_c * const /* p_username */,
       
   315 	eap_variable_data_c * const /* p_imsi */,
       
   316 	eap_type_sim_triplet_array_c * const triplets,
       
   317 	eap_type_gsmsim_identity_type * const type)
       
   318 {
       
   319 	EAP_UNREFERENCED_PARAMETER(must_be_synchronous);
       
   320 	EAP_UNREFERENCED_PARAMETER(type);
       
   321 
       
   322 	// NOTE if user needs to use state_selector or imsi after return from query_SIM_triplets()
       
   323 	// function those parameters MUST be copied using copy() member function of each parameter.
       
   324 	// For example: saved_imsi = p_imsi_or_pseudonym->copy()
       
   325 	//              saved_state_selector = state_selector->copy()
       
   326 
       
   327 	eap_status_e status = eap_status_process_general_error;
       
   328 	const u32_t rand_length = 16u;
       
   329 	const u8_t test_rand[] = "0123456789abcdef";
       
   330 	const u8_t test_Ki[rand_length] = {0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,
       
   331 										0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5,0xA5};
       
   332 	const u32_t triplet_count = 2u;
       
   333 	u32_t ind;
       
   334 	u32_t i = 0;
       
   335 
       
   336 	if (triplets == 0)
       
   337 	{
       
   338 		// Something is really wrong.
       
   339 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   340 		return eap_status_process_general_error;
       
   341 	}
       
   342 
       
   343 	triplets->set_triplet_count(triplet_count);
       
   344 
       
   345 	for (ind = 0u; ind < triplet_count; ind++)
       
   346 	{
       
   347 		eap_type_saesim_triplet_c *tripl = triplets->get_triplet(m_am_tools, ind);
       
   348 		u8_t tmp[rand_length] = {0,};
       
   349 
       
   350 		status = tripl->get_rand()->set_copy_of_buffer((u8_t *)test_rand, 16);
       
   351 		if (status != eap_status_ok)
       
   352 		{
       
   353 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   354 			return status;
       
   355 		}
       
   356 
       
   357 		status = tripl->get_kc()->init(SIM_KC_LENGTH);
       
   358 		if (status != eap_status_ok)
       
   359 		{
       
   360 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   361 			return status;
       
   362 		}
       
   363 
       
   364 		tripl->get_kc()->set_is_valid();
       
   365 		tripl->get_kc()->set_data_length(SIM_KC_LENGTH);
       
   366 
       
   367 		status = tripl->get_sres()->init(SIM_SRES_LENGTH);
       
   368 		if (status != eap_status_ok)
       
   369 		{
       
   370 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   371 			return status;
       
   372 		}
       
   373 
       
   374 		tripl->get_sres()->set_is_valid();
       
   375 		tripl->get_sres()->set_data_length(SIM_SRES_LENGTH);
       
   376 
       
   377 		for (i = 0; i < (SIM_KC_LENGTH + SIM_SRES_LENGTH); i++)
       
   378 		{
       
   379 			tmp[i] = (u8_t)(test_rand[i] ^ test_Ki[i]);
       
   380 		}
       
   381 
       
   382 		tripl->get_sres()->set_copy_of_buffer(tmp, SIM_SRES_LENGTH);
       
   383 		tripl->get_kc()->set_copy_of_buffer(tmp + SIM_SRES_LENGTH, SIM_KC_LENGTH);
       
   384 
       
   385 	}
       
   386 
       
   387 	return status;
       
   388 }
       
   389 
       
   390 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
   391 
       
   392 //--------------------------------------------------
       
   393 
       
   394 #if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
   395 
       
   396 //
       
   397 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::cancel_SIM_triplets_query()
       
   398 {
       
   399 	EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: cancel_SIM_triplets_query() not supported here..\n")));
       
   400 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   401 }
       
   402 
       
   403 #endif //#if defined(USE_EAP_TYPE_SERVER_GSMSIM)
       
   404 
       
   405 //--------------------------------------------------
       
   406 
       
   407 //
       
   408 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_SIM_kc_sres(
       
   409 	const eap_boolean_e must_be_synchronous,
       
   410 	//const eap_variable_data_c * const p_imsi,
       
   411 	const eap_variable_data_c * const p_n_rands,
       
   412 	eap_variable_data_c * const n_kc,
       
   413 	eap_variable_data_c * const n_sres)
       
   414 {
       
   415 	EAP_UNREFERENCED_PARAMETER(must_be_synchronous);
       
   416 
       
   417 	// NOTE if user needs to use state_selector or n_rands after return from query_SIM_kc_sres()
       
   418 	// function those parameters MUST be copied using copy() member function of each parameter.
       
   419 	// For example: saved_n_rands = n_rands->copy()
       
   420 	//              saved_state_selector = state_selector->copy()
       
   421 
       
   422 	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == eap_boolean_true);
       
   423 
       
   424 	if (n_kc == 0
       
   425 		|| n_sres == 0
       
   426 		|| p_n_rands == 0)
       
   427 	{
       
   428 		// Something is really wrong.
       
   429 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   430 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
   431 	}
       
   432 
       
   433 
       
   434 	eap_status_e status = eap_status_process_general_error;
       
   435 	eap_variable_data_c copy_of_imsi(m_am_tools);
       
   436 
       
   437 	// First we must query IMSI.
       
   438 	u32_t imsi_length = 0u;
       
   439 
       
   440 	copy_of_imsi.init(SIM_IMSI_LENGTH);
       
   441 	copy_of_imsi.set_is_valid();
       
   442 
       
   443 	status = query_SIM_imsi(
       
   444 		copy_of_imsi.get_data(copy_of_imsi.get_data_length()),
       
   445 		SIM_IMSI_LENGTH,
       
   446 		&imsi_length);
       
   447 
       
   448 	if (status != eap_status_ok
       
   449 		|| imsi_length != SIM_IMSI_LENGTH)
       
   450 	{
       
   451 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   452 		return status;
       
   453 	}
       
   454 
       
   455 	copy_of_imsi.set_data_length(imsi_length);
       
   456 
       
   457 
       
   458 	eap_variable_data_c *copy_of_n_rands = p_n_rands->copy();
       
   459 
       
   460 	if (copy_of_n_rands == 0)
       
   461 	{
       
   462 		return eap_status_allocation_error;
       
   463 	}
       
   464 
       
   465 
       
   466 	u32_t kc_length = SIM_KC_LENGTH;
       
   467 	u32_t sres_length = SIM_SRES_LENGTH;
       
   468 
       
   469 	u32_t count = copy_of_n_rands->get_data_length() / SIM_RAND_LENGTH;
       
   470 
       
   471 	if (n_kc->get_is_valid() == eap_boolean_false
       
   472 		|| n_kc->get_buffer_length() < count*SIM_KC_LENGTH)
       
   473 	{
       
   474 		n_kc->init(count*SIM_KC_LENGTH);
       
   475 		n_kc->set_is_valid();
       
   476 	}
       
   477 
       
   478 	if (n_sres->get_is_valid() == eap_boolean_false
       
   479 		|| n_sres->get_buffer_length() < count*SIM_SRES_LENGTH)
       
   480 	{
       
   481 		n_sres->init(count*SIM_SRES_LENGTH);
       
   482 		n_sres->set_is_valid();
       
   483 	}
       
   484 
       
   485 	u8_t *rand = copy_of_n_rands->get_data(copy_of_n_rands->get_data_length());
       
   486 	u8_t *kc = n_kc->get_data(n_kc->get_data_length());
       
   487 	u8_t *sres = n_sres->get_data(n_sres->get_data_length());
       
   488 
       
   489 	for (u32_t ind = 0u; ind < count; ind++)
       
   490 	{
       
   491 		kc_length = SIM_KC_LENGTH;
       
   492 		sres_length = SIM_SRES_LENGTH;
       
   493 		query_SIM_kc_and_sres(
       
   494 			copy_of_imsi.get_data(copy_of_imsi.get_data_length()),
       
   495 			copy_of_imsi.get_data_length(),
       
   496 			rand+(ind*SIM_RAND_LENGTH),
       
   497 			SIM_RAND_LENGTH,
       
   498 			kc+(ind*SIM_KC_LENGTH),
       
   499 			&kc_length,
       
   500 			sres+(ind*SIM_SRES_LENGTH),
       
   501 			&sres_length);
       
   502 	}
       
   503 
       
   504 	n_kc->set_data_length(count*SIM_KC_LENGTH);
       
   505 	n_sres->set_data_length(count*SIM_SRES_LENGTH);
       
   506 
       
   507 	status = get_am_partner()->complete_SIM_kc_sres(
       
   508 		copy_of_n_rands,
       
   509 		n_kc,
       
   510 		n_sres);
       
   511 
       
   512 	delete copy_of_n_rands;
       
   513 
       
   514 	if (status == eap_status_ok)
       
   515 	{
       
   516 		status = eap_status_completed_request;
       
   517 	}
       
   518 
       
   519 	return status;
       
   520 }
       
   521 
       
   522 //--------------------------------------------------
       
   523 
       
   524 //
       
   525 eap_status_e eap_am_type_gsmsim_simulator_c::cancel_SIM_kc_sres_query()
       
   526 {
       
   527 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   528 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   529 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   530 }
       
   531 
       
   532 //--------------------------------------------------
       
   533 
       
   534 //
       
   535 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::generate_encryption_IV(
       
   536 	eap_variable_data_c * const encryption_IV,
       
   537 		const u32_t IV_length)
       
   538 {
       
   539 	encryption_IV->init(IV_length);
       
   540 	encryption_IV->set_is_valid();
       
   541 	encryption_IV->set_data_length(IV_length);
       
   542 
       
   543 	m_am_tools->get_crypto()->add_rand_seed_hw_ticks();
       
   544 
       
   545 	eap_status_e status = m_am_tools->get_crypto()->get_rand_bytes(
       
   546 		encryption_IV->get_data(encryption_IV->get_data_length()),
       
   547 		encryption_IV->get_data_length());
       
   548 
       
   549 	return status;
       
   550 }
       
   551 
       
   552 //--------------------------------------------------
       
   553 
       
   554 //
       
   555 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::query_imsi_from_username(
       
   556 	const eap_boolean_e must_be_synchronous,
       
   557 	const u8_t next_eap_identifier,
       
   558 	const eap_am_network_id_c * const /* network_id */,
       
   559 	const eap_variable_data_c * const /* username */,
       
   560 	eap_variable_data_c * const imsi,
       
   561 	eap_type_gsmsim_identity_type * const type)
       
   562 {
       
   563 	EAP_UNREFERENCED_PARAMETER(must_be_synchronous);
       
   564 	EAP_UNREFERENCED_PARAMETER(next_eap_identifier);
       
   565 	EAP_UNREFERENCED_PARAMETER(type);
       
   566 
       
   567 	// Note this is syncronous call.
       
   568 
       
   569 	imsi->init(SIM_IMSI_LENGTH);
       
   570 	imsi->set_is_valid();
       
   571 	u32_t imsi_length = 0u;
       
   572 	query_SIM_imsi(
       
   573 		imsi->get_data(imsi->get_data_length()),
       
   574 		SIM_IMSI_LENGTH,
       
   575 		&imsi_length);
       
   576 	EAP_ASSERT_ALWAYS(imsi_length == SIM_IMSI_LENGTH);
       
   577 	imsi->set_data_length(imsi_length);
       
   578 	return eap_status_ok;
       
   579 
       
   580 }
       
   581 
       
   582 //--------------------------------------------------
       
   583 
       
   584 //
       
   585 eap_status_e eap_am_type_gsmsim_simulator_c::cancel_imsi_from_username_query()
       
   586 {
       
   587 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   588 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   589 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   590 }
       
   591 
       
   592 //--------------------------------------------------
       
   593 
       
   594 //
       
   595 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::generate_reauthentication_id(
       
   596 	const eap_am_network_id_c * const network_id,
       
   597 	const eap_variable_data_c * const imsi,
       
   598 	eap_variable_data_c * const reauthentication_identity,
       
   599 	const u32_t maximum_reauthentication_identity_length)
       
   600 {
       
   601 	// This is an example.
       
   602 
       
   603 	return generate_pseudonym_id(
       
   604 		network_id,
       
   605 		imsi,
       
   606 		reauthentication_identity,
       
   607 		maximum_reauthentication_identity_length);
       
   608 }
       
   609 
       
   610 //--------------------------------------------------
       
   611 
       
   612 //
       
   613 EAP_FUNC_EXPORT eap_status_e eap_am_type_gsmsim_simulator_c::generate_pseudonym_id(
       
   614 	const eap_am_network_id_c * const /* network_id */,
       
   615 	const eap_variable_data_c * const imsi,
       
   616 	eap_variable_data_c * const pseudonym,
       
   617 	const u32_t maximum_pseudonym_length)
       
   618 {
       
   619 	// This is an example. Pseudonym is mostly same length as IMSI.
       
   620 	eap_variable_data_c tmp_pseudonym(m_am_tools);
       
   621 	tmp_pseudonym.init(imsi->get_data_length());
       
   622 	tmp_pseudonym.set_is_valid();
       
   623 	tmp_pseudonym.set_data_length(imsi->get_data_length());
       
   624 
       
   625 	m_am_tools->get_crypto()->add_rand_seed_hw_ticks();
       
   626 
       
   627 	eap_status_e status = m_am_tools->get_crypto()->get_rand_bytes(
       
   628 		tmp_pseudonym.get_data(tmp_pseudonym.get_data_length()),
       
   629 		tmp_pseudonym.get_data_length());
       
   630 
       
   631 
       
   632 	pseudonym->init(tmp_pseudonym.get_data_length()*2u);
       
   633 	pseudonym->set_is_valid();
       
   634 	pseudonym->set_data_length(imsi->get_data_length()*2u);
       
   635 
       
   636 	u32_t pseudonym_length = pseudonym->get_data_length();
       
   637 	m_am_tools->convert_bytes_to_hex_ascii(
       
   638 		tmp_pseudonym.get_data_offset(0u, tmp_pseudonym.get_data_length()),
       
   639 		tmp_pseudonym.get_data_length(),
       
   640 		pseudonym->get_data_offset(0u, pseudonym->get_data_length()),
       
   641 		&pseudonym_length);
       
   642 
       
   643 	if (pseudonym_length > maximum_pseudonym_length)
       
   644 	{
       
   645 		pseudonym_length = maximum_pseudonym_length;
       
   646 	}
       
   647 	pseudonym->set_data_length(pseudonym_length);
       
   648 
       
   649 	return status;
       
   650 }
       
   651 
       
   652 
       
   653 //--------------------------------------------------
       
   654 
       
   655 EAP_FUNC_EXPORT void eap_am_type_gsmsim_simulator_c::set_is_valid()
       
   656 {
       
   657 	m_is_valid = eap_boolean_true;
       
   658 }
       
   659 
       
   660 //--------------------------------------------------
       
   661 
       
   662 EAP_FUNC_EXPORT eap_boolean_e eap_am_type_gsmsim_simulator_c::get_is_valid()
       
   663 {
       
   664 	return m_is_valid;
       
   665 }
       
   666 
       
   667 //--------------------------------------------------
       
   668 
       
   669 //
       
   670 EAP_FUNC_EXPORT const eap_status_e eap_am_type_gsmsim_simulator_c::type_configure_read(
       
   671 	eap_config_string field,
       
   672 	const u32_t field_length,
       
   673 	eap_variable_data_c * const data)
       
   674 {
       
   675 	// Here configuration data must be read from type spesific database.
       
   676 
       
   677 	// NOTE: This is really just for simulation.
       
   678 	// Read is routed to partner object.
       
   679 	eap_status_e status = m_partner->read_configure(
       
   680 			field,
       
   681 			field_length,
       
   682 			data);
       
   683 	return status;
       
   684 }
       
   685 
       
   686 //--------------------------------------------------
       
   687 
       
   688 //
       
   689 EAP_FUNC_EXPORT const eap_status_e eap_am_type_gsmsim_simulator_c::type_configure_write(
       
   690 	eap_config_string field,
       
   691 	const u32_t field_length,
       
   692 	eap_variable_data_c * const data)
       
   693 {
       
   694 	// Here configuration data must be read from type spesific database.
       
   695 
       
   696 	// NOTE: This is really just for simulation.
       
   697 	// Write is routed to partner object.
       
   698 	eap_status_e status = m_partner->write_configure(
       
   699 			field,
       
   700 			field_length,
       
   701 			data);
       
   702 	return status;
       
   703 }
       
   704 
       
   705 //--------------------------------------------------
       
   706 
       
   707 
       
   708 // End.