eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_crypto_symbian.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 145 
       
    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 // INCLUDES
       
    29 #include <hash.h>
       
    30 #include <random.h>
       
    31 #include <asymmetric.h>
       
    32 #include <symmetric.h>
       
    33 #include <rijndael.h>
       
    34 
       
    35 #include <x509keys.h>
       
    36 #include <asn1dec.h>
       
    37 #include <asn1enc.h>
       
    38 
       
    39 #include "eap_am_crypto_symbian.h"
       
    40 #include "eap_tools.h"
       
    41 #include "eap_am_tools_symbian.h"
       
    42 #include "dss_random.h"
       
    43 
       
    44 #include "eap_am_crypto_sha_256.h"
       
    45 #include "eap_am_crypto_sha1.h"
       
    46 #include "eap_am_crypto_rc4.h"
       
    47 #include "eap_am_crypto_md4.h"
       
    48 
       
    49 #include "eap_am_memory.h"
       
    50 #include "eap_am_assert.h"
       
    51 
       
    52 // LOCAL DATA
       
    53 const u32_t BLOCK_SIZE_3DES_EDE = 8ul;
       
    54 const u32_t MD5_BLOCK_SIZE = 64ul;
       
    55 const u32_t AES_KEY_SIZE = 16ul;
       
    56 const u32_t AES_BLOCK_SIZE = 16ul;
       
    57 
       
    58 //--------------------------------------------------
       
    59 
       
    60 //
       
    61 EAP_FUNC_EXPORT eap_am_crypto_symbian_c::~eap_am_crypto_symbian_c()
       
    62 {
       
    63 }
       
    64 
       
    65 //--------------------------------------------------
       
    66 
       
    67 //
       
    68 EAP_FUNC_EXPORT eap_am_crypto_symbian_c::eap_am_crypto_symbian_c(abs_eap_am_tools_c * const tools)
       
    69 	: m_am_tools(tools)
       
    70 	, m_is_valid(false)
       
    71 {
       
    72 	m_is_valid = true;
       
    73 }
       
    74 
       
    75 //--------------------------------------------------
       
    76 
       
    77 //
       
    78 EAP_FUNC_EXPORT bool eap_am_crypto_symbian_c::get_is_valid() const
       
    79 {
       
    80 	return m_is_valid;
       
    81 }
       
    82 
       
    83 //--------------------------------------------------
       
    84 
       
    85 //
       
    86 EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::set_is_valid()
       
    87 {
       
    88 	m_is_valid = true;
       
    89 }
       
    90 	
       
    91 //--------------------------------------------------
       
    92 
       
    93 //
       
    94 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::configure()
       
    95 {
       
    96 	return eap_status_ok;
       
    97 }
       
    98 
       
    99 //--------------------------------------------------
       
   100 
       
   101 //
       
   102 EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::use_test_random(
       
   103 	const u8_t * const /* seed */,
       
   104 	const u32_t /* seed_length */,
       
   105 	const bool /* does_continuous_seeding_when_true */)
       
   106 {
       
   107 	// This does nothing yet. Later we may need test random generator.
       
   108 }
       
   109 
       
   110 //--------------------------------------------------
       
   111 
       
   112 //
       
   113 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::add_rand_seed(
       
   114 	const u8_t * const /* bytes */, const u32_t /* length */)
       
   115 {
       
   116 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
   117 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   118 	return eap_status_ok;
       
   119 }
       
   120 
       
   121 //--------------------------------------------------
       
   122 
       
   123 //
       
   124 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::add_rand_seed_hw_ticks()
       
   125 {
       
   126 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   127 	u64_t ticks = m_am_tools->get_hardware_ticks();
       
   128 	u8_t entropy_bits = static_cast<u8_t>(ticks & 0xff);
       
   129 	add_rand_seed(
       
   130 		reinterpret_cast<u8_t *>(&entropy_bits),
       
   131 		sizeof(entropy_bits));
       
   132 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   133 	return eap_status_ok;
       
   134 }
       
   135 
       
   136 //--------------------------------------------------
       
   137 
       
   138 //
       
   139 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::get_rand_bytes(
       
   140 	u8_t * const bytes,
       
   141 	const u32_t length)
       
   142 {
       
   143 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   144 
       
   145 	TPtr8 target(bytes, length, length);
       
   146 
       
   147 	TRandom::Random(target);
       
   148 
       
   149 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   150 	return eap_status_ok;
       
   151 }
       
   152 
       
   153 
       
   154 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::generate_diffie_hellman_keys(
       
   155 	eap_variable_data_c * const own_private_dh_key,
       
   156 	eap_variable_data_c * const own_public_dh_key,
       
   157 	const u8_t * const prime,
       
   158 	const u32_t prime_length,
       
   159 	const u8_t * const group_generator,
       
   160 	const u32_t group_generator_length)
       
   161 {
       
   162 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
   163 	eap_status_e status = eap_status_ok;
       
   164 	TRAPD(err, generate_diffie_hellman_keysL(
       
   165 		own_private_dh_key,
       
   166 		own_public_dh_key,
       
   167 		prime,
       
   168 		prime_length,
       
   169 		group_generator,
       
   170 		group_generator_length));
       
   171 	if (err != KErrNone)
       
   172 	{
       
   173 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
   174 	} 
       
   175 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   176 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   177 }
       
   178 
       
   179 //--------------------------------------------------
       
   180 
       
   181 void eap_am_crypto_symbian_c::generate_diffie_hellman_keysL(
       
   182 	eap_variable_data_c * const own_private_dh_key,
       
   183 	eap_variable_data_c * const own_public_dh_key,
       
   184 	const u8_t * const prime,
       
   185 	const u32_t prime_length,
       
   186 	const u8_t * const group_generator,
       
   187 	const u32_t group_generator_length)
       
   188 {
       
   189 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   190 	
       
   191 	eap_status_e status;
       
   192 
       
   193 	TPtrC8 _prime(prime, prime_length);
       
   194 	TPtrC8 _generator(group_generator, group_generator_length);
       
   195 	
       
   196 	RInteger N = RInteger::NewL(_prime);
       
   197 	CleanupStack::PushL(N);
       
   198 	
       
   199 	RInteger G = RInteger::NewL(_generator);
       
   200 	CleanupStack::PushL(G);	
       
   201 	
       
   202 	CDHKeyPair* dh_key = CDHKeyPair::NewL(N, G);
       
   203 	CleanupStack::Pop(&G); // N, G
       
   204 	CleanupStack::Pop(&N); // N, G
       
   205 
       
   206 	CleanupStack::PushL(dh_key);
       
   207 	
       
   208 	const CDHPublicKey& publicKey = dh_key->PublicKey();
       
   209 	
       
   210 	const TInteger& X = publicKey.X();
       
   211 	
       
   212 	HBufC8* p = X.BufferLC();
       
   213 	// Copy the public key
       
   214 	status = own_public_dh_key->set_copy_of_buffer(p->Des().Ptr(), p->Length());
       
   215 	if (status != eap_status_ok)
       
   216 	{
       
   217 		User::Leave(KErrNoMemory);
       
   218 	}
       
   219 	CleanupStack::PopAndDestroy(p); 
       
   220 
       
   221 
       
   222 	const CDHPrivateKey& privateKey = dh_key->PrivateKey();
       
   223 	
       
   224 	const TInteger& x = privateKey.x();
       
   225 	
       
   226 	p = x.BufferLC();
       
   227 	// Copy the private key
       
   228 	status = own_private_dh_key->set_copy_of_buffer(p->Des().Ptr(), p->Length());
       
   229 	if (status != eap_status_ok)
       
   230 	{
       
   231 		User::Leave(KErrNoMemory);
       
   232 	}
       
   233 	CleanupStack::PopAndDestroy(p); 
       
   234 
       
   235 	CleanupStack::PopAndDestroy(dh_key);			
       
   236 
       
   237 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("own_public_dh_key"),
       
   238 		own_public_dh_key->get_data(own_public_dh_key->get_data_length()),
       
   239 		own_public_dh_key->get_data_length()));
       
   240 
       
   241 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("own_private_dh_key is hidden in Symbian.\n")));
       
   242 	
       
   243 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   244 }
       
   245 
       
   246 //--------------------------------------------------
       
   247 
       
   248 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::generate_g_power_to_xy(
       
   249 	const eap_variable_data_c * const own_private_dh_key,
       
   250 	const eap_variable_data_c * const peer_public_dh_key,
       
   251 	eap_variable_data_c * const shared_dh_key,
       
   252 	const u8_t * const prime,
       
   253 	const u32_t prime_length,
       
   254 	const u8_t * const group_generator,
       
   255 	const u32_t group_generator_length)
       
   256 {
       
   257 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
   258 	eap_status_e status = eap_status_ok;
       
   259 	TRAPD(err, generate_g_power_to_xyL(
       
   260 		own_private_dh_key,
       
   261 		peer_public_dh_key,
       
   262 		shared_dh_key,
       
   263 		prime,
       
   264 		prime_length,
       
   265 		group_generator,
       
   266 		group_generator_length));
       
   267 	if (err != KErrNone)
       
   268 	{
       
   269 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
   270 	} 
       
   271 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   272 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   273 }
       
   274 
       
   275 //--------------------------------------------------
       
   276 
       
   277 void eap_am_crypto_symbian_c::generate_g_power_to_xyL(
       
   278 	const eap_variable_data_c * const own_private_dh_key,
       
   279 	const eap_variable_data_c * const peer_public_dh_key,
       
   280 	eap_variable_data_c * const shared_dh_key,
       
   281 	const u8_t * const prime,
       
   282 	const u32_t prime_length,
       
   283 	const u8_t * const group_generator,
       
   284 	const u32_t group_generator_length)
       
   285 {
       
   286 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   287 
       
   288 	eap_status_e status(eap_status_ok);
       
   289 
       
   290 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("peer_public_dh_key"),
       
   291 		peer_public_dh_key->get_data(peer_public_dh_key->get_data_length()),
       
   292 		peer_public_dh_key->get_data_length()));
       
   293 
       
   294 	
       
   295 	// PUBLIC KEY
       
   296 	TPtrC8 peer_key(
       
   297 		peer_public_dh_key->get_data(peer_public_dh_key->get_data_length()), 
       
   298 		peer_public_dh_key->get_data_length());
       
   299 	if (peer_key.Ptr() == 0)
       
   300 	{
       
   301 		User::Leave(KErrArgument);
       
   302 	}
       
   303 
       
   304 	RInteger Y = RInteger::NewL(peer_key);
       
   305 	CleanupStack::PushL(Y); 
       
   306 	
       
   307 	
       
   308 	TPtrC8 peer_prime(
       
   309 		prime, 
       
   310 		prime_length);
       
   311 	if (peer_prime.Ptr() == 0)
       
   312 	{
       
   313 		User::Leave(KErrArgument);
       
   314 	}
       
   315 
       
   316 	RInteger N = RInteger::NewL(peer_prime);
       
   317 	CleanupStack::PushL(N); 
       
   318 
       
   319 	TPtrC8 peer_generator(
       
   320 		group_generator, 
       
   321 		group_generator_length);
       
   322 	if (peer_prime.Ptr() == 0)
       
   323 	{
       
   324 		User::Leave(KErrArgument);
       
   325 	}
       
   326 	
       
   327 	RInteger G = RInteger::NewL(peer_generator);
       
   328 	CleanupStack::PushL(G); 
       
   329 
       
   330 	CDHPublicKey* publicKey = CDHPublicKey::NewL(N, G, Y);
       
   331 	CleanupStack::Pop(&G); // The parameters are freed by CDHPublicKey
       
   332 	CleanupStack::Pop(&N); // The parameters are freed by CDHPublicKey
       
   333 	CleanupStack::Pop(&Y); // The parameters are freed by CDHPublicKey
       
   334 	CleanupStack::PushL(publicKey);
       
   335 
       
   336 	// PRIVATE KEY
       
   337 	RInteger Npriv = RInteger::NewL(peer_prime);
       
   338 	CleanupStack::PushL(Npriv);
       
   339 	
       
   340 	RInteger Gpriv = RInteger::NewL(peer_generator); // !
       
   341 	CleanupStack::PushL(Gpriv);
       
   342 	
       
   343 	TPtrC8 private_key(
       
   344 		own_private_dh_key->get_data(own_private_dh_key->get_data_length()), 
       
   345 		own_private_dh_key->get_data_length());
       
   346 	if (private_key.Ptr() == 0)
       
   347 	{
       
   348 		User::Leave(KErrArgument);
       
   349 	}
       
   350 	RInteger x = RInteger::NewL(private_key);
       
   351 	CleanupStack::PushL(x); 
       
   352 	
       
   353 	CDHPrivateKey* privateKey = CDHPrivateKey::NewL(Npriv, Gpriv, x);
       
   354 	CleanupStack::Pop(&x);
       
   355 	CleanupStack::Pop(&Gpriv);
       
   356 	CleanupStack::Pop(&Npriv);
       
   357 	CleanupStack::PushL(privateKey);
       
   358 	
       
   359 	CDH* dh = CDH::NewL(*privateKey);
       
   360 	CleanupStack::PushL(dh);
       
   361 
       
   362 	// Have to do const_cast so that the object can be pushed... strange...
       
   363 	HBufC8* p = const_cast<HBufC8*>(dh->AgreeL(*publicKey));
       
   364 	CleanupStack::PushL(p);
       
   365 
       
   366 	// Copy the shared key
       
   367 	status = shared_dh_key->set_copy_of_buffer(const_cast<HBufC8*>(p)->Des().Ptr(), p->Length());
       
   368 	if (status != eap_status_ok)
       
   369 	{		
       
   370 		User::Leave(KErrNoMemory);
       
   371 	}
       
   372 
       
   373 	CleanupStack::PopAndDestroy(p);  // p, dh, publicKey, privateKey
       
   374 	CleanupStack::PopAndDestroy(dh);  // p, dh, publicKey, privateKey
       
   375 	CleanupStack::PopAndDestroy(privateKey);  // p, dh, publicKey, privateKey
       
   376 	CleanupStack::PopAndDestroy(publicKey);  // p, dh, publicKey, privateKey
       
   377 	
       
   378 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("     shared_dh_key"),
       
   379 		shared_dh_key->get_data(shared_dh_key->get_data_length()),
       
   380 		shared_dh_key->get_data_length()));
       
   381 }
       
   382 
       
   383 //--------------------------------------------------
       
   384 
       
   385 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dh_cleanup(
       
   386 		const eap_variable_data_c * const /*dh_context*/)
       
   387 {	
       
   388 	return eap_status_ok;
       
   389 }
       
   390 
       
   391 //--------------------------------------------------
       
   392 
       
   393 
       
   394 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha_256_digest_length(
       
   395 	eap_variable_data_c * const sha_256_context)
       
   396 {
       
   397 	eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   398 		sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   399 	if (sha_256 == 0
       
   400 		|| sha_256->get_is_valid() == false)
       
   401 	{
       
   402 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   403 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
   404 	}
       
   405 
       
   406 	return sha_256->get_digest_length();
       
   407 }
       
   408 
       
   409 //--------------------------------------------------
       
   410 
       
   411 
       
   412 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha_256_block_size(
       
   413 	eap_variable_data_c * const sha_256_context)
       
   414 {
       
   415 	eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   416 		sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   417 	if (sha_256 == 0
       
   418 		|| sha_256->get_is_valid() == false)
       
   419 	{
       
   420 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   421 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
   422 	}
       
   423 
       
   424 	return sha_256->get_block_size();
       
   425 }
       
   426 
       
   427 //--------------------------------------------------
       
   428 
       
   429 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_init(
       
   430 	eap_variable_data_c * const sha_256_context)
       
   431 {
       
   432 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   433 
       
   434 	eap_am_crypto_sha_256_c * sha_256 = 0;
       
   435 
       
   436 	if (sha_256_context->get_is_valid_data() == true)
       
   437 	{
       
   438 		sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   439 			sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   440 		if (sha_256 == 0
       
   441 			|| sha_256->get_is_valid() == false)
       
   442 		{
       
   443 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   444 		}
       
   445 	}
       
   446 
       
   447 	eap_status_e status = eap_status_process_general_error;
       
   448 
       
   449 	if (sha_256 == 0)
       
   450 	{
       
   451 		sha_256 = new eap_am_crypto_sha_256_c(m_am_tools);
       
   452 		if (sha_256 == 0
       
   453 			|| sha_256->get_is_valid() == false)
       
   454 		{
       
   455 			delete sha_256;
       
   456 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   457 		}
       
   458 
       
   459 		status = sha_256_context->set_buffer(sha_256, sizeof(sha_256), false, true);
       
   460 		if (status != eap_status_ok)
       
   461 		{
       
   462 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   463 		}
       
   464 	}
       
   465 
       
   466 	status = sha_256->hash_init();
       
   467 	if (status != eap_status_ok)
       
   468 	{
       
   469 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   470 	}
       
   471 
       
   472 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   473 }
       
   474 
       
   475 //--------------------------------------------------
       
   476 
       
   477 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_update(
       
   478 	eap_variable_data_c * const sha_256_context,
       
   479 	const u8_t * const data,
       
   480 	const u32_t data_length)
       
   481 {
       
   482 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   483 
       
   484 	EAP_ASSERT(sha_256_context->get_is_valid_data() == true);
       
   485 
       
   486 	eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   487 		sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   488 	if (sha_256 == 0
       
   489 		|| sha_256->get_is_valid() == false)
       
   490 	{
       
   491 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   492 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   493 	}
       
   494 
       
   495 	eap_status_e status = sha_256->hash_update(
       
   496 		data,
       
   497 		data_length);
       
   498 	if (status != eap_status_ok)
       
   499 	{
       
   500 		EAP_TRACE_DEBUG(
       
   501 			m_am_tools,
       
   502 			TRACE_FLAGS_DEFAULT,
       
   503 			(EAPL("ERROR: eap_am_crypto_symbian_c::sha_256_update(), failed status = %d\n"),
       
   504 			 status));
       
   505 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   506 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   507 	}
       
   508 
       
   509 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   510 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   511 }
       
   512 
       
   513 //--------------------------------------------------
       
   514 
       
   515 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_final(
       
   516 	eap_variable_data_c * const sha_256_context,
       
   517 	u8_t * const message_digest,
       
   518 	u32_t *md_length_or_null)
       
   519 {
       
   520 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   521 
       
   522 	EAP_ASSERT(sha_256_context->get_is_valid_data() == true);
       
   523 
       
   524 	eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   525 		sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   526 	if (sha_256 == 0
       
   527 		|| sha_256->get_is_valid() == false)
       
   528 	{
       
   529 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   530 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   531 	}
       
   532 
       
   533 	eap_status_e status = sha_256->hash_final(
       
   534 		message_digest,
       
   535 		md_length_or_null);
       
   536 	if (status != eap_status_ok)
       
   537 	{
       
   538 		EAP_TRACE_DEBUG(
       
   539 			m_am_tools,
       
   540 			TRACE_FLAGS_DEFAULT,
       
   541 			(EAPL("ERROR: eap_am_crypto_symbian_c::sha_256_final(), failed status = %d\n"),
       
   542 			 status));
       
   543 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   544 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   545 	}
       
   546 
       
   547 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   548 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   549 }
       
   550 
       
   551 //--------------------------------------------------
       
   552 
       
   553 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_cleanup(
       
   554 	eap_variable_data_c * const sha_256_context)
       
   555 {
       
   556 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   557 
       
   558 	EAP_ASSERT(sha_256_context->get_is_valid_data() == true);
       
   559 
       
   560 	eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   561 		sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   562 	if (sha_256 == 0
       
   563 		|| sha_256->get_is_valid() == false)
       
   564 	{
       
   565 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   566 	}
       
   567 
       
   568 	delete sha_256;
       
   569 
       
   570 	sha_256_context->reset();
       
   571 
       
   572 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   573 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   574 }
       
   575 
       
   576 //--------------------------------------------------
       
   577 
       
   578 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_copy_context(
       
   579 	eap_variable_data_c * const copied_sha_256_context,
       
   580 	const eap_variable_data_c * const original_sha_256_context)
       
   581 {
       
   582 	eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
       
   583 		original_sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
       
   584 	if (sha_256 == 0
       
   585 		|| sha_256->get_is_valid() == false)
       
   586 	{
       
   587 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   588 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   589 	}
       
   590 
       
   591 	eap_am_crypto_sha_256_c * const sha_256_copy = sha_256->copy();
       
   592 	if (sha_256_copy == 0
       
   593 		|| sha_256_copy->get_is_valid() == false)
       
   594 	{
       
   595 		delete sha_256_copy;
       
   596 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   597 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   598 	}
       
   599 
       
   600 	eap_status_e status = copied_sha_256_context->set_buffer(sha_256_copy, sizeof(sha_256_copy), false, true);
       
   601 
       
   602 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   603 }
       
   604 
       
   605 //--------------------------------------------------
       
   606 
       
   607 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha1_digest_length(
       
   608 	eap_variable_data_c * const sha1_context)
       
   609 {
       
   610 	eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   611 		sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   612 
       
   613 	if (sha1 == 0
       
   614 		|| sha1->get_is_valid() == false)
       
   615 	{
       
   616 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
   617 	}
       
   618 
       
   619 	return sha1->get_digest_length();
       
   620 }
       
   621 
       
   622 //--------------------------------------------------
       
   623 
       
   624 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha1_block_size(
       
   625 	eap_variable_data_c * const sha1_context)
       
   626 {
       
   627 	eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   628 		sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   629 
       
   630 	if (sha1 == 0
       
   631 		|| sha1->get_is_valid() == false)
       
   632 	{
       
   633 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
   634 	}
       
   635 
       
   636 	return sha1->get_block_size();
       
   637 }
       
   638 
       
   639 //--------------------------------------------------
       
   640 
       
   641 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_init(
       
   642 	eap_variable_data_c * const sha1_context)
       
   643 {
       
   644 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   645 	eap_status_e status = eap_status_process_general_error;
       
   646 
       
   647 	eap_am_crypto_sha1_c * sha1 = 0;
       
   648 
       
   649 	if (sha1_context->get_is_valid_data() == true)
       
   650 	{
       
   651 		sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   652 			sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   653 
       
   654 		if (sha1 != 0
       
   655 			&& sha1->get_is_valid() == false)
       
   656 		{
       
   657 			// Delete old invalid context.
       
   658 			status = sha1_cleanup(sha1_context);
       
   659 			if (status != eap_status_ok)
       
   660 			{
       
   661 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   662 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   663 			}
       
   664 
       
   665 			// Next we allocate new context.
       
   666 			sha1 = 0;
       
   667 		}
       
   668 	
       
   669 	}
       
   670 	else
       
   671 	{
       
   672 		// There are no context.
       
   673 		// We will allocate a new one.
       
   674 	}
       
   675 
       
   676 	if (sha1 == 0)
       
   677 	{
       
   678 		sha1 = new eap_am_crypto_sha1_c(m_am_tools);
       
   679 		if (sha1 == 0
       
   680 			|| sha1->get_is_valid() == false)
       
   681 		{
       
   682 			delete sha1;
       
   683 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   684 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   685 		}
       
   686 
       
   687 		status = sha1_context->set_buffer(sha1, sizeof(*sha1), false, true);
       
   688 		if (status != eap_status_ok)
       
   689 		{
       
   690 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   691 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   692 		}
       
   693 	}
       
   694 
       
   695 	status = sha1->hash_init();
       
   696 	if (status != eap_status_ok)
       
   697 	{
       
   698 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   699 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   700 	}
       
   701 
       
   702 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   703 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   704 }
       
   705 
       
   706 //--------------------------------------------------
       
   707 
       
   708 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_update(
       
   709 	eap_variable_data_c * const sha1_context,
       
   710 	const u8_t * const data,
       
   711 	const u32_t data_length)
       
   712 {
       
   713 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   714 
       
   715 	eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   716 		sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   717 
       
   718 	if (sha1 == 0
       
   719 		|| sha1->get_is_valid() == false)
       
   720 	{
       
   721 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   722 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   723 	}
       
   724 
       
   725 	eap_status_e status = sha1->hash_update(
       
   726 		data,
       
   727 		data_length);
       
   728 
       
   729 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   730 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   731 }
       
   732 
       
   733 //--------------------------------------------------
       
   734 
       
   735 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_final(
       
   736 	eap_variable_data_c * const sha1_context,
       
   737 	u8_t * const message_digest,
       
   738 	u32_t *md_length_or_null)
       
   739 {
       
   740 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   741 
       
   742 	eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   743 		sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   744 
       
   745 	if (sha1 == 0
       
   746 		|| sha1->get_is_valid() == false)
       
   747 	{
       
   748 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   749 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   750 	}
       
   751 
       
   752     eap_status_e status = sha1->hash_final(
       
   753 		message_digest,
       
   754 		md_length_or_null);
       
   755 
       
   756 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   757 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   758 }
       
   759 
       
   760 //--------------------------------------------------
       
   761 
       
   762 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_cleanup(
       
   763 	eap_variable_data_c * const sha1_context)
       
   764 {
       
   765 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   766 
       
   767 	EAP_ASSERT(sha1_context != 0);
       
   768 	EAP_ASSERT(sha1_context->get_is_valid() == true);
       
   769 	if (sha1_context == 0
       
   770 		|| sha1_context->get_is_valid_data() == false)
       
   771 	{
       
   772 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   773 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   774 	}
       
   775 
       
   776 	eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   777 		sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   778 
       
   779 	delete sha1;
       
   780 
       
   781 	sha1_context->reset();
       
   782 	
       
   783 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   784 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   785 }
       
   786 
       
   787 //--------------------------------------------------
       
   788 
       
   789 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_copy_context(
       
   790 	eap_variable_data_c * const copied_sha1_context,
       
   791 	const eap_variable_data_c * const original_sha1_context)
       
   792 {
       
   793 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   794 	
       
   795 	eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
       
   796 		original_sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
       
   797 
       
   798 	if (sha1 == 0
       
   799 		|| sha1->get_is_valid() == false)
       
   800 	{
       
   801 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   802 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   803 	}
       
   804 
       
   805 	eap_am_crypto_sha1_c * const sha1_copy = sha1->copy();
       
   806 
       
   807 	if (sha1_copy == 0
       
   808 		|| sha1_copy->get_is_valid() == false)
       
   809 	{
       
   810 		delete sha1_copy;
       
   811 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   812 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   813 	}
       
   814 
       
   815 	eap_status_e status = copied_sha1_context->set_buffer(sha1_copy, sizeof(*sha1_copy), false, true);
       
   816 
       
   817 	if (status != eap_status_ok)
       
   818 	{
       
   819 		delete sha1_copy;
       
   820 	}
       
   821 	
       
   822 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   823 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   824 }
       
   825 
       
   826 //--------------------------------------------------
       
   827 
       
   828 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::aes_key_length()
       
   829 {
       
   830 	return AES_KEY_SIZE;
       
   831 }
       
   832 
       
   833 //--------------------------------------------------
       
   834 
       
   835 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::aes_block_size()
       
   836 {
       
   837 	return AES_BLOCK_SIZE;
       
   838 }
       
   839 
       
   840 
       
   841 //--------------------------------------------------
       
   842 
       
   843 // NOTE ::dss_pseudo_random is implemented in am/common/DSS_random/dss_random.cpp.
       
   844 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dss_pseudo_random(
       
   845 	u8_t *out,
       
   846 	u32_t out_length,
       
   847 	u8_t *xkey,
       
   848 	u32_t xkey_length)
       
   849 {
       
   850 	eap_status_e status = ::dss_pseudo_random(m_am_tools, out, out_length, xkey, xkey_length);
       
   851 	return status;
       
   852 }
       
   853 
       
   854 //--------------------------------------------------
       
   855 
       
   856 EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::open_crypto_memory_leaks()
       
   857 {
       
   858 }
       
   859 
       
   860 //--------------------------------------------------
       
   861 
       
   862 EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::close_crypto_memory_leaks()
       
   863 {
       
   864 }
       
   865 
       
   866 //--------------------------------------------------
       
   867 
       
   868 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_set_key(eap_variable_data_c * const rc4_context, 
       
   869 																const eap_variable_data_c * const key)
       
   870 {
       
   871 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   872 
       
   873 	if (key == 0
       
   874 		|| key->get_is_valid_data() == false
       
   875 		|| key->get_data_length() == 0
       
   876 		|| rc4_context == 0)
       
   877 	{
       
   878 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   879 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   880 	}
       
   881 
       
   882 	eap_am_crypto_rc4_c * const rc4 = new eap_am_crypto_rc4_c(m_am_tools);
       
   883 	if (rc4 == 0
       
   884 		|| rc4->get_is_valid() == false)
       
   885 	{
       
   886 		delete rc4;
       
   887 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   888 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   889 	}
       
   890 
       
   891 	eap_status_e status = rc4->set_key(key);
       
   892 	if (status != eap_status_ok)
       
   893 	{
       
   894 		delete rc4;
       
   895 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   896 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   897 	}
       
   898 
       
   899 	if (rc4_context->get_is_valid_data() == true)
       
   900 	{
       
   901 		status = rc4_cleanup(rc4_context);
       
   902 		if (status != eap_status_ok)
       
   903 		{
       
   904 			delete rc4;
       
   905 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   906 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   907 		}
       
   908 	}
       
   909 
       
   910 	status = rc4_context->set_buffer(rc4, sizeof(*rc4), false, true);
       
   911 	if (status != eap_status_ok)
       
   912 	{
       
   913 		delete rc4;		
       
   914 	}
       
   915 
       
   916 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   917 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   918 }
       
   919 
       
   920 //--------------------------------------------------
       
   921 
       
   922 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_cleanup(
       
   923 	eap_variable_data_c * const rc4_context)
       
   924 {
       
   925 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   926 	
       
   927 	EAP_ASSERT(rc4_context != 0);
       
   928 	EAP_ASSERT(rc4_context->get_is_valid() == true);
       
   929 	if (rc4_context == 0
       
   930 		|| rc4_context->get_is_valid_data() == false)
       
   931 	{
       
   932 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   933 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   934 	}
       
   935 
       
   936 	eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
       
   937 		rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
       
   938 	
       
   939 	delete rc4;
       
   940 
       
   941 	rc4_context->reset();
       
   942 
       
   943 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   944 	return eap_status_ok;
       
   945 }
       
   946 
       
   947 //--------------------------------------------------
       
   948 
       
   949 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_encrypt(
       
   950 	const eap_variable_data_c * const rc4_context,
       
   951 	void * const data_in_out,
       
   952 	const u32_t data_length)
       
   953 {	
       
   954 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   955 
       
   956 	EAP_ASSERT(rc4_context != 0);
       
   957 	EAP_ASSERT(rc4_context->get_is_valid() == true);
       
   958 	if (rc4_context == 0
       
   959 		|| rc4_context->get_is_valid_data() == false)
       
   960 	{
       
   961 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   962 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   963 	}
       
   964 
       
   965 	eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
       
   966 		rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
       
   967 	
       
   968 	if (rc4 == 0
       
   969 		|| rc4->get_is_valid() == false)
       
   970 	{
       
   971 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   972 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
   973 	}
       
   974 
       
   975 	eap_status_e status = rc4->encrypt_data(
       
   976 		data_in_out,
       
   977 		data_in_out,
       
   978 		data_length);
       
   979 
       
   980 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   981 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   982 }
       
   983 
       
   984 //--------------------------------------------------
       
   985 
       
   986 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_encrypt(
       
   987 	const eap_variable_data_c * const rc4_context,
       
   988 	const void * const data_in, 
       
   989 	void * const data_out,
       
   990 	const u32_t data_length)
       
   991 {	
       
   992 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
   993 
       
   994 	EAP_ASSERT(rc4_context != 0);
       
   995 	EAP_ASSERT(rc4_context->get_is_valid() == true);
       
   996 	if (rc4_context == 0
       
   997 		|| rc4_context->get_is_valid_data() == false)
       
   998 	{
       
   999 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1000 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1001 	}
       
  1002 
       
  1003 	eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
       
  1004 		rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
       
  1005 
       
  1006 	if (rc4 == 0
       
  1007 		|| rc4->get_is_valid() == false)
       
  1008 	{
       
  1009 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1010 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  1011 	}
       
  1012 
       
  1013 	eap_status_e status = rc4->encrypt_data(
       
  1014 		data_in,
       
  1015 		data_out,
       
  1016 		data_length);
       
  1017 
       
  1018 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1019 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1020 }
       
  1021 
       
  1022 //--------------------------------------------------
       
  1023 
       
  1024 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_decrypt(
       
  1025 	const eap_variable_data_c * const rc4_context,
       
  1026 	void * const data_in_out,
       
  1027 	const u32_t data_length)
       
  1028 {	
       
  1029 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1030 
       
  1031 	EAP_ASSERT(rc4_context != 0);
       
  1032 	EAP_ASSERT(rc4_context->get_is_valid() == true);
       
  1033 	if (rc4_context == 0
       
  1034 		|| rc4_context->get_is_valid_data() == false)
       
  1035 	{
       
  1036 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1037 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1038 	}
       
  1039 
       
  1040 	eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
       
  1041 		rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
       
  1042 
       
  1043 	if (rc4 == 0
       
  1044 		|| rc4->get_is_valid() == false)
       
  1045 	{
       
  1046 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1047 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  1048 	}
       
  1049 
       
  1050 	eap_status_e status = rc4->decrypt_data(
       
  1051 		data_in_out,
       
  1052 		data_in_out,
       
  1053 		data_length);
       
  1054 
       
  1055 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1056 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1057 }
       
  1058 
       
  1059 //--------------------------------------------------
       
  1060 
       
  1061 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_decrypt(
       
  1062 	const eap_variable_data_c * const rc4_context,
       
  1063 	const void * const data_in, 
       
  1064 	void * const data_out,
       
  1065 	const u32_t data_length)
       
  1066 {		
       
  1067 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1068 
       
  1069 	EAP_ASSERT(rc4_context != 0);
       
  1070 	EAP_ASSERT(rc4_context->get_is_valid() == true);
       
  1071 	if (rc4_context == 0
       
  1072 		|| rc4_context->get_is_valid_data() == false)
       
  1073 	{
       
  1074 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1075 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1076 	}
       
  1077 
       
  1078 	eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
       
  1079 		rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
       
  1080 
       
  1081 	if (rc4 == 0
       
  1082 		|| rc4->get_is_valid() == false)
       
  1083 	{
       
  1084 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1085 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  1086 	}
       
  1087 
       
  1088 	eap_status_e status = rc4->decrypt_data(
       
  1089 		data_in,
       
  1090 		data_out,
       
  1091 		data_length);
       
  1092 
       
  1093 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1094 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1095 }
       
  1096 
       
  1097 //--------------------------------------------------
       
  1098 
       
  1099 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_init(
       
  1100 		eap_variable_data_c * const rsa_context)
       
  1101 {
       
  1102 	EAP_UNREFERENCED_PARAMETER(rsa_context);
       
  1103 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1104 
       
  1105 	eap_status_e status = rsa_context->init(0);
       
  1106 	if (status != eap_status_ok)
       
  1107 	{
       
  1108 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1109 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1110 	}
       
  1111 	
       
  1112 	rsa_context->set_is_valid(); 		
       
  1113 	
       
  1114 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1115 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1116 }
       
  1117 
       
  1118 //--------------------------------------------------
       
  1119 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_public_key(
       
  1120 	eap_variable_data_c * const rsa_context,
       
  1121 	const eap_variable_data_c * const public_rsa_key,
       
  1122 	const eap_variable_data_c * const input_data,
       
  1123 	eap_variable_data_c * const output_data)
       
  1124 {
       
  1125 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1126 	
       
  1127 	EAP_TRACE_DEBUG(
       
  1128 		m_am_tools,
       
  1129 		TRACE_FLAGS_DEFAULT,
       
  1130 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_key(), begins.\n")));
       
  1131 
       
  1132 	eap_status_e status = eap_status_ok;
       
  1133 	
       
  1134 	TRAPD(err, rsa_encrypt_with_public_keyL(
       
  1135 		rsa_context,
       
  1136 		public_rsa_key,
       
  1137 		input_data,
       
  1138 		output_data));
       
  1139 	if (err != KErrNone)
       
  1140 	{
       
  1141 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
  1142 		EAP_TRACE_DEBUG(
       
  1143 			m_am_tools,
       
  1144 			TRACE_FLAGS_ERROR,
       
  1145 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_key() failed, status %d.\n"),
       
  1146 			status));
       
  1147 	} 
       
  1148 	
       
  1149 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1150 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1151 }
       
  1152 
       
  1153 
       
  1154 void eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(
       
  1155 	eap_variable_data_c * const /*rsa_context*/,
       
  1156 	const eap_variable_data_c * const public_rsa_key,
       
  1157 	const eap_variable_data_c * const input_data,
       
  1158 	eap_variable_data_c * const output_data)
       
  1159 {
       
  1160 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1161 	
       
  1162 	EAP_TRACE_DEBUG(
       
  1163 		m_am_tools,
       
  1164 		TRACE_FLAGS_DEFAULT,
       
  1165 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), begins.\n")));
       
  1166 
       
  1167 	TPtrC8 ptr(
       
  1168 		public_rsa_key->get_data(public_rsa_key->get_data_length()), 
       
  1169 		public_rsa_key->get_data_length());
       
  1170 	if (ptr.Ptr() == 0)
       
  1171 	{
       
  1172 		EAP_TRACE_DEBUG(
       
  1173 			m_am_tools,
       
  1174 			TRACE_FLAGS_ERROR,
       
  1175 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, public_rsa_key is invalid.\n")));
       
  1176 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1177 		User::Leave(KErrArgument);
       
  1178 	}	
       
  1179 	// The public_rsa_key is ASN.1 encoded.
       
  1180 	// SEQUENCE {
       
  1181 	//	  INTEGER modulus
       
  1182 	//	  INTEGER exponent
       
  1183 	// }
       
  1184 	//
       
  1185 	//
       
  1186 	TASN1DecSequence seq;
       
  1187 	TASN1DecInteger asn1;
       
  1188 	TASN1DecGeneric* gen;
       
  1189 
       
  1190 	EAP_TRACE_DEBUG(
       
  1191 		m_am_tools,
       
  1192 		TRACE_FLAGS_DEFAULT,
       
  1193 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLC().\n")));
       
  1194 
       
  1195 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  1196 	TInt pos(0);
       
  1197 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  1198 	
       
  1199 	EAP_TRACE_DEBUG(
       
  1200 		m_am_tools,
       
  1201 		TRACE_FLAGS_DEFAULT,
       
  1202 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLongL().\n")));
       
  1203 
       
  1204 	gen = arrayPtr->At(0);
       
  1205 	if (gen == 0)
       
  1206 	{
       
  1207 		EAP_TRACE_DEBUG(
       
  1208 			m_am_tools,
       
  1209 			TRACE_FLAGS_ERROR,
       
  1210 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
       
  1211 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1212 		User::Leave(KErrArgument);
       
  1213 	}
       
  1214 
       
  1215 	TPtrC8 m = gen->Encoding();			
       
  1216 	if (m.Length() == 0)
       
  1217 	{
       
  1218 		EAP_TRACE_DEBUG(
       
  1219 			m_am_tools,
       
  1220 			TRACE_FLAGS_ERROR,
       
  1221 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
       
  1222 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1223 		User::Leave(KErrArgument);
       
  1224 	}	
       
  1225 	pos = 0;
       
  1226 	RInteger modulus = asn1.DecodeDERLongL(m, pos);
       
  1227 	CleanupStack::PushL(modulus);
       
  1228 
       
  1229 	EAP_TRACE_DEBUG(
       
  1230 		m_am_tools,
       
  1231 		TRACE_FLAGS_DEFAULT,
       
  1232 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLongL().\n")));
       
  1233 
       
  1234 	gen = arrayPtr->At(1);
       
  1235 	if (gen == 0)
       
  1236 	{
       
  1237 		EAP_TRACE_DEBUG(
       
  1238 			m_am_tools,
       
  1239 			TRACE_FLAGS_ERROR,
       
  1240 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
       
  1241 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1242 		User::Leave(KErrArgument);
       
  1243 	}
       
  1244 
       
  1245 	TPtrC8 e = gen->Encoding();			
       
  1246 	if (e.Length() == 0)
       
  1247 	{
       
  1248 		EAP_TRACE_DEBUG(
       
  1249 			m_am_tools,
       
  1250 			TRACE_FLAGS_ERROR,
       
  1251 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
       
  1252 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1253 		User::Leave(KErrArgument);
       
  1254 	}	
       
  1255 	pos = 0;
       
  1256 	RInteger exponent = asn1.DecodeDERLongL(e, pos);
       
  1257 	CleanupStack::PushL(exponent);
       
  1258 
       
  1259 	TPtrC8 input(
       
  1260 		input_data->get_data(input_data->get_data_length()), 
       
  1261 		input_data->get_data_length());
       
  1262 	if (input.Ptr() == 0)
       
  1263 	{
       
  1264 		EAP_TRACE_DEBUG(
       
  1265 			m_am_tools,
       
  1266 			TRACE_FLAGS_ERROR,
       
  1267 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, input_data is invalid.\n")));
       
  1268 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1269 		User::Leave(KErrArgument);
       
  1270 	}
       
  1271 
       
  1272 	// The length of the ciphertext in RSA is the next multiple of block size. 
       
  1273 	TUint output_data_length = ((input_data->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount();
       
  1274 	eap_status_e status = output_data->init(output_data_length);
       
  1275 	if (status != eap_status_ok)
       
  1276 	{
       
  1277 		EAP_TRACE_DEBUG(
       
  1278 			m_am_tools,
       
  1279 			TRACE_FLAGS_ERROR,
       
  1280 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, output_data is invalid, status %d.\n"),
       
  1281 			status));
       
  1282 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1283 		User::Leave(KErrNoMemory);
       
  1284 	}
       
  1285 
       
  1286 	output_data->set_is_valid();
       
  1287 	output_data->set_data_length(output_data_length);
       
  1288 	TPtr8 output(
       
  1289 		output_data->get_data(output_data->get_data_length()), 
       
  1290 		output_data->get_data_length());
       
  1291 	if (output.Ptr() == 0)
       
  1292 	{
       
  1293 		EAP_TRACE_DEBUG(
       
  1294 			m_am_tools,
       
  1295 			TRACE_FLAGS_ERROR,
       
  1296 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, output_data is invalid.\n")));
       
  1297 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1298 		User::Leave(KErrArgument);
       
  1299 	}
       
  1300 	
       
  1301 	CRSAPublicKey* public_key = CRSAPublicKey::NewL(modulus, exponent);
       
  1302 	CleanupStack::Pop(&exponent); // Exponent, modulus are freed by CRSAPublicKey
       
  1303 	CleanupStack::Pop(&modulus); // Exponent, modulus are freed by CRSAPublicKey
       
  1304 	CleanupStack::PushL(public_key);
       
  1305 
       
  1306 	CRSAPKCS1v15Encryptor* rsa_encryptor = CRSAPKCS1v15Encryptor::NewL(*public_key);
       
  1307 	CleanupStack::PushL(rsa_encryptor);
       
  1308 
       
  1309 	EAP_TRACE_DEBUG(
       
  1310 		m_am_tools,
       
  1311 		TRACE_FLAGS_DEFAULT,
       
  1312 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before EncryptL().\n")));
       
  1313 
       
  1314 	rsa_encryptor->EncryptL(input, output);
       
  1315 	
       
  1316 	output_data->set_data_length(output.Length());
       
  1317 
       
  1318 	CleanupStack::PopAndDestroy(rsa_encryptor);
       
  1319 	CleanupStack::PopAndDestroy(public_key);
       
  1320 	CleanupStack::PopAndDestroy(arrayPtr);
       
  1321 
       
  1322 	EAP_TRACE_DEBUG(
       
  1323 		m_am_tools,
       
  1324 		TRACE_FLAGS_DEFAULT,
       
  1325 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), OK.\n")));
       
  1326 
       
  1327 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1328 }
       
  1329 
       
  1330 //--------------------------------------------------
       
  1331 
       
  1332 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_public_key(
       
  1333 	eap_variable_data_c * const /*rsa_context*/,
       
  1334 	const eap_variable_data_c * const /*public_rsa_key*/,
       
  1335 	const eap_variable_data_c * const /*input_data*/,
       
  1336 	eap_variable_data_c * const /*output_data*/)
       
  1337 {
       
  1338 	EAP_TRACE_DEBUG(
       
  1339 		m_am_tools,
       
  1340 		TRACE_FLAGS_DEFAULT,
       
  1341 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_key(), begins.\n")));
       
  1342 
       
  1343 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  1344 }
       
  1345 
       
  1346 void eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(
       
  1347 	eap_variable_data_c * const /*rsa_context*/,
       
  1348 	const eap_variable_data_c * const public_rsa_key,
       
  1349 	const eap_variable_data_c * const input_data,
       
  1350 	eap_variable_data_c * const output_data)
       
  1351 {
       
  1352 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
  1353 
       
  1354 	EAP_TRACE_DEBUG(
       
  1355 		m_am_tools,
       
  1356 		TRACE_FLAGS_DEFAULT,
       
  1357 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), begins.\n")));
       
  1358 
       
  1359 	TPtrC8 ptr(
       
  1360 		public_rsa_key->get_data(public_rsa_key->get_data_length()), 
       
  1361 		public_rsa_key->get_data_length());
       
  1362 	if (ptr.Ptr() == 0)
       
  1363 	{
       
  1364 		EAP_TRACE_DEBUG(
       
  1365 			m_am_tools,
       
  1366 			TRACE_FLAGS_ERROR,
       
  1367 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, public_rsa_key is invalid.\n")));
       
  1368 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1369 		User::Leave(KErrArgument);
       
  1370 	}	
       
  1371 	// The public_rsa_key is ASN.1 encoded.
       
  1372 	// SEQUENCE {
       
  1373 	//	  INTEGER modulus
       
  1374 	//	  INTEGER exponent
       
  1375 	// }
       
  1376 	//
       
  1377 	//
       
  1378 	TASN1DecSequence seq;
       
  1379 	TASN1DecInteger asn1;
       
  1380 	TASN1DecGeneric* gen;
       
  1381 	
       
  1382 	EAP_TRACE_DEBUG(
       
  1383 		m_am_tools,
       
  1384 		TRACE_FLAGS_DEFAULT,
       
  1385 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLC().\n")));
       
  1386 
       
  1387 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  1388 	TInt pos(0);
       
  1389 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  1390 	
       
  1391 	EAP_TRACE_DEBUG(
       
  1392 		m_am_tools,
       
  1393 		TRACE_FLAGS_DEFAULT,
       
  1394 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLongL().\n")));
       
  1395 
       
  1396 	gen = arrayPtr->At(0);
       
  1397 	if (gen == 0)
       
  1398 	{
       
  1399 		EAP_TRACE_DEBUG(
       
  1400 			m_am_tools,
       
  1401 			TRACE_FLAGS_ERROR,
       
  1402 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
       
  1403 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1404 		User::Leave(KErrArgument);
       
  1405 	}
       
  1406 
       
  1407 	TPtrC8 m = gen->Encoding();			
       
  1408 	if (m.Length() == 0)
       
  1409 	{
       
  1410 		EAP_TRACE_DEBUG(
       
  1411 			m_am_tools,
       
  1412 			TRACE_FLAGS_ERROR,
       
  1413 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
       
  1414 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1415 		User::Leave(KErrArgument);
       
  1416 	}	
       
  1417 	pos = 0;
       
  1418 	RInteger modulus = asn1.DecodeDERLongL(m, pos);
       
  1419 	CleanupStack::PushL(modulus);
       
  1420 
       
  1421 	EAP_TRACE_DEBUG(
       
  1422 		m_am_tools,
       
  1423 		TRACE_FLAGS_DEFAULT,
       
  1424 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLongL().\n")));
       
  1425 
       
  1426 	gen = arrayPtr->At(1);
       
  1427 	if (gen == 0)
       
  1428 	{
       
  1429 		EAP_TRACE_DEBUG(
       
  1430 			m_am_tools,
       
  1431 			TRACE_FLAGS_ERROR,
       
  1432 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
       
  1433 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1434 		User::Leave(KErrArgument);
       
  1435 	}
       
  1436 
       
  1437 	TPtrC8 e = gen->Encoding();			
       
  1438 	if (e.Length() == 0)
       
  1439 	{
       
  1440 		EAP_TRACE_DEBUG(
       
  1441 			m_am_tools,
       
  1442 			TRACE_FLAGS_ERROR,
       
  1443 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
       
  1444 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1445 		User::Leave(KErrArgument);
       
  1446 	}	
       
  1447 	pos = 0;
       
  1448 	RInteger exponent = asn1.DecodeDERLongL(e, pos);
       
  1449 	CleanupStack::PushL(exponent);
       
  1450 
       
  1451 	TPtrC8 input(
       
  1452 		input_data->get_data(input_data->get_data_length()), 
       
  1453 		input_data->get_data_length());
       
  1454 	if (input.Ptr() == 0)
       
  1455 	{
       
  1456 		EAP_TRACE_DEBUG(
       
  1457 			m_am_tools,
       
  1458 			TRACE_FLAGS_ERROR,
       
  1459 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, input_data is invalid.\n")));
       
  1460 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1461 		User::Leave(KErrArgument);
       
  1462 	}
       
  1463 
       
  1464 	// The length of the plaintext is equal or less than the ciphertext length.
       
  1465 	TUint output_data_length = input_data->get_data_length();
       
  1466 	eap_status_e status = output_data->init(output_data_length);
       
  1467 	if (status != eap_status_ok)
       
  1468 	{
       
  1469 		EAP_TRACE_DEBUG(
       
  1470 			m_am_tools,
       
  1471 			TRACE_FLAGS_ERROR,
       
  1472 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, output_data is invalid, status %d.\n"),
       
  1473 			status));
       
  1474 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1475 		User::Leave(KErrNoMemory);
       
  1476 	}
       
  1477 	output_data->set_is_valid();
       
  1478 	output_data->set_data_length(output_data_length);
       
  1479 
       
  1480 	TPtr8 output(
       
  1481 		output_data->get_data(output_data->get_data_length()), 
       
  1482 		output_data->get_data_length());
       
  1483 	if (output.Ptr() == 0)
       
  1484 	{
       
  1485 		EAP_TRACE_DEBUG(
       
  1486 			m_am_tools,
       
  1487 			TRACE_FLAGS_ERROR,
       
  1488 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, output_data is invalid.\n")));
       
  1489 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1490 		User::Leave(KErrArgument);
       
  1491 	}
       
  1492 
       
  1493 	// The key is actually public key but the class still needs to be CRSAPrivateKey for decryption
       
  1494 	CleanupStack::Pop(&exponent); // Next class frees the integers
       
  1495 	CleanupStack::Pop(&modulus); // Next class frees the integers
       
  1496 	
       
  1497 	CRSAPrivateKeyStandard* public_key = CRSAPrivateKeyStandard::NewL(modulus, exponent);
       
  1498 	CleanupStack::PushL(public_key);
       
  1499 
       
  1500 	CRSAPKCS1v15Decryptor* rsa_decryptor = CRSAPKCS1v15Decryptor::NewL(*public_key);
       
  1501 	CleanupStack::PushL(rsa_decryptor);
       
  1502 
       
  1503 	EAP_TRACE_DEBUG(
       
  1504 		m_am_tools,
       
  1505 		TRACE_FLAGS_DEFAULT,
       
  1506 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecryptL().\n")));
       
  1507 
       
  1508 	rsa_decryptor->DecryptL(input, output);
       
  1509 	
       
  1510 	// Set the real data length
       
  1511 	output_data->set_data_length(output.Length());
       
  1512 
       
  1513 	EAP_TRACE_DEBUG(
       
  1514 		m_am_tools,
       
  1515 		TRACE_FLAGS_DEFAULT,
       
  1516 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), OK.\n")));
       
  1517 
       
  1518 	CleanupStack::PopAndDestroy(rsa_decryptor);
       
  1519 	CleanupStack::PopAndDestroy(public_key);
       
  1520 	CleanupStack::PopAndDestroy(arrayPtr);
       
  1521 
       
  1522 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1523 }
       
  1524 
       
  1525 //--------------------------------------------------
       
  1526 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_private_key(
       
  1527 	eap_variable_data_c * const /*rsa_context*/,
       
  1528 	const eap_variable_data_c * const /*private_rsa_key*/,
       
  1529 	const eap_variable_data_c * const /*input_data*/,
       
  1530 	eap_variable_data_c * const /*output_data*/)
       
  1531 {
       
  1532 	EAP_TRACE_DEBUG(
       
  1533 		m_am_tools,
       
  1534 		TRACE_FLAGS_DEFAULT,
       
  1535 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_key(), begins.\n")));
       
  1536 
       
  1537 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  1538 }
       
  1539 
       
  1540 
       
  1541 void eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(
       
  1542 	eap_variable_data_c * const /*rsa_context*/,
       
  1543 	const eap_variable_data_c * const private_rsa_key,
       
  1544 	const eap_variable_data_c * const input_data,
       
  1545 	eap_variable_data_c * const output_data)
       
  1546 {
       
  1547 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1548 
       
  1549 	EAP_TRACE_DEBUG(
       
  1550 		m_am_tools,
       
  1551 		TRACE_FLAGS_DEFAULT,
       
  1552 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), begins.\n")));
       
  1553 
       
  1554 	TPtrC8 ptr(
       
  1555 		private_rsa_key->get_data(private_rsa_key->get_data_length()), 
       
  1556 		private_rsa_key->get_data_length());
       
  1557 	if (ptr.Ptr() == 0)
       
  1558 	{
       
  1559 		EAP_TRACE_DEBUG(
       
  1560 			m_am_tools,
       
  1561 			TRACE_FLAGS_ERROR,
       
  1562 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, private_rsa_key is invalid.\n")));
       
  1563 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1564 		User::Leave(KErrArgument);
       
  1565 	}	
       
  1566 	// The private_rsa_key is ASN.1 encoded.
       
  1567 	// SEQUENCE {
       
  1568 	//	  INTEGER modulus
       
  1569 	//	  INTEGER public_exponent
       
  1570 	//	  INTEGER private_exponent
       
  1571 	//    ...
       
  1572 	// }
       
  1573 	//
       
  1574 	//
       
  1575 	TASN1DecSequence seq;
       
  1576 	TASN1DecInteger asn1;
       
  1577 	TASN1DecGeneric* gen;
       
  1578 	
       
  1579 	RInteger modulus;
       
  1580 	RInteger private_exponent;
       
  1581 
       
  1582 	EAP_TRACE_DEBUG(
       
  1583 		m_am_tools,
       
  1584 		TRACE_FLAGS_DEFAULT,
       
  1585 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLC().\n")));
       
  1586 
       
  1587 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  1588 	TInt pos(0);
       
  1589 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  1590 	
       
  1591 	EAP_TRACE_DEBUG(
       
  1592 		m_am_tools,
       
  1593 		TRACE_FLAGS_DEFAULT,
       
  1594 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLongL().\n")));
       
  1595 
       
  1596 	gen = arrayPtr->At(1);
       
  1597 	if (gen == 0)
       
  1598 	{
       
  1599 		EAP_TRACE_DEBUG(
       
  1600 			m_am_tools,
       
  1601 			TRACE_FLAGS_ERROR,
       
  1602 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
       
  1603 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1604 		User::Leave(KErrArgument);
       
  1605 	}
       
  1606 
       
  1607 	TPtrC8 m = gen->Encoding();			
       
  1608 	if (m.Length() == 0)
       
  1609 	{
       
  1610 		EAP_TRACE_DEBUG(
       
  1611 			m_am_tools,
       
  1612 			TRACE_FLAGS_ERROR,
       
  1613 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
       
  1614 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1615 		User::Leave(KErrArgument);
       
  1616 	}
       
  1617 	pos = 0;
       
  1618 	modulus = asn1.DecodeDERLongL(m, pos);
       
  1619 	CleanupStack::PushL(modulus);
       
  1620 
       
  1621 	EAP_TRACE_DEBUG(
       
  1622 		m_am_tools,
       
  1623 		TRACE_FLAGS_DEFAULT,
       
  1624 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLongL().\n")));
       
  1625 
       
  1626 	gen = arrayPtr->At(3);
       
  1627 	if (gen == 0)
       
  1628 	{
       
  1629 		EAP_TRACE_DEBUG(
       
  1630 			m_am_tools,
       
  1631 			TRACE_FLAGS_ERROR,
       
  1632 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
       
  1633 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1634 		User::Leave(KErrArgument);
       
  1635 	}
       
  1636 
       
  1637 	TPtrC8 priv_e = gen->Encoding();			
       
  1638 	if (priv_e.Length() == 0)
       
  1639 	{
       
  1640 		EAP_TRACE_DEBUG(
       
  1641 			m_am_tools,
       
  1642 			TRACE_FLAGS_ERROR,
       
  1643 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
       
  1644 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1645 		User::Leave(KErrArgument);
       
  1646 	}
       
  1647 	pos = 0;
       
  1648 	private_exponent = asn1.DecodeDERLongL(priv_e, pos);
       
  1649 	CleanupStack::PushL(private_exponent);
       
  1650 
       
  1651 	TPtrC8 input(
       
  1652 		input_data->get_data(input_data->get_data_length()), 
       
  1653 		input_data->get_data_length());
       
  1654 	if (input.Ptr() == 0)
       
  1655 	{
       
  1656 		EAP_TRACE_DEBUG(
       
  1657 			m_am_tools,
       
  1658 			TRACE_FLAGS_ERROR,
       
  1659 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, input_data is invalid.\n")));
       
  1660 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1661 		User::Leave(KErrArgument);
       
  1662 	}
       
  1663 
       
  1664 	// The length of the ciphertext in RSA is the next multiple of block size. 
       
  1665 	TUint output_data_length = ((input_data->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount();
       
  1666 	eap_status_e status = output_data->init(output_data_length);
       
  1667 	if (status != eap_status_ok)
       
  1668 	{
       
  1669 		EAP_TRACE_DEBUG(
       
  1670 			m_am_tools,
       
  1671 			TRACE_FLAGS_ERROR,
       
  1672 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, output_data is invalid, status %d.\n"),
       
  1673 			status));
       
  1674 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1675 		User::Leave(KErrNoMemory);
       
  1676 	}
       
  1677 	output_data->set_is_valid();
       
  1678 	output_data->set_data_length(output_data_length);
       
  1679 
       
  1680 	TPtr8 output(
       
  1681 		output_data->get_data(output_data->get_data_length()), 
       
  1682 		output_data->get_data_length());
       
  1683 	if (output.Ptr() == 0)
       
  1684 	{
       
  1685 		EAP_TRACE_DEBUG(
       
  1686 			m_am_tools,
       
  1687 			TRACE_FLAGS_ERROR,
       
  1688 			(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, output_data is invalid.\n")));
       
  1689 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1690 		User::Leave(KErrArgument);
       
  1691 	}
       
  1692 
       
  1693 	CleanupStack::Pop(&private_exponent); // private exponent & modulus are freed by the next class
       
  1694 	CleanupStack::Pop(&modulus); // private exponent & modulus are freed by the next class
       
  1695 	CRSAPublicKey* private_key = CRSAPublicKey::NewL(modulus, private_exponent);
       
  1696 	CleanupStack::PushL(private_key);
       
  1697 
       
  1698 	CRSAPKCS1v15Encryptor* rsa_encryptor = CRSAPKCS1v15Encryptor::NewL(*private_key);
       
  1699 	CleanupStack::PushL(rsa_encryptor);
       
  1700 
       
  1701 	EAP_TRACE_DEBUG(
       
  1702 		m_am_tools,
       
  1703 		TRACE_FLAGS_DEFAULT,
       
  1704 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before EncryptL().\n")));
       
  1705 
       
  1706 	rsa_encryptor->EncryptL(input, output);
       
  1707 	
       
  1708 	output_data->set_data_length(output.Length());
       
  1709 
       
  1710 	CleanupStack::PopAndDestroy(rsa_encryptor);
       
  1711 	CleanupStack::PopAndDestroy(private_key);
       
  1712 	CleanupStack::PopAndDestroy(arrayPtr);
       
  1713 
       
  1714 	EAP_TRACE_DEBUG(
       
  1715 		m_am_tools,
       
  1716 		TRACE_FLAGS_DEFAULT,
       
  1717 		(EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), OK.\n")));
       
  1718 
       
  1719 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1720 }
       
  1721 
       
  1722 //--------------------------------------------------
       
  1723 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_private_key(
       
  1724 	eap_variable_data_c * const rsa_context,
       
  1725 	const eap_variable_data_c * const private_rsa_key,
       
  1726 	const eap_variable_data_c * const input_data,
       
  1727 	eap_variable_data_c * const output_data)
       
  1728 {
       
  1729 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1730 
       
  1731 	EAP_TRACE_DEBUG(
       
  1732 		m_am_tools,
       
  1733 		TRACE_FLAGS_DEFAULT,
       
  1734 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_key(), begins.\n")));
       
  1735 
       
  1736 	eap_status_e status = eap_status_ok;
       
  1737 	TRAPD(err, rsa_decrypt_with_private_keyL(
       
  1738 		rsa_context,
       
  1739 		private_rsa_key,
       
  1740 		input_data,
       
  1741 		output_data));
       
  1742 	if (err != KErrNone)
       
  1743 	{
       
  1744 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
  1745 		EAP_TRACE_DEBUG(
       
  1746 			m_am_tools,
       
  1747 			TRACE_FLAGS_ERROR,
       
  1748 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_key() failed, err %d, status %d.\n"),
       
  1749 			err,
       
  1750 			status));
       
  1751 	} 
       
  1752 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1753 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1754 }
       
  1755 
       
  1756 
       
  1757 void eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(
       
  1758 	eap_variable_data_c * const /*rsa_context*/,
       
  1759 	const eap_variable_data_c * const private_rsa_key,
       
  1760 	const eap_variable_data_c * const input_data,
       
  1761 	eap_variable_data_c * const output_data)
       
  1762 {
       
  1763 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1764 
       
  1765 	EAP_TRACE_DEBUG(
       
  1766 		m_am_tools,
       
  1767 		TRACE_FLAGS_DEFAULT,
       
  1768 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), begins.\n")));
       
  1769 
       
  1770 	TPtrC8 ptr(
       
  1771 		private_rsa_key->get_data(private_rsa_key->get_data_length()), 
       
  1772 		private_rsa_key->get_data_length());
       
  1773 	if (ptr.Ptr() == 0)
       
  1774 	{
       
  1775 		EAP_TRACE_DEBUG(
       
  1776 			m_am_tools,
       
  1777 			TRACE_FLAGS_ERROR,
       
  1778 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, private_rsa_key is invalid.\n")));
       
  1779 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1780 		User::Leave(KErrArgument);
       
  1781 	}	
       
  1782 	// The private_rsa_key is ASN.1 encoded.
       
  1783 	// SEQUENCE {
       
  1784 	//	  INTEGER modulus
       
  1785 	//	  INTEGER public_exponent
       
  1786 	//	  INTEGER private_exponent
       
  1787 	//    ...
       
  1788 	// }
       
  1789 	//
       
  1790 	//
       
  1791 	TASN1DecSequence seq;
       
  1792 	TASN1DecInteger asn1;
       
  1793 	TASN1DecGeneric* gen;
       
  1794 	RInteger modulus;
       
  1795 	RInteger private_exponent;
       
  1796 	
       
  1797 	EAP_TRACE_DEBUG(
       
  1798 		m_am_tools,
       
  1799 		TRACE_FLAGS_DEFAULT,
       
  1800 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLC().\n")));
       
  1801 
       
  1802 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  1803 	TInt pos(0);
       
  1804 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  1805 	
       
  1806 	EAP_TRACE_DEBUG(
       
  1807 		m_am_tools,
       
  1808 		TRACE_FLAGS_DEFAULT,
       
  1809 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLongL().\n")));
       
  1810 
       
  1811 	gen = arrayPtr->At(1);
       
  1812 	if (gen == 0)
       
  1813 	{
       
  1814 		EAP_TRACE_DEBUG(
       
  1815 			m_am_tools,
       
  1816 			TRACE_FLAGS_ERROR,
       
  1817 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
       
  1818 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1819 		User::Leave(KErrArgument);
       
  1820 	}
       
  1821 
       
  1822 	TPtrC8 m = gen->Encoding();			
       
  1823 	if (m.Length() == 0)
       
  1824 	{
       
  1825 		EAP_TRACE_DEBUG(
       
  1826 			m_am_tools,
       
  1827 			TRACE_FLAGS_ERROR,
       
  1828 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
       
  1829 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1830 		User::Leave(KErrArgument);
       
  1831 	}	
       
  1832 	pos = 0;
       
  1833 	modulus = asn1.DecodeDERLongL(m, pos);
       
  1834 	CleanupStack::PushL(modulus);
       
  1835 
       
  1836 	EAP_TRACE_DEBUG(
       
  1837 		m_am_tools,
       
  1838 		TRACE_FLAGS_DEFAULT,
       
  1839 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLongL().\n")));
       
  1840 
       
  1841 	gen = arrayPtr->At(3);
       
  1842 	if (gen == 0)
       
  1843 	{
       
  1844 		EAP_TRACE_DEBUG(
       
  1845 			m_am_tools,
       
  1846 			TRACE_FLAGS_ERROR,
       
  1847 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
       
  1848 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1849 		User::Leave(KErrArgument);
       
  1850 	}
       
  1851 
       
  1852 	TPtrC8 priv_e = gen->Encoding();			
       
  1853 	if (priv_e.Length() == 0)
       
  1854 	{
       
  1855 		EAP_TRACE_DEBUG(
       
  1856 			m_am_tools,
       
  1857 			TRACE_FLAGS_ERROR,
       
  1858 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
       
  1859 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1860 		User::Leave(KErrArgument);
       
  1861 	}
       
  1862 	pos = 0;
       
  1863 	private_exponent = asn1.DecodeDERLongL(priv_e, pos);
       
  1864 	CleanupStack::PushL(private_exponent);
       
  1865 
       
  1866 	TPtrC8 input(
       
  1867 		input_data->get_data(input_data->get_data_length()), 
       
  1868 		input_data->get_data_length());
       
  1869 	if (input.Ptr() == 0)
       
  1870 	{
       
  1871 		EAP_TRACE_DEBUG(
       
  1872 			m_am_tools,
       
  1873 			TRACE_FLAGS_ERROR,
       
  1874 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, input_data is invalid.\n")));
       
  1875 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1876 		User::Leave(KErrArgument);
       
  1877 	}
       
  1878 	// The length of the plaintext is equal or less than the ciphertext length.
       
  1879 	TUint output_data_length = input_data->get_data_length();
       
  1880 	eap_status_e status = output_data->init(output_data_length);
       
  1881 	if (status != eap_status_ok)
       
  1882 	{
       
  1883 		EAP_TRACE_DEBUG(
       
  1884 			m_am_tools,
       
  1885 			TRACE_FLAGS_ERROR,
       
  1886 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, output_data is invalid, status %d.\n"),
       
  1887 			status));
       
  1888 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1889 		User::Leave(KErrNoMemory);
       
  1890 	}
       
  1891 	output_data->set_is_valid();
       
  1892 	output_data->set_data_length(output_data_length);
       
  1893 
       
  1894 	TPtr8 output(
       
  1895 		output_data->get_data(output_data->get_data_length()), 
       
  1896 		output_data->get_data_length());
       
  1897 	if (output.Ptr() == 0)
       
  1898 	{
       
  1899 		EAP_TRACE_DEBUG(
       
  1900 			m_am_tools,
       
  1901 			TRACE_FLAGS_ERROR,
       
  1902 			(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, output_data is invalid.\n")));
       
  1903 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1904 		User::Leave(KErrArgument);
       
  1905 	}	
       
  1906 
       
  1907 	CRSAPrivateKey* private_key = CRSAPrivateKeyStandard::NewL(modulus, private_exponent);
       
  1908 
       
  1909 	CleanupStack::Pop(&private_exponent); // modulus & private_exponent are freed CRSAPrivateKey
       
  1910 	CleanupStack::Pop(&modulus); // modulus & private_exponent are freed CRSAPrivateKey
       
  1911 	CleanupStack::PushL(private_key);
       
  1912 
       
  1913 	CRSAPKCS1v15Decryptor* rsa_decryptor = CRSAPKCS1v15Decryptor::NewL(*private_key);
       
  1914 	CleanupStack::PushL(rsa_decryptor);
       
  1915 
       
  1916 	EAP_TRACE_DEBUG(
       
  1917 		m_am_tools,
       
  1918 		TRACE_FLAGS_DEFAULT,
       
  1919 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecryptL().\n")));
       
  1920 
       
  1921 	rsa_decryptor->DecryptL(input, output);
       
  1922 	
       
  1923 	// Now set the correct length
       
  1924 	output_data->set_data_length(output.Length());
       
  1925 
       
  1926 	CleanupStack::PopAndDestroy(rsa_decryptor);
       
  1927 	CleanupStack::PopAndDestroy(private_key);
       
  1928 	CleanupStack::PopAndDestroy(arrayPtr);
       
  1929 
       
  1930 	EAP_TRACE_DEBUG(
       
  1931 		m_am_tools,
       
  1932 		TRACE_FLAGS_DEFAULT,
       
  1933 		(EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), OK.\n")));
       
  1934 
       
  1935 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1936 }
       
  1937 
       
  1938 //--------------------------------------------------
       
  1939 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_sign(
       
  1940 	eap_variable_data_c * const rsa_context,
       
  1941 	const eap_variable_data_c * const private_rsa_key,
       
  1942 	const eap_variable_data_c * const hash,
       
  1943 	eap_variable_data_c * const signed_hash)
       
  1944 {
       
  1945 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
  1946 
       
  1947 	EAP_TRACE_DEBUG(
       
  1948 		m_am_tools,
       
  1949 		TRACE_FLAGS_DEFAULT,
       
  1950 		(EAPL("eap_am_crypto_symbian_c::rsa_sign(), begins.\n")));
       
  1951 
       
  1952 	eap_status_e status = eap_status_ok;
       
  1953 
       
  1954 	TRAPD(err, rsa_signL(
       
  1955 		rsa_context,
       
  1956 		private_rsa_key,
       
  1957 		hash,
       
  1958 		signed_hash));
       
  1959 	if (err != KErrNone)
       
  1960 	{
       
  1961 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
  1962 		EAP_TRACE_DEBUG(
       
  1963 			m_am_tools,
       
  1964 			TRACE_FLAGS_ERROR,
       
  1965 			(EAPL("eap_am_crypto_symbian_c::rsa_sign() failed, err %d, status %d.\n"),
       
  1966 			err,
       
  1967 			status));
       
  1968 	} 
       
  1969 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1970 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1971 }
       
  1972 
       
  1973 eap_status_e eap_am_crypto_symbian_c::rsa_signL(
       
  1974 	eap_variable_data_c * const /*rsa_context*/,
       
  1975 	const eap_variable_data_c * const private_rsa_key,
       
  1976 	const eap_variable_data_c * const hash,
       
  1977 	eap_variable_data_c * const signed_hash)
       
  1978 {
       
  1979 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1980 
       
  1981 	EAP_TRACE_DEBUG(
       
  1982 		m_am_tools,
       
  1983 		TRACE_FLAGS_DEFAULT,
       
  1984 		(EAPL("eap_am_crypto_symbian_c::rsa_signL(), begins.\n")));
       
  1985 
       
  1986 	TPtrC8 ptr(
       
  1987 		private_rsa_key->get_data(private_rsa_key->get_data_length()), 
       
  1988 		private_rsa_key->get_data_length());
       
  1989 	if (ptr.Ptr() == 0)
       
  1990 	{
       
  1991 		EAP_TRACE_DEBUG(
       
  1992 			m_am_tools,
       
  1993 			TRACE_FLAGS_ERROR,
       
  1994 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, private_rsa_key is invalid.\n")));
       
  1995 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  1996 		User::Leave(KErrArgument);
       
  1997 	}	
       
  1998 	// The private_rsa_key is ASN.1 encoded.
       
  1999 	// SEQUENCE {
       
  2000 	//	  INTEGER modulus
       
  2001 	//	  INTEGER public_exponent
       
  2002 	//	  INTEGER private_exponent
       
  2003 	//    ...
       
  2004 	// }
       
  2005 	//
       
  2006 	//
       
  2007 	TASN1DecSequence seq;
       
  2008 	TASN1DecInteger asn1;
       
  2009 	TASN1DecGeneric* gen;
       
  2010 	
       
  2011 	RInteger modulus;
       
  2012 	RInteger private_exponent;
       
  2013 
       
  2014 	EAP_TRACE_DEBUG(
       
  2015 		m_am_tools,
       
  2016 		TRACE_FLAGS_DEFAULT,
       
  2017 		(EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLC().\n")));
       
  2018 
       
  2019 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  2020 	TInt pos(0);
       
  2021 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  2022 	
       
  2023 	EAP_TRACE_DEBUG(
       
  2024 		m_am_tools,
       
  2025 		TRACE_FLAGS_DEFAULT,
       
  2026 		(EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLongL().\n")));
       
  2027 
       
  2028 	gen = arrayPtr->At(1);
       
  2029 	if (gen == 0)
       
  2030 	{
       
  2031 		EAP_TRACE_DEBUG(
       
  2032 			m_am_tools,
       
  2033 			TRACE_FLAGS_ERROR,
       
  2034 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
       
  2035 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2036 		User::Leave(KErrArgument);
       
  2037 	}
       
  2038 
       
  2039 	TPtrC8 m = gen->Encoding();			
       
  2040 	if (m.Length() == 0)
       
  2041 	{
       
  2042 		EAP_TRACE_DEBUG(
       
  2043 			m_am_tools,
       
  2044 			TRACE_FLAGS_ERROR,
       
  2045 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
       
  2046 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2047 		User::Leave(KErrArgument);
       
  2048 	}
       
  2049 
       
  2050 	pos = 0;
       
  2051 	modulus = asn1.DecodeDERLongL(m, pos);
       
  2052 	CleanupStack::PushL(modulus);
       
  2053 
       
  2054 	EAP_TRACE_DEBUG(
       
  2055 		m_am_tools,
       
  2056 		TRACE_FLAGS_DEFAULT,
       
  2057 		(EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLongL().\n")));
       
  2058 
       
  2059 	gen = arrayPtr->At(3);
       
  2060 	if (gen == 0)
       
  2061 	{
       
  2062 		EAP_TRACE_DEBUG(
       
  2063 			m_am_tools,
       
  2064 			TRACE_FLAGS_ERROR,
       
  2065 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
       
  2066 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2067 		User::Leave(KErrArgument);
       
  2068 	}
       
  2069 
       
  2070 	TPtrC8 priv_e = gen->Encoding();			
       
  2071 	if (priv_e.Length() == 0)
       
  2072 	{
       
  2073 		EAP_TRACE_DEBUG(
       
  2074 			m_am_tools,
       
  2075 			TRACE_FLAGS_ERROR,
       
  2076 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
       
  2077 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2078 		User::Leave(KErrArgument);
       
  2079 	}
       
  2080 	pos = 0;
       
  2081 	private_exponent = asn1.DecodeDERLongL(priv_e, pos);
       
  2082 	CleanupStack::PushL(private_exponent);
       
  2083 
       
  2084 	TPtrC8 input(
       
  2085 		hash->get_data(hash->get_data_length()), 
       
  2086 		hash->get_data_length());
       
  2087 	if (input.Ptr() == 0)
       
  2088 	{
       
  2089 		EAP_TRACE_DEBUG(
       
  2090 			m_am_tools,
       
  2091 			TRACE_FLAGS_ERROR,
       
  2092 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, hash is invalid.\n")));
       
  2093 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2094 		User::Leave(KErrArgument);
       
  2095 	}
       
  2096 
       
  2097 	// The length of the ciphertext in RSA is the next multiple of block size. 
       
  2098 	TUint output_data_length = ((hash->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount();
       
  2099 
       
  2100 	eap_status_e status = signed_hash->init(output_data_length);
       
  2101 	if (status != eap_status_ok)
       
  2102 	{
       
  2103 		EAP_TRACE_DEBUG(
       
  2104 			m_am_tools,
       
  2105 			TRACE_FLAGS_ERROR,
       
  2106 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, signed_hash is invalid, status %d.\n"),
       
  2107 			status));
       
  2108 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2109 		User::Leave(KErrNoMemory);
       
  2110 	}
       
  2111 	signed_hash->set_is_valid();
       
  2112 	signed_hash->set_data_length(output_data_length);
       
  2113 
       
  2114 	TPtr8 output(
       
  2115 		signed_hash->get_data(signed_hash->get_data_length()), 
       
  2116 		signed_hash->get_data_length());
       
  2117 	if (output.Ptr() == 0)
       
  2118 	{
       
  2119 		EAP_TRACE_DEBUG(
       
  2120 			m_am_tools,
       
  2121 			TRACE_FLAGS_ERROR,
       
  2122 			(EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, signed_hash is invalid.\n")));
       
  2123 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2124 		User::Leave(KErrArgument);
       
  2125 	}
       
  2126 
       
  2127 	CleanupStack::Pop(&private_exponent); // private exponent & modulus are freed by the next class
       
  2128 	CleanupStack::Pop(&modulus); // private exponent & modulus are freed by the next class
       
  2129 	CRSAPrivateKeyStandard* private_key = CRSAPrivateKeyStandard::NewL(modulus, private_exponent);
       
  2130 	CleanupStack::PushL(private_key);
       
  2131 
       
  2132 	CRSAPKCS1v15Signer* rsa_signer = CRSAPKCS1v15Signer::NewL(*private_key);	
       
  2133 	CleanupStack::PushL(rsa_signer);
       
  2134 
       
  2135 	EAP_TRACE_DEBUG(
       
  2136 		m_am_tools,
       
  2137 		TRACE_FLAGS_DEFAULT,
       
  2138 		(EAPL("eap_am_crypto_symbian_c::rsa_signL(), before SignL().\n")));
       
  2139 
       
  2140 	const CRSASignature* signature = rsa_signer->SignL(input);
       
  2141 	const TInteger& sig = signature->S();
       
  2142 
       
  2143 	HBufC8* buf = sig.BufferLC();
       
  2144 
       
  2145 	output.Copy(*buf);
       
  2146 	signed_hash->set_data_length(output.Length());
       
  2147 	
       
  2148 	CleanupStack::PopAndDestroy(buf);
       
  2149 	CleanupStack::PopAndDestroy(rsa_signer);
       
  2150 	CleanupStack::PopAndDestroy(private_key);
       
  2151 	CleanupStack::PopAndDestroy(arrayPtr);
       
  2152 
       
  2153 	EAP_TRACE_DEBUG(
       
  2154 		m_am_tools,
       
  2155 		TRACE_FLAGS_DEFAULT,
       
  2156 		(EAPL("eap_am_crypto_symbian_c::rsa_signL(), OK.\n")));
       
  2157 
       
  2158 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2159 	return eap_status_ok;
       
  2160 }
       
  2161 //--------------------------------------------------
       
  2162 
       
  2163 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_verify(
       
  2164 	eap_variable_data_c * const rsa_context,
       
  2165 	const eap_variable_data_c * const public_rsa_key,
       
  2166 	const eap_variable_data_c * const hash,
       
  2167 	const eap_variable_data_c * const signed_hash)
       
  2168 {
       
  2169 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
  2170 
       
  2171 	EAP_TRACE_DEBUG(
       
  2172 		m_am_tools,
       
  2173 		TRACE_FLAGS_DEFAULT,
       
  2174 		(EAPL("eap_am_crypto_symbian_c::rsa_verify(), begins.\n")));
       
  2175 
       
  2176 	eap_status_e status = eap_status_ok;
       
  2177 
       
  2178 	TRAPD(err, rsa_verifyL(
       
  2179 		rsa_context,
       
  2180 		public_rsa_key,
       
  2181 		hash,
       
  2182 		signed_hash));
       
  2183 	if (err != KErrNone)
       
  2184 	{
       
  2185 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
  2186 		EAP_TRACE_DEBUG(
       
  2187 			m_am_tools,
       
  2188 			TRACE_FLAGS_ERROR,
       
  2189 			(EAPL("eap_am_crypto_symbian_c::rsa_verify() failed, err %d, status %d.\n"),
       
  2190 			err,
       
  2191 			status));
       
  2192 	} 
       
  2193 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2194 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2195 }
       
  2196 
       
  2197 eap_status_e eap_am_crypto_symbian_c::rsa_verifyL(
       
  2198 	eap_variable_data_c * const /*rsa_context*/,
       
  2199 	const eap_variable_data_c * const public_rsa_key,
       
  2200 	const eap_variable_data_c * const hash,
       
  2201 	const eap_variable_data_c * const signed_hash)
       
  2202 {
       
  2203 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
  2204 	TPtrC8 ptr(
       
  2205 		public_rsa_key->get_data(public_rsa_key->get_data_length()), 
       
  2206 		public_rsa_key->get_data_length());
       
  2207 	if (ptr.Ptr() == 0)
       
  2208 	{
       
  2209 		EAP_TRACE_DEBUG(
       
  2210 			m_am_tools,
       
  2211 			TRACE_FLAGS_ERROR,
       
  2212 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, public_rsa_key is invalid.\n")));
       
  2213 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2214 		User::Leave(KErrArgument);
       
  2215 	}	
       
  2216 	// The public_rsa_key is ASN.1 encoded.
       
  2217 	// SEQUENCE {
       
  2218 	//	  INTEGER modulus
       
  2219 	//	  INTEGER exponent
       
  2220 	// }
       
  2221 	//
       
  2222 	//
       
  2223 	TASN1DecSequence seq;
       
  2224 	TASN1DecInteger asn1;
       
  2225 	TASN1DecGeneric* gen;
       
  2226 	
       
  2227 	EAP_TRACE_DEBUG(
       
  2228 		m_am_tools,
       
  2229 		TRACE_FLAGS_DEFAULT,
       
  2230 		(EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLC().\n")));
       
  2231 
       
  2232 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  2233 	TInt pos(0);
       
  2234 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  2235 	
       
  2236 	EAP_TRACE_DEBUG(
       
  2237 		m_am_tools,
       
  2238 		TRACE_FLAGS_DEFAULT,
       
  2239 		(EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLongL().\n")));
       
  2240 
       
  2241 	gen = arrayPtr->At(0);
       
  2242 	if (gen == 0)
       
  2243 	{
       
  2244 		EAP_TRACE_DEBUG(
       
  2245 			m_am_tools,
       
  2246 			TRACE_FLAGS_ERROR,
       
  2247 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
       
  2248 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2249 		User::Leave(KErrArgument);
       
  2250 	}
       
  2251 
       
  2252 	TPtrC8 m = gen->Encoding();			
       
  2253 	if (m.Length() == 0)
       
  2254 	{
       
  2255 		EAP_TRACE_DEBUG(
       
  2256 			m_am_tools,
       
  2257 			TRACE_FLAGS_ERROR,
       
  2258 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
       
  2259 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2260 		User::Leave(KErrArgument);
       
  2261 	}
       
  2262 	pos = 0;
       
  2263 	RInteger modulus = asn1.DecodeDERLongL(m, pos);
       
  2264 	CleanupStack::PushL(modulus);
       
  2265 
       
  2266 	EAP_TRACE_DEBUG(
       
  2267 		m_am_tools,
       
  2268 		TRACE_FLAGS_DEFAULT,
       
  2269 		(EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLongL().\n")));
       
  2270 
       
  2271 	gen = arrayPtr->At(1);
       
  2272 	if (gen == 0)
       
  2273 	{
       
  2274 		EAP_TRACE_DEBUG(
       
  2275 			m_am_tools,
       
  2276 			TRACE_FLAGS_ERROR,
       
  2277 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
       
  2278 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2279 		User::Leave(KErrArgument);
       
  2280 	}
       
  2281 
       
  2282 	TPtrC8 e = gen->Encoding();			
       
  2283 	if (e.Length() == 0)
       
  2284 	{
       
  2285 		EAP_TRACE_DEBUG(
       
  2286 			m_am_tools,
       
  2287 			TRACE_FLAGS_ERROR,
       
  2288 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
       
  2289 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2290 		User::Leave(KErrArgument);
       
  2291 	}
       
  2292 	pos = 0;
       
  2293 	RInteger exponent = asn1.DecodeDERLongL(e, pos);
       
  2294 	CleanupStack::PushL(exponent);
       
  2295 
       
  2296 	TPtrC8 p_hash(
       
  2297 		hash->get_data(hash->get_data_length()), 
       
  2298 		hash->get_data_length());
       
  2299 	if (p_hash.Ptr() == 0)
       
  2300 	{
       
  2301 		EAP_TRACE_DEBUG(
       
  2302 			m_am_tools,
       
  2303 			TRACE_FLAGS_ERROR,
       
  2304 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, hash is invalid.\n")));
       
  2305 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2306 		User::Leave(KErrArgument);
       
  2307 	}
       
  2308 	
       
  2309 	TPtrC8 p_sig(
       
  2310 		signed_hash->get_data(signed_hash->get_data_length()), 
       
  2311 		signed_hash->get_data_length());
       
  2312 	if (p_sig.Ptr() == 0)
       
  2313 	{
       
  2314 		EAP_TRACE_DEBUG(
       
  2315 			m_am_tools,
       
  2316 			TRACE_FLAGS_ERROR,
       
  2317 			(EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, signed_hash is invalid.\n")));
       
  2318 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2319 		User::Leave(KErrArgument);
       
  2320 	}
       
  2321 	
       
  2322 	CRSAPublicKey* public_key = CRSAPublicKey::NewL(modulus, exponent);
       
  2323 	// Modulus and exponent are popped here because CRSAPublicKey frees them
       
  2324 	CleanupStack::Pop(&exponent);
       
  2325 	CleanupStack::Pop(&modulus);
       
  2326 	CleanupStack::PushL(public_key);
       
  2327 
       
  2328 	RInteger signature = RInteger::NewL(p_sig);
       
  2329 	CleanupStack::PushL(signature);
       
  2330 
       
  2331 	CRSASignature* rsa_signature = CRSASignature::NewL(signature);	
       
  2332 	// signature is popped here because CRSASignature frees it
       
  2333 	CleanupStack::Pop(&signature);
       
  2334 	CleanupStack::PushL(rsa_signature);	
       
  2335 
       
  2336 	
       
  2337 	CRSAPKCS1v15Verifier* rsa_verifier = CRSAPKCS1v15Verifier::NewL(*public_key);
       
  2338 	CleanupStack::PushL(rsa_verifier);
       
  2339 
       
  2340 	EAP_TRACE_DEBUG(
       
  2341 		m_am_tools,
       
  2342 		TRACE_FLAGS_DEFAULT,
       
  2343 		(EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before VerifyL().\n")));
       
  2344 
       
  2345 	TBool result = rsa_verifier->VerifyL(p_hash, *rsa_signature);
       
  2346 	eap_status_e status;
       
  2347 	if (result)
       
  2348 	{
       
  2349 		// Verify successful
       
  2350 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_am_crypto_symbian: RSA verify successful.\n")));	
       
  2351 		status = eap_status_ok;
       
  2352 	}
       
  2353 	else
       
  2354 	{
       
  2355 		// Verify failed
       
  2356 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_am_crypto_symbian: RSA verify failed.\n")));
       
  2357 		status = eap_status_illegal_parameter; 
       
  2358 	}
       
  2359 
       
  2360 	CleanupStack::PopAndDestroy(rsa_verifier);	
       
  2361 	CleanupStack::PopAndDestroy(rsa_signature);	
       
  2362 	CleanupStack::PopAndDestroy(public_key);	
       
  2363 	CleanupStack::PopAndDestroy(arrayPtr);	
       
  2364 
       
  2365 	EAP_TRACE_DEBUG(
       
  2366 		m_am_tools,
       
  2367 		TRACE_FLAGS_DEFAULT,
       
  2368 		(EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), OK.\n")));
       
  2369 
       
  2370 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2371 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2372 }
       
  2373 //--------------------------------------------------
       
  2374 
       
  2375 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_cleanup(
       
  2376 	eap_variable_data_c * const /*rsa_context*/)
       
  2377 {
       
  2378 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2379 
       
  2380 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2381 	return eap_status_ok;
       
  2382 }
       
  2383 
       
  2384 
       
  2385 //--------------------------------------------------
       
  2386 
       
  2387 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_init(
       
  2388 	eap_variable_data_c * const dsa_context)
       
  2389 {	
       
  2390 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2391 	
       
  2392 	eap_status_e status = dsa_context->init(0);
       
  2393 	if (status != eap_status_ok)
       
  2394 	{
       
  2395 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2396 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2397 	}
       
  2398 
       
  2399 	dsa_context->set_is_valid(); 
       
  2400 
       
  2401 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2402 	return eap_status_ok;
       
  2403 }
       
  2404 
       
  2405 //--------------------------------------------------
       
  2406 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_sign(
       
  2407 	eap_variable_data_c * const dsa_context,
       
  2408 	const eap_variable_data_c * const private_dsa_key,
       
  2409 	const eap_variable_data_c * const hash,
       
  2410 	eap_variable_data_c * const signed_hash)
       
  2411 {
       
  2412 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
  2413 
       
  2414 	EAP_TRACE_DEBUG(
       
  2415 		m_am_tools,
       
  2416 		TRACE_FLAGS_DEFAULT,
       
  2417 		(EAPL("eap_am_crypto_symbian_c::dsa_sign(), begins.\n")));
       
  2418 
       
  2419 	eap_status_e status = eap_status_ok;
       
  2420 
       
  2421 	TRAPD(err, dsa_signL(
       
  2422 		dsa_context,
       
  2423 		private_dsa_key,
       
  2424 		hash,
       
  2425 		signed_hash));
       
  2426 	if (err != KErrNone)
       
  2427 	{
       
  2428 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
  2429 		EAP_TRACE_DEBUG(
       
  2430 			m_am_tools,
       
  2431 			TRACE_FLAGS_ERROR,
       
  2432 			(EAPL("eap_am_crypto_symbian_c::dsa_sign() failed, err %d, status %d.\n"),
       
  2433 			err,
       
  2434 			status));
       
  2435 	} 
       
  2436 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2437 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2438 }
       
  2439 
       
  2440 void eap_am_crypto_symbian_c::dsa_signL(
       
  2441 	eap_variable_data_c * const dsa_context,
       
  2442 	const eap_variable_data_c * const private_dsa_key,
       
  2443 	const eap_variable_data_c * const hash,
       
  2444 	eap_variable_data_c * const signed_hash)
       
  2445 {
       
  2446 	EAP_UNREFERENCED_PARAMETER(dsa_context);
       
  2447 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2448 	
       
  2449 	EAP_TRACE_DEBUG(
       
  2450 		m_am_tools,
       
  2451 		TRACE_FLAGS_DEFAULT,
       
  2452 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), begins.\n")));
       
  2453 
       
  2454 	TPtrC8 ptr(
       
  2455 		private_dsa_key->get_data(private_dsa_key->get_data_length()), 
       
  2456 		private_dsa_key->get_data_length());
       
  2457 	if (ptr.Ptr() == 0)
       
  2458 	{
       
  2459 		EAP_TRACE_DEBUG(
       
  2460 			m_am_tools,
       
  2461 			TRACE_FLAGS_ERROR,
       
  2462 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, private_dsa_key is invalid.\n")));
       
  2463 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2464 		User::Leave(KErrArgument);
       
  2465 	}
       
  2466 
       
  2467 	// The private_dsa_key is ASN.1 encoded and contains DSA parameters and public and private keys.
       
  2468 	// It must be decoded before it can be used.
       
  2469 	// SEQUENCE {
       
  2470 	//	  INTEGER version
       
  2471 	//	  INTEGER p
       
  2472 	//	  INTEGER q
       
  2473 	//	  INTEGER g
       
  2474 	//	  INTEGER Y
       
  2475 	//	  INTEGER X
       
  2476 	// }
       
  2477 	//
       
  2478 	//
       
  2479 	TASN1DecSequence seq;
       
  2480 	TASN1DecInteger asn1;
       
  2481 	TASN1DecGeneric* gen;
       
  2482 	RInteger param_p;
       
  2483 	RInteger param_q;
       
  2484 	RInteger param_g;	
       
  2485 	RInteger public_key;
       
  2486 	RInteger private_key;
       
  2487 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  2488 	TInt pos(0);
       
  2489 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  2490 
       
  2491 	EAP_TRACE_DEBUG(
       
  2492 		m_am_tools,
       
  2493 		TRACE_FLAGS_DEFAULT,
       
  2494 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
       
  2495 
       
  2496 	gen = arrayPtr->At(1);
       
  2497 	if (gen == 0)
       
  2498 	{
       
  2499 		EAP_TRACE_DEBUG(
       
  2500 			m_am_tools,
       
  2501 			TRACE_FLAGS_ERROR,
       
  2502 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2503 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2504 		User::Leave(KErrArgument);
       
  2505 	}
       
  2506 
       
  2507 	TPtrC8 p = gen->Encoding();			
       
  2508 	if (p.Length() == 0)
       
  2509 	{
       
  2510 		EAP_TRACE_DEBUG(
       
  2511 			m_am_tools,
       
  2512 			TRACE_FLAGS_ERROR,
       
  2513 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2514 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2515 		User::Leave(KErrArgument);
       
  2516 	}
       
  2517 	pos = 0;
       
  2518 	param_p = asn1.DecodeDERLongL(p, pos);
       
  2519 	CleanupStack::PushL(param_p);
       
  2520 
       
  2521 	EAP_TRACE_DEBUG(
       
  2522 		m_am_tools,
       
  2523 		TRACE_FLAGS_DEFAULT,
       
  2524 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
       
  2525 
       
  2526 	gen = arrayPtr->At(2);
       
  2527 	if (gen == 0)
       
  2528 	{
       
  2529 		EAP_TRACE_DEBUG(
       
  2530 			m_am_tools,
       
  2531 			TRACE_FLAGS_ERROR,
       
  2532 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2533 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2534 		User::Leave(KErrArgument);
       
  2535 	}
       
  2536 
       
  2537 	TPtrC8 q = gen->Encoding();
       
  2538 	if (q.Length() == 0)
       
  2539 	{
       
  2540 		EAP_TRACE_DEBUG(
       
  2541 			m_am_tools,
       
  2542 			TRACE_FLAGS_ERROR,
       
  2543 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2544 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2545 		User::Leave(KErrArgument);
       
  2546 	}
       
  2547 	pos = 0;
       
  2548 	param_q = asn1.DecodeDERLongL(q, pos);
       
  2549 	CleanupStack::PushL(param_q);
       
  2550 	
       
  2551 	EAP_TRACE_DEBUG(
       
  2552 		m_am_tools,
       
  2553 		TRACE_FLAGS_DEFAULT,
       
  2554 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
       
  2555 
       
  2556 	gen = arrayPtr->At(3);
       
  2557 	if (gen == 0)
       
  2558 	{
       
  2559 		EAP_TRACE_DEBUG(
       
  2560 			m_am_tools,
       
  2561 			TRACE_FLAGS_ERROR,
       
  2562 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2563 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2564 		User::Leave(KErrArgument);
       
  2565 	}
       
  2566 
       
  2567 	TPtrC8 g = gen->Encoding();
       
  2568 	if (g.Length() == 0)
       
  2569 	{
       
  2570 		EAP_TRACE_DEBUG(
       
  2571 			m_am_tools,
       
  2572 			TRACE_FLAGS_ERROR,
       
  2573 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2574 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2575 		User::Leave(KErrArgument);
       
  2576 	}
       
  2577 	pos = 0;
       
  2578 	param_g = asn1.DecodeDERLongL(g, pos);
       
  2579 	CleanupStack::PushL(param_g);
       
  2580 	
       
  2581 	EAP_TRACE_DEBUG(
       
  2582 		m_am_tools,
       
  2583 		TRACE_FLAGS_DEFAULT,
       
  2584 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
       
  2585 
       
  2586 	gen = arrayPtr->At(4);
       
  2587 	if (gen == 0)
       
  2588 	{
       
  2589 		EAP_TRACE_DEBUG(
       
  2590 			m_am_tools,
       
  2591 			TRACE_FLAGS_ERROR,
       
  2592 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2593 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2594 		User::Leave(KErrArgument);
       
  2595 	}
       
  2596 
       
  2597 	TPtrC8 Y = gen->Encoding();
       
  2598 	if (Y.Length() == 0)
       
  2599 	{
       
  2600 		EAP_TRACE_DEBUG(
       
  2601 			m_am_tools,
       
  2602 			TRACE_FLAGS_ERROR,
       
  2603 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2604 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2605 		User::Leave(KErrArgument);
       
  2606 	}
       
  2607 	pos = 0;
       
  2608 	public_key = asn1.DecodeDERLongL(Y, pos);
       
  2609 	CleanupStack::PushL(public_key);
       
  2610 	
       
  2611 	EAP_TRACE_DEBUG(
       
  2612 		m_am_tools,
       
  2613 		TRACE_FLAGS_DEFAULT,
       
  2614 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
       
  2615 
       
  2616 	gen = arrayPtr->At(5);
       
  2617 	if (gen == 0)
       
  2618 	{
       
  2619 		EAP_TRACE_DEBUG(
       
  2620 			m_am_tools,
       
  2621 			TRACE_FLAGS_ERROR,
       
  2622 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2623 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2624 		User::Leave(KErrArgument);
       
  2625 	}
       
  2626 
       
  2627 	TPtrC8 X = gen->Encoding();
       
  2628 	if (X.Length() == 0)
       
  2629 	{
       
  2630 		EAP_TRACE_DEBUG(
       
  2631 			m_am_tools,
       
  2632 			TRACE_FLAGS_ERROR,
       
  2633 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
       
  2634 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2635 		User::Leave(KErrArgument);
       
  2636 	}
       
  2637 
       
  2638 	pos = 0;
       
  2639 	private_key = asn1.DecodeDERLongL(X, pos);
       
  2640 	CleanupStack::PushL(private_key);		
       
  2641 
       
  2642 	CDSAPrivateKey* priv_key = CDSAPrivateKey::NewL(param_p, param_q, param_g, private_key);
       
  2643 	CleanupStack::PushL(priv_key);
       
  2644 
       
  2645 	CDSASigner* signer = CDSASigner::NewL(*priv_key);
       
  2646 	CleanupStack::PushL(signer);
       
  2647 
       
  2648 	TPtrC8 data(
       
  2649 		hash->get_data(hash->get_data_length()), 
       
  2650 		hash->get_data_length());
       
  2651 	if (data.Ptr() == 0)
       
  2652 	{
       
  2653 		EAP_TRACE_DEBUG(
       
  2654 			m_am_tools,
       
  2655 			TRACE_FLAGS_ERROR,
       
  2656 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, hash is invalid.\n")));
       
  2657 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2658 		User::Leave(KErrArgument);
       
  2659 	}
       
  2660 	
       
  2661 	const CDSASignature* signature = signer->SignL(data);
       
  2662 
       
  2663 	RInteger R = RInteger::NewL(signature->R());
       
  2664 	CleanupStack::PushL(R);
       
  2665 	RInteger S = RInteger::NewL(signature->S());
       
  2666 	CleanupStack::PushL(S);
       
  2667 	
       
  2668 	CASN1EncSequence* sequence = CASN1EncSequence::NewLC();
       
  2669 	CASN1EncBigInt* enc_r = CASN1EncBigInt::NewLC(R);
       
  2670 	CASN1EncBigInt* enc_s = CASN1EncBigInt::NewLC(S);
       
  2671 
       
  2672 	sequence->AddChildL(enc_r);
       
  2673 	
       
  2674 	sequence->AddChildL(enc_s);
       
  2675 	
       
  2676 	EAP_TRACE_DEBUG(
       
  2677 		m_am_tools,
       
  2678 		TRACE_FLAGS_DEFAULT,
       
  2679 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before NewLC().\n")));
       
  2680 
       
  2681 	HBufC8* buf = HBufC8::NewLC(sequence->LengthDER());
       
  2682 	TPtr8 tmp = buf->Des();
       
  2683 	
       
  2684 	EAP_TRACE_DEBUG(
       
  2685 		m_am_tools,
       
  2686 		TRACE_FLAGS_DEFAULT,
       
  2687 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), before WriteDERL().\n")));
       
  2688 
       
  2689 	tmp.SetLength(sequence->LengthDER());
       
  2690 	pos = 0;
       
  2691 	sequence->WriteDERL(tmp, (TUint&) pos);
       
  2692 	
       
  2693 	eap_status_e status = signed_hash->set_copy_of_buffer(tmp.Ptr(), tmp.Length());
       
  2694 	if (status != eap_status_ok)
       
  2695 	{
       
  2696 		EAP_TRACE_DEBUG(
       
  2697 			m_am_tools,
       
  2698 			TRACE_FLAGS_ERROR,
       
  2699 			(EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, signed_hash is invalid, status %d.\n"),
       
  2700 			status));
       
  2701 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2702 		User::Leave(KErrNoMemory);
       
  2703 	}
       
  2704 
       
  2705 	CleanupStack::PopAndDestroy(buf);
       
  2706 	CleanupStack::Pop(enc_s);		// BigInts are deleted by the sequence
       
  2707 	CleanupStack::Pop(enc_r);		// BigInts are deleted by the sequence
       
  2708 
       
  2709 	CleanupStack::PopAndDestroy(sequence);
       
  2710 	CleanupStack::PopAndDestroy(&S);
       
  2711 	CleanupStack::PopAndDestroy(&R);
       
  2712 	CleanupStack::PopAndDestroy(signer);
       
  2713 	CleanupStack::PopAndDestroy(priv_key);
       
  2714 	CleanupStack::PopAndDestroy(&private_key);
       
  2715 	CleanupStack::PopAndDestroy(&public_key);
       
  2716 	CleanupStack::PopAndDestroy(&param_g);
       
  2717 	CleanupStack::PopAndDestroy(&param_q);
       
  2718 	CleanupStack::PopAndDestroy(&param_p);
       
  2719 	CleanupStack::PopAndDestroy(arrayPtr);
       
  2720 
       
  2721 	EAP_TRACE_DEBUG(
       
  2722 		m_am_tools,
       
  2723 		TRACE_FLAGS_DEFAULT,
       
  2724 		(EAPL("eap_am_crypto_symbian_c::dsa_signL(), OK.\n")));
       
  2725 
       
  2726 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2727 }
       
  2728 
       
  2729 //--------------------------------------------------
       
  2730 
       
  2731 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_verify(
       
  2732 	eap_variable_data_c * const dsa_context,		
       
  2733 	const eap_variable_data_c * const public_dsa_key,
       
  2734 	const eap_variable_data_c * const dsa_param_p,
       
  2735 	const eap_variable_data_c * const dsa_param_q,
       
  2736 	const eap_variable_data_c * const dsa_param_g,
       
  2737 	const eap_variable_data_c * const hash,
       
  2738 	const eap_variable_data_c * const signed_hash)
       
  2739 {
       
  2740 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);	
       
  2741 
       
  2742 	EAP_TRACE_DEBUG(
       
  2743 		m_am_tools,
       
  2744 		TRACE_FLAGS_DEFAULT,
       
  2745 		(EAPL("eap_am_crypto_symbian_c::dsa_verify(), begins.\n")));
       
  2746 
       
  2747 	eap_status_e status = eap_status_ok;
       
  2748 
       
  2749 	__UHEAP_MARK;
       
  2750 	TRAPD(err, dsa_verifyL(
       
  2751 		dsa_context,
       
  2752 		public_dsa_key,
       
  2753 		dsa_param_p,
       
  2754 		dsa_param_q,
       
  2755 		dsa_param_g,
       
  2756 		hash,
       
  2757 		signed_hash));
       
  2758 	__UHEAP_MARKEND;
       
  2759 	if (err != KErrNone)
       
  2760 	{
       
  2761 		status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
       
  2762 		EAP_TRACE_DEBUG(
       
  2763 			m_am_tools,
       
  2764 			TRACE_FLAGS_ERROR,
       
  2765 			(EAPL("eap_am_crypto_symbian_c::dsa_verify() failed, err %d, status %d.\n"),
       
  2766 			err,
       
  2767 			status));
       
  2768 	} 
       
  2769 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2770 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2771 }
       
  2772 
       
  2773 void eap_am_crypto_symbian_c::dsa_verifyL(
       
  2774 	eap_variable_data_c * const /*dsa_context*/,		
       
  2775 	const eap_variable_data_c * const public_dsa_key,
       
  2776 	const eap_variable_data_c * const dsa_param_p,
       
  2777 	const eap_variable_data_c * const dsa_param_q,
       
  2778 	const eap_variable_data_c * const dsa_param_g,
       
  2779 	const eap_variable_data_c * const hash,
       
  2780 	const eap_variable_data_c * const signed_hash)
       
  2781 {
       
  2782 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2783 
       
  2784 	EAP_TRACE_DEBUG(
       
  2785 		m_am_tools,
       
  2786 		TRACE_FLAGS_DEFAULT,
       
  2787 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(1), begins.\n")));
       
  2788 
       
  2789 	// Parameters
       
  2790 	TPtrC8 p(
       
  2791 		dsa_param_p->get_data(dsa_param_p->get_data_length()), 
       
  2792 		dsa_param_p->get_data_length());
       
  2793 	if (p.Ptr() == 0)
       
  2794 	{
       
  2795 		EAP_TRACE_DEBUG(
       
  2796 			m_am_tools,
       
  2797 			TRACE_FLAGS_ERROR,
       
  2798 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(2) failed, dsa_param_p is invalid.\n")));
       
  2799 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2800 		User::Leave(KErrArgument);
       
  2801 	}	
       
  2802 	TPtrC8 q(
       
  2803 		dsa_param_q->get_data(dsa_param_q->get_data_length()), 
       
  2804 		dsa_param_q->get_data_length());
       
  2805 	if (q.Ptr() == 0)
       
  2806 	{
       
  2807 		EAP_TRACE_DEBUG(
       
  2808 			m_am_tools,
       
  2809 			TRACE_FLAGS_ERROR,
       
  2810 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(3) failed, dsa_param_q is invalid.\n")));
       
  2811 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2812 		User::Leave(KErrArgument);
       
  2813 	}
       
  2814 	TPtrC8 g(
       
  2815 		dsa_param_g->get_data(dsa_param_g->get_data_length()), 
       
  2816 		dsa_param_g->get_data_length());
       
  2817 	if (g.Ptr() == 0)
       
  2818 	{
       
  2819 		EAP_TRACE_DEBUG(
       
  2820 			m_am_tools,
       
  2821 			TRACE_FLAGS_ERROR,
       
  2822 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(4) failed, dsa_param_g is invalid.\n")));
       
  2823 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2824 		User::Leave(KErrArgument);
       
  2825 	}	
       
  2826 
       
  2827 	RInteger P = RInteger::NewL(p);
       
  2828 	CleanupStack::PushL(P);
       
  2829 	
       
  2830 	RInteger Q = RInteger::NewL(q);
       
  2831 	CleanupStack::PushL(Q);
       
  2832 	
       
  2833 	RInteger G = RInteger::NewL(g);
       
  2834 	CleanupStack::PushL(G);
       
  2835 
       
  2836 	TPtrC8 calculated_hash(
       
  2837 		hash->get_data(hash->get_data_length()), 
       
  2838 		hash->get_data_length());
       
  2839 	if (calculated_hash.Ptr() == 0)
       
  2840 	{
       
  2841 		EAP_TRACE_DEBUG(
       
  2842 			m_am_tools,
       
  2843 			TRACE_FLAGS_ERROR,
       
  2844 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(5) failed, hash is invalid.\n")));
       
  2845 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2846 		User::Leave(KErrArgument);
       
  2847 	}
       
  2848 
       
  2849 	
       
  2850 	// Public key is ASN.1 encoded so it must be decoded
       
  2851 	TPtrC8 pkey (
       
  2852 		public_dsa_key->get_data(public_dsa_key->get_data_length()), 
       
  2853 		public_dsa_key->get_data_length());
       
  2854 	if (pkey.Ptr() == 0)
       
  2855 	{
       
  2856 		EAP_TRACE_DEBUG(
       
  2857 			m_am_tools,
       
  2858 			TRACE_FLAGS_ERROR,
       
  2859 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(6) failed, public_dsa_key is invalid.\n")));
       
  2860 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2861 		User::Leave(KErrArgument);
       
  2862 	}
       
  2863 
       
  2864 	TASN1DecInteger asn1;
       
  2865 	TInt pos(0);
       
  2866 
       
  2867 	EAP_TRACE_DEBUG(
       
  2868 		m_am_tools,
       
  2869 		TRACE_FLAGS_DEFAULT,
       
  2870 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(7), before DecodeDERLongL().\n")));
       
  2871 
       
  2872 	RInteger public_key_int = asn1.DecodeDERLongL(
       
  2873 		pkey, 
       
  2874 		pos);	
       
  2875 	
       
  2876 	CleanupStack::PushL(public_key_int);	
       
  2877 	CDSAPublicKey* pub_key = CDSAPublicKey::NewL(P, Q, G, public_key_int);
       
  2878 	// RIntegers needs to be popped because CDSAPublicKey frees them
       
  2879 	CleanupStack::Pop(&public_key_int);
       
  2880 	CleanupStack::Pop(&G);
       
  2881 	CleanupStack::Pop(&Q);
       
  2882 	CleanupStack::Pop(&P);
       
  2883 	CleanupStack::PushL(pub_key);
       
  2884 
       
  2885 	TPtrC8 ptr(
       
  2886 		signed_hash->get_data(hash->get_data_length()),
       
  2887 		signed_hash->get_data_length());
       
  2888 	if (ptr.Ptr() == 0)
       
  2889 	{
       
  2890 		EAP_TRACE_DEBUG(
       
  2891 			m_am_tools,
       
  2892 			TRACE_FLAGS_ERROR,
       
  2893 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(8) failed, signed_hash is invalid.\n")));
       
  2894 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2895 		User::Leave(KErrArgument);
       
  2896 	}		
       
  2897 
       
  2898 	EAP_TRACE_DEBUG(
       
  2899 		m_am_tools,
       
  2900 		TRACE_FLAGS_DEFAULT,
       
  2901 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(9), before DecodeDERLC().\n")));
       
  2902 
       
  2903 	TASN1DecSequence seq;	
       
  2904 	TASN1DecGeneric* gen;
       
  2905 	RInteger R;
       
  2906 	RInteger S;
       
  2907 	CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
       
  2908 	pos = 0;
       
  2909 	arrayPtr = seq.DecodeDERLC(ptr, pos);
       
  2910 	
       
  2911 	EAP_TRACE_DEBUG(
       
  2912 		m_am_tools,
       
  2913 		TRACE_FLAGS_DEFAULT,
       
  2914 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(10), before DecodeDERLongL().\n")));
       
  2915 
       
  2916 	gen = arrayPtr->At(0);
       
  2917 	if (gen == 0)
       
  2918 	{
       
  2919 		EAP_TRACE_DEBUG(
       
  2920 			m_am_tools,
       
  2921 			TRACE_FLAGS_ERROR,
       
  2922 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n")));
       
  2923 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2924 		User::Leave(KErrArgument);
       
  2925 	}
       
  2926 
       
  2927 	TPtrC8 r = gen->Encoding();
       
  2928 	if (r.Length() == 0)
       
  2929 	{
       
  2930 		EAP_TRACE_DEBUG(
       
  2931 			m_am_tools,
       
  2932 			TRACE_FLAGS_ERROR,
       
  2933 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n")));
       
  2934 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2935 		User::Leave(KErrArgument);
       
  2936 	}	
       
  2937 	pos = 0;
       
  2938 	R = asn1.DecodeDERLongL(r, pos);
       
  2939 	CleanupStack::PushL(R);
       
  2940 
       
  2941 	EAP_TRACE_DEBUG(
       
  2942 		m_am_tools,
       
  2943 		TRACE_FLAGS_DEFAULT,
       
  2944 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(11), before arrayPtr->At(1).\n")));
       
  2945 
       
  2946 	gen = arrayPtr->At(1);
       
  2947 	if (gen == 0)
       
  2948 	{
       
  2949 		EAP_TRACE_DEBUG(
       
  2950 			m_am_tools,
       
  2951 			TRACE_FLAGS_ERROR,
       
  2952 			(EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n")));
       
  2953 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  2954 		User::Leave(KErrArgument);
       
  2955 	}	
       
  2956 
       
  2957 	EAP_TRACE_DEBUG(
       
  2958 		m_am_tools,
       
  2959 		TRACE_FLAGS_DEFAULT,
       
  2960 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(12), before gen->Encoding().\n")));
       
  2961 
       
  2962 	TPtrC8 s = gen->Encoding();
       
  2963 	pos = 0;
       
  2964 
       
  2965 	EAP_TRACE_DEBUG(
       
  2966 		m_am_tools,
       
  2967 		TRACE_FLAGS_DEFAULT,
       
  2968 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(13), before DecodeDERLongL().\n")));
       
  2969 
       
  2970 	S = asn1.DecodeDERLongL(s, pos);
       
  2971 	CleanupStack::PushL(S);
       
  2972 	
       
  2973 	EAP_TRACE_DEBUG(
       
  2974 		m_am_tools,
       
  2975 		TRACE_FLAGS_DEFAULT,
       
  2976 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(14), before CDSASignature::NewL().\n")));
       
  2977 
       
  2978 	CDSASignature* signature = CDSASignature::NewL(R, S);
       
  2979 	// Parameters needs to be popped because CDSASignature frees them
       
  2980 	CleanupStack::Pop(&S);
       
  2981 	CleanupStack::Pop(&R);
       
  2982 	CleanupStack::PushL(signature);
       
  2983 
       
  2984 	EAP_TRACE_DEBUG(
       
  2985 		m_am_tools,
       
  2986 		TRACE_FLAGS_DEFAULT,
       
  2987 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(15), before CDSAVerifier::NewL().\n")));
       
  2988 
       
  2989 	CDSAVerifier* verifier = CDSAVerifier::NewL(*pub_key);
       
  2990 	CleanupStack::PushL(verifier);
       
  2991 
       
  2992 	EAP_TRACE_DEBUG(
       
  2993 		m_am_tools,
       
  2994 		TRACE_FLAGS_DEFAULT,
       
  2995 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(16), before VerifyL().\n")));
       
  2996 
       
  2997 	TBool result = verifier->VerifyL(calculated_hash, *signature);
       
  2998 	if (result == EFalse)
       
  2999 	{
       
  3000 		// Verify failed
       
  3001 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_ERROR, (EAPL("eap_am_crypto_symbian: DSA verify failed.\n")));
       
  3002 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_ERROR);
       
  3003 		User::Leave(KErrArgument);
       
  3004 	}
       
  3005 
       
  3006 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_crypto_symbian: DSA verify successful.\n")));
       
  3007 
       
  3008 	CleanupStack::PopAndDestroy(verifier);
       
  3009 	CleanupStack::PopAndDestroy(signature);
       
  3010 	CleanupStack::PopAndDestroy(arrayPtr);
       
  3011 	CleanupStack::PopAndDestroy(pub_key);
       
  3012 
       
  3013 	EAP_TRACE_DEBUG(
       
  3014 		m_am_tools,
       
  3015 		TRACE_FLAGS_DEFAULT,
       
  3016 		(EAPL("eap_am_crypto_symbian_c::dsa_verifyL(17), OK.\n")));
       
  3017 
       
  3018 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
       
  3019 }
       
  3020 
       
  3021 
       
  3022 //--------------------------------------------------
       
  3023 
       
  3024 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_cleanup(
       
  3025 	eap_variable_data_c * const /*dsa_context*/)
       
  3026 {
       
  3027 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3028 
       
  3029 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3030 	return eap_status_ok;
       
  3031 }
       
  3032 
       
  3033 //--------------------------------------------------
       
  3034 
       
  3035 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md5_digest_length(
       
  3036 	eap_variable_data_c * const md5_context)
       
  3037 {
       
  3038 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3039 
       
  3040 	EAP_ASSERT(md5_context->get_is_valid());
       
  3041 	
       
  3042 	CMessageDigest *ctx = (CMessageDigest *)md5_context->get_data(md5_context->get_data_length());
       
  3043 	
       
  3044 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3045 	return ctx->HashSize();	
       
  3046 }
       
  3047 
       
  3048 //--------------------------------------------------
       
  3049 
       
  3050 
       
  3051 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md5_block_size(
       
  3052 	eap_variable_data_c * const /* md5_context */)
       
  3053 {
       
  3054 	return MD5_BLOCK_SIZE;
       
  3055 }
       
  3056 
       
  3057 //--------------------------------------------------
       
  3058 
       
  3059 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_init(
       
  3060 	eap_variable_data_c * const md5_context)
       
  3061 {
       
  3062 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3063 
       
  3064 	CMessageDigest *md5 = 0;
       
  3065 
       
  3066 	TRAPD(ret, md5 = CMD5::NewL());
       
  3067 	
       
  3068 	if (ret != KErrNone)
       
  3069 	{
       
  3070 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3071 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3072 	}
       
  3073 
       
  3074 	if (md5_context->get_is_valid_data() == true)
       
  3075 	{
       
  3076 		md5_cleanup(md5_context);
       
  3077 	}
       
  3078 
       
  3079 	eap_status_e status = md5_context->set_buffer(md5, sizeof(*md5), false, false);
       
  3080 	if (status != eap_status_ok)
       
  3081 	{
       
  3082 		delete md5;
       
  3083 	}
       
  3084 
       
  3085 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3086 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3087 }
       
  3088 
       
  3089 //--------------------------------------------------
       
  3090 
       
  3091 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_update(
       
  3092 	eap_variable_data_c * const md5_context,
       
  3093 	const u8_t * const data,
       
  3094 	const u32_t data_length)
       
  3095 {
       
  3096 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3097 	
       
  3098 	EAP_ASSERT(md5_context != 0);
       
  3099 	EAP_ASSERT(md5_context->get_is_valid() == true);
       
  3100 	if (md5_context == 0
       
  3101 		|| md5_context->get_is_valid_data() == false)
       
  3102 	{
       
  3103 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3104 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3105 	}
       
  3106 
       
  3107 	CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest));
       
  3108 	
       
  3109 	if (md5 == 0)
       
  3110 	{
       
  3111 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3112 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3113 	}
       
  3114 
       
  3115 	// This breaks the const type.
       
  3116 	TPtr8 tmp(const_cast<u8_t *>(data), data_length, data_length);
       
  3117 
       
  3118 	md5->Hash(tmp);
       
  3119 
       
  3120 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3121 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3122 }
       
  3123 
       
  3124 //--------------------------------------------------
       
  3125 
       
  3126 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_final(
       
  3127 	eap_variable_data_c * const md5_context,
       
  3128 	u8_t * const message_digest,
       
  3129 	u32_t *md_length_or_null)
       
  3130 {
       
  3131 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3132 
       
  3133 	EAP_ASSERT(md5_context != 0);
       
  3134 	EAP_ASSERT(md5_context->get_is_valid() == true);
       
  3135 	if (md5_context == 0
       
  3136 		|| md5_context->get_is_valid_data() == false)
       
  3137 	{
       
  3138 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3139 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3140 	}
       
  3141 
       
  3142 	CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest));
       
  3143 
       
  3144 	if (md5 == 0
       
  3145 		|| message_digest == 0)
       
  3146 	{
       
  3147 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3148 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3149 	}
       
  3150 
       
  3151 	if (md_length_or_null != 0)
       
  3152 	{
       
  3153 		*md_length_or_null = md5->HashSize();
       
  3154 	}
       
  3155 
       
  3156 	TPtrC8 digest = md5->Hash(TPtrC8(0,0));
       
  3157 
       
  3158 	if (digest.Ptr() == 0)
       
  3159 	{
       
  3160 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3161 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3162 	}
       
  3163 
       
  3164 	m_am_tools->memmove(message_digest, digest.Ptr(), md5->HashSize());
       
  3165 
       
  3166 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3167 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3168 }
       
  3169 
       
  3170 //--------------------------------------------------
       
  3171 
       
  3172 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_cleanup(
       
  3173 	eap_variable_data_c * const md5_context)
       
  3174 {
       
  3175 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3176 
       
  3177 	EAP_ASSERT(md5_context != 0);
       
  3178 	EAP_ASSERT(md5_context->get_is_valid() == true);
       
  3179 	if (md5_context == 0
       
  3180 		|| md5_context->get_is_valid_data() == false)
       
  3181 	{
       
  3182 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3183 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3184 	}
       
  3185 
       
  3186 	
       
  3187 	CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest));
       
  3188 
       
  3189 	delete md5;
       
  3190 
       
  3191 	md5_context->reset();
       
  3192 
       
  3193 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3194 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3195 }
       
  3196 
       
  3197 //--------------------------------------------------
       
  3198 
       
  3199 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_copy_context(
       
  3200 	eap_variable_data_c * const copied_md5_context,
       
  3201 	const eap_variable_data_c * const original_md5_context)
       
  3202 {
       
  3203 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3204 
       
  3205 	CMessageDigest *ctx_copy = 0;
       
  3206 
       
  3207 	if (original_md5_context == 0
       
  3208 		|| original_md5_context->get_is_valid_data() == false)
       
  3209 	{
       
  3210 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3211 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3212 	}
       
  3213 
       
  3214 	CMessageDigest *ctx = (CMessageDigest *)original_md5_context->get_data(sizeof(CMessageDigest));
       
  3215 
       
  3216 	TRAPD(ret, ctx_copy = ctx->CopyL());
       
  3217 
       
  3218 	if (ret != KErrNone)
       
  3219 	{
       
  3220 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3221 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3222 	}
       
  3223 
       
  3224 	eap_status_e status = copied_md5_context->set_buffer(ctx_copy, sizeof(*ctx_copy), false, false);
       
  3225 	if (status != eap_status_ok)
       
  3226 	{
       
  3227 		delete ctx_copy;		
       
  3228 	}
       
  3229 
       
  3230 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3231 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3232 }
       
  3233 
       
  3234 //--------------------------------------------------
       
  3235 
       
  3236 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md4_digest_length(
       
  3237 	eap_variable_data_c * const md4_context)
       
  3238 {
       
  3239 	if (md4_context == 0
       
  3240 		|| md4_context->get_is_valid_data() == false)
       
  3241 	{
       
  3242 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3243 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3244 	}
       
  3245 
       
  3246 	eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
       
  3247 		md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
       
  3248 
       
  3249 	if (md4 == 0
       
  3250 		|| md4->get_is_valid() == false)
       
  3251 	{
       
  3252 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3253 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3254 	}
       
  3255 
       
  3256 	return md4->get_digest_length();
       
  3257 }
       
  3258 
       
  3259 //--------------------------------------------------
       
  3260 
       
  3261 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md4_block_size(
       
  3262 	eap_variable_data_c * const md4_context)
       
  3263 {
       
  3264 	if (md4_context == 0
       
  3265 		|| md4_context->get_is_valid_data() == false)
       
  3266 	{
       
  3267 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3268 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3269 	}
       
  3270 
       
  3271 	eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
       
  3272 		md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
       
  3273 
       
  3274 	if (md4 == 0
       
  3275 		|| md4->get_is_valid() == false)
       
  3276 	{
       
  3277 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3278 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3279 	}
       
  3280 
       
  3281 	return md4->get_block_size();
       
  3282 }
       
  3283 
       
  3284 //--------------------------------------------------
       
  3285 
       
  3286 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_init(
       
  3287 	eap_variable_data_c * const md4_context)
       
  3288 {
       
  3289 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3290 
       
  3291 	if (md4_context == 0)
       
  3292 	{
       
  3293 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3294 	}
       
  3295 
       
  3296 	if (md4_context->get_is_valid_data() == true)
       
  3297 	{
       
  3298 		md4_cleanup(md4_context);
       
  3299 	}
       
  3300 
       
  3301 	eap_am_crypto_md4_c * const md4 = new eap_am_crypto_md4_c(m_am_tools);
       
  3302 	if (md4 == 0
       
  3303 		|| md4->get_is_valid() == false)
       
  3304 	{
       
  3305 		delete md4;
       
  3306 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3307 	}
       
  3308 
       
  3309 	eap_status_e status = md4->hash_init();
       
  3310 	if (status != eap_status_ok)
       
  3311 	{
       
  3312 		delete md4;
       
  3313 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3314 	}
       
  3315 
       
  3316 	if (md4_context->get_is_valid_data() == true)
       
  3317 	{
       
  3318 		md4_cleanup(md4_context);
       
  3319 	}
       
  3320 
       
  3321 	status = md4_context->set_buffer(md4, sizeof(*md4), false, true);
       
  3322 	if (status != eap_status_ok)
       
  3323 	{
       
  3324 		delete md4;		
       
  3325 	}
       
  3326 
       
  3327 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3328 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3329 }
       
  3330 
       
  3331 //--------------------------------------------------
       
  3332 
       
  3333 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_update(
       
  3334 	eap_variable_data_c * const md4_context,
       
  3335 	const u8_t * const data,
       
  3336 	const u32_t data_length)
       
  3337 {
       
  3338 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3339 
       
  3340 	EAP_ASSERT(md4_context != 0);
       
  3341 	EAP_ASSERT(md4_context->get_is_valid() == true);
       
  3342 	if (md4_context == 0
       
  3343 		|| md4_context->get_is_valid_data() == false)
       
  3344 	{
       
  3345 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3346 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3347 	}
       
  3348 
       
  3349 	eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
       
  3350 		md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
       
  3351 
       
  3352 	if (md4 == 0
       
  3353 		|| md4->get_is_valid() == false)
       
  3354 	{
       
  3355 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3356 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3357 	}
       
  3358 
       
  3359 	eap_status_e status =  md4->hash_update(
       
  3360 		data,
       
  3361 		data_length);
       
  3362 
       
  3363 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3364 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3365 }
       
  3366 
       
  3367 //--------------------------------------------------
       
  3368 
       
  3369 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_final(
       
  3370 	eap_variable_data_c * const md4_context,
       
  3371 	u8_t * const message_digest,
       
  3372 	u32_t * md_length_or_null)
       
  3373 {
       
  3374 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3375 
       
  3376 	EAP_ASSERT(md4_context != 0);
       
  3377 	EAP_ASSERT(md4_context->get_is_valid() == true);
       
  3378 	if (md4_context == 0
       
  3379 		|| md4_context->get_is_valid_data() == false)
       
  3380 	{
       
  3381 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3382 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3383 	}
       
  3384 
       
  3385 	eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
       
  3386 		md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
       
  3387 
       
  3388 	if (md4 == 0
       
  3389 		|| md4->get_is_valid() == false)
       
  3390 	{
       
  3391 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3392 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3393 	}
       
  3394 
       
  3395 	eap_status_e status =  md4->hash_final(
       
  3396 		message_digest,
       
  3397 		md_length_or_null);
       
  3398 
       
  3399 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3400 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3401 }
       
  3402 
       
  3403 //--------------------------------------------------
       
  3404 
       
  3405 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_cleanup(
       
  3406 	eap_variable_data_c * const md4_context)
       
  3407 {
       
  3408 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3409 
       
  3410 	EAP_ASSERT(md4_context != 0);
       
  3411 	EAP_ASSERT(md4_context->get_is_valid() == true);
       
  3412 	if (md4_context == 0
       
  3413 		|| md4_context->get_is_valid_data() == false)
       
  3414 	{
       
  3415 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3416 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3417 	}
       
  3418 	
       
  3419 	eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
       
  3420 		md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
       
  3421 	
       
  3422 	delete md4;
       
  3423 
       
  3424 	md4_context->reset();
       
  3425 
       
  3426 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3427 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3428 }
       
  3429 
       
  3430 //--------------------------------------------------
       
  3431 
       
  3432 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_copy_context(
       
  3433 	eap_variable_data_c * const copied_md4_context,
       
  3434 	const eap_variable_data_c * const original_md4_context)
       
  3435 {
       
  3436 	if (original_md4_context == 0
       
  3437 		|| original_md4_context->get_is_valid_data() == false)
       
  3438 	{
       
  3439 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3440 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3441 	}
       
  3442 
       
  3443 	eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
       
  3444 		original_md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
       
  3445 
       
  3446 	if (md4 == 0
       
  3447 		|| md4->get_is_valid() == false)
       
  3448 	{
       
  3449 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3450 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3451 	}
       
  3452 
       
  3453 	eap_am_crypto_md4_c * const md4_copy = md4->copy();
       
  3454 	if (md4_copy == 0
       
  3455 		|| md4_copy->get_is_valid() == false)
       
  3456 	{
       
  3457 		delete md4_copy;
       
  3458 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3459 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3460 	}
       
  3461 
       
  3462 	eap_status_e status = copied_md4_context->set_buffer(md4_copy, sizeof(*md4_copy), false, true);
       
  3463 	if (status != eap_status_ok)
       
  3464 	{
       
  3465 		delete md4_copy;
       
  3466 	}
       
  3467 	
       
  3468 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3469 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3470 }
       
  3471 
       
  3472 //--------------------------------------------------
       
  3473 
       
  3474 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_set_encryption_key(
       
  3475 	eap_variable_data_c * const aes_context,
       
  3476 	const u8_t * const key, const u32_t key_length)
       
  3477 {
       
  3478 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3479 
       
  3480 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("encryption_key"),
       
  3481 		key, key_length));
       
  3482 
       
  3483 	if (key_length != aes_key_length())
       
  3484 	{
       
  3485 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3486 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3487 	}
       
  3488 	
       
  3489 	TPtrC8 aes_key(key, key_length);
       
  3490 	
       
  3491 	CAESEncryptor* aes = 0;
       
  3492 	TRAPD(err, aes = CAESEncryptor::NewL(aes_key));
       
  3493 	if (err != KErrNone)
       
  3494 	{
       
  3495 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
       
  3496 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3497 	}
       
  3498 
       
  3499 	// If context is already reserved then cleanup it.
       
  3500 	if (aes_context->get_is_valid_data() == true)
       
  3501 	{
       
  3502 		aes_cleanup(aes_context);
       
  3503 	}
       
  3504 
       
  3505 	eap_status_e status = aes_context->set_buffer( 
       
  3506 		aes,
       
  3507 		sizeof(*aes),
       
  3508 		false,
       
  3509 		false);
       
  3510 	if (status != eap_status_ok)
       
  3511 	{
       
  3512 		delete aes;
       
  3513 	}
       
  3514 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3515 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3516 
       
  3517 }
       
  3518 
       
  3519 //--------------------------------------------------
       
  3520 
       
  3521 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_set_decryption_key(
       
  3522 	eap_variable_data_c * const aes_context,
       
  3523 	const u8_t * const key, const u32_t key_length)
       
  3524 {
       
  3525 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3526 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("decryption_key"),
       
  3527 		key, key_length));
       
  3528 
       
  3529 	if (key_length != aes_key_length())
       
  3530 	{
       
  3531 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3532 	}
       
  3533 	
       
  3534 	TPtrC8 aes_key(key, key_length);
       
  3535 	
       
  3536 	CAESDecryptor* aes = 0;
       
  3537 	TRAPD(err, aes = CAESDecryptor::NewL(aes_key));
       
  3538 	if (err != KErrNone)
       
  3539 	{
       
  3540 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
       
  3541 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3542 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3543 	}
       
  3544 
       
  3545 	// If context is already reserved then cleanup it.
       
  3546 	if (aes_context->get_is_valid_data() == true)
       
  3547 	{
       
  3548 		aes_cleanup(aes_context);
       
  3549 	}
       
  3550 
       
  3551 	eap_status_e status = aes_context->set_buffer( 
       
  3552 		aes,
       
  3553 		sizeof(*aes),
       
  3554 		false,
       
  3555 		false);
       
  3556 	if (status != eap_status_ok)
       
  3557 	{
       
  3558 		delete aes;		
       
  3559 	}
       
  3560 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3561 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3562 
       
  3563 }
       
  3564 
       
  3565 //--------------------------------------------------
       
  3566 
       
  3567 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_cleanup(
       
  3568 	eap_variable_data_c * const aes_context)
       
  3569 {
       
  3570 	EAP_ASSERT(aes_context != 0);
       
  3571 	EAP_ASSERT(aes_context->get_is_valid() == true);
       
  3572 	if (aes_context == 0
       
  3573 		|| aes_context->get_is_valid_data() == false)
       
  3574 	{
       
  3575 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3576 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3577 	}
       
  3578 
       
  3579 	CRijndael* aes = reinterpret_cast<CRijndael *>(aes_context->get_data(sizeof(CRijndael)));
       
  3580 	
       
  3581 	delete aes;	
       
  3582 	
       
  3583 	aes_context->reset();
       
  3584 
       
  3585 	return eap_status_ok;
       
  3586 }
       
  3587 
       
  3588 //--------------------------------------------------
       
  3589 
       
  3590 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_encrypt_block(
       
  3591 	eap_variable_data_c * const aes_context,
       
  3592 	const u8_t * const data_in,
       
  3593 	u8_t * const data_out,
       
  3594 	const u32_t data_length)
       
  3595 {
       
  3596 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_in"),
       
  3597 		data_in, data_length));
       
  3598 
       
  3599 	if (data_length != aes_block_size())
       
  3600 	{
       
  3601 		return EAP_STATUS_RETURN(m_am_tools, eap_status_encryption_failure);
       
  3602 	}
       
  3603 
       
  3604 	EAP_ASSERT(aes_context != 0);
       
  3605 	EAP_ASSERT(aes_context->get_is_valid() == true);
       
  3606 	if (aes_context == 0
       
  3607 		|| aes_context->get_is_valid_data() == false)
       
  3608 	{
       
  3609 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3610 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3611 	}
       
  3612 
       
  3613 	CAESEncryptor* aes = (CAESEncryptor*)aes_context->get_data(sizeof(CAESEncryptor)); 
       
  3614 	if (aes == 0)
       
  3615 	{
       
  3616 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3617 	}
       
  3618 	
       
  3619 	Mem::Copy(data_out, data_in, data_length);
       
  3620 	
       
  3621 	TPtr8 ptr(data_out, data_length, data_length);
       
  3622 	
       
  3623 	aes->Transform(ptr);
       
  3624 	
       
  3625 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_out"),
       
  3626 		data_out, data_length));
       
  3627 
       
  3628 	return eap_status_ok;
       
  3629 }
       
  3630 
       
  3631 //--------------------------------------------------
       
  3632 
       
  3633 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_decrypt_block(
       
  3634 	eap_variable_data_c * const aes_context,
       
  3635 	const u8_t * const data_in,
       
  3636 	u8_t * const data_out,
       
  3637 	const u32_t data_length)
       
  3638 {
       
  3639 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_in"),
       
  3640 		data_in, data_length));
       
  3641 
       
  3642 	if (data_length != aes_block_size())
       
  3643 	{
       
  3644 		return EAP_STATUS_RETURN(m_am_tools, eap_status_decryption_failure);
       
  3645 	}
       
  3646 
       
  3647 	EAP_ASSERT(aes_context != 0);
       
  3648 	EAP_ASSERT(aes_context->get_is_valid() == true);
       
  3649 	if (aes_context == 0
       
  3650 		|| aes_context->get_is_valid_data() == false)
       
  3651 	{
       
  3652 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3653 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3654 	}
       
  3655 
       
  3656 	CAESDecryptor* aes = (CAESDecryptor*)aes_context->get_data(sizeof(CAESDecryptor)); 
       
  3657 	if (aes == 0)
       
  3658 	{
       
  3659 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3660 	}
       
  3661 	
       
  3662 	// Copy input to output so we can transform it in the output buffer
       
  3663 	Mem::Copy(data_out, data_in, data_length);
       
  3664 	
       
  3665 	TPtr8 ptr(data_out, data_length, data_length);
       
  3666 	
       
  3667 	aes->Transform(ptr);
       
  3668 	
       
  3669 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_out"),
       
  3670 		data_out, data_length));
       
  3671 
       
  3672 	return eap_status_ok;
       
  3673 }
       
  3674 
       
  3675 //--------------------------------------------------
       
  3676 
       
  3677 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::key_length_3des_ede()
       
  3678 {
       
  3679 	return 3ul * BLOCK_SIZE_3DES_EDE;
       
  3680 }
       
  3681 
       
  3682 //--------------------------------------------------
       
  3683 
       
  3684 EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::block_size_3des_ede()
       
  3685 {
       
  3686 	return BLOCK_SIZE_3DES_EDE;
       
  3687 }
       
  3688 
       
  3689 //--------------------------------------------------
       
  3690 
       
  3691 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::set_encryption_key_3des_ede(
       
  3692 	eap_variable_data_c * const context,
       
  3693 	const u8_t * const key, const u32_t key_length)
       
  3694 {
       
  3695 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("encryption_key"),
       
  3696 		key, key_length));
       
  3697 
       
  3698 	if (key_length != key_length_3des_ede())
       
  3699 	{
       
  3700 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3701 	}
       
  3702 	
       
  3703 	TPtrC8 des_key(key, key_length);
       
  3704 	
       
  3705 	C3DESEncryptor* ede_3des = 0;
       
  3706 	TRAPD(err, ede_3des = C3DESEncryptor::NewL(des_key));
       
  3707 	if (err != KErrNone)
       
  3708 	{
       
  3709 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
       
  3710 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3711 	}
       
  3712 
       
  3713 	// If context is already reserved then cleanup it.
       
  3714 	if (context->get_is_valid_data() == true)
       
  3715 	{
       
  3716 		cleanup_3des_ede(context);
       
  3717 	}
       
  3718 
       
  3719 	eap_status_e status = context->set_buffer( 
       
  3720 		ede_3des,
       
  3721 		sizeof(*ede_3des),
       
  3722 		false,
       
  3723 		false);
       
  3724 	if (status != eap_status_ok)
       
  3725 	{
       
  3726 		delete ede_3des;
       
  3727 	}
       
  3728 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3729 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3730 }
       
  3731 
       
  3732 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::cleanup_3des_ede(
       
  3733 	eap_variable_data_c * const context)
       
  3734 {
       
  3735 	EAP_ASSERT(context != 0);
       
  3736 	EAP_ASSERT(context->get_is_valid() == true);
       
  3737 	if (context == 0
       
  3738 		|| context->get_is_valid_data() == false)
       
  3739 	{
       
  3740 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3741 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3742 	}
       
  3743 
       
  3744 	C3DES* ede_3des = (C3DES*)context->get_data(sizeof(C3DES));
       
  3745 	
       
  3746 	delete ede_3des;
       
  3747 
       
  3748 	context->reset();
       
  3749 
       
  3750 	return eap_status_ok;
       
  3751 }
       
  3752 
       
  3753 //--------------------------------------------------
       
  3754 
       
  3755 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::set_decryption_key_3des_ede(
       
  3756 	eap_variable_data_c * const context,
       
  3757 	const u8_t * const key, const u32_t key_length)
       
  3758 {
       
  3759 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("decryption_key"),
       
  3760 		key, key_length));
       
  3761 
       
  3762 	if (key_length != key_length_3des_ede())
       
  3763 	{
       
  3764 		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
       
  3765 	}
       
  3766 	
       
  3767 	TPtrC8 des_key(key, key_length);
       
  3768 	
       
  3769 	C3DESDecryptor* ede_3des = 0;
       
  3770 	TRAPD(err, ede_3des = C3DESDecryptor::NewL(des_key));
       
  3771 	if (err != KErrNone)
       
  3772 	{
       
  3773 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
       
  3774 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  3775 	}
       
  3776 
       
  3777 	// If context is already reserved then cleanup it.
       
  3778 	if (context->get_is_valid_data() == true)
       
  3779 	{
       
  3780 		cleanup_3des_ede(context);
       
  3781 	}
       
  3782 
       
  3783 	eap_status_e status = context->set_buffer( // 
       
  3784 		ede_3des,
       
  3785 		sizeof(*ede_3des),
       
  3786 		false,
       
  3787 		false);
       
  3788 	if (status != eap_status_ok)
       
  3789 	{
       
  3790 		delete ede_3des;
       
  3791 	}
       
  3792 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3793 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3794 }
       
  3795 
       
  3796 //--------------------------------------------------
       
  3797 
       
  3798 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::encrypt_block_3des_ede(
       
  3799 	eap_variable_data_c * const context,
       
  3800 	const u8_t * const data_in,
       
  3801 	u8_t * const data_out,
       
  3802 	const u32_t data_length)
       
  3803 {
       
  3804 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE encrypt data_in"),
       
  3805 		data_in, data_length));
       
  3806 
       
  3807 	if (data_length != block_size_3des_ede())
       
  3808 	{
       
  3809 		return EAP_STATUS_RETURN(m_am_tools, eap_status_encryption_failure);
       
  3810 	}
       
  3811 	
       
  3812 	EAP_ASSERT(context != 0);
       
  3813 	EAP_ASSERT(context->get_is_valid() == true);
       
  3814 	if (context == 0
       
  3815 		|| context->get_is_valid_data() == false)
       
  3816 	{
       
  3817 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3818 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3819 	}
       
  3820 
       
  3821 	C3DESEncryptor* ede_3des = (C3DESEncryptor*)context->get_data(sizeof(C3DESEncryptor)); 
       
  3822 	if (ede_3des == 0)
       
  3823 	{
       
  3824 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3825 	}
       
  3826 	
       
  3827 	Mem::Copy(data_out, data_in, data_length);
       
  3828 	
       
  3829 	TPtr8 ptr(data_out, data_length, data_length);
       
  3830 	
       
  3831 	ede_3des->Transform(ptr);
       
  3832 	
       
  3833 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE encrypt data_out"),
       
  3834 		data_out, data_length));
       
  3835 
       
  3836 	return eap_status_ok;
       
  3837 }
       
  3838 
       
  3839 //--------------------------------------------------
       
  3840 
       
  3841 EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::decrypt_block_3des_ede(
       
  3842 	eap_variable_data_c * const context,
       
  3843 	const u8_t * const data_in,
       
  3844 	u8_t * const data_out,
       
  3845 	const u32_t data_length)
       
  3846 {
       
  3847 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE decrypt data_in"),
       
  3848 		data_in, data_length));
       
  3849 
       
  3850 	if (data_length != block_size_3des_ede())
       
  3851 	{
       
  3852 		return EAP_STATUS_RETURN(m_am_tools, eap_status_decryption_failure);
       
  3853 	}
       
  3854 	
       
  3855 	EAP_ASSERT(context != 0);
       
  3856 	EAP_ASSERT(context->get_is_valid() == true);
       
  3857 	if (context == 0
       
  3858 		|| context->get_is_valid_data() == false)
       
  3859 	{
       
  3860 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
       
  3861 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3862 	}
       
  3863 
       
  3864 	C3DESDecryptor* ede_3des = (C3DESDecryptor*)context->get_data(sizeof(C3DESDecryptor)); 
       
  3865 	if (ede_3des == 0)
       
  3866 	{
       
  3867 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  3868 	}
       
  3869 	
       
  3870 	Mem::Copy(data_out, data_in, data_length);
       
  3871 	
       
  3872 	TPtr8 ptr(data_out, data_length, data_length);
       
  3873 	
       
  3874 	ede_3des->Transform(ptr);
       
  3875 	
       
  3876 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE decrypt data_out"),
       
  3877 		data_out, data_length));
       
  3878 
       
  3879 	return eap_status_ok;
       
  3880 }
       
  3881 
       
  3882 //--------------------------------------------------
       
  3883 
       
  3884 
       
  3885 
       
  3886 
       
  3887 // End.