--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/eapol_symbian/am/common/symbian/eap_am_crypto_symbian.cpp Thu Dec 17 08:47:43 2009 +0200
@@ -0,0 +1,3887 @@
+/*
+* Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: EAP and WLAN authentication protocols.
+*
+*/
+
+
+// This is enumeration of EAPOL source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+ #undef EAP_FILE_NUMBER_ENUM
+ #define EAP_FILE_NUMBER_ENUM 145
+ #undef EAP_FILE_NUMBER_DATE
+ #define EAP_FILE_NUMBER_DATE 1127594498
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+// INCLUDES
+#include <hash.h>
+#include <random.h>
+#include <asymmetric.h>
+#include <symmetric.h>
+#include <rijndael.h>
+
+#include <x509keys.h>
+#include <asn1dec.h>
+#include <asn1enc.h>
+
+#include "eap_am_crypto_symbian.h"
+#include "eap_tools.h"
+#include "eap_am_tools_symbian.h"
+#include "dss_random.h"
+
+#include "eap_am_crypto_sha_256.h"
+#include "eap_am_crypto_sha1.h"
+#include "eap_am_crypto_rc4.h"
+#include "eap_am_crypto_md4.h"
+
+#include "eap_am_memory.h"
+#include "eap_am_assert.h"
+
+// LOCAL DATA
+const u32_t BLOCK_SIZE_3DES_EDE = 8ul;
+const u32_t MD5_BLOCK_SIZE = 64ul;
+const u32_t AES_KEY_SIZE = 16ul;
+const u32_t AES_BLOCK_SIZE = 16ul;
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_am_crypto_symbian_c::~eap_am_crypto_symbian_c()
+{
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_am_crypto_symbian_c::eap_am_crypto_symbian_c(abs_eap_am_tools_c * const tools)
+ : m_am_tools(tools)
+ , m_is_valid(false)
+{
+ m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT bool eap_am_crypto_symbian_c::get_is_valid() const
+{
+ return m_is_valid;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::set_is_valid()
+{
+ m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::configure()
+{
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::use_test_random(
+ const u8_t * const /* seed */,
+ const u32_t /* seed_length */,
+ const bool /* does_continuous_seeding_when_true */)
+{
+ // This does nothing yet. Later we may need test random generator.
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::add_rand_seed(
+ const u8_t * const /* bytes */, const u32_t /* length */)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::add_rand_seed_hw_ticks()
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ u64_t ticks = m_am_tools->get_hardware_ticks();
+ u8_t entropy_bits = static_cast<u8_t>(ticks & 0xff);
+ add_rand_seed(
+ reinterpret_cast<u8_t *>(&entropy_bits),
+ sizeof(entropy_bits));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::get_rand_bytes(
+ u8_t * const bytes,
+ const u32_t length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ TPtr8 target(bytes, length, length);
+
+ TRandom::Random(target);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::generate_diffie_hellman_keys(
+ eap_variable_data_c * const own_private_dh_key,
+ eap_variable_data_c * const own_public_dh_key,
+ const u8_t * const prime,
+ const u32_t prime_length,
+ const u8_t * const group_generator,
+ const u32_t group_generator_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ eap_status_e status = eap_status_ok;
+ TRAPD(err, generate_diffie_hellman_keysL(
+ own_private_dh_key,
+ own_public_dh_key,
+ prime,
+ prime_length,
+ group_generator,
+ group_generator_length));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+void eap_am_crypto_symbian_c::generate_diffie_hellman_keysL(
+ eap_variable_data_c * const own_private_dh_key,
+ eap_variable_data_c * const own_public_dh_key,
+ const u8_t * const prime,
+ const u32_t prime_length,
+ const u8_t * const group_generator,
+ const u32_t group_generator_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_status_e status;
+
+ TPtrC8 _prime(prime, prime_length);
+ TPtrC8 _generator(group_generator, group_generator_length);
+
+ RInteger N = RInteger::NewL(_prime);
+ CleanupStack::PushL(N);
+
+ RInteger G = RInteger::NewL(_generator);
+ CleanupStack::PushL(G);
+
+ CDHKeyPair* dh_key = CDHKeyPair::NewL(N, G);
+ CleanupStack::Pop(&G); // N, G
+ CleanupStack::Pop(&N); // N, G
+
+ CleanupStack::PushL(dh_key);
+
+ const CDHPublicKey& publicKey = dh_key->PublicKey();
+
+ const TInteger& X = publicKey.X();
+
+ HBufC8* p = X.BufferLC();
+ // Copy the public key
+ status = own_public_dh_key->set_copy_of_buffer(p->Des().Ptr(), p->Length());
+ if (status != eap_status_ok)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ CleanupStack::PopAndDestroy(p);
+
+
+ const CDHPrivateKey& privateKey = dh_key->PrivateKey();
+
+ const TInteger& x = privateKey.x();
+
+ p = x.BufferLC();
+ // Copy the private key
+ status = own_private_dh_key->set_copy_of_buffer(p->Des().Ptr(), p->Length());
+ if (status != eap_status_ok)
+ {
+ User::Leave(KErrNoMemory);
+ }
+ CleanupStack::PopAndDestroy(p);
+
+ CleanupStack::PopAndDestroy(dh_key);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("own_public_dh_key"),
+ own_public_dh_key->get_data(own_public_dh_key->get_data_length()),
+ own_public_dh_key->get_data_length()));
+
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("own_private_dh_key is hidden in Symbian.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::generate_g_power_to_xy(
+ const eap_variable_data_c * const own_private_dh_key,
+ const eap_variable_data_c * const peer_public_dh_key,
+ eap_variable_data_c * const shared_dh_key,
+ const u8_t * const prime,
+ const u32_t prime_length,
+ const u8_t * const group_generator,
+ const u32_t group_generator_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ eap_status_e status = eap_status_ok;
+ TRAPD(err, generate_g_power_to_xyL(
+ own_private_dh_key,
+ peer_public_dh_key,
+ shared_dh_key,
+ prime,
+ prime_length,
+ group_generator,
+ group_generator_length));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+void eap_am_crypto_symbian_c::generate_g_power_to_xyL(
+ const eap_variable_data_c * const own_private_dh_key,
+ const eap_variable_data_c * const peer_public_dh_key,
+ eap_variable_data_c * const shared_dh_key,
+ const u8_t * const prime,
+ const u32_t prime_length,
+ const u8_t * const group_generator,
+ const u32_t group_generator_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_status_e status(eap_status_ok);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("peer_public_dh_key"),
+ peer_public_dh_key->get_data(peer_public_dh_key->get_data_length()),
+ peer_public_dh_key->get_data_length()));
+
+
+ // PUBLIC KEY
+ TPtrC8 peer_key(
+ peer_public_dh_key->get_data(peer_public_dh_key->get_data_length()),
+ peer_public_dh_key->get_data_length());
+ if (peer_key.Ptr() == 0)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ RInteger Y = RInteger::NewL(peer_key);
+ CleanupStack::PushL(Y);
+
+
+ TPtrC8 peer_prime(
+ prime,
+ prime_length);
+ if (peer_prime.Ptr() == 0)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ RInteger N = RInteger::NewL(peer_prime);
+ CleanupStack::PushL(N);
+
+ TPtrC8 peer_generator(
+ group_generator,
+ group_generator_length);
+ if (peer_prime.Ptr() == 0)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ RInteger G = RInteger::NewL(peer_generator);
+ CleanupStack::PushL(G);
+
+ CDHPublicKey* publicKey = CDHPublicKey::NewL(N, G, Y);
+ CleanupStack::Pop(&G); // The parameters are freed by CDHPublicKey
+ CleanupStack::Pop(&N); // The parameters are freed by CDHPublicKey
+ CleanupStack::Pop(&Y); // The parameters are freed by CDHPublicKey
+ CleanupStack::PushL(publicKey);
+
+ // PRIVATE KEY
+ RInteger Npriv = RInteger::NewL(peer_prime);
+ CleanupStack::PushL(Npriv);
+
+ RInteger Gpriv = RInteger::NewL(peer_generator); // !
+ CleanupStack::PushL(Gpriv);
+
+ TPtrC8 private_key(
+ own_private_dh_key->get_data(own_private_dh_key->get_data_length()),
+ own_private_dh_key->get_data_length());
+ if (private_key.Ptr() == 0)
+ {
+ User::Leave(KErrArgument);
+ }
+ RInteger x = RInteger::NewL(private_key);
+ CleanupStack::PushL(x);
+
+ CDHPrivateKey* privateKey = CDHPrivateKey::NewL(Npriv, Gpriv, x);
+ CleanupStack::Pop(&x);
+ CleanupStack::Pop(&Gpriv);
+ CleanupStack::Pop(&Npriv);
+ CleanupStack::PushL(privateKey);
+
+ CDH* dh = CDH::NewL(*privateKey);
+ CleanupStack::PushL(dh);
+
+ // Have to do const_cast so that the object can be pushed... strange...
+ HBufC8* p = const_cast<HBufC8*>(dh->AgreeL(*publicKey));
+ CleanupStack::PushL(p);
+
+ // Copy the shared key
+ status = shared_dh_key->set_copy_of_buffer(const_cast<HBufC8*>(p)->Des().Ptr(), p->Length());
+ if (status != eap_status_ok)
+ {
+ User::Leave(KErrNoMemory);
+ }
+
+ CleanupStack::PopAndDestroy(p); // p, dh, publicKey, privateKey
+ CleanupStack::PopAndDestroy(dh); // p, dh, publicKey, privateKey
+ CleanupStack::PopAndDestroy(privateKey); // p, dh, publicKey, privateKey
+ CleanupStack::PopAndDestroy(publicKey); // p, dh, publicKey, privateKey
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL(" shared_dh_key"),
+ shared_dh_key->get_data(shared_dh_key->get_data_length()),
+ shared_dh_key->get_data_length()));
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dh_cleanup(
+ const eap_variable_data_c * const /*dh_context*/)
+{
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha_256_digest_length(
+ eap_variable_data_c * const sha_256_context)
+{
+ eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ return sha_256->get_digest_length();
+}
+
+//--------------------------------------------------
+
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha_256_block_size(
+ eap_variable_data_c * const sha_256_context)
+{
+ eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ return sha_256->get_block_size();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_init(
+ eap_variable_data_c * const sha_256_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_am_crypto_sha_256_c * sha_256 = 0;
+
+ if (sha_256_context->get_is_valid_data() == true)
+ {
+ sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ }
+ }
+
+ eap_status_e status = eap_status_process_general_error;
+
+ if (sha_256 == 0)
+ {
+ sha_256 = new eap_am_crypto_sha_256_c(m_am_tools);
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ delete sha_256;
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ status = sha_256_context->set_buffer(sha_256, sizeof(sha_256), false, true);
+ if (status != eap_status_ok)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+
+ status = sha_256->hash_init();
+ if (status != eap_status_ok)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_update(
+ eap_variable_data_c * const sha_256_context,
+ const u8_t * const data,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(sha_256_context->get_is_valid_data() == true);
+
+ eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = sha_256->hash_update(
+ data,
+ data_length);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("ERROR: eap_am_crypto_symbian_c::sha_256_update(), failed status = %d\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_final(
+ eap_variable_data_c * const sha_256_context,
+ u8_t * const message_digest,
+ u32_t *md_length_or_null)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(sha_256_context->get_is_valid_data() == true);
+
+ eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = sha_256->hash_final(
+ message_digest,
+ md_length_or_null);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("ERROR: eap_am_crypto_symbian_c::sha_256_final(), failed status = %d\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_cleanup(
+ eap_variable_data_c * const sha_256_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(sha_256_context->get_is_valid_data() == true);
+
+ eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ }
+
+ delete sha_256;
+
+ sha_256_context->reset();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha_256_copy_context(
+ eap_variable_data_c * const copied_sha_256_context,
+ const eap_variable_data_c * const original_sha_256_context)
+{
+ eap_am_crypto_sha_256_c * const sha_256 = reinterpret_cast<eap_am_crypto_sha_256_c *>(
+ original_sha_256_context->get_data(sizeof(eap_am_crypto_sha_256_c * const)));
+ if (sha_256 == 0
+ || sha_256->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_sha_256_c * const sha_256_copy = sha_256->copy();
+ if (sha_256_copy == 0
+ || sha_256_copy->get_is_valid() == false)
+ {
+ delete sha_256_copy;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = copied_sha_256_context->set_buffer(sha_256_copy, sizeof(sha_256_copy), false, true);
+
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha1_digest_length(
+ eap_variable_data_c * const sha1_context)
+{
+ eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ if (sha1 == 0
+ || sha1->get_is_valid() == false)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ return sha1->get_digest_length();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_sha1_block_size(
+ eap_variable_data_c * const sha1_context)
+{
+ eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ if (sha1 == 0
+ || sha1->get_is_valid() == false)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ return sha1->get_block_size();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_init(
+ eap_variable_data_c * const sha1_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ eap_status_e status = eap_status_process_general_error;
+
+ eap_am_crypto_sha1_c * sha1 = 0;
+
+ if (sha1_context->get_is_valid_data() == true)
+ {
+ sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ if (sha1 != 0
+ && sha1->get_is_valid() == false)
+ {
+ // Delete old invalid context.
+ status = sha1_cleanup(sha1_context);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ // Next we allocate new context.
+ sha1 = 0;
+ }
+
+ }
+ else
+ {
+ // There are no context.
+ // We will allocate a new one.
+ }
+
+ if (sha1 == 0)
+ {
+ sha1 = new eap_am_crypto_sha1_c(m_am_tools);
+ if (sha1 == 0
+ || sha1->get_is_valid() == false)
+ {
+ delete sha1;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ status = sha1_context->set_buffer(sha1, sizeof(*sha1), false, true);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+
+ status = sha1->hash_init();
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_update(
+ eap_variable_data_c * const sha1_context,
+ const u8_t * const data,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ if (sha1 == 0
+ || sha1->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = sha1->hash_update(
+ data,
+ data_length);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_final(
+ eap_variable_data_c * const sha1_context,
+ u8_t * const message_digest,
+ u32_t *md_length_or_null)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ if (sha1 == 0
+ || sha1->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = sha1->hash_final(
+ message_digest,
+ md_length_or_null);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_cleanup(
+ eap_variable_data_c * const sha1_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(sha1_context != 0);
+ EAP_ASSERT(sha1_context->get_is_valid() == true);
+ if (sha1_context == 0
+ || sha1_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ delete sha1;
+
+ sha1_context->reset();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::sha1_copy_context(
+ eap_variable_data_c * const copied_sha1_context,
+ const eap_variable_data_c * const original_sha1_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_am_crypto_sha1_c * const sha1 = reinterpret_cast<eap_am_crypto_sha1_c *>(
+ original_sha1_context->get_data(sizeof(eap_am_crypto_sha1_c)));
+
+ if (sha1 == 0
+ || sha1->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_sha1_c * const sha1_copy = sha1->copy();
+
+ if (sha1_copy == 0
+ || sha1_copy->get_is_valid() == false)
+ {
+ delete sha1_copy;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = copied_sha1_context->set_buffer(sha1_copy, sizeof(*sha1_copy), false, true);
+
+ if (status != eap_status_ok)
+ {
+ delete sha1_copy;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::aes_key_length()
+{
+ return AES_KEY_SIZE;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::aes_block_size()
+{
+ return AES_BLOCK_SIZE;
+}
+
+
+//--------------------------------------------------
+
+// NOTE ::dss_pseudo_random is implemented in am/common/DSS_random/dss_random.cpp.
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dss_pseudo_random(
+ u8_t *out,
+ u32_t out_length,
+ u8_t *xkey,
+ u32_t xkey_length)
+{
+ eap_status_e status = ::dss_pseudo_random(m_am_tools, out, out_length, xkey, xkey_length);
+ return status;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::open_crypto_memory_leaks()
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void eap_am_crypto_symbian_c::close_crypto_memory_leaks()
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_set_key(eap_variable_data_c * const rc4_context,
+ const eap_variable_data_c * const key)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ if (key == 0
+ || key->get_is_valid_data() == false
+ || key->get_data_length() == 0
+ || rc4_context == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_rc4_c * const rc4 = new eap_am_crypto_rc4_c(m_am_tools);
+ if (rc4 == 0
+ || rc4->get_is_valid() == false)
+ {
+ delete rc4;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ eap_status_e status = rc4->set_key(key);
+ if (status != eap_status_ok)
+ {
+ delete rc4;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ if (rc4_context->get_is_valid_data() == true)
+ {
+ status = rc4_cleanup(rc4_context);
+ if (status != eap_status_ok)
+ {
+ delete rc4;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+ }
+
+ status = rc4_context->set_buffer(rc4, sizeof(*rc4), false, true);
+ if (status != eap_status_ok)
+ {
+ delete rc4;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_cleanup(
+ eap_variable_data_c * const rc4_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(rc4_context != 0);
+ EAP_ASSERT(rc4_context->get_is_valid() == true);
+ if (rc4_context == 0
+ || rc4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
+ rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
+
+ delete rc4;
+
+ rc4_context->reset();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_encrypt(
+ const eap_variable_data_c * const rc4_context,
+ void * const data_in_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(rc4_context != 0);
+ EAP_ASSERT(rc4_context->get_is_valid() == true);
+ if (rc4_context == 0
+ || rc4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
+ rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
+
+ if (rc4 == 0
+ || rc4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ eap_status_e status = rc4->encrypt_data(
+ data_in_out,
+ data_in_out,
+ data_length);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_encrypt(
+ const eap_variable_data_c * const rc4_context,
+ const void * const data_in,
+ void * const data_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(rc4_context != 0);
+ EAP_ASSERT(rc4_context->get_is_valid() == true);
+ if (rc4_context == 0
+ || rc4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
+ rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
+
+ if (rc4 == 0
+ || rc4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ eap_status_e status = rc4->encrypt_data(
+ data_in,
+ data_out,
+ data_length);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_decrypt(
+ const eap_variable_data_c * const rc4_context,
+ void * const data_in_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(rc4_context != 0);
+ EAP_ASSERT(rc4_context->get_is_valid() == true);
+ if (rc4_context == 0
+ || rc4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
+ rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
+
+ if (rc4 == 0
+ || rc4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ eap_status_e status = rc4->decrypt_data(
+ data_in_out,
+ data_in_out,
+ data_length);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rc4_decrypt(
+ const eap_variable_data_c * const rc4_context,
+ const void * const data_in,
+ void * const data_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(rc4_context != 0);
+ EAP_ASSERT(rc4_context->get_is_valid() == true);
+ if (rc4_context == 0
+ || rc4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_rc4_c * const rc4 = reinterpret_cast<eap_am_crypto_rc4_c *>(
+ rc4_context->get_data(sizeof(eap_am_crypto_rc4_c)));
+
+ if (rc4 == 0
+ || rc4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ eap_status_e status = rc4->decrypt_data(
+ data_in,
+ data_out,
+ data_length);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_init(
+ eap_variable_data_c * const rsa_context)
+{
+ EAP_UNREFERENCED_PARAMETER(rsa_context);
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_status_e status = rsa_context->init(0);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ rsa_context->set_is_valid();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_public_key(
+ eap_variable_data_c * const rsa_context,
+ const eap_variable_data_c * const public_rsa_key,
+ const eap_variable_data_c * const input_data,
+ eap_variable_data_c * const output_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_key(), begins.\n")));
+
+ eap_status_e status = eap_status_ok;
+
+ TRAPD(err, rsa_encrypt_with_public_keyL(
+ rsa_context,
+ public_rsa_key,
+ input_data,
+ output_data));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_key() failed, status %d.\n"),
+ status));
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+void eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const public_rsa_key,
+ const eap_variable_data_c * const input_data,
+ eap_variable_data_c * const output_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), begins.\n")));
+
+ TPtrC8 ptr(
+ public_rsa_key->get_data(public_rsa_key->get_data_length()),
+ public_rsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, public_rsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The public_rsa_key is ASN.1 encoded.
+ // SEQUENCE {
+ // INTEGER modulus
+ // INTEGER exponent
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLC().\n")));
+
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(0);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 m = gen->Encoding();
+ if (m.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ RInteger modulus = asn1.DecodeDERLongL(m, pos);
+ CleanupStack::PushL(modulus);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 e = gen->Encoding();
+ if (e.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ RInteger exponent = asn1.DecodeDERLongL(e, pos);
+ CleanupStack::PushL(exponent);
+
+ TPtrC8 input(
+ input_data->get_data(input_data->get_data_length()),
+ input_data->get_data_length());
+ if (input.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, input_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ // The length of the ciphertext in RSA is the next multiple of block size.
+ TUint output_data_length = ((input_data->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount();
+ eap_status_e status = output_data->init(output_data_length);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, output_data is invalid, status %d.\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrNoMemory);
+ }
+
+ output_data->set_is_valid();
+ output_data->set_data_length(output_data_length);
+ TPtr8 output(
+ output_data->get_data(output_data->get_data_length()),
+ output_data->get_data_length());
+ if (output.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL() failed, output_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ CRSAPublicKey* public_key = CRSAPublicKey::NewL(modulus, exponent);
+ CleanupStack::Pop(&exponent); // Exponent, modulus are freed by CRSAPublicKey
+ CleanupStack::Pop(&modulus); // Exponent, modulus are freed by CRSAPublicKey
+ CleanupStack::PushL(public_key);
+
+ CRSAPKCS1v15Encryptor* rsa_encryptor = CRSAPKCS1v15Encryptor::NewL(*public_key);
+ CleanupStack::PushL(rsa_encryptor);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), before EncryptL().\n")));
+
+ rsa_encryptor->EncryptL(input, output);
+
+ output_data->set_data_length(output.Length());
+
+ CleanupStack::PopAndDestroy(rsa_encryptor);
+ CleanupStack::PopAndDestroy(public_key);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_public_keyL(), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_public_key(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const /*public_rsa_key*/,
+ const eap_variable_data_c * const /*input_data*/,
+ eap_variable_data_c * const /*output_data*/)
+{
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_key(), begins.\n")));
+
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+}
+
+void eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const public_rsa_key,
+ const eap_variable_data_c * const input_data,
+ eap_variable_data_c * const output_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), begins.\n")));
+
+ TPtrC8 ptr(
+ public_rsa_key->get_data(public_rsa_key->get_data_length()),
+ public_rsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, public_rsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The public_rsa_key is ASN.1 encoded.
+ // SEQUENCE {
+ // INTEGER modulus
+ // INTEGER exponent
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLC().\n")));
+
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(0);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 m = gen->Encoding();
+ if (m.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ RInteger modulus = asn1.DecodeDERLongL(m, pos);
+ CleanupStack::PushL(modulus);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 e = gen->Encoding();
+ if (e.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ RInteger exponent = asn1.DecodeDERLongL(e, pos);
+ CleanupStack::PushL(exponent);
+
+ TPtrC8 input(
+ input_data->get_data(input_data->get_data_length()),
+ input_data->get_data_length());
+ if (input.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, input_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ // The length of the plaintext is equal or less than the ciphertext length.
+ TUint output_data_length = input_data->get_data_length();
+ eap_status_e status = output_data->init(output_data_length);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, output_data is invalid, status %d.\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrNoMemory);
+ }
+ output_data->set_is_valid();
+ output_data->set_data_length(output_data_length);
+
+ TPtr8 output(
+ output_data->get_data(output_data->get_data_length()),
+ output_data->get_data_length());
+ if (output.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL() failed, output_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ // The key is actually public key but the class still needs to be CRSAPrivateKey for decryption
+ CleanupStack::Pop(&exponent); // Next class frees the integers
+ CleanupStack::Pop(&modulus); // Next class frees the integers
+
+ CRSAPrivateKeyStandard* public_key = CRSAPrivateKeyStandard::NewL(modulus, exponent);
+ CleanupStack::PushL(public_key);
+
+ CRSAPKCS1v15Decryptor* rsa_decryptor = CRSAPKCS1v15Decryptor::NewL(*public_key);
+ CleanupStack::PushL(rsa_decryptor);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), before DecryptL().\n")));
+
+ rsa_decryptor->DecryptL(input, output);
+
+ // Set the real data length
+ output_data->set_data_length(output.Length());
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_public_keyL(), OK.\n")));
+
+ CleanupStack::PopAndDestroy(rsa_decryptor);
+ CleanupStack::PopAndDestroy(public_key);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+}
+
+//--------------------------------------------------
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_encrypt_with_private_key(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const /*private_rsa_key*/,
+ const eap_variable_data_c * const /*input_data*/,
+ eap_variable_data_c * const /*output_data*/)
+{
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_key(), begins.\n")));
+
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+}
+
+
+void eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const private_rsa_key,
+ const eap_variable_data_c * const input_data,
+ eap_variable_data_c * const output_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), begins.\n")));
+
+ TPtrC8 ptr(
+ private_rsa_key->get_data(private_rsa_key->get_data_length()),
+ private_rsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, private_rsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The private_rsa_key is ASN.1 encoded.
+ // SEQUENCE {
+ // INTEGER modulus
+ // INTEGER public_exponent
+ // INTEGER private_exponent
+ // ...
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+
+ RInteger modulus;
+ RInteger private_exponent;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLC().\n")));
+
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 m = gen->Encoding();
+ if (m.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ modulus = asn1.DecodeDERLongL(m, pos);
+ CleanupStack::PushL(modulus);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(3);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 priv_e = gen->Encoding();
+ if (priv_e.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ private_exponent = asn1.DecodeDERLongL(priv_e, pos);
+ CleanupStack::PushL(private_exponent);
+
+ TPtrC8 input(
+ input_data->get_data(input_data->get_data_length()),
+ input_data->get_data_length());
+ if (input.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, input_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ // The length of the ciphertext in RSA is the next multiple of block size.
+ TUint output_data_length = ((input_data->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount();
+ eap_status_e status = output_data->init(output_data_length);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, output_data is invalid, status %d.\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrNoMemory);
+ }
+ output_data->set_is_valid();
+ output_data->set_data_length(output_data_length);
+
+ TPtr8 output(
+ output_data->get_data(output_data->get_data_length()),
+ output_data->get_data_length());
+ if (output.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL() failed, output_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ CleanupStack::Pop(&private_exponent); // private exponent & modulus are freed by the next class
+ CleanupStack::Pop(&modulus); // private exponent & modulus are freed by the next class
+ CRSAPublicKey* private_key = CRSAPublicKey::NewL(modulus, private_exponent);
+ CleanupStack::PushL(private_key);
+
+ CRSAPKCS1v15Encryptor* rsa_encryptor = CRSAPKCS1v15Encryptor::NewL(*private_key);
+ CleanupStack::PushL(rsa_encryptor);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), before EncryptL().\n")));
+
+ rsa_encryptor->EncryptL(input, output);
+
+ output_data->set_data_length(output.Length());
+
+ CleanupStack::PopAndDestroy(rsa_encryptor);
+ CleanupStack::PopAndDestroy(private_key);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_encrypt_with_private_keyL(), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+}
+
+//--------------------------------------------------
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_decrypt_with_private_key(
+ eap_variable_data_c * const rsa_context,
+ const eap_variable_data_c * const private_rsa_key,
+ const eap_variable_data_c * const input_data,
+ eap_variable_data_c * const output_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_key(), begins.\n")));
+
+ eap_status_e status = eap_status_ok;
+ TRAPD(err, rsa_decrypt_with_private_keyL(
+ rsa_context,
+ private_rsa_key,
+ input_data,
+ output_data));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_key() failed, err %d, status %d.\n"),
+ err,
+ status));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+void eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const private_rsa_key,
+ const eap_variable_data_c * const input_data,
+ eap_variable_data_c * const output_data)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), begins.\n")));
+
+ TPtrC8 ptr(
+ private_rsa_key->get_data(private_rsa_key->get_data_length()),
+ private_rsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, private_rsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The private_rsa_key is ASN.1 encoded.
+ // SEQUENCE {
+ // INTEGER modulus
+ // INTEGER public_exponent
+ // INTEGER private_exponent
+ // ...
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+ RInteger modulus;
+ RInteger private_exponent;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLC().\n")));
+
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 m = gen->Encoding();
+ if (m.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ modulus = asn1.DecodeDERLongL(m, pos);
+ CleanupStack::PushL(modulus);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(3);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 priv_e = gen->Encoding();
+ if (priv_e.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ private_exponent = asn1.DecodeDERLongL(priv_e, pos);
+ CleanupStack::PushL(private_exponent);
+
+ TPtrC8 input(
+ input_data->get_data(input_data->get_data_length()),
+ input_data->get_data_length());
+ if (input.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, input_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The length of the plaintext is equal or less than the ciphertext length.
+ TUint output_data_length = input_data->get_data_length();
+ eap_status_e status = output_data->init(output_data_length);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, output_data is invalid, status %d.\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrNoMemory);
+ }
+ output_data->set_is_valid();
+ output_data->set_data_length(output_data_length);
+
+ TPtr8 output(
+ output_data->get_data(output_data->get_data_length()),
+ output_data->get_data_length());
+ if (output.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL() failed, output_data is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ CRSAPrivateKey* private_key = CRSAPrivateKeyStandard::NewL(modulus, private_exponent);
+
+ CleanupStack::Pop(&private_exponent); // modulus & private_exponent are freed CRSAPrivateKey
+ CleanupStack::Pop(&modulus); // modulus & private_exponent are freed CRSAPrivateKey
+ CleanupStack::PushL(private_key);
+
+ CRSAPKCS1v15Decryptor* rsa_decryptor = CRSAPKCS1v15Decryptor::NewL(*private_key);
+ CleanupStack::PushL(rsa_decryptor);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), before DecryptL().\n")));
+
+ rsa_decryptor->DecryptL(input, output);
+
+ // Now set the correct length
+ output_data->set_data_length(output.Length());
+
+ CleanupStack::PopAndDestroy(rsa_decryptor);
+ CleanupStack::PopAndDestroy(private_key);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_decrypt_with_private_keyL(), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+}
+
+//--------------------------------------------------
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_sign(
+ eap_variable_data_c * const rsa_context,
+ const eap_variable_data_c * const private_rsa_key,
+ const eap_variable_data_c * const hash,
+ eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_sign(), begins.\n")));
+
+ eap_status_e status = eap_status_ok;
+
+ TRAPD(err, rsa_signL(
+ rsa_context,
+ private_rsa_key,
+ hash,
+ signed_hash));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_sign() failed, err %d, status %d.\n"),
+ err,
+ status));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+eap_status_e eap_am_crypto_symbian_c::rsa_signL(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const private_rsa_key,
+ const eap_variable_data_c * const hash,
+ eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL(), begins.\n")));
+
+ TPtrC8 ptr(
+ private_rsa_key->get_data(private_rsa_key->get_data_length()),
+ private_rsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, private_rsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The private_rsa_key is ASN.1 encoded.
+ // SEQUENCE {
+ // INTEGER modulus
+ // INTEGER public_exponent
+ // INTEGER private_exponent
+ // ...
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+
+ RInteger modulus;
+ RInteger private_exponent;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLC().\n")));
+
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 m = gen->Encoding();
+ if (m.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ pos = 0;
+ modulus = asn1.DecodeDERLongL(m, pos);
+ CleanupStack::PushL(modulus);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(3);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 priv_e = gen->Encoding();
+ if (priv_e.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ private_exponent = asn1.DecodeDERLongL(priv_e, pos);
+ CleanupStack::PushL(private_exponent);
+
+ TPtrC8 input(
+ hash->get_data(hash->get_data_length()),
+ hash->get_data_length());
+ if (input.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ // The length of the ciphertext in RSA is the next multiple of block size.
+ TUint output_data_length = ((hash->get_data_length() / modulus.ByteCount()) + 1) * modulus.ByteCount();
+
+ eap_status_e status = signed_hash->init(output_data_length);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, signed_hash is invalid, status %d.\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrNoMemory);
+ }
+ signed_hash->set_is_valid();
+ signed_hash->set_data_length(output_data_length);
+
+ TPtr8 output(
+ signed_hash->get_data(signed_hash->get_data_length()),
+ signed_hash->get_data_length());
+ if (output.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL() failed, signed_hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ CleanupStack::Pop(&private_exponent); // private exponent & modulus are freed by the next class
+ CleanupStack::Pop(&modulus); // private exponent & modulus are freed by the next class
+ CRSAPrivateKeyStandard* private_key = CRSAPrivateKeyStandard::NewL(modulus, private_exponent);
+ CleanupStack::PushL(private_key);
+
+ CRSAPKCS1v15Signer* rsa_signer = CRSAPKCS1v15Signer::NewL(*private_key);
+ CleanupStack::PushL(rsa_signer);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL(), before SignL().\n")));
+
+ const CRSASignature* signature = rsa_signer->SignL(input);
+ const TInteger& sig = signature->S();
+
+ HBufC8* buf = sig.BufferLC();
+
+ output.Copy(*buf);
+ signed_hash->set_data_length(output.Length());
+
+ CleanupStack::PopAndDestroy(buf);
+ CleanupStack::PopAndDestroy(rsa_signer);
+ CleanupStack::PopAndDestroy(private_key);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_signL(), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_verify(
+ eap_variable_data_c * const rsa_context,
+ const eap_variable_data_c * const public_rsa_key,
+ const eap_variable_data_c * const hash,
+ const eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verify(), begins.\n")));
+
+ eap_status_e status = eap_status_ok;
+
+ TRAPD(err, rsa_verifyL(
+ rsa_context,
+ public_rsa_key,
+ hash,
+ signed_hash));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verify() failed, err %d, status %d.\n"),
+ err,
+ status));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+eap_status_e eap_am_crypto_symbian_c::rsa_verifyL(
+ eap_variable_data_c * const /*rsa_context*/,
+ const eap_variable_data_c * const public_rsa_key,
+ const eap_variable_data_c * const hash,
+ const eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ TPtrC8 ptr(
+ public_rsa_key->get_data(public_rsa_key->get_data_length()),
+ public_rsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, public_rsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ // The public_rsa_key is ASN.1 encoded.
+ // SEQUENCE {
+ // INTEGER modulus
+ // INTEGER exponent
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLC().\n")));
+
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(0);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 m = gen->Encoding();
+ if (m.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ RInteger modulus = asn1.DecodeDERLongL(m, pos);
+ CleanupStack::PushL(modulus);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 e = gen->Encoding();
+ if (e.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ RInteger exponent = asn1.DecodeDERLongL(e, pos);
+ CleanupStack::PushL(exponent);
+
+ TPtrC8 p_hash(
+ hash->get_data(hash->get_data_length()),
+ hash->get_data_length());
+ if (p_hash.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 p_sig(
+ signed_hash->get_data(signed_hash->get_data_length()),
+ signed_hash->get_data_length());
+ if (p_sig.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL() failed, signed_hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ CRSAPublicKey* public_key = CRSAPublicKey::NewL(modulus, exponent);
+ // Modulus and exponent are popped here because CRSAPublicKey frees them
+ CleanupStack::Pop(&exponent);
+ CleanupStack::Pop(&modulus);
+ CleanupStack::PushL(public_key);
+
+ RInteger signature = RInteger::NewL(p_sig);
+ CleanupStack::PushL(signature);
+
+ CRSASignature* rsa_signature = CRSASignature::NewL(signature);
+ // signature is popped here because CRSASignature frees it
+ CleanupStack::Pop(&signature);
+ CleanupStack::PushL(rsa_signature);
+
+
+ CRSAPKCS1v15Verifier* rsa_verifier = CRSAPKCS1v15Verifier::NewL(*public_key);
+ CleanupStack::PushL(rsa_verifier);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), before VerifyL().\n")));
+
+ TBool result = rsa_verifier->VerifyL(p_hash, *rsa_signature);
+ eap_status_e status;
+ if (result)
+ {
+ // Verify successful
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_am_crypto_symbian: RSA verify successful.\n")));
+ status = eap_status_ok;
+ }
+ else
+ {
+ // Verify failed
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("eap_am_crypto_symbian: RSA verify failed.\n")));
+ status = eap_status_illegal_parameter;
+ }
+
+ CleanupStack::PopAndDestroy(rsa_verifier);
+ CleanupStack::PopAndDestroy(rsa_signature);
+ CleanupStack::PopAndDestroy(public_key);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::rsa_verifyL(), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::rsa_cleanup(
+ eap_variable_data_c * const /*rsa_context*/)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_init(
+ eap_variable_data_c * const dsa_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ eap_status_e status = dsa_context->init(0);
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ dsa_context->set_is_valid();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_sign(
+ eap_variable_data_c * const dsa_context,
+ const eap_variable_data_c * const private_dsa_key,
+ const eap_variable_data_c * const hash,
+ eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_sign(), begins.\n")));
+
+ eap_status_e status = eap_status_ok;
+
+ TRAPD(err, dsa_signL(
+ dsa_context,
+ private_dsa_key,
+ hash,
+ signed_hash));
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_sign() failed, err %d, status %d.\n"),
+ err,
+ status));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+void eap_am_crypto_symbian_c::dsa_signL(
+ eap_variable_data_c * const dsa_context,
+ const eap_variable_data_c * const private_dsa_key,
+ const eap_variable_data_c * const hash,
+ eap_variable_data_c * const signed_hash)
+{
+ EAP_UNREFERENCED_PARAMETER(dsa_context);
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), begins.\n")));
+
+ TPtrC8 ptr(
+ private_dsa_key->get_data(private_dsa_key->get_data_length()),
+ private_dsa_key->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, private_dsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ // The private_dsa_key is ASN.1 encoded and contains DSA parameters and public and private keys.
+ // It must be decoded before it can be used.
+ // SEQUENCE {
+ // INTEGER version
+ // INTEGER p
+ // INTEGER q
+ // INTEGER g
+ // INTEGER Y
+ // INTEGER X
+ // }
+ //
+ //
+ TASN1DecSequence seq;
+ TASN1DecInteger asn1;
+ TASN1DecGeneric* gen;
+ RInteger param_p;
+ RInteger param_q;
+ RInteger param_g;
+ RInteger public_key;
+ RInteger private_key;
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ TInt pos(0);
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 p = gen->Encoding();
+ if (p.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ param_p = asn1.DecodeDERLongL(p, pos);
+ CleanupStack::PushL(param_p);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(2);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 q = gen->Encoding();
+ if (q.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ param_q = asn1.DecodeDERLongL(q, pos);
+ CleanupStack::PushL(param_q);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(3);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 g = gen->Encoding();
+ if (g.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ param_g = asn1.DecodeDERLongL(g, pos);
+ CleanupStack::PushL(param_g);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(4);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 Y = gen->Encoding();
+ if (Y.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ public_key = asn1.DecodeDERLongL(Y, pos);
+ CleanupStack::PushL(public_key);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(5);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 X = gen->Encoding();
+ if (X.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ pos = 0;
+ private_key = asn1.DecodeDERLongL(X, pos);
+ CleanupStack::PushL(private_key);
+
+ CDSAPrivateKey* priv_key = CDSAPrivateKey::NewL(param_p, param_q, param_g, private_key);
+ CleanupStack::PushL(priv_key);
+
+ CDSASigner* signer = CDSASigner::NewL(*priv_key);
+ CleanupStack::PushL(signer);
+
+ TPtrC8 data(
+ hash->get_data(hash->get_data_length()),
+ hash->get_data_length());
+ if (data.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ const CDSASignature* signature = signer->SignL(data);
+
+ RInteger R = RInteger::NewL(signature->R());
+ CleanupStack::PushL(R);
+ RInteger S = RInteger::NewL(signature->S());
+ CleanupStack::PushL(S);
+
+ CASN1EncSequence* sequence = CASN1EncSequence::NewLC();
+ CASN1EncBigInt* enc_r = CASN1EncBigInt::NewLC(R);
+ CASN1EncBigInt* enc_s = CASN1EncBigInt::NewLC(S);
+
+ sequence->AddChildL(enc_r);
+
+ sequence->AddChildL(enc_s);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before NewLC().\n")));
+
+ HBufC8* buf = HBufC8::NewLC(sequence->LengthDER());
+ TPtr8 tmp = buf->Des();
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), before WriteDERL().\n")));
+
+ tmp.SetLength(sequence->LengthDER());
+ pos = 0;
+ sequence->WriteDERL(tmp, (TUint&) pos);
+
+ eap_status_e status = signed_hash->set_copy_of_buffer(tmp.Ptr(), tmp.Length());
+ if (status != eap_status_ok)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL() failed, signed_hash is invalid, status %d.\n"),
+ status));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrNoMemory);
+ }
+
+ CleanupStack::PopAndDestroy(buf);
+ CleanupStack::Pop(enc_s); // BigInts are deleted by the sequence
+ CleanupStack::Pop(enc_r); // BigInts are deleted by the sequence
+
+ CleanupStack::PopAndDestroy(sequence);
+ CleanupStack::PopAndDestroy(&S);
+ CleanupStack::PopAndDestroy(&R);
+ CleanupStack::PopAndDestroy(signer);
+ CleanupStack::PopAndDestroy(priv_key);
+ CleanupStack::PopAndDestroy(&private_key);
+ CleanupStack::PopAndDestroy(&public_key);
+ CleanupStack::PopAndDestroy(¶m_g);
+ CleanupStack::PopAndDestroy(¶m_q);
+ CleanupStack::PopAndDestroy(¶m_p);
+ CleanupStack::PopAndDestroy(arrayPtr);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_signL(), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_verify(
+ eap_variable_data_c * const dsa_context,
+ const eap_variable_data_c * const public_dsa_key,
+ const eap_variable_data_c * const dsa_param_p,
+ const eap_variable_data_c * const dsa_param_q,
+ const eap_variable_data_c * const dsa_param_g,
+ const eap_variable_data_c * const hash,
+ const eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verify(), begins.\n")));
+
+ eap_status_e status = eap_status_ok;
+
+ __UHEAP_MARK;
+ TRAPD(err, dsa_verifyL(
+ dsa_context,
+ public_dsa_key,
+ dsa_param_p,
+ dsa_param_q,
+ dsa_param_g,
+ hash,
+ signed_hash));
+ __UHEAP_MARKEND;
+ if (err != KErrNone)
+ {
+ status = ((m_am_tools)->convert_am_error_to_eapol_error(err));
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verify() failed, err %d, status %d.\n"),
+ err,
+ status));
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+void eap_am_crypto_symbian_c::dsa_verifyL(
+ eap_variable_data_c * const /*dsa_context*/,
+ const eap_variable_data_c * const public_dsa_key,
+ const eap_variable_data_c * const dsa_param_p,
+ const eap_variable_data_c * const dsa_param_q,
+ const eap_variable_data_c * const dsa_param_g,
+ const eap_variable_data_c * const hash,
+ const eap_variable_data_c * const signed_hash)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(1), begins.\n")));
+
+ // Parameters
+ TPtrC8 p(
+ dsa_param_p->get_data(dsa_param_p->get_data_length()),
+ dsa_param_p->get_data_length());
+ if (p.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(2) failed, dsa_param_p is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ TPtrC8 q(
+ dsa_param_q->get_data(dsa_param_q->get_data_length()),
+ dsa_param_q->get_data_length());
+ if (q.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(3) failed, dsa_param_q is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ TPtrC8 g(
+ dsa_param_g->get_data(dsa_param_g->get_data_length()),
+ dsa_param_g->get_data_length());
+ if (g.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(4) failed, dsa_param_g is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ RInteger P = RInteger::NewL(p);
+ CleanupStack::PushL(P);
+
+ RInteger Q = RInteger::NewL(q);
+ CleanupStack::PushL(Q);
+
+ RInteger G = RInteger::NewL(g);
+ CleanupStack::PushL(G);
+
+ TPtrC8 calculated_hash(
+ hash->get_data(hash->get_data_length()),
+ hash->get_data_length());
+ if (calculated_hash.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(5) failed, hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+
+ // Public key is ASN.1 encoded so it must be decoded
+ TPtrC8 pkey (
+ public_dsa_key->get_data(public_dsa_key->get_data_length()),
+ public_dsa_key->get_data_length());
+ if (pkey.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(6) failed, public_dsa_key is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TASN1DecInteger asn1;
+ TInt pos(0);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(7), before DecodeDERLongL().\n")));
+
+ RInteger public_key_int = asn1.DecodeDERLongL(
+ pkey,
+ pos);
+
+ CleanupStack::PushL(public_key_int);
+ CDSAPublicKey* pub_key = CDSAPublicKey::NewL(P, Q, G, public_key_int);
+ // RIntegers needs to be popped because CDSAPublicKey frees them
+ CleanupStack::Pop(&public_key_int);
+ CleanupStack::Pop(&G);
+ CleanupStack::Pop(&Q);
+ CleanupStack::Pop(&P);
+ CleanupStack::PushL(pub_key);
+
+ TPtrC8 ptr(
+ signed_hash->get_data(hash->get_data_length()),
+ signed_hash->get_data_length());
+ if (ptr.Ptr() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(8) failed, signed_hash is invalid.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(9), before DecodeDERLC().\n")));
+
+ TASN1DecSequence seq;
+ TASN1DecGeneric* gen;
+ RInteger R;
+ RInteger S;
+ CArrayPtrFlat<TASN1DecGeneric>* arrayPtr;
+ pos = 0;
+ arrayPtr = seq.DecodeDERLC(ptr, pos);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(10), before DecodeDERLongL().\n")));
+
+ gen = arrayPtr->At(0);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ TPtrC8 r = gen->Encoding();
+ if (r.Length() == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+ pos = 0;
+ R = asn1.DecodeDERLongL(r, pos);
+ CleanupStack::PushL(R);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(11), before arrayPtr->At(1).\n")));
+
+ gen = arrayPtr->At(1);
+ if (gen == 0)
+ {
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_ERROR,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL() failed, illegal data.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ User::Leave(KErrArgument);
+ }
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(12), before gen->Encoding().\n")));
+
+ TPtrC8 s = gen->Encoding();
+ pos = 0;
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(13), before DecodeDERLongL().\n")));
+
+ S = asn1.DecodeDERLongL(s, pos);
+ CleanupStack::PushL(S);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(14), before CDSASignature::NewL().\n")));
+
+ CDSASignature* signature = CDSASignature::NewL(R, S);
+ // Parameters needs to be popped because CDSASignature frees them
+ CleanupStack::Pop(&S);
+ CleanupStack::Pop(&R);
+ CleanupStack::PushL(signature);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(15), before CDSAVerifier::NewL().\n")));
+
+ CDSAVerifier* verifier = CDSAVerifier::NewL(*pub_key);
+ CleanupStack::PushL(verifier);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(16), before VerifyL().\n")));
+
+ TBool result = verifier->VerifyL(calculated_hash, *signature);
+ if (result == EFalse)
+ {
+ // Verify failed
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_ERROR, (EAPL("eap_am_crypto_symbian: DSA verify failed.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_ERROR);
+ User::Leave(KErrArgument);
+ }
+
+ EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_am_crypto_symbian: DSA verify successful.\n")));
+
+ CleanupStack::PopAndDestroy(verifier);
+ CleanupStack::PopAndDestroy(signature);
+ CleanupStack::PopAndDestroy(arrayPtr);
+ CleanupStack::PopAndDestroy(pub_key);
+
+ EAP_TRACE_DEBUG(
+ m_am_tools,
+ TRACE_FLAGS_DEFAULT,
+ (EAPL("eap_am_crypto_symbian_c::dsa_verifyL(17), OK.\n")));
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::dsa_cleanup(
+ eap_variable_data_c * const /*dsa_context*/)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md5_digest_length(
+ eap_variable_data_c * const md5_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md5_context->get_is_valid());
+
+ CMessageDigest *ctx = (CMessageDigest *)md5_context->get_data(md5_context->get_data_length());
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return ctx->HashSize();
+}
+
+//--------------------------------------------------
+
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md5_block_size(
+ eap_variable_data_c * const /* md5_context */)
+{
+ return MD5_BLOCK_SIZE;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_init(
+ eap_variable_data_c * const md5_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ CMessageDigest *md5 = 0;
+
+ TRAPD(ret, md5 = CMD5::NewL());
+
+ if (ret != KErrNone)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ if (md5_context->get_is_valid_data() == true)
+ {
+ md5_cleanup(md5_context);
+ }
+
+ eap_status_e status = md5_context->set_buffer(md5, sizeof(*md5), false, false);
+ if (status != eap_status_ok)
+ {
+ delete md5;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_update(
+ eap_variable_data_c * const md5_context,
+ const u8_t * const data,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md5_context != 0);
+ EAP_ASSERT(md5_context->get_is_valid() == true);
+ if (md5_context == 0
+ || md5_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest));
+
+ if (md5 == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ // This breaks the const type.
+ TPtr8 tmp(const_cast<u8_t *>(data), data_length, data_length);
+
+ md5->Hash(tmp);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_final(
+ eap_variable_data_c * const md5_context,
+ u8_t * const message_digest,
+ u32_t *md_length_or_null)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md5_context != 0);
+ EAP_ASSERT(md5_context->get_is_valid() == true);
+ if (md5_context == 0
+ || md5_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest));
+
+ if (md5 == 0
+ || message_digest == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ if (md_length_or_null != 0)
+ {
+ *md_length_or_null = md5->HashSize();
+ }
+
+ TPtrC8 digest = md5->Hash(TPtrC8(0,0));
+
+ if (digest.Ptr() == 0)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ m_am_tools->memmove(message_digest, digest.Ptr(), md5->HashSize());
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_cleanup(
+ eap_variable_data_c * const md5_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md5_context != 0);
+ EAP_ASSERT(md5_context->get_is_valid() == true);
+ if (md5_context == 0
+ || md5_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+
+ CMessageDigest *md5 = (CMessageDigest *)md5_context->get_data(sizeof(CMessageDigest));
+
+ delete md5;
+
+ md5_context->reset();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md5_copy_context(
+ eap_variable_data_c * const copied_md5_context,
+ const eap_variable_data_c * const original_md5_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ CMessageDigest *ctx_copy = 0;
+
+ if (original_md5_context == 0
+ || original_md5_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ CMessageDigest *ctx = (CMessageDigest *)original_md5_context->get_data(sizeof(CMessageDigest));
+
+ TRAPD(ret, ctx_copy = ctx->CopyL());
+
+ if (ret != KErrNone)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ eap_status_e status = copied_md5_context->set_buffer(ctx_copy, sizeof(*ctx_copy), false, false);
+ if (status != eap_status_ok)
+ {
+ delete ctx_copy;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md4_digest_length(
+ eap_variable_data_c * const md4_context)
+{
+ if (md4_context == 0
+ || md4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
+ md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
+
+ if (md4 == 0
+ || md4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ return md4->get_digest_length();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::get_md4_block_size(
+ eap_variable_data_c * const md4_context)
+{
+ if (md4_context == 0
+ || md4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
+ md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
+
+ if (md4 == 0
+ || md4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ return md4->get_block_size();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_init(
+ eap_variable_data_c * const md4_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ if (md4_context == 0)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ if (md4_context->get_is_valid_data() == true)
+ {
+ md4_cleanup(md4_context);
+ }
+
+ eap_am_crypto_md4_c * const md4 = new eap_am_crypto_md4_c(m_am_tools);
+ if (md4 == 0
+ || md4->get_is_valid() == false)
+ {
+ delete md4;
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ eap_status_e status = md4->hash_init();
+ if (status != eap_status_ok)
+ {
+ delete md4;
+ return EAP_STATUS_RETURN(m_am_tools, status);
+ }
+
+ if (md4_context->get_is_valid_data() == true)
+ {
+ md4_cleanup(md4_context);
+ }
+
+ status = md4_context->set_buffer(md4, sizeof(*md4), false, true);
+ if (status != eap_status_ok)
+ {
+ delete md4;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_update(
+ eap_variable_data_c * const md4_context,
+ const u8_t * const data,
+ const u32_t data_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md4_context != 0);
+ EAP_ASSERT(md4_context->get_is_valid() == true);
+ if (md4_context == 0
+ || md4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
+ md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
+
+ if (md4 == 0
+ || md4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = md4->hash_update(
+ data,
+ data_length);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_final(
+ eap_variable_data_c * const md4_context,
+ u8_t * const message_digest,
+ u32_t * md_length_or_null)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md4_context != 0);
+ EAP_ASSERT(md4_context->get_is_valid() == true);
+ if (md4_context == 0
+ || md4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
+ md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
+
+ if (md4 == 0
+ || md4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = md4->hash_final(
+ message_digest,
+ md_length_or_null);
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_cleanup(
+ eap_variable_data_c * const md4_context)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_ASSERT(md4_context != 0);
+ EAP_ASSERT(md4_context->get_is_valid() == true);
+ if (md4_context == 0
+ || md4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
+ md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
+
+ delete md4;
+
+ md4_context->reset();
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::md4_copy_context(
+ eap_variable_data_c * const copied_md4_context,
+ const eap_variable_data_c * const original_md4_context)
+{
+ if (original_md4_context == 0
+ || original_md4_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4 = reinterpret_cast<eap_am_crypto_md4_c *>(
+ original_md4_context->get_data(sizeof(eap_am_crypto_md4_c)));
+
+ if (md4 == 0
+ || md4->get_is_valid() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_am_crypto_md4_c * const md4_copy = md4->copy();
+ if (md4_copy == 0
+ || md4_copy->get_is_valid() == false)
+ {
+ delete md4_copy;
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ eap_status_e status = copied_md4_context->set_buffer(md4_copy, sizeof(*md4_copy), false, true);
+ if (status != eap_status_ok)
+ {
+ delete md4_copy;
+ }
+
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_set_encryption_key(
+ eap_variable_data_c * const aes_context,
+ const u8_t * const key, const u32_t key_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("encryption_key"),
+ key, key_length));
+
+ if (key_length != aes_key_length())
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ TPtrC8 aes_key(key, key_length);
+
+ CAESEncryptor* aes = 0;
+ TRAPD(err, aes = CAESEncryptor::NewL(aes_key));
+ if (err != KErrNone)
+ {
+ EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ // If context is already reserved then cleanup it.
+ if (aes_context->get_is_valid_data() == true)
+ {
+ aes_cleanup(aes_context);
+ }
+
+ eap_status_e status = aes_context->set_buffer(
+ aes,
+ sizeof(*aes),
+ false,
+ false);
+ if (status != eap_status_ok)
+ {
+ delete aes;
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_set_decryption_key(
+ eap_variable_data_c * const aes_context,
+ const u8_t * const key, const u32_t key_length)
+{
+ EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("decryption_key"),
+ key, key_length));
+
+ if (key_length != aes_key_length())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ TPtrC8 aes_key(key, key_length);
+
+ CAESDecryptor* aes = 0;
+ TRAPD(err, aes = CAESDecryptor::NewL(aes_key));
+ if (err != KErrNone)
+ {
+ EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ // If context is already reserved then cleanup it.
+ if (aes_context->get_is_valid_data() == true)
+ {
+ aes_cleanup(aes_context);
+ }
+
+ eap_status_e status = aes_context->set_buffer(
+ aes,
+ sizeof(*aes),
+ false,
+ false);
+ if (status != eap_status_ok)
+ {
+ delete aes;
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_cleanup(
+ eap_variable_data_c * const aes_context)
+{
+ EAP_ASSERT(aes_context != 0);
+ EAP_ASSERT(aes_context->get_is_valid() == true);
+ if (aes_context == 0
+ || aes_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ CRijndael* aes = reinterpret_cast<CRijndael *>(aes_context->get_data(sizeof(CRijndael)));
+
+ delete aes;
+
+ aes_context->reset();
+
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_encrypt_block(
+ eap_variable_data_c * const aes_context,
+ const u8_t * const data_in,
+ u8_t * const data_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_in"),
+ data_in, data_length));
+
+ if (data_length != aes_block_size())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_encryption_failure);
+ }
+
+ EAP_ASSERT(aes_context != 0);
+ EAP_ASSERT(aes_context->get_is_valid() == true);
+ if (aes_context == 0
+ || aes_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ CAESEncryptor* aes = (CAESEncryptor*)aes_context->get_data(sizeof(CAESEncryptor));
+ if (aes == 0)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ Mem::Copy(data_out, data_in, data_length);
+
+ TPtr8 ptr(data_out, data_length, data_length);
+
+ aes->Transform(ptr);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_out"),
+ data_out, data_length));
+
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::aes_decrypt_block(
+ eap_variable_data_c * const aes_context,
+ const u8_t * const data_in,
+ u8_t * const data_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_in"),
+ data_in, data_length));
+
+ if (data_length != aes_block_size())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_decryption_failure);
+ }
+
+ EAP_ASSERT(aes_context != 0);
+ EAP_ASSERT(aes_context->get_is_valid() == true);
+ if (aes_context == 0
+ || aes_context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ CAESDecryptor* aes = (CAESDecryptor*)aes_context->get_data(sizeof(CAESDecryptor));
+ if (aes == 0)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ // Copy input to output so we can transform it in the output buffer
+ Mem::Copy(data_out, data_in, data_length);
+
+ TPtr8 ptr(data_out, data_length, data_length);
+
+ aes->Transform(ptr);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("AES data_out"),
+ data_out, data_length));
+
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::key_length_3des_ede()
+{
+ return 3ul * BLOCK_SIZE_3DES_EDE;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t eap_am_crypto_symbian_c::block_size_3des_ede()
+{
+ return BLOCK_SIZE_3DES_EDE;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::set_encryption_key_3des_ede(
+ eap_variable_data_c * const context,
+ const u8_t * const key, const u32_t key_length)
+{
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("encryption_key"),
+ key, key_length));
+
+ if (key_length != key_length_3des_ede())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ TPtrC8 des_key(key, key_length);
+
+ C3DESEncryptor* ede_3des = 0;
+ TRAPD(err, ede_3des = C3DESEncryptor::NewL(des_key));
+ if (err != KErrNone)
+ {
+ EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ // If context is already reserved then cleanup it.
+ if (context->get_is_valid_data() == true)
+ {
+ cleanup_3des_ede(context);
+ }
+
+ eap_status_e status = context->set_buffer(
+ ede_3des,
+ sizeof(*ede_3des),
+ false,
+ false);
+ if (status != eap_status_ok)
+ {
+ delete ede_3des;
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::cleanup_3des_ede(
+ eap_variable_data_c * const context)
+{
+ EAP_ASSERT(context != 0);
+ EAP_ASSERT(context->get_is_valid() == true);
+ if (context == 0
+ || context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ C3DES* ede_3des = (C3DES*)context->get_data(sizeof(C3DES));
+
+ delete ede_3des;
+
+ context->reset();
+
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::set_decryption_key_3des_ede(
+ eap_variable_data_c * const context,
+ const u8_t * const key, const u32_t key_length)
+{
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("decryption_key"),
+ key, key_length));
+
+ if (key_length != key_length_3des_ede())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+ }
+
+ TPtrC8 des_key(key, key_length);
+
+ C3DESDecryptor* ede_3des = 0;
+ TRAPD(err, ede_3des = C3DESDecryptor::NewL(des_key));
+ if (err != KErrNone)
+ {
+ EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Probably weak crypto library installed. FATAL.\n")));
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+ }
+
+ // If context is already reserved then cleanup it.
+ if (context->get_is_valid_data() == true)
+ {
+ cleanup_3des_ede(context);
+ }
+
+ eap_status_e status = context->set_buffer( //
+ ede_3des,
+ sizeof(*ede_3des),
+ false,
+ false);
+ if (status != eap_status_ok)
+ {
+ delete ede_3des;
+ }
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+ return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::encrypt_block_3des_ede(
+ eap_variable_data_c * const context,
+ const u8_t * const data_in,
+ u8_t * const data_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE encrypt data_in"),
+ data_in, data_length));
+
+ if (data_length != block_size_3des_ede())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_encryption_failure);
+ }
+
+ EAP_ASSERT(context != 0);
+ EAP_ASSERT(context->get_is_valid() == true);
+ if (context == 0
+ || context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ C3DESEncryptor* ede_3des = (C3DESEncryptor*)context->get_data(sizeof(C3DESEncryptor));
+ if (ede_3des == 0)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ Mem::Copy(data_out, data_in, data_length);
+
+ TPtr8 ptr(data_out, data_length, data_length);
+
+ ede_3des->Transform(ptr);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE encrypt data_out"),
+ data_out, data_length));
+
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e eap_am_crypto_symbian_c::decrypt_block_3des_ede(
+ eap_variable_data_c * const context,
+ const u8_t * const data_in,
+ u8_t * const data_out,
+ const u32_t data_length)
+{
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE decrypt data_in"),
+ data_in, data_length));
+
+ if (data_length != block_size_3des_ede())
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_decryption_failure);
+ }
+
+ EAP_ASSERT(context != 0);
+ EAP_ASSERT(context->get_is_valid() == true);
+ if (context == 0
+ || context->get_is_valid_data() == false)
+ {
+ EAP_TRACE_END(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO);
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ C3DESDecryptor* ede_3des = (C3DESDecryptor*)context->get_data(sizeof(C3DESDecryptor));
+ if (ede_3des == 0)
+ {
+ return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+ }
+
+ Mem::Copy(data_out, data_in, data_length);
+
+ TPtr8 ptr(data_out, data_length, data_length);
+
+ ede_3des->Transform(ptr);
+
+ EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_EAP_AM_CRYPTO, (EAPL("3DES-EDE decrypt data_out"),
+ data_out, data_length));
+
+ return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+
+
+
+// End.