Initial commit 50/137050/1
authoru.harbuz <u.harbuz@samsung.com>
Thu, 4 May 2017 11:13:54 +0000 (13:13 +0200)
committerLukasz Kostyra <l.kostyra@samsung.com>
Tue, 4 Jul 2017 08:23:57 +0000 (10:23 +0200)
Change-Id: Ibd50eeba46cf910eb59bb45bc631b06c1e9bb742

317 files changed:
.cproject [new file with mode: 0644]
.project [new file with mode: 0644]
TEECLib/.cproject [new file with mode: 0755]
TEECLib/.gitignore [new file with mode: 0755]
TEECLib/.project [new file with mode: 0755]
TEECLib/.settings/language.settings.xml [new file with mode: 0755]
TEECLib/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
TEECLib/inc/teec_connection.h [new file with mode: 0755]
TEECLib/src/teec_api.c [new file with mode: 0755]
TEECLib/src/teec_connection.c [new file with mode: 0755]
TEEStub/.cproject [new file with mode: 0755]
TEEStub/.gitignore [new file with mode: 0755]
TEEStub/.project [new file with mode: 0755]
TEEStub/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
TEEStub/.settings/org.eclipse.cdt.ui.prefs [new file with mode: 0755]
TEEStub/.settings/org.eclipse.ltk.core.refactoring.prefs [new file with mode: 0755]
TEEStub/DeveloperReadme.txt [new file with mode: 0755]
TEEStub/PropertyAccess/ClientProperty.cpp [new file with mode: 0755]
TEEStub/PropertyAccess/ClientProperty.h [new file with mode: 0755]
TEEStub/PropertyAccess/Property.h [new file with mode: 0755]
TEEStub/PropertyAccess/PropertyApi.cpp [new file with mode: 0755]
TEEStub/PropertyAccess/PropertyApi.h [new file with mode: 0755]
TEEStub/PropertyAccess/PropertyUtility.cpp [new file with mode: 0755]
TEEStub/PropertyAccess/PropertyUtility.h [new file with mode: 0755]
TEEStub/PropertyAccess/TAProperty.cpp [new file with mode: 0755]
TEEStub/PropertyAccess/TAProperty.h [new file with mode: 0755]
TEEStub/PropertyAccess/TEEProperty.cpp [new file with mode: 0755]
TEEStub/PropertyAccess/TEEProperty.h [new file with mode: 0755]
TEEStub/PropertyAccess/rapidxml/rapidxml.hpp [new file with mode: 0755]
TEEStub/PropertyAccess/rapidxml/rapidxml_iterators.hpp [new file with mode: 0755]
TEEStub/PropertyAccess/rapidxml/rapidxml_print.hpp [new file with mode: 0755]
TEEStub/PropertyAccess/rapidxml/rapidxml_utils.hpp [new file with mode: 0755]
TEEStub/TACommands/CommandBase.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandBase.h [new file with mode: 0755]
TEEStub/TACommands/CommandCloseSession.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandCloseSession.h [new file with mode: 0755]
TEEStub/TACommands/CommandCreateEntryPoint.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandCreateEntryPoint.h [new file with mode: 0755]
TEEStub/TACommands/CommandDestroyEntryPoint.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandDestroyEntryPoint.h [new file with mode: 0755]
TEEStub/TACommands/CommandInvoke.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandInvoke.h [new file with mode: 0755]
TEEStub/TACommands/CommandOpenSession.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandOpenSession.h [new file with mode: 0755]
TEEStub/TACommands/CommandRequestCancel.cpp [new file with mode: 0755]
TEEStub/TACommands/CommandRequestCancel.h [new file with mode: 0755]
TEEStub/TACommands/MakeCommand.cpp [new file with mode: 0755]
TEEStub/TACommands/MakeCommand.h [new file with mode: 0755]
TEEStub/TACommands/SharedMemoryMap.cpp [new file with mode: 0755]
TEEStub/TACommands/SharedMemoryMap.h [new file with mode: 0755]
TEEStub/TEEStubServer/ConnectionSession.cpp [new file with mode: 0755]
TEEStub/TEEStubServer/ConnectionSession.h [new file with mode: 0755]
TEEStub/TEEStubServer/TAProperty.cpp [new file with mode: 0755]
TEEStub/TEEStubServer/TAProperty.h [new file with mode: 0755]
TEEStub/TEEStubServer/TEEStubServer.cpp [new file with mode: 0755]
TEEStub/TEEStubServer/TEEStubServer.h [new file with mode: 0755]
TEEStub/TaskStrategy/SessionState.cpp [new file with mode: 0755]
TEEStub/TaskStrategy/SessionState.h [new file with mode: 0755]
TEEStub/TaskStrategy/TaskQueuedStrategy.cpp [new file with mode: 0755]
TEEStub/TaskStrategy/TaskQueuedStrategy.h [new file with mode: 0755]
TEEStub/TaskStrategy/TaskStrategy.cpp [new file with mode: 0755]
TEEStub/TaskStrategy/TaskStrategy.h [new file with mode: 0755]
TEEStub/teestubmain.cpp [new file with mode: 0755]
build/TEECLib/makefile [new file with mode: 0755]
build/TEECLib/objects.mk [new file with mode: 0755]
build/TEECLib/sources.mk [new file with mode: 0755]
build/TEECLib/src/subdir.mk [new file with mode: 0755]
build/TEEStub/PropertyAccess/subdir.mk [new file with mode: 0755]
build/TEEStub/TACommands/subdir.mk [new file with mode: 0755]
build/TEEStub/TEEStubServer/subdir.mk [new file with mode: 0755]
build/TEEStub/TaskStrategy/subdir.mk [new file with mode: 0755]
build/TEEStub/makefile [new file with mode: 0755]
build/TEEStub/objects.mk [new file with mode: 0755]
build/TEEStub/sources.mk [new file with mode: 0755]
build/TEEStub/subdir.mk [new file with mode: 0755]
build/build.sh [new file with mode: 0755]
build/log/makefile [new file with mode: 0755]
build/log/objects.mk [new file with mode: 0755]
build/log/sources.mk [new file with mode: 0755]
build/log/subdir.mk [new file with mode: 0755]
build/osal/makefile [new file with mode: 0755]
build/osal/objects.mk [new file with mode: 0755]
build/osal/sources.mk [new file with mode: 0755]
build/osal/subdir.mk [new file with mode: 0755]
build/simulatordaemon/makefile [new file with mode: 0755]
build/simulatordaemon/objects.mk [new file with mode: 0755]
build/simulatordaemon/sources.mk [new file with mode: 0755]
build/simulatordaemon/src/ClientCommands/subdir.mk [new file with mode: 0755]
build/simulatordaemon/src/ResponseCommands/subdir.mk [new file with mode: 0755]
build/simulatordaemon/src/TABinaryManager/subdir.mk [new file with mode: 0755]
build/simulatordaemon/src/subdir.mk [new file with mode: 0755]
build/ssflib/dep/cryptocore/source/base/subdir.mk [new file with mode: 0755]
build/ssflib/dep/cryptocore/source/middle/subdir.mk [new file with mode: 0755]
build/ssflib/dep/cryptocore/source/subdir.mk [new file with mode: 0755]
build/ssflib/dep/swdss/source/subdir.mk [new file with mode: 0755]
build/ssflib/dep/time/subdir.mk [new file with mode: 0755]
build/ssflib/dep/uci/source/subdir.mk [new file with mode: 0755]
build/ssflib/makefile [new file with mode: 0755]
build/ssflib/objects.mk [new file with mode: 0755]
build/ssflib/sources.mk [new file with mode: 0755]
build/ssflib/src/subdir.mk [new file with mode: 0755]
include/.cproject [new file with mode: 0755]
include/.project [new file with mode: 0755]
include/.settings/language.settings.xml [new file with mode: 0755]
include/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
include/include/config.h [new file with mode: 0755]
include/include/tee_client_api.h [new file with mode: 0755]
include/include/tee_command.h [new file with mode: 0755]
include/include/tee_internal_api.h [new file with mode: 0755]
include/include/tee_sim_command.h [new file with mode: 0755]
include/include/teec_data.h [new file with mode: 0755]
include/include/teestub_command_data.h [new file with mode: 0755]
log/.cproject [new file with mode: 0755]
log/.gitignore [new file with mode: 0755]
log/.project [new file with mode: 0755]
log/.settings/language.settings.xml [new file with mode: 0755]
log/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
log/log.c [new file with mode: 0755]
log/log.h [new file with mode: 0755]
osal/.cproject [new file with mode: 0755]
osal/.gitignore [new file with mode: 0755]
osal/.project [new file with mode: 0755]
osal/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
osal/.settings/org.eclipse.cdt.managedbuilder.core.prefs [new file with mode: 0755]
osal/OsaCommon.c [new file with mode: 0755]
osal/OsaIpc.c [new file with mode: 0755]
osal/OsaLinuxUser.h [new file with mode: 0755]
osal/OsaQueue.c [new file with mode: 0755]
osal/OsaSem.c [new file with mode: 0755]
osal/OsaSignal.c [new file with mode: 0755]
osal/OsaTask.c [new file with mode: 0755]
osal/Osal.h [new file with mode: 0755]
simulatordaemon/.cproject [new file with mode: 0755]
simulatordaemon/.gitignore [new file with mode: 0755]
simulatordaemon/.project [new file with mode: 0755]
simulatordaemon/.settings/language.settings.xml [new file with mode: 0755]
simulatordaemon/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandBase.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandCloseSession.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandCloseTASession.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandFinContext.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandInitContext.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandInvokeCommand.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandInvokeTACommand.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandOpenSession.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandOpenTASession.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandPanic.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandRegSharedMem.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandRelSharedMem.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/CommandReqCancellation.h [new file with mode: 0755]
simulatordaemon/inc/ClientCommands/MakeCommand.h [new file with mode: 0755]
simulatordaemon/inc/ConnectionSession.h [new file with mode: 0755]
simulatordaemon/inc/IConnectionSession.h [new file with mode: 0644]
simulatordaemon/inc/ISession.h [new file with mode: 0644]
simulatordaemon/inc/ITAInstance.h [new file with mode: 0644]
simulatordaemon/inc/ResponseCommands/ResCommandBase.h [new file with mode: 0755]
simulatordaemon/inc/ResponseCommands/ResCommandCloseSession.h [new file with mode: 0755]
simulatordaemon/inc/ResponseCommands/ResCommandInvokeCommand.h [new file with mode: 0755]
simulatordaemon/inc/ResponseCommands/ResCommandOpenSession.h [new file with mode: 0755]
simulatordaemon/inc/ResponseCommands/ResCommandReqCancellation.h [new file with mode: 0755]
simulatordaemon/inc/ResponseCommands/ResMakeCommand.h [new file with mode: 0755]
simulatordaemon/inc/Session.h [new file with mode: 0755]
simulatordaemon/inc/SimulatorDaemonServer.h [new file with mode: 0755]
simulatordaemon/inc/TAFactory.h [new file with mode: 0755]
simulatordaemon/inc/TAInstance.h [new file with mode: 0755]
simulatordaemon/inc/TEEContext.h [new file with mode: 0755]
simulatordaemon/inc/ioService.h [new file with mode: 0755]
simulatordaemon/inc/path.h [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandCloseSession.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandCloseTASession.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandFinContext.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandInitContext.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandInvokeCommand.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandInvokeTACommand.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandOpenSession.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandOpenTASession.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandPanic.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandRegSharedMem.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandRelSharedMem.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/CommandReqCancellation.cpp [new file with mode: 0755]
simulatordaemon/src/ClientCommands/MakeCommand.cpp [new file with mode: 0755]
simulatordaemon/src/ConnectionSession.cpp [new file with mode: 0755]
simulatordaemon/src/RemoteSystemsTempFiles/.project [new file with mode: 0755]
simulatordaemon/src/ResponseCommands/ResCommandCloseSession.cpp [new file with mode: 0755]
simulatordaemon/src/ResponseCommands/ResCommandInvokeCommand.cpp [new file with mode: 0755]
simulatordaemon/src/ResponseCommands/ResCommandOpenSession.cpp [new file with mode: 0755]
simulatordaemon/src/ResponseCommands/ResCommandReqCancellation.cpp [new file with mode: 0755]
simulatordaemon/src/ResponseCommands/ResMakeCommand.cpp [new file with mode: 0755]
simulatordaemon/src/Session.cpp [new file with mode: 0755]
simulatordaemon/src/SimulatorDaemon.cpp [new file with mode: 0755]
simulatordaemon/src/SimulatorDaemonServer.cpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/.cproject [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/.project [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Config.h [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/TABinaryManager [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/TABinaryManager.d [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/TAManifest.d [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/TAUnpack.d [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/TestMain.d [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/makefile [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/objects.mk [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/sources.mk [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/Debug/subdir.mk [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TABinaryManager.cpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TABinaryManager.h [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TAManifest.cpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TAManifest.h [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TAUnpack.cpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TAUnpack.h [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/TestMain.cpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/rapidxml/rapidxml.hpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_iterators.hpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_print.hpp [new file with mode: 0755]
simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_utils.hpp [new file with mode: 0755]
simulatordaemon/src/TAFactory.cpp [new file with mode: 0755]
simulatordaemon/src/TAInstance.cpp [new file with mode: 0755]
simulatordaemon/src/TEEContext.cpp [new file with mode: 0755]
simulatordaemon/src/ioService.cpp [new file with mode: 0755]
simulatordaemon/src/rapidxml/rapidxml.hpp [new file with mode: 0755]
simulatordaemon/src/scripts/update_uuid_list.sh [new file with mode: 0755]
ssflib/.cproject [new file with mode: 0755]
ssflib/.gitignore [new file with mode: 0755]
ssflib/.project [new file with mode: 0755]
ssflib/.settings/org.eclipse.cdt.core.prefs [new file with mode: 0755]
ssflib/dep/cryptocore/include/CC_API.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/CC_Constants.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/CC_Context.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/CC_Type.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/CryptoCore.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_ANSI_x931.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_aes.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_bignum.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_des.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_ecc.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_fast_math.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_hash.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_md5.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_moo.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_pkcs1_v21.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_rc4.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_sha1.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_sha2.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/base/cc_snow2.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/drm_macro.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_cmac.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_dh.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_dsa.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_ecdh.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_ecdsa.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_hmac.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_rng.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_rsa.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_symmetric.h [new file with mode: 0755]
ssflib/dep/cryptocore/include/middle/cc_tdes.h [new file with mode: 0755]
ssflib/dep/cryptocore/source/CC_API.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_ANSI_x931.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_aes.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_bignum.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_des.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_ecc.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_fast_math.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_hash.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_md5.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_moo.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_pkcs1_v21.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_rc4.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_sha1.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_sha2.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/base/cc_snow2.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_cmac.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_dh.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_dsa.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_ecdh.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_ecdsa.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_hmac.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_rng.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_rsa.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_symmetric.c [new file with mode: 0755]
ssflib/dep/cryptocore/source/middle/cc_tdes.c [new file with mode: 0755]
ssflib/dep/swdss/include/file_op.h [new file with mode: 0755]
ssflib/dep/swdss/include/secure_file.h [new file with mode: 0755]
ssflib/dep/swdss/include/slog.h [new file with mode: 0755]
ssflib/dep/swdss/include/ss_api.h [new file with mode: 0755]
ssflib/dep/swdss/include/ss_crypto.h [new file with mode: 0755]
ssflib/dep/swdss/include/ss_misc.h [new file with mode: 0755]
ssflib/dep/swdss/include/ss_temp_store.h [new file with mode: 0755]
ssflib/dep/swdss/include/ss_types.h [new file with mode: 0755]
ssflib/dep/swdss/source/file_op.cpp [new file with mode: 0755]
ssflib/dep/swdss/source/secure_file.cpp [new file with mode: 0755]
ssflib/dep/swdss/source/ss_api.cpp [new file with mode: 0755]
ssflib/dep/swdss/source/ss_crypto.cpp [new file with mode: 0755]
ssflib/dep/swdss/source/ss_misc.cpp [new file with mode: 0755]
ssflib/dep/swdss/source/ss_temp_store.cpp [new file with mode: 0755]
ssflib/dep/time/ssf_time.cpp [new file with mode: 0755]
ssflib/dep/uci/include/uci_aes_xcbc_mac.h [new file with mode: 0755]
ssflib/dep/uci/include/uci_api.h [new file with mode: 0755]
ssflib/dep/uci/include/uci_cryptocore.h [new file with mode: 0755]
ssflib/dep/uci/include/uci_hwcrypto.h [new file with mode: 0755]
ssflib/dep/uci/include/uci_internal.h [new file with mode: 0755]
ssflib/dep/uci/include/uci_type.h [new file with mode: 0755]
ssflib/dep/uci/source/uci_aes_xcbc_mac.c [new file with mode: 0755]
ssflib/dep/uci/source/uci_api.c [new file with mode: 0755]
ssflib/dep/uci/source/uci_cryptocore.c [new file with mode: 0755]
ssflib/dep/uci/source/uci_hwcrypto.c [new file with mode: 0755]
ssflib/inc/app_debug.h [new file with mode: 0755]
ssflib/inc/ssf_client.h [new file with mode: 0755]
ssflib/inc/ssf_lib.h [new file with mode: 0755]
ssflib/inc/ssf_storage.h [new file with mode: 0755]
ssflib/src/app_debug.c [new file with mode: 0755]
ssflib/src/ssf_arithmetic.c [new file with mode: 0755]
ssflib/src/ssf_client.c [new file with mode: 0755]
ssflib/src/ssf_crypto.c [new file with mode: 0755]
ssflib/src/ssf_lib.c [new file with mode: 0755]
ssflib/src/ssf_malloc.c [new file with mode: 0755]
ssflib/src/ssf_panic.c [new file with mode: 0755]
ssflib/src/ssf_storage.c [new file with mode: 0755]
ssflib/src/ssf_taentrypoint.c [new file with mode: 0755]

diff --git a/.cproject b/.cproject
new file mode 100644 (file)
index 0000000..2e304b4
--- /dev/null
+++ b/.cproject
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="0.2061892542">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.2061892542" moduleId="org.eclipse.cdt.core.settings" name="Default">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration buildProperties="" description="" id="0.2061892542" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
+                                       <folderInfo id="0.2061892542." name="/" resourcePath="">
+                                               <toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.863250730" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
+                                                       <targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.863250730.1083387452" name=""/>
+                                                       <builder id="org.eclipse.cdt.build.core.settings.default.builder.1174681342" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
+                                                       <tool id="org.eclipse.cdt.build.core.settings.holder.libs.891674801" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
+                                                       <tool id="org.eclipse.cdt.build.core.settings.holder.339047950" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
+                                                               <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.781182995" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+                                                       </tool>
+                                                       <tool id="org.eclipse.cdt.build.core.settings.holder.1656449544" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
+                                                               <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.64834437" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+                                                       </tool>
+                                                       <tool id="org.eclipse.cdt.build.core.settings.holder.435370037" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
+                                                               <inputType id="org.eclipse.cdt.build.core.settings.holder.inType.414851423" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="simulator.null.1944047215" name="simulator"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="0.2061892542">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject>
diff --git a/.project b/.project
new file mode 100644 (file)
index 0000000..bc6a330
--- /dev/null
+++ b/.project
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>simulator</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/TEECLib/.cproject b/TEECLib/.cproject
new file mode 100755 (executable)
index 0000000..9a99562
--- /dev/null
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings>
+                                       <externalSetting>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/TEECLib"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/TEECLib/Debug"/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="teec" srcPrefixMapping="" srcRootPath=""/>
+                                       </externalSetting>
+                               </externalSettings>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactExtension="so" artifactName="teec" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.1189841724" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1800539002" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder buildPath="${workspace_loc:/TEECLib}/Debug" id="cdt.managedbuild.target.gnu.builder.base.1578534939" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.1386278298" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.211318763" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.1130680006" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.771109175" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.compiler.base.530538911" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1186814661" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.1044308771" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.misc.other.1976276135" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <option id="gnu.c.compiler.option.include.paths.1647572130" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/include/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/}/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.411646858" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.linker.base.1688991976" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
+                                                               <option defaultValue="true" id="gnu.c.link.option.shared.713890105" name="Shared (-shared)" superClass="gnu.c.link.option.shared" valueType="boolean"/>
+                                                               <option id="gnu.c.link.option.ldflags.1499133722" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="--sysroot=&quot;..\..\..\toolchain\windows\i386-linux-gnueabi-gcc-4.6\lib\gcc\i386-linux-gnueabi\4.6.4&quot;" valueType="string"/>
+                                                               <option id="gnu.c.link.option.paths.20152546" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal/Debug}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log/Debug}&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.c.link.option.libs.1068157777" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+                                                                       <listOptionValue builtIn="false" value="osal"/>
+                                                                       <listOptionValue builtIn="false" value="rt"/>
+                                                                       <listOptionValue builtIn="false" value="log"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.273194164" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1858335100" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <option defaultValue="true" id="gnu.cpp.link.option.shared.1879728922" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" valueType="boolean"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.1369784750" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1884926805" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.583311770">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.583311770" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.autotools.core.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.583311770" name="Release" parent="cdt.managedbuild.config.gnu.cross.exe.release.583311770">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.583311770." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1189971184" name="Cross GCC">
+                                                       <option id="cdt.managedbuild.option.gnu.cross.prefix.734225244" name="Prefix" superClass="cdt.managedbuild.option.gnu.cross.prefix" value="gg" valueType="string"/>
+                                                       <option id="cdt.managedbuild.option.gnu.cross.path.760604454" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" value="gg" valueType="string"/>
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.635799552" isAbstract="false" osList="all"/>
+                                                       <builder buildPath="${workspace_loc:/TEECLib}/Release" id="cdt.managedbuild.builder.gnu.cross.108915352" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder"/>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="TEECLib.cdt.managedbuild.target.gnu.cross.exe.600650852" name="Executable"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838;cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.;cdt.managedbuild.tool.gnu.cross.c.compiler.1098408817;cdt.managedbuild.tool.gnu.c.compiler.input.742060954">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.583311770;cdt.managedbuild.config.gnu.cross.exe.release.583311770.;cdt.managedbuild.tool.gnu.cross.c.compiler.1263751289;cdt.managedbuild.tool.gnu.c.compiler.input.184011538">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope" versionNumber="2">
+               <configuration configurationName="Windows-Debug">
+                       <resource resourceType="PROJECT" workspacePath="/TEECLib"/>
+               </configuration>
+               <configuration configurationName="Debug">
+                       <resource resourceType="PROJECT" workspacePath="/TEECLib"/>
+               </configuration>
+               <configuration configurationName="Release">
+                       <resource resourceType="PROJECT" workspacePath="/TEECLib"/>
+               </configuration>
+       </storageModule>
+</cproject>
diff --git a/TEECLib/.gitignore b/TEECLib/.gitignore
new file mode 100755 (executable)
index 0000000..3df573f
--- /dev/null
@@ -0,0 +1 @@
+/Debug/
diff --git a/TEECLib/.project b/TEECLib/.project
new file mode 100755 (executable)
index 0000000..6b5f6d3
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>TEECLib</name>
+       <comment></comment>
+       <projects>
+               <project>log</project>
+               <project>osal</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/TEECLib/.settings/language.settings.xml b/TEECLib/.settings/language.settings.xml
new file mode 100755 (executable)
index 0000000..a85d310
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838" name="Debug">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="231234145544" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.583311770" name="Release">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1987866778809" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.295131884" name="Windows-Debug">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="231234145544" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+</project>
diff --git a/TEECLib/.settings/org.eclipse.cdt.core.prefs b/TEECLib/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..40a6ba6
--- /dev/null
@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.1187618160/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.1187618160/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.295131884/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.295131884/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.295131884/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\Program Files (x86)\\Java\\jre1.8.0_45\\bin;C\:\\Program Files\\eclipse;C\:/Program Files/Java/jre1.8.0_31/bin/server;C\:/Program Files/Java/jre1.8.0_31/bin;C\:/Program Files/Java/jre1.8.0_31/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\csvn\\bin\\;C\:\\csvn\\Python25\\;C\:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files\\Diskeeper Corporation\\ExpressCache\\;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x64;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files (x86)\\WinSCP\\;C\:\\Program Files (x86)\\PuTTY;C\:\\Program Files\\Microsoft\\Web Platform Installer\\;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C\:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;C\:\\Program Files (x86)\\doxygen\\bin;C\:\\Program Files (x86)\\sfk168;C\:\\Program Files (x86)\\vlc-2.1.0;C\:\\Python27\\Scripts;C\:\\Program Files (x86)\\GnuWin32\\bin;C\:\\Python27;C\:\\Program Files (x86)\\Subversion\\bin;c\:\\Program Files\\Synergy;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\MinGW\\lib\\gcc\\mingw32\\4.8.1;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C\:\\Program Files (x86)\\GitExtensions\\;C\:\\Program Files\\Perforce;c\:\\Program Files\\Java\\jre1.8.0_31\\bin\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;D\:\\samsung-tv-sdk\\ide;${Path};D\:\\samsung-tv-sdk\\tools\\i386-linux-gnueabi-gcc-4.6\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.295131884/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838.295131884/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\GitExtensions\\;D\:\\Tizen\\tizen-sdk\\tools;D\:\\Android\\android-sdk\\platform-tools;D\:\\Android\\android-ndk-r10c;C\:\\Program Files\\Perforce;D\:\\eclipse\\eclipse-rcp-luna-SR1-win32-x86_64;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\bin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\mingbin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1008004838/appendContributed=true
diff --git a/TEECLib/inc/teec_connection.h b/TEECLib/inc/teec_connection.h
new file mode 100755 (executable)
index 0000000..a921a03
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  teec_connection.h
+ *
+ *    Description:  TEEC Connection Header file
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:43:30  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef __TEEC_CONNECTION_H__
+#define __TEEC_CONNECTION_H__
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/queue.h>
+#include "OsaLinuxUser.h"
+#include "tee_client_api.h"
+#include "tee_command.h"
+#include "teec_data.h"
+#include "log.h"
+
+// TEEC_Context void* imp structure
+typedef struct TEEC_CONTEXT_IMP {
+       uint32_t contextID;
+       int32_t sockfd;
+       pthread_mutex_t lock;
+} TEEC_ContextImp;
+
+// TEEC_Session void* imp structure
+typedef struct TEEC_SESSION_IMP {
+       uint32_t sessionID;
+       TEEC_Context *context;
+} TEEC_SessionImp;
+
+// TEEC_SharedMemory void* imp structure
+typedef struct TEEC_SHARED_MEMORY_IMP {
+       int32_t shmKey;
+       int32_t memId;
+       void* allocPtr;
+       TEEC_Context *context;
+} TEEC_SharedMemoryImp;
+
+// TEEC_Operation void* imp structure
+typedef struct TEEC_OPERATION_IMP {
+TEEC_Session *session;
+uint32_t OperationID;
+} TEEC_OperationImp;
+
+int32_t connecttoServer(void);
+void disconnectfromServer(int32_t ServerSocket);
+uint32_t sendCommand(int32_t sockfd, TEE_CMD cmd, void* data, size_t size);
+
+#endif /* __TEEC_CONNECTION_H__ */
diff --git a/TEECLib/src/teec_api.c b/TEECLib/src/teec_api.c
new file mode 100755 (executable)
index 0000000..7a81e34
--- /dev/null
@@ -0,0 +1,1451 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  teec_api.c
+ *
+ *    Description:  TEEC API implementation
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "teec_connection.h"
+#include <sys/stat.h>
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define PAGE_SIZE              0x1000
+#define PAGE_MASK              (~(PAGE_SIZE - 1))
+
+#define MAX_ID                 64U
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+
+typedef struct smem_info {
+       int32_t memKey;
+       uint32_t ftokID;
+       uint32_t pathID;
+} mem_info;
+
+typedef struct sTEEC_ContextList {
+       LIST_ENTRY(sTEEC_ContextList) list;
+       TEEC_Context *context;
+} TEEC_ContextList;
+
+typedef struct sMemkeyList {
+       LIST_ENTRY(sMemkeyList) mem_list;
+       mem_info *mem;
+} MemkeyList;
+
+LIST_HEAD(context_listhead, sTEEC_ContextList) context_list = LIST_HEAD_INITIALIZER(NULL);
+
+LIST_HEAD(memkey_listhead, sMemkeyList) memkey_list = LIST_HEAD_INITIALIZER(NULL);
+
+uint32_t ftokId = 0;
+uint32_t pathId = 0;
+
+static pthread_rwlock_t key_lock = PTHREAD_RWLOCK_INITIALIZER;
+static pthread_rwlock_t context_list_lock = PTHREAD_RWLOCK_INITIALIZER;
+static pthread_rwlock_t memkey_list_lock = PTHREAD_RWLOCK_INITIALIZER;
+static pthread_rwlock_t file_create_lock = PTHREAD_RWLOCK_INITIALIZER;
+
+
+/*-----------------------------------------------------------------------------
+ *  Local functions
+ *-----------------------------------------------------------------------------*/
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  initShm
+ *  Description:  Local function to create shm pathname file
+ *   Parameters:  path - pathname
+ *       Return:  0 on success
+ *                -1 on failure
+ * =====================================================================================
+ */
+static int32_t initShm(char* path) {
+       LOGD(TEEC_LIB, "Entry");
+       int fd;
+       struct stat attr;
+       snprintf(path, 20, "/tmp/shm%d", pathId);
+       
+       pthread_rwlock_wrlock(&file_create_lock);
+       if (stat(path, &attr) == -1) {
+               fd = creat(path, S_IRWXU);
+               if (-1 == fd) {
+                       LOGE(TEEC_LIB, "shm file creation failed");
+                       return -1;
+               }
+               close(fd);
+       }
+       pthread_rwlock_unlock(&file_create_lock);
+       return 0;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  checkMemory
+ *  Description:  Local function to check if the Memory is already in use
+ *   Parameters:  None
+ *       Return:  0 on success
+ *               -1 on failure
+ * =====================================================================================
+ */
+static int32_t checkMemory(void) {
+       LOGD(TEEC_LIB, "Entry");
+       uint32_t found = 0;
+       MemkeyList *pmem_info;
+
+       /* Check if the memory is in the memory list containing all the allocated
+        * shared memory info
+        */
+       pthread_rwlock_wrlock(&memkey_list_lock);
+       LIST_FOREACH(pmem_info, &memkey_list, mem_list)
+       {
+               if ((pmem_info->mem->ftokID == ftokId) && (pmem_info->mem->pathID == pathId)) {
+                       found = 1;
+                       break;
+               }
+       }
+       pthread_rwlock_unlock(&memkey_list_lock);
+       return found;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  allocateSharedMemory
+ *  Description:  Local function to allocate shared memory
+ *   Parameters:  shm - TEEC_SharedMemory type of data to allocate memory and update
+ *       Return:  memoryKey on success
+ *                -1 on failure
+ * =====================================================================================
+ */
+static int32_t allocateSharedMemory(TEEC_SharedMemory *shm) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_SharedMemoryImp* sharedMem_imp = (TEEC_SharedMemoryImp*)shm->imp;
+       int32_t memKey = -1;
+       uint32_t size = shm->size;
+       int32_t shmid = -1;
+       char path[20];
+       uint32_t pathIdBase = pathId;
+       uint32_t ftokIdBase = ftokId;
+       MemkeyList *pmem_info = NULL;
+
+       pthread_rwlock_wrlock(&key_lock);
+       // Get shared memory key to be shared with TEEStub
+       do {
+               ftokId = (ftokId % MAX_ID) + 1;
+               if (1 == ftokId) {
+                       pathId = (pathId % MAX_ID) + 1;
+                       if (-1 == initShm(path)) {
+                               LOGE(TEEC_LIB, "initShm failed");
+                               return TEEC_ERROR_GENERIC;
+                       }
+               } else {
+                       snprintf(path, 20, "/tmp/shm%d", pathId);
+               }
+       } while((checkMemory()) && (pathIdBase != pathId) && (ftokIdBase != ftokId));
+
+       if (checkMemory()) {
+               LOGE(TEEC_LIB, "All memory segments already in use");
+                return TEEC_ERROR_OUT_OF_MEMORY;
+       }
+
+       if ((memKey = ftok(path, ftokId)) == -1) {
+               perror("ftok: ftok failed");
+       }
+
+       pmem_info = (MemkeyList*)OsaMalloc(sizeof(MemkeyList));
+       if (!pmem_info) {
+               LOGE(TEEC_LIB, "pmem_info malloc failed");
+               return TEEC_ERROR_OUT_OF_MEMORY;
+       }
+       pmem_info->mem = (mem_info*)OsaMalloc(sizeof(mem_info));
+       if (!pmem_info->mem) {
+               LOGE(TEEC_LIB, "pmem_info->mem malloc failed");
+               OsaFree(pmem_info);
+               return TEEC_ERROR_OUT_OF_MEMORY;
+       }
+
+       pmem_info->mem->ftokID = ftokId;
+       pmem_info->mem->pathID = pathId - 1;
+       pthread_rwlock_unlock(&key_lock);
+       // Check if the obtained Shared Memory Key is valid
+       if (memKey == -1) {
+               LOGE(TEEC_LIB, "ftok failed");
+               OsaFree(pmem_info->mem);
+               OsaFree(pmem_info);
+               return TEEC_ERROR_GENERIC;
+       }
+       /* Allocate page aligned buffer */
+       if (size < PAGE_SIZE) {
+               size = PAGE_SIZE;
+       } else if (size & (PAGE_SIZE - 1)) {
+               size = (size & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
+       }
+       size = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
+
+       // Get the shared memory ID
+       if ((shmid = shmget(memKey, size, IPC_CREAT | 0666)) == -1) {
+               perror("shmget: shmget failed");
+       }
+       // Check if the obtained Shared Memory ID is valid
+       if (shmid == -1) {
+               LOGE(TEEC_LIB, "shmget failed");
+               OsaFree(pmem_info->mem);
+               OsaFree(pmem_info);
+               return TEEC_ERROR_GENERIC;
+       }
+
+       // attach a buffer with the obtained shared memory ID
+       shm->buffer = (void*)shmat(shmid, NULL, 0);
+       // Check if the obtained buffer is valid
+       if (!shm->buffer) {
+               LOGE(TEEC_LIB, "shmat failed - allocateSharedMemory failed");
+               OsaFree(pmem_info->mem);
+               OsaFree(pmem_info);
+               return TEEC_ERROR_GENERIC;
+       }
+
+       // Clear the buffer
+       memset(shm->buffer, 0x00, shm->size);
+
+       // Add the mem in the mem list
+       pmem_info->mem->memKey = memKey;
+       pthread_rwlock_wrlock(&memkey_list_lock);
+       LIST_INSERT_HEAD(&memkey_list, pmem_info, mem_list);
+       pthread_rwlock_unlock(&memkey_list_lock);
+
+       // Update shared memory imp structure
+       sharedMem_imp->shmKey = memKey;
+       sharedMem_imp->memId = shmid;
+       sharedMem_imp->allocPtr = shm->buffer;
+       return TEEC_SUCCESS;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  freeSharedMemory
+ *  Description:  Local function to free shared memory
+ *   Parameters:  shm - TEEC_SharedMemory type of data to free memory
+ * =====================================================================================
+ */
+static void freeSharedMemory(TEEC_SharedMemory *shm) {
+       LOGD(TEEC_LIB, "Entry");
+       MemkeyList *pmem_info;
+       TEEC_SharedMemoryImp* sharedMem_imp = (TEEC_SharedMemoryImp*)shm->imp;
+
+       // Detach the buffer atached with the Shared Memory ID
+       if (shmdt(sharedMem_imp->allocPtr) == -1) {
+               LOGE(TEEC_LIB, "freeSharedMemory failed");
+       }
+       sharedMem_imp->allocPtr = NULL;
+
+       if ( -1 == shmctl( sharedMem_imp->memId, IPC_RMID, 0)) {
+               LOGE(TEEC_LIB, "freeSharedMemory shmctl IPC_RMID failed");
+       }
+       sharedMem_imp->memId = -1;
+       // Remove the memKey from the list
+       pthread_rwlock_wrlock(&memkey_list_lock);
+       LIST_FOREACH(pmem_info, &memkey_list, mem_list)
+       {
+               if (pmem_info->mem->memKey == sharedMem_imp->shmKey) {
+                       LIST_REMOVE(pmem_info, mem_list);
+                       OsaFree(pmem_info->mem);
+                       OsaFree(pmem_info);
+                       break;
+               }
+       }
+       pthread_rwlock_unlock(&memkey_list_lock);
+
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  getMemoryKey
+ *  Description:  Local function to generate shmkey for shared memory
+ *   Parameters:  shm - TEEC_SharedMemory type of data to allocate memory and update
+ * =====================================================================================
+ */
+static TEEC_Result getMemoryKey(TEEC_SharedMemory *shm) {
+       TEEC_Result result;
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_SharedMemory sharedmem;
+       sharedmem.imp = shm->imp;
+       sharedmem.size = shm->size;
+       sharedmem.flags = shm->flags;
+       sharedmem.buffer = NULL;
+
+       // Allocate shared memory and get the shared memory key
+       result = allocateSharedMemory(&sharedmem);
+       // Copy the input buffer data to shared buffer
+       if ((result == TEEC_SUCCESS) && ((shm->flags && TEEC_MEM_INPUT) != 0))
+         memcpy(sharedmem.buffer, shm->buffer, shm->size);
+
+       return result;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  checkContext
+ *  Description:  Local function to check if the context is valid
+ *   Parameters:  context - TEEC_Context* to check if context exists
+ *       Return:  0 on success
+ *                -1 on failure
+ * =====================================================================================
+ */
+static uint32_t checkContext(TEEC_Context * context) {
+       LOGD(TEEC_LIB, "Entry");
+
+       TEEC_ContextList *pContext;
+       uint32_t found = 0;
+
+       /* Check if the context is in the Context list containing all the alive
+        * contexts
+        */
+       pthread_rwlock_wrlock(&context_list_lock);
+       LIST_FOREACH(pContext, &context_list, list)
+       {
+               if (pContext->context == context) {
+                       found = 1;
+                       break;
+               }
+       }
+       pthread_rwlock_unlock(&context_list_lock);
+       return found;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  preProcessOperation
+ *  Description:  Local function to pre-process TEEC_Operation structure passed by CA
+ *   Parameters:  session - TEEC_Session* (Session handler)
+ *                operation - TEEC_Operation* (Operation structure pointer)
+ *                op - OperationData* (Structure to be filled and returned)
+ *                tmpSharedMem[4] - TEEC_SharedMemory* (Shared memory in params)
+ *       Return:  TEEC_SUCCESS: Success
+ *                Another error code: Failure
+ * =====================================================================================
+ */
+static TEEC_Result preProcessOperation(TEEC_Session *session,
+    TEEC_Operation *operation, OperationData *op,
+    TEEC_SharedMemory *tmpSharedMem[4]) {
+       TEEC_Context *context = NULL;
+
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_RegisteredMemoryReference *memref;
+       TEEC_SharedMemoryImp *memref_imp;
+       TEEC_Result result = TEEC_SUCCESS;
+       uint32_t i, type;
+
+       // Check if Session is valid
+       if (session)
+               context = ((TEEC_SessionImp*)session->imp)->context;
+       else return TEEC_ERROR_BAD_PARAMETERS;
+       // Check if output Operation structure is valid
+       if (!op) {
+               return TEEC_ERROR_GENERIC;
+       }
+       // Initialize output Operation structure paramtypes to NONE
+       op->paramTypes = (TEE_PARAM_TYPE_NONE << 24) | (TEE_PARAM_TYPE_NONE << 16)
+           | (TEE_PARAM_TYPE_NONE << 8) | TEE_PARAM_TYPE_NONE;
+
+       /* Process params in output Operation structure based on input Operation
+        * structure
+        */
+       for (i = 0; i < 4; i++) {
+               type = ((operation->paramTypes) >> (8 * i)) & 0x7f;
+               switch (type) {
+                       case TEEC_NONE:
+                               op->paramTypes |= TEE_PARAM_TYPE_NONE << (8 * i);
+                               break;
+                       case TEEC_VALUE_INPUT:
+                       case TEEC_VALUE_OUTPUT:
+                       case TEEC_VALUE_INOUT:
+                               /*
+                                * TEEC_VALUE_* and TEE_PARAM_TYPE_VALUE_* constants have
+                                * equal values according to TEE Internal API and Client API
+                                * specifications, so assign them without modifications.
+                                */
+                               op->paramTypes |= type << (8 * i);
+                               memcpy(&op->params[i].value, &operation->params[i].value,
+                                   sizeof(TEEC_Value));
+                               break;
+                       case TEEC_MEMREF_TEMP_INPUT:
+                       case TEEC_MEMREF_TEMP_OUTPUT:
+                       case TEEC_MEMREF_TEMP_INOUT:
+                               /*
+                                * TEEC_MEMREF_TEMP_* and TEE_PARAM_TYPE_MEMREF_* constants have
+                                * equal values according to TEE Internal API and Client API
+                                * specifications, so assign them without modifications.
+                                */
+                               op->paramTypes |= type << (8 * i);
+                               if (!tmpSharedMem[i]) {
+                                       tmpSharedMem[i] = (TEEC_SharedMemory*)OsaMalloc(
+                                           sizeof(TEEC_SharedMemory));
+                                       tmpSharedMem[i]->size = operation->params[i].tmpref.size;
+                                       tmpSharedMem[i]->buffer = operation->params[i].tmpref.buffer;
+                                       result = TEEC_RegisterSharedMemory(
+                                           ((TEEC_SessionImp*)session->imp)->context, tmpSharedMem[i]);
+                                       if (result != TEEC_SUCCESS) {
+                                               for (i = 0; i < 4; i++) {
+                                                       if (tmpSharedMem[i]) {
+                                                               OsaFree(tmpSharedMem[i]);
+                                                               tmpSharedMem[i] = NULL;
+                                                       }
+                                               }
+                                               return result;
+                                       }
+                                       if (type == TEEC_MEMREF_TEMP_INPUT) {
+                                               tmpSharedMem[i]->flags = TEEC_MEM_INPUT;
+                                               memcpy(((TEEC_SharedMemoryImp*)tmpSharedMem[i]->imp)->allocPtr,
+                                                   tmpSharedMem[i]->buffer, tmpSharedMem[i]->size);
+                                       } else if (type == TEEC_MEMREF_TEMP_OUTPUT)
+                                               tmpSharedMem[i]->flags = TEEC_MEM_OUTPUT;
+                                       else {
+                                               tmpSharedMem[i]->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
+                                               memcpy(((TEEC_SharedMemoryImp*)tmpSharedMem[i]->imp)->allocPtr,
+                                                   tmpSharedMem[i]->buffer, tmpSharedMem[i]->size);
+                                       }
+                               }
+                               op->params[i].mem.size = tmpSharedMem[i]->size;
+                               op->params[i].mem.offset = 0;
+                               op->params[i].mem.shmKey = ((TEEC_SharedMemoryImp*)tmpSharedMem[i]->imp)
+                                   ->shmKey;
+                               break;
+                       case TEEC_MEMREF_WHOLE:
+                               op->paramTypes |= TEE_PARAM_TYPE_MEMREF_INOUT << (8 * i);
+                               memref = &operation->params[i].memref;
+                               if ((NULL == memref) || (NULL == memref->parent)
+                                   || (((TEEC_SharedMemoryImp*)memref->parent->imp)->context->imp
+                                       != context->imp)) {
+                                       for (i = 0; i < 4; i++) {
+                                               if (tmpSharedMem[i]) {
+                                                       TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                                                       OsaFree(tmpSharedMem[i]);
+                                                       tmpSharedMem[i] = NULL;
+                                               }
+                                       }
+                                       LOGE(TEEC_LIB, "Bad parameters");
+                                       return TEEC_ERROR_BAD_PARAMETERS;
+                               }
+                               memref_imp = (TEEC_SharedMemoryImp*)memref->parent->imp;
+                               op->params[i].mem.offset = 0;
+                               op->params[i].mem.size = memref->parent->size;
+                               op->params[i].mem.shmKey = memref_imp->shmKey;
+                               if (memref->parent->buffer != memref_imp->allocPtr) {
+                                       memcpy(memref_imp->allocPtr, memref->parent->buffer, memref->size);
+                               }
+                               break;
+                       case TEEC_MEMREF_PARTIAL_INPUT:
+                       case TEEC_MEMREF_PARTIAL_OUTPUT:
+                       case TEEC_MEMREF_PARTIAL_INOUT:
+                               op->paramTypes |= (type + TEE_PARAM_TYPE_MEMREF_INPUT
+                                   - TEEC_MEMREF_PARTIAL_INPUT) << (8 * i);
+                               memref = &operation->params[i].memref;
+                               if ((NULL == memref) || (NULL == memref->parent)
+                                   || (((TEEC_SharedMemoryImp*)memref->parent->imp)->context->imp
+                                       != context->imp)) {
+                                       for (i = 0; i < 4; i++) {
+                                               if (tmpSharedMem[i]) {
+                                                       TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                                                       OsaFree(tmpSharedMem[i]);
+                                                       tmpSharedMem[i] = NULL;
+                                               }
+                                       }
+                                       LOGE(TEEC_LIB, "Bad parameters");
+                                       return TEEC_ERROR_BAD_PARAMETERS;
+                               }
+                               memref_imp = (TEEC_SharedMemoryImp*)memref->parent->imp;
+                               op->params[i].mem.size = memref->size;
+                               op->params[i].mem.offset = memref->offset;
+                               op->params[i].mem.shmKey = memref_imp->shmKey;
+
+                               if (memref->parent->buffer != memref_imp->allocPtr) {
+                                       if ((type == TEEC_MEMREF_PARTIAL_INPUT)
+                                           || (type == TEEC_MEMREF_PARTIAL_INOUT))
+                                         memcpy((uint8_t*)(memref_imp->allocPtr) + memref->offset,
+                                             (uint8_t*)(memref->parent->buffer) + memref->offset,
+                                             memref->size);
+                               }
+                               break;
+                       default:
+                               for (i = 0; i < 4; i++) {
+                                       if (tmpSharedMem[i]) {
+                                               TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                                               OsaFree(tmpSharedMem[i]);
+                                               tmpSharedMem[i] = NULL;
+                                       }
+                               }
+                               return TEEC_ERROR_BAD_PARAMETERS;
+               }
+       }
+       return TEEC_SUCCESS;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  postProcessOperation
+ *  Description:  Local function to post-process the TEEC_Operation structure
+ *                returned by Simulator Daemon
+ *   Parameters:  operation - TEEC_Operation* (Operation structure pointer)
+ *                op - OperationData* (Structure to read)
+ *                tmpSharedMem[4] - TEEC_SharedMemory* (Shared memory in params)
+ * =====================================================================================
+ */
+static void postProcessOperation(TEEC_Operation *operation, OperationData *op,
+    TEEC_SharedMemory *tmpSharedMem[4]) {
+       LOGD(TEEC_LIB, "Entry");
+       uint32_t i, type;
+       TEEC_RegisteredMemoryReference *memref;
+       TEEC_SharedMemoryImp *memref_imp;
+
+       /* Process params in output Operation structure based on input Operation
+        * structure
+        */
+       for (i = 0; i < 4; i++) {
+               type = ((operation->paramTypes) >> (8 * i)) & 0x7f;
+               switch (type) {
+                       case TEEC_VALUE_INPUT:
+                       case TEEC_VALUE_OUTPUT:
+                       case TEEC_VALUE_INOUT:
+                               memcpy(&operation->params[i].value, &op->params[i].value,
+                                   sizeof(TEEC_Value));
+                               break;
+                       case TEEC_MEMREF_TEMP_OUTPUT:
+                       case TEEC_MEMREF_TEMP_INOUT:
+                               operation->params[i].tmpref.size = op->params[i].mem.size;
+                               memcpy(operation->params[i].tmpref.buffer,
+                                   ((TEEC_SharedMemoryImp*)tmpSharedMem[i]->imp)->allocPtr,
+                                   operation->params[i].tmpref.size);
+                               break;
+                       case TEEC_MEMREF_WHOLE:
+                               memref = &operation->params[i].memref;
+                               memref->parent->size = op->params[i].mem.size;
+                               memref_imp = (TEEC_SharedMemoryImp*)memref->parent->imp;
+
+                               if (memref->parent->buffer != memref_imp->allocPtr) {
+                                       memcpy((uint8_t*)(memref->parent->buffer) + memref->offset,
+                                           (uint8_t*)(memref_imp->allocPtr) + memref->offset, memref->size);
+                               }
+                               break;
+                       case TEEC_MEMREF_PARTIAL_OUTPUT:
+                       case TEEC_MEMREF_PARTIAL_INOUT:
+                               memref = &operation->params[i].memref;
+                               memref_imp = (TEEC_SharedMemoryImp*)memref->parent->imp;
+                               memref->size = op->params[i].mem.size;
+                               if (memref->parent->buffer != memref_imp->allocPtr) {
+                                       memcpy((uint8_t*)(memref->parent->buffer) + memref->offset,
+                                           (uint8_t*)(memref_imp->allocPtr) + memref->offset, memref->size);
+                               }
+                               break;
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------------
+ *  TEEC API implementation
+ *-----------------------------------------------------------------------------*/
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_InitializeContext
+ *  Description:  API implementation for initializing a context with TEE
+ *   Parameters:  name - a zero-terminated string that describes the TEE to connect to.
+ *                  If this parameter is set to NULL the Implementation MUST
+ *                  select a default TEE.
+ *                context - a TEEC_Context structure that MUST be initialized by the
+ *                  Implementation.
+ *       Return:  TEEC_SUCCESS: the initialization was successful.
+ *                Another error code: initialization was not successful.
+ * =====================================================================================
+ */
+
+TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       TEEC_ContextImp* context_imp = NULL;
+       TEEC_ContextList* pContext = NULL;
+       InitContextData ctx;
+
+       // Check if the context is valid
+       if (!context) {
+               LOGE(TEEC_LIB, "NULL Context");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Initialize Context imp structure
+       context->imp = (TEEC_ContextImp*)OsaMalloc(sizeof(TEEC_ContextImp));
+       context_imp = (TEEC_ContextImp*)context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "context_imp malloc failed");
+               return TEEC_ERROR_OUT_OF_MEMORY;
+       }
+       memset(context_imp, 0x00, sizeof(TEEC_ContextImp));
+
+       // Initialize InitContextData structure to be sent to Simulator Daemon
+       memset(&ctx, 0x00, sizeof(InitContextData));
+
+       /* check if the Context name is NULL. If it is NULL then set the namelength
+        * to zero else update it accordingly, also update TEEName accordingly
+        */
+       ctx.nameLength = (name == NULL) ? 0 : strlen(name) + 1;
+       if (ctx.nameLength > MAX_CONTEXT_NAME_LEN) {
+               OsaFree(context_imp);
+               context->imp = NULL;
+               LOGE(TEEC_LIB, "TEE name length exceeding");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       if (name) strncpy(ctx.TEEName, name, ctx.nameLength);
+
+       // Connect to Simulator Daemon as a client
+       context_imp->sockfd = connecttoServer();
+       if (context_imp->sockfd == -1) {
+               OsaFree(context_imp);
+               context->imp = NULL;
+               LOGE(TEEC_LIB, "Unable to connect to Simulator daemon");
+               return TEEC_ERROR_GENERIC;
+       }
+       ctx.returnValue = TEEC_SUCCESS;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, INITIALIZE_CONTEXT, &ctx,
+           sizeof(InitContextData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               // Disconnect from Simulator Daemon
+               disconnectfromServer(context_imp->sockfd);
+
+               OsaFree(context_imp);
+               context->imp = NULL;
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               return result;
+       }
+
+       if (ctx.returnValue != TEEC_SUCCESS) { // Command Failure
+               // Disconnect from Simulator Daemon
+               disconnectfromServer(context_imp->sockfd);
+
+               OsaFree(context_imp);
+               context->imp = NULL;
+               LOGE(TEEC_LIB, "Simulator Daemon Initialize context returned failure");
+               return ctx.returnValue;
+       }
+
+       // Update the Context ID in context imp structure
+       context_imp->contextID = ctx.contextID;
+
+       // Add the context in the Context list
+       pContext = (TEEC_ContextList*)OsaMalloc(sizeof(TEEC_ContextList));
+       if (!pContext) {
+               LOGE(TEEC_LIB, "pContext malloc failed");
+               return TEEC_ERROR_OUT_OF_MEMORY;
+       }
+       pContext->context = context;
+       pthread_rwlock_wrlock(&context_list_lock);
+       LIST_INSERT_HEAD(&context_list, pContext, list);
+       pthread_rwlock_unlock(&context_list_lock);
+
+       return result;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_FinalizeContext
+ *  Description:  API implementation for finalizing a context with TEE
+ *   Parameters:  context - an initialized TEEC_Context structure which is to be
+ *                finalized.
+ * =====================================================================================
+ */
+void TEEC_FinalizeContext(TEEC_Context *context) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       FinalizeContextData ctx;
+       TEEC_ContextList *pContext;
+       uint32_t context_initialized = 0;
+
+       // Check if the Context is valid
+       if (!context) {
+               LOGE(TEEC_LIB, "NULL context");
+               return;
+       }
+       // Remove the Context from the list
+       pthread_rwlock_wrlock(&context_list_lock);
+       LIST_FOREACH(pContext, &context_list, list)
+       {
+               if (pContext->context == context) {
+                       context_initialized = 1;
+                       LIST_REMOVE(pContext, list);
+                       OsaFree(pContext);
+                       break;
+               }
+       }
+       pthread_rwlock_unlock(&context_list_lock);
+
+       if (!context_initialized) {
+               LOGE(TEEC_LIB, "Invalid Context");
+               return;
+       }
+       // Check if the Context imp structure is valid
+       TEEC_ContextImp* context_imp = (TEEC_ContextImp*)context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "NULL context_imp");
+               return;
+       }
+
+       // Initialize FinalizeContextData structure to be sent to Simulator Daemon
+       memset(&ctx, 0x00, sizeof(FinalizeContextData));
+       ctx.contextID = context_imp->contextID;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, FINALIZE_CONTEXT, &ctx,
+           sizeof(FinalizeContextData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) // Communication Failure
+         LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+
+       // Disconnect from Simulator Daemon
+       disconnectfromServer(context_imp->sockfd);
+       // Release Context imp
+       OsaFree(context_imp);
+       context->imp = NULL;
+       return;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_RegisterSharedMemory
+ *  Description:  API implementation for registering shared memory with TEE
+ *   Parameters:  context - a pointer to an initialized TEE Context
+ *                sharedMem - a pointer to a Shared Memory structure to register:
+ *                  the buffer, size, and flags fields of the sharedMem
+ *                  structure MUST be set in accordance with the
+ *                  specification
+ *       Return:  TEEC_SUCCESS: the registration was successful.
+ *                TEEC_ERROR_OUT_OF_MEMORY: the registration could not be completed
+ *                  because of a lack of resources.
+ *                Another error code: registration was not successful for another reason
+ * =====================================================================================
+ */
+TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context,
+    TEEC_SharedMemory *sharedMem) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       RegSharedMemData regmem;
+
+       // Check if the Context is valid
+       if (!context) {
+               LOGE(TEEC_LIB, "NULL context");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the context is initialized
+       if (!checkContext(context)) {
+               LOGE(TEEC_LIB, "Invalid context");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the Context imp structure is valid
+       TEEC_ContextImp* context_imp = (TEEC_ContextImp*)context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "NULL context_imp");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the socket is valid
+       if (context_imp->sockfd < 0) {
+               LOGE(TEEC_LIB, "Bad parameter context_imp->sockfd = %d",
+                   context_imp->sockfd);
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if shared memory pointer is valid
+       if (!sharedMem) {
+               LOGE(TEEC_LIB, "Shared Memory is NULL");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       /*
+        * Restrict registration of shared memory regions more than
+        * TEEC_CONFIG_SHAREDMEM_MAX_SIZE and less than PAGE_SIZE.
+        */
+       if (sharedMem->size > TEEC_CONFIG_SHAREDMEM_MAX_SIZE) {
+               LOGE(TEEC_LIB, "Shared Memory size is too large 0x%x", sharedMem->size);
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       // Check if the Shared Memory Buffer is valid
+       if (!sharedMem->buffer) {
+               LOGE(TEEC_LIB, "Shared Memory buffer is NULL");
+               return TEEC_ERROR_NO_DATA;
+       }
+       // Check if the Shared memory flags are valid
+       if ((sharedMem->flags == 0)
+           || (sharedMem->flags > (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT))) {
+               LOGE(TEEC_LIB, "Shared Memory flag is a bad parameter");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       // Initialize RegSharedMemData structure to sent to Simulator Daemon
+       memset(&regmem, 0x00, sizeof(RegSharedMemData));
+
+       sharedMem->imp = (TEEC_SharedMemoryImp*)OsaMalloc(
+           sizeof(TEEC_SharedMemoryImp));
+       TEEC_SharedMemoryImp* sharedMem_imp = (TEEC_SharedMemoryImp*)sharedMem->imp;
+       sharedMem_imp->context = context;
+       regmem.contextID = context_imp->contextID;
+       regmem.sharedMem.size = sharedMem->size;
+       regmem.sharedMem.flags = sharedMem->flags;
+       regmem.returnValue = TEEC_SUCCESS;
+
+       // Generate shared memory key to be shared with TEEStub
+       result = getMemoryKey(sharedMem);
+       if (result != TEEC_SUCCESS) { // Memory allocation Failure
+               LOGE(TEEC_LIB, "Memory alocation failed");
+               OsaFree(sharedMem_imp);
+               return result;
+       }
+       // Check if the obained shared memory is valid
+       if (sharedMem_imp->shmKey == -1) {
+               LOGE(TEEC_LIB, "Failed to get MemoryID");
+               OsaFree(sharedMem_imp);
+               return TEEC_ERROR_GENERIC;
+       }
+       regmem.sharedMem.shmKey = sharedMem_imp->shmKey;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, REGISTER_SHARED_MEMORY, &regmem,
+           sizeof(RegSharedMemData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               OsaFree(sharedMem_imp);
+               return result;
+       }
+       result = regmem.returnValue;
+       if (result != TEEC_SUCCESS) { // Command Failure
+               LOGE(TEEC_LIB, "Simulator Daemon Register Shared Memory returned failure");
+               OsaFree(sharedMem_imp);
+               return result;
+       }
+       return result;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_AllocateSharedMemory
+ *  Description:  API implementation for requesting TEE to allocate shared memory
+ *   Parameters:  context - a pointer to an initialized TEE Context
+ *                sharedMem - a pointer to a Shared Memory structure to allocate:
+ *                  Before calling this function, the Client Application MUST have set
+ *                  the size, and flags fields. On return, for a successful allocation
+ *                  the Implementation MUST have set the pointer buffer to the address
+ *                  of the allocated block, otherwise it MUST set buffer to NULL.
+ *       Return:  TEEC_SUCCESS: the registration was successful.
+ *                TEEC_ERROR_OUT_OF_MEMORY: the registration could not be completed
+ *                  because of a lack of resources.
+ *                Another error code: registration was not successful for another
+ *                  reason
+ * =====================================================================================
+ */
+TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context,
+    TEEC_SharedMemory *sharedMem) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       TEEC_ContextImp* context_imp;
+       RegSharedMemData regmem;
+
+       // Check if the Context is valid
+       if (!context) {
+               LOGE(TEEC_LIB, "context is NULL");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the Context is initialized
+       if (!checkContext(context)) {
+               LOGE(TEEC_LIB, "context is not found");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the Context imp structure is valid
+       context_imp = (TEEC_ContextImp*)context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "context_imp is not found");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the socket is valid
+       if (context_imp->sockfd < 0) {
+               LOGE(TEEC_LIB, "Bad parameter context_imp->sockfd = %d",
+                   context_imp->sockfd);
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if shared memory pointer is valid
+       if (!sharedMem) {
+               LOGE(TEEC_LIB, "Shared Memory is NULL");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       /*
+        * Restrict registration of shared memory regions more than
+        * TEEC_CONFIG_SHAREDMEM_MAX_SIZE and less than PAGE_SIZE.
+        */
+       if (sharedMem->size > TEEC_CONFIG_SHAREDMEM_MAX_SIZE) {
+               LOGE(TEEC_LIB, "Shared Memory size is too large 0x%x", sharedMem->size);
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       // Check if the Shared memory flags are valid
+       if ((sharedMem->flags == 0)
+           || (sharedMem->flags > (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT))) {
+               LOGE(TEEC_LIB, "Shared Memory flag is a bad parameter");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Generate Shared Memory imp structure
+       sharedMem->imp = (TEEC_SharedMemoryImp*)OsaMalloc(
+           sizeof(TEEC_SharedMemoryImp));
+       TEEC_SharedMemoryImp* sharedMem_imp = (TEEC_SharedMemoryImp*)sharedMem->imp;
+       sharedMem->buffer = NULL;
+       sharedMem_imp->context = context;
+
+       /* Allocate shared memory and get the Shared Memory key to be shared with
+        * TEEStub
+        */
+       result = allocateSharedMemory(sharedMem);
+       if (result != TEEC_SUCCESS) { // Memory Allocation Failure
+               LOGE(TEEC_LIB, "allocateSharedMemory failed");
+               OsaFree(sharedMem_imp);
+               return result;
+       }
+       // Check if the obtained key is valid
+       if (sharedMem_imp->shmKey == -1) {
+               LOGE(TEEC_LIB, "allocateSharedMemory failed");
+               OsaFree(sharedMem_imp);
+               return TEEC_ERROR_GENERIC;
+       }
+
+       // Initialize RegSharedMemData to be sent to Simulator Daemon
+       memset(&regmem, 0x00, sizeof(RegSharedMemData));
+
+       regmem.contextID = context_imp->contextID;
+       regmem.returnValue = TEEC_SUCCESS;
+       regmem.sharedMem.size = sharedMem->size;
+       regmem.sharedMem.flags = sharedMem->flags;
+       regmem.sharedMem.shmKey = sharedMem_imp->shmKey;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, REGISTER_SHARED_MEMORY, &regmem,
+           sizeof(RegSharedMemData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               sharedMem->buffer = NULL;
+               OsaFree(sharedMem_imp);
+               return result;
+       }
+       result = regmem.returnValue;
+       if (result != TEEC_SUCCESS) { // Command Failure
+               LOGE(TEEC_LIB, "Simulator Daemon Allocate Shared Memory returned failure");
+               OsaFree(sharedMem_imp);
+               return result;
+       }
+       return result;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_ReleaseSharedMemory
+ *  Description:  API implementation for releasing shared memory
+ *   Parameters:  sharedMem - a pointer to a valid Shared Memory structure
+ * =====================================================================================
+ */
+void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMem) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       TEEC_Context* context;
+       TEEC_ContextImp* context_imp;
+       RelSharedMemData relmem;
+
+       // Check if the Shared Memory is valid
+       if (!sharedMem) {
+               LOGE(TEEC_LIB, "SharedMem is NULL");
+               return;
+       }
+       // Check if the Shared Memory imp structure is valid
+       TEEC_SharedMemoryImp* sharedMem_imp = (TEEC_SharedMemoryImp*)sharedMem->imp;
+       if (!sharedMem_imp) {
+               LOGE(TEEC_LIB, "NULL sharedMem_imp");
+               return;
+       }
+       // Check if the Context is valid
+       context = sharedMem_imp->context;
+       if (!context) {
+               LOGE(TEEC_LIB, "context is NULL");
+               return;
+       }
+       // Check if the Context imp structure is valid
+       context_imp = (TEEC_ContextImp*)context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "context_imp is NULL");
+               return;
+       }
+
+       // Initialize RelSharedMemData structure to be sent to Simulator Daemon
+       memset(&relmem, 0x00, sizeof(RelSharedMemData));
+
+       relmem.contextID = context_imp->contextID;
+       relmem.sharedMem.size = sharedMem->size;
+       relmem.sharedMem.flags = sharedMem->flags;
+       relmem.sharedMem.shmKey = sharedMem_imp->shmKey;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, RELEASE_SHARED_MEMORY, &relmem,
+           sizeof(RelSharedMemData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               return;
+       }
+       // free Shared Memory
+       freeSharedMemory(sharedMem);
+       OsaFree(sharedMem_imp);
+       sharedMem->imp = NULL;
+       return;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_OpenSession
+ *  Description:  API implementation for opening a session with TA
+ *   Parameters:  context - a pointer to an initialized TEE Context
+ *                session - a pointer to a Session structure to open
+ *                destination - a pointer to a structure containing the UUID of the
+ *                  destination Trusted Application
+ *                connectionMethod - the method of connection to use
+ *                connectionData - any necessary data required to support the
+ *                  connection method chosen
+ *                operation - a pointer to an Operation containing a set of Parameters
+ *                  to exchange with the Trusted Application, or NULL if no
+ *                  Parameters are to be exchanged or if the operation cannot
+ *                  be cancelled
+ *                returnOrigin - a pointer to a variable which will contain the return
+ *                origin. This field may be NULL if the return origin is not needed
+ *       Return:  If the returnOrigin is different from TEEC_ORIGIN_TRUSTED_APP,
+ *                  an error code
+ *                If the returnOrigin is equal to TEEC_ORIGIN_TRUSTED_APP, a return
+ *                  code defined by the protocol between the Client Application and
+ *                  the Trusted Application. In any case, a return code set to
+ *                  TEEC_SUCCESS means that the session was successfully opened and a
+ *                  return code different from TEEC_SUCCESS means that the session
+ *                  opening failed
+ * =====================================================================================
+ */
+TEEC_Result TEEC_OpenSession(TEEC_Context *context, TEEC_Session *session,
+    const TEEC_UUID *destination, uint32_t connectionMethod,
+    const void *connectionData, TEEC_Operation *operation,
+    uint32_t *returnOrigin) {
+
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       OpenSessionData os;
+       OperationData op;
+       TEEC_SharedMemory *tmpSharedMem[4];
+       memset(tmpSharedMem, 0x0, sizeof(TEEC_SharedMemory *) * 4);
+       uint32_t i;
+
+       // Check if the context, session and UUID is valid
+       if (!session || !context || !destination) {
+               LOGE(TEEC_LIB, "Invalid input parameters");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if the context imp is valid
+       TEEC_ContextImp* context_imp = (TEEC_ContextImp*)context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "NULL context_imp");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       /* Initialize the OpenSessionData and OperationData structures to be sent to
+        * Simulator daemon
+        */
+       memset(&os, 0x00, sizeof(OpenSessionData));
+       memset(&op, 0x00, sizeof(OperationData));
+
+       // Set returnOrigin
+       if (returnOrigin) {
+               *returnOrigin = TEEC_ORIGIN_API;
+               os.returnOrigin = *returnOrigin;
+       } else os.returnOrigin = 0x00;
+
+       // Update Context ID
+       os.contextID = context_imp->contextID;
+       // Update Connection details
+       switch (connectionMethod) {
+               case TEEC_LOGIN_PUBLIC:
+               case TEEC_LOGIN_USER:
+               case TEEC_LOGIN_APPLICATION:
+               case TEEC_LOGIN_USER_APPLICATION:
+                       if (connectionData != NULL) {
+                               return TEEC_ERROR_BAD_PARAMETERS;
+                       }
+                       break;
+               case TEEC_LOGIN_GROUP:
+               case TEEC_LOGIN_GROUP_APPLICATION:
+                       if (connectionData == NULL) {
+                               return TEEC_ERROR_BAD_PARAMETERS;
+                       }
+                       os.connData = *(uint32_t*)connectionData;
+                       break;
+               default:
+                       return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       os.connMeth = connectionMethod;
+
+       session->imp = (TEEC_SessionImp*)OsaMalloc(sizeof(TEEC_SessionImp));
+       TEEC_SessionImp* session_imp = (TEEC_SessionImp*)session->imp;
+       if (!session_imp) {
+               LOGE(TEEC_LIB, "NULL session_imp");
+               return TEEC_ERROR_OUT_OF_MEMORY;
+       }
+       session_imp->context = context;
+       memcpy(&os.uuid, destination, sizeof(TEEC_UUID));
+
+       if (operation) {
+               result = preProcessOperation(session, operation, &op, tmpSharedMem);
+               if (result != TEEC_SUCCESS) {
+                       LOGE(TEEC_LIB, "preProcessOperation failed");
+                       OsaFree(session_imp);
+                       session->imp = NULL;
+                       if (operation) postProcessOperation(operation, &op, tmpSharedMem);
+                       /* temp memref cleanup & release */
+                       for (i = 0; i < 4; i++) {
+                               if (tmpSharedMem[i]) {
+                                       TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                                       OsaFree(tmpSharedMem[i]);
+                                       tmpSharedMem[i] = NULL;
+                               }
+                       }
+                       return result;
+               }
+               memcpy(&os.operation, &op, sizeof(OperationData));
+       } else memset(&os.operation, 0x00, sizeof(OperationData));
+
+       os.returnValue = TEEC_SUCCESS;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, OPEN_SESSION, &os,
+           sizeof(OpenSessionData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               if (returnOrigin) *returnOrigin = TEEC_ORIGIN_COMMS;
+               OsaFree(session_imp);
+               session->imp = NULL;
+               if (operation) postProcessOperation(operation, &os.operation, tmpSharedMem);
+               /* temp memref cleanup & release */
+               for (i = 0; i < 4; i++) {
+                       if (tmpSharedMem[i]) {
+                               TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                               OsaFree(tmpSharedMem[i]);
+                               tmpSharedMem[i] = NULL;
+                       }
+               }
+               return result;
+       }
+
+       if (returnOrigin) *returnOrigin = os.returnOrigin;
+
+       result = os.returnValue;
+       if (result != TEEC_SUCCESS) { // Command Failure
+               LOGE(TEEC_LIB, "Simulator Daemon Open Session returned failure");
+               OsaFree(session_imp);
+               session->imp = NULL;
+               if (operation) postProcessOperation(operation, &os.operation, tmpSharedMem);
+               /* temp memref cleanup & release */
+               for (i = 0; i < 4; i++) {
+                       if (tmpSharedMem[i]) {
+                               TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                               OsaFree(tmpSharedMem[i]);
+                               tmpSharedMem[i] = NULL;
+                       }
+               }
+               return result;
+       } else session_imp->sessionID = os.sessionID;
+
+       if (operation) postProcessOperation(operation, &os.operation, tmpSharedMem);
+       /* temp memref cleanup & release */
+       for (i = 0; i < 4; i++) {
+               if (tmpSharedMem[i]) {
+                       TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                       OsaFree(tmpSharedMem[i]);
+                       tmpSharedMem[i] = NULL;
+               }
+       }
+       return result;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_CloseSession
+ *  Description:  API implementation for closing a session with TA
+ *   Parameters:  session - the session to close.
+ * =====================================================================================
+ */
+void TEEC_CloseSession(TEEC_Session *session) {
+
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       CloseSessionData cs;
+
+       // Check if Session is valid
+       if (!session) {
+               LOGE(TEEC_LIB, "NULL session");
+               return;
+       }
+       // Check if Session imp is valid
+       TEEC_SessionImp* session_imp = (TEEC_SessionImp*)session->imp;
+       if (!session_imp) {
+               LOGE(TEEC_LIB, "NULL session_imp");
+               return;
+       }
+       // Check if Context imp is valid
+       TEEC_ContextImp* context_imp = (TEEC_ContextImp*)session_imp->context->imp;
+       if (!context_imp || context_imp->sockfd < 0) {
+               LOGE(TEEC_LIB, "Bad parameters");
+               return;
+       }
+
+       // Initialize CloseSessionData structure to be sent to Simulator Daemon
+       memset(&cs, 0x00, sizeof(CloseSessionData));
+
+       cs.contextID = context_imp->contextID;
+       cs.sessionID = session_imp->sessionID;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, CLOSE_SESSION, &cs,
+           sizeof(CloseSessionData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               return;
+       }
+       // Release Session
+       session->imp = NULL;
+       OsaFree(session_imp);
+       return;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_InvokeCommand
+ *  Description:  API implementation for invoking a command in a session with TA
+ *   Parameters:  session - the open Session in which the command will be invoked
+ *                commandID - the identifier of the Command within the Trusted
+ *                  Application to invoke. The meaning of each Command
+ *                  Identifier must be defined in the protocol exposed
+ *                  by the Trusted Application
+ *                operation - a pointer to a Client Application initialized
+ *                  TEEC_Operation structure, or NULL if there is no payload
+ *                  to send or if the Command does not need to support cancellation
+ *                returnOrigin - a pointer to a variable which will contain the return
+ *                  origin. This field may be NULL if the return origin
+ *                  is not needed
+ *       Return:  If the return origin is different from TEEC_ORIGIN_TRUSTED_APP,
+ *                  an error code
+ *                If the return origin is TEEC_ORIGIN_TRUSTED_APP, a return code
+ *                defined by the Trusted Application protocol
+ * =====================================================================================
+ */
+TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, uint32_t commandID,
+    TEEC_Operation *operation, uint32_t *returnOrigin) {
+
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+
+       InvokeCommandData ic;
+       OperationData op;
+       TEEC_SharedMemory *tmpSharedMem[4];
+       memset(tmpSharedMem, 0x0, sizeof(TEEC_SharedMemory*) * 4);
+       uint32_t i;
+
+       // Check if Session is valid
+       if (!session) {
+               LOGE(TEEC_LIB, "NULL session");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       // Check if Session imp is valid
+       TEEC_SessionImp* session_imp = (TEEC_SessionImp*)session->imp;
+       if (!session_imp) {
+               LOGE(TEEC_LIB, "NULL session_imp");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+       // Check if Context imp is valid
+       TEEC_ContextImp *context_imp = (TEEC_ContextImp*)session_imp->context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "NULL context_imp");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       /* Initialize InvokeCommandData and OperationData structures to be sent to
+        * Simulator Daemon
+        */
+       memset(&ic, 0x00, sizeof(InvokeCommandData));
+       memset(&op, 0x00, sizeof(OperationData));
+
+       // Set returnOrigin
+       if (returnOrigin) {
+               *returnOrigin = TEEC_ORIGIN_API;
+               ic.returnOrigin = *returnOrigin;
+       } else ic.returnOrigin = 0x00;
+
+       if (operation) {
+               result = preProcessOperation(session, operation, &op, tmpSharedMem);
+               if (result != TEEC_SUCCESS) {
+                       LOGE(TEEC_LIB, "preProcessOperation failed");
+                       if (operation) postProcessOperation(operation, &op, tmpSharedMem);
+                       /* temp memref cleanup & release */
+                       for (i = 0; i < 4; i++) {
+                               if (tmpSharedMem[i]) {
+                                       TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                                       OsaFree(tmpSharedMem[i]);
+                                       tmpSharedMem[i] = NULL;
+                               }
+                       }
+                       return result;
+               }
+               memcpy(&ic.operation, &op, sizeof(OperationData));
+       } else memset(&ic.operation, 0x00, sizeof(OperationData));
+
+       ic.contextID = context_imp->contextID;
+       ic.sessionID = session_imp->sessionID;
+       ic.commandID = commandID;
+       ic.returnValue = TEEC_SUCCESS;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, INVOKE_COMMAND, &ic,
+           sizeof(InvokeCommandData));
+       pthread_mutex_unlock(&context_imp->lock);
+
+       if (result != TEEC_SUCCESS) { // Communication Failure
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+               if (returnOrigin) *returnOrigin = TEEC_ORIGIN_COMMS;
+               if (operation) postProcessOperation(operation, &ic.operation, tmpSharedMem);
+               /* temp memref cleanup & release */
+               for (i = 0; i < 4; i++) {
+                       if (tmpSharedMem[i]) {
+                               TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                               OsaFree(tmpSharedMem[i]);
+                               tmpSharedMem[i] = NULL;
+                       }
+               }
+               return result;
+       }
+
+       if (returnOrigin) *returnOrigin = ic.returnOrigin;
+
+       result = ic.returnValue;
+       if (result != TEEC_SUCCESS) { // Command Failure
+               if (operation) postProcessOperation(operation, &ic.operation, tmpSharedMem);
+               /* temp memref cleanup & release */
+               for (i = 0; i < 4; i++) {
+                       if (tmpSharedMem[i]) {
+                               TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                               OsaFree(tmpSharedMem[i]);
+                               tmpSharedMem[i] = NULL;
+                       }
+               }
+               return result;
+       }
+
+       if (operation) postProcessOperation(operation, &ic.operation, tmpSharedMem);
+       /* temp memref cleanup & release */
+       for (i = 0; i < 4; i++) {
+               if (tmpSharedMem[i]) {
+                       TEEC_ReleaseSharedMemory(tmpSharedMem[i]);
+                       OsaFree(tmpSharedMem[i]);
+                       tmpSharedMem[i] = NULL;
+               }
+       }
+       return result;
+}
+
+/*
+ * ===  FUNCTION  ======================================================================
+ *         Name:  TEEC_RequestCancellation
+ *  Description:  API implementation for requesting cancellation of an operation
+ *   Parameters:  operation - a pointer to a Client Application instantiated Operation
+ *                  structure.
+ * =====================================================================================
+ */
+void TEEC_RequestCancellation(TEEC_Operation *operation) {
+
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+
+       ReqCancellationData rc;
+
+       // Check if cancellation is allowed
+       if (operation->started != 0) {
+               LOGE(TEEC_LIB, "Cancellation not allowed");
+               return;
+       }
+       // Check if Operation imp is valid
+       TEEC_OperationImp* operation_imp = (TEEC_OperationImp*)operation->imp;
+       if (!operation_imp) {
+               LOGE(TEEC_LIB, "NULL operation_imp");
+               return;
+       }
+       // Check if session is valid
+       if (!operation_imp->session) {
+               LOGE(TEEC_LIB, "NULL session");
+               return;
+       }
+       // check if Session imp is valid
+       TEEC_SessionImp* session_imp = (TEEC_SessionImp*)operation_imp->session->imp;
+       if (!session_imp) {
+               LOGE(TEEC_LIB, "NULL session_imp");
+               return;
+       }
+       // Check if Context imp is valid
+       TEEC_ContextImp *context_imp = (TEEC_ContextImp*)session_imp->context->imp;
+       if (!context_imp) {
+               LOGE(TEEC_LIB, "NULL context_imp");
+               return;
+       }
+
+       // Initialize ReqCancellationData structure to be sent to Simulator Daemon
+       memset(&rc, 0x00, sizeof(ReqCancellationData));
+
+       rc.contextID = context_imp->contextID;
+       rc.sessionID = session_imp->sessionID;
+       rc.operationID = operation_imp->OperationID;
+
+       // Send the command and data to Simulator Daemon through the socket
+       pthread_mutex_lock(&context_imp->lock);
+       result = sendCommand(context_imp->sockfd, REQUEST_CANCELLATION, &rc,
+           sizeof(ReqCancellationData));
+       pthread_mutex_unlock(&context_imp->lock);
+       if (result != TEEC_SUCCESS) {
+               LOGE(TEEC_LIB, "sendCommand to Simulator Daemon failed");
+       }
+       return;
+}
diff --git a/TEECLib/src/teec_connection.c b/TEECLib/src/teec_connection.c
new file mode 100755 (executable)
index 0000000..34c0968
--- /dev/null
@@ -0,0 +1,434 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  teec_connection.c
+ *
+ *    Description:  TEEC Library connection with Simulator Daemon is handled here
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "teec_connection.h"
+
+/*-----------------------------------------------------------------------------
+ *  Macros
+ *-----------------------------------------------------------------------------*/
+#define SOCKPATH "/tmp/simdaemon"
+
+/*-----------------------------------------------------------------------------
+ *  TEST MACROS
+ *-----------------------------------------------------------------------------*/
+//#define TEST
+
+/* 
+ * ===  FUNCTION  ======================================================================
+ *         Name:  connecttoServer
+ *  Description:  API (Interface for TEECAPI) implementation for connecting to
+ *                the Simulator Daemon through socket
+ *       Return:       Socket fd on success
+ *                                             -1 on failure
+ * =====================================================================================
+ */
+int32_t connecttoServer(void) {
+       LOGD(TEEC_LIB, "Entry");
+       int32_t serverSocket, socklen;
+       size_t sock_path_len = 0;
+       struct sockaddr* sockptr;
+       struct sockaddr_un daemonsock;
+
+       // Get socket decriptor
+       if ((serverSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+               LOGE(TEEC_LIB, "No socket for simdaemon");
+               return -1;
+       }
+       daemonsock.sun_family = AF_UNIX;
+
+       sock_path_len = strlen(SOCKPATH);
+       strncpy(daemonsock.sun_path, SOCKPATH, sock_path_len+1);
+
+       socklen = sizeof(daemonsock);
+       sockptr = (struct sockaddr*)&daemonsock;
+
+       // Connect to Simulator Daemon
+       if (connect(serverSocket, sockptr, socklen) == -1) {
+               LOGE(TEEC_LIB, "connection to simdaemon failed");
+               close(serverSocket);
+               return -1;
+       }
+       return serverSocket;
+}
+
+/* 
+ * ===  FUNCTION  ======================================================================
+ *         Name:  disconnectfromServer
+ *  Description:  API (Interface for TEECAPI) implementation for disconnecting
+ *                from the Simulator daemon through socket
+ *   Parameters:       serverSocket - Socket fd
+ * =====================================================================================
+ */
+void disconnectfromServer(int32_t serverSocket) {
+       int32_t result;
+       LOGD(TEEC_LIB, "Entry");
+
+       if (serverSocket > 0) {
+               // shutdown the socket
+               result = shutdown(serverSocket, SHUT_WR);
+               if (result != 0)
+               LOGE(TEEC_LIB, "disconnectfromServer failed");
+
+               // close the socket
+               close(serverSocket);
+       } else {
+               LOGE(TEEC_LIB, "Invalid socket, disconnectfromServer failed");
+       }
+}
+
+/* 
+ * ===  FUNCTION  ======================================================================
+ *         Name:  sendCommandtoDaemon
+ *  Description:  Function implementation for sending data to Simulator daemon
+ *                through socket
+ *   Parameters:       serverSocket - Socket fd
+ *                                                     fdata - data to be sent to Simulator Daemon
+ *                                                     size - Size of data to be sent
+ *              Return:        0 on success
+ *                                                     errno on failure
+ * =====================================================================================
+ */
+static uint32_t sendCommandtoDaemon(int32_t sockfd, char* fdata, size_t size) {
+       LOGD(TEEC_LIB, "Entry");
+       ssize_t nwrite = 0;
+       size_t nbytes = 0;
+
+       if (sockfd > 0) {
+               // send size number of bytes to Simulator Daemon
+               do {
+                       nwrite = send(sockfd, fdata + nbytes, size - nbytes, 0);
+               } while ((nwrite == -1 && errno == EINTR) || (nwrite > 0 && ((nbytes +=
+                   nwrite) < size)));
+               return (size != nbytes) ? errno : 0;
+       }
+       LOGE(TEEC_LIB, "failed");
+       return TEEC_ERROR_COMMUNICATION;
+}
+
+/* 
+ * ===  FUNCTION  ======================================================================
+ *         Name:  receiveResponse
+ *  Description:  Function implementation for recieving data from Simulator
+ *                daemon through socket
+ *   Parameters:       serverSocket - Socket fd
+ *                                                     fdata - data received from Simulator Daemon
+ *                                                     size - Size of received data
+ *              Return:        0 on success
+ *                                                     errno on failure
+ * =====================================================================================
+ */
+static uint32_t receiveResponse(int32_t sockfd, char* fdata, size_t size) {
+       LOGD(TEEC_LIB, "Entry");
+       ssize_t nread = 0;
+       size_t nbytes = 0;
+
+       if (sockfd > 0) {
+               // receive size number of bytes to Simulator Daemon
+               do {
+                       nread = recv(sockfd, fdata + nbytes, size - nbytes, 0);
+               } while ((nread == -1 && errno == EINTR)
+                   || (nread > 0 && ((nbytes += nread) < size)));
+
+               return (size != nbytes) ? errno : 0;
+       }
+       LOGE(TEEC_LIB, "failed");
+       return TEEC_ERROR_COMMUNICATION;
+}
+
+#ifdef TEST
+/* 
+ * ===  FUNCTION  ======================================================================
+ *         Name:  Test
+ *  Description:  Local function for Unit testing of TEECLib module
+ *   Parameters:       cmd - Command sent/received
+ *                                                     fdata - data sent/received
+ *                                                     size - size of data sent/received
+ *                                                     in - 1: Sent data
+ *                                                                      Any other value: Received data
+ *              Return:        TEEC_SUCCESS: Success
+ *                                               TEEC_ERROR_GENERIC: Failure
+ * =====================================================================================
+ */
+static uint32_t Test(char cmd, char* fdata, size_t size, uint32_t in) {
+
+       LOGD(TEEC_LIB, "Entry");
+       FILE *f1;
+       char *fname;
+       uint32_t type, i, j, shmid, key;
+       char *buffer;
+
+       switch (cmd) {
+               case INITIALIZE_CONTEXT:
+               if (in == 1)
+               fname = "InitContext.txt";
+               else
+               fname = "InitContextResult.txt";
+               f1 = fopen(fname, "w+");
+               InitContextData initdata = *(InitContextData*) fdata;
+               fprintf(f1,
+                               "InitializeContextData ---------\ncontextID %d\nnameLength %d\
+        \nTEEName %s\nreturnValue %d\n",
+                               initdata.contextID, initdata.nameLength, &initdata.TEEName[0],
+                               initdata.returnValue);
+               fclose(f1);
+               break;
+               case FINALIZE_CONTEXT:
+               if (in == 1)
+               fname = "FinContext.txt";
+               else
+               fname = "FinContextResult.txt";
+               f1 = fopen(fname, "w+");
+               FinalizeContextData findata = *(FinalizeContextData*) fdata;
+               fprintf(f1, "FinalizeContextData ---------\ncontextID %d\n",
+                               findata.contextID);
+               fclose(f1);
+               break;
+               case REGISTER_SHARED_MEMORY:
+               if (in == 1)
+               fname = "RegMem.txt";
+               else
+               fname = "RegMemResult.txt";
+               f1 = fopen(fname, "w+");
+               RegSharedMemData regdata = *(RegSharedMemData*) fdata;
+               fprintf(f1,
+                               "RegSharedMemData ---------\ncontextID %d\nsize %d\nflags %d\
+        \nshmKey %d\nreturnValue %d\n",
+                               regdata.contextID, regdata.sharedMem.size, regdata.sharedMem.flags,
+                               regdata.sharedMem.shmKey, regdata.returnValue);
+               fclose(f1);
+               break;
+               case RELEASE_SHARED_MEMORY:
+               if (in == 1)
+               fname = "RelMem.txt";
+               else
+               fname = "RelMemResult.txt";
+               f1 = fopen(fname, "w+");
+               RelSharedMemData reldata = *(RelSharedMemData*) fdata;
+               fprintf(f1,
+                               "RelSharedMemData ---------\ncontextID %d\nsize %d\nflags %d\
+        \nshmKey %d\n",
+                               reldata.contextID, reldata.sharedMem.size, reldata.sharedMem.flags,
+                               reldata.sharedMem.shmKey);
+               break;
+               case OPEN_SESSION:
+               if (in == 1)
+               fname = "OpenSess.txt";
+               else
+               fname = "OpenSessResult.txt";
+               f1 = fopen(fname, "w+");
+               OpenSessionData osdata = *(OpenSessionData*) fdata;
+               fprintf(f1,
+                               "OpensessionData ---------\ncontextID %d\nSessionID %d\
+        \nuuidtimeLow %d\nuuidtimeMid %d\ntimeHiAndVersion %d\n",
+                               osdata.contextID, osdata.sessionID, osdata.uuid.timeLow,
+                               osdata.uuid.timeMid, osdata.uuid.timeHiAndVersion);
+               for (i = 0; i < 8; i++)
+               fprintf(f1, "clockSeqAndNode[%d] %d\n", i,
+                               osdata.uuid.clockSeqAndNode[i]);
+               fprintf(f1, "connMethod %d\nconnData %d\nparamTypes %d\n", osdata.connMeth,
+                               osdata.connData, osdata.operation.paramTypes);
+               for (i = 0; i < 4; i++) {
+                       type = ((osdata.operation.paramTypes) >> (8 * i)) & 0x7f;
+                       if (type == TEEC_NONE)
+                       fprintf(f1, "param[%d] NONE\n", i);
+                       else if ((type
+                                                       == TEEC_VALUE_INPUT) | (type == TEEC_VALUE_OUTPUT) | (type == TEEC_VALUE_INOUT))
+                       fprintf(f1, "param[%d] value a %d value b %d\n", i,
+                                       osdata.operation.params[i].value.a,
+                                       osdata.operation.params[i].value.b);
+                       else {
+                               fprintf(f1, "param[%d] mem shmKey %d size %d offset %d\n", i,
+                                               osdata.operation.params[i].mem.shmKey,
+                                               osdata.operation.params[i].mem.size,
+                                               osdata.operation.params[i].mem.offset);
+                               key = osdata.operation.params[i].mem.shmKey;
+                               shmid = shmget(key, osdata.operation.params[i].mem.size,
+                                               IPC_CREAT | 0666);
+                               if (shmid == -1) {
+                                       LOGE(TEEC_LIB, "shmget failed");
+                                       return TEEC_ERROR_GENERIC;
+                               }
+
+                               if ((buffer = (char*) shmat(shmid, NULL, 0)) == (char*) -1) {
+                                       LOGE(TEEC_LIB, "shmat failed");
+                                       return TEEC_ERROR_GENERIC;
+                               }
+
+                               if (!buffer) {
+                                       LOGE(TEEC_LIB, "shmat failed");
+                                       return TEEC_ERROR_GENERIC;
+                               }
+
+                               fprintf(f1, "SharedMemData: \n");
+                               char *shmdata = (buffer + osdata.operation.params[i].mem.offset);
+                               for (j = 0; j < osdata.operation.params[i].mem.size; j++)
+                               fprintf(f1, "%x", shmdata[j]);
+                               fprintf(f1, "\n");
+
+                               if (shmdt(buffer) == -1) {
+                                       printf("shmdt failed");
+                               }
+                               buffer = NULL;
+                       }
+               }
+               fprintf(f1, "OperationID %d\nreturnOrigin %d\nreturnValue %d\n",
+                               osdata.operation.OperationID, osdata.returnOrigin, osdata.returnValue);
+               fclose(f1);
+               break;
+               case CLOSE_SESSION:
+               if (in == 1)
+               fname = "CloseSess.txt";
+               else
+               fname = "CloseSessResult.txt";
+               f1 = fopen(fname, "w+");
+               CloseSessionData csdata = *(CloseSessionData*) fdata;
+               fprintf(f1, "ClosesessionData ---------\ncontextID %d\nSessionID %d\n",
+                               csdata.contextID, csdata.sessionID);
+               fclose(f1);
+               break;
+               case INVOKE_COMMAND:
+               if (in == 1)
+               fname = "InvComm.txt";
+               else
+               fname = "InvCommResult.txt";
+               f1 = fopen(fname, "w+");
+               InvokeCommandData icdata = *(InvokeCommandData*) fdata;
+               fprintf(f1,
+                               "InvokeCommandData ---------\ncontextID %d\nSessionID %d\
+        \nCommandID %d\nparamTypes %d\n",
+                               icdata.contextID, icdata.sessionID, icdata.commandID,
+                               icdata.operation.paramTypes);
+               for (i = 0; i < 4; i++) {
+                       type = ((icdata.operation.paramTypes) >> (8 * i)) & 0x7f;
+                       if (type == TEEC_NONE)
+                       fprintf(f1, "param[%d] NONE\n", i);
+                       else if ((type
+                                                       == TEEC_VALUE_INPUT) | (type == TEEC_VALUE_OUTPUT) | (type == TEEC_VALUE_INOUT))
+                       fprintf(f1, "param[%d] value a %d value b %d\n", i,
+                                       icdata.operation.params[i].value.a,
+                                       icdata.operation.params[i].value.b);
+                       else {
+                               fprintf(f1, "param[%d] mem shmKey %d size %d offset %d\n", i,
+                                               icdata.operation.params[i].mem.shmKey,
+                                               icdata.operation.params[i].mem.size,
+                                               icdata.operation.params[i].mem.offset);
+                               key = icdata.operation.params[i].mem.shmKey;
+                               shmid = shmget(key, icdata.operation.params[i].mem.size,
+                                               IPC_CREAT | 0666);
+                               if (shmid == -1) {
+                                       LOGE(TEEC_LIB, "shmget failed");
+                                       return TEEC_ERROR_GENERIC;
+                               }
+
+                               if ((buffer = (char*) shmat(shmid, NULL, 0)) == (char*) -1) {
+                                       LOGE(TEEC_LIB, "shmat failed");
+                                       return TEEC_ERROR_GENERIC;
+                               }
+
+                               if (!buffer) {
+                                       LOGE(TEEC_LIB, "shmat failed");
+                                       return TEEC_ERROR_GENERIC;
+                               }
+
+                               fprintf(f1, "SharedMemData: \n");
+                               char *shmdata = (buffer + icdata.operation.params[i].mem.offset);
+                               for (j = 0; j < icdata.operation.params[i].mem.size; j++)
+                               fprintf(f1, "%x", shmdata[j]);
+                               fprintf(f1, "\n");
+
+                               if (shmdt(buffer) == -1) {
+                                       printf("shmdt failed");
+                               }
+                               buffer = NULL;
+                       }
+               }
+               fprintf(f1, "OperationID %d\nreturnOrigin %d\nreturnValue %d\n",
+                               icdata.operation.OperationID, icdata.returnOrigin, icdata.returnValue);
+               fclose(f1);
+               break;
+               case REQUEST_CANCELLATION:
+               if (in == 1)
+               fname = "ReqCancell.txt";
+               else
+               fname = "ReqCancellResult.txt";
+               //Not supported in current design
+               break;
+               default:
+               LOGE(TEEC_LIB, "Invalid command");
+       }
+       return TEEC_SUCCESS;
+}
+#endif
+
+/* 
+ * ===  FUNCTION  ======================================================================
+ *         Name:  sendCommand
+ *  Description:  API (Interface for TEECAPI) implementation for sending a
+ *                command to Simulator daemon
+ *   Parameters:       sockfd - Socket fd
+ *                                                     cmd - Command sent/received
+ *                                                     fdata - data sent/received
+ *                                                     size - size of data sent/received
+ *              Return:        TEEC_SUCCESS: Success
+ *                                               TEEC_ERROR_GENERIC: Failure
+ * =====================================================================================
+ */
+uint32_t sendCommand(int32_t sockfd, TEE_CMD cmd, void* data, size_t size) {
+       LOGD(TEEC_LIB, "Entry");
+       TEEC_Result result = TEEC_SUCCESS;
+       char command = (char)cmd;
+
+#ifdef TEST
+       // Check if the data is proper
+       result = Test(command, data, size, 1);
+       if (result != TEEC_SUCCESS) {
+               return TEEC_ERROR_GENERIC;
+       }
+#endif
+       // send command to Simulator Daemon
+       result = sendCommandtoDaemon(sockfd, (char*)&command, sizeof(char));
+       if (result != TEEC_SUCCESS) {
+               return TEEC_ERROR_GENERIC;
+       }
+       // send command data to Simulator Daemon
+       result = sendCommandtoDaemon(sockfd, (char*)data, size);
+       if (result != TEEC_SUCCESS) {
+               return TEEC_ERROR_GENERIC;
+       }
+       // receive command from Simulator Daemon
+       result = receiveResponse(sockfd, (char*)&command, sizeof(char));
+       if (result != TEEC_SUCCESS) {
+               return TEEC_ERROR_GENERIC;
+       }
+       // receive command data from Simulator Daemon
+       result = receiveResponse(sockfd, (char*)data, size);
+       if (result != TEEC_SUCCESS) {
+               return TEEC_ERROR_GENERIC;
+       }
+#ifdef TEST
+       // Check if the data is proper
+       result = Test(command, data, size, 0);
+       if (result != TEEC_SUCCESS) {
+               return TEEC_ERROR_GENERIC;
+       }
+#endif
+       return result;
+}
diff --git a/TEEStub/.cproject b/TEEStub/.cproject
new file mode 100755 (executable)
index 0000000..9ed7e56
--- /dev/null
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1955467152">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1955467152" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings>
+                                       <externalSetting>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/TEEStub"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/TEEStub/Debug"/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="TEEStub" srcPrefixMapping="" srcRootPath=""/>
+                                       </externalSetting>
+                               </externalSettings>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1955467152" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug" postbuildStep="">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1955467152." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1449006830" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.825635640" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
+                                                       <builder buildPath="${workspace_loc:/TEEStub/Debug}" id="cdt.managedbuild.target.gnu.builder.exe.debug.692581027" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
+                                                       <tool commandLinePattern="${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ../../log/Debug/log.o" id="cdt.managedbuild.tool.gnu.archiver.base.807434037" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1039026998" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
+                                                               <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.525868718" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1681341605" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.include.paths.1087921098" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/include/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../ssflib/inc&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.compiler.option.other.other.1169906680" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" useByScannerDiscovery="false" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <option id="gnu.cpp.compiler.option.dialect.std.697389764" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.535611869" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2105062808" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1894059728" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.exe.debug.option.debugging.level.2138735640" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.misc.other.1463309461" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <option id="gnu.c.compiler.option.include.paths.1502177071" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="${workspace_loc:/include/include}"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/ssflib/inc}&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.c.compiler.option.dialect.std.916936364" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.208162664" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.992157221" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
+                                                               <option defaultValue="true" id="gnu.c.link.option.shared.2106073913" name="Shared (-shared)" superClass="gnu.c.link.option.shared" valueType="boolean"/>
+                                                       </tool>
+                                                       <tool command="g++" id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.165077164" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
+                                                               <option id="gnu.cpp.link.option.paths.918423048" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/ssflib/Debug}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="/usr/local/lib"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.link.option.libs.308192272" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
+                                                                       <listOptionValue builtIn="false" value="pthread"/>
+                                                                       <listOptionValue builtIn="false" value="ssflib"/>
+                                                                       <listOptionValue builtIn="false" value="boost_thread"/>
+                                                                       <listOptionValue builtIn="false" value="boost_system"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.link.option.flags.48763098" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-fmessage-length=0 -Wl,-rpath=&quot;${workspace_loc:/${ProjName}}/../ssflib/Debug&quot;" valueType="string"/>
+                                                               <option id="gnu.cpp.link.option.other.2023739620" name="Other options (-Xlinker [option])" superClass="gnu.cpp.link.option.other"/>
+                                                               <option defaultValue="true" id="gnu.cpp.link.option.shared.1812936745" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" valueType="boolean"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1932371634" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.541106137" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1446974415" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1350514530">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1350514530" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1350514530" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.exe.release.1350514530." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1881434458" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1140414013" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
+                                                       <builder buildPath="${workspace_loc:/TEEStub/Release}" id="cdt.managedbuild.target.gnu.builder.exe.release.1997461956" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.1637896193" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.419108628" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
+                                                               <option id="gnu.cpp.compiler.exe.release.option.optimization.level.1341538649" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.exe.release.option.debugging.level.336041258" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.492401246" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1194584617" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
+                                                               <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.1816003718" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.exe.release.option.debugging.level.873407693" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1513122754" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.406314174" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1606470224" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.76826893" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.2124734211" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1948793594" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="TEEStub.cdt.managedbuild.target.gnu.exe.618517162" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1350514530;cdt.managedbuild.config.gnu.exe.release.1350514530.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1194584617;cdt.managedbuild.tool.gnu.c.compiler.input.1513122754">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1955467152;cdt.managedbuild.config.gnu.exe.debug.1955467152.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2105062808;cdt.managedbuild.tool.gnu.c.compiler.input.208162664">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1840422736;cdt.managedbuild.config.gnu.exe.release.1840422736.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1923251783;cdt.managedbuild.tool.gnu.cpp.compiler.input.1894020902">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1840422736;cdt.managedbuild.config.gnu.exe.release.1840422736.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.2031867453;cdt.managedbuild.tool.gnu.c.compiler.input.1392949639">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.196208732;cdt.managedbuild.config.gnu.exe.debug.196208732.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.2069440054;cdt.managedbuild.tool.gnu.c.compiler.input.1935981755">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1350514530;cdt.managedbuild.config.gnu.exe.release.1350514530.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.419108628;cdt.managedbuild.tool.gnu.cpp.compiler.input.492401246">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1955467152;cdt.managedbuild.config.gnu.exe.debug.1955467152.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1039026998;cdt.managedbuild.tool.gnu.cpp.compiler.input.535611869">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.196208732;cdt.managedbuild.config.gnu.exe.debug.196208732.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1153050214;cdt.managedbuild.tool.gnu.cpp.compiler.input.839338597">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="refreshScope" versionNumber="2">
+               <configuration configurationName="Windows-Debug">
+                       <resource resourceType="PROJECT" workspacePath="/TEEStub"/>
+               </configuration>
+               <configuration configurationName="Debug">
+                       <resource resourceType="PROJECT" workspacePath="/TEEStub"/>
+               </configuration>
+               <configuration configurationName="Release">
+                       <resource resourceType="PROJECT" workspacePath="/TEEStub"/>
+               </configuration>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+</cproject>
diff --git a/TEEStub/.gitignore b/TEEStub/.gitignore
new file mode 100755 (executable)
index 0000000..3df573f
--- /dev/null
@@ -0,0 +1 @@
+/Debug/
diff --git a/TEEStub/.project b/TEEStub/.project
new file mode 100755 (executable)
index 0000000..dae54e6
--- /dev/null
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>TEEStub</name>
+       <comment></comment>
+       <projects>
+               <project>ssflib</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                               <dictionary>
+                                       <key>?name?</key>
+                                       <value></value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.append_environment</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
+                                       <value>all</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildArguments</key>
+                                       <value></value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildCommand</key>
+                                       <value>make</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.buildLocation</key>
+                                       <value>${workspace_loc:/TEEStub/Debug}</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
+                                       <value>clean</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.contents</key>
+                                       <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
+                                       <value>false</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.enableFullBuild</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
+                                       <value>all</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.stopOnError</key>
+                                       <value>true</value>
+                               </dictionary>
+                               <dictionary>
+                                       <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
+                                       <value>true</value>
+                               </dictionary>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/TEEStub/.settings/org.eclipse.cdt.core.prefs b/TEEStub/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..935792c
--- /dev/null
@@ -0,0 +1,16 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152.533145061/PATH/delimiter=\:
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152.533145061/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152.533145061/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\Program Files (x86)\\Java\\jre1.8.0_45\\bin;C\:\\Program Files\\eclipse;C\:/Program Files/Java/jre1.8.0_31/bin/server;C\:/Program Files/Java/jre1.8.0_31/bin;C\:/Program Files/Java/jre1.8.0_31/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\csvn\\bin\\;C\:\\csvn\\Python25\\;C\:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files\\Diskeeper Corporation\\ExpressCache\\;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x64;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files (x86)\\WinSCP\\;C\:\\Program Files (x86)\\PuTTY;C\:\\Program Files\\Microsoft\\Web Platform Installer\\;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C\:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;C\:\\Program Files (x86)\\doxygen\\bin;C\:\\Program Files (x86)\\sfk168;C\:\\Program Files (x86)\\vlc-2.1.0;C\:\\Python27\\Scripts;C\:\\Program Files (x86)\\GnuWin32\\bin;C\:\\Python27;C\:\\Program Files (x86)\\Subversion\\bin;c\:\\Program Files\\Synergy;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\MinGW\\lib\\gcc\\mingw32\\4.8.1;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C\:\\Program Files (x86)\\GitExtensions\\;C\:\\Program Files\\Perforce;c\:\\Program Files\\Java\\jre1.8.0_31\\bin\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;D\:\\tizen-sdk\\ide;D\:\\samsung-tv-sdk\\tasdk_ide\\tasdk_tools\\i386-linux-gnueabi-gcc-4.6\\bin;D\:\\samsung-tv-sdk\\tasdk_ide\\tasdk_tools\\mingw\\bin;D\:\\samsung-tv-sdk\\tasdk_ide\\tasdk_tools\\mingw\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152.533145061/append=true
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152.533145061/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152/PATH/delimiter=\:
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152/PATH/value=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/usr/games\:/usr/local/games\:/usr/local/lib\:usr/lib;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\bin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\mingbin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152/append=true
+environment/project/cdt.managedbuild.config.gnu.exe.debug.1955467152/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.exe.release.1350514530/PATH/delimiter=\:
+environment/project/cdt.managedbuild.config.gnu.exe.release.1350514530/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.exe.release.1350514530/PATH/value=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/usr/games\:/usr/local/games
+environment/project/cdt.managedbuild.config.gnu.exe.release.1350514530/append=true
+environment/project/cdt.managedbuild.config.gnu.exe.release.1350514530/appendContributed=true
diff --git a/TEEStub/.settings/org.eclipse.cdt.ui.prefs b/TEEStub/.settings/org.eclipse.cdt.ui.prefs
new file mode 100755 (executable)
index 0000000..4ee12a4
--- /dev/null
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+formatter_settings_version=1
diff --git a/TEEStub/.settings/org.eclipse.ltk.core.refactoring.prefs b/TEEStub/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100755 (executable)
index 0000000..b196c64
--- /dev/null
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/TEEStub/DeveloperReadme.txt b/TEEStub/DeveloperReadme.txt
new file mode 100755 (executable)
index 0000000..58c5444
--- /dev/null
@@ -0,0 +1,43 @@
+# Samsung Research and Development Institute, Bangalore
+# Copyright (c) 2015, All Rights Reserved
+
+This readme is a developer's log book on progress of implementation and status
+of functionality. It is intended to aid development and is not to be 
+used for any other purpose. 
+
+
+Properties:
+1.     As per specification, Property access function shall be accessible as described below:
+
+                       Excerpt from TEE Internal Specification:
+                       |       Note that Client Properties can be accessed only in the context of a TA entry point associated with
+                       |       a client, i.e. in one of the following entry point 
+                       |       functions: TA_OpenSessionEntryPoint, TA_InvokeCommandEntryPoint, or TA_CloseSessionEntryPoint 
+       
+       Access to the property functions in above mentioned restricted context is yet to be implemented in case of
+       Client properties.
+
+2.     Due to change in C standards, compilers do not support typecasting to pointer type of constant values
+       in #define s. As per spec. we need to define Propsets as:
+       TEE_PROPSET_TEE_IMPLEMENTATION (TEE_PropSetHandle)0xFFFFFFFD
+       The above is not possible anymore. Specification does not understand this.
+       
+       As of now, above macro is defined as:
+       TEE_PROPSET_TEE_IMPLEMENTATION 0xFFFFFFFD
+       
+       Which forces user to typecast TEE_PROPSET_TEE_IMPLEMENTATION to (TEE_PropSetHandle)TEE_PROPSET_TEE_IMPLEMENTATION
+       when calling Property Access APIs
+       
+3.     Client Identity for client properties: UUID of client doesn't make sense as it is not defined in the
+       specificationc clearly. As of now the client UUID is set to Nil UUID. This needs to be fixed when
+       permission management to access TA Entrypoints is to be enforced.
+
+4.     Client Properties may need to stored on each new session and appended to a list of client props.
+       All of the client properties bear the name "gpd.client.identity" hence has to be a list
+       unlike other propsets which use maps as they have unique keys. This feature is yet to be implemented.
+       
+SSFLib:
+1.     Communication with other TAs from this TA:
+               Replies from other multiple TA to be handled yet based on operation IDs or some other
+               way of unique identification of commands to map replies to caller.
+        
\ No newline at end of file
diff --git a/TEEStub/PropertyAccess/ClientProperty.cpp b/TEEStub/PropertyAccess/ClientProperty.cpp
new file mode 100755 (executable)
index 0000000..1184d3d
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  ClientProperty.cpp\r
+ *\r
+ *    Description:  ClientProperty class\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/ClientProperty.h>\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Member functions\r
+ *-----------------------------------------------------------------------------*/\r
+/**\r
+ * Constructor of Client Property\r
+ * @param filePath[in] file to read Client properties from.\r
+ */\r
+// TODO: identity by defauly in property file to be stored as\r
+// identity: integer (‘:’ uuid)?\r
+// so that when fetched, is by default in string format as stated above\r
+ClientProperty::ClientProperty(PropertyValue init) :\r
+               theOnlyClientPropertyName("gpd.client.identity"), theOnlyCientProperty(init) {\r
+}\r
+\r
+/**\r
+ * Get name of the property in format gpd.client.*\r
+ * @param name[out]     Name of property\r
+ * @return  true if enumerator marker is pointing in valid range else false/\r
+ */\r
+bool ClientProperty::getPropertyName(string &name) {\r
+       name = theOnlyClientPropertyName;\r
+       return true;\r
+}\r
+\r
+/**\r
+ * Advance the marker of enumerator to point to next property\r
+ * @return true if successfully advanced to next property else false\r
+ * if marker reached end of enumeration.\r
+ */\r
+bool ClientProperty::getNextProperty() {\r
+       // Do nothing, as we have only one property in enumeration\r
+       return false;\r
+}\r
+\r
+/**\r
+ * Start enumeration by reading the property file and set marker to first property\r
+ * @return true if property file successfully read else false\r
+ */\r
+bool ClientProperty::start() {\r
+       // Do nothing, as we have only one property in enumeration\r
+       return true;\r
+}\r
+\r
+/**\r
+ * Reset marker to start from first.\r
+ */\r
+void ClientProperty::reset() {\r
+       // Do nothing, as we have only one property in enumeration\r
+}\r
+\r
+/**\r
+ * Get property value pointed by marker currently.\r
+ * @param pv[out]   Property value pointed by marker\r
+ * @return  If marker is not pointing to end of enumeration then returns true\r
+ * else false\r
+ */\r
+bool ClientProperty::getPropertyValue(PropertyValue &pv) {\r
+       pv = theOnlyCientProperty;\r
+       return true;\r
+}\r
+\r
+/**\r
+ * Client property destructor\r
+ */\r
+ClientProperty::~ClientProperty() {\r
+}\r
+\r
+/**\r
+ * Get property value associated with given property name by searching for it\r
+ * @param propName[in]  Property name in format gpd.client.*\r
+ * @param value[out]    Property value on successful match\r
+ * @return true if property of given name exists else false\r
+ */\r
+bool ClientProperty::getPropertyByName(const string &propName,\r
+    PropertyValue &value) {\r
+       if (theOnlyClientPropertyName == propName) {\r
+               value = theOnlyCientProperty;\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
diff --git a/TEEStub/PropertyAccess/ClientProperty.h b/TEEStub/PropertyAccess/ClientProperty.h
new file mode 100755 (executable)
index 0000000..e6c0a91
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  ClientProperty.h\r
+ *\r
+ *    Description:  ClientProperty header file\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+#ifndef PROPERTYACCESS_CLIENTPROPERTY_H_\r
+#define PROPERTYACCESS_CLIENTPROPERTY_H_\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/Property.h>\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Class definitions\r
+ *-----------------------------------------------------------------------------*/\r
+class ClientProperty:\r
+    public Property {\r
+private:\r
+       string theOnlyClientPropertyName;\r
+       PropertyValue theOnlyCientProperty;\r
+public:\r
+       bool getPropertyName(string&);\r
+       bool getPropertyByName(const string &propName, PropertyValue &value);\r
+       bool getNextProperty();\r
+       bool getPropertyValue(PropertyValue&);\r
+       bool start();\r
+       void reset();\r
+       ClientProperty(PropertyValue init);\r
+       virtual ~ClientProperty();\r
+};\r
+\r
+#endif /* PROPERTYACCESS_CLIENTPROPERTY_H_ */\r
diff --git a/TEEStub/PropertyAccess/Property.h b/TEEStub/PropertyAccess/Property.h
new file mode 100755 (executable)
index 0000000..a0b3519
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  Property.h\r
+ *\r
+ *    Description:  Property header file\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  20 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+#ifndef PROPERTYACCESS_PROPERTY_H_\r
+#define PROPERTYACCESS_PROPERTY_H_\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <string>\r
+using namespace std;\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Definitions\r
+ *-----------------------------------------------------------------------------*/\r
+typedef struct {\r
+       string type;\r
+       string value;\r
+} PropertyValue;\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Class definitions\r
+ *-----------------------------------------------------------------------------*/\r
+class Property {\r
+public:\r
+       virtual bool getPropertyName(string&) = 0;\r
+       virtual bool getPropertyByName(const string &propName,\r
+           PropertyValue &value) = 0;\r
+       virtual bool getNextProperty() = 0;\r
+       virtual bool start() = 0;\r
+       virtual void reset() = 0;\r
+       virtual bool getPropertyValue(PropertyValue&) = 0;\r
+       Property() {\r
+       }\r
+       ;\r
+       virtual ~Property() {\r
+       }\r
+       ;\r
+};\r
+\r
+#endif /* PROPERTYACCESS_PROPERTY_H_ */\r
diff --git a/TEEStub/PropertyAccess/PropertyApi.cpp b/TEEStub/PropertyAccess/PropertyApi.cpp
new file mode 100755 (executable)
index 0000000..7cc2e15
--- /dev/null
@@ -0,0 +1,405 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  PropertyApi.cpp\r
+ *\r
+ *    Description:  PropertyApi class\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/Property.h>\r
+#include <PropertyAccess/PropertyApi.h>\r
+#include <PropertyAccess/ClientProperty.h>\r
+#include <PropertyAccess/TEEProperty.h>\r
+#include <PropertyAccess/TAProperty.h>\r
+#include <PropertyAccess/PropertyUtility.h>\r
+#include "config.h"\r
+#include <string.h>\r
+\r
+using namespace std;\r
+\r
+// PRIVATE TO THIS API FILE\r
+static Property* clientProperty;\r
+static Property* taProperty;\r
+static Property* teeProperty;\r
+static uint32_t clientLoginGlobal = 0;\r
+static string thisTAUUIDGlobal = "";\r
+bool _allowPropertyAccess = false;\r
+\r
+/**\r
+ * Static local function to identify the right object of Property\r
+ * If propsetOrEnumerator is a constant propset then existing objects of\r
+ * Property on given propset is returned. If propsetOrEnumerator is a handle to\r
+ * an enumerator then PropertyEnumHandle object is returned.\r
+ * @param propsetOrEnumerator[in]   A handle of type TEE_PropSetHandle\r
+ * @return NULL if handle is invalid else returns valid handle\r
+ */\r
+static Property* _GetTargetProperty(TEE_PropSetHandle propsetOrEnumerator);\r
+\r
+//GLOBAL DEFNS\r
+typedef struct {\r
+       Property* property;\r
+} PropertyEnumHandle;\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Member functions\r
+ *-----------------------------------------------------------------------------*/\r
+/**\r
+ * Initialization routine of PropertyAccess Module. This function should be\r
+ * called when TA stub starts with UUID of this TA.\r
+ * @param UUID[in]          UUID of this TA\r
+ * @param clientLogin[in]   login method to this TA from client.\r
+ *                          Refer Table 4-13: Client Identities\r
+ * @return TEE_ERROR_OUT_OF_MEMORY on failure to initialize else TEE_SUCCESS\r
+ */\r
+TEE_Result InitPropertyModule(char* UUID, uint32_t clientLogin) {\r
+       PropertyValue pv;\r
+       pv.type = "identity";\r
+       pv.value = "" + clientLogin;\r
+       string thisTA_UUID(UUID);\r
+       clientLoginGlobal = clientLogin;\r
+       thisTAUUIDGlobal = thisTA_UUID;\r
+       try {\r
+               clientProperty = new ClientProperty(pv);\r
+               clientProperty->start();\r
+               teeProperty = new TEEProperty();\r
+               teeProperty->start();\r
+               taProperty = new TAProperty(\r
+                   string(TEE_TASTORE_ROOT) + thisTA_UUID + "-ext/" + thisTA_UUID\r
+                       + ".manifest");\r
+               taProperty->start();\r
+       } catch (std::bad_alloc &ba) {\r
+               return TEE_ERROR_OUT_OF_MEMORY;\r
+       }\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+/**\r
+ * Deallocate Property Access objects\r
+ */\r
+void DeInitPropertyModule() {\r
+       delete clientProperty;\r
+       delete taProperty;\r
+       delete teeProperty;\r
+}\r
+\r
+//TODO: TEE_ERROR_ITEM_NOT_FOUND also to be returned when the string\r
+//received in not UTF8 encoded format\r
+//Assuming valueBufferLen is [in] param only.\r
+\r
+TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,\r
+    const char* name, char* valueBuffer, size_t* valueBufferLen) {\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       Property* targetProperty = NULL;\r
+       PropertyValue pv;\r
+       string queryProp = "";\r
+\r
+       if (NULL == propsetOrEnumerator){\r
+               return TEE_ERROR_ITEM_NOT_FOUND;\r
+       }\r
+\r
+       if (NULL != name) queryProp = string(name);\r
+       // 1. Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(propsetOrEnumerator);\r
+       // 2. after selecting targetProperty fetch the property name\r
+       if (targetProperty\r
+           && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))\r
+               || (NULL == name && targetProperty->getPropertyValue(pv)))) {\r
+               if (valueBuffer && pv.value.size() < *valueBufferLen)\r
+                       strncpy(valueBuffer, pv.value.c_str(), *valueBufferLen);\r
+               else returnValue = TEE_ERROR_SHORT_BUFFER;\r
+       } else returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+\r
+// Above is optimized version of below\r
+#if 0\r
+\r
+       if (NULL != name && targetProperty && targetProperty->getPropertyByName(queryProp, pv))\r
+       {\r
+               // SIZE FITS IN BUFFER\r
+               if (pv.value.size() < *valueBufferLen)\r
+               strcpy(valueBuffer, pv.value.c_str());\r
+               else\r
+               returnValue = TEE_ERROR_SHORT_BUFFER;\r
+       }\r
+       else if (NULL == name && targetProperty && targetProperty->getPropertyValue(pv))\r
+       {\r
+               if (pv.value.size() < *valueBufferLen)\r
+               strcpy(valueBuffer, pv.value.c_str());\r
+               else\r
+               returnValue = TEE_ERROR_SHORT_BUFFER;\r
+       }\r
+       else\r
+       returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+#endif\r
+       return returnValue;\r
+}\r
+\r
+TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,\r
+    const char* name, bool* value) {\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       Property* targetProperty = NULL;\r
+       PropertyValue pv;\r
+       string queryProp = "";\r
+       if (NULL != name) queryProp = string(name);\r
+       // 1. Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(propsetOrEnumerator);\r
+       // 2. after selecting targetProperty fetch the property by name or as in\r
+       // pointed by enumerator marker\r
+       if (targetProperty\r
+           && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))\r
+               || (NULL == name && targetProperty->getPropertyValue(pv)))) {\r
+               returnValue = PropertyUtility::convertToBool(pv, *value);\r
+       } else returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+// Above is optimized version of below\r
+#if 0\r
+       if (NULL != name && targetProperty && targetProperty->getPropertyByName(queryProp, pv))\r
+       {\r
+               returnValue = PropertyUtility::convertToBool(pv, *value);\r
+       }\r
+       else if (NULL == name && targetProperty && targetProperty->getPropertyValue(pv))\r
+       {\r
+               returnValue = PropertyUtility::convertToBool(pv, *value);\r
+       }\r
+       else\r
+       returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+#endif\r
+       return returnValue;\r
+}\r
+\r
+TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,\r
+    const char* name, uint32_t* value) {\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       Property* targetProperty = NULL;\r
+       PropertyValue pv;\r
+       string queryProp = "";\r
+       if (NULL != name) queryProp = string(name);\r
+       // 1. Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(propsetOrEnumerator);\r
+       // 2. after selecting targetProperty fetch the property by name or as in\r
+       // pointed by enumerator marker\r
+       if (targetProperty\r
+           && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))\r
+               || (NULL == name && targetProperty->getPropertyValue(pv)))) {\r
+               returnValue = PropertyUtility::convertToU32(pv, *value);\r
+       } else returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+       return returnValue;\r
+}\r
+\r
+TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,\r
+    const char* name, void* valueBuffer, size_t* valueBufferLen) {\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       Property* targetProperty = NULL;\r
+       PropertyValue pv;\r
+       string queryProp = "";\r
+       if (NULL != name) queryProp = string(name);\r
+\r
+       // Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(propsetOrEnumerator);\r
+       // After selecting targetProperty fetch the property name\r
+       if (targetProperty\r
+           && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))\r
+               || (NULL == name && targetProperty->getPropertyValue(pv)))) {\r
+\r
+               string binaryBlockOut;\r
+               returnValue = PropertyUtility::convertToBinaryBlock(pv, binaryBlockOut);\r
+               bool conversionStatus = (returnValue == TEE_SUCCESS) ? true : false;\r
+               if (valueBuffer && conversionStatus\r
+                   && binaryBlockOut.size() < *valueBufferLen) {\r
+                       strncpy((char*)valueBuffer, binaryBlockOut.c_str(), *valueBufferLen);\r
+               } else returnValue = TEE_ERROR_SHORT_BUFFER;\r
+       } else returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+       return returnValue;\r
+}\r
+\r
+// TODO: In spec: value: A pointer filled with the UUID. MUST NOT be NULL.\r
+// What does it mean? Must not be NULL\r
+TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,\r
+    const char* name, TEE_UUID* value) {\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       Property* targetProperty = NULL;\r
+       PropertyValue pv;\r
+       string queryProp = "";\r
+       if (NULL != name) queryProp = string(name);\r
+       // 1. Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(propsetOrEnumerator);\r
+       // 2. after selecting targetProperty fetch the property by name or as in\r
+       // pointed by enumerator marker\r
+       if (targetProperty\r
+           && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))\r
+               || (NULL == name && targetProperty->getPropertyValue(pv)))) {\r
+               returnValue = PropertyUtility::convertToUUID(pv, *value);\r
+       } else returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+       return returnValue;\r
+}\r
+\r
+// TODO: In spec: value: A pointer filled with the UUID. MUST NOT be NULL.\r
+// What does it mean? Must not be NULL\r
+TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,\r
+    const char* name, TEE_Identity* value) {\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       Property* targetProperty = NULL;\r
+       PropertyValue pv;\r
+       string queryProp = "";\r
+       if (NULL != name) queryProp = string(name);\r
+       // 1. Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(propsetOrEnumerator);\r
+       // 2. after selecting targetProperty fetch the property by name or as in\r
+       // pointed by enumerator marker\r
+       if (targetProperty\r
+           && ((NULL != name && targetProperty->getPropertyByName(queryProp, pv))\r
+               || (NULL == name && targetProperty->getPropertyValue(pv)))) {\r
+               returnValue = PropertyUtility::convertToIdentity(pv, *value);\r
+       } else returnValue = TEE_ERROR_ITEM_NOT_FOUND;\r
+       return returnValue;\r
+}\r
+\r
+TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle* enumerator) {\r
+       try {\r
+               PropertyEnumHandle *newEnumHandle = new PropertyEnumHandle;\r
+               newEnumHandle->property = NULL;\r
+               *enumerator = (TEE_PropSetHandle)newEnumHandle;\r
+       } catch (std::bad_alloc &ba) {\r
+               return TEE_ERROR_OUT_OF_MEMORY;\r
+       }\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator) {\r
+       PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;\r
+       if (enumeratorHandle) {\r
+               delete enumeratorHandle->property;\r
+               enumeratorHandle = NULL;\r
+               delete enumeratorHandle;\r
+       }\r
+}\r
+\r
+//TODO: propSet value sent from user has to typecased to TEE_PropSetHandle\r
+// this shouldnt happen, make it straight\r
+void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,\r
+    TEE_PropSetHandle propSet) {\r
+       PropertyEnumHandle *newEnumHandle = (PropertyEnumHandle*)enumerator;\r
+       switch ((uint32_t)propSet) {\r
+               case TEE_PROPSET_CURRENT_TA: {\r
+                       newEnumHandle->property = new TAProperty(\r
+                           string(TEE_TASTORE_ROOT) + thisTAUUIDGlobal + "-ext/"\r
+                               + thisTAUUIDGlobal + ".manifest");\r
+                       break;\r
+               }\r
+               case TEE_PROPSET_CURRENT_CLIENT: {\r
+                       PropertyValue pv;\r
+                       pv.type = "identity";\r
+                       pv.value = "" + clientLoginGlobal;\r
+                       if(!_allowPropertyAccess)\r
+                       {\r
+                               break;\r
+                       }                                       \r
+                       newEnumHandle->property = new ClientProperty(pv);\r
+                       break;\r
+               }\r
+               case TEE_PROPSET_TEE_IMPLEMENTATION: {\r
+                       newEnumHandle->property = new TEEProperty();\r
+                       break;\r
+               }\r
+               default: {\r
+                       // Nothing\r
+                       break;\r
+               }\r
+       }\r
+\r
+       if (newEnumHandle && newEnumHandle->property)   \r
+               newEnumHandle->property->start();\r
+}\r
+\r
+void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator) {\r
+       PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;\r
+       if (enumeratorHandle->property) delete enumeratorHandle->property;\r
+}\r
+\r
+/*\r
+ * Considers nameBufferLen as [in] param as spec. is ambiguous\r
+ */\r
+TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator, void* nameBuffer,\r
+    size_t* nameBufferLen) {\r
+       Property* targetProperty = NULL;\r
+       // 1. Select the enumerator object based on propset or consider given enumerator\r
+       // if any\r
+       targetProperty = _GetTargetProperty(enumerator);\r
+       \r
+       PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;\r
+       // Check if enumerator and property are valid\r
+       //if (enumeratorHandle && enumeratorHandle->property) {\r
+       if (enumeratorHandle && targetProperty) {\r
+               string propName;\r
+               // If item exists and and not reached end of enumerator, get the name\r
+               if (enumeratorHandle->property->getPropertyName(propName)) {\r
+                       if (*nameBufferLen < propName.size() + 1) return TEE_ERROR_SHORT_BUFFER;\r
+                       strncpy((char*)nameBuffer, propName.c_str(), *nameBufferLen);\r
+               }\r
+               // item not found or enumerator end has reached\r
+               else {\r
+                       return TEE_ERROR_ITEM_NOT_FOUND;\r
+               }\r
+       } else {\r
+               return TEE_ERROR_ITEM_NOT_FOUND;\r
+       }\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator) {\r
+       PropertyEnumHandle* enumeratorHandle = (PropertyEnumHandle*)enumerator;\r
+       // Check if enumerator and property are valid and enumerator has not reached end of enum\r
+       if (enumeratorHandle && enumeratorHandle->property\r
+           && enumeratorHandle->property->getNextProperty()) {\r
+               return TEE_SUCCESS;\r
+       } else return TEE_ERROR_ITEM_NOT_FOUND;\r
+\r
+}\r
+\r
+Property* _GetTargetProperty(TEE_PropSetHandle propsetOrEnumerator) {\r
+       Property *targetProperty = NULL;\r
+       switch ((uint32_t)propsetOrEnumerator) {\r
+               case TEE_PROPSET_TEE_IMPLEMENTATION: {\r
+                       targetProperty = teeProperty;\r
+                       break;\r
+               }\r
+               case TEE_PROPSET_CURRENT_CLIENT: {\r
+                       if(!_allowPropertyAccess)\r
+                       {\r
+                               break;\r
+                       }\r
+                       targetProperty = clientProperty;\r
+                       break;\r
+               }\r
+               case TEE_PROPSET_CURRENT_TA: {\r
+                       targetProperty = taProperty;\r
+                       break;\r
+               }\r
+/*             default: {\r
+                       PropertyEnumHandle *newEnumHandle =\r
+                           (PropertyEnumHandle*)propsetOrEnumerator;\r
+\r
+                       if (newEnumHandle && newEnumHandle->property) \r
+                               targetProperty = newEnumHandle->property;\r
+                       break;\r
+               }\r
+*/     }\r
+       return targetProperty;\r
+}\r
diff --git a/TEEStub/PropertyAccess/PropertyApi.h b/TEEStub/PropertyAccess/PropertyApi.h
new file mode 100755 (executable)
index 0000000..f7e5de3
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  PropertyApi.h\r
+ *\r
+ *    Description:  PropertyApi header file\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+#ifndef PROPERTYACCESS_PROPERTYAPI_H_\r
+#define PROPERTYACCESS_PROPERTYAPI_H_\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include "tee_internal_api.h"\r
+\r
+#ifdef  __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Functions\r
+ *-----------------------------------------------------------------------------*/\r
+TEE_Result InitPropertyModule(char* UUID, uint32_t clientLogin);\r
+void DeInitPropertyModule();\r
+\r
+#ifdef  __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* PROPERTYACCESS_PROPERTYAPI_H_ */\r
diff --git a/TEEStub/PropertyAccess/PropertyUtility.cpp b/TEEStub/PropertyAccess/PropertyUtility.cpp
new file mode 100755 (executable)
index 0000000..7603aa0
--- /dev/null
@@ -0,0 +1,384 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  PropertyUtility.cpp\r
+ *\r
+ *    Description:  PropertyUtility class\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/PropertyUtility.h>\r
+#include <sstream>\r
+#include <string>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <sstream>\r
+\r
+using namespace std;\r
+\r
+/// Constant charset of base64 encoding\r
+static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\r
+               "abcdefghijklmnopqrstuvwxyz"\r
+               "0123456789+/";\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Member functions\r
+ *-----------------------------------------------------------------------------*/\r
+/**\r
+ * Converts a string in properties entry to UTF8\r
+ * ACSII printable characters are subset of UTF8 hence no need of conversion.\r
+ * @param in[in]    a property to be converted to UTF8\r
+ * @param out[out]  converted property\r
+ * @return TEE_SUCCESS always. Here function returns fixed value for the\r
+ * to maintain uniformity.\r
+ */\r
+TEE_Result PropertyUtility::convertToUTF8(const PropertyValue& in,\r
+    string& out) {\r
+       out = in.value;\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+/**\r
+ * Try to convert given property to bool\r
+ * @param in[in]    a property to be converted to bool\r
+ * @param out[out]  converted property\r
+ * @return\r
+ */\r
+TEE_Result PropertyUtility::convertToBool(const PropertyValue &in, bool& out) {\r
+       TEE_Result returnval = TEE_SUCCESS;\r
+       if (in.type == "boolean") {\r
+               if ("true" == in.value)\r
+                       out = true;\r
+               else out = false;\r
+       } else {\r
+               // As per spec: A pointer to the variable that will contain the value of the\r
+               // property on success or "false" on error. Hence default value is "false"\r
+               out = false;\r
+               returnval = TEE_ERROR_BAD_FORMAT;\r
+       }\r
+       return returnval;\r
+}\r
+\r
+/**\r
+ * Try to convert given property to unsigned 32 bit integer\r
+ * @param in[in]    a property to be converted to 32 bit unsigned integer\r
+ * @param out[out]  converted property\r
+ * @return\r
+ */\r
+TEE_Result PropertyUtility::convertToU32(const PropertyValue& in,\r
+    uint32_t &out) {\r
+       TEE_Result returnval = TEE_SUCCESS;\r
+       stringstream sstr;\r
+       if (in.type == "integer") {\r
+               sstr << in.value;\r
+               sstr >> out;\r
+       }\r
+       else if (in.type == "boolean")\r
+       {\r
+               out = (in.value == "true" ? 1 : 0);\r
+       }\r
+       else\r
+       { // As per spec:A pointer to the variable that will contain the value of the property\r
+                // on success, or zero on error\r
+                // Hence default value is "false"\r
+               out = 0;\r
+               returnval = TEE_ERROR_BAD_FORMAT;\r
+       }\r
+       return returnval;\r
+}\r
+\r
+/**\r
+ * Try to convert given property to TEE_UUID\r
+ * @param in[in]    a property to be converted to TEE_UUID\r
+ * @param out[out]  converted property\r
+ * @return\r
+ */\r
+TEE_Result PropertyUtility::convertToUUID(const PropertyValue& in,\r
+    TEE_UUID& out) {\r
+       TEE_UUID uuid;\r
+       TEE_Result returnValue = TEE_SUCCESS;\r
+       if ("uuid" == in.type) {\r
+               // Split UUID string into tokens\r
+               string text = in.value;\r
+\r
+               string tokensString[8];\r
+               int i = 0;\r
+               for (i = 0; i < 8; i++) {\r
+                       strncpy(&tokensString[i][0], &text[4 * i], 4);\r
+               }\r
+               // convert each token\r
+               sscanf((tokensString[0] + tokensString[1]).c_str(), "%8x", &uuid.timeLow);\r
+               sscanf(tokensString[2].c_str(), "%4hx", &uuid.timeMid);\r
+               sscanf(tokensString[3].c_str(), "%4hx", &uuid.timeHiAndVersion);\r
+               uint64_t clockSeq;\r
+               string clockSeqStr = tokensString[4] + tokensString[5] + tokensString[6]\r
+                   + tokensString[7];\r
+               //TEST CODE: string clockSeqStr("0123456789ABCDEF");\r
+               sscanf(clockSeqStr.c_str(), "%16llx", &clockSeq);\r
+               memcpy(uuid.clockSeqAndNode, &clockSeq, sizeof(uint64_t));\r
+               // Change endian-ness\r
+               uint8_t temp[4];\r
+               temp[0] = uuid.clockSeqAndNode[0];\r
+               temp[1] = uuid.clockSeqAndNode[1];\r
+               temp[2] = uuid.clockSeqAndNode[2];\r
+               temp[3] = uuid.clockSeqAndNode[3];\r
+               uuid.clockSeqAndNode[0] = uuid.clockSeqAndNode[7];\r
+               uuid.clockSeqAndNode[1] = uuid.clockSeqAndNode[6];\r
+               uuid.clockSeqAndNode[2] = uuid.clockSeqAndNode[5];\r
+               uuid.clockSeqAndNode[3] = uuid.clockSeqAndNode[4];\r
+               uuid.clockSeqAndNode[4] = temp[3];\r
+               uuid.clockSeqAndNode[5] = temp[2];\r
+               uuid.clockSeqAndNode[6] = temp[1];\r
+               uuid.clockSeqAndNode[7] = temp[0];\r
+               out = uuid;\r
+       } else returnValue = TEE_ERROR_BAD_FORMAT;\r
+       return returnValue;\r
+}\r
+\r
+// TODO: If UUID exists need to append that to identity\r
+// Right now it is Nil UUID always\r
+/**\r
+ * Try to convert given property to TEE_Identity\r
+ * @param in[in]    a property to be converted to TEE_Identity\r
+ * @param out[out]  converted property\r
+ * @return\r
+ */\r
+TEE_Result PropertyUtility::convertToIdentity(const PropertyValue& in,\r
+    TEE_Identity& out) {\r
+       if ("identity" != in.type)\r
+               return TEE_ERROR_BAD_FORMAT;\r
+       else {\r
+               out.login = atoi(in.value.c_str());\r
+               // Set to Nil UUID as per [RFC 4122].\r
+               out.uuid.timeLow = 0;\r
+               out.uuid.timeMid = 0;\r
+               out.uuid.timeHiAndVersion = 0;\r
+               for (int i = 0; i < 8; i++) {\r
+                       out.uuid.clockSeqAndNode[i] = 0;\r
+               }\r
+       }\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+/**\r
+ * Convert given property to BinaryBlock in Base64 encoding.\r
+ *\r
+ * @param in[in]    a property to be converted to a block of Base64 encoded data\r
+ * @param out[out]  converted property\r
+ * @return TEE_SUCCESS always. Here function returns fixed value for the\r
+ * to maintain uniformity.\r
+ */\r
+TEE_Result PropertyUtility::convertToBinaryBlock(const PropertyValue& in,\r
+    string& out) {\r
+       string s = in.value;\r
+       string base64Encoded = PropertyUtility::base64_encode(\r
+           reinterpret_cast<const unsigned char*>(s.c_str()), s.size());\r
+       out = base64Encoded;\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+/**\r
+ * Convert given Base64 encoded data to its original form.\r
+ * @param in[in]    a property to be converted from Base64 encoding\r
+ * @param out[out]  converted property back to its original form\r
+ * @return\r
+ */\r
+// TODO: This function to be removed for final release. This is just for testing\r
+TEE_Result PropertyUtility::convertFromBinaryBlock(const string& in,\r
+    string& out) {\r
+       out = PropertyUtility::base64_decode(in);\r
+       return TEE_SUCCESS;\r
+}\r
+\r
+/**\r
+ * Checks if a characters is part of base64 encoding character set\r
+ * @param c character to be verified\r
+ * @return true if conformant to base64 charset else false\r
+ */\r
+bool PropertyUtility::is_base64(unsigned char c) {\r
+       return (isalnum(c) || (c == '+') || (c == '/'));\r
+}\r
+\r
+/**\r
+ * Thanks to: René Nyffenegger\r
+ * Reused from: http://www.adp-gmbh.ch/cpp/common/base64.html\r
+ * License Notice:\r
+ * Copyright (C) 2004-2008 René Nyffenegger\r
+ *\r
+ *  This source code is provided 'as-is', without any express or implied\r
+ *  warranty. In no event will the author be held liable for any damages\r
+ *  arising from the use of this software.\r
+ *\r
+ *  Permission is granted to anyone to use this software for any purpose,\r
+ *  including commercial applications, and to alter it and redistribute it\r
+ *  freely, subject to the following restrictions:\r
+ *\r
+ *  1. The origin of this source code must not be misrepresented; you must not\r
+ *     claim that you wrote the original source code. If you use this source code\r
+ *     in a product, an acknowledgment in the product documentation would be\r
+ *     appreciated but is not required.\r
+ *\r
+ *  2. Altered source versions must be plainly marked as such, and must not be\r
+ *     misrepresented as being the original source code.\r
+ *\r
+ *  3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ *  René Nyffenegger rene.nyffenegger@adp-gmbh.ch\r
+ *\r
+ * @param bytes_to_encode\r
+ * @param in_len\r
+ * @return encoded string\r
+ */\r
+string PropertyUtility::base64_encode(unsigned char const* bytes_to_encode,\r
+    unsigned int in_len) {\r
+       std::string ret;\r
+       int i = 0;\r
+       int j = 0;\r
+       unsigned char char_array_3[3];\r
+       unsigned char char_array_4[4];\r
+\r
+       while (in_len--) {\r
+               char_array_3[i++] = *(bytes_to_encode++);\r
+               if (i == 3) {\r
+                       char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;\r
+                       char_array_4[1] = ((char_array_3[0] & 0x03) << 4)\r
+                           + ((char_array_3[1] & 0xf0) >> 4);\r
+                       char_array_4[2] = ((char_array_3[1] & 0x0f) << 2)\r
+                           + ((char_array_3[2] & 0xc0) >> 6);\r
+                       char_array_4[3] = char_array_3[2] & 0x3f;\r
+\r
+                       for (i = 0; (i < 4); i++)\r
+                               ret += base64_chars[char_array_4[i]];\r
+                       i = 0;\r
+               }\r
+       }\r
+       if (i) {\r
+               for (j = i; j < 3; j++)\r
+                       char_array_3[j] = '\0';\r
+               char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;\r
+               char_array_4[1] = ((char_array_3[0] & 0x03) << 4)\r
+                   + ((char_array_3[1] & 0xf0) >> 4);\r
+               char_array_4[2] = ((char_array_3[1] & 0x0f) << 2)\r
+                   + ((char_array_3[2] & 0xc0) >> 6);\r
+               char_array_4[3] = char_array_3[2] & 0x3f;\r
+               for (j = 0; (j < i + 1); j++)\r
+                       ret += base64_chars[char_array_4[j]];\r
+               while ((i++ < 3))\r
+                       ret += '=';\r
+       }\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * Thanks to: René Nyffenegger\r
+ * Reused from: http://www.adp-gmbh.ch/cpp/common/base64.html\r
+ * License Notice:\r
+ * Copyright (C) 2004-2008 René Nyffenegger\r
+ *\r
+ *  This source code is provided 'as-is', without any express or implied\r
+ *  warranty. In no event will the author be held liable for any damages\r
+ *  arising from the use of this software.\r
+ *\r
+ *  Permission is granted to anyone to use this software for any purpose,\r
+ *  including commercial applications, and to alter it and redistribute it\r
+ *  freely, subject to the following restrictions:\r
+ *\r
+ *  1. The origin of this source code must not be misrepresented; you must not\r
+ *     claim that you wrote the original source code. If you use this source code\r
+ *     in a product, an acknowledgment in the product documentation would be\r
+ *     appreciated but is not required.\r
+ *\r
+ *  2. Altered source versions must be plainly marked as such, and must not be\r
+ *     misrepresented as being the original source code.\r
+ *\r
+ *  3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ *  René Nyffenegger rene.nyffenegger@adp-gmbh.ch\r
+ *\r
+ * @param encoded_string\r
+ * @return\r
+ */\r
+//TODO: This function to be removed for final release\r
+string PropertyUtility::base64_decode(std::string const& encoded_string) {\r
+       int in_len = encoded_string.size();\r
+       int i = 0;\r
+       int j = 0;\r
+       int in_ = 0;\r
+       unsigned char char_array_4[4], char_array_3[3];\r
+       std::string ret;\r
+\r
+       while (in_len-- && (encoded_string[in_] != '=')\r
+           && is_base64(encoded_string[in_])) {\r
+               char_array_4[i++] = encoded_string[in_];\r
+               in_++;\r
+               if (i == 4) {\r
+                       for (i = 0; i < 4; i++)\r
+                               char_array_4[i] = (unsigned char)base64_chars.find(char_array_4[i]);\r
+                       char_array_3[0] = (char_array_4[0] << 2)\r
+                           + ((char_array_4[1] & 0x30) >> 4);\r
+                       char_array_3[1] = ((char_array_4[1] & 0xf) << 4)\r
+                           + ((char_array_4[2] & 0x3c) >> 2);\r
+                       char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];\r
+                       for (i = 0; (i < 3); i++)\r
+                               ret += char_array_3[i];\r
+                       i = 0;\r
+               }\r
+       }\r
+       if (i) {\r
+               for (j = i; j < 4; j++)\r
+                       char_array_4[j] = 0;\r
+               for (j = 0; j < 4; j++)\r
+                       char_array_4[j] = (unsigned char)base64_chars.find(char_array_4[j]);\r
+               char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);\r
+               char_array_3[1] = ((char_array_4[1] & 0xf) << 4)\r
+                   + ((char_array_4[2] & 0x3c) >> 2);\r
+               char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];\r
+               for (j = 0; (j < i - 1); j++)\r
+                       ret += char_array_3[j];\r
+       }\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * Utility function to check if a string is a positive number\r
+ * @param s Input string to be validated\r
+ * @return true if a number else false\r
+ */\r
+bool PropertyUtility::isNumber(const string& s) {\r
+       std::string::const_iterator it = s.begin();\r
+       while (it != s.end() && std::isdigit(*it))\r
+               ++it;\r
+       return (!s.empty() && it == s.end());\r
+}\r
+\r
+/**\r
+ * Converts UUID from TEE_UUID to a string\r
+ * @return string of TEE_UUID\r
+ */\r
+string PropertyUtility::getUUIDAsString(TEE_UUID uuid) {\r
+       // E.g. returns a string in the format 79B77788-9789-4a7a-A2BE-B60155EEF5F3\r
+       std::stringstream strStream;\r
+       strStream << IntToHex(uuid.timeLow) << "-";\r
+       strStream << IntToHex(uuid.timeMid) << "-";\r
+       strStream << IntToHex(uuid.timeHiAndVersion) << "-";\r
+       strStream << IntToHex((short)uuid.clockSeqAndNode[0], 2);\r
+       strStream << IntToHex((short)uuid.clockSeqAndNode[1], 2);\r
+       strStream << "-";\r
+       for (int i = 2; i < 8; i++) {\r
+               strStream << IntToHex((short)uuid.clockSeqAndNode[i], 2);\r
+       }\r
+       return strStream.str();\r
+}\r
diff --git a/TEEStub/PropertyAccess/PropertyUtility.h b/TEEStub/PropertyAccess/PropertyUtility.h
new file mode 100755 (executable)
index 0000000..a74eaca
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  PropertyUtility.h\r
+ *\r
+ *    Description:  PropertyUtility header file\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  20 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+#ifndef PROPERTYACCESS_PROPERTYUTILITY_H_\r
+#define PROPERTYACCESS_PROPERTYUTILITY_H_\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include "tee_internal_api.h"\r
+#include "log.h"\r
+#include <PropertyAccess/Property.h>\r
+#include <string>\r
+#include <sstream>\r
+#include <iomanip>\r
+\r
+using namespace std;\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Class definitions\r
+ *-----------------------------------------------------------------------------*/\r
+class PropertyUtility {\r
+private:\r
+       PropertyUtility() {\r
+       }\r
+       ;\r
+       static bool is_base64(unsigned char c);\r
+       static string base64_encode(unsigned char const*, unsigned int len);\r
+       static string base64_decode(std::string const& s);\r
+       static string getUUIDAsString(TEE_UUID uuid);\r
+       template<typename T>\r
+       static string IntToHex(T i, int width = sizeof(T) * 2) {\r
+               stringstream stream;\r
+               stream << std::setfill('0') << std::setw(width) << std::hex << i;\r
+               return stream.str();\r
+       }\r
+public:\r
+       static bool isNumber(const string &s);\r
+       static TEE_Result convertToUTF8(const PropertyValue &in, string &out);\r
+       static TEE_Result convertToBool(const PropertyValue &in, bool &out);\r
+       static TEE_Result convertToU32(const PropertyValue &in, uint32_t &out);\r
+       static TEE_Result convertToBinaryBlock(const PropertyValue &in, string &out);\r
+       static TEE_Result convertFromBinaryBlock(const string &in, string& out);\r
+       static TEE_Result convertToUUID(const PropertyValue &in, TEE_UUID &out);\r
+       static TEE_Result convertToIdentity(const PropertyValue &in,\r
+           TEE_Identity &out);\r
+       virtual ~PropertyUtility() {\r
+       }\r
+       ;\r
+};\r
+\r
+#endif /* PROPERTYACCESS_PROPERTYUTILITY_H_ */\r
diff --git a/TEEStub/PropertyAccess/TAProperty.cpp b/TEEStub/PropertyAccess/TAProperty.cpp
new file mode 100755 (executable)
index 0000000..0fcb988
--- /dev/null
@@ -0,0 +1,173 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  TAProperty.cpp\r
+ *\r
+ *    Description:  TAProperty class\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/TAProperty.h>\r
+#include <PropertyAccess/rapidxml/rapidxml.hpp>\r
+#include <PropertyAccess/PropertyUtility.h>\r
+#include <sstream>\r
+#include <fstream>\r
+#include <iostream>\r
+#include <config.h>\r
+#include <string.h>\r
+\r
+using namespace rapidxml;\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Member functions\r
+ *-----------------------------------------------------------------------------*/\r
+/**\r
+ * Constructor of TA Property\r
+ * @param filePath[in] file to read TA properties from.\r
+ */\r
+TAProperty::TAProperty(string filePath) {\r
+       currentItr = propertiesMap.begin();\r
+       this->filePath = filePath;\r
+\r
+}\r
+\r
+/**\r
+ * Read property file of TA which is nothing but the manifest in XML format.\r
+ * @return true if successfully read else false\r
+ */\r
+bool TAProperty::readPropertyFile() {\r
+       // Open file\r
+       std::ifstream xmlfile(filePath.c_str());\r
+       std::stringstream buffer;\r
+       buffer << xmlfile.rdbuf();\r
+       xmlfile.close();\r
+       std::string content(buffer.str());\r
+       // Create xml DOM\r
+       xml_document<> doc;\r
+       // Parse XML from file and populate doc\r
+       doc.parse<0>((char*)content.c_str());\r
+       try {\r
+               xml_node<> *propertiesName = doc.first_node("manifest")->first_node(\r
+                   "properties")->first_node("general");\r
+               for (xml_attribute<> *attr = propertiesName->first_attribute(); attr; attr =\r
+                   attr->next_attribute()) {\r
+                       //LOGD(TEE_STUB, "Permission vector: %s", string(childnode->first_attribute("name")->value()));\r
+                       //1. Populate the map\r
+                       PropertyValue newValue;\r
+                       string type;\r
+                       //1a. Get property value\r
+                       newValue.value = attr->value();\r
+\r
+                       //1b. Identify type\r
+                       // TODO: UUID type to be added yet\r
+                       if (PropertyUtility::isNumber(newValue.value)) {\r
+                               type = "integer";\r
+                       } else if (newValue.value == "true" || newValue.value == "false")\r
+                               type = "boolean";\r
+                       else type = "string";\r
+                       //1c. Assign type identified\r
+                       newValue.type = type;\r
+                       //2. Assign property value to map\r
+                       propertiesMap[attr->name()] = newValue;\r
+               }\r
+       }\r
+       // Catch rapid xml errors\r
+       catch (rapidxml::parse_error &e) {\r
+               LOGE(TEE_STUB, "xml exception, at TA Properties %d", e.what());\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+/**\r
+ * Get name of the property in format gpd.ta.*\r
+ * @param name[out]     Name of property\r
+ * @return  true if enumerator marker is pointing in valid range else false/\r
+ */\r
+bool TAProperty::getPropertyName(string &name) {\r
+       if (currentItr != propertiesMap.end()) {\r
+               name = "gpd.ta." + currentItr->first;\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+/**\r
+ * Advance the marker of enumerator to point to next property\r
+ * @return true if successfully advanced to next property else false\r
+ * if marker reached end of enumeration.\r
+ */\r
+bool TAProperty::getNextProperty() {\r
+       if (currentItr == propertiesMap.end()) {\r
+               return false;\r
+       } else {\r
+               ++currentItr;\r
+               if (currentItr == propertiesMap.end())\r
+                       return false;\r
+               else return true;\r
+       }\r
+}\r
+\r
+/**\r
+ * Start enumeration by reading the property file and set marker to first property\r
+ * @return true if property file successfully read else false\r
+ */\r
+bool TAProperty::start() {\r
+       bool ret = readPropertyFile();\r
+       currentItr = propertiesMap.begin();\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * Reset marker to start from first.\r
+ */\r
+void TAProperty::reset() {\r
+       currentItr = propertiesMap.begin();\r
+}\r
+\r
+/**\r
+ * Get property value pointed by marker currently.\r
+ * @param pv[out]   Property value pointed by marker\r
+ * @return  If marker is not pointing to end of enumeration then returns true\r
+ * else false\r
+ */\r
+bool TAProperty::getPropertyValue(PropertyValue &pv) {\r
+       if (currentItr != propertiesMap.end()) {\r
+               pv = currentItr->second;\r
+               return true;\r
+       } else return false;\r
+}\r
+\r
+/**\r
+ * TA property destructor\r
+ */\r
+TAProperty::~TAProperty() {\r
+}\r
+\r
+/**\r
+ * Get property value associated with given property name by searching for it\r
+ * @param propName[in]  Property name in format gpd.ta.*\r
+ * @param value[out]    Property value on successful match\r
+ * @return true if property of given name exists else false\r
+ */\r
+bool TAProperty::getPropertyByName(const string &propName,\r
+    PropertyValue &value) {\r
+       bool returnval = true;\r
+       map<string, PropertyValue>::iterator it = propertiesMap.find(propName);\r
+       if (it != propertiesMap.end()) {\r
+               value = it->second;\r
+       } else returnval = false;\r
+       return returnval;\r
+}\r
diff --git a/TEEStub/PropertyAccess/TAProperty.h b/TEEStub/PropertyAccess/TAProperty.h
new file mode 100755 (executable)
index 0000000..6adcbe6
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  TAProperty.h\r
+ *\r
+ *    Description:  TAProperty header file\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  20 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+#ifndef PROPERTYACCESS_TAPROPERTY_H_\r
+#define PROPERTYACCESS_TAPROPERTY_H_\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/Property.h>\r
+#include <map>\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Class definitions\r
+ *-----------------------------------------------------------------------------*/\r
+class TAProperty:\r
+    public Property {\r
+private:\r
+       string filePath;\r
+       map<string, PropertyValue> propertiesMap;\r
+       bool readPropertyFile();\r
+       map<string, PropertyValue>::iterator currentItr;\r
+public:\r
+       bool getPropertyName(string&);\r
+       bool getPropertyByName(const string &propName, PropertyValue &value);\r
+       bool getNextProperty();\r
+       bool getPropertyValue(PropertyValue&);\r
+       bool start();\r
+       void reset();\r
+       TAProperty(string filePath);\r
+       virtual ~TAProperty();\r
+};\r
+\r
+#endif /* PROPERTYACCESS_TAPROPERTY_H_ */\r
diff --git a/TEEStub/PropertyAccess/TEEProperty.cpp b/TEEStub/PropertyAccess/TEEProperty.cpp
new file mode 100755 (executable)
index 0000000..44b5b40
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  TEEProperty.cpp\r
+ *\r
+ *    Description:  TEEProperty class\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  21 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/TEEProperty.h>\r
+#include <sstream>\r
+#include <fstream>\r
+#include <PropertyAccess/rapidxml/rapidxml.hpp>\r
+#include <iostream>\r
+#include <config.h>\r
+\r
+using namespace rapidxml;\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Member functions\r
+ *-----------------------------------------------------------------------------*/\r
+/**\r
+ * Constructor of TEE Property Set\r
+ * @param filePath[in] file to read TEE properties from.\r
+ */\r
+TEEProperty::TEEProperty() {\r
+       currentItr = propertiesMap.begin();\r
+}\r
+\r
+/**\r
+ * Read property file of TEE and parse it to extract property values and types.\r
+ * @return true if successfully read else false\r
+ */\r
+bool TEEProperty::readPropertyFile(string filePath) {\r
+\r
+       // Open file\r
+       std::ifstream xmlfile(filePath.c_str());\r
+       if (xmlfile.fail()) return false;\r
+       std::stringstream buffer;\r
+       buffer << xmlfile.rdbuf();\r
+       xmlfile.close();\r
+       std::string content(buffer.str());\r
+       // Create xml DOM\r
+       xml_document<> doc;\r
+       // Parse XML from file and populate doc\r
+       doc.parse<0>((char*)content.c_str());\r
+       try {\r
+               xml_node<> *propertiesName = doc.first_node("teeproperties");\r
+               for (xml_node<> *childnode = propertiesName->first_node("property");\r
+                   childnode; childnode = childnode->next_sibling()) {\r
+                       //LOGD(TEE_STUB, "Permission vector: %s", string(childnode->first_attribute("name")->value()));\r
+                       // Populate the map\r
+                       PropertyValue newValue;\r
+                       newValue.type = childnode->first_attribute("type")->value();\r
+                       newValue.value = childnode->first_attribute("value")->value();\r
+                       propertiesMap[childnode->first_attribute("name")->value()] = newValue;\r
+               }\r
+       }\r
+       // Catch rapid xml errors\r
+       catch (rapidxml::parse_error &e) {\r
+               LOGE(TEE_STUB, "xml exception, at TEE Properties %s", e.what());\r
+               return false;\r
+       }\r
+       return true;\r
+}\r
+\r
+/**\r
+ * Get name of the property in format gpd.tee.*\r
+ * @param name[out]     Name of property\r
+ * @return  true if enumerator marker is pointing in valid range else false/\r
+ */\r
+bool TEEProperty::getPropertyName(string &name) {\r
+       if (currentItr != propertiesMap.end()) {\r
+               name = currentItr->first;\r
+               return true;\r
+       }\r
+       return false;\r
+}\r
+\r
+/**\r
+ * Advance the marker of enumerator to point to next property\r
+ * @return true if successfully advanced to next property else false\r
+ * if marker reached end of enumeration.\r
+ */\r
+bool TEEProperty::getNextProperty() {\r
+       if (currentItr == propertiesMap.end()) {\r
+               return false;\r
+       } else {\r
+               ++currentItr;\r
+               if (currentItr == propertiesMap.end())\r
+                       return false;\r
+               else return true;\r
+       }\r
+}\r
+\r
+/**\r
+ * Start enumeration by reading the property file and set marker to first property\r
+ * @return true if property file successfully read else false\r
+ */\r
+bool TEEProperty::start() {\r
+       bool ret = readPropertyFile(string(TEE_PROP_FILE));\r
+       currentItr = propertiesMap.begin();\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * Reset marker to start from first.\r
+ */\r
+void TEEProperty::reset() {\r
+       currentItr = propertiesMap.begin();\r
+}\r
+\r
+/**\r
+ * Get property value pointed by marker currently.\r
+ * @param pv[out]   Property value pointed by marker\r
+ * @return  If marker is not pointing to end of enumeration then returns true\r
+ * else false\r
+ */\r
+bool TEEProperty::getPropertyValue(PropertyValue &pv) {\r
+       if (currentItr != propertiesMap.end()) {\r
+               pv = currentItr->second;\r
+               return true;\r
+       } else return false;\r
+}\r
+\r
+/**\r
+ * TEE property destructor\r
+ */\r
+TEEProperty::~TEEProperty() {\r
+}\r
+\r
+/**\r
+ * Get property value associated with given property name by searching for it\r
+ * @param propName[in]  Property name in format gpd.tee.*\r
+ * @param value[out]    Property value on successful match\r
+ * @return true if property of given name exists else false\r
+ */\r
+bool TEEProperty::getPropertyByName(const string &propName,\r
+    PropertyValue &value) {\r
+       bool returnval = true;\r
+       map<string, PropertyValue>::iterator it = propertiesMap.find(propName);\r
+       if (it != propertiesMap.end()) {\r
+               value = it->second;\r
+       } else returnval = false;\r
+       return returnval;\r
+}\r
diff --git a/TEEStub/PropertyAccess/TEEProperty.h b/TEEStub/PropertyAccess/TEEProperty.h
new file mode 100755 (executable)
index 0000000..690c8c2
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * =====================================================================================\r
+ *\r
+ *       Filename:  TEEProperty.h\r
+ *\r
+ *    Description:  TEEProperty header file\r
+ *\r
+ *        Version:  1.0\r
+ *        Created:  20 May 2015 12:41:39  IST\r
+ *       Revision:  Original\r
+ *       Compiler:  gcc\r
+ *\r
+ *         Author:  Krishna (Kr), k.devale@samsung.com\r
+ *   Organization:  Samsung Electronics\r
+ *\r
+ * =====================================================================================\r
+ */\r
+\r
+#ifndef PROPERTYACCESS_TEEPROPERTY_H_\r
+#define PROPERTYACCESS_TEEPROPERTY_H_\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Include files\r
+ *-----------------------------------------------------------------------------*/\r
+#include <PropertyAccess/Property.h>\r
+#include "log.h"\r
+#include <map>\r
+\r
+/*-----------------------------------------------------------------------------\r
+ *  Class definitions\r
+ *-----------------------------------------------------------------------------*/\r
+class TEEProperty:\r
+    public Property {\r
+private:\r
+       map<string, PropertyValue> propertiesMap;\r
+       map<string, PropertyValue>::iterator currentItr;\r
+       bool readPropertyFile(string filePath);\r
+public:\r
+       bool getPropertyName(string&);\r
+       bool getPropertyByName(const string &propName, PropertyValue &value);\r
+       bool getNextProperty();\r
+       bool getPropertyValue(PropertyValue&);\r
+       bool start();\r
+       void reset();\r
+       TEEProperty();\r
+       virtual ~TEEProperty();\r
+};\r
+\r
+#endif /* PROPERTYACCESS_TEEPROPERTY_H_ */\r
diff --git a/TEEStub/PropertyAccess/rapidxml/rapidxml.hpp b/TEEStub/PropertyAccess/rapidxml/rapidxml.hpp
new file mode 100755 (executable)
index 0000000..73a2b78
--- /dev/null
@@ -0,0 +1,2396 @@
+#ifndef RAPIDXML_HPP_INCLUDED\r
+#define RAPIDXML_HPP_INCLUDED\r
+\r
+// Copyright (C) 2006, 2009 Marcin Kalicinski\r
+// Version 1.13\r
+// Revision $DateTime: 2009/05/13 01:46:17 $\r
+//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation\r
+\r
+// If standard library is disabled, user must provide implementations of required functions and typedefs\r
+#if !defined(RAPIDXML_NO_STDLIB)\r
+#include <cstdlib>      // For std::size_t\r
+#include <cassert>      // For assert\r
+#include <new>          // For placement new\r
+#endif\r
+\r
+// On MSVC, disable "conditional expression is constant" warning (level 4). \r
+// This warning is almost impossible to avoid with certain types of templated code\r
+#ifdef _MSC_VER\r
+#pragma warning(push)\r
+#pragma warning(disable:4127)   // Conditional expression is constant\r
+#endif\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// RAPIDXML_PARSE_ERROR\r
+\r
+#if defined(RAPIDXML_NO_EXCEPTIONS)\r
+\r
+#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); }\r
+\r
+namespace rapidxml\r
+{\r
+       //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, \r
+       //! this function is called to notify user about the error.\r
+       //! It must be defined by the user.\r
+       //! <br><br>\r
+       //! This function cannot return. If it does, the results are undefined.\r
+       //! <br><br>\r
+       //! A very simple definition might look like that:\r
+       //! <pre>\r
+       //! void %rapidxml::%parse_error_handler(const char *what, void *where)\r
+       //! {\r
+       //!     LOGE(TEE_STUB, "Parse error: %s", what);\r
+       //!     std::abort();\r
+       //! }\r
+       //! </pre>\r
+       //! \param what Human readable description of the error.\r
+       //! \param where Pointer to character data where error was detected.\r
+       void parse_error_handler(const char *what, void *where);\r
+}\r
+\r
+#else\r
+\r
+#include <exception>    // For std::exception\r
+\r
+#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)\r
+\r
+namespace rapidxml {\r
+\r
+//! Parse error exception. \r
+//! This exception is thrown by the parser when an error occurs. \r
+//! Use what() function to get human-readable error message. \r
+//! Use where() function to get a pointer to position within source text where error was detected.\r
+//! <br><br>\r
+//! If throwing exceptions by the parser is undesirable, \r
+//! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included.\r
+//! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception.\r
+//! This function must be defined by the user.\r
+//! <br><br>\r
+//! This class derives from <code>std::exception</code> class.\r
+class parse_error:\r
+    public std::exception {\r
+\r
+public:\r
+\r
+       //! Constructs parse error\r
+       parse_error(const char *what, void *where) :\r
+                       m_what(what), m_where(where) {\r
+       }\r
+\r
+       //! Gets human readable description of error.\r
+       //! \return Pointer to null terminated description of the error.\r
+       virtual const char *what() const throw () {\r
+               return m_what;\r
+       }\r
+\r
+       //! Gets pointer to character data where error happened.\r
+       //! Ch should be the same as char type of xml_document that produced the error.\r
+       //! \return Pointer to location within the parsed string where error occured.\r
+       template<class Ch>\r
+       Ch *where() const {\r
+               return reinterpret_cast<Ch *>(m_where);\r
+       }\r
+\r
+private:\r
+\r
+       const char *m_what;\r
+       void *m_where;\r
+\r
+};\r
+}\r
+\r
+#endif\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// Pool sizes\r
+\r
+#ifndef RAPIDXML_STATIC_POOL_SIZE\r
+// Size of static memory block of memory_pool.\r
+// Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.\r
+// No dynamic memory allocations are performed by memory_pool until static memory is exhausted.\r
+#define RAPIDXML_STATIC_POOL_SIZE (64 * 1024)\r
+#endif\r
+\r
+#ifndef RAPIDXML_DYNAMIC_POOL_SIZE\r
+// Size of dynamic memory block of memory_pool.\r
+// Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.\r
+// After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.\r
+#define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)\r
+#endif\r
+\r
+#ifndef RAPIDXML_ALIGNMENT\r
+// Memory allocation alignment.\r
+// Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.\r
+// All memory allocations for nodes, attributes and strings will be aligned to this value.\r
+// This must be a power of 2 and at least 1, otherwise memory_pool will not work.\r
+#define RAPIDXML_ALIGNMENT sizeof(void *)\r
+#endif\r
+\r
+namespace rapidxml {\r
+// Forward declarations\r
+template<class Ch> class xml_node;\r
+template<class Ch> class xml_attribute;\r
+template<class Ch> class xml_document;\r
+\r
+//! Enumeration listing all node types produced by the parser.\r
+//! Use xml_node::type() function to query node type.\r
+enum node_type {\r
+       node_document,      //!< A document node. Name and value are empty.\r
+       node_element, //!< An element node. Name contains element name. Value contains text of first data node.\r
+       node_data,        //!< A data node. Name is empty. Value contains data text.\r
+       node_cdata,      //!< A CDATA node. Name is empty. Value contains data text.\r
+       node_comment, //!< A comment node. Name is empty. Value contains comment text.\r
+       node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.\r
+       node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.\r
+       node_pi   //!< A PI node. Name contains target. Value contains instructions.\r
+};\r
+\r
+///////////////////////////////////////////////////////////////////////\r
+// Parsing flags\r
+\r
+//! Parse flag instructing the parser to not create data nodes. \r
+//! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_no_data_nodes = 0x1;\r
+\r
+//! Parse flag instructing the parser to not use text of first data node as a value of parent element.\r
+//! Can be combined with other flags by use of | operator.\r
+//! Note that child data nodes of element node take precendence over its value when printing. \r
+//! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored.\r
+//! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_no_element_values = 0x2;\r
+\r
+//! Parse flag instructing the parser to not place zero terminators after strings in the source text.\r
+//! By default zero terminators are placed, modifying source text.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_no_string_terminators = 0x4;\r
+\r
+//! Parse flag instructing the parser to not translate entities in the source text.\r
+//! By default entities are translated, modifying source text.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_no_entity_translation = 0x8;\r
+\r
+//! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters.\r
+//! By default, UTF-8 handling is enabled.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_no_utf8 = 0x10;\r
+\r
+//! Parse flag instructing the parser to create XML declaration node.\r
+//! By default, declaration node is not created.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_declaration_node = 0x20;\r
+\r
+//! Parse flag instructing the parser to create comments nodes.\r
+//! By default, comment nodes are not created.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_comment_nodes = 0x40;\r
+\r
+//! Parse flag instructing the parser to create DOCTYPE node.\r
+//! By default, doctype node is not created.\r
+//! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_doctype_node = 0x80;\r
+\r
+//! Parse flag instructing the parser to create PI nodes.\r
+//! By default, PI nodes are not created.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_pi_nodes = 0x100;\r
+\r
+//! Parse flag instructing the parser to validate closing tag names. \r
+//! If not set, name inside closing tag is irrelevant to the parser.\r
+//! By default, closing tags are not validated.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_validate_closing_tags = 0x200;\r
+\r
+//! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes.\r
+//! By default, whitespace is not trimmed. \r
+//! This flag does not cause the parser to modify source text.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_trim_whitespace = 0x400;\r
+\r
+//! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character.\r
+//! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag.\r
+//! By default, whitespace is not normalized. \r
+//! If this flag is specified, source text will be modified.\r
+//! Can be combined with other flags by use of | operator.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_normalize_whitespace = 0x800;\r
+\r
+// Compound flags\r
+\r
+//! Parse flags which represent default behaviour of the parser. \r
+//! This is always equal to 0, so that all other flags can be simply ored together.\r
+//! Normally there is no need to inconveniently disable flags by anding with their negated (~) values.\r
+//! This also means that meaning of each flag is a <i>negation</i> of the default setting. \r
+//! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default,\r
+//! and using the flag will disable it.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_default = 0;\r
+\r
+//! A combination of parse flags that forbids any modifications of the source text. \r
+//! This also results in faster parsing. However, note that the following will occur:\r
+//! <ul>\r
+//! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li>\r
+//! <li>entities will not be translated</li>\r
+//! <li>whitespace will not be normalized</li>\r
+//! </ul>\r
+//! See xml_document::parse() function.\r
+const int parse_non_destructive = parse_no_string_terminators\r
+    | parse_no_entity_translation;\r
+\r
+//! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_fastest = parse_non_destructive | parse_no_data_nodes;\r
+\r
+//! A combination of parse flags resulting in largest amount of data being extracted. \r
+//! This usually results in slowest parsing.\r
+//! <br><br>\r
+//! See xml_document::parse() function.\r
+const int parse_full = parse_declaration_node | parse_comment_nodes\r
+    | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;\r
+\r
+///////////////////////////////////////////////////////////////////////\r
+// Internals\r
+\r
+//! \cond internal\r
+namespace internal {\r
+\r
+// Struct that contains lookup tables for the parser\r
+// It must be a template to allow correct linking (because it has static data members, which are defined in a header file).\r
+template<int Dummy>\r
+struct lookup_tables {\r
+       static const unsigned char lookup_whitespace[256];       // Whitespace table\r
+       static const unsigned char lookup_node_name[256];         // Node name table\r
+       static const unsigned char lookup_text[256];                   // Text table\r
+       static const unsigned char lookup_text_pure_no_ws[256];        // Text table\r
+       static const unsigned char lookup_text_pure_with_ws[256];      // Text table\r
+       static const unsigned char lookup_attribute_name[256]; // Attribute name table\r
+       static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote\r
+       static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote\r
+       static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes\r
+       static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes\r
+       static const unsigned char lookup_digits[256];                  // Digits\r
+       static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters\r
+};\r
+\r
+// Find length of the string\r
+template<class Ch>\r
+inline std::size_t measure(const Ch *p) {\r
+       const Ch *tmp = p;\r
+       while (*tmp)\r
+               ++tmp;\r
+       return tmp - p;\r
+}\r
+\r
+// Compare strings for equality\r
+template<class Ch>\r
+inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2,\r
+    std::size_t size2, bool case_sensitive) {\r
+       if (size1 != size2) return false;\r
+       if (case_sensitive) {\r
+               for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)\r
+                       if (*p1 != *p2) return false;\r
+       } else {\r
+               for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)\r
+                       if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)]\r
+                           != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])\r
+                         return false;\r
+       }\r
+       return true;\r
+}\r
+}\r
+//! \endcond\r
+\r
+///////////////////////////////////////////////////////////////////////\r
+// Memory pool\r
+\r
+//! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation.\r
+//! In most cases, you will not need to use this class directly. \r
+//! However, if you need to create nodes manually or modify names/values of nodes, \r
+//! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. \r
+//! Not only is this faster than allocating them by using <code>new</code> operator, \r
+//! but also their lifetime will be tied to the lifetime of document, \r
+//! possibly simplyfing memory management. \r
+//! <br><br>\r
+//! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. \r
+//! You can also call allocate_string() function to allocate strings.\r
+//! Such strings can then be used as names or values of nodes without worrying about their lifetime.\r
+//! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called, \r
+//! or when the pool is destroyed.\r
+//! <br><br>\r
+//! It is also possible to create a standalone memory_pool, and use it \r
+//! to allocate nodes, whose lifetime will not be tied to any document.\r
+//! <br><br>\r
+//! Pool maintains <code>RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory. \r
+//! Until static memory is exhausted, no dynamic memory allocations are done.\r
+//! When static memory is exhausted, pool allocates additional blocks of memory of size <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> each,\r
+//! by using global <code>new[]</code> and <code>delete[]</code> operators. \r
+//! This behaviour can be changed by setting custom allocation routines. \r
+//! Use set_allocator() function to set them.\r
+//! <br><br>\r
+//! Allocations for nodes, attributes and strings are aligned at <code>RAPIDXML_ALIGNMENT</code> bytes.\r
+//! This value defaults to the size of pointer on target architecture.\r
+//! <br><br>\r
+//! To obtain absolutely top performance from the parser,\r
+//! it is important that all nodes are allocated from a single, contiguous block of memory.\r
+//! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably.\r
+//! If required, you can tweak <code>RAPIDXML_STATIC_POOL_SIZE</code>, <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>RAPIDXML_ALIGNMENT</code> \r
+//! to obtain best wasted memory to performance compromise.\r
+//! To do it, define their values before rapidxml.hpp file is included.\r
+//! \param Ch Character type of created nodes. \r
+template<class Ch = char>\r
+class memory_pool {\r
+\r
+public:\r
+\r
+       //! \cond internal\r
+       typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory\r
+       typedef void (free_func)(void *); // Type of user-defined function used to free memory\r
+       //! \endcond\r
+\r
+       //! Constructs empty pool with default allocator functions.\r
+       memory_pool() :\r
+                       m_alloc_func(0), m_free_func(0) {\r
+               init();\r
+       }\r
+\r
+       //! Destroys pool and frees all the memory. \r
+       //! This causes memory occupied by nodes allocated by the pool to be freed.\r
+       //! Nodes allocated from the pool are no longer valid.\r
+       ~memory_pool() {\r
+               clear();\r
+       }\r
+\r
+       //! Allocates a new node from the pool, and optionally assigns name and value to it. \r
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.\r
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function\r
+       //! will call rapidxml::parse_error_handler() function.\r
+       //! \param type Type of node to create.\r
+       //! \param name Name to assign to the node, or 0 to assign no name.\r
+       //! \param value Value to assign to the node, or 0 to assign no value.\r
+       //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.\r
+       //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.\r
+       //! \return Pointer to allocated node. This pointer will never be NULL.\r
+       xml_node<Ch> *allocate_node(node_type type, const Ch *name = 0,\r
+           const Ch *value = 0, std::size_t name_size = 0,\r
+           std::size_t value_size = 0) {\r
+               void *memory = allocate_aligned(sizeof(xml_node<Ch> ));\r
+               xml_node<Ch> *node = new (memory) xml_node<Ch>(type);\r
+               if (name) {\r
+                       if (name_size > 0)\r
+                               node->name(name, name_size);\r
+                       else node->name(name);\r
+               }\r
+               if (value) {\r
+                       if (value_size > 0)\r
+                               node->value(value, value_size);\r
+                       else node->value(value);\r
+               }\r
+               return node;\r
+       }\r
+\r
+       //! Allocates a new attribute from the pool, and optionally assigns name and value to it.\r
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.\r
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function\r
+       //! will call rapidxml::parse_error_handler() function.\r
+       //! \param name Name to assign to the attribute, or 0 to assign no name.\r
+       //! \param value Value to assign to the attribute, or 0 to assign no value.\r
+       //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.\r
+       //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.\r
+       //! \return Pointer to allocated attribute. This pointer will never be NULL.\r
+       xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,\r
+           std::size_t name_size = 0, std::size_t value_size = 0) {\r
+               void *memory = allocate_aligned(sizeof(xml_attribute<Ch> ));\r
+               xml_attribute<Ch> *attribute = new (memory) xml_attribute<Ch>;\r
+               if (name) {\r
+                       if (name_size > 0)\r
+                               attribute->name(name, name_size);\r
+                       else attribute->name(name);\r
+               }\r
+               if (value) {\r
+                       if (value_size > 0)\r
+                               attribute->value(value, value_size);\r
+                       else attribute->value(value);\r
+               }\r
+               return attribute;\r
+       }\r
+\r
+       //! Allocates a char array of given size from the pool, and optionally copies a given string to it.\r
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.\r
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function\r
+       //! will call rapidxml::parse_error_handler() function.\r
+       //! \param source String to initialize the allocated memory with, or 0 to not initialize it.\r
+       //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.\r
+       //! \return Pointer to allocated char array. This pointer will never be NULL.\r
+       Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) {\r
+               assert(source || size); // Either source or size (or both) must be specified\r
+               if (size == 0) size = internal::measure(source) + 1;\r
+               Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));\r
+               if (source) for (std::size_t i = 0; i < size; ++i)\r
+                       result[i] = source[i];\r
+               return result;\r
+       }\r
+\r
+       //! Clones an xml_node and its hierarchy of child nodes and attributes.\r
+       //! Nodes and attributes are allocated from this memory pool.\r
+       //! Names and values are not cloned, they are shared between the clone and the source.\r
+       //! Result node can be optionally specified as a second parameter, \r
+       //! in which case its contents will be replaced with cloned source node.\r
+       //! This is useful when you want to clone entire document.\r
+       //! \param source Node to clone.\r
+       //! \param result Node to put results in, or 0 to automatically allocate result node\r
+       //! \return Pointer to cloned node. This pointer will never be NULL.\r
+       xml_node<Ch> *clone_node(const xml_node<Ch> *source,\r
+           xml_node<Ch> *result = 0) {\r
+               // Prepare result node\r
+               if (result) {\r
+                       result->remove_all_attributes();\r
+                       result->remove_all_nodes();\r
+                       result->type(source->type());\r
+               } else result = allocate_node(source->type());\r
+\r
+               // Clone name and value\r
+               result->name(source->name(), source->name_size());\r
+               result->value(source->value(), source->value_size());\r
+\r
+               // Clone child nodes and attributes\r
+               for (xml_node<Ch> *child = source->first_node(); child;\r
+                   child = child->next_sibling())\r
+                       result->append_node(clone_node(child));\r
+               for (xml_attribute<Ch> *attr = source->first_attribute(); attr;\r
+                   attr = attr->next_attribute())\r
+                       result->append_attribute(\r
+                           allocate_attribute(attr->name(), attr->value(), attr->name_size(),\r
+                               attr->value_size()));\r
+\r
+               return result;\r
+       }\r
+\r
+       //! Clears the pool. \r
+       //! This causes memory occupied by nodes allocated by the pool to be freed.\r
+       //! Any nodes or strings allocated from the pool will no longer be valid.\r
+       void clear() {\r
+               while (m_begin != m_static_memory) {\r
+                       char *previous_begin = reinterpret_cast<header *>(align(m_begin))\r
+                           ->previous_begin;\r
+                       if (m_free_func)\r
+                               m_free_func(m_begin);\r
+                       else delete[] m_begin;\r
+                       m_begin = previous_begin;\r
+               }\r
+               init();\r
+       }\r
+\r
+       //! Sets or resets the user-defined memory allocation functions for the pool.\r
+       //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined.\r
+       //! Allocation function must not return invalid pointer on failure. It should either throw,\r
+       //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program. \r
+       //! If it returns invalid pointer, results are undefined.\r
+       //! <br><br>\r
+       //! User defined allocation functions must have the following forms:\r
+       //! <br><code>\r
+       //! <br>void *allocate(std::size_t size);\r
+       //! <br>void free(void *pointer);\r
+       //! </code><br>\r
+       //! \param af Allocation function, or 0 to restore default function\r
+       //! \param ff Free function, or 0 to restore default function\r
+       void set_allocator(alloc_func *af, free_func *ff) {\r
+               assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet\r
+               m_alloc_func = af;\r
+               m_free_func = ff;\r
+       }\r
+\r
+private:\r
+\r
+       struct header {\r
+               char *previous_begin;\r
+       };\r
+\r
+       void init() {\r
+               m_begin = m_static_memory;\r
+               m_ptr = align(m_begin);\r
+               m_end = m_static_memory + sizeof(m_static_memory);\r
+       }\r
+\r
+       char *align(char *ptr) {\r
+               std::size_t alignment = ((RAPIDXML_ALIGNMENT\r
+                   - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1)))\r
+                   & (RAPIDXML_ALIGNMENT - 1));\r
+               return ptr + alignment;\r
+       }\r
+\r
+       char *allocate_raw(std::size_t size) {\r
+               // Allocate\r
+               void *memory;\r
+               if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[]\r
+               {\r
+                       memory = m_alloc_func(size);\r
+                       assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp\r
+               } else {\r
+                       memory = new char[size];\r
+#ifdef RAPIDXML_NO_EXCEPTIONS\r
+                       if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc\r
+                       RAPIDXML_PARSE_ERROR("out of memory", 0);\r
+#endif\r
+               }\r
+               return static_cast<char *>(memory);\r
+       }\r
+\r
+       void *allocate_aligned(std::size_t size) {\r
+               // Calculate aligned pointer\r
+               char *result = align(m_ptr);\r
+\r
+               // If not enough memory left in current pool, allocate a new pool\r
+               if (result + size > m_end) {\r
+                       // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE)\r
+                       std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;\r
+                       if (pool_size < size) pool_size = size;\r
+\r
+                       // Allocate\r
+                       std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2)\r
+                           + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation\r
+                       char *raw_memory = allocate_raw(alloc_size);\r
+\r
+                       // Setup new pool in allocated memory\r
+                       char *pool = align(raw_memory);\r
+                       header *new_header = reinterpret_cast<header *>(pool);\r
+                       new_header->previous_begin = m_begin;\r
+                       m_begin = raw_memory;\r
+                       m_ptr = pool + sizeof(header);\r
+                       m_end = raw_memory + alloc_size;\r
+\r
+                       // Calculate aligned pointer again using new pool\r
+                       result = align(m_ptr);\r
+               }\r
+\r
+               // Update pool and return aligned pointer\r
+               m_ptr = result + size;\r
+               return result;\r
+       }\r
+\r
+       char *m_begin;                 // Start of raw memory making up current pool\r
+       char *m_ptr;                              // First free byte in current pool\r
+       char *m_end;                 // One past last available byte in current pool\r
+       char m_static_memory[RAPIDXML_STATIC_POOL_SIZE];    // Static raw memory\r
+       alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used\r
+       free_func *m_free_func;      // Free function, or 0 if default is to be used\r
+};\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// XML base\r
+\r
+//! Base class for xml_node and xml_attribute implementing common functions: \r
+//! name(), name_size(), value(), value_size() and parent().\r
+//! \param Ch Character type to use\r
+template<class Ch = char>\r
+class xml_base {\r
+\r
+public:\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Construction & destruction\r
+\r
+       // Construct a base with empty name, value and parent\r
+       xml_base() :\r
+                       m_name(0), m_value(0), m_parent(0) {\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Node data access\r
+\r
+       //! Gets name of the node. \r
+       //! Interpretation of name depends on type of node.\r
+       //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.\r
+       //! <br><br>\r
+       //! Use name_size() function to determine length of the name.\r
+       //! \return Name of node, or empty string if node has no name.\r
+       Ch *name() const {\r
+               return m_name ? m_name : nullstr();\r
+       }\r
+\r
+       //! Gets size of node name, not including terminator character.\r
+       //! This function works correctly irrespective of whether name is or is not zero terminated.\r
+       //! \return Size of node name, in characters.\r
+       std::size_t name_size() const {\r
+               return m_name ? m_name_size : 0;\r
+       }\r
+\r
+       //! Gets value of node. \r
+       //! Interpretation of value depends on type of node.\r
+       //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.\r
+       //! <br><br>\r
+       //! Use value_size() function to determine length of the value.\r
+       //! \return Value of node, or empty string if node has no value.\r
+       Ch *value() const {\r
+               return m_value ? m_value : nullstr();\r
+       }\r
+\r
+       //! Gets size of node value, not including terminator character.\r
+       //! This function works correctly irrespective of whether value is or is not zero terminated.\r
+       //! \return Size of node value, in characters.\r
+       std::size_t value_size() const {\r
+               return m_value ? m_value_size : 0;\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Node modification\r
+\r
+       //! Sets name of node to a non zero-terminated string.\r
+       //! See \ref ownership_of_strings.\r
+       //! <br><br>\r
+       //! Note that node does not own its name or value, it only stores a pointer to it. \r
+       //! It will not delete or otherwise free the pointer on destruction.\r
+       //! It is reponsibility of the user to properly manage lifetime of the string.\r
+       //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -\r
+       //! on destruction of the document the string will be automatically freed.\r
+       //! <br><br>\r
+       //! Size of name must be specified separately, because name does not have to be zero terminated.\r
+       //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).\r
+       //! \param name Name of node to set. Does not have to be zero terminated.\r
+       //! \param size Size of name, in characters. This does not include zero terminator, if one is present.\r
+       void name(const Ch *name, std::size_t size) {\r
+               m_name = const_cast<Ch *>(name);\r
+               m_name_size = size;\r
+       }\r
+\r
+       //! Sets name of node to a zero-terminated string.\r
+       //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t).\r
+       //! \param name Name of node to set. Must be zero terminated.\r
+       void name(const Ch *name) {\r
+               this->name(name, internal::measure(name));\r
+       }\r
+\r
+       //! Sets value of node to a non zero-terminated string.\r
+       //! See \ref ownership_of_strings.\r
+       //! <br><br>\r
+       //! Note that node does not own its name or value, it only stores a pointer to it. \r
+       //! It will not delete or otherwise free the pointer on destruction.\r
+       //! It is reponsibility of the user to properly manage lifetime of the string.\r
+       //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -\r
+       //! on destruction of the document the string will be automatically freed.\r
+       //! <br><br>\r
+       //! Size of value must be specified separately, because it does not have to be zero terminated.\r
+       //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).\r
+       //! <br><br>\r
+       //! If an element has a child node of type node_data, it will take precedence over element value when printing.\r
+       //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.\r
+       //! \param value value of node to set. Does not have to be zero terminated.\r
+       //! \param size Size of value, in characters. This does not include zero terminator, if one is present.\r
+       void value(const Ch *value, std::size_t size) {\r
+               m_value = const_cast<Ch *>(value);\r
+               m_value_size = size;\r
+       }\r
+\r
+       //! Sets value of node to a zero-terminated string.\r
+       //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t).\r
+       //! \param value Vame of node to set. Must be zero terminated.\r
+       void value(const Ch *value) {\r
+               this->value(value, internal::measure(value));\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Related nodes access\r
+\r
+       //! Gets node parent.\r
+       //! \return Pointer to parent node, or 0 if there is no parent.\r
+       xml_node<Ch> *parent() const {\r
+               return m_parent;\r
+       }\r
+\r
+protected:\r
+\r
+       // Return empty string\r
+       static Ch *nullstr() {\r
+               static Ch zero = Ch('\0');\r
+               return &zero;\r
+       }\r
+\r
+       Ch *m_name;                         // Name of node, or 0 if no name\r
+       Ch *m_value;                        // Value of node, or 0 if no value\r
+       std::size_t m_name_size;     // Length of node name, or undefined of no name\r
+       std::size_t m_value_size;  // Length of node value, or undefined if no value\r
+       xml_node<Ch> *m_parent;             // Pointer to parent node, or 0 if none\r
+\r
+};\r
+\r
+//! Class representing attribute node of XML document. \r
+//! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base).\r
+//! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. \r
+//! Thus, this text must persist in memory for the lifetime of attribute.\r
+//! \param Ch Character type to use.\r
+template<class Ch = char>\r
+class xml_attribute:\r
+    public xml_base<Ch> {\r
+\r
+       friend class xml_node<Ch> ;\r
+\r
+public:\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Construction & destruction\r
+\r
+       //! Constructs an empty attribute with the specified type. \r
+       //! Consider using memory_pool of appropriate xml_document if allocating attributes manually.\r
+       xml_attribute() {\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Related nodes access\r
+\r
+       //! Gets document of which attribute is a child.\r
+       //! \return Pointer to document that contains this attribute, or 0 if there is no parent document.\r
+       xml_document<Ch> *document() const {\r
+               if (xml_node<Ch> *node = this->parent()) {\r
+                       while (node->parent())\r
+                               node = node->parent();\r
+                       return\r
+                           node->type() == node_document ?\r
+                               static_cast<xml_document<Ch> *>(node) : 0;\r
+               } else return 0;\r
+       }\r
+\r
+       //! Gets previous attribute, optionally matching attribute name. \r
+       //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found attribute, or 0 if not found.\r
+       xml_attribute<Ch> *previous_attribute(const Ch *name = 0,\r
+           std::size_t name_size = 0, bool case_sensitive = true) const {\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute;\r
+                           attribute = attribute->m_prev_attribute)\r
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,\r
+                                   name_size, case_sensitive)) return attribute;\r
+                       return 0;\r
+               } else return this->m_parent ? m_prev_attribute : 0;\r
+       }\r
+\r
+       //! Gets next attribute, optionally matching attribute name. \r
+       //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found attribute, or 0 if not found.\r
+       xml_attribute<Ch> *next_attribute(const Ch *name = 0, std::size_t name_size =\r
+           0, bool case_sensitive = true) const {\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_attribute<Ch> *attribute = m_next_attribute; attribute;\r
+                           attribute = attribute->m_next_attribute)\r
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,\r
+                                   name_size, case_sensitive)) return attribute;\r
+                       return 0;\r
+               } else return this->m_parent ? m_next_attribute : 0;\r
+       }\r
+\r
+private:\r
+\r
+       xml_attribute<Ch> *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero\r
+       xml_attribute<Ch> *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero\r
+\r
+};\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// XML node\r
+\r
+//! Class representing a node of XML document. \r
+//! Each node may have associated name and value strings, which are available through name() and value() functions. \r
+//! Interpretation of name and value depends on type of the node.\r
+//! Type of node can be determined by using type() function.\r
+//! <br><br>\r
+//! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. \r
+//! Thus, this text must persist in the memory for the lifetime of node.\r
+//! \param Ch Character type to use.\r
+template<class Ch = char>\r
+class xml_node:\r
+    public xml_base<Ch> {\r
+\r
+public:\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Construction & destruction\r
+\r
+       //! Constructs an empty node with the specified type. \r
+       //! Consider using memory_pool of appropriate document to allocate nodes manually.\r
+       //! \param type Type of node to construct.\r
+       xml_node(node_type type) :\r
+                       m_type(type), m_first_node(0), m_first_attribute(0) {\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Node data access\r
+\r
+       //! Gets type of node.\r
+       //! \return Type of node.\r
+       node_type type() const {\r
+               return m_type;\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Related nodes access\r
+\r
+       //! Gets document of which node is a child.\r
+       //! \return Pointer to document that contains this node, or 0 if there is no parent document.\r
+       xml_document<Ch> *document() const {\r
+               xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);\r
+               while (node->parent())\r
+                       node = node->parent();\r
+               return\r
+                   node->type() == node_document ? static_cast<xml_document<Ch> *>(node) :\r
+                                                   0;\r
+       }\r
+\r
+       //! Gets first child node, optionally matching node name.\r
+       //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found child, or 0 if not found.\r
+       xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0,\r
+           bool case_sensitive = true) const {\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_node<Ch> *child = m_first_node; child;\r
+                           child = child->next_sibling())\r
+                               if (internal::compare(child->name(), child->name_size(), name,\r
+                                   name_size, case_sensitive)) return child;\r
+                       return 0;\r
+               } else return m_first_node;\r
+       }\r
+\r
+       //! Gets last child node, optionally matching node name. \r
+       //! Behaviour is undefined if node has no children.\r
+       //! Use first_node() to test if node has children.\r
+       //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found child, or 0 if not found.\r
+       xml_node<Ch> *last_node(const Ch *name = 0, std::size_t name_size = 0,\r
+           bool case_sensitive = true) const {\r
+               assert(m_first_node); // Cannot query for last child if node has no children\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_node<Ch> *child = m_last_node; child;\r
+                           child = child->previous_sibling())\r
+                               if (internal::compare(child->name(), child->name_size(), name,\r
+                                   name_size, case_sensitive)) return child;\r
+                       return 0;\r
+               } else return m_last_node;\r
+       }\r
+\r
+       //! Gets previous sibling node, optionally matching node name. \r
+       //! Behaviour is undefined if node has no parent.\r
+       //! Use parent() to test if node has a parent.\r
+       //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found sibling, or 0 if not found.\r
+       xml_node<Ch> *previous_sibling(const Ch *name = 0, std::size_t name_size = 0,\r
+           bool case_sensitive = true) const {\r
+               assert(this->m_parent); // Cannot query for siblings if node has no parent\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_node<Ch> *sibling = m_prev_sibling; sibling;\r
+                           sibling = sibling->m_prev_sibling)\r
+                               if (internal::compare(sibling->name(), sibling->name_size(), name,\r
+                                   name_size, case_sensitive)) return sibling;\r
+                       return 0;\r
+               } else return m_prev_sibling;\r
+       }\r
+\r
+       //! Gets next sibling node, optionally matching node name. \r
+       //! Behaviour is undefined if node has no parent.\r
+       //! Use parent() to test if node has a parent.\r
+       //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found sibling, or 0 if not found.\r
+       xml_node<Ch> *next_sibling(const Ch *name = 0, std::size_t name_size = 0,\r
+           bool case_sensitive = true) const {\r
+               assert(this->m_parent); // Cannot query for siblings if node has no parent\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_node<Ch> *sibling = m_next_sibling; sibling;\r
+                           sibling = sibling->m_next_sibling)\r
+                               if (internal::compare(sibling->name(), sibling->name_size(), name,\r
+                                   name_size, case_sensitive)) return sibling;\r
+                       return 0;\r
+               } else return m_next_sibling;\r
+       }\r
+\r
+       //! Gets first attribute of node, optionally matching attribute name.\r
+       //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found attribute, or 0 if not found.\r
+       xml_attribute<Ch> *first_attribute(const Ch *name = 0, std::size_t name_size =\r
+           0, bool case_sensitive = true) const {\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_attribute<Ch> *attribute = m_first_attribute; attribute;\r
+                           attribute = attribute->m_next_attribute)\r
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,\r
+                                   name_size, case_sensitive)) return attribute;\r
+                       return 0;\r
+               } else return m_first_attribute;\r
+       }\r
+\r
+       //! Gets last attribute of node, optionally matching attribute name.\r
+       //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero\r
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string\r
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters\r
+       //! \return Pointer to found attribute, or 0 if not found.\r
+       xml_attribute<Ch> *last_attribute(const Ch *name = 0, std::size_t name_size =\r
+           0, bool case_sensitive = true) const {\r
+               if (name) {\r
+                       if (name_size == 0) name_size = internal::measure(name);\r
+                       for (xml_attribute<Ch> *attribute = m_last_attribute; attribute;\r
+                           attribute = attribute->m_prev_attribute)\r
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,\r
+                                   name_size, case_sensitive)) return attribute;\r
+                       return 0;\r
+               } else return m_first_attribute ? m_last_attribute : 0;\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Node modification\r
+\r
+       //! Sets type of node.\r
+       //! \param type Type of node to set.\r
+       void type(node_type type) {\r
+               m_type = type;\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Node manipulation\r
+\r
+       //! Prepends a new child node.\r
+       //! The prepended child becomes the first child, and all existing children are moved one position back.\r
+       //! \param child Node to prepend.\r
+       void prepend_node(xml_node<Ch> *child) {\r
+               assert(child && !child->parent() && child->type() != node_document);\r
+               if (first_node()) {\r
+                       child->m_next_sibling = m_first_node;\r
+                       m_first_node->m_prev_sibling = child;\r
+               } else {\r
+                       child->m_next_sibling = 0;\r
+                       m_last_node = child;\r
+               }\r
+               m_first_node = child;\r
+               child->m_parent = this;\r
+               child->m_prev_sibling = 0;\r
+       }\r
+\r
+       //! Appends a new child node. \r
+       //! The appended child becomes the last child.\r
+       //! \param child Node to append.\r
+       void append_node(xml_node<Ch> *child) {\r
+               assert(child && !child->parent() && child->type() != node_document);\r
+               if (first_node()) {\r
+                       child->m_prev_sibling = m_last_node;\r
+                       m_last_node->m_next_sibling = child;\r
+               } else {\r
+                       child->m_prev_sibling = 0;\r
+                       m_first_node = child;\r
+               }\r
+               m_last_node = child;\r
+               child->m_parent = this;\r
+               child->m_next_sibling = 0;\r
+       }\r
+\r
+       //! Inserts a new child node at specified place inside the node. \r
+       //! All children after and including the specified node are moved one position back.\r
+       //! \param where Place where to insert the child, or 0 to insert at the back.\r
+       //! \param child Node to insert.\r
+       void insert_node(xml_node<Ch> *where, xml_node<Ch> *child) {\r
+               assert(!where || where->parent() == this);\r
+               assert(child && !child->parent() && child->type() != node_document);\r
+               if (where == m_first_node)\r
+                       prepend_node(child);\r
+               else if (where == 0)\r
+                       append_node(child);\r
+               else {\r
+                       child->m_prev_sibling = where->m_prev_sibling;\r
+                       child->m_next_sibling = where;\r
+                       where->m_prev_sibling->m_next_sibling = child;\r
+                       where->m_prev_sibling = child;\r
+                       child->m_parent = this;\r
+               }\r
+       }\r
+\r
+       //! Removes first child node. \r
+       //! If node has no children, behaviour is undefined.\r
+       //! Use first_node() to test if node has children.\r
+       void remove_first_node() {\r
+               assert(first_node());\r
+               xml_node<Ch> *child = m_first_node;\r
+               m_first_node = child->m_next_sibling;\r
+               if (child->m_next_sibling)\r
+                       child->m_next_sibling->m_prev_sibling = 0;\r
+               else m_last_node = 0;\r
+               child->m_parent = 0;\r
+       }\r
+\r
+       //! Removes last child of the node. \r
+       //! If node has no children, behaviour is undefined.\r
+       //! Use first_node() to test if node has children.\r
+       void remove_last_node() {\r
+               assert(first_node());\r
+               xml_node<Ch> *child = m_last_node;\r
+               if (child->m_prev_sibling) {\r
+                       m_last_node = child->m_prev_sibling;\r
+                       child->m_prev_sibling->m_next_sibling = 0;\r
+               } else m_first_node = 0;\r
+               child->m_parent = 0;\r
+       }\r
+\r
+       //! Removes specified child from the node\r
+       // \param where Pointer to child to be removed.\r
+       void remove_node(xml_node<Ch> *where) {\r
+               assert(where && where->parent() == this);\r
+               assert(first_node());\r
+               if (where == m_first_node)\r
+                       remove_first_node();\r
+               else if (where == m_last_node)\r
+                       remove_last_node();\r
+               else {\r
+                       where->m_prev_sibling->m_next_sibling = where->m_next_sibling;\r
+                       where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;\r
+                       where->m_parent = 0;\r
+               }\r
+       }\r
+\r
+       //! Removes all child nodes (but not attributes).\r
+       void remove_all_nodes() {\r
+               for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)\r
+                       node->m_parent = 0;\r
+               m_first_node = 0;\r
+       }\r
+\r
+       //! Prepends a new attribute to the node.\r
+       //! \param attribute Attribute to prepend.\r
+       void prepend_attribute(xml_attribute<Ch> *attribute) {\r
+               assert(attribute && !attribute->parent());\r
+               if (first_attribute()) {\r
+                       attribute->m_next_attribute = m_first_attribute;\r
+                       m_first_attribute->m_prev_attribute = attribute;\r
+               } else {\r
+                       attribute->m_next_attribute = 0;\r
+                       m_last_attribute = attribute;\r
+               }\r
+               m_first_attribute = attribute;\r
+               attribute->m_parent = this;\r
+               attribute->m_prev_attribute = 0;\r
+       }\r
+\r
+       //! Appends a new attribute to the node.\r
+       //! \param attribute Attribute to append.\r
+       void append_attribute(xml_attribute<Ch> *attribute) {\r
+               assert(attribute && !attribute->parent());\r
+               if (first_attribute()) {\r
+                       attribute->m_prev_attribute = m_last_attribute;\r
+                       m_last_attribute->m_next_attribute = attribute;\r
+               } else {\r
+                       attribute->m_prev_attribute = 0;\r
+                       m_first_attribute = attribute;\r
+               }\r
+               m_last_attribute = attribute;\r
+               attribute->m_parent = this;\r
+               attribute->m_next_attribute = 0;\r
+       }\r
+\r
+       //! Inserts a new attribute at specified place inside the node. \r
+       //! All attributes after and including the specified attribute are moved one position back.\r
+       //! \param where Place where to insert the attribute, or 0 to insert at the back.\r
+       //! \param attribute Attribute to insert.\r
+       void insert_attribute(xml_attribute<Ch> *where,\r
+           xml_attribute<Ch> *attribute) {\r
+               assert(!where || where->parent() == this);\r
+               assert(attribute && !attribute->parent());\r
+               if (where == m_first_attribute)\r
+                       prepend_attribute(attribute);\r
+               else if (where == 0)\r
+                       append_attribute(attribute);\r
+               else {\r
+                       attribute->m_prev_attribute = where->m_prev_attribute;\r
+                       attribute->m_next_attribute = where;\r
+                       where->m_prev_attribute->m_next_attribute = attribute;\r
+                       where->m_prev_attribute = attribute;\r
+                       attribute->m_parent = this;\r
+               }\r
+       }\r
+\r
+       //! Removes first attribute of the node. \r
+       //! If node has no attributes, behaviour is undefined.\r
+       //! Use first_attribute() to test if node has attributes.\r
+       void remove_first_attribute() {\r
+               assert(first_attribute());\r
+               xml_attribute<Ch> *attribute = m_first_attribute;\r
+               if (attribute->m_next_attribute) {\r
+                       attribute->m_next_attribute->m_prev_attribute = 0;\r
+               } else m_last_attribute = 0;\r
+               attribute->m_parent = 0;\r
+               m_first_attribute = attribute->m_next_attribute;\r
+       }\r
+\r
+       //! Removes last attribute of the node. \r
+       //! If node has no attributes, behaviour is undefined.\r
+       //! Use first_attribute() to test if node has attributes.\r
+       void remove_last_attribute() {\r
+               assert(first_attribute());\r
+               xml_attribute<Ch> *attribute = m_last_attribute;\r
+               if (attribute->m_prev_attribute) {\r
+                       attribute->m_prev_attribute->m_next_attribute = 0;\r
+                       m_last_attribute = attribute->m_prev_attribute;\r
+               } else m_first_attribute = 0;\r
+               attribute->m_parent = 0;\r
+       }\r
+\r
+       //! Removes specified attribute from node.\r
+       //! \param where Pointer to attribute to be removed.\r
+       void remove_attribute(xml_attribute<Ch> *where) {\r
+               assert(first_attribute() && where->parent() == this);\r
+               if (where == m_first_attribute)\r
+                       remove_first_attribute();\r
+               else if (where == m_last_attribute)\r
+                       remove_last_attribute();\r
+               else {\r
+                       where->m_prev_attribute->m_next_attribute = where->m_next_attribute;\r
+                       where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;\r
+                       where->m_parent = 0;\r
+               }\r
+       }\r
+\r
+       //! Removes all attributes of node.\r
+       void remove_all_attributes() {\r
+               for (xml_attribute<Ch> *attribute = first_attribute(); attribute;\r
+                   attribute = attribute->m_next_attribute)\r
+                       attribute->m_parent = 0;\r
+               m_first_attribute = 0;\r
+       }\r
+\r
+private:\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Restrictions\r
+\r
+       // No copying\r
+       xml_node(const xml_node &);\r
+       void operator =(const xml_node &);\r
+\r
+       ///////////////////////////////////////////////////////////////////////////\r
+       // Data members\r
+\r
+       // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.\r
+       // This is required for maximum performance, as it allows the parser to omit initialization of \r
+       // unneded/redundant values.\r
+       //\r
+       // The rules are as follows:\r
+       // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively\r
+       // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage\r
+       // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage\r
+\r
+       node_type m_type;                       // Type of node; always valid\r
+       xml_node<Ch> *m_first_node; // Pointer to first child node, or 0 if none; always valid\r
+       xml_node<Ch> *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero\r
+       xml_attribute<Ch> *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid\r
+       xml_attribute<Ch> *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero\r
+       xml_node<Ch> *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero\r
+       xml_node<Ch> *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero\r
+\r
+};\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// XML document\r
+\r
+//! This class represents root of the DOM hierarchy. \r
+//! It is also an xml_node and a memory_pool through public inheritance.\r
+//! Use parse() function to build a DOM tree from a zero-terminated XML text string.\r
+//! parse() function allocates memory for nodes and attributes by using functions of xml_document, \r
+//! which are inherited from memory_pool.\r
+//! To access root node of the document, use the document itself, as if it was an xml_node.\r
+//! \param Ch Character type to use.\r
+template<class Ch = char>\r
+class xml_document:\r
+    public xml_node<Ch>, public memory_pool<Ch> {\r
+\r
+public:\r
+\r
+       //! Constructs empty XML document\r
+       xml_document() :\r
+                       xml_node<Ch>(node_document) {\r
+       }\r
+\r
+       //! Parses zero-terminated XML string according to given flags.\r
+       //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.\r
+       //! The string must persist for the lifetime of the document.\r
+       //! In case of error, rapidxml::parse_error exception will be thrown.\r
+       //! <br><br>\r
+       //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning.\r
+       //! Make sure that data is zero-terminated.\r
+       //! <br><br>\r
+       //! Document can be parsed into multiple times. \r
+       //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.\r
+       //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.\r
+       template<int Flags>\r
+       void parse(Ch *text) {\r
+               assert(text);\r
+\r
+               // Remove current contents\r
+               this->remove_all_nodes();\r
+               this->remove_all_attributes();\r
+\r
+               // Parse BOM, if any\r
+               parse_bom<Flags>(text);\r
+\r
+               // Parse children\r
+               while (1) {\r
+                       // Skip whitespace before node\r
+                       skip<whitespace_pred, Flags>(text);\r
+                       if (*text == 0) break;\r
+\r
+                       // Parse and append new child\r
+                       if (*text == Ch('<')) {\r
+                               ++text;     // Skip '<'\r
+                               if (xml_node<Ch> *node = parse_node<Flags>(text))\r
+                                 this->append_node(node);\r
+                       } else\r
+                       RAPIDXML_PARSE_ERROR("expected <", text);\r
+               }\r
+\r
+       }\r
+\r
+       //! Clears the document by deleting all nodes and clearing the memory pool.\r
+       //! All nodes owned by document pool are destroyed.\r
+       void clear() {\r
+               this->remove_all_nodes();\r
+               this->remove_all_attributes();\r
+               memory_pool<Ch>::clear();\r
+       }\r
+\r
+private:\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       // Internal character utility functions\r
+\r
+       // Detect whitespace character\r
+       struct whitespace_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];\r
+               }\r
+       };\r
+\r
+       // Detect node name character\r
+       struct node_name_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];\r
+               }\r
+       };\r
+\r
+       // Detect attribute name character\r
+       struct attribute_name_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];\r
+               }\r
+       };\r
+\r
+       // Detect text character (PCDATA)\r
+       struct text_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];\r
+               }\r
+       };\r
+\r
+       // Detect text character (PCDATA) that does not require processing\r
+       struct text_pure_no_ws_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];\r
+               }\r
+       };\r
+\r
+       // Detect text character (PCDATA) that does not require processing\r
+       struct text_pure_with_ws_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];\r
+               }\r
+       };\r
+\r
+       // Detect attribute value character\r
+       template<Ch Quote>\r
+       struct attribute_value_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       if (Quote == Ch('\''))\r
+                         return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];\r
+                       if (Quote == Ch('\"'))\r
+                         return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];\r
+                       return 0;   // Should never be executed, to avoid warnings on Comeau\r
+               }\r
+       };\r
+\r
+       // Detect attribute value character\r
+       template<Ch Quote>\r
+       struct attribute_value_pure_pred {\r
+               static unsigned char test(Ch ch) {\r
+                       if (Quote == Ch('\''))\r
+                         return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];\r
+                       if (Quote == Ch('\"'))\r
+                         return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];\r
+                       return 0;   // Should never be executed, to avoid warnings on Comeau\r
+               }\r
+       };\r
+\r
+       // Insert coded character, using UTF8 or 8-bit ASCII\r
+       template<int Flags>\r
+       static void insert_coded_character(Ch *&text, unsigned long code) {\r
+               if (Flags & parse_no_utf8) {\r
+                       // Insert 8-bit ASCII character\r
+                       // Todo: possibly verify that code is less than 256 and use replacement char otherwise?\r
+                       text[0] = static_cast<unsigned char>(code);\r
+                       text += 1;\r
+               } else {\r
+                       // Insert UTF8 sequence\r
+                       if (code < 0x80)    // 1 byte sequence\r
+                           {\r
+                               text[0] = static_cast<unsigned char>(code);\r
+                               text += 1;\r
+                       } else if (code < 0x800)  // 2 byte sequence\r
+                           {\r
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);\r
+                               code >>= 6;\r
+                               text[0] = static_cast<unsigned char>(code | 0xC0);\r
+                               text += 2;\r
+                       } else if (code < 0x10000)    // 3 byte sequence\r
+                           {\r
+                               text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);\r
+                               code >>= 6;\r
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);\r
+                               code >>= 6;\r
+                               text[0] = static_cast<unsigned char>(code | 0xE0);\r
+                               text += 3;\r
+                       } else if (code < 0x110000)   // 4 byte sequence\r
+                           {\r
+                               text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF);\r
+                               code >>= 6;\r
+                               text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);\r
+                               code >>= 6;\r
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);\r
+                               code >>= 6;\r
+                               text[0] = static_cast<unsigned char>(code | 0xF0);\r
+                               text += 4;\r
+                       } else  // Invalid, only codes up to 0x10FFFF are allowed in Unicode\r
+                       {\r
+                               RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Skip characters until predicate evaluates to true\r
+       template<class StopPred, int Flags>\r
+       static void skip(Ch *&text) {\r
+               Ch *tmp = text;\r
+               while (StopPred::test(*tmp))\r
+                       ++tmp;\r
+               text = tmp;\r
+       }\r
+\r
+       // Skip characters until predicate evaluates to true while doing the following:\r
+       // - replacing XML character entity references with proper characters (&apos; &amp; &quot; &lt; &gt; &#...;)\r
+       // - condensing whitespace sequences to single space character\r
+       template<class StopPred, class StopPredPure, int Flags>\r
+       static Ch *skip_and_expand_character_refs(Ch *&text) {\r
+               // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip\r
+               if (Flags & parse_no_entity_translation\r
+                   && !(Flags & parse_normalize_whitespace)\r
+                   && !(Flags & parse_trim_whitespace)) {\r
+                       skip<StopPred, Flags>(text);\r
+                       return text;\r
+               }\r
+\r
+               // Use simple skip until first modification is detected\r
+               skip<StopPredPure, Flags>(text);\r
+\r
+               // Use translation skip\r
+               Ch *src = text;\r
+               Ch *dest = src;\r
+               while (StopPred::test(*src)) {\r
+                       // If entity translation is enabled    \r
+                       if (!(Flags & parse_no_entity_translation)) {\r
+                               // Test if replacement is needed\r
+                               if (src[0] == Ch('&')) {\r
+                                       switch (src[1]) {\r
+\r
+                                               // &amp; &apos;\r
+                                               case Ch('a'):\r
+                                                       if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) {\r
+                                                               *dest = Ch('&');\r
+                                                               ++dest;\r
+                                                               src += 5;\r
+                                                               continue;\r
+                                                       }\r
+                                                       if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s')\r
+                                                           && src[5] == Ch(';')) {\r
+                                                               *dest = Ch('\'');\r
+                                                               ++dest;\r
+                                                               src += 6;\r
+                                                               continue;\r
+                                                       }\r
+                                                       break;\r
+\r
+                                                       // &quot;\r
+                                               case Ch('q'):\r
+                                                       if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t')\r
+                                                           && src[5] == Ch(';')) {\r
+                                                               *dest = Ch('"');\r
+                                                               ++dest;\r
+                                                               src += 6;\r
+                                                               continue;\r
+                                                       }\r
+                                                       break;\r
+\r
+                                                       // &gt;\r
+                                               case Ch('g'):\r
+                                                       if (src[2] == Ch('t') && src[3] == Ch(';')) {\r
+                                                               *dest = Ch('>');\r
+                                                               ++dest;\r
+                                                               src += 4;\r
+                                                               continue;\r
+                                                       }\r
+                                                       break;\r
+\r
+                                                       // &lt;\r
+                                               case Ch('l'):\r
+                                                       if (src[2] == Ch('t') && src[3] == Ch(';')) {\r
+                                                               *dest = Ch('<');\r
+                                                               ++dest;\r
+                                                               src += 4;\r
+                                                               continue;\r
+                                                       }\r
+                                                       break;\r
+\r
+                                                       // &#...; - assumes ASCII\r
+                                               case Ch('#'):\r
+                                                       if (src[2] == Ch('x')) {\r
+                                                               unsigned long code = 0;\r
+                                                               src += 3;   // Skip &#x\r
+                                                               while (1) {\r
+                                                                       unsigned char digit =\r
+                                                                           internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];\r
+                                                                       if (digit == 0xFF) break;\r
+                                                                       code = code * 16 + digit;\r
+                                                                       ++src;\r
+                                                               }\r
+                                                               insert_coded_character<Flags>(dest, code); // Put character in output\r
+                                                       } else {\r
+                                                               unsigned long code = 0;\r
+                                                               src += 2;   // Skip &#\r
+                                                               while (1) {\r
+                                                                       unsigned char digit =\r
+                                                                           internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];\r
+                                                                       if (digit == 0xFF) break;\r
+                                                                       code = code * 10 + digit;\r
+                                                                       ++src;\r
+                                                               }\r
+                                                               insert_coded_character<Flags>(dest, code); // Put character in output\r
+                                                       }\r
+                                                       if (*src == Ch(';'))\r
+                                                               ++src;\r
+                                                       else\r
+                                                       RAPIDXML_PARSE_ERROR("expected ;", src);\r
+                                                       continue;\r
+\r
+                                                       // Something else\r
+                                               default:\r
+                                                       // Ignore, just copy '&' verbatim\r
+                                                       break;\r
+\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       // If whitespace condensing is enabled\r
+                       if (Flags & parse_normalize_whitespace) {\r
+                               // Test if condensing is needed                 \r
+                               if (whitespace_pred::test(*src)) {\r
+                                       *dest = Ch(' ');\r
+                                       ++dest;    // Put single space in dest\r
+                                       ++src;                      // Skip first whitespace char\r
+                                       // Skip remaining whitespace chars\r
+                                       while (whitespace_pred::test(*src))\r
+                                               ++src;\r
+                                       continue;\r
+                               }\r
+                       }\r
+\r
+                       // No replacement, only copy character\r
+                       *dest++ = *src++;\r
+\r
+               }\r
+\r
+               // Return new end\r
+               text = src;\r
+               return dest;\r
+\r
+       }\r
+\r
+       ///////////////////////////////////////////////////////////////////////\r
+       // Internal parsing functions\r
+\r
+       // Parse BOM, if any\r
+       template<int Flags>\r
+       void parse_bom(Ch *&text) {\r
+               // UTF-8?\r
+               if (static_cast<unsigned char>(text[0]) == 0xEF\r
+                   && static_cast<unsigned char>(text[1]) == 0xBB\r
+                   && static_cast<unsigned char>(text[2]) == 0xBF) {\r
+                       text += 3;      // Skup utf-8 bom\r
+               }\r
+       }\r
+\r
+       // Parse XML declaration (<?xml...)\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_xml_declaration(Ch *&text) {\r
+               // If parsing of declaration is disabled\r
+               if (!(Flags & parse_declaration_node)) {\r
+                       // Skip until end of declaration\r
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {\r
+                               if (!text[0])\r
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                               ++text;\r
+                       }\r
+                       text += 2;    // Skip '?>'\r
+                       return 0;\r
+               }\r
+\r
+               // Create declaration\r
+               xml_node<Ch> *declaration = this->allocate_node(node_declaration);\r
+\r
+               // Skip whitespace before attributes or ?>\r
+               skip<whitespace_pred, Flags>(text);\r
+\r
+               // Parse declaration attributes\r
+               parse_node_attributes<Flags>(text, declaration);\r
+\r
+               // Skip ?>\r
+               if (text[0] != Ch('?') || text[1] != Ch('>'))\r
+               RAPIDXML_PARSE_ERROR("expected ?>", text);\r
+               text += 2;\r
+\r
+               return declaration;\r
+       }\r
+\r
+       // Parse XML comment (<!--...)\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_comment(Ch *&text) {\r
+               // If parsing of comments is disabled\r
+               if (!(Flags & parse_comment_nodes)) {\r
+                       // Skip until end of comment\r
+                       while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {\r
+                               if (!text[0])\r
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                               ++text;\r
+                       }\r
+                       text += 3;     // Skip '-->'\r
+                       return 0;      // Do not produce comment node\r
+               }\r
+\r
+               // Remember value start\r
+               Ch *value = text;\r
+\r
+               // Skip until end of comment\r
+               while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {\r
+                       if (!text[0])\r
+                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                       ++text;\r
+               }\r
+\r
+               // Create comment node\r
+               xml_node<Ch> *comment = this->allocate_node(node_comment);\r
+               comment->value(value, text - value);\r
+\r
+               // Place zero terminator after comment value\r
+               if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');\r
+\r
+               text += 3;     // Skip '-->'\r
+               return comment;\r
+       }\r
+\r
+       // Parse DOCTYPE\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_doctype(Ch *&text) {\r
+               // Remember value start\r
+               Ch *value = text;\r
+\r
+               // Skip to >\r
+               while (*text != Ch('>')) {\r
+                       // Determine character type\r
+                       switch (*text) {\r
+\r
+                               // If '[' encountered, scan for matching ending ']' using naive algorithm with depth\r
+                               // This works for all W3C test files except for 2 most wicked\r
+                               case Ch('['): {\r
+                                       ++text;     // Skip '['\r
+                                       int depth = 1;\r
+                                       while (depth > 0) {\r
+                                               switch (*text) {\r
+                                                       case Ch('['):\r
+                                                               ++depth;\r
+                                                               break;\r
+                                                       case Ch(']'):\r
+                                                               --depth;\r
+                                                               break;\r
+                                                       case 0:\r
+                                                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                                               }\r
+                                               ++text;\r
+                                       }\r
+                                       break;\r
+                               }\r
+\r
+                                       // Error on end of text\r
+                               case Ch('\0'):\r
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+\r
+                                       // Other character, skip it\r
+                               default:\r
+                                       ++text;\r
+\r
+                       }\r
+               }\r
+\r
+               // If DOCTYPE nodes enabled\r
+               if (Flags & parse_doctype_node) {\r
+                       // Create a new doctype node\r
+                       xml_node<Ch> *doctype = this->allocate_node(node_doctype);\r
+                       doctype->value(value, text - value);\r
+\r
+                       // Place zero terminator after value\r
+                       if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');\r
+\r
+                       text += 1;      // skip '>'\r
+                       return doctype;\r
+               } else {\r
+                       text += 1;      // skip '>'\r
+                       return 0;\r
+               }\r
+\r
+       }\r
+\r
+       // Parse PI\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_pi(Ch *&text) {\r
+               // If creation of PI nodes is enabled\r
+               if (Flags & parse_pi_nodes) {\r
+                       // Create pi node\r
+                       xml_node<Ch> *pi = this->allocate_node(node_pi);\r
+\r
+                       // Extract PI target name\r
+                       Ch *name = text;\r
+                       skip<node_name_pred, Flags>(text);\r
+                       if (text == name)\r
+                       RAPIDXML_PARSE_ERROR("expected PI target", text);\r
+                       pi->name(name, text - name);\r
+\r
+                       // Skip whitespace between pi target and pi\r
+                       skip<whitespace_pred, Flags>(text);\r
+\r
+                       // Remember start of pi\r
+                       Ch *value = text;\r
+\r
+                       // Skip to '?>'\r
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {\r
+                               if (*text == Ch('\0'))\r
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                               ++text;\r
+                       }\r
+\r
+                       // Set pi value (verbatim, no entity expansion or whitespace normalization)\r
+                       pi->value(value, text - value);\r
+\r
+                       // Place zero terminator after name and value\r
+                       if (!(Flags & parse_no_string_terminators)) {\r
+                               pi->name()[pi->name_size()] = Ch('\0');\r
+                               pi->value()[pi->value_size()] = Ch('\0');\r
+                       }\r
+\r
+                       text += 2;                          // Skip '?>'\r
+                       return pi;\r
+               } else {\r
+                       // Skip to '?>'\r
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {\r
+                               if (*text == Ch('\0'))\r
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                               ++text;\r
+                       }\r
+                       text += 2;    // Skip '?>'\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       // Parse and append data\r
+       // Return character that ends data.\r
+       // This is necessary because this character might have been overwritten by a terminating 0\r
+       template<int Flags>\r
+       Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start) {\r
+               // Backup to contents start if whitespace trimming is disabled\r
+               if (!(Flags & parse_trim_whitespace)) text = contents_start;\r
+\r
+               // Skip until end of data\r
+               Ch *value = text, *end;\r
+               if (Flags & parse_normalize_whitespace)\r
+                       end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred,\r
+                           Flags>(text);\r
+               else end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred,\r
+                   Flags>(text);\r
+\r
+               // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >\r
+               if (Flags & parse_trim_whitespace) {\r
+                       if (Flags & parse_normalize_whitespace) {\r
+                               // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end\r
+                               if (*(end - 1) == Ch(' ')) --end;\r
+                       } else {\r
+                               // Backup until non-whitespace character is found\r
+                               while (whitespace_pred::test(*(end - 1)))\r
+                                       --end;\r
+                       }\r
+               }\r
+\r
+               // If characters are still left between end and value (this test is only necessary if normalization is enabled)\r
+               // Create new data node\r
+               if (!(Flags & parse_no_data_nodes)) {\r
+                       xml_node<Ch> *data = this->allocate_node(node_data);\r
+                       data->value(value, end - value);\r
+                       node->append_node(data);\r
+               }\r
+\r
+               // Add data to parent node if no data exists yet\r
+               if (!(Flags & parse_no_element_values))\r
+                 if (*node->value() == Ch('\0')) node->value(value, end - value);\r
+\r
+               // Place zero terminator after value\r
+               if (!(Flags & parse_no_string_terminators)) {\r
+                       Ch ch = *text;\r
+                       *end = Ch('\0');\r
+                       return ch; // Return character that ends data; this is required because zero terminator overwritten it\r
+               }\r
+\r
+               // Return character that ends data\r
+               return *text;\r
+       }\r
+\r
+       // Parse CDATA\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_cdata(Ch *&text) {\r
+               // If CDATA is disabled\r
+               if (Flags & parse_no_data_nodes) {\r
+                       // Skip until end of cdata\r
+                       while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {\r
+                               if (!text[0])\r
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                               ++text;\r
+                       }\r
+                       text += 3;      // Skip ]]>\r
+                       return 0;       // Do not produce CDATA node\r
+               }\r
+\r
+               // Skip until end of cdata\r
+               Ch *value = text;\r
+               while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {\r
+                       if (!text[0])\r
+                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                       ++text;\r
+               }\r
+\r
+               // Create new cdata node\r
+               xml_node<Ch> *cdata = this->allocate_node(node_cdata);\r
+               cdata->value(value, text - value);\r
+\r
+               // Place zero terminator after value\r
+               if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');\r
+\r
+               text += 3;      // Skip ]]>\r
+               return cdata;\r
+       }\r
+\r
+       // Parse element node\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_element(Ch *&text) {\r
+               // Create element node\r
+               xml_node<Ch> *element = this->allocate_node(node_element);\r
+\r
+               // Extract element name\r
+               Ch *name = text;\r
+               skip<node_name_pred, Flags>(text);\r
+               if (text == name)\r
+               RAPIDXML_PARSE_ERROR("expected element name", text);\r
+               element->name(name, text - name);\r
+\r
+               // Skip whitespace between element name and attributes or >\r
+               skip<whitespace_pred, Flags>(text);\r
+\r
+               // Parse attributes, if any\r
+               parse_node_attributes<Flags>(text, element);\r
+\r
+               // Determine ending type\r
+               if (*text == Ch('>')) {\r
+                       ++text;\r
+                       parse_node_contents<Flags>(text, element);\r
+               } else if (*text == Ch('/')) {\r
+                       ++text;\r
+                       if (*text != Ch('>'))\r
+                       RAPIDXML_PARSE_ERROR("expected >", text);\r
+                       ++text;\r
+               } else\r
+               RAPIDXML_PARSE_ERROR("expected >", text);\r
+\r
+               // Place zero terminator after name\r
+               if (!(Flags & parse_no_string_terminators))\r
+                 element->name()[element->name_size()] = Ch('\0');\r
+\r
+               // Return parsed element\r
+               return element;\r
+       }\r
+\r
+       // Determine node type, and parse it\r
+       template<int Flags>\r
+       xml_node<Ch> *parse_node(Ch *&text) {\r
+               // Parse proper node type\r
+               switch (text[0]) {\r
+\r
+                       // <...\r
+                       default:\r
+                               // Parse and append element node\r
+                               return parse_element<Flags>(text);\r
+\r
+                               // <?...\r
+                       case Ch('?'):\r
+                               ++text;     // Skip ?\r
+                               if ((text[0] == Ch('x') || text[0] == Ch('X'))\r
+                                   && (text[1] == Ch('m') || text[1] == Ch('M'))\r
+                                   && (text[2] == Ch('l') || text[2] == Ch('L'))\r
+                                   && whitespace_pred::test(text[3])) {\r
+                                       // '<?xml ' - xml declaration\r
+                                       text += 4;      // Skip 'xml '\r
+                                       return parse_xml_declaration<Flags>(text);\r
+                               } else {\r
+                                       // Parse PI\r
+                                       return parse_pi<Flags>(text);\r
+                               }\r
+\r
+                               // <!...\r
+                       case Ch('!'):\r
+\r
+                               // Parse proper subset of <! node\r
+                               switch (text[1]) {\r
+\r
+                                       // <!-\r
+                                       case Ch('-'):\r
+                                               if (text[2] == Ch('-')) {\r
+                                                       // '<!--' - xml comment\r
+                                                       text += 3;     // Skip '!--'\r
+                                                       return parse_comment<Flags>(text);\r
+                                               }\r
+                                               break;\r
+\r
+                                               // <![\r
+                                       case Ch('['):\r
+                                               if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A')\r
+                                                   && text[5] == Ch('T') && text[6] == Ch('A')\r
+                                                   && text[7] == Ch('[')) {\r
+                                                       // '<![CDATA[' - cdata\r
+                                                       text += 8;     // Skip '![CDATA['\r
+                                                       return parse_cdata<Flags>(text);\r
+                                               }\r
+                                               break;\r
+\r
+                                               // <!D\r
+                                       case Ch('D'):\r
+                                               if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T')\r
+                                                   && text[5] == Ch('Y') && text[6] == Ch('P')\r
+                                                   && text[7] == Ch('E') && whitespace_pred::test(text[8])) {\r
+                                                       // '<!DOCTYPE ' - doctype\r
+                                                       text += 9;      // skip '!DOCTYPE '\r
+                                                       return parse_doctype<Flags>(text);\r
+                                               }\r
+\r
+                               }   // switch\r
+\r
+                               // Attempt to skip other, unrecognized node types starting with <!\r
+                               ++text;     // Skip !\r
+                               while (*text != Ch('>')) {\r
+                                       if (*text == 0)\r
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+                                       ++text;\r
+                               }\r
+                               ++text;     // Skip '>'\r
+                               return 0;   // No node recognized\r
+\r
+               }\r
+       }\r
+\r
+       // Parse contents of the node - children, data etc.\r
+       template<int Flags>\r
+       void parse_node_contents(Ch *&text, xml_node<Ch> *node) {\r
+               // For all children and text\r
+               while (1) {\r
+                       // Skip whitespace between > and node contents\r
+                       Ch *contents_start = text; // Store start of node contents before whitespace is skipped\r
+                       skip<whitespace_pred, Flags>(text);\r
+                       Ch next_char = *text;\r
+\r
+                       // After data nodes, instead of continuing the loop, control jumps here.\r
+                       // This is because zero termination inside parse_and_append_data() function\r
+                       // would wreak havoc with the above code.\r
+                       // Also, skipping whitespace after data nodes is unnecessary.\r
+                       after_data_node:\r
+\r
+                       // Determine what comes next: node closing, child node, data node, or 0?\r
+                       switch (next_char) {\r
+\r
+                               // Node closing or child node\r
+                               case Ch('<'):\r
+                                       if (text[1] == Ch('/')) {\r
+                                               // Node closing\r
+                                               text += 2;      // Skip '</'\r
+                                               if (Flags & parse_validate_closing_tags) {\r
+                                                       // Skip and validate closing tag name\r
+                                                       Ch *closing_name = text;\r
+                                                       skip<node_name_pred, Flags>(text);\r
+                                                       if (!internal::compare(node->name(), node->name_size(),\r
+                                                           closing_name, text - closing_name, true))\r
+                                                       RAPIDXML_PARSE_ERROR("invalid closing tag name", text);\r
+                                               } else {\r
+                                                       // No validation, just skip name\r
+                                                       skip<node_name_pred, Flags>(text);\r
+                                               }\r
+                                               // Skip remaining whitespace after node name\r
+                                               skip<whitespace_pred, Flags>(text);\r
+                                               if (*text != Ch('>'))\r
+                                               RAPIDXML_PARSE_ERROR("expected >", text);\r
+                                               ++text;     // Skip '>'\r
+                                               return;     // Node closed, finished parsing contents\r
+                                       } else {\r
+                                               // Child node\r
+                                               ++text;     // Skip '<'\r
+                                               if (xml_node<Ch> *child = parse_node<Flags>(text))\r
+                                                 node->append_node(child);\r
+                                       }\r
+                                       break;\r
+\r
+                                       // End of data - error\r
+                               case Ch('\0'):\r
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);\r
+\r
+                                       // Data node\r
+                               default:\r
+                                       next_char = parse_and_append_data<Flags>(node, text, contents_start);\r
+                                       goto after_data_node;\r
+                                       // Bypass regular processing after data nodes\r
+\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Parse XML attributes of the node\r
+       template<int Flags>\r
+       void parse_node_attributes(Ch *&text, xml_node<Ch> *node) {\r
+               // For all attributes \r
+               while (attribute_name_pred::test(*text)) {\r
+                       // Extract attribute name\r
+                       Ch *name = text;\r
+                       ++text;     // Skip first character of attribute name\r
+                       skip<attribute_name_pred, Flags>(text);\r
+                       if (text == name)\r
+                       RAPIDXML_PARSE_ERROR("expected attribute name", name);\r
+\r
+                       // Create new attribute\r
+                       xml_attribute<Ch> *attribute = this->allocate_attribute();\r
+                       attribute->name(name, text - name);\r
+                       node->append_attribute(attribute);\r
+\r
+                       // Skip whitespace after attribute name\r
+                       skip<whitespace_pred, Flags>(text);\r
+\r
+                       // Skip =\r
+                       if (*text != Ch('='))\r
+                       RAPIDXML_PARSE_ERROR("expected =", text);\r
+                       ++text;\r
+\r
+                       // Add terminating zero after name\r
+                       if (!(Flags & parse_no_string_terminators))\r
+                         attribute->name()[attribute->name_size()] = 0;\r
+\r
+                       // Skip whitespace after =\r
+                       skip<whitespace_pred, Flags>(text);\r
+\r
+                       // Skip quote and remember if it was ' or "\r
+                       Ch quote = *text;\r
+                       if (quote != Ch('\'') && quote != Ch('"'))\r
+                       RAPIDXML_PARSE_ERROR("expected ' or \"", text);\r
+                       ++text;\r
+\r
+                       // Extract attribute value and expand char refs in it\r
+                       Ch *value = text, *end;\r
+                       const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes\r
+                       if (quote == Ch('\''))\r
+                               end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>,\r
+                                   attribute_value_pure_pred<Ch('\'')>, AttFlags>(text);\r
+                       else end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>,\r
+                           attribute_value_pure_pred<Ch('"')>, AttFlags>(text);\r
+\r
+                       // Set attribute value\r
+                       attribute->value(value, end - value);\r
+\r
+                       // Make sure that end quote is present\r
+                       if (*text != quote)\r
+                       RAPIDXML_PARSE_ERROR("expected ' or \"", text);\r
+                       ++text;     // Skip quote\r
+\r
+                       // Add terminating zero after value\r
+                       if (!(Flags & parse_no_string_terminators))\r
+                         attribute->value()[attribute->value_size()] = 0;\r
+\r
+                       // Skip whitespace after attribute value\r
+                       skip<whitespace_pred, Flags>(text);\r
+               }\r
+       }\r
+\r
+};\r
+\r
+//! \cond internal\r
+namespace internal {\r
+\r
+// Whitespace (space \n \r \t)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,  // 0\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1\r
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E\r
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F\r
+    };\r
+\r
+// Node name (anything but space \n \r \t / > ? \0)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_node_name[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Text (i.e. PCDATA) (anything but < \0)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_text[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Text (i.e. PCDATA) that does not require processing when ws normalization is disabled \r
+// (anything but < \0 &)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled\r
+// (anything but < \0 & space \n \r \t)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Attribute name (anything but space \n \r \t / < > = ? ! \0)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Attribute data with single quote (anything but ' \0)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Attribute data with single quote that does not require processing (anything but ' \0 &)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Attribute data with double quote (anything but " \0)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Attribute data with double quote that does not require processing (anything but " \0 &)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] = {\r
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1\r
+    1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E\r
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F\r
+    };\r
+\r
+// Digits (dec and hex, 255 denotes end of numeric character reference)\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_digits[256] = {\r
+    // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 0\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 1\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 2\r
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255,\r
+    255,  // 3\r
+    255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 4\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 5\r
+    255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 6\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 7\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 8\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // 9\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // A\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // B\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // C\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // D\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255,  // E\r
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\r
+    255   // F\r
+    };\r
+\r
+// Upper case conversion\r
+template<int Dummy>\r
+const unsigned char lookup_tables<Dummy>::lookup_upcase[256] = {\r
+    // 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  A   B   C   D   E   F\r
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,\r
+    15,   // 0\r
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,\r
+    31,   // 1\r
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,\r
+    47,   // 2\r
+    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,\r
+    63,   // 3\r
+    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,\r
+    79,   // 4\r
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,\r
+    95,   // 5\r
+    96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,\r
+    79,   // 6\r
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126,\r
+    127,  // 7\r
+    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,\r
+    143,  // 8\r
+    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,\r
+    159,  // 9\r
+    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,\r
+    175,  // A\r
+    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,\r
+    191,  // B\r
+    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,\r
+    207,  // C\r
+    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,\r
+    223,  // D\r
+    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,\r
+    239,  // E\r
+    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,\r
+    255   // F\r
+    };\r
+}\r
+//! \endcond\r
+\r
+}\r
+\r
+// Undefine internal macros\r
+#undef RAPIDXML_PARSE_ERROR\r
+\r
+// On MSVC, restore warnings state\r
+#ifdef _MSC_VER\r
+#pragma warning(pop)\r
+#endif\r
+\r
+#endif\r
diff --git a/TEEStub/PropertyAccess/rapidxml/rapidxml_iterators.hpp b/TEEStub/PropertyAccess/rapidxml/rapidxml_iterators.hpp
new file mode 100755 (executable)
index 0000000..379dcf7
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED\r
+#define RAPIDXML_ITERATORS_HPP_INCLUDED\r
+\r
+// Copyright (C) 2006, 2009 Marcin Kalicinski\r
+// Version 1.13\r
+// Revision $DateTime: 2009/05/13 01:46:17 $\r
+//! \file rapidxml_iterators.hpp This file contains rapidxml iterators\r
+\r
+#include "rapidxml.hpp"\r
+\r
+namespace rapidxml {\r
+\r
+//! Iterator of child nodes of xml_node\r
+template<class Ch>\r
+class node_iterator {\r
+\r
+public:\r
+\r
+       typedef typename xml_node<Ch> value_type;\r
+       typedef typename xml_node<Ch> &reference;\r
+       typedef typename xml_node<Ch> *pointer;\r
+       typedef std::ptrdiff_t difference_type;\r
+       typedef std::bidirectional_iterator_tag iterator_category;\r
+\r
+       node_iterator() :\r
+                       m_node(0) {\r
+       }\r
+\r
+       node_iterator(xml_node<Ch> *node) :\r
+                       m_node(node->first_node()) {\r
+       }\r
+\r
+       reference operator *() const {\r
+               assert(m_node);\r
+               return *m_node;\r
+       }\r
+\r
+       pointer operator->() const {\r
+               assert(m_node);\r
+               return m_node;\r
+       }\r
+\r
+       node_iterator& operator++() {\r
+               assert(m_node);\r
+               m_node = m_node->next_sibling();\r
+               return *this;\r
+       }\r
+\r
+       node_iterator operator++(int) {\r
+               node_iterator tmp = *this;\r
+               ++this;\r
+               return tmp;\r
+       }\r
+\r
+       node_iterator& operator--() {\r
+               assert(m_node && m_node->previous_sibling());\r
+               m_node = m_node->previous_sibling();\r
+               return *this;\r
+       }\r
+\r
+       node_iterator operator--(int) {\r
+               node_iterator tmp = *this;\r
+               ++this;\r
+               return tmp;\r
+       }\r
+\r
+       bool operator ==(const node_iterator<Ch> &rhs) {\r
+               return m_node == rhs.m_node;\r
+       }\r
+\r
+       bool operator !=(const node_iterator<Ch> &rhs) {\r
+               return m_node != rhs.m_node;\r
+       }\r
+\r
+private:\r
+\r
+       xml_node<Ch> *m_node;\r
+\r
+};\r
+\r
+//! Iterator of child attributes of xml_node\r
+template<class Ch>\r
+class attribute_iterator {\r
+\r
+public:\r
+\r
+       typedef typename xml_attribute<Ch> value_type;\r
+       typedef typename xml_attribute<Ch> &reference;\r
+       typedef typename xml_attribute<Ch> *pointer;\r
+       typedef std::ptrdiff_t difference_type;\r
+       typedef std::bidirectional_iterator_tag iterator_category;\r
+\r
+       attribute_iterator() :\r
+                       m_attribute(0) {\r
+       }\r
+\r
+       attribute_iterator(xml_node<Ch> *node) :\r
+                       m_attribute(node->first_attribute()) {\r
+       }\r
+\r
+       reference operator *() const {\r
+               assert(m_attribute);\r
+               return *m_attribute;\r
+       }\r
+\r
+       pointer operator->() const {\r
+               assert(m_attribute);\r
+               return m_attribute;\r
+       }\r
+\r
+       attribute_iterator& operator++() {\r
+               assert(m_attribute);\r
+               m_attribute = m_attribute->next_attribute();\r
+               return *this;\r
+       }\r
+\r
+       attribute_iterator operator++(int) {\r
+               attribute_iterator tmp = *this;\r
+               ++this;\r
+               return tmp;\r
+       }\r
+\r
+       attribute_iterator& operator--() {\r
+               assert(m_attribute && m_attribute->previous_attribute());\r
+               m_attribute = m_attribute->previous_attribute();\r
+               return *this;\r
+       }\r
+\r
+       attribute_iterator operator--(int) {\r
+               attribute_iterator tmp = *this;\r
+               ++this;\r
+               return tmp;\r
+       }\r
+\r
+       bool operator ==(const attribute_iterator<Ch> &rhs) {\r
+               return m_attribute == rhs.m_attribute;\r
+       }\r
+\r
+       bool operator !=(const attribute_iterator<Ch> &rhs) {\r
+               return m_attribute != rhs.m_attribute;\r
+       }\r
+\r
+private:\r
+\r
+       xml_attribute<Ch> *m_attribute;\r
+\r
+};\r
+\r
+}\r
+\r
+#endif\r
diff --git a/TEEStub/PropertyAccess/rapidxml/rapidxml_print.hpp b/TEEStub/PropertyAccess/rapidxml/rapidxml_print.hpp
new file mode 100755 (executable)
index 0000000..8a627e5
--- /dev/null
@@ -0,0 +1,426 @@
+#ifndef RAPIDXML_PRINT_HPP_INCLUDED\r
+#define RAPIDXML_PRINT_HPP_INCLUDED\r
+\r
+// Copyright (C) 2006, 2009 Marcin Kalicinski\r
+// Version 1.13\r
+// Revision $DateTime: 2009/05/13 01:46:17 $\r
+//! \file rapidxml_print.hpp This file contains rapidxml printer implementation\r
+\r
+#include "rapidxml.hpp"\r
+\r
+// Only include streams if not disabled\r
+#ifndef RAPIDXML_NO_STREAMS\r
+#include <ostream>\r
+#include <iterator>\r
+#endif\r
+\r
+namespace rapidxml {\r
+\r
+///////////////////////////////////////////////////////////////////////\r
+// Printing flags\r
+\r
+const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.\r
+\r
+///////////////////////////////////////////////////////////////////////\r
+// Internal\r
+\r
+//! \cond internal\r
+namespace internal {\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// Internal character operations\r
+\r
+// Copy characters from given range to given output iterator\r
+template<class OutIt, class Ch>\r
+inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) {\r
+       while (begin != end)\r
+               *out++ = *begin++;\r
+       return out;\r
+}\r
+\r
+// Copy characters from given range to given output iterator and expand\r
+// characters into references (&lt; &gt; &apos; &quot; &amp;)\r
+template<class OutIt, class Ch>\r
+inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand,\r
+    OutIt out) {\r
+       while (begin != end) {\r
+               if (*begin == noexpand) {\r
+                       *out++ = *begin;    // No expansion, copy character\r
+               } else {\r
+                       switch (*begin) {\r
+                               case Ch('<'):\r
+                                       *out++ = Ch('&');\r
+                                       *out++ = Ch('l');\r
+                                       *out++ = Ch('t');\r
+                                       *out++ = Ch(';');\r
+                                       break;\r
+                               case Ch('>'):\r
+                                       *out++ = Ch('&');\r
+                                       *out++ = Ch('g');\r
+                                       *out++ = Ch('t');\r
+                                       *out++ = Ch(';');\r
+                                       break;\r
+                               case Ch('\''):\r
+                                       *out++ = Ch('&');\r
+                                       *out++ = Ch('a');\r
+                                       *out++ = Ch('p');\r
+                                       *out++ = Ch('o');\r
+                                       *out++ = Ch('s');\r
+                                       *out++ = Ch(';');\r
+                                       break;\r
+                               case Ch('"'):\r
+                                       *out++ = Ch('&');\r
+                                       *out++ = Ch('q');\r
+                                       *out++ = Ch('u');\r
+                                       *out++ = Ch('o');\r
+                                       *out++ = Ch('t');\r
+                                       *out++ = Ch(';');\r
+                                       break;\r
+                               case Ch('&'):\r
+                                       *out++ = Ch('&');\r
+                                       *out++ = Ch('a');\r
+                                       *out++ = Ch('m');\r
+                                       *out++ = Ch('p');\r
+                                       *out++ = Ch(';');\r
+                                       break;\r
+                               default:\r
+                                       *out++ = *begin;    // No expansion, copy character\r
+                       }\r
+               }\r
+               ++begin;    // Step to next character\r
+       }\r
+       return out;\r
+}\r
+\r
+// Fill given output iterator with repetitions of the same character\r
+template<class OutIt, class Ch>\r
+inline OutIt fill_chars(OutIt out, int n, Ch ch) {\r
+       for (int i = 0; i < n; ++i)\r
+               *out++ = ch;\r
+       return out;\r
+}\r
+\r
+// Find character\r
+template<class Ch, Ch ch>\r
+inline bool find_char(const Ch *begin, const Ch *end) {\r
+       while (begin != end)\r
+               if (*begin++ == ch) return true;\r
+       return false;\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// Internal printing operations\r
+\r
+// Print node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       // Print proper node type\r
+       switch (node->type()) {\r
+\r
+               // Document\r
+               case node_document:\r
+                       out = print_children(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Element\r
+               case node_element:\r
+                       out = print_element_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Data\r
+               case node_data:\r
+                       out = print_data_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // CDATA\r
+               case node_cdata:\r
+                       out = print_cdata_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Declaration\r
+               case node_declaration:\r
+                       out = print_declaration_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Comment\r
+               case node_comment:\r
+                       out = print_comment_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Doctype\r
+               case node_doctype:\r
+                       out = print_doctype_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Pi\r
+               case node_pi:\r
+                       out = print_pi_node(out, node, flags, indent);\r
+                       break;\r
+\r
+                       // Unknown\r
+               default:\r
+                       assert(0);\r
+                       break;\r
+       }\r
+\r
+       // If indenting not disabled, add line break after node\r
+       if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out;\r
+\r
+       // Return modified iterator\r
+       return out;\r
+}\r
+\r
+// Print children of the node                               \r
+template<class OutIt, class Ch>\r
+inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       for (xml_node<Ch> *child = node->first_node(); child;\r
+           child = child->next_sibling())\r
+               out = print_node(out, child, flags, indent);\r
+       return out;\r
+}\r
+\r
+// Print attributes of the node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags) {\r
+       for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute;\r
+           attribute = attribute->next_attribute()) {\r
+               if (attribute->name() && attribute->value()) {\r
+                       // Print attribute name\r
+                       *out = Ch(' '), ++out;\r
+                       out = copy_chars(attribute->name(),\r
+                           attribute->name() + attribute->name_size(), out);\r
+                       *out = Ch('='), ++out;\r
+                       // Print attribute value using appropriate quote type\r
+                       if (find_char<Ch, Ch('"')>(attribute->value(),\r
+                           attribute->value() + attribute->value_size())) {\r
+                               *out = Ch('\''), ++out;\r
+                               out = copy_and_expand_chars(attribute->value(),\r
+                                   attribute->value() + attribute->value_size(), Ch('"'), out);\r
+                               *out = Ch('\''), ++out;\r
+                       } else {\r
+                               *out = Ch('"'), ++out;\r
+                               out = copy_and_expand_chars(attribute->value(),\r
+                                   attribute->value() + attribute->value_size(), Ch('\''), out);\r
+                               *out = Ch('"'), ++out;\r
+                       }\r
+               }\r
+       }\r
+       return out;\r
+}\r
+\r
+// Print data node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       assert(node->type() == node_data);\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       out = copy_and_expand_chars(node->value(), node->value() + node->value_size(),\r
+           Ch(0), out);\r
+       return out;\r
+}\r
+\r
+// Print data node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       assert(node->type() == node_cdata);\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       *out = Ch('<');\r
+       ++out;\r
+       *out = Ch('!');\r
+       ++out;\r
+       *out = Ch('[');\r
+       ++out;\r
+       *out = Ch('C');\r
+       ++out;\r
+       *out = Ch('D');\r
+       ++out;\r
+       *out = Ch('A');\r
+       ++out;\r
+       *out = Ch('T');\r
+       ++out;\r
+       *out = Ch('A');\r
+       ++out;\r
+       *out = Ch('[');\r
+       ++out;\r
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);\r
+       *out = Ch(']');\r
+       ++out;\r
+       *out = Ch(']');\r
+       ++out;\r
+       *out = Ch('>');\r
+       ++out;\r
+       return out;\r
+}\r
+\r
+// Print element node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       assert(node->type() == node_element);\r
+\r
+       // Print element name and attributes, if any\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       *out = Ch('<'), ++out;\r
+       out = copy_chars(node->name(), node->name() + node->name_size(), out);\r
+       out = print_attributes(out, node, flags);\r
+\r
+       // If node is childless\r
+       if (node->value_size() == 0 && !node->first_node()) {\r
+               // Print childless node tag ending\r
+               *out = Ch('/'), ++out;\r
+               *out = Ch('>'), ++out;\r
+       } else {\r
+               // Print normal node tag ending\r
+               *out = Ch('>'), ++out;\r
+\r
+               // Test if node contains a single data node only (and no other nodes)\r
+               xml_node<Ch> *child = node->first_node();\r
+               if (!child) {\r
+                       // If node has no children, only print its value without indenting\r
+                       out = copy_and_expand_chars(node->value(),\r
+                           node->value() + node->value_size(), Ch(0), out);\r
+               } else if (child->next_sibling() == 0 && child->type() == node_data) {\r
+                       // If node has a sole data child, only print its value without indenting\r
+                       out = copy_and_expand_chars(child->value(),\r
+                           child->value() + child->value_size(), Ch(0), out);\r
+               } else {\r
+                       // Print all children with full indenting\r
+                       if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out;\r
+                       out = print_children(out, node, flags, indent + 1);\r
+                       if (!(flags & print_no_indenting))\r
+                         out = fill_chars(out, indent, Ch('\t'));\r
+               }\r
+\r
+               // Print node end\r
+               *out = Ch('<'), ++out;\r
+               *out = Ch('/'), ++out;\r
+               out = copy_chars(node->name(), node->name() + node->name_size(), out);\r
+               *out = Ch('>'), ++out;\r
+       }\r
+       return out;\r
+}\r
+\r
+// Print declaration node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node,\r
+    int flags, int indent) {\r
+       // Print declaration start\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       *out = Ch('<'), ++out;\r
+       *out = Ch('?'), ++out;\r
+       *out = Ch('x'), ++out;\r
+       *out = Ch('m'), ++out;\r
+       *out = Ch('l'), ++out;\r
+\r
+       // Print attributes\r
+       out = print_attributes(out, node, flags);\r
+\r
+       // Print declaration end\r
+       *out = Ch('?'), ++out;\r
+       *out = Ch('>'), ++out;\r
+\r
+       return out;\r
+}\r
+\r
+// Print comment node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       assert(node->type() == node_comment);\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       *out = Ch('<'), ++out;\r
+       *out = Ch('!'), ++out;\r
+       *out = Ch('-'), ++out;\r
+       *out = Ch('-'), ++out;\r
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);\r
+       *out = Ch('-'), ++out;\r
+       *out = Ch('-'), ++out;\r
+       *out = Ch('>'), ++out;\r
+       return out;\r
+}\r
+\r
+// Print doctype node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       assert(node->type() == node_doctype);\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       *out = Ch('<'), ++out;\r
+       *out = Ch('!'), ++out;\r
+       *out = Ch('D'), ++out;\r
+       *out = Ch('O'), ++out;\r
+       *out = Ch('C'), ++out;\r
+       *out = Ch('T'), ++out;\r
+       *out = Ch('Y'), ++out;\r
+       *out = Ch('P'), ++out;\r
+       *out = Ch('E'), ++out;\r
+       *out = Ch(' '), ++out;\r
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);\r
+       *out = Ch('>'), ++out;\r
+       return out;\r
+}\r
+\r
+// Print pi node\r
+template<class OutIt, class Ch>\r
+inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags,\r
+    int indent) {\r
+       assert(node->type() == node_pi);\r
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));\r
+       *out = Ch('<'), ++out;\r
+       *out = Ch('?'), ++out;\r
+       out = copy_chars(node->name(), node->name() + node->name_size(), out);\r
+       *out = Ch(' '), ++out;\r
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);\r
+       *out = Ch('?'), ++out;\r
+       *out = Ch('>'), ++out;\r
+       return out;\r
+}\r
+\r
+}\r
+//! \endcond\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+// Printing\r
+\r
+//! Prints XML to given output iterator.\r
+//! \param out Output iterator to print to.\r
+//! \param node Node to be printed. Pass xml_document to print entire document.\r
+//! \param flags Flags controlling how XML is printed.\r
+//! \return Output iterator pointing to position immediately after last character of printed text.\r
+template<class OutIt, class Ch>\r
+inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0) {\r
+       return internal::print_node(out, &node, flags, 0);\r
+}\r
+\r
+#ifndef RAPIDXML_NO_STREAMS\r
+\r
+//! Prints XML to given output stream.\r
+//! \param out Output stream to print to.\r
+//! \param node Node to be printed. Pass xml_document to print entire document.\r
+//! \param flags Flags controlling how XML is printed.\r
+//! \return Output stream.\r
+template<class Ch>\r
+inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out,\r
+    const xml_node<Ch> &node, int flags = 0) {\r
+       print(std::ostream_iterator < Ch > (out), node, flags);\r
+       return out;\r
+}\r
+\r
+//! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.\r
+//! \param out Output stream to print to.\r
+//! \param node Node to be printed.\r
+//! \return Output stream.\r
+template<class Ch>\r
+inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out,\r
+    const xml_node<Ch> &node) {\r
+       return print(out, node);\r
+}\r
+\r
+#endif\r
+\r
+}\r
+\r
+#endif\r
diff --git a/TEEStub/PropertyAccess/rapidxml/rapidxml_utils.hpp b/TEEStub/PropertyAccess/rapidxml/rapidxml_utils.hpp
new file mode 100755 (executable)
index 0000000..c95e1e5
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef RAPIDXML_UTILS_HPP_INCLUDED\r
+#define RAPIDXML_UTILS_HPP_INCLUDED\r
+\r
+// Copyright (C) 2006, 2009 Marcin Kalicinski\r
+// Version 1.13\r
+// Revision $DateTime: 2009/05/13 01:46:17 $\r
+//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful\r
+//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective.\r
+\r
+#include "rapidxml.hpp"\r
+#include <vector>\r
+#include <string>\r
+#include <fstream>\r
+#include <stdexcept>\r
+\r
+namespace rapidxml {\r
+\r
+//! Represents data loaded from a file\r
+template<class Ch = char>\r
+class file {\r
+\r
+public:\r
+\r
+       //! Loads file into the memory. Data will be automatically destroyed by the destructor.\r
+       //! \param filename Filename to load.\r
+       file(const char *filename) {\r
+               using namespace std;\r
+\r
+               // Open stream\r
+               basic_ifstream<Ch> stream(filename, ios::binary);\r
+               if (!stream) throw runtime_error(string("cannot open file ") + filename);\r
+               stream.unsetf(ios::skipws);\r
+\r
+               // Determine stream size\r
+               stream.seekg(0, ios::end);\r
+               size_t size = stream.tellg();\r
+               stream.seekg(0);\r
+\r
+               // Load data and add terminating 0\r
+               m_data.resize(size + 1);\r
+               stream.read(&m_data.front(), static_cast<streamsize>(size));\r
+               m_data[size] = 0;\r
+       }\r
+\r
+       //! Loads file into the memory. Data will be automatically destroyed by the destructor\r
+       //! \param stream Stream to load from\r
+       file(std::basic_istream<Ch> &stream) {\r
+               using namespace std;\r
+\r
+               // Load data and add terminating 0\r
+               stream.unsetf(ios::skipws);\r
+               m_data.assign(istreambuf_iterator < Ch > (stream),\r
+                   istreambuf_iterator<Ch>());\r
+               if (stream.fail() || stream.bad())\r
+                 throw runtime_error("error reading stream");\r
+               m_data.push_back(0);\r
+       }\r
+\r
+       //! Gets file data.\r
+       //! \return Pointer to data of file.\r
+       Ch *data() {\r
+               return &m_data.front();\r
+       }\r
+\r
+       //! Gets file data.\r
+       //! \return Pointer to data of file.\r
+       const Ch *data() const {\r
+               return &m_data.front();\r
+       }\r
+\r
+       //! Gets file data size.\r
+       //! \return Size of file data, in characters.\r
+       std::size_t size() const {\r
+               return m_data.size();\r
+       }\r
+\r
+private:\r
+\r
+       std::vector<Ch> m_data;   // File data\r
+\r
+};\r
+\r
+//! Counts children of node. Time complexity is O(n).\r
+//! \return Number of children of node\r
+template<class Ch>\r
+inline std::size_t count_children(xml_node<Ch> *node) {\r
+       xml_node<Ch> *child = node->first_node();\r
+       std::size_t count = 0;\r
+       while (child) {\r
+               ++count;\r
+               child = child->next_sibling();\r
+       }\r
+       return count;\r
+}\r
+\r
+//! Counts attributes of node. Time complexity is O(n).\r
+//! \return Number of attributes of node\r
+template<class Ch>\r
+inline std::size_t count_attributes(xml_node<Ch> *node) {\r
+       xml_attribute<Ch> *attr = node->first_attribute();\r
+       std::size_t count = 0;\r
+       while (attr) {\r
+               ++count;\r
+               attr = attr->next_attribute();\r
+       }\r
+       return count;\r
+}\r
+\r
+}\r
+\r
+#endif\r
diff --git a/TEEStub/TACommands/CommandBase.cpp b/TEEStub/TACommands/CommandBase.cpp
new file mode 100755 (executable)
index 0000000..3ededa4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  BaseCommand.cpp
+ *
+ *    Description:  BaseCommand class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+unsigned int CommandBase::sessionContextContainer = 0;
+void *CommandBase::sessionContext = &CommandBase::sessionContextContainer;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Constructor for Base command class where command gets initialized
+ * @param acommand[in] command enum value
+ */
+CommandBase::CommandBase(SIM_COMMAND acommand) :
+               command(acommand), sessionID(0) {
+}
+
+/**
+ * Destructor
+ */
+CommandBase::~CommandBase() {
+}
+
+/**
+ *
+ * @return returns command ID of the derived command class.
+ */
+SIM_COMMAND CommandBase::getCommandID() const {
+       return command;
+}
+
+/**
+ * Overridden by CommandRequestCancel only which returns true.
+ * Else, all other derived classes shall NOT override this function.
+ * @return true if derived class is CommandRequestCancel and when overridden.
+ * Else false by default.
+ */
+bool CommandBase::isCancelCommand() const {
+       return false;
+}
diff --git a/TEEStub/TACommands/CommandBase.h b/TEEStub/TACommands/CommandBase.h
new file mode 100755 (executable)
index 0000000..d7048d3
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  BaseCommand.h
+ *
+ *    Description:  BaseCommand header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef BASECOMMAND_H_
+#define BASECOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_sim_command.h"
+#include "tee_internal_api.h"
+#include "log.h"
+#include "boost/shared_ptr.hpp"
+#include <string>
+#include <string.h>
+
+extern void* sessionContext;
+extern bool _allowPropertyAccess;
+
+#ifndef TOGGLE_PROPERTY_ACCESS
+#define  TOGGLE_PROPERTY_ACCESS {_allowPropertyAccess = !_allowPropertyAccess;}
+#endif
+/**
+ * @class CommandBase
+ * Base class for all commands.
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandBase {
+protected:
+       SIM_COMMAND command;
+public:
+       /**
+        * TODO: remove sessionID, this is redundant but session = 0 is
+        * used for commands which do not use session id, like CREATE and DESTROY
+        * Use a special slot for them
+        *
+        */
+       uint32_t sessionID;
+private:
+       /**
+        * The Trusted Application instance can register a session data pointer by
+        * setting *sessionContext. The value of this pointer is not interpreted by
+        * the Framework, and is simply passed back to other TA_ functions within
+        * this session. Note that *sessionContext may be set with a pointer to a
+        * memory allocated by the Trusted Application instance or with anything
+        * else, such as an integer, a handle, etc. The Framework will not automatically
+        * free *sessionContext when the session is closed; the Trusted Application
+        * instance is responsible for freeing memory if required.
+        *
+        */
+       static unsigned int sessionContextContainer;
+public:
+       CommandBase(SIM_COMMAND acommand);
+       virtual std::string getCommandUID() const = 0;
+       virtual TEE_Result execute() = 0;
+       virtual void getSerializedData(unsigned char *data, unsigned int &size) = 0;
+       virtual ~CommandBase();
+       virtual bool isCancelCommand() const;
+       SIM_COMMAND getCommandID() const;
+       /**
+        * sessionContext: A pointer to a variable that can be filled by the
+        * Trusted Application instance with an opaque void* data pointer
+        */
+       static void *sessionContext;
+};
+typedef boost::shared_ptr<CommandBase> CommandBasePtr;
+typedef std::string CommandUID;
+
+#endif /* BASECOMMAND_H_ */
diff --git a/TEEStub/TACommands/CommandCloseSession.cpp b/TEEStub/TACommands/CommandCloseSession.cpp
new file mode 100755 (executable)
index 0000000..5f9cf27
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCloseSession.cpp
+ *
+ *    Description:  CommandCloseSession class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandCloseSession.h"
+#include <sstream>
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Constructor
+ * @param data[in] Initialization data
+ */
+CommandCloseSession::CommandCloseSession(CloseTASessionData data) :
+               CommandBase(CLOSESESSION) {
+       this->data = data;
+       sessionID = data.sessionID;
+}
+
+/**
+ * Executes command close session
+ * @return TEE_SUCCESS
+ */
+TEE_Result CommandCloseSession::execute() {
+       TOGGLE_PROPERTY_ACCESS;
+       TA_CloseSessionEntryPoint(&sessionContext);
+       LOGD(TEE_STUB, "TA_CloseSessionEntryPoint done");
+       TOGGLE_PROPERTY_ACCESS;
+       return TEE_SUCCESS;
+}
+
+/**
+ * Returns this command's UID in the format "sessionID:commandID".
+ * If commandID is not relevant for this command, it is set to 0.
+ * For create and destroy commands, it is "0:0". SessionID 0 is reserved.
+ * @return this command's UID
+ */
+std::string CommandCloseSession::getCommandUID() const {
+       std::stringstream ss;
+       ss << data.sessionID;
+       ss << ":";
+       ss << "0";
+       return ss.str();
+}
+
+/**
+ * Destructor
+ */
+CommandCloseSession::~CommandCloseSession() {
+}
+
+/**
+ * Serializes this object data of  CommandCloseSession
+ * @param data[out] serialized object data
+ * @param size[out] size in bytes
+ */
+void CommandCloseSession::getSerializedData(unsigned char *data,
+    unsigned int &size) {
+       data[0] = command;
+       memcpy(&data[1], (unsigned char*)&this->data, sizeof(CloseTASessionData));
+       size = sizeof(CloseTASessionData);
+}
diff --git a/TEEStub/TACommands/CommandCloseSession.h b/TEEStub/TACommands/CommandCloseSession.h
new file mode 100755 (executable)
index 0000000..a8d9186
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCloseSession.h
+ *
+ *    Description:  CommandCloseSession header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDCLOSESESSION_H_
+#define COMMANDCLOSESESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class CommandCloseSession
+ * Implements command to close a session
+ */
+class CommandCloseSession:
+    public CommandBase {
+public:
+       CloseTASessionData data;
+       void getSerializedData(unsigned char *data, unsigned int &size);
+       CommandCloseSession(CloseTASessionData data);
+       TEE_Result execute();
+       std::string getCommandUID() const;
+       virtual ~CommandCloseSession();
+};
+
+#endif /* COMMANDCLOSESESSION_H_ */
diff --git a/TEEStub/TACommands/CommandCreateEntryPoint.cpp b/TEEStub/TACommands/CommandCreateEntryPoint.cpp
new file mode 100755 (executable)
index 0000000..a411a93
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCreateEntryPoint.cpp
+ *
+ *    Description:  CommandCreateEntryPoint class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandCreateEntryPoint.h"
+#include <sstream>
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+CommandCreateEntryPoint::CommandCreateEntryPoint(CreateTAEntryPointData data) :
+               CommandBase(CREATE) {
+       this->data = data;
+       sessionID = data.sessionID;
+}
+
+/**
+ * Execute this command by calling TA_CreateEntryPoint
+ * @return return value from TA_CreateEntryPoint
+ */
+TEE_Result CommandCreateEntryPoint::execute() {
+       data.returnValue = TA_CreateEntryPoint();
+       LOGD(TEE_STUB, "TA_CreateEntryPoint done");
+       return data.returnValue;
+}
+
+/**
+ * Returns this command's UID in the format "sessionID:commandID".
+ * If commandID is not relevant for this command, it is set to 0.
+ * For create and destroy commands, it is "0:0". SessionID 0 is reserved.
+ * @return this command's UID
+ */
+std::string CommandCreateEntryPoint::getCommandUID() const {
+       std::stringstream ss;
+       ss << "0";
+       ss << ":";
+       ss << "0";
+       return ss.str();
+}
+
+CommandCreateEntryPoint::~CommandCreateEntryPoint() {
+}
+
+/**
+ * Serializes this object data of  CommandCreateEntryPoint
+ * @param data[out] serialized object data
+ * @param size[out] size in bytes
+ */
+void CommandCreateEntryPoint::getSerializedData(unsigned char *data,
+    unsigned int &size) {
+       data[0] = command;
+       memcpy(&data[1], (unsigned char*)&this->data, sizeof(CreateTAEntryPointData));
+       size = sizeof(CreateTAEntryPointData);
+}
diff --git a/TEEStub/TACommands/CommandCreateEntryPoint.h b/TEEStub/TACommands/CommandCreateEntryPoint.h
new file mode 100755 (executable)
index 0000000..e1ae0b0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCreateEntryPoint.h
+ *
+ *    Description:  CommandCreateEntryPoint header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef COMMANDCREATEENTRYPOINT_H_
+#define COMMANDCREATEENTRYPOINT_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+#include "tee_sim_command.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class CommandCreateEntryPoint
+ * Implements command to call TA_CreateEntryPoint() of TA
+ */
+class CommandCreateEntryPoint:
+    public CommandBase {
+public:
+       CreateTAEntryPointData data;
+       TEE_Result execute();
+       std::string getCommandUID() const;
+       void getSerializedData(unsigned char *data, unsigned int &size);
+       CommandCreateEntryPoint(CreateTAEntryPointData data);
+       virtual ~CommandCreateEntryPoint();
+};
+
+#endif /* COMMANDCREATEENTRYPOINT_H_ */
diff --git a/TEEStub/TACommands/CommandDestroyEntryPoint.cpp b/TEEStub/TACommands/CommandDestroyEntryPoint.cpp
new file mode 100755 (executable)
index 0000000..998ff32
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandDestroyEntryPoint.cpp
+ *
+ *    Description:  CommandDestroyEntryPoint class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandDestroyEntryPoint.h"
+#include <sstream>
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+CommandDestroyEntryPoint::CommandDestroyEntryPoint(DestroyTAEntryPointData data) :
+               CommandBase(DESTROY) {
+       this->data = data;
+       sessionID = data.sessionID;
+}
+
+//TODO: Handle exit of TA instance in a clean way
+/**
+ * Execute this command by calling TA_DestroyEntryPoint
+ * @return Does not return, directly exits this TA instance.
+ */
+TEE_Result CommandDestroyEntryPoint::execute() {
+       TA_DestroyEntryPoint();
+       LOGD(TEE_STUB, "TA_DestroyEntryPoint done");
+       exit(0);
+       return TEE_SUCCESS;
+}
+
+/**
+ * Returns this command's UID in the format "sessionID:commandID".
+ * If commandID is not relevant for this command, it is set to 0.
+ * For create and destroy commands, it is "0:0". SessionID 0 is reserved.
+ * @return this command's UID
+ */
+std::string CommandDestroyEntryPoint::getCommandUID() const {
+       std::stringstream ss;
+       ss << "0";
+       ss << ":";
+       ss << "0";
+       return ss.str();
+}
+
+CommandDestroyEntryPoint::~CommandDestroyEntryPoint() {
+}
+
+/**
+ * Serializes this object data of  CommandDestroyEntryPoint
+ * @param data[out] serialized object data
+ * @param size[out] size in bytes
+ */
+void CommandDestroyEntryPoint::getSerializedData(unsigned char *data,
+    unsigned int &size) {
+       data[0] = command;
+       memcpy(&data[1], (unsigned char*)&this->data,
+           sizeof(DestroyTAEntryPointData));
+       size = sizeof(DestroyTAEntryPointData);
+}
diff --git a/TEEStub/TACommands/CommandDestroyEntryPoint.h b/TEEStub/TACommands/CommandDestroyEntryPoint.h
new file mode 100755 (executable)
index 0000000..5f1d48a
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandDestroyEntryPoint.h
+ *
+ *    Description:  CommandDestroyEntryPoint header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef COMMANDDESTROYENTRYPOINT_H_
+#define COMMANDDESTROYENTRYPOINT_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class CommandDestroyEntryPoint
+ * Implements command to call TA_DestroyEntryPoint() of TA
+ */
+class CommandDestroyEntryPoint:
+    public CommandBase {
+public:
+       TEE_Result execute();
+       DestroyTAEntryPointData data;
+       void getSerializedData(unsigned char *data, unsigned int &size);
+       std::string getCommandUID() const;
+       CommandDestroyEntryPoint(DestroyTAEntryPointData data);
+       virtual ~CommandDestroyEntryPoint();
+};
+
+#endif /* COMMANDDESTROYENTRYPOINT_H_ */
diff --git a/TEEStub/TACommands/CommandInvoke.cpp b/TEEStub/TACommands/CommandInvoke.cpp
new file mode 100755 (executable)
index 0000000..86a22cb
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOperation.cpp
+ *
+ *    Description:  CommandOperation class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandInvoke.h"
+#include "SharedMemoryMap.h"
+#include <sstream>
+#include <stdio.h>
+#include <sys/shm.h>
+#include <iostream>
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define PAGE_SIZE               0x1000
+#define PAGE_MASK               (~(PAGE_SIZE - 1))
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+CommandInvoke::CommandInvoke(InvokeTACommandData data) :
+               CommandBase(INVOKECOMMAND) {
+       this->data = data;
+       sessionID = data.sessionID;
+}
+
+/**
+ * Execute command by calling TA_InvokeCommandEntryPoint()
+ * @return return value from TA_InvokeCommandEntryPoint() or TEE_ERROR_OUT_OF_MEMORY
+ * when shared memory cannot be allocated.
+ */
+TEE_Result CommandInvoke::execute() {
+       bool sharedResult = true;
+
+       TOGGLE_PROPERTY_ACCESS;
+       sharedResult = SharedMemoryMap::allocateSharedMemory(data.op);
+       if (sharedResult) {
+               data.returnValue = TA_InvokeCommandEntryPoint(&sessionContext,
+                   data.commandID, data.op.paramTypes, data.op.params);
+               LOGD(TEE_STUB, "TA_InvokeCommandEntryPoint done");
+       } else {
+               data.returnOrigin = TEE_ORIGIN_TRUSTED_APP;
+               data.returnValue = TEE_ERROR_OUT_OF_MEMORY;
+       }
+       sharedResult = SharedMemoryMap::deleteSharedMemory(data.op);
+       if (!sharedResult) {
+               data.returnOrigin = TEE_ORIGIN_TRUSTED_APP;
+               data.returnValue = TEE_ERROR_OUT_OF_MEMORY;
+       }
+
+       TOGGLE_PROPERTY_ACCESS;
+       return data.returnValue;
+}
+
+/**
+ * Returns this command's UID in the format "sessionID:commandID".
+ * If commandID is not relevant for this command, it is set to 0.
+ * For create and destroy commands, it is "0:0". SessionID 0 is reserved.
+ * @return this command's UID
+ */
+std::string CommandInvoke::getCommandUID() const {
+       std::stringstream ss;
+       ss << data.sessionID;
+       ss << ":";
+       ss << data.op.operationID;
+       return ss.str();
+}
+
+CommandInvoke::~CommandInvoke() {
+}
+
+/**
+ * Serializes this object data of  CommandInvoke
+ * @param data[out] serialized object data
+ * @param size[out] size in bytes
+ */
+void CommandInvoke::getSerializedData(unsigned char *data, unsigned int &size) {
+       data[0] = command;
+       memcpy(&data[1], (unsigned char*)&this->data, sizeof(InvokeTACommandData));
+       size = sizeof(InvokeTACommandData);
+}
diff --git a/TEEStub/TACommands/CommandInvoke.h b/TEEStub/TACommands/CommandInvoke.h
new file mode 100755 (executable)
index 0000000..29d0a01
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOperation.h
+ *
+ *    Description:  CommandOperation header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef COMMANDOPERATION_H_
+#define COMMANDOPERATION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class CommandInvoke
+ * Implements command to call TA_InvokeCommandEntryPoint() of TA
+ */
+class CommandInvoke:
+    public CommandBase {
+public:
+       InvokeTACommandData data;
+       CommandInvoke(InvokeTACommandData data);
+       TEE_Result execute();
+       std::string getCommandUID() const;
+       void getSerializedData(unsigned char *data, unsigned int &size);
+       virtual ~CommandInvoke();
+};
+
+#endif /* COMMANDOPERATION_H_ */
diff --git a/TEEStub/TACommands/CommandOpenSession.cpp b/TEEStub/TACommands/CommandOpenSession.cpp
new file mode 100755 (executable)
index 0000000..468066e
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOpenSession.cpp
+ *
+ *    Description:  CommandOpenSession class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandOpenSession.h"
+#include "SharedMemoryMap.h"
+#include <stdio.h>
+#include <sstream>
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+CommandOpenSession::CommandOpenSession(OpenTASessionData data) :
+               CommandBase(OPENSESSION) {
+       this->data = data;
+       sessionID = data.sessionID;
+}
+
+CommandOpenSession::~CommandOpenSession() {
+}
+
+/**
+ * Calls API TA_OpenSessionEntryPoint
+ * @return result returned from TA_OpenSessionEntryPoint
+ */
+TEE_Result CommandOpenSession::execute() {
+       // If param. type is of memory reference type then allocate shared memory
+       bool sharedResult = true;
+       TOGGLE_PROPERTY_ACCESS;
+       sharedResult = SharedMemoryMap::allocateSharedMemory(data.op);
+       if (sharedResult) {
+               data.returnValue = TA_OpenSessionEntryPoint(data.op.paramTypes,
+                   data.op.params, &sessionContext);
+               LOGD(TEE_STUB, "TA_OpenSessionEntryPoint done");
+       } else {
+               data.returnOrigin = TEE_ORIGIN_TRUSTED_APP;
+               data.returnValue = TEE_ERROR_OUT_OF_MEMORY;
+       }
+       sharedResult = SharedMemoryMap::deleteSharedMemory(data.op);
+       if (!sharedResult) {
+               data.returnOrigin = TEE_ORIGIN_TRUSTED_APP;
+               data.returnValue = TEE_ERROR_OUT_OF_MEMORY;
+       }
+       TOGGLE_PROPERTY_ACCESS;
+       return data.returnValue;
+}
+
+/**
+ * Returns this command's UID in the format "sessionID:commandID".
+ * If commandID is not relevant for this command, it is set to 0.
+ * For create and destroy commands, it is "0:0". SessionID 0 is reserved.
+ * @return this command's UID
+ */
+std::string CommandOpenSession::getCommandUID() const {
+       std::stringstream ss;
+       ss << data.sessionID;
+       ss << ":";
+       ss << data.op.operationID;
+       return ss.str();
+}
+
+/**
+ * Serializes this object data of  CommandOpenSession
+ * @param data[out] serialized object data
+ * @param size[out] size in bytes
+ */
+void CommandOpenSession::getSerializedData(unsigned char *data,
+    unsigned int &size) {
+       data[0] = command;
+       memcpy(&data[1], (unsigned char*)&this->data, sizeof(OpenTASessionData));
+       size = sizeof(OpenTASessionData);
+}
diff --git a/TEEStub/TACommands/CommandOpenSession.h b/TEEStub/TACommands/CommandOpenSession.h
new file mode 100755 (executable)
index 0000000..0ff0cd0
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOpenSession.h
+ *
+ *    Description:  CommandOpenSession header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef COMMANDOPENSESSION_H_
+#define COMMANDOPENSESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class CommandOpenSession
+ * Implements command to call TA_OpenSessionEntryPoint() of TA
+ */
+class CommandOpenSession:
+    public CommandBase {
+public:
+       OpenTASessionData data;
+       CommandOpenSession(OpenTASessionData data);
+       virtual ~CommandOpenSession();
+       TEE_Result execute();
+       std::string getCommandUID() const;
+       void getSerializedData(unsigned char *data, unsigned int &size);
+};
+
+#endif /* COMMANDOPENSESSION_H_ */
diff --git a/TEEStub/TACommands/CommandRequestCancel.cpp b/TEEStub/TACommands/CommandRequestCancel.cpp
new file mode 100755 (executable)
index 0000000..63291a4
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandRequestCancel.cpp
+ *
+ *    Description:  CommandRequestCancel class
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <TACommands/CommandRequestCancel.h>
+#include <sstream>
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+//Cancellation vector which holds the cancellation requests
+std::vector<CommandRequestCancelPtr> CommandRequestCancel::cancelVector;
+boost::mutex CommandRequestCancel::vectorMutex;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Constructor
+ * @param data
+ */
+CommandRequestCancel::CommandRequestCancel(RequestTACancelData data) :
+               CommandBase(REQCANCEL) {
+       this->data = data;
+       sessionID = data.sessionID;
+}
+
+/**
+ * Adds this request of cancellation of a command to cancellation vector.
+ * @return TEE_SUCCESS
+ */
+TEE_Result CommandRequestCancel::execute() {
+       // Set return values
+       data.returnValue = TEE_ERROR_CANCEL;
+       data.returnOrigin = TEE_ORIGIN_TEE;
+       // Push the cancel request into cancellation vector
+       vectorMutex.lock();
+       cancelVector.push_back(shared_from_this());
+       vectorMutex.unlock();
+       return TEE_SUCCESS;
+}
+
+CommandRequestCancel::~CommandRequestCancel() {
+}
+
+/**
+ * Serializes this object data of CommandRequestCancel
+ * @param data[out] serialized object data
+ * @param size[out] size in bytes
+ */
+void CommandRequestCancel::getSerializedData(unsigned char *data,
+    unsigned int &size) {
+       data[0] = command;
+       memcpy(&data[1], (unsigned char*)&this->data, sizeof(RequestTACancelData));
+       size = sizeof(RequestTACancelData);
+}
+
+/**
+ * Returns UID of command to be cancelled in the format "sessionID:commandID".
+ * @return this command's UID
+ */
+std::string CommandRequestCancel::getCommandUID() const {
+       std::stringstream ss;
+       ss << data.sessionID;
+       ss << ":";
+       ss << data.operationID;
+       return ss.str();
+}
+
+/**
+ * Checks if a given task identified by sessionID and operationID.
+ * When a given task is found, it is removed from cancellation vector.
+ * @param sessionID Session ID
+ * @param operationID Operation ID
+ * @return shared_ptr to CommandRequestCancelPtr
+ */
+CommandRequestCancelPtr CommandRequestCancel::isCancelled(CommandUID uid) {
+       bool found = false;
+       CommandRequestCancelPtr ptr; // Uninitialized shared pointer
+       std::vector<CommandRequestCancelPtr>::iterator itr;
+       vectorMutex.lock();
+       for (itr = cancelVector.begin(); cancelVector.end() != itr; itr++) {
+               if (itr->get()->getCommandUID() == uid) {
+                       found = true;
+                       break;
+               }
+       }
+       vectorMutex.unlock();
+       if (found) {
+               ptr = *itr;
+               // If cancellation request has come then remove the entry from vector
+               cancelVector.erase(itr);
+       }
+       return ptr;
+}
diff --git a/TEEStub/TACommands/CommandRequestCancel.h b/TEEStub/TACommands/CommandRequestCancel.h
new file mode 100755 (executable)
index 0000000..797911e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandRequestCancel.h
+ *
+ *    Description:  CommandRequestCancel header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TACOMMANDS_COMMANDREQUESTCANCEL_H_
+#define TACOMMANDS_COMMANDREQUESTCANCEL_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <TACommands/CommandBase.h>
+#include <vector>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandRequestCancel;
+typedef boost::shared_ptr<CommandRequestCancel> CommandRequestCancelPtr;
+
+/**
+ * @class CommandRequestCancel
+ * Implements command to cancel pending TA entry points in the task execution queue
+ * (Open session and invoke command only) OR set cancellation flag for running task.
+ * This is the only class to override function "isCancelCommand" which returns true.
+ */
+class CommandRequestCancel:
+    public CommandBase, public boost::enable_shared_from_this<
+        CommandRequestCancel> {
+private:
+       static std::vector<CommandRequestCancelPtr> cancelVector;
+       static boost::mutex vectorMutex;
+public:
+       RequestTACancelData data;
+       CommandRequestCancel(RequestTACancelData data);
+       TEE_Result execute();
+       std::string getCommandUID() const;
+       void getSerializedData(unsigned char *data, unsigned int &size);
+       virtual ~CommandRequestCancel();
+public:
+       static CommandRequestCancelPtr isCancelled(CommandUID);
+       bool isCancelCommand() const {
+               return true;
+       }
+};
+
+#endif /* TACOMMANDS_COMMANDREQUESTCANCEL_H_ */
diff --git a/TEEStub/TACommands/MakeCommand.cpp b/TEEStub/TACommands/MakeCommand.cpp
new file mode 100755 (executable)
index 0000000..e206c36
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  MakeCommand.cpp
+ *
+ *    Description:  MakeCommand class
+ *
+ *        Version:  1.0
+ *        Created:  14 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "MakeCommand.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Creates a command object based on the type of command passed in
+ * @param command name of command from enum SIM_COMMAND
+ * @param data pointer to structure defining the command in SIM_COMMAND
+ */
+CommandBasePtr MakeCommand::getCommand(SIM_COMMAND simcommand, void* simdata) {
+
+       CommandBasePtr command;
+       switch (simcommand) {
+               case CREATE: {
+                       CreateTAEntryPointData data;
+                       data = *(reinterpret_cast<CreateTAEntryPointData*>(simdata));
+                       command = CommandBasePtr(new CommandCreateEntryPoint(data));
+                       break;
+               }
+               case OPENSESSION: {
+                       OpenTASessionData data;
+                       data = *(reinterpret_cast<OpenTASessionData*>(simdata));
+                       command = CommandBasePtr(new CommandOpenSession(data));
+                       break;
+               }
+               case INVOKECOMMAND: {
+                       InvokeTACommandData data;
+                       data = *(reinterpret_cast<InvokeTACommandData*>(simdata));
+                       command = CommandBasePtr(new CommandInvoke(data));
+                       break;
+               }
+               case CLOSESESSION: {
+                       CloseTASessionData data;
+                       data = *(reinterpret_cast<CloseTASessionData*>(simdata));
+                       command = CommandBasePtr(new CommandCloseSession(data));
+                       break;
+               }
+               case DESTROY: {
+                       DestroyTAEntryPointData data;
+                       data = *(reinterpret_cast<DestroyTAEntryPointData*>(simdata));
+                       command = CommandBasePtr(new CommandDestroyEntryPoint(data));
+                       break;
+               }
+               case REQCANCEL: {
+                       RequestTACancelData data;
+                       data = *(reinterpret_cast<RequestTACancelData*>(simdata));
+                       command = CommandBasePtr(new CommandRequestCancel(data));
+                       break;
+               }
+               default: {
+                       command.reset();
+                       break;
+               }
+       }
+       return command;
+}
+
+MakeCommand::~MakeCommand() {
+
+}
+
+/**
+ * Calculates size of payload expected based on command received
+ * @param command SIM_COMMAND to be executed on TA
+ * @return size of payload in bytes based on command.
+ * A return size of zero means invalid command. For a valid command
+ * return size will always be positive integer.
+ *
+ */
+int MakeCommand::getCommandPayloadSize(SIM_COMMAND command) {
+
+       int size = -1;
+       switch (command) {
+               case CREATE:
+                       size = sizeof(CreateTAEntryPointData);
+                       break;
+               case OPENSESSION:
+                       size = sizeof(OpenTASessionData);
+                       break;
+               case INVOKECOMMAND:
+                       size = sizeof(InvokeTACommandData);
+                       break;
+               case CLOSESESSION:
+                       size = sizeof(CloseTASessionData);
+                       break;
+               case DESTROY:
+                       size = sizeof(DestroyTAEntryPointData);
+                       break;
+               case REQCANCEL:
+                       size = sizeof(RequestTACancelData);
+                       break;
+               default:
+                       size = -1;
+                       break;
+       }
+       return size;
+}
diff --git a/TEEStub/TACommands/MakeCommand.h b/TEEStub/TACommands/MakeCommand.h
new file mode 100755 (executable)
index 0000000..ce735dd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  MakeCommand.h
+ *
+ *    Description:  MakeCommand header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef MAKECOMMAND_H_
+#define MAKECOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandCloseSession.h"
+#include "CommandCreateEntryPoint.h"
+#include "CommandDestroyEntryPoint.h"
+#include "CommandInvoke.h"
+#include "CommandOpenSession.h"
+#include "CommandRequestCancel.h"
+#include "tee_sim_command.h"
+#include "boost/shared_ptr.hpp"
+#include <vector>
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class MakeCommand
+ * Creates instances of all available commands based on parsing of socket stream
+ * done by TaskQueuedStrategy. Commands are sent by Simulator daemon.
+ * This class just creates instances of commands and does not parse socket stream.
+ */
+class MakeCommand {
+private:
+       MakeCommand();
+public:
+       static CommandBasePtr getCommand(SIM_COMMAND command, void* data);
+       static int getCommandPayloadSize(SIM_COMMAND command);
+       virtual ~MakeCommand();
+};
+
+#endif /* MAKECOMMAND_H_ */
diff --git a/TEEStub/TACommands/SharedMemoryMap.cpp b/TEEStub/TACommands/SharedMemoryMap.cpp
new file mode 100755 (executable)
index 0000000..0122085
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SharedMemoryMap.cpp
+ *
+ *    Description:  SharedMemoryMap class
+ *
+ *        Version:  1.0
+ *        Created:  28 May 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "SharedMemoryMap.h"
+#include <sys/shm.h>
+#include <iostream>
+#include <string.h>
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define PAGE_SIZE               0x1000
+#define PAGE_MASK               (~(PAGE_SIZE - 1))
+
+map<uint32_t, void*> SharedMemoryMap::shmMap;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Adds a key to a map
+ * @param key[in] Shared memory key
+ * @param pBuffer[in] Pointer to shared memory
+ */
+void SharedMemoryMap::addToMap(const uint32_t key, void* pBuffer) {
+       shmMap[key] = pBuffer;
+}
+
+/**
+ * Deletes a key from map thereby detaching shared memory.
+ * @param key Shared memory key to be deleted
+ * @return true if successfully detached else false.
+ */
+bool SharedMemoryMap::deleteFromMap(uint32_t key) {
+       map<uint32_t, void*>::iterator it = shmMap.find(key);
+       if (it != shmMap.end()) {
+               if (-1 != shmdt(it->second)) {
+                       shmMap.erase(it);
+                       return true;
+               } else return false;
+       }
+       return false;
+}
+
+/**
+ * Allocates shared memory from a pre-shared key
+ * @param op Operation values which contain param types and params.
+ * @return true if shared memory was successfully created else false.
+ */
+bool SharedMemoryMap::allocateSharedMemory(Operation &op) {
+       bool sharedResult = true;
+       for (int i = 0; i < 4; i++) {
+               uint32_t type = ((op.paramTypes) >> (8 * i)) & 0x7f;
+               // If not of value type, then has to be of memory reference type.
+               if ((type != TEE_PARAM_TYPE_VALUE_INPUT)
+                   && (type != TEE_PARAM_TYPE_VALUE_OUTPUT)
+                   && (type != TEE_PARAM_TYPE_VALUE_INOUT)
+                   && (type != TEE_PARAM_TYPE_NONE)) {
+                       uint32_t size = op.params[i].memref.size;
+                       uint32_t shmid = shmget(op.shmID[i], size, 0666);
+
+                       //LOGD(TEE_STUB, "SHM KEY: %d SHM ID: %d", op.shmID[i], shmid);
+                       /* Allocate page aligned buffer */
+                       if (size < PAGE_SIZE) {
+                               size = PAGE_SIZE;
+                       } else if (size & (PAGE_SIZE - 1)) {
+                               size = (size & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
+                       }
+                       size = (size + (PAGE_SIZE - 1)) & PAGE_MASK;
+                       op.params[i].memref.buffer = (void*)shmat(shmid, NULL, 0);
+                       if (op.params[i].memref.buffer == (void*)-1) {
+                               LOGE(TEE_STUB, "shmat failed");
+                               sharedResult = false;
+                       }
+                       if (!op.params[i].memref.buffer) {
+                               LOGE(TEE_STUB, "allocate failed");
+                               sharedResult = false;
+                       }
+                       //memset(op.params[i].memref.buffer, 0x00, size);
+
+                       // Add shared memory allocated to shared memory map so that
+                       // it can be detached on closing the sessions or exiting the TA
+                       SharedMemoryMap::addToMap(op.shmID[i], op.params[i].memref.buffer);
+               }
+       }
+       return sharedResult;
+}
+
+/**
+ * De-allocates shared memory from a pre-shared key
+ * @param op Operation values which contain param types and params.
+ * @return true if shared memory was successfully created else false.
+ */
+bool SharedMemoryMap::deleteSharedMemory(Operation &op) {
+       bool sharedResult = true;
+       for (int i = 0; i < 4; i++) {
+               uint32_t type = ((op.paramTypes) >> (8 * i)) & 0x7f;
+               // If not of value type, then has to be of memory reference type.
+               if ((type != TEE_PARAM_TYPE_VALUE_INPUT)
+                   && (type != TEE_PARAM_TYPE_VALUE_OUTPUT)
+                   && (type != TEE_PARAM_TYPE_VALUE_INOUT)
+                   && (type != TEE_PARAM_TYPE_NONE)) {
+                       if (!op.params[i].memref.buffer) {
+                               LOGE(TEE_STUB, "de-allocate failed");
+                               sharedResult = false;
+                       }
+                       // Add shared memory allocated to shared memory map so that
+                       // it can be detached on closing the sessions or exiting the TA
+                       SharedMemoryMap::deleteFromMap(op.shmID[i]);
+               }
+       }
+       return sharedResult;
+}
+
+/**
+ * Deletes all allocated shared memory for this TA
+ * @return true if all shared memories allocated were successfully
+ * deleted, else false.
+ */
+bool SharedMemoryMap::deleteAllSharedMemory() {
+       bool sharedResult = true;
+       for (map<uint32_t, void*>::iterator it = shmMap.begin(); it != shmMap.end();
+           it++) {
+               if (-1 == shmdt(it->second)) {
+                       sharedResult = false;
+               }
+       }
+       return sharedResult;
+}
+
+bool deleteAllSharedMemory() {
+       return SharedMemoryMap::deleteAllSharedMemory();
+}
+
+bool allocateSharedMemory(Operation &op) {
+       return SharedMemoryMap::allocateSharedMemory(op);
+}
+
+bool deleteSharedMemory(Operation &op) {
+       return SharedMemoryMap::deleteSharedMemory(op);
+}
diff --git a/TEEStub/TACommands/SharedMemoryMap.h b/TEEStub/TACommands/SharedMemoryMap.h
new file mode 100755 (executable)
index 0000000..098768f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SharedMemoryMap.h
+ *
+ *    Description:  SharedMemoryMap header file
+ *
+ *        Version:  1.0
+ *        Created:  28 May 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TACOMMANDS_SHAREDMEMORYMAP_H_
+#define TACOMMANDS_SHAREDMEMORYMAP_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <map>
+#include "log.h"
+#include "tee_internal_api.h"
+#include "tee_sim_command.h"
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * SharedMemoryMap class provides API to allocate and attach to shared
+ * memory and detach them finally during cleanup of TA.
+ * Here shared memory key is expected from Simulator daemon.
+ *
+ * This is a no instance class with static methods.
+ */
+class SharedMemoryMap {
+private:
+       // map <shared memory key, shared memory buffer pointer>
+       static map<uint32_t, void*> shmMap;
+       static void addToMap(const uint32_t key, void* shmid);
+       static bool deleteFromMap(uint32_t key);
+public:
+       static bool allocateSharedMemory(Operation &op);
+       static bool deleteSharedMemory(Operation &op);
+       static bool deleteAllSharedMemory();
+};
+
+extern "C" {
+bool allocateSharedMemory(Operation &op);
+bool deleteSharedMemory(Operation &op);
+bool deleteAllSharedMemory();
+}
+
+#endif /* TACOMMANDS_SHAREDMEMORYMAP_H_ */
diff --git a/TEEStub/TEEStubServer/ConnectionSession.cpp b/TEEStub/TEEStubServer/ConnectionSession.cpp
new file mode 100755 (executable)
index 0000000..ca7d3cb
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ConnectionSession.cpp
+ *
+ *    Description:  ConnectionSession class
+ *
+ *        Version:  1.0
+ *        Created:  09 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ConnectionSession.h"
+#include "TaskStrategy/TaskStrategy.h"
+#include "TaskStrategy/TaskQueuedStrategy.h"
+#include "TACommands/MakeCommand.h"
+#include <iostream>
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * On starting the server and accepting a connection, read some data from the socket.
+ */
+void ConnectionSession::start() {
+       taskThread = new TaskQueuedStrategy(socket());
+       taskThread->startThread();
+       // read exactly 1 byte to identify the command and execute callback when
+       // command is received
+       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+           boost::asio::transfer_exactly(1),
+           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+               boost::asio::placeholders::error,
+               boost::asio::placeholders::bytes_transferred));
+}
+
+/**
+ * On asynchronously reading from socket, this call back is executed.
+ * @param error[in] Boost error code and error message object
+ * @param bytes_transferred[in] Number of bytes read from the socket
+ */
+void ConnectionSession::handleRead(const boost::system::error_code& error,
+    size_t bytes_transferred) {
+
+       typedef enum {
+               READ_PAYLOAD, PAYLOAD_COMPLETE,
+       } states;
+       static states currentState = READ_PAYLOAD;
+       LOGD(TEE_STUB, "Entry");
+       if (!error) {
+               /**
+                * A simple small state machine to parse command and handle its
+                * call back to TA interface
+                * The state machine identifies the command. If valid, finds out how
+                * many bytes of payload to be read further else if invalid, exits the stub.
+                *
+                * Later, exact number of identified size of payload is read from
+                * stream and stored. Task strategy is invoked with the command and payload.
+                */
+               switch (currentState) {
+                       case READ_PAYLOAD: {
+                               // Identify command
+                               command = (SIM_COMMAND)clientData.at(0);
+                               LOGD(TEE_STUB, "Command received: %d", (int )command);
+
+                               // Calculate pending numbers of bytes pending to be read only for commands
+                               // OPENSESSION, INVOKECOMMAND, CLOSESESSION
+                               int payload_size = MakeCommand::getCommandPayloadSize(command);
+
+                               if (payload_size > 0) {
+                                       currentState = PAYLOAD_COMPLETE;
+                                       // read remaining bytes related to received valid command
+                                       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+                                           boost::asio::transfer_exactly(payload_size),
+                                           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+                               else if (-1 == payload_size) {
+                                       // else case is invalid command
+                                       // TODO: Identify the correct behaviour; what to do when invalid command is received?
+                                       LOGE(TEE_STUB, "Invalid command received!");
+                               } else if (0 == payload_size) {
+                                       // Call the TaskStrategy object to handle commands
+                                       taskThread->handleCommand(MakeCommand::getCommand(command, (void*)0));
+
+                                       // reset state to read new command
+                                       currentState = READ_PAYLOAD;
+                                       // read command and register callback to read payload
+                                       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+                                           boost::asio::transfer_exactly(1),
+                                           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+                               break;
+                       } //case
+                       case PAYLOAD_COMPLETE: {
+                               // At this point payload is completely read
+                               // clear the vector for the first time and copy client data received
+                               commandPayload.clear();
+                               for (unsigned int i = 0; i < clientData.size(); i++) {
+                                       commandPayload.push_back(clientData.at(i));
+                               }
+                               string tempData(commandPayload.begin(), commandPayload.end());
+                               // Call the TaskStrategy object to handle commands
+                               taskThread->handleCommand(
+                                   MakeCommand::getCommand(command, (void*)tempData.c_str()));
+                               // reset state to read new command
+                               currentState = READ_PAYLOAD;
+                               if (command != DESTROY) {
+                               // read command and register callback to read payload
+                                       boost::asio::async_read(clientSocket,
+                                               boost::asio::buffer(clientData),
+                                               boost::asio::transfer_exactly(1),
+                                               boost::bind(&ConnectionSession::handleRead,
+                                               shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+                               break;
+                       } //case
+               } //switch
+       }
+       // On error
+       else {
+               LOGE(TEE_STUB, "error code %s", error.category().name());
+               if (boost::asio::error::eof == error.value()) {
+                       LOGE(TEE_STUB, "Simulator daemon is down! Exiting this TA instance.");
+                       taskThread->stopThread();
+               }
+       }
+}
+/**
+ * On asynchronously writing to socket, this call back is executed.
+ * @param error[in] Boost error code and error message object
+ */
+void ConnectionSession::handleWrite(const boost::system::error_code& error) {
+       if (!error) {
+               // Write to socket
+//        clientSocket.async_write_some(boost::asio::buffer(serverData),
+//                boost::bind(&ConnectionSession::handleWrite, shared_from_this(),
+//                        boost::asio::placeholders::error,
+//                        boost::asio::placeholders::bytes_transferred));
+       }
+}
+
+ConnectionSession::~ConnectionSession() {
+       //TODO: Before deleting task strategy object, check how to stop thread and then delete it
+       //delete taskThread;
+}
diff --git a/TEEStub/TEEStubServer/ConnectionSession.h b/TEEStub/TEEStubServer/ConnectionSession.h
new file mode 100755 (executable)
index 0000000..51a75ad
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ConnectionSession.h
+ *
+ *    Description:  ConnectionSession header file
+ *
+ *        Version:  1.0
+ *        Created:  09 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef CONNECTIONSESSION_H_
+#define CONNECTIONSESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <boost/array.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/asio.hpp>
+#include "tee_sim_command.h"
+#include "TaskStrategy/TaskStrategy.h"
+#include <vector>
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+// COMPILE TIME CHECK TO SEE IF UNIX DOMAIN SOCKETS ARE AVAILABLE ON SYSTEM
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+using boost::asio::local::stream_protocol;
+/**
+ * @class ConnectionSession
+ * Represents a socket for a session. USes unix domain sockets from communication
+ */
+class ConnectionSession: public boost::enable_shared_from_this<ConnectionSession>
+{
+public:
+       ConnectionSession(boost::asio::io_service& io_service) :
+       clientSocket(io_service), command((SIM_COMMAND) -1), taskThread(0)
+       {
+       }
+       stream_protocol::socket& socket()
+       {
+               return clientSocket;
+       }
+       void start();
+       void handleRead(const boost::system::error_code& error,
+                       size_t bytes_transferred);
+       void handleWrite(const boost::system::error_code& error);
+       virtual ~ConnectionSession();
+private:
+       // The socket used to communicate with the client.
+       stream_protocol::socket clientSocket;
+       // Buffer used to store data received from the client.
+       boost::array<char, 1024> clientData;
+       vector<char> commandPayload;
+       SIM_COMMAND command;
+       TaskStrategy *taskThread;
+};
+#else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+# error Unix domain/local sockets not available on this platform.
+#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+#endif /* CONNECTIONSESSION_H_ */
+
diff --git a/TEEStub/TEEStubServer/TAProperty.cpp b/TEEStub/TEEStubServer/TAProperty.cpp
new file mode 100755 (executable)
index 0000000..acab173
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ConnectionSession.cpp
+ *
+ *    Description:  ConnectionSession class
+ *
+ *        Version:  1.0
+ *        Created:  09 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TAProperty.h"
+#include <sstream>
+#include <iostream>
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+TAProperty::TAProperty() {
+       singleInstance = false;
+       multipleSession = false;
+       uuid.timeLow = 0x0;
+       uuid.timeMid = 0x0;
+       uuid.timeHiAndVersion = 0x0;
+       uuid.clockSeqAndNode[0] = 0x0;
+       uuid.clockSeqAndNode[1] = 0x0;
+       uuid.clockSeqAndNode[2] = 0x0;
+       uuid.clockSeqAndNode[3] = 0x0;
+       uuid.clockSeqAndNode[4] = 0x0;
+       uuid.clockSeqAndNode[5] = 0x0;
+       uuid.clockSeqAndNode[6] = 0x0;
+       uuid.clockSeqAndNode[7] = 0x0;
+}
+/**
+ * Read TA properties from the TA header
+ */
+void TAProperty::readProperty() {
+       //TODO: Read property from TA
+       // Test Code
+       // Hardcoding the read values
+       // UUID 79B77788-9789-4a7a-A2BE-B60155EEF5F3
+       uuid.timeLow = 0x79b77788;
+       uuid.timeMid = 0x9789;
+       uuid.timeHiAndVersion = 0x4a7a;
+       uuid.clockSeqAndNode[0] = 0xa2;
+       uuid.clockSeqAndNode[1] = 0xbe;
+       uuid.clockSeqAndNode[2] = 0xb6;
+       uuid.clockSeqAndNode[3] = 0x01;
+       uuid.clockSeqAndNode[4] = 0x55;
+       uuid.clockSeqAndNode[5] = 0xee;
+       uuid.clockSeqAndNode[6] = 0xf5;
+       uuid.clockSeqAndNode[7] = 0xf3;
+}
+
+/**
+ * Converts UUID from TEE_UUID to a string
+ * @return string of TEE_UUID
+ */
+string TAProperty::getUUID(void) {
+       // E.g. returns a string in the format 79B77788-9789-4a7a-A2BE-B60155EEF5F3
+       std::stringstream strStream;
+       strStream << IntToHex(uuid.timeLow) << "-";
+       strStream << IntToHex(uuid.timeMid) << "-";
+       strStream << IntToHex(uuid.timeHiAndVersion) << "-";
+       strStream << IntToHex((short)uuid.clockSeqAndNode[0], 2);
+       strStream << IntToHex((short)uuid.clockSeqAndNode[1], 2);
+       strStream << "-";
+       for (int i = 2; i < 8; i++) {
+               strStream << IntToHex((short)uuid.clockSeqAndNode[i], 2);
+       }
+       return strStream.str();
+}
+
+TAProperty::~TAProperty() {
+}
diff --git a/TEEStub/TEEStubServer/TAProperty.h b/TEEStub/TEEStubServer/TAProperty.h
new file mode 100755 (executable)
index 0000000..b9c7e93
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAProperty.h
+ *
+ *    Description:  TAProperty header file
+ *
+ *        Version:  1.0
+ *        Created:  09 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TAPROPERTY_H_
+#define TAPROPERTY_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_internal_api.h"
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class TAProperty {
+private:
+       TEE_UUID uuid;
+       bool singleInstance;
+       bool multipleSession;
+public:
+       TAProperty();
+       void readProperty(void);
+       string getUUID(void);
+       bool isSingleInstance() {
+               return singleInstance;
+       }
+       bool isMultipleSession() {
+               return multipleSession;
+       }
+       virtual ~TAProperty();
+private:
+       template<typename T>
+       std::string IntToHex(T i, int width = sizeof(T) * 2) {
+               std::stringstream stream;
+               stream << std::setfill('0') << std::setw(width) << std::hex << i;
+               return stream.str();
+       }
+};
+
+#endif /* TAPROPERTY_H_ */
diff --git a/TEEStub/TEEStubServer/TEEStubServer.cpp b/TEEStub/TEEStubServer/TEEStubServer.cpp
new file mode 100755 (executable)
index 0000000..8c6ff1a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TEEStubServer.cpp
+ *
+ *    Description:  TEEStubServer class
+ *
+ *        Version:  1.0
+ *        Created:  09 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TEEStubServer.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Accepts a new connection from local machine on a UDS
+ * @param io_service[in] provides OS abstraction for async communication
+ * @param file[in] path to Unix Domain Socket represented by a local file
+ */
+TEEStubServer::TEEStubServer(boost::asio::io_service& io_service,
+    const std::string& file) :
+               mem_io_service(io_service),
+                   acceptor(io_service, stream_protocol::endpoint(file)) {
+       LOGD(TEE_STUB, "Waiting for connection from Simulator daemon");
+       session_ptr new_session(new ConnectionSession(mem_io_service));
+       acceptor.async_accept(new_session->socket(),
+           boost::bind(&TEEStubServer::handleAccept, this, new_session,
+               boost::asio::placeholders::error));
+}
+
+/**
+ * Call back for boost acceptor.async_accept() to handle a new connection
+ * @param new_session[in] a pointer to a session
+ * @param error[in] error code if any occurred
+ */
+void TEEStubServer::handleAccept(session_ptr new_session,
+    const boost::system::error_code& error) {
+       if (!error) {
+               new_session->start();
+       }
+       // Below is test code to handle multiple concurrent connections
+       // Disabled as it is a test feature here
+       //LOGD(TEE_STUB, "Shared ptr ref count (before reset): %d", new_session.use_count());
+       new_session.reset(new ConnectionSession(mem_io_service));
+       //LOGD(TEE_STUB, "Shared ptr ref count (after reset): %d", new_session.use_count());
+       acceptor.async_accept(new_session->socket(),
+           boost::bind(&TEEStubServer::handleAccept, this, new_session,
+               boost::asio::placeholders::error));
+}
diff --git a/TEEStub/TEEStubServer/TEEStubServer.h b/TEEStub/TEEStubServer/TEEStubServer.h
new file mode 100755 (executable)
index 0000000..599633b
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ConnectionSession.h
+ *
+ *    Description:  ConnectionSession header file
+ *
+ *        Version:  1.0
+ *        Created:  09 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TEESTUBSERVER_H_
+#define TEESTUBSERVER_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ConnectionSession.h"
+
+typedef boost::shared_ptr<ConnectionSession> session_ptr;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class TEEStubServer
+ * Starts a server to accept connection from simulator daemon.
+ * Accepts only a single connection.
+ */
+class TEEStubServer {
+public:
+       TEEStubServer(boost::asio::io_service& io_service, const std::string& file);
+       void handleAccept(session_ptr new_session,
+           const boost::system::error_code& error);
+private:
+       boost::asio::io_service& mem_io_service;
+       stream_protocol::acceptor acceptor;
+};
+
+#endif /* TEESTUBSERVER_H_ */
diff --git a/TEEStub/TaskStrategy/SessionState.cpp b/TEEStub/TaskStrategy/SessionState.cpp
new file mode 100755 (executable)
index 0000000..a1fbfd7
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SessionState.cpp
+ *
+ *    Description:  SessionState class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "SessionState.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Constructor of SessionState
+ * @param sID[in] session ID for this SessionState
+ */
+SessionState::SessionState(uint32_t sID) {
+       sessionID = sID;
+}
+
+/**
+ * Ass a task to session task queue
+ * @param command[in] a task to be queued in session
+ */
+void SessionState::addTask(CommandBasePtr command) {
+       queuedTasks.push(command);
+}
+
+/**
+ * Gets next task in queue for this session
+ * @return Task in queue
+ */
+CommandBasePtr SessionState::getNextTask() {
+       if (!queuedTasks.empty()) {
+               CommandBasePtr ptr(queuedTasks.front());
+               queuedTasks.pop();
+               return ptr;
+       } else {
+               CommandBasePtr ptr;
+               return ptr;
+       }
+}
+
+/**
+ * Constructor of SessionState
+ */
+SessionState::SessionState() {
+       sessionID = 0;
+}
+
+/**
+ * Is task queue in this session is empty
+ * @return true if task queue in this session is empty else false
+ */
+bool SessionState::empty() {
+       return queuedTasks.empty();
+}
+
+SessionState::~SessionState() {
+}
diff --git a/TEEStub/TaskStrategy/SessionState.h b/TEEStub/TaskStrategy/SessionState.h
new file mode 100755 (executable)
index 0000000..0ef0694
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SessionState.h
+ *
+ *    Description:  SessionState header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef SESSIONSTATE_H_
+#define SESSIONSTATE_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_sim_command.h"
+#include "TACommands/CommandBase.h"
+#include <queue>
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class SessionState
+ * Represents a set of commands within a session.
+ * This class encapsulates all commands of same session that
+ * are received from CA into a queue. Later this queue is dequeued by
+ * TaskQueuedStrategy to execute the commands.
+ */
+class SessionState {
+private:
+       std::queue<CommandBasePtr> queuedTasks;
+       uint32_t sessionID;
+public:
+       SessionState();
+       SessionState(uint32_t sID);
+       void addTask(CommandBasePtr command);
+       bool empty();
+       CommandBasePtr getNextTask();
+       virtual ~SessionState();
+};
+
+#endif /* SESSIONSTATE_H_ */
diff --git a/TEEStub/TaskStrategy/TaskQueuedStrategy.cpp b/TEEStub/TaskStrategy/TaskQueuedStrategy.cpp
new file mode 100755 (executable)
index 0000000..9587203
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TaskQueuedStrategy.cpp
+ *
+ *    Description:  TaskQueuedStrategy class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TaskQueuedStrategy.h"
+#include <boost/asio.hpp>
+#include "ssf_lib.h"
+#include <string>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Constructor
+ * @param msocket[in] Initializes socket to be used. Used to write back reply.
+ */
+TaskQueuedStrategy::TaskQueuedStrategy(stream_protocol::socket &msocket) :
+               clientSocket(msocket) {
+       runThread = false;
+}
+
+/**
+ * Adds given task (command) to queue based on session ID with which a
+ * command is associated with. Default session ID is 0 for commands
+ * like CreateTA Entry/Destroy Point which do not have session IDs.
+ * @param command[in] task/command to be queued for execution
+ */
+void TaskQueuedStrategy::handleCommand(CommandBasePtr command) {
+       LOGD(TEE_STUB, "Entry");
+       if (command->isCancelCommand()) {
+               LOGD(TEE_STUB, "A Cancel command has been received!");
+               executeCancellation(command);
+       } else {
+               map_mutex.lock();
+               //If new session ID, just add to map
+               if (sessionTaskMap.find(command->sessionID) == sessionTaskMap.end()) {
+                       SessionState ss(command->sessionID);
+                       ss.addTask(command);
+                       sessionTaskMap[command->sessionID] = ss;
+                       LOGD(TEE_STUB, "New Session ID");
+               }
+               // Else, the session ID exists in map, so append to list in session
+               else {
+                       LOGD(TEE_STUB, "Session ID Exists, adding tasks");
+                       sessionTaskMap[command->sessionID].addTask(command);
+               }
+               LOGD(TEE_STUB, "MapSize: %d", sessionTaskMap.size());
+               map_mutex.unlock();
+       }
+}
+
+/**
+ * Sets requested command to be cancelled from task execution queue
+ * @param cancelCommand[in] command to be cancelled
+ */
+void TaskQueuedStrategy::executeCancellation(CommandBasePtr cancelCommand) {
+       // If cancel command is the first command and no history of other commands
+       // exist, just return
+       if (true == !currentCommand) {
+               return;
+       }
+
+       // check if the currently executing task needs to be cancelled.
+       // If so set the shared data flag to communicate that the
+       // current task should be cancelled.
+       //LOGD(TEE_STUB, "Current Command UID: %s", currentCommand->getCommandUID());
+       //LOGD(TEE_STUB, "Cancel Command UID: %s", cancelCommand->getCommandUID());
+       if (currentCommand->getCommandUID() == cancelCommand->getCommandUID()) {
+               LOGD(TEE_STUB, "Cancel command matched with current task");
+               sharedData.thisTaskCancel = true;
+       }
+       // If the task to be cancelled is not the current task
+       // then the task must be in execution queue, yet to be executed.
+       // Just push the request to cancellation vector using
+       // cancel commands execute
+       else {
+               LOGD(TEE_STUB, "Cancel command queued");
+               cancelCommand->execute();
+       }
+}
+
+/**
+ * Execute all tasks inside a session
+ */
+void TaskQueuedStrategy::executeCommands() {
+       LOGD(TEE_STUB, "Entry");
+       /**
+        * Iterate the map for all SessionStates and dequeue all
+        * the Tasks from the queue. Execute the dequeued tasks.
+        */
+       unsigned char writeData[1024];
+       while (runThread) {
+               map_mutex.lock();
+
+               if (sessionTaskMap.size() > 0) {
+                       for (std::map<uint32_t, SessionState>::iterator itr =
+                           sessionTaskMap.begin(); itr != sessionTaskMap.end(); itr++) {
+                               if (!itr->second.empty()) {
+                                       /**
+                                        * Dequeue the entries in task queue
+                                        */
+                                       CommandBasePtr task;
+                                       task = itr->second.getNextTask();
+                                       while (false == !task) // execute as long as task is not invalid.
+                                       {
+                                               currentCommand = task;
+                                               // Before execution of task check if the task is set for cancellation
+                                               CommandRequestCancelPtr ptr = CommandRequestCancel::isCancelled(
+                                                   task->getCommandUID());
+                                               if (false == !ptr) {
+                                                       unsigned int size;
+                                                       ptr->getSerializedData(writeData, size);
+                                                       boost::asio::write(clientSocket,
+                                                           boost::asio::buffer(writeData, size));
+                                                       // CAUTION: after this the while loop should continue with next task.
+                                                       // Be careful while changing the code after else part
+                                               } else {
+                                                       task->execute();
+                                                       // Invalidate the shared pointer
+                                                       currentCommand = CommandBasePtr();
+                                                       // reset cancel flag for this task
+                                                       sharedData.thisTaskCancel = false;
+                                                       // write reply back
+                                                       unsigned int size;
+                                                       task->getSerializedData(writeData, size);
+                                                       boost::system::error_code ec;
+                                                       boost::asio::write(clientSocket,
+                                                           boost::asio::buffer(writeData, size + 1), ec);
+                                                       if (!ec)
+                                                               LOGD(TEE_STUB, "Reply written back");
+                                                       else
+                                                       LOGE(TEE_STUB, "Reply write failed!");
+                                                       task = itr->second.getNextTask();
+                                               }                            //if-else
+                                       } //while
+                               } //if queue
+                       } //for
+               } //if map
+               map_mutex.unlock();
+
+               // TODO: check how to reduce cycles from while(1)
+               // boost::this_thread::sleep(boost::posix_time::milliseconds(1));
+       } //while(1)
+}
+
+/**
+ * Start the executor thread which executes task queue in all sessions.
+ */
+void TaskQueuedStrategy::startThread() {
+       LOGD(TEE_STUB, "Entry");
+       runThread = true;
+       executorThread = boost::thread(&TaskQueuedStrategy::executeCommands, this);
+}
+
+TaskQueuedStrategy::~TaskQueuedStrategy() {
+}
+
+/**
+ * Stops thread and exits to thread caller
+ */
+void TaskQueuedStrategy::stopThread() {
+       runThread = false;
+}
diff --git a/TEEStub/TaskStrategy/TaskQueuedStrategy.h b/TEEStub/TaskStrategy/TaskQueuedStrategy.h
new file mode 100755 (executable)
index 0000000..a38da7a
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics Co., Ltd. ("Confidential Information").
+ * you shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ *
+ * TaskQueuedStrategy.h
+ *
+ *  Created on: 13-Apr-2015
+ *      Author: Krishna Devale
+ */
+
+#ifndef TASKQUEUEDSTRATEGY_H_
+#define TASKQUEUEDSTRATEGY_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TaskStrategy.h"
+#include "SessionState.h"
+#include "TACommands/CommandBase.h"
+#include "TACommands/CommandRequestCancel.h"
+#include <map>
+#include <vector>
+#include <queue>
+#include <boost/thread.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/asio.hpp>
+
+using boost::asio::local::stream_protocol;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class TaskQueuedStrategy
+ * Implements TaskStategy. Here, commands are added to session map where
+ * internally, each session has a queue of tasks a.k.a commands.
+ * The executor thread later picks up each of these commands and
+ * serves the command request.
+ *
+ * Cancellation of command is also possible in two ways as per
+ * GP specification:
+ * 1. Command is still in queue then directly discard the command.
+ * 2. The current command in execution is to be cancelled, raise a flag
+ *    which reached the current command, where TA developer needs to take
+ *    action.
+ */
+class TaskQueuedStrategy:
+    public TaskStrategy {
+private:
+       std::map<uint32_t, SessionState> sessionTaskMap;
+       std::vector<CommandRequestCancel> cancelVector;
+       boost::thread executorThread;
+       boost::mutex map_mutex;
+
+       // The socket used to communicate with the client.
+       stream_protocol::socket &clientSocket;
+       CommandBasePtr currentCommand;
+       bool runThread;
+       void executeCancellation(CommandBasePtr cancelCommand);
+       void executeCommands();
+public:
+       TaskQueuedStrategy(stream_protocol::socket &msocket);
+       virtual void handleCommand(CommandBasePtr command);
+       virtual ~TaskQueuedStrategy();
+       virtual void startThread();
+       virtual void stopThread();
+};
+
+#endif /* TASKQUEUEDSTRATEGY_H_ */
diff --git a/TEEStub/TaskStrategy/TaskStrategy.cpp b/TEEStub/TaskStrategy/TaskStrategy.cpp
new file mode 100755 (executable)
index 0000000..79aa4d3
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TaskStrategy.cpp
+ *
+ *    Description:  TaskStrategy class
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TaskStrategy.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+TaskStrategy::TaskStrategy() {
+}
+
+TaskStrategy::~TaskStrategy() {
+}
diff --git a/TEEStub/TaskStrategy/TaskStrategy.h b/TEEStub/TaskStrategy/TaskStrategy.h
new file mode 100755 (executable)
index 0000000..f9c2c31
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TaskStrategy.h
+ *
+ *    Description:  TaskStrategy header file
+ *
+ *        Version:  1.0
+ *        Created:  13 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TASKSTRATEGY_H_
+#define TASKSTRATEGY_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_sim_command.h"
+#include "TACommands/CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+/**
+ * @class TaskStrategy
+ * Abstract class to provide interface to queue up commands and execute them.
+ */
+class TaskStrategy {
+public:
+       TaskStrategy();
+       virtual void handleCommand(CommandBasePtr command) = 0;
+       virtual void startThread() = 0;
+       virtual void stopThread() = 0;
+       virtual void executeCommands() = 0;
+       virtual ~TaskStrategy();
+};
+
+#endif /* TASKSTRATEGY_H_ */
diff --git a/TEEStub/teestubmain.cpp b/TEEStub/teestubmain.cpp
new file mode 100755 (executable)
index 0000000..9f1a9b6
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  main.cpp
+ *
+ *    Description:  main
+ *
+ *        Version:  1.0
+ *        Created:  08 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <cstdio>
+#include <iostream>
+#include "TACommands/SharedMemoryMap.h"
+#include "TEEStubServer/TEEStubServer.h"
+#include <PropertyAccess/PropertyApi.h>
+#include <PropertyAccess/PropertyUtility.h>
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+extern TEE_UUID ssf_sharedthisTAUUID;
+boost::asio::io_service io_service; ///< io_service provides OS abstraction for async communication
+
+/*-----------------------------------------------------------------------------
+ *  Local functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Starts the TEEStub as server which listens for connection from
+ * Simulator Daemon.
+ * @param socketName
+ */
+void StartServer(string socketName) {
+       try {
+               ::unlink(socketName.c_str());
+               LOGD(TEE_STUB, "Waiting on socket");
+               TEEStubServer s(io_service, socketName.c_str());
+               io_service.run();
+       } catch (std::exception& e) {
+               LOGE(TEE_STUB, "Exception: %s", e.what());
+       }
+}
+
+/**
+ * Stops the TEEStub server
+ */
+void StopServer() {
+       io_service.stop();
+}
+
+/**
+ * Entry point for a TA. TEEStub supplies the main function where
+ * as the TA Interface is implemented by TA developer
+ * @param argc Number of arguments to main function
+ * @param argv Arguments passed to TA
+ * @return
+ */
+int main(int argc, char* argv[]) {
+
+       if (argc < 2) {
+               LOGE(TEE_STUB, "Invalid arguments to TEE Stub");
+       }
+       // Initialize Properties module
+       // TODO: fetch login method from Context, not to be hardcoded
+       TEE_Result initStatus;
+       char uuid[100];
+       int uuidlen = strlen(argv[0]);
+       printf("argv[0]: %s\n", argv[0]);
+       // fetch uuid from argv[0]
+       int i, j;
+       for (i = uuidlen - 38, j = 0; i < uuidlen - 6; j++, i++) {
+               uuid[j] = argv[0][i];
+       }
+       uuid[j] = '\0';
+       // Inititalize the property module
+       initStatus = InitPropertyModule(uuid, TEE_LOGIN_PUBLIC);
+       // Pass UUID to SSF
+       TEE_UUID out;
+       PropertyValue pv;
+       pv.type = "uuid";
+       pv.value = string(uuid);
+       PropertyUtility::convertToUUID(pv, out);
+       ssf_sharedthisTAUUID = out;
+
+       // Once the server is started, it exits only after the
+       // connection is lost or gracefully disconnected.
+       StartServer(string("/tmp/") + string(argv[1]));
+       LOGD(TEE_STUB, "Exiting TEEStub\n");
+       // Deallocate property objects
+       if (TEE_SUCCESS == initStatus) DeInitPropertyModule();
+
+       // Cleanup by deleting all shared memory
+       deleteAllSharedMemory();
+       return 0;
+}
diff --git a/build/TEECLib/makefile b/build/TEECLib/makefile
new file mode 100755 (executable)
index 0000000..7c44a62
--- /dev/null
@@ -0,0 +1,51 @@
+# Directory where Simulator code is placed
+
+GIT_SDK = ../../..
+TOOLCHAIN_PATH = $(GIT_SDK)/toolchain/linux
+TOOLCHAIN = $(TOOLCHAIN_PATH)/i386-linux-gnueabi-gcc-4.6/bin/i386-linux-gnueabi-
+INCLUDE = $(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr/include/
+SYSROOT = --sysroot=$(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/
+
+HOME = $(GIT_SDK)/simulator
+TEECLIB_SOURCE = $(HOME)/TEECLib
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include src/subdir.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: libteec2.so
+
+# Tool invocations
+libteec2.so: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC C Linker'
+       $(TOOLCHAIN)g++ -L"../osal" -L"../log" -shared -o "libteec2.so" $(OBJS) $(USER_OBJS) $(LIBS) $(SYSROOT)
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(OBJS)$(C_DEPS)$(LIBRARIES) libteec2.so
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/build/TEECLib/objects.mk b/build/TEECLib/objects.mk
new file mode 100755 (executable)
index 0000000..9422d85
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS := -losal -lrt -llog
+
diff --git a/build/TEECLib/sources.mk b/build/TEECLib/sources.mk
new file mode 100755 (executable)
index 0000000..1ba014d
--- /dev/null
@@ -0,0 +1,17 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+O_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+OBJS := 
+C_DEPS := 
+LIBRARIES := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+src \
+
diff --git a/build/TEECLib/src/subdir.mk b/build/TEECLib/src/subdir.mk
new file mode 100755 (executable)
index 0000000..1af650e
--- /dev/null
@@ -0,0 +1,23 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(TEECLIB_SOURCE)/src/teec_api.c \
+$(TEECLIB_SOURCE)/src/teec_connection.c 
+
+OBJS += \
+./src/teec_api.o \
+./src/teec_connection.o 
+
+C_DEPS += \
+./src/teec_api.d \
+./src/teec_connection.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/%.o: $(TEECLIB_SOURCE)/src/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/TEECLib/inc" -I"../../osal" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/TEEStub/PropertyAccess/subdir.mk b/build/TEEStub/PropertyAccess/subdir.mk
new file mode 100755 (executable)
index 0000000..89bc675
--- /dev/null
@@ -0,0 +1,32 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(TEESTUB_SOURCE)/PropertyAccess/ClientProperty.cpp \
+$(TEESTUB_SOURCE)/PropertyAccess/PropertyApi.cpp \
+$(TEESTUB_SOURCE)/PropertyAccess/PropertyUtility.cpp \
+$(TEESTUB_SOURCE)/PropertyAccess/TAProperty.cpp \
+$(TEESTUB_SOURCE)/PropertyAccess/TEEProperty.cpp 
+
+OBJS += \
+./PropertyAccess/ClientProperty.o \
+./PropertyAccess/PropertyApi.o \
+./PropertyAccess/PropertyUtility.o \
+./PropertyAccess/TAProperty.o \
+./PropertyAccess/TEEProperty.o 
+
+CPP_DEPS += \
+./PropertyAccess/ClientProperty.d \
+./PropertyAccess/PropertyApi.d \
+./PropertyAccess/PropertyUtility.d \
+./PropertyAccess/TAProperty.d \
+./PropertyAccess/TEEProperty.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+PropertyAccess/%.o: $(TEESTUB_SOURCE)/PropertyAccess/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/TEEStub/../ssflib/inc" -I"$(HOME)/TEEStub" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/TEEStub/TACommands/subdir.mk b/build/TEEStub/TACommands/subdir.mk
new file mode 100755 (executable)
index 0000000..9648d87
--- /dev/null
@@ -0,0 +1,44 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(TEESTUB_SOURCE)/TACommands/CommandBase.cpp \
+$(TEESTUB_SOURCE)/TACommands/CommandCloseSession.cpp \
+$(TEESTUB_SOURCE)/TACommands/CommandCreateEntryPoint.cpp \
+$(TEESTUB_SOURCE)/TACommands/CommandDestroyEntryPoint.cpp \
+$(TEESTUB_SOURCE)/TACommands/CommandInvoke.cpp \
+$(TEESTUB_SOURCE)/TACommands/CommandOpenSession.cpp \
+$(TEESTUB_SOURCE)/TACommands/CommandRequestCancel.cpp \
+$(TEESTUB_SOURCE)/TACommands/MakeCommand.cpp \
+$(TEESTUB_SOURCE)/TACommands/SharedMemoryMap.cpp 
+
+OBJS += \
+./TACommands/CommandBase.o \
+./TACommands/CommandCloseSession.o \
+./TACommands/CommandCreateEntryPoint.o \
+./TACommands/CommandDestroyEntryPoint.o \
+./TACommands/CommandInvoke.o \
+./TACommands/CommandOpenSession.o \
+./TACommands/CommandRequestCancel.o \
+./TACommands/MakeCommand.o \
+./TACommands/SharedMemoryMap.o 
+
+CPP_DEPS += \
+./TACommands/CommandBase.d \
+./TACommands/CommandCloseSession.d \
+./TACommands/CommandCreateEntryPoint.d \
+./TACommands/CommandDestroyEntryPoint.d \
+./TACommands/CommandInvoke.d \
+./TACommands/CommandOpenSession.d \
+./TACommands/CommandRequestCancel.d \
+./TACommands/MakeCommand.d \
+./TACommands/SharedMemoryMap.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+TACommands/%.o: $(TEESTUB_SOURCE)/TACommands/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/TEEStub/../ssflib/inc" -I"$(HOME)/TEEStub" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/TEEStub/TEEStubServer/subdir.mk b/build/TEEStub/TEEStubServer/subdir.mk
new file mode 100755 (executable)
index 0000000..4e40be9
--- /dev/null
@@ -0,0 +1,26 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(TEESTUB_SOURCE)/TEEStubServer/ConnectionSession.cpp \
+$(TEESTUB_SOURCE)/TEEStubServer/TAProperty.cpp \
+$(TEESTUB_SOURCE)/TEEStubServer/TEEStubServer.cpp 
+
+OBJS += \
+./TEEStubServer/ConnectionSession.o \
+./TEEStubServer/TAProperty.o \
+./TEEStubServer/TEEStubServer.o 
+
+CPP_DEPS += \
+./TEEStubServer/ConnectionSession.d \
+./TEEStubServer/TAProperty.d \
+./TEEStubServer/TEEStubServer.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+TEEStubServer/%.o: $(TEESTUB_SOURCE)/TEEStubServer/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/TEEStub/../ssflib/inc" -I"$(HOME)/TEEStub" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/TEEStub/TaskStrategy/subdir.mk b/build/TEEStub/TaskStrategy/subdir.mk
new file mode 100755 (executable)
index 0000000..711898d
--- /dev/null
@@ -0,0 +1,26 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(TEESTUB_SOURCE)/TaskStrategy/SessionState.cpp \
+$(TEESTUB_SOURCE)/TaskStrategy/TaskQueuedStrategy.cpp \
+$(TEESTUB_SOURCE)/TaskStrategy/TaskStrategy.cpp 
+
+OBJS += \
+./TaskStrategy/SessionState.o \
+./TaskStrategy/TaskQueuedStrategy.o \
+./TaskStrategy/TaskStrategy.o 
+
+CPP_DEPS += \
+./TaskStrategy/SessionState.d \
+./TaskStrategy/TaskQueuedStrategy.d \
+./TaskStrategy/TaskStrategy.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+TaskStrategy/%.o: $(TEESTUB_SOURCE)/TaskStrategy/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/TEEStub/../ssflib/inc" -I"$(HOME)/TEEStub" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/TEEStub/makefile b/build/TEEStub/makefile
new file mode 100755 (executable)
index 0000000..e21018c
--- /dev/null
@@ -0,0 +1,69 @@
+# Directory where Simulator code is placed
+
+GIT_SDK = ../../..
+TOOLCHAIN_PATH = $(GIT_SDK)/toolchain/linux
+TOOLCHAIN = $(TOOLCHAIN_PATH)/i386-linux-gnueabi-gcc-4.6/bin/i386-linux-gnueabi-
+INCLUDE = $(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr/include/
+SYSROOT = --sysroot=$(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr
+
+HOME = $(GIT_SDK)/simulator
+TEESTUB_SOURCE = $(HOME)/TEEStub
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include TaskStrategy/subdir.mk
+-include TEEStubServer/subdir.mk
+-include TACommands/subdir.mk
+-include PropertyAccess/subdir.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C++_DEPS)),)
+-include $(C++_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+ifneq ($(strip $(CC_DEPS)),)
+-include $(CC_DEPS)
+endif
+ifneq ($(strip $(CPP_DEPS)),)
+-include $(CPP_DEPS)
+endif
+ifneq ($(strip $(CXX_DEPS)),)
+-include $(CXX_DEPS)
+endif
+ifneq ($(strip $(C_UPPER_DEPS)),)
+-include $(C_UPPER_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: libTEEStub.a
+
+# Tool invocations
+libTEEStub.a: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC Archiver'
+       $(TOOLCHAIN)ar -r  "libTEEStub.a" $(OBJS) $(USER_OBJS) $(LIBS) ../log/log.o
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(OBJS)$(C++_DEPS)$(C_DEPS)$(CC_DEPS)$(ARCHIVES)$(CPP_DEPS)$(CXX_DEPS)$(C_UPPER_DEPS) libTEEStub.a
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/build/TEEStub/objects.mk b/build/TEEStub/objects.mk
new file mode 100755 (executable)
index 0000000..742c2da
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
diff --git a/build/TEEStub/sources.mk b/build/TEEStub/sources.mk
new file mode 100755 (executable)
index 0000000..dc0c730
--- /dev/null
@@ -0,0 +1,31 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+O_SRCS := 
+CPP_SRCS := 
+C_UPPER_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+CXX_SRCS := 
+C++_SRCS := 
+CC_SRCS := 
+OBJS := 
+C++_DEPS := 
+C_DEPS := 
+CC_DEPS := 
+ARCHIVES := 
+CPP_DEPS := 
+CXX_DEPS := 
+C_UPPER_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+. \
+TaskStrategy \
+TEEStubServer \
+TACommands \
+PropertyAccess \
+
diff --git a/build/TEEStub/subdir.mk b/build/TEEStub/subdir.mk
new file mode 100755 (executable)
index 0000000..0502a59
--- /dev/null
@@ -0,0 +1,20 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(TEESTUB_SOURCE)/teestubmain.cpp 
+
+OBJS += \
+./teestubmain.o 
+
+CPP_DEPS += \
+./teestubmain.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+%.o: $(TEESTUB_SOURCE)/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/TEEStub/../ssflib/inc" -I"$(HOME)/TEEStub" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/build.sh b/build/build.sh
new file mode 100755 (executable)
index 0000000..4eac26d
--- /dev/null
@@ -0,0 +1,173 @@
+#!/bin/bash
+#
+# This script builds all modules in TA SDK Simulator and copies the binaries
+# in the package
+#
+# Written by Cheryl Bansal <cheryl.b@samsung.com>
+# Samsung R & D Institute, Bangalore
+# Samsung Electronics
+# 7 July, 2015
+#
+
+# Paths
+
+# build.sh path
+DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+
+# Module Paths
+
+LOG_PATH=$DIR/log
+OSAL_PATH=$DIR/osal
+TEECLIB_PATH=$DIR/TEECLib
+SSFLIB_PATH=$DIR/ssflib
+TEESTUB_PATH=$DIR/TEEStub
+SIMDAEMON_PATH=$DIR/simulatordaemon
+Package=$2
+
+#check error case
+check_make_error()
+{
+       if [ "$?" != "0" ]; then
+       echo "BUILD ERROR! BUILD TERMINATED."
+       exit 1
+       fi
+}
+
+# Clean all modules
+clean_all()
+{
+cd $LOG_PATH
+make clean
+check_make_error
+cd $OSAL_PATH
+make clean
+check_make_error
+cd $TEECLIB_PATH
+make clean
+check_make_error
+cd $SSFLIB_PATH
+make clean
+check_make_error
+cd $TEESTUB_PATH
+make clean
+check_make_error
+cd $SIMDAEMON_PATH
+make clean
+check_make_error
+cd $DIR
+}
+
+# Build functions for each module
+
+build_log()
+{
+cd $LOG_PATH
+make clean
+check_make_error
+make
+check_make_error
+cd $DIR
+}
+
+build_osal()
+{
+cd $OSAL_PATH
+make clean
+check_make_error
+make
+check_make_error
+cd $DIR
+}
+
+build_libteec()
+{
+cd $TEECLIB_PATH
+make clean
+check_make_error
+make
+check_make_error
+echo "Copying libteec.so in Package"
+cp libteec2.so $Package/CA/simulator/usr/lib/
+check_make_error
+cd $DIR
+}
+
+build_ssflib()
+{
+cd $SSFLIB_PATH
+make clean
+check_make_error
+make
+check_make_error
+echo "Copying libssflib.so in Package"
+cp libssflib.so $Package/TA/simulator/usr/lib/
+check_make_error
+cd $DIR
+}
+
+build_teestub()
+{
+cd $TEESTUB_PATH
+make clean
+check_make_error
+make
+check_make_error
+echo "Copying libTEEStub.a in Package"
+cp libTEEStub.a $Package/TA/simulator/usr/lib/
+check_make_error
+cd $DIR
+}
+
+build_simdaemon()
+{
+cd $SIMDAEMON_PATH
+make clean
+check_make_error
+make
+check_make_error
+echo "Copying SimulatorDaemon in Package"
+cp SimulatorDaemon $Package/CA/simulator/usr/lib/
+check_make_error
+cd $DIR
+}
+
+# User help
+
+echo_invalid() {
+echo "Simulator Build script
+Invalid arguments
+Format: ./build.sh <Build Option> <Package Path>
+Example:./build.sh buildall ~/Package
+
+<Build Option>
+       log             :       Build Logger module
+       osal            :       Build OSAL module
+       TEECLib         :       Build TEE Client Library module
+       SSFLib          :       Build SSF Library module
+       TEEStub         :       Build TEE Stub module
+       SimDaemon       :       Build Simulator Daemon module
+       buildall        :       Build all modules
+       clean           :       Clean all modules
+       Exit            :       To exit this Program"
+}
+
+# Verify number of arguments to build.sh
+if [[ "$#" -ne 2 ]]; then
+       echo "Illegal number of arguments"
+       echo_invalid
+       exit 0
+fi
+
+case $1 in
+    'log') build_log ;;
+    'osal') build_osal ;;
+    'TEECLib') build_log ; build_osal ; build_libteec ;;
+    'SSFLib') build_log ; build_osal ; build_ssflib ;;
+    'TEEStub') build_log ; build_osal ; build_ssflib ; build_teestub ;;
+    'SimDaemon') build_log ; build_osal ; build_simdaemon ;;
+    'buildall') build_log ; build_osal ; build_libteec ; build_ssflib ; build_teestub ; build_simdaemon ;;
+    'clean') clean_all ;;
+    'Exit') exit 0 ;; 
+    *) echo_invalid ;;
+esac    
+
diff --git a/build/log/makefile b/build/log/makefile
new file mode 100755 (executable)
index 0000000..c351a93
--- /dev/null
@@ -0,0 +1,46 @@
+-include ../makefile.init
+
+GIT_SDK = ../../..
+TOOLCHAIN_PATH = $(GIT_SDK)/toolchain/linux
+TOOLCHAIN = $(TOOLCHAIN_PATH)/i386-linux-gnueabi-gcc-4.6/bin/i386-linux-gnueabi-
+INCLUDE = $(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr/include/
+
+LOG_SOURCE = ../../log
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: liblog.a
+
+# Tool invocations
+liblog.a: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC Archiver'
+       $(TOOLCHAIN)ar -r  "liblog.a" $(OBJS) $(USER_OBJS) $(LIBS)
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(OBJS)$(C_DEPS)$(ARCHIVES) liblog.a
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/build/log/objects.mk b/build/log/objects.mk
new file mode 100755 (executable)
index 0000000..742c2da
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
diff --git a/build/log/sources.mk b/build/log/sources.mk
new file mode 100755 (executable)
index 0000000..3e7cfef
--- /dev/null
@@ -0,0 +1,17 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+O_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+OBJS := 
+C_DEPS := 
+ARCHIVES := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+. \
+
diff --git a/build/log/subdir.mk b/build/log/subdir.mk
new file mode 100755 (executable)
index 0000000..354843c
--- /dev/null
@@ -0,0 +1,19 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(LOG_SOURCE)/log.c 
+
+OBJS += \
+./log.o 
+
+C_DEPS += \
+./log.d 
+
+# Each subdirectory must supply rules for building sources it contributes
+%.o: $(LOG_SOURCE)/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -I$(INCLUDE) -O0 -g3 -Wall -c $(SYSROOT) -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/osal/makefile b/build/osal/makefile
new file mode 100755 (executable)
index 0000000..af05f50
--- /dev/null
@@ -0,0 +1,46 @@
+-include ../makefile.init
+
+GIT_SDK = ../../..
+TOOLCHAIN_PATH = $(GIT_SDK)/toolchain/linux
+TOOLCHAIN = $(TOOLCHAIN_PATH)/i386-linux-gnueabi-gcc-4.6/bin/i386-linux-gnueabi-
+INCLUDE = $(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr/include/
+
+OSAL_SOURCE = ../../osal
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: libosal.a
+
+# Tool invocations
+libosal.a: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC Archiver'
+       $(TOOLCHAIN)ar -r  "libosal.a" $(OBJS) $(USER_OBJS) $(LIBS)
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(OBJS)$(C_DEPS)$(ARCHIVES) libosal.a
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/build/osal/objects.mk b/build/osal/objects.mk
new file mode 100755 (executable)
index 0000000..742c2da
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
diff --git a/build/osal/sources.mk b/build/osal/sources.mk
new file mode 100755 (executable)
index 0000000..3e7cfef
--- /dev/null
@@ -0,0 +1,17 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+O_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+OBJS := 
+C_DEPS := 
+ARCHIVES := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+. \
+
diff --git a/build/osal/subdir.mk b/build/osal/subdir.mk
new file mode 100755 (executable)
index 0000000..4f05c36
--- /dev/null
@@ -0,0 +1,35 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(OSAL_SOURCE)/OsaCommon.c \
+$(OSAL_SOURCE)/OsaIpc.c \
+$(OSAL_SOURCE)/OsaQueue.c \
+$(OSAL_SOURCE)/OsaSem.c \
+$(OSAL_SOURCE)/OsaSignal.c \
+$(OSAL_SOURCE)/OsaTask.c 
+
+OBJS += \
+./OsaCommon.o \
+./OsaIpc.o \
+./OsaQueue.o \
+./OsaSem.o \
+./OsaSignal.o \
+./OsaTask.o 
+
+C_DEPS += \
+./OsaCommon.d \
+./OsaIpc.d \
+./OsaQueue.d \
+./OsaSem.d \
+./OsaSignal.d \
+./OsaTask.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+%.o: $(OSAL_SOURCE)/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -lrt -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/simulatordaemon/makefile b/build/simulatordaemon/makefile
new file mode 100755 (executable)
index 0000000..7e56eaa
--- /dev/null
@@ -0,0 +1,69 @@
+# Directory where Simulator code is placed
+
+GIT_SDK = ../../..
+TOOLCHAIN_PATH = $(GIT_SDK)/toolchain/linux
+TOOLCHAIN = $(TOOLCHAIN_PATH)/i386-linux-gnueabi-gcc-4.6/bin/i386-linux-gnueabi-
+INCLUDE = $(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr/include/
+SYSROOT = --sysroot=$(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/
+
+HOME = $(GIT_SDK)/simulator
+SIMDAEMON_SOURCE = $(HOME)/simulatordaemon
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include src/TABinaryManager/subdir.mk
+-include src/ResponseCommands/subdir.mk
+-include src/ClientCommands/subdir.mk
+-include src/subdir.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C++_DEPS)),)
+-include $(C++_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+ifneq ($(strip $(CC_DEPS)),)
+-include $(CC_DEPS)
+endif
+ifneq ($(strip $(CPP_DEPS)),)
+-include $(CPP_DEPS)
+endif
+ifneq ($(strip $(CXX_DEPS)),)
+-include $(CXX_DEPS)
+endif
+ifneq ($(strip $(C_UPPER_DEPS)),)
+-include $(C_UPPER_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: SimulatorDaemon
+
+# Tool invocations
+SimulatorDaemon: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC C++ Linker'
+       $(TOOLCHAIN)g++ -L"../log" -L"../osal" -o "SimulatorDaemon" $(SYSROOT) $(OBJS) $(USER_OBJS) $(LIBS)
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(OBJS)$(C++_DEPS)$(C_DEPS)$(CC_DEPS)$(CPP_DEPS)$(EXECUTABLES)$(CXX_DEPS)$(C_UPPER_DEPS) SimulatorDaemon
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/build/simulatordaemon/objects.mk b/build/simulatordaemon/objects.mk
new file mode 100755 (executable)
index 0000000..f8a3a8b
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS := -lrt -llog -losal -lpthread -lboost_system -lboost_thread
+
diff --git a/build/simulatordaemon/sources.mk b/build/simulatordaemon/sources.mk
new file mode 100755 (executable)
index 0000000..e2a915a
--- /dev/null
@@ -0,0 +1,30 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+O_SRCS := 
+CPP_SRCS := 
+C_UPPER_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+CXX_SRCS := 
+C++_SRCS := 
+CC_SRCS := 
+OBJS := 
+C++_DEPS := 
+C_DEPS := 
+CC_DEPS := 
+CPP_DEPS := 
+EXECUTABLES := 
+CXX_DEPS := 
+C_UPPER_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+src \
+src/TABinaryManager \
+src/ResponseCommands \
+src/ClientCommands \
+
diff --git a/build/simulatordaemon/src/ClientCommands/subdir.mk b/build/simulatordaemon/src/ClientCommands/subdir.mk
new file mode 100755 (executable)
index 0000000..a099059
--- /dev/null
@@ -0,0 +1,55 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandCloseSession.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandCloseTASession.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandFinContext.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandInitContext.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandInvokeCommand.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandInvokeTACommand.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandOpenSession.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandOpenTASession.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandPanic.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandRegSharedMem.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandRelSharedMem.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/CommandReqCancellation.cpp \
+$(SIMDAEMON_SOURCE)/src/ClientCommands/MakeCommand.cpp 
+
+OBJS += \
+./src/ClientCommands/CommandCloseSession.o \
+./src/ClientCommands/CommandCloseTASession.o \
+./src/ClientCommands/CommandFinContext.o \
+./src/ClientCommands/CommandInitContext.o \
+./src/ClientCommands/CommandInvokeCommand.o \
+./src/ClientCommands/CommandInvokeTACommand.o \
+./src/ClientCommands/CommandOpenSession.o \
+./src/ClientCommands/CommandOpenTASession.o \
+./src/ClientCommands/CommandPanic.o \
+./src/ClientCommands/CommandRegSharedMem.o \
+./src/ClientCommands/CommandRelSharedMem.o \
+./src/ClientCommands/CommandReqCancellation.o \
+./src/ClientCommands/MakeCommand.o 
+
+CPP_DEPS += \
+./src/ClientCommands/CommandCloseSession.d \
+./src/ClientCommands/CommandCloseTASession.d \
+./src/ClientCommands/CommandFinContext.d \
+./src/ClientCommands/CommandInitContext.d \
+./src/ClientCommands/CommandInvokeCommand.d \
+./src/ClientCommands/CommandInvokeTACommand.d \
+./src/ClientCommands/CommandOpenSession.d \
+./src/ClientCommands/CommandOpenTASession.d \
+./src/ClientCommands/CommandPanic.d \
+./src/ClientCommands/CommandRegSharedMem.d \
+./src/ClientCommands/CommandRelSharedMem.d \
+./src/ClientCommands/CommandReqCancellation.d \
+./src/ClientCommands/MakeCommand.d 
+
+# Each subdirectory must supply rules for building sources it contributes
+src/ClientCommands/%.o: $(SIMDAEMON_SOURCE)/src/ClientCommands/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/simulatordaemon/src/TABinaryManager" -I"$(HOME)/simulatordaemon/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/simulatordaemon/src/ResponseCommands/subdir.mk b/build/simulatordaemon/src/ResponseCommands/subdir.mk
new file mode 100755 (executable)
index 0000000..be7554c
--- /dev/null
@@ -0,0 +1,32 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(SIMDAEMON_SOURCE)/src/ResponseCommands/ResCommandCloseSession.cpp \
+$(SIMDAEMON_SOURCE)/src/ResponseCommands/ResCommandInvokeCommand.cpp \
+$(SIMDAEMON_SOURCE)/src/ResponseCommands/ResCommandOpenSession.cpp \
+$(SIMDAEMON_SOURCE)/src/ResponseCommands/ResCommandReqCancellation.cpp \
+$(SIMDAEMON_SOURCE)/src/ResponseCommands/ResMakeCommand.cpp 
+
+OBJS += \
+./src/ResponseCommands/ResCommandCloseSession.o \
+./src/ResponseCommands/ResCommandInvokeCommand.o \
+./src/ResponseCommands/ResCommandOpenSession.o \
+./src/ResponseCommands/ResCommandReqCancellation.o \
+./src/ResponseCommands/ResMakeCommand.o 
+
+CPP_DEPS += \
+./src/ResponseCommands/ResCommandCloseSession.d \
+./src/ResponseCommands/ResCommandInvokeCommand.d \
+./src/ResponseCommands/ResCommandOpenSession.d \
+./src/ResponseCommands/ResCommandReqCancellation.d \
+./src/ResponseCommands/ResMakeCommand.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/ResponseCommands/%.o: $(SIMDAEMON_SOURCE)/src/ResponseCommands/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/simulatordaemon/src/TABinaryManager" -I"$(HOME)/simulatordaemon/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/simulatordaemon/src/TABinaryManager/subdir.mk b/build/simulatordaemon/src/TABinaryManager/subdir.mk
new file mode 100755 (executable)
index 0000000..de7446e
--- /dev/null
@@ -0,0 +1,29 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(SIMDAEMON_SOURCE)/src/TABinaryManager/TABinaryManager.cpp \
+$(SIMDAEMON_SOURCE)/src/TABinaryManager/TAManifest.cpp \
+$(SIMDAEMON_SOURCE)/src/TABinaryManager/TAUnpack.cpp \
+$(SIMDAEMON_SOURCE)/src/TABinaryManager/TestMain.cpp 
+
+OBJS += \
+./src/TABinaryManager/TABinaryManager.o \
+./src/TABinaryManager/TAManifest.o \
+./src/TABinaryManager/TAUnpack.o \
+./src/TABinaryManager/TestMain.o 
+
+CPP_DEPS += \
+./src/TABinaryManager/TABinaryManager.d \
+./src/TABinaryManager/TAManifest.d \
+./src/TABinaryManager/TAUnpack.d \
+./src/TABinaryManager/TestMain.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/TABinaryManager/%.o: $(SIMDAEMON_SOURCE)/src/TABinaryManager/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/simulatordaemon/src/TABinaryManager" -I"$(HOME)/simulatordaemon/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/simulatordaemon/src/subdir.mk b/build/simulatordaemon/src/subdir.mk
new file mode 100755 (executable)
index 0000000..f2c0e3c
--- /dev/null
@@ -0,0 +1,41 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(SIMDAEMON_SOURCE)/src/ConnectionSession.cpp \
+$(SIMDAEMON_SOURCE)/src/Session.cpp \
+$(SIMDAEMON_SOURCE)/src/SimulatorDaemon.cpp \
+$(SIMDAEMON_SOURCE)/src/SimulatorDaemonServer.cpp \
+$(SIMDAEMON_SOURCE)/src/TAFactory.cpp \
+$(SIMDAEMON_SOURCE)/src/TAInstance.cpp \
+$(SIMDAEMON_SOURCE)/src/TEEContext.cpp \
+$(SIMDAEMON_SOURCE)/src/ioService.cpp 
+
+OBJS += \
+./src/ConnectionSession.o \
+./src/Session.o \
+./src/SimulatorDaemon.o \
+./src/SimulatorDaemonServer.o \
+./src/TAFactory.o \
+./src/TAInstance.o \
+./src/TEEContext.o \
+./src/ioService.o 
+
+CPP_DEPS += \
+./src/ConnectionSession.d \
+./src/Session.d \
+./src/SimulatorDaemon.d \
+./src/SimulatorDaemonServer.d \
+./src/TAFactory.d \
+./src/TAInstance.d \
+./src/TEEContext.d \
+./src/ioService.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/%.o: $(SIMDAEMON_SOURCE)/src/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -I"$(HOME)/include/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/simulatordaemon/src/TABinaryManager" -I"$(HOME)/simulatordaemon/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/dep/cryptocore/source/base/subdir.mk b/build/ssflib/dep/cryptocore/source/base/subdir.mk
new file mode 100755 (executable)
index 0000000..5f01c31
--- /dev/null
@@ -0,0 +1,59 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_ANSI_x931.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_aes.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_bignum.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_des.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_ecc.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_fast_math.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_hash.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_md5.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_moo.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_pkcs1_v21.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_rc4.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_sha1.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_sha2.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/base/cc_snow2.c 
+
+OBJS += \
+./dep/cryptocore/source/base/cc_ANSI_x931.o \
+./dep/cryptocore/source/base/cc_aes.o \
+./dep/cryptocore/source/base/cc_bignum.o \
+./dep/cryptocore/source/base/cc_des.o \
+./dep/cryptocore/source/base/cc_ecc.o \
+./dep/cryptocore/source/base/cc_fast_math.o \
+./dep/cryptocore/source/base/cc_hash.o \
+./dep/cryptocore/source/base/cc_md5.o \
+./dep/cryptocore/source/base/cc_moo.o \
+./dep/cryptocore/source/base/cc_pkcs1_v21.o \
+./dep/cryptocore/source/base/cc_rc4.o \
+./dep/cryptocore/source/base/cc_sha1.o \
+./dep/cryptocore/source/base/cc_sha2.o \
+./dep/cryptocore/source/base/cc_snow2.o 
+
+C_DEPS += \
+./dep/cryptocore/source/base/cc_ANSI_x931.d \
+./dep/cryptocore/source/base/cc_aes.d \
+./dep/cryptocore/source/base/cc_bignum.d \
+./dep/cryptocore/source/base/cc_des.d \
+./dep/cryptocore/source/base/cc_ecc.d \
+./dep/cryptocore/source/base/cc_fast_math.d \
+./dep/cryptocore/source/base/cc_hash.d \
+./dep/cryptocore/source/base/cc_md5.d \
+./dep/cryptocore/source/base/cc_moo.d \
+./dep/cryptocore/source/base/cc_pkcs1_v21.d \
+./dep/cryptocore/source/base/cc_rc4.d \
+./dep/cryptocore/source/base/cc_sha1.d \
+./dep/cryptocore/source/base/cc_sha2.d \
+./dep/cryptocore/source/base/cc_snow2.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+dep/cryptocore/source/base/%.o: $(SSFLIB_SOURCE)/dep/cryptocore/source/base/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/dep/cryptocore/source/middle/subdir.mk b/build/ssflib/dep/cryptocore/source/middle/subdir.mk
new file mode 100755 (executable)
index 0000000..73d96ca
--- /dev/null
@@ -0,0 +1,47 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_cmac.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_dh.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_dsa.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_ecdh.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_ecdsa.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_hmac.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_rng.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_rsa.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_symmetric.c \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/middle/cc_tdes.c 
+
+OBJS += \
+./dep/cryptocore/source/middle/cc_cmac.o \
+./dep/cryptocore/source/middle/cc_dh.o \
+./dep/cryptocore/source/middle/cc_dsa.o \
+./dep/cryptocore/source/middle/cc_ecdh.o \
+./dep/cryptocore/source/middle/cc_ecdsa.o \
+./dep/cryptocore/source/middle/cc_hmac.o \
+./dep/cryptocore/source/middle/cc_rng.o \
+./dep/cryptocore/source/middle/cc_rsa.o \
+./dep/cryptocore/source/middle/cc_symmetric.o \
+./dep/cryptocore/source/middle/cc_tdes.o 
+
+C_DEPS += \
+./dep/cryptocore/source/middle/cc_cmac.d \
+./dep/cryptocore/source/middle/cc_dh.d \
+./dep/cryptocore/source/middle/cc_dsa.d \
+./dep/cryptocore/source/middle/cc_ecdh.d \
+./dep/cryptocore/source/middle/cc_ecdsa.d \
+./dep/cryptocore/source/middle/cc_hmac.d \
+./dep/cryptocore/source/middle/cc_rng.d \
+./dep/cryptocore/source/middle/cc_rsa.d \
+./dep/cryptocore/source/middle/cc_symmetric.d \
+./dep/cryptocore/source/middle/cc_tdes.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+dep/cryptocore/source/middle/%.o: $(SSFLIB_SOURCE)/dep/cryptocore/source/middle/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/dep/cryptocore/source/subdir.mk b/build/ssflib/dep/cryptocore/source/subdir.mk
new file mode 100755 (executable)
index 0000000..0b82019
--- /dev/null
@@ -0,0 +1,20 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(SSFLIB_SOURCE)/dep/cryptocore/source/CC_API.c 
+
+OBJS += \
+./dep/cryptocore/source/CC_API.o 
+
+C_DEPS += \
+./dep/cryptocore/source/CC_API.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+dep/cryptocore/source/%.o: $(SSFLIB_SOURCE)/dep/cryptocore/source/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/dep/swdss/source/subdir.mk b/build/ssflib/dep/swdss/source/subdir.mk
new file mode 100755 (executable)
index 0000000..fd93294
--- /dev/null
@@ -0,0 +1,35 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(SSFLIB_SOURCE)/dep/swdss/source/file_op.cpp \
+$(SSFLIB_SOURCE)/dep/swdss/source/secure_file.cpp \
+$(SSFLIB_SOURCE)/dep/swdss/source/ss_api.cpp \
+$(SSFLIB_SOURCE)/dep/swdss/source/ss_crypto.cpp \
+$(SSFLIB_SOURCE)/dep/swdss/source/ss_misc.cpp \
+$(SSFLIB_SOURCE)/dep/swdss/source/ss_temp_store.cpp 
+
+OBJS += \
+./dep/swdss/source/file_op.o \
+./dep/swdss/source/secure_file.o \
+./dep/swdss/source/ss_api.o \
+./dep/swdss/source/ss_crypto.o \
+./dep/swdss/source/ss_misc.o \
+./dep/swdss/source/ss_temp_store.o 
+
+CPP_DEPS += \
+./dep/swdss/source/file_op.d \
+./dep/swdss/source/secure_file.d \
+./dep/swdss/source/ss_api.d \
+./dep/swdss/source/ss_crypto.d \
+./dep/swdss/source/ss_misc.d \
+./dep/swdss/source/ss_temp_store.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+dep/swdss/source/%.o: $(SSFLIB_SOURCE)/dep/swdss/source/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/dep/time/subdir.mk b/build/ssflib/dep/time/subdir.mk
new file mode 100755 (executable)
index 0000000..58955f9
--- /dev/null
@@ -0,0 +1,20 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+$(SSFLIB_SOURCE)/dep/time/ssf_time.cpp 
+
+OBJS += \
+./dep/time/ssf_time.o 
+
+CPP_DEPS += \
+./dep/time/ssf_time.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+dep/time/%.o: $(SSFLIB_SOURCE)/dep/time/%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/dep/uci/source/subdir.mk b/build/ssflib/dep/uci/source/subdir.mk
new file mode 100755 (executable)
index 0000000..e103ce3
--- /dev/null
@@ -0,0 +1,29 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(SSFLIB_SOURCE)/dep/uci/source/uci_aes_xcbc_mac.c \
+$(SSFLIB_SOURCE)/dep/uci/source/uci_api.c \
+$(SSFLIB_SOURCE)/dep/uci/source/uci_cryptocore.c \
+$(SSFLIB_SOURCE)/dep/uci/source/uci_hwcrypto.c 
+
+OBJS += \
+./dep/uci/source/uci_aes_xcbc_mac.o \
+./dep/uci/source/uci_api.o \
+./dep/uci/source/uci_cryptocore.o \
+./dep/uci/source/uci_hwcrypto.o 
+
+C_DEPS += \
+./dep/uci/source/uci_aes_xcbc_mac.d \
+./dep/uci/source/uci_api.d \
+./dep/uci/source/uci_cryptocore.d \
+./dep/uci/source/uci_hwcrypto.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+dep/uci/source/%.o: $(SSFLIB_SOURCE)/dep/uci/source/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/build/ssflib/makefile b/build/ssflib/makefile
new file mode 100755 (executable)
index 0000000..d979fa5
--- /dev/null
@@ -0,0 +1,72 @@
+# Directory where Simulator code is placed
+
+GIT_SDK = ../../..
+TOOLCHAIN_PATH = $(GIT_SDK)/toolchain/linux
+TOOLCHAIN = $(TOOLCHAIN_PATH)/i386-linux-gnueabi-gcc-4.6/bin/i386-linux-gnueabi-
+INCLUDE = $(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/usr/include/
+SYSROOT = --sysroot=$(TOOLCHAIN_PATH)/rootstraps/mobile-2.3-emulator.core/
+
+HOME = $(GIT_SDK)/simulator
+SSFLIB_SOURCE = $(HOME)/ssflib
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include src/subdir.mk
+-include dep/uci/source/subdir.mk
+-include dep/time/subdir.mk
+-include dep/swdss/source/subdir.mk
+-include dep/cryptocore/source/middle/subdir.mk
+-include dep/cryptocore/source/base/subdir.mk
+-include dep/cryptocore/source/subdir.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(C++_DEPS)),)
+-include $(C++_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+ifneq ($(strip $(CC_DEPS)),)
+-include $(CC_DEPS)
+endif
+ifneq ($(strip $(CPP_DEPS)),)
+-include $(CPP_DEPS)
+endif
+ifneq ($(strip $(CXX_DEPS)),)
+-include $(CXX_DEPS)
+endif
+ifneq ($(strip $(C_UPPER_DEPS)),)
+-include $(C_UPPER_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: libssflib.so
+
+# Tool invocations
+libssflib.so: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC C++ Linker'
+       $(TOOLCHAIN)g++ -L"../log" -L"../osal" $(SYSROOT) -fmessage-length=0 -shared -o "libssflib.so" $(OBJS) $(USER_OBJS) $(LIBS)
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(OBJS)$(C++_DEPS)$(C_DEPS)$(CC_DEPS)$(LIBRARIES)$(CPP_DEPS)$(CXX_DEPS)$(C_UPPER_DEPS) libssflib.so
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/build/ssflib/objects.mk b/build/ssflib/objects.mk
new file mode 100755 (executable)
index 0000000..cc72611
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS := -lboost_thread -llog -losal -lrt
+
diff --git a/build/ssflib/sources.mk b/build/ssflib/sources.mk
new file mode 100755 (executable)
index 0000000..7ed1286
--- /dev/null
@@ -0,0 +1,33 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+O_SRCS := 
+CPP_SRCS := 
+C_UPPER_SRCS := 
+C_SRCS := 
+S_UPPER_SRCS := 
+OBJ_SRCS := 
+ASM_SRCS := 
+CXX_SRCS := 
+C++_SRCS := 
+CC_SRCS := 
+OBJS := 
+C++_DEPS := 
+C_DEPS := 
+CC_DEPS := 
+LIBRARIES := 
+CPP_DEPS := 
+CXX_DEPS := 
+C_UPPER_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+src \
+dep/uci/source \
+dep/time \
+dep/swdss/source \
+dep/cryptocore/source/middle \
+dep/cryptocore/source/base \
+dep/cryptocore/source \
+
diff --git a/build/ssflib/src/subdir.mk b/build/ssflib/src/subdir.mk
new file mode 100755 (executable)
index 0000000..6a5a5b6
--- /dev/null
@@ -0,0 +1,44 @@
+# Add inputs and outputs from these tool invocations to the build variables 
+C_SRCS += \
+$(SSFLIB_SOURCE)/src/ssf_arithmetic.c \
+$(SSFLIB_SOURCE)/src/ssf_client.c \
+$(SSFLIB_SOURCE)/src/ssf_crypto.c \
+$(SSFLIB_SOURCE)/src/ssf_lib.c \
+$(SSFLIB_SOURCE)/src/ssf_malloc.c \
+$(SSFLIB_SOURCE)/src/ssf_panic.c \
+$(SSFLIB_SOURCE)/src/ssf_storage.c \
+$(SSFLIB_SOURCE)/src/ssf_taentrypoint.c \
+$(SSFLIB_SOURCE)/src/app_debug.c
+
+OBJS += \
+./src/ssf_arithmetic.o \
+./src/ssf_client.o \
+./src/ssf_crypto.o \
+./src/ssf_lib.o \
+./src/ssf_malloc.o \
+./src/ssf_panic.o \
+./src/ssf_storage.o \
+./src/ssf_taentrypoint.o  \
+./src/app_debug.o
+
+C_DEPS += \
+./src/ssf_arithmetic.d \
+./src/ssf_client.d \
+./src/ssf_crypto.d \
+./src/ssf_lib.d \
+./src/ssf_malloc.d \
+./src/ssf_panic.d \
+./src/ssf_storage.d \
+./src/ssf_taentrypoint.d \
+./src/app_debug.d
+
+
+# Each subdirectory must supply rules for building sources it contributes
+src/%.o: $(SSFLIB_SOURCE)/src/%.c
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C Compiler'
+       $(TOOLCHAIN)g++ -D_SECOS_SIM_ -D__DEBUG__ -I"$(HOME)/ssflib/dep/cryptocore/include" -I"$(HOME)/log" -I"$(HOME)/osal" -I"$(HOME)/include/include" -I"$(HOME)/ssflib/dep/cryptocore/include/base" -I"$(HOME)/ssflib/dep/cryptocore/include/middle" -I"$(HOME)/ssflib/dep/swdss/include" -I"$(HOME)/ssflib/dep/uci/include" -I"$(HOME)/ssflib/inc" -I$(INCLUDE) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/include/.cproject b/include/.cproject
new file mode 100755 (executable)
index 0000000..abef4a7
--- /dev/null
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.624722712">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.624722712" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.624722712" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.624722712." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.debug.1358095903" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.debug">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.148697098" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
+                                                       <builder buildPath="${workspace_loc:/include}/Debug" id="cdt.managedbuild.builder.gnu.cross.1071637649" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.586391385" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1599143748" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.1244760951" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1988643041" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.337570397" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.1210109081" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.12802745" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.1009830925" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.538300527" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.191862665" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.archiver.2020503154" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.assembler.734446146" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.640467610" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.2029390413">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.2029390413" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.2029390413" name="Release" parent="cdt.managedbuild.config.gnu.cross.exe.release">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.2029390413." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1514082122" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.412485029" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
+                                                       <builder buildPath="${workspace_loc:/include}/Release" id="cdt.managedbuild.builder.gnu.cross.7028166" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1890570091" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
+                                                               <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.359985149" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.2011007728" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.523184850" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.577606906" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.1586818887" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.304633136" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.2059133515" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1953662530" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.1981592531" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1757348403" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.assembler.232946617" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.400925012" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="include.cdt.managedbuild.target.gnu.cross.exe.957851233" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.624722712;cdt.managedbuild.config.gnu.cross.exe.debug.624722712.;cdt.managedbuild.tool.gnu.cross.c.compiler.586391385;cdt.managedbuild.tool.gnu.c.compiler.input.1988643041">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.2029390413;cdt.managedbuild.config.gnu.cross.exe.release.2029390413.;cdt.managedbuild.tool.gnu.cross.c.compiler.1890570091;cdt.managedbuild.tool.gnu.c.compiler.input.523184850">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope"/>
+</cproject>
diff --git a/include/.project b/include/.project
new file mode 100755 (executable)
index 0000000..5b839e7
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>include</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/include/.settings/language.settings.xml b/include/.settings/language.settings.xml
new file mode 100755 (executable)
index 0000000..1408bef
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.624722712" name="Debug">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="1883712732631" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.2029390413" name="Release">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="1883712732631" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+</project>
diff --git a/include/.settings/org.eclipse.cdt.core.prefs b/include/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..ecae8d3
--- /dev/null
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.624722712/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.624722712/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.624722712/PATH/value=D\:\\eclipse\\eclipse-rcp-luna-SR1-win32-x86_64;C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\GitExtensions\\;D\:\\Tizen\\tizen-sdk\\tools;D\:\\Android\\android-sdk\\platform-tools;D\:\\Android\\android-ndk-r10c;C\:\\Program Files\\Perforce;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.624722712/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.624722712/appendContributed=true
diff --git a/include/include/config.h b/include/include/config.h
new file mode 100755 (executable)
index 0000000..b4428d7
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * config.h
+ *
+ *  Created on: May 20, 2015
+ *      Author: krishna.r
+ */
+
+#ifndef INCLUDE_CONFIG_H_
+#define INCLUDE_CONFIG_H_
+
+#define TEE_PROP_FILE "/usr/bin/GPD_TEE_PROP"
+#define TA_ROOT "/tmp/"
+#define TEE_TASTORE_ROOT "/tmp/tastore/"
+
+#endif /* INCLUDE_CONFIG_H_ */
diff --git a/include/include/tee_client_api.h b/include/include/tee_client_api.h
new file mode 100755 (executable)
index 0000000..c002367
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  tee_client_api.h
+ *
+ *    Description:  TEEC API Header file
+ *
+ *        Version:  1.0
+ *        Created:  Thursday 26 March 2015 12:42:45  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef __TEE_CLIENT_API_H__
+#define __TEE_CLIENT_API_H__
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*-----------------------------------------------------------------------------
+ * TEE Client API types and constants definitions
+ *-----------------------------------------------------------------------------*/
+#define TEEC_SUCCESS                   0x00000000 // The operation was successful
+#define TEEC_ERROR_GENERIC             0xFFFF0000 // Non-specific cause
+#define TEEC_ERROR_ACCESS_DENIED       0xFFFF0001 // Access privileges are not sufficient
+#define TEEC_ERROR_CANCEL              0xFFFF0002 // The operation was cancelled
+#define TEEC_ERROR_ACCESS_CONFLICT     0xFFFF0003 // Concurrent accesses caused conflict
+#define TEEC_ERROR_EXCESS_DATA         0xFFFF0004 // Too much data for the requested operation was passed
+#define TEEC_ERROR_BAD_FORMAT          0xFFFF0005 // Input data was of invalid format
+#define TEEC_ERROR_BAD_PARAMETERS      0xFFFF0006 // Input parameters were invalid
+#define TEEC_ERROR_BAD_STATE           0xFFFF0007 // Operation is not valid in the current state
+#define TEEC_ERROR_ITEM_NOT_FOUND      0xFFFF0008 // The requested data item is not found
+#define TEEC_ERROR_NOT_IMPLEMENTED     0xFFFF0009 // The requested operation should exist but is not yet implemented
+#define TEEC_ERROR_NOT_SUPPORTED       0xFFFF000A // The requested operation is valid but is not supported in this Implementation
+#define TEEC_ERROR_NO_DATA             0xFFFF000B // Expected data was missing
+#define TEEC_ERROR_OUT_OF_MEMORY       0xFFFF000C // System ran out of resources
+#define TEEC_ERROR_BUSY                        0xFFFF000D // The system is busy working on something else.
+#define TEEC_ERROR_COMMUNICATION       0xFFFF000E // Communication with a remote party failed.
+#define TEEC_ERROR_SECURITY            0xFFFF000F // A security fault was detected.
+#define TEEC_ERROR_SHORT_BUFFER                0xFFFF0010 // The supplied buffer is too short for the generated output.
+#define TEEC_ERROR_TARGET_DEAD         0xFFFF3024 // Targed TA panic'ed
+#define TEEC_IMP_MIN                   0x00000001
+#define TEEC_IMP_MAX                   0xFFFEFFFF
+#define TEEC_RFU_MIN                   0xFFFF0011
+#define TEEC_RFU_MAX                   0xFFFFFFFF
+
+#define TEEC_ORIGIN_API                        0x1
+#define TEEC_ORIGIN_COMMS              0x2
+#define TEEC_ORIGIN_TEE                        0x3
+#define TEEC_ORIGIN_TRUSTED_APP                0x4
+
+#define TEEC_CONFIG_SHAREDMEM_MAX_SIZE 0x800000
+
+#define TEEC_MEM_INPUT                 (1 << 0)
+#define TEEC_MEM_OUTPUT                        (1 << 1)
+
+#define TEEC_NONE                      0x00000000
+#define TEEC_VALUE_INPUT               0x00000001
+#define TEEC_VALUE_OUTPUT              0x00000002
+#define TEEC_VALUE_INOUT               0x00000003
+#define TEEC_MEMREF_TEMP_INPUT         0x00000005
+#define TEEC_MEMREF_TEMP_OUTPUT                0x00000006
+#define TEEC_MEMREF_TEMP_INOUT         0x00000007
+#define TEEC_MEMREF_WHOLE              0x0000000C
+#define TEEC_MEMREF_PARTIAL_INPUT      0x0000000D
+#define TEEC_MEMREF_PARTIAL_OUTPUT     0x0000000E
+#define TEEC_MEMREF_PARTIAL_INOUT      0x0000000F
+
+#define TEE_PARAM_TYPE_NONE            0x00000000
+#define TEE_PARAM_TYPE_VALUE_INPUT     0x00000001
+#define TEE_PARAM_TYPE_VALUE_OUTPUT    0x00000002
+#define TEE_PARAM_TYPE_VALUE_INOUT     0x00000003
+#define TEE_PARAM_TYPE_MEMREF_INPUT    0x00000005
+#define TEE_PARAM_TYPE_MEMREF_OUTPUT   0x00000006
+#define TEE_PARAM_TYPE_MEMREF_INOUT    0x00000007
+
+#define TEEC_LOGIN_PUBLIC              0x00000000
+#define TEEC_LOGIN_USER                        0x00000001
+#define TEEC_LOGIN_GROUP               0x00000002
+#define TEEC_LOGIN_APPLICATION         0x00000004 
+#define TEEC_LOGIN_USER_APPLICATION    0x00000005
+#define TEEC_LOGIN_GROUP_APPLICATION   0x00000006
+
+#define MAX_CONTEXT_NAME_LEN 128
+
+typedef uint32_t TEEC_Result;
+
+typedef struct {
+       uint32_t timeLow;
+       uint16_t timeMid;
+       uint16_t timeHiAndVersion;
+       uint8_t clockSeqAndNode[8];
+} TEEC_UUID;
+
+typedef struct {
+       void* imp;
+} TEEC_Context;
+
+typedef struct {
+       void *imp;
+} TEEC_Session;
+
+typedef struct {
+       void *buffer;
+       size_t size;
+       uint32_t flags;
+       void *imp;
+} TEEC_SharedMemory;
+
+typedef struct {
+       void *buffer;
+       size_t size;
+} TEEC_TempMemoryReference;
+
+typedef struct {
+       TEEC_SharedMemory* parent;
+       size_t size;
+       size_t offset;
+} TEEC_RegisteredMemoryReference;
+
+typedef struct {
+       uint32_t a;
+       uint32_t b;
+} TEEC_Value;
+
+typedef union {
+       TEEC_TempMemoryReference tmpref;
+       TEEC_RegisteredMemoryReference memref;
+       TEEC_Value value;
+} TEEC_Parameter;
+
+typedef struct {
+       uint32_t started;
+       uint32_t paramTypes;
+       TEEC_Parameter params[4];
+       void *imp;
+} TEEC_Operation;
+
+/*-----------------------------------------------------------------------------
+ * TEE Client API functions and macros definitions
+ *-----------------------------------------------------------------------------*/
+TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context);
+
+void TEEC_FinalizeContext(TEEC_Context *context);
+
+TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context,
+    TEEC_SharedMemory *sharedMem);
+
+TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context,
+    TEEC_SharedMemory *sharedMem);
+
+void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMem);
+
+TEEC_Result TEEC_OpenSession(TEEC_Context *context,
+    TEEC_Session *session,
+    const TEEC_UUID *destination,
+    uint32_t connectionMethod,
+    const void *connectionData,
+    TEEC_Operation *operation,
+    uint32_t *returnOrigin);
+
+void TEEC_CloseSession(TEEC_Session *session);
+
+TEEC_Result TEEC_InvokeCommand(TEEC_Session *session,
+    uint32_t commandID,
+    TEEC_Operation *operation,
+    uint32_t *returnOrigin);
+
+void TEEC_RequestCancellation(TEEC_Operation *operation);
+
+#define TEEC_PARAM_TYPES(param0Type, param1Type, param2Type, param3Type) \
+               (uint32_t)(((param0Type) & 0x7f) | \
+                               (((param1Type) & 0x7f) << 8) | \
+                               (((param2Type) & 0x7f) << 16) | \
+                               (((param3Type) & 0x7f) << 24))
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __TEE_CLIENT_API_H__ */
diff --git a/include/include/tee_command.h b/include/include/tee_command.h
new file mode 100755 (executable)
index 0000000..2f1426a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  tee_command.h
+ *
+ *    Description:  TEEC Connection Header file
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:43:30  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef __TEE_COMMAND_H__
+#define __TEE_COMMAND_H__
+
+typedef enum {
+       INVALID = -1,
+       INITIALIZE_CONTEXT = 0,
+       OPEN_SESSION,
+       REGISTER_SHARED_MEMORY,
+       INVOKE_COMMAND,
+       RELEASE_SHARED_MEMORY,
+       REQUEST_CANCELLATION,
+       CLOSE_SESSION,
+       FINALIZE_CONTEXT,
+       OPEN_TA_SESSION,
+       INVOKE_TA_COMMAND,
+       CLOSE_TA_SESSION,
+       CHECK_MEMORY,
+       PANIC
+} TEE_CMD;
+#endif /* __TEE_COMMAND_H__ */
diff --git a/include/include/tee_internal_api.h b/include/include/tee_internal_api.h
new file mode 100755 (executable)
index 0000000..65025c5
--- /dev/null
@@ -0,0 +1,2045 @@
+/*
+ * tee_internal_api.h
+ *
+ * This source file is proprietary property of Samsung Electronics Co., Ltd.
+ *
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Krishna Raghottam Devale <k.devale@samsung.com>
+ *
+ */
+
+#ifndef __TEE_INTERNAL_API_H__
+#define __TEE_INTERNAL_API_H__
+
+#ifndef ECC_IMPLEMENTATION
+#define ECC_IMPLEMENTATION
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+
+#define NON_GP_PADDING
+
+#ifndef CERTIFICATES_API
+#define CERTIFICATES_API
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * 3 Common Definitions
+ ******************************************************************************/
+
+//TEE_Result is the type used for return codes from the APIs.
+typedef uint32_t TEE_Result;
+
+//TEE_UUID is the Universally Unique Resource Identifier
+//This type is used to identify Trusted Applications and clients.
+typedef struct {
+       uint32_t timeLow;
+       uint16_t timeMid;
+       uint16_t timeHiAndVersion;
+       uint8_t clockSeqAndNode[8];
+} TEE_UUID;
+
+typedef enum {
+       TEE_SUCCESS = 0x00000000,
+       TEE_EXTERNAL_REQUEST = 0xEEEEEEEE,
+       TEE_ERROR_GENERIC = 0xFFFF0000,
+       TEE_ERROR_ACCESS_DENIED = 0xFFFF0001,
+       TEE_ERROR_CANCEL = 0xFFFF0002,
+       TEE_ERROR_ACCESS_CONFLICT = 0xFFFF0003,
+       TEE_ERROR_EXCESS_DATA = 0xFFFF0004,
+       TEE_ERROR_BAD_FORMAT = 0xFFFF0005,
+       TEE_ERROR_BAD_PARAMETERS = 0xFFFF0006,
+       TEE_ERROR_BAD_STATE = 0xFFFF0007,
+       TEE_ERROR_ITEM_NOT_FOUND = 0xFFFF0008,
+       TEE_ERROR_NOT_IMPLEMENTED = 0xFFFF0009,
+       TEE_ERROR_NOT_SUPPORTED = 0xFFFF000A,
+       TEE_ERROR_NO_DATA = 0xFFFF000B,
+       TEE_ERROR_OUT_OF_MEMORY = 0xFFFF000C,
+       TEE_ERROR_BUSY = 0xFFFF000D,
+       TEE_ERROR_COMMUNICATION = 0xFFFF000E,
+       TEE_ERROR_SECURITY = 0xFFFF000F,
+       TEE_ERROR_SHORT_BUFFER = 0xFFFF0010,
+       TEE_ERROR_TASK_NOT_FOUND = 0xFFFF0011,
+       TEE_PENDING = 0xFFFF2000,
+       TEE_ERROR_TIMEOUT = 0xFFFF3001,
+       TEE_ERROR_OVERFLOW = 0xFFFF300F,
+       TEE_ERROR_TARGET_DEAD = 0xFFFF3024,
+       TEE_ERROR_STORAGE_NO_SPACE = 0xFFFF3041,
+       TEE_ERROR_MAC_INVALID = 0xFFFF3071,
+       TEE_ERROR_SIGNATURE_INVALID = 0xFFFF3072,
+       TEE_ERROR_TIME_NOT_SET = 0xFFFF5000,
+       TEE_ERROR_TIME_NEEDS_RESET = 0xFFFF5001,
+       TEE_ERROR_CERT_PARSING = 0xFFFF6000,
+       TEE_ERROR_CRL_PARSING = 0xFFFF6001,
+       TEE_ERROR_CERT_EXPIRED = 0xFFFF6002,
+       TEE_ERROR_CERT_VERIFICATION = 0xFFFF6003,
+
+       TEE_RESULT_NOT_READY = 0xFFFF0FFF
+
+} TEE_Error_Codes;
+
+#define TEE_HANDLE_NULL 0
+#define TEE_TIMEOUT_INFINITE   (0xFFFFFFFF)
+/******************************************************************************
+ *  4. Trusted Core Framework API */
+
+/******************************************************************************
+ *  4.1 Data Types
+ ******************************************************************************/
+
+typedef struct {
+       uint32_t login;
+       TEE_UUID uuid;
+} TEE_Identity;
+
+typedef union {
+       struct {
+               void *buffer;
+               size_t size;
+               int memid;
+       } memref;
+       struct {
+               uint32_t a, b;
+       } value;
+} TEE_Param;
+
+#define TEE_PARAM_TYPES(t0,t1,t2,t3) \
+               ((t0) | ((t1) << 8) | ((t2) << 16) | ((t3) << 24))
+
+#define TEE_PARAM_TYPE_GET(t, i) (((t) >> (i*8)) & 0x7F)
+
+typedef struct __TEE_TASessionHandle* TEE_TASessionHandle;
+
+typedef struct __TEE_PropSetHandle* TEE_PropSetHandle;
+
+/******************************************************************************
+ *  4.2 Constants
+ ******************************************************************************/
+
+#define TEE_PARAM_TYPE_NONE                    0x00000000
+#define TEE_PARAM_TYPE_VALUE_INPUT             0x00000001
+#define TEE_PARAM_TYPE_VALUE_OUTPUT            0x00000002
+#define TEE_PARAM_TYPE_VALUE_INOUT             0x00000003
+#define TEE_PARAM_TYPE_MEMREF_INPUT            0x00000005
+#define TEE_PARAM_TYPE_MEMREF_OUTPUT           0x00000006
+#define TEE_PARAM_TYPE_MEMREF_INOUT            0x00000007
+
+#define TEE_MEM_INPUT                          0x00000001
+#define TEE_MEM_OUTPUT                         0x00000002
+
+#define TEE_LOGIN_PUBLIC                       0x00000000
+#define TEE_LOGIN_USER                         0x00000001
+#define TEE_LOGIN_GROUP                                0x00000002
+#define TEE_LOGIN_APPLICATION                  0x00000004
+#define TEE_LOGIN_APPLICATION_USER             0x00000005
+#define TEE_LOGIN_APPLICATION_GROUP            0x00000006
+#define TEE_LOGIN_TRUSTED_APP                  0xF0000000
+
+#define TEE_ORIGIN_API                         0x1
+#define TEE_ORIGIN_COMMS                       0x2
+#define TEE_ORIGIN_TEE                         0x3
+#define TEE_ORIGIN_TRUSTED_APP                 0x4
+
+#define TEE_ACCESS_READ                                0x00000001
+#define TEE_ACCESS_WRITE                       0x00000002
+#define TEE_ACCESS_ANY_OWNER                   0x00000004
+
+#define TEE_PROPSET_TEE_IMPLEMENTATION  (0xFFFFFFFD)
+#define TEE_PROPSET_CURRENT_CLIENT      (0xFFFFFFFE)
+#define TEE_PROPSET_CURRENT_TA          (0xFFFFFFFF)
+
+/******************************************************************************
+ *  4.3 TA Interface
+ ******************************************************************************/
+
+#define TA_EXPORT
+
+/**
+ * Trusted Application's constructor
+ *
+ * The function TA_CreateEntryPoint is the Trusted Application's constructor,
+ * which the Framework calls when it creates a new instance of the Trusted
+ * Application. To register instance data, the implementation of this
+ * constructor can use either global variables or the function
+ * @ref TEE_SetInstanceData.
+ *
+ * @return TEE_SUCCESS if the instance is successfully created. Any other value
+ * if any other code is returned, then the instance is not created, and no other
+ * entry points of this instance will be called. The Framework reclaims all
+ * resources and dereference all objects related to the creation of the
+ * instance. If this entry point was called as a result of a client opening a
+ * session, the error code is returned to the client and the session is not
+ * opened.
+ */
+TEE_Result TA_EXPORT TA_CreateEntryPoint(void);
+
+/**
+ * Trusted Application's destructor
+ *
+ * The function TA_DestroyEntryPoint is the Trusted Application's destructor,
+ * which the Framework calls when the instance is being destroyed.
+ * When the function TA_DestroyEntryPoint is called, the Framework guarantees
+ * that no client session is currently open. Once the call to
+ * TA_DestroyEntryPoint has been completed, no other entry point of this
+ * instance will ever be called. Note that when this function is called, all
+ * resources opened by the instance are still available. It is only after the
+ * function returns that the Implementation MUST start automatically reclaiming
+ * resources left opened.
+ *
+ * @return his function can return no success or error code. After this
+ * unction returns the  mplementation Monsider sthe instance destroyed and
+ *Meclaim sall resources left open by the instance.
+ */
+void TA_EXPORT TA_DestroyEntryPoint(void);
+
+/**
+ * Connects to the Trusted Application instance to open a new session
+ *
+ * This function is called whenever a client attempts to connect to the Trusted
+ * Application instance to open a new session. If this function returns an
+ * error, the connection is rejected and no new session is opened. In this
+ * function, the Trusted Application can attach an opaque void* context to the
+ * session. This context is recalled in all subsequent TA calls within the
+ * session.
+ *
+ * @param[in] paramTypes The types of the four parameters.
+ * @param[in,out] params A pointer to an array of four parameters.
+ * @param[out] sessionContext A pointer to a variable that can be filled by the
+ * Trusted Application instance with an opaque void* data pointer
+ *
+ * @return EE_SUCCESS:Ii the session is successfully opened , and any other
+ * value if the session could not be opened. The error code may be one of the
+ * pre-defined codes, or may be a new error code defined by the
+ * Trusted Application implementation itself. In any case, the Implementation
+ * reports the error code to the client with the origin
+ * @ref TEEC_ORIGIN_TRUSTED_APP.
+ */
+TEE_Result TA_EXPORT TA_OpenSessionEntryPoint(uint32_t paramTypes,
+    TEE_Param params[4],
+    void** sessionContext);
+
+/**
+ * Closes a client session
+ *
+ * The Framework calls the function TA_CloseSessionEntryPoint to close a client
+ * session. The Trusted Application implementation is responsible for freeing
+ * any resources consumed by the session being closed. Note that the Trusted
+ * Application cannot refuse to close a session, but can hold the closing until
+ * it returns from TA_CloseSessionEntryPoint. This is why this function cannot
+ * return an error code.
+ *
+ * @param[in] sessionContext The value of the void* opaque data pointer set by
+ * the Trusted Application in the function @ref TA_OpenSessionEntryPoint for
+ * this session.
+ *
+ * @return his function can return no success or error code.
+ *
+ */
+void TA_EXPORT TA_CloseSessionEntryPoint(const void* sessionContext);
+
+/**
+ * Invokes a command within the given sessionContext
+ *
+ * The Framework calls the function TA_InvokeCommandEntryPoint when the client
+ * invokes a command within the given session. The Trusted Application can
+ * access the parameters sent by the client through the paramTypes and params
+ * arguments. It can also use these arguments to transfer response data back to
+ * the client. During the call to TA_InvokeCommandEntryPoint the client may
+ * request to cancel the operation. A command is always invoked within the
+ * context of a client session. Thus, any session function can be called by the
+ * command implementation.
+ *
+ * @param[in] sessionContext The value of the void* opaque data pointer set by
+ * the rusted Application in the function @ref TA_OpenSessionEntryPoint
+ * @param[in] commandID A Trusted Application-specific code that identifies the
+ * command to be invoked
+ * @param[in] paramTypes The types of the four parameters.
+ * @param[in,out] params A pointer to an array of four parameters.
+ *
+ * @return TEE_SUCCESS if the command is successfully executed, the function
+ * must return this value, and any other value if the invocation of the command
+ * fails for any reason. The error code may be one of the pre-defined codes, or
+ * may be a new error code defined by the Trusted Application implementation
+ * itself. In any case, the Implementation reports the error code to the client
+ * with the origin @ref TEEC_ORIGIN_TRUSTED_APP.
+ */
+TEE_Result TA_EXPORT TA_InvokeCommandEntryPoint(const void* sessionContext,
+    uint32_t commandID,
+    uint32_t paramTypes,
+    TEE_Param params[4]);
+
+/******************************************************************************
+ *  4.4 Property Access Functions
+ ******************************************************************************/
+
+/**
+ * Retrieves an individual property
+ *
+ * The TEE_GetPropertyAsString function performs a lookup in a property set to
+ * retrieve an individual property and convert its value into a printable
+ * string. When the lookup succeeds, the implementation converts the property
+ * into a printable string and copy the result into the buffer described by
+ * valueBuffer and valueBufferLen.
+ *
+ * @param[in] name A pointer to the zero-terminated string containing the name
+ * of the property to retrieve. Its content is case-sensitive and it must be
+ * encoded in UTF-8.
+ * @param[out] valueBuffer Output buffer for the property value
+ * @param[in] valueBufferLen Size of output buffer for the property value
+ *
+ * @return EE_SUCCESS:In case of success , EE_ERROR_ITEM_NOT_FOUND: i the
+ *property is not found or if name is not a valid UTF-8 encoding ,
+ *TEE_ERROR_SHORT_BUFFER: i the value buffer is not large enough to hold the
+ *whole property value .
+ */
+TEE_Result __TEE_SetProperty(
+// TEE_UUID *uuid,
+const char *name,
+    char *valueBuffer,
+    size_t valueBufferLen,
+    int type);
+
+/**
+ * Retrieves property and convert its value into a tring
+ *
+ * The TEE_GetPropertyAsString function performs a lookup in a property set to
+ * retrieve an individual property and convert its value into a printable
+ * string. When the lookup succeeds, the implementation converts the property
+ * into a printable string and copy the result into the buffer described by
+ * valueBuffer and valueBufferLen.
+ *
+ * @param[in] propsetOrEnumerator One of the TEE_PROPSET_XXX pseudo-handles or a
+ * handle on a property enumerator
+ * @param[in] name A pointer to the zero-terminated string containing the name
+ * of the property to retrieve. Its content is case-sensitive and it must be
+ * encoded in UTF-8.
+ * @param[out] valueBuffer Output buffer for the property value
+ * @param[in] valueBufferLen: Size of output buffer for the property value
+ *
+ * @return EE_SUCCESS:Ii case of success , TEE_ERROR_ITEM_NOT_FOUND if the
+ * property is not found or if name is not a valid UTF-8 encoding,
+ * TEE_ERROR_SHORT_BUFFER if the value buffer is not large enough to hold the
+ * whole property value.
+ */
+extern TEE_Result TEE_GetPropertyAsString(TEE_PropSetHandle propsetOrEnumerator,
+    const char* name,
+    char* valueBuffer,
+    size_t* valueBufferLen);
+
+/**
+ * Retrieves property and convert its value into a Boolean
+ *
+ * The TEE_GetPropertyAsBool function retrieves a single property in a property
+ * set and converts its value to a Boolean. If a property cannot be viewed as a
+ * Boolean, this function returns TEE_ERROR_BAD_FORMAT. Otherwise, if this
+ * function succeeds, then calling the function @ref TEE_GetPropertyAsString on
+ * the same name and with a sufficiently large output buffer also succeed and
+ * return a string equal to true or false case-insensitive, depending on the
+ * value of the Boolean.
+ *
+ * @param[in] propsetOrEnumerator One of the TEE_PROPSET_XXX pseudo-handles or a
+ * handle on a property enumerator
+ * @param[in] name A pointer to the zero-terminated string containing the name
+ * of the property to retrieve. Its content is case-sensitive and must be
+ * encoded in UTF-8.
+ * @param[out] value A pointer to the variable that will contain the value of
+ * the property on success or false on error.
+ *
+ * @return EE_SUCCESS:Ii case of success , TEE_ERROR_ITEM_NOT_FOUND  if the
+ * property is not found or if name is not a valid UTF-8 encoding,
+ * TEE_ERROR_BAD_FORMAT if the property value cannot be converted to a Boolean.
+ */
+TEE_Result TEE_GetPropertyAsBool(TEE_PropSetHandle propsetOrEnumerator,
+    const char* name,
+    bool* value); // commented fix build error
+
+/**
+ * Retrieves property and convert its value to a 32-bit unsigned integer
+ *
+ *
+ * The TEE_GetPropertyAsU32 function retrieves a single property in a property
+ * set and converts its value to a 32-bit unsigned integer. If a property cannot
+ * be viewed as a 32-bit unsigned integer, this function returns
+ * TEE_ERROR_BAD_FORMAT. Otherwise, if this function succeeds, then calling the
+ * function @ref TEE_GetPropertyAsString on the same name and with a
+ * sufficiently large output buffer also succeed and return a string that is
+ * consistent with the following syntax:
+ * integer: decimal-integer | hexadecimal-integer | binary-integer
+ * decimal-integer: [0-9,_]+{K,M}?
+ * hexadecimal-integer: 0[x,X][0-9,a-f,A-F,_]+
+ * binary-integer: 0[b,B][0,1,_]+
+ * Note that the syntax allows returning the integer either in decimal,
+ * hexadecimal, or binary format, that the representation can mix cases and can
+ * include underscores to separate groups of digits, and finally that the
+ * decimal representation may use 'K' or 'M' to denote multiplication by 1024 or
+ * 1048576 respectively. For example, here are a few acceptable representations
+ * of the number 1024: "1K", "0X400", "0b100_0000_0000".
+ *
+ * @param[in] propsetOrEnumerator One of the TEE_PROPSET_XXX pseudo-handles or a
+ * handle on a property enumerator
+ * @param[in] name A pointer to the zero-terminated string containing the name of
+ * the property to retrieve. Its content is case-sensitive and must be encoded
+ * in UTF-8.
+ * @param[out] value: A pointer to the variable that will contain the value of
+ * the property on success, or zero on error.
+ *
+ * @return EE_SUCCESS:Ii case of success ,TEE_ERROR_ITEM_NOT_FOUND:Ii the
+ * roperty is not found or if name is not a valid UTF-8 encoding ,
+ * EE_ERROR_BAD_FORMAT: i the property value cannot be converted to an unsigned
+ *32-bit integer
+ */
+TEE_Result TEE_GetPropertyAsU32(TEE_PropSetHandle propsetOrEnumerator,
+    const char* name,
+    uint32_t* value);
+
+/**
+ * Retrieves property and convert its value into a binary block
+ *
+ * The function TEE_GetPropertyAsBinaryBlock retrieves an individual property
+ * and converts its value into a binary block. If a property cannot be viewed as
+ * a binary block, this function returns TEE_ERROR_BAD_FORMAT. Otherwise, if
+ * this function succeeds, then calling the function
+ * @ref TEE_GetPropertyAsString on the same name and with a sufficiently large
+ * output buffer also succeed and return a string that is consistent with a
+ * Base64 encoding of the binary block as defined in RFC 2045 [6], section 6.8
+ * but with the following tolerance:
+ * + An Implementation is allowed not to encode the final padding '='
+ * characters.
+ * + An Implementation is allowed to insert characters that are not in the
+ * Base64 character set.
+ *
+ * @param[in] propsetOrEnumerator One of the TEE_PROPSET_XXX pseudo-handles or a
+ * handle on a property enumerator
+ * @param[in] name A pointer to the zero-terminated string containing the name
+ * of the property to retrieve. Its content is case-sensitive and must be
+ * encoded in UTF-8.
+ * @param[out] valueBuffer Output buffer for the binary block
+ * @param[in] valueBufferLen Size of output buffer for the binary block
+ *
+ * @return EE_SUCCESS:Ii case of success , TEE_ERROR_ITEM_NOT_FOUND if the
+ * property is not found or if name is not a valid UTF-8 encoding,
+ * TEE_ERROR_BAD_FORMAT if the property cannot be retrieved as a binary block,
+ * TEE_ERROR_SHORT_BUFFER: If the value buffer is not large enough to hold the
+ * whole property value
+ */
+TEE_Result TEE_GetPropertyAsBinaryBlock(TEE_PropSetHandle propsetOrEnumerator,
+    const char* name,
+    void* valueBuffer,
+    size_t* valueBufferLen);
+
+/**
+ * Retrieves property and convert its value into a UUID
+ *
+ * The function TEE_GetPropertyAsUUID retrieves an individual property and
+ * converts its value into a UUID. If a property cannot be viewed as a UUID,
+ * this function returns TEE_ERROR_BAD_FORMAT. Otherwise, if this function
+ * succeeds, then calling the function @ref TEE_GetPropertyAsString on the same
+ * name and with a sufficiently large output buffer MUST also succeed and return
+ * a string that is consistent with the concrete syntax of UUIDs defined in RFC
+ * 4122. Note that this string may mix character cases.
+ *
+ * @param[in] propsetOrEnumerator One of the TEE_PROPSET_XXX pseudo-handles or
+ * a handle on a property enumerator
+ * @param[in] name A pointer to the zero-terminated string containing the name
+ * of the property to retrieve. ts content is case-sensitive and must be
+ *encoded in UTF-8.
+ * @param[out] value A pointer filled with the UUID. Must not be NULL.
+ *
+ * @return EE_SUCCESS:Ii case of success, TEE_ERROR_ITEM_NOT_FOUND  if the
+ * property is not found or if name is not a valid UTF-8 encoding,
+ * TEE_ERROR_BAD_FORMAT  if the property cannot be converted into a UUID
+ */
+TEE_Result TEE_GetPropertyAsUUID(TEE_PropSetHandle propsetOrEnumerator,
+    const char* name,
+    TEE_UUID* value);
+
+/**
+ * Retrieves property and convert its value into a into a TEE_Identity
+ *
+ * The function TEE_GetPropertyAsIdentity retrieves an individual property and
+ * converts its value into a TEE_Identity. If this function succeeds then
+ * retrieving the property as a printable string using
+ * @ref TEE_GetPropertyAsString must return a string consistent with the
+ * following syntax: identity: integer (':' uuid)? where: The integer is
+ * consistent with the integer syntax described in the specification of the
+ * function @ref TEE_GetPropertyAsU32. If the identity UUID is Nil, then it can
+ * be omitted from the string representation of the property.
+ *
+ * @param[in] propsetOrEnumerator One of the TEE_PROPSET_XXX pseudo-handles or a
+ * handle on a property enumerator
+ * @param[in] name A pointer to the zero-terminated string containing the name
+ * of the property to retrieve. Its content is case-sensitive and must be
+ * encoded in UTF-8.
+ * @param[in] value A pointer filled with the identity. Must not be NULL.
+ * @return EE_SUCCESS: i case of success , TEE_ERROR_ITEM_NOT_FOUND if the
+ * property is not found or if name is not a valid UTF-8 encoding,
+ * TEE_ERROR_BAD_FORMAT if the property value cannot be converted into an
+ * Identity
+ */
+TEE_Result TEE_GetPropertyAsIdentity(TEE_PropSetHandle propsetOrEnumerator,
+    const char* name,
+    TEE_Identity* value);
+
+/**
+ * Allocates a property enumerator object
+ *
+ * The function TEE_AllocatePropertyEnumerator allocates a property enumerator
+ * object. Once a handle on a property enumerator has been allocated, it can be
+ * used to enumerate properties in a property set using the function
+ * @ref TEE_StartPropertyEnumerator.
+ *
+ * @param[in] enumerator A pointer filled with an opaque handle on the property
+ * enumerator on success and with TEE_HANDLE_NULL on error
+ * @return EE_SUCCESS: In case of success ; TEE_ERROR_OUT_OF_MEMORY: If there
+ * are not enough resources to allocate the property enumerator
+ */
+TEE_Result TEE_AllocatePropertyEnumerator(TEE_PropSetHandle* enumerator);
+
+/**
+ * Deallocates a property enumerator object
+ *
+ * The function TEE_FreePropertyEnumerator deallocates a property enumerator
+ * object.
+ * @param[in] enumerator A handle on the enumerator to free
+ */
+void TEE_FreePropertyEnumerator(TEE_PropSetHandle enumerator);
+
+/**
+ * Starts to enumerate the properties in an enumerator
+ *
+ * The function TEE_StartPropertyEnumerator starts to enumerate the properties
+ * in an enumerator. Once an enumerator is attached to a property set:
+ *
+ * + Properties can be retrieved using one of the TEE_GetPropertyAsXXX
+ * functions, passing the enumerator handle as the property set and NULL as the
+ * name.
+ *
+ * + The function @ref TEE_GetPropertyName can be used to retrieve the name of
+ * the current property in the enumerator.
+ *
+ * + The function @ref TEE_GetNextProperty can be used to advance the
+ * enumeration to the next property in the property set.
+ *
+ * @param[in] enumerator A handle on the enumerator
+ * @param[in] propSet A pseudo-handle on the property set to enumerate. Must be
+ * one of the TEE_PROPSET_XXX pseudo-handles.
+ */
+void TEE_StartPropertyEnumerator(TEE_PropSetHandle enumerator,
+    TEE_PropSetHandle propSet);
+
+/**
+ * Resets a property enumerate to its state
+ *
+ * The function TEE_ResetPropertyEnumerator resets a property enumerate to its
+ * state immediately after allocation. If an enumeration is currently started,
+ * it is abandoned.
+ *
+ * @param[in] enumerator A handle on the enumerator to reset
+ */
+void TEE_ResetPropertyEnumerator(TEE_PropSetHandle enumerator);
+
+/**
+ * Gets the name of the current property
+ *
+ * The function TEE_GetPropertyName gets the name of the current property in an
+ * enumerator. The property name must the valid UTF-8 encoding of a Unicode
+ * string containing no U+0000 code points.
+ *
+ * @param[in] enumerator A handle on the enumerator
+ * @param[out] nameBufferThe The buffer filled with the name
+ * @param[in] nameBufferLen: Length of the buffer allocated by user
+ *
+ * @return TEE_SUCCESS: In case of success , TEE_ERROR_ITEM_NOT_FOUND: If there
+ * is no current property either because the enumerator has not started or
+ * because it has reached the end of the property set, TEE_ERROR_SHORT_BUFFER:
+ * If the name buffer is not large enough to contain the property name
+ */
+TEE_Result TEE_GetPropertyName(TEE_PropSetHandle enumerator,
+    void* nameBuffer,
+    size_t* nameBufferLen);
+
+/**
+ * Advances the enumerator to the next property
+ *
+ * The function TEE_GetNextProperty advances the enumerator to the next
+ * property.
+ *
+ * @param[in] enumerator A handle on the enumerator
+ *
+ * @return EE_SUCCESS: In case of success , TEE_ERROR_ITEM_NOT_FOUND: If the
+ * enumerator has reached the end of the property set or if it has not started
+ */
+TEE_Result TEE_GetNextProperty(TEE_PropSetHandle enumerator);
+
+/******************************************************************************
+ *  4.5 Trusted Application Configuration Properties
+ ******************************************************************************/
+
+/******************************************************************************
+ *  4.6 Client Properties
+ ******************************************************************************/
+
+/******************************************************************************
+ *  4.7 Implementation Properties
+ ******************************************************************************/
+
+/******************************************************************************
+ *  4.8 Panics
+ ******************************************************************************/
+/**
+ * Raises a Panic in the Trusted Application instance
+ *
+ * The TEE_Panic function raises a Panic in the Trusted Application instance.
+ * When a Trusted Application calls the TEE_Panic function, the current instance
+ * is destroyed and all the resources opened by the instance are reclaimed. All
+ * sessions opened from the panicking instance on another TA must be gracefully
+ * closed and all cryptographic objects and operations must be closed properly.
+ * When an instance panics, its clients receive the error code
+ * TEE_ERROR_TARGET_DEAD of origin TEE_ORIGIN_TEE until they close their
+ * session. This applies to Rich Execution Environment clients calling through
+ * the TEE Client API and to Trusted Execution Environment clients calling
+ * through the Internal Client API. Once an instance is panicked, no TA entry
+ * point is ever called again for this instance, not even TA_DestroyEntryPoint.
+ * The caller cannot expect that the TEE_Panic function will return.
+ *
+ * @param[in] panicCode An informative panic code defined by the TA. May be
+ * displayed in traces if traces are available.
+ */
+void TEE_Panic(TEE_Result panicCode);
+
+/******************************************************************************
+ *  4.9 Internal Client API
+ ******************************************************************************/
+/**
+ * Opens a new session with a Trusted Application. (Not implemented yet!)
+ *
+ * The function TEE_OpenTASession opens a new session with a Trusted Application.
+ * The destination Trusted Application is identified by its UUID passed in
+ * destination. This UUID can be hardcoded in the caller code. An initial set of
+ * four parameters can be passed during the operation. The result of this function
+ * is returned both in the return value and the return origin, stored in the
+ * variable pointed to by returnOrigin:
+ *
+ * + If the return origin is different from TEE_ORIGIN_TRUSTED_APP,
+ * then the function has failed before it could reach the target Trusted
+ * Application. The possible error codes are listed in "Return Value" below.
+ *
+ * + If the return origin is TEE_ORIGIN_TRUSTED_APP, then the meaning of the return
+ * value depends on the protocol exposed by the target Trusted Application.
+ *
+ * However, if TEE_SUCCESS is returned, it always means that the session was
+ * successfully opened and if the function returns a value different from
+ * TEE_SUCCESS, it means that the session opening failed. When the session is
+ * successfully opened, i.e., when the function returns TEE_SUCCESS, a valid
+ * session handle is written into *session. Otherwise, the value TEE_HANDLE_NULL is
+ * written into *session. When a session is to be closed, the client Trusted
+ * Application must call the function @ref TEE_CloseTASession with the session
+ * handle.
+ *
+ * @param[in] destination A pointer to a TEE_UUID structure containing the UUID of
+ * the destination Trusted Application
+ * @param[in] cancellationRequestTimeout Timeout in milliseconds or the special
+ * value TEE_TIMEOUT_INFINITE if there is no timeout. After the timeout expires, a
+ * cancellation request for the operation must be automatically sent.
+ * @param[in] paramTypes The types of all parameters passed in the operation.
+ * @param[in,out] params: The parameters passed in the operation.
+ * @param[out] session: A pointer to a variable that will receive the client
+ * session handle. The pointer must not be NULL. The value is set to
+ * TEE_HANDLE_NULL upon error.
+ * @param[out] returnOrigin A pointer to a variable which will contain the return
+ * origin. This field may be NULL if the return origin is not needed.
+ *
+ * @return f the return origin is different from TEE_ORIGIN_TRUSTED_APP, one of
+ * he following error codes can be returned:
+ *
+ * + TEE_ERROR_OUT_OF_MEMORY: If not enough resources are available to open the
+ * session
+ *
+ * + TEE_ERROR_ITEM_NOT_FOUND: If no Trusted Application matches the requested
+ * destination UUID
+ *
+ * + TEE_ERROR_ACCESS_DENIED: If access to the destination Trusted Application is
+ * denied
+ *
+ * + TEE_ERROR_BUSY: If the destination Trusted Application does not allow more
+ * than one session at a time  and already has a session in progress
+ *
+ * + TEE_ERROR_TARGET_DEAD: If the destination Trusted Application has panicked
+ * during the operation
+ */
+TEE_Result TEE_OpenTASession(const TEE_UUID* destination,
+    uint32_t cancellationRequestTimeout,
+    uint32_t paramTypes,
+    TEE_Param params[4],
+    TEE_TASessionHandle* session,
+    uint32_t* returnOrigin);
+
+/**
+ * Closes a client session (Not implemented yet!)
+ *
+ * The function TEE_CloseTASession closes a client session.
+ *
+ * @param[in] session An opened session handle
+ */
+void TEE_CloseTASession(TEE_TASessionHandle session);
+
+/**
+ * Invokes a command within a session opened between the client (Not implemented
+ * yet!)
+ *
+ * The function TEE_InvokeTACommand invokes a command within a session opened
+ * between the client. Trusted Application instance and a destination Trusted
+ * Application instance. The parameter session must reference a valid session
+ * handle opened by @ref TEE_OpenTASession. Up to four parameters can be passed
+ * during the operation. The result of this function is returned both in the
+ * return value and the return origin, stored in the variable pointed to by
+ * returnOrigin:
+ *
+ * + If the return origin is different from TEE_ORIGIN_TRUSTED_APP, then the
+ * function has failed before it could reach the destination Trusted
+ * Application. The possible error codes are listed in "Return Value" below.
+ *
+ * + If the return origin is TEE_ORIGIN_TRUSTED_APP, then the meaning of the
+ * return value is determined by the protocol exposed by the destination Trusted
+ * Application. It is recommended that the Trusted Application developer choose
+ * TEE_SUCCESS (0) to indicate success in their protocol, as this makes it
+ * possible to determine success or failure without looking at the return
+ * origin.
+ *
+ * @param[in] session: An opened session handle
+ * @param[in] cancellationRequestTimeout: Timeout in milliseconds or the special
+ * value TEE_TIMEOUT_INFINITE if there is no timeout. After the timeout expires,
+ * a cancellation request for the operation must be automatically sent.
+ * @param[in] commandID: The identifier of the Command to invoke. The meaning of
+ * each Command Identifier must be defined in the protocol exposed by the target
+ * Trusted Application.
+ * @param[in] paramTypes: The types of all parameters passed in the operation.
+ * @param[in] params: The parameters passed in the operation.
+ * @param[out] returnOrigin: A pointer to a variable which will contain the
+ * return origin. This field may be NULL if the return origin is not needed.
+ *
+ * @return If the return origin is different from TEE_ORIGIN_TRUSTED_APP, one of
+ * the following error codes can be returned: TEE_ERROR_OUT_OF_MEMORY: If not
+ * enough resources are available to perform the operation;
+ * TEE_ERROR_TARGET_DEAD: If the destination Trusted Application has panicked
+ * during the operation
+ */
+TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
+    uint32_t cancellationRequestTimeout,
+    uint32_t commandID,
+    uint32_t paramTypes,
+    TEE_Param params[4],
+    uint32_t* returnOrigin);
+
+/******************************************************************************
+ *  4.10 Cancellation Functions
+ ******************************************************************************/
+/**
+ * Determines whether the current task's Cancellation Flag is set
+ *
+ * The TEE_GetCancellationFlag function determines whether the current task's
+ * Cancellation Flag is set. If cancellations are masked, this function must
+ * return false.
+ *
+ * @return 'false' if the cancellation flag is not set or if cancellations are
+ * masked; 'true' if the cancellation flag is set and cancellations are not
+ * masked
+ */
+bool TEE_GetCancellationFlag(void);
+
+/**
+ * Unmasks the effects of cancellation
+ *
+ * The TEE_UnmaskCancellation function unmasks the effects of cancellation for
+ * the current task. When cancellation requests are unmasked, the Cancellation
+ * Flag interrupts cancellable functions such as @ref TEE_Wait and requests the
+ * cancellation of operations started with @ref TEE_OpenTASession or
+ * @ref TEE_InvokeTACommand. By default, tasks created to handle a TA entry
+ * point have cancellation masked, so that a TA does not have to cope with the
+ * effects of cancellation requests.
+ * @return 'true' if cancellations were masked prior to calling this function;
+ * 'false' otherwise
+ */
+bool TEE_UnmaskCancellation(void);
+
+/**
+ * Masks the effects of cancellation
+ *
+ * The TEE_MaskCancellation function masks the effects of cancellation for the
+ * current task. When cancellation requests are masked, the Cancellation Flag
+ * does not have an effect on the cancellable functions and cannot be retrieved
+ * using @ref TEE_GetCancellationFlag. By default, tasks created to handle a TA
+ * entry point have cancellation masked, so that a TA does not have to cope with
+ * the effects of cancellation requests.
+ *
+ * @return 'true' if cancellations were masked prior to calling this function;
+ * 'false' otherwise
+ */
+bool TEE_MaskCancellation(void);
+
+/******************************************************************************
+ *  4.11 Memory Management Functions
+ ******************************************************************************/
+
+#define HINT_FILL_WITH_ZEROS           0
+#define HINT_DEFAULT                   0xFFFFFFFF
+
+#define UUID_STRING_LEN                        37
+extern char *uuid2string(char *str, const TEE_UUID *uuid);
+extern int string2uuid(TEE_UUID *uu, const char *in);
+
+enum {
+       TEE_MEMORY_ACCESS_READ = 1,
+       TEE_MEMORY_ACCESS_WRITE = 2,
+       TEE_MEMORY_ACCESS_ANY_OWNER = 4
+};
+
+/**
+ * Checks specified buffer for access rights
+ *
+ * The TEE_CheckMemoryAccessRights function causes the Implementation to examine
+ * a buffer of memory specified in the parameters buffer and size and to
+ * determine whether the current Trusted Application instance has the access
+ * rights requested in the parameter accessFlags. If the characteristics of the
+ * buffer are compatible with accessFlags, then the function returns
+ * TEE_SUCCESS. Otherwise, it returns TEE_ERROR_ACCESS_DENIED. Note that the
+ * buffer should not be accessed by the function, but the Implementation should
+ * check the access rights based on the address of the buffer and internal
+ * memory management information.
+ * This function MUST NOT panic for any reason.
+ *
+ * @param[in] buffer Pointer to the buffer to check
+ * @param[in] size Size of the buffer to check
+ * @param[in] accessFlags The access flags to check
+ *
+ * @return TEE_SUCCESS: If the entire buffer allows the requested accesses or
+ * TEE_ERROR_ACCESS_DENIED: If at least one byte in the buffer is not accessible
+ * with the requested accesses
+ */
+TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags,
+    void* buffer,
+    size_t size);
+
+/**
+ *  Provides an alternative to writable global data
+ *
+ * The TEE_SetInstanceData and TEE_GetInstanceData functions provide an
+ * alternative to writable global data (writable variables with global scope and
+ * writable static variables with global or function scope). While an
+ * Implementation supports C global variables, using these functions may be
+ * sometimes more efficient, especially if only a single instance data variable
+ * is required.
+ *
+ * @param[in] instanceData A pointer to the global Trusted Application instance
+ * data. This pointer may be NULL.
+ */
+void TEE_SetInstanceData(void* instanceData);
+
+/**
+ * Retrieves the instance data pointer
+ *
+ * The TEE_GetInstanceData function retrieves the instance data pointer set by
+ * the Trusted Application using the @ref TEE_GetInstanceData function.
+ *
+ * @return The value returned is the previously set pointer to the Trusted
+ * Application instance data, or NULL if no instance data pointer has yet been
+ * set.
+ */
+void* TEE_GetInstanceData(void);
+
+/**
+ * Allocates space for an object
+ *
+ * The TEE_Malloc function allocates space for an object whose size in bytes is
+ * specified in the parameter size.
+ *
+ * @param[in] size The size of the buffer to be allocated.
+ * @param[in] hint A hint to the allocator. Currently defined values are as
+ * follows:
+ *
+ * + The default value, 0, guarantees that the returned block of memory is
+ * filled with zeros.
+ *
+ * + Values in the range [0x00000001, 0x7FFFFFFF] are reserved for future
+ * version of this specification.
+ *
+ * + Values in the range [0x80000000, 0xFFFFFFFF] can be used for
+ * implementation-defined hints.
+ *
+ * @return Upon successful completion, with size not equal to zero, the function
+ * returns a pointer to the allocated space. If the space cannot be allocated, a
+ * NULL pointer is returned.
+ */
+extern void* TEE_Malloc(size_t size, uint32_t hint);
+
+/**
+ * Changes the size of the memory object
+ *
+ * The TEE_Realloc function changes the size of the memory object pointed to by
+ * buffer to the size specified by nNewSize.
+ *
+ * @param[in] buffer: The pointer to the object to be reallocated
+ * @param[in] newSize: The new size required for the object
+ *
+ * @return Upon successful completion, TEE_Realloc returns a pointer to the
+ * (possibly moved) allocated space. If there is not enough available memory,
+ * TEE_Realloc returns a NULL pointer.
+ */
+extern void* TEE_Realloc(const void* buffer, uint32_t newSize);
+
+/**
+ * Causes the space pointed to by buffer to be deallocated
+ *
+ * The TEE_Free function causes the space pointed to by buffer to be
+ * deallocated; that is, made available for further allocation. If buffer is a
+ * NULL pointer, TEE_Free does nothing. Otherwise, it is a Programmer Error
+ * if the argument does not match a pointer previously returned by the
+ * @ref TEE_Malloc or @ref TEE_Realloc, or if the space has been deallocated by
+ * a call to TEE_Free or @ref TEE_Realloc.
+ *
+ * @param[in] buffer The pointer to the memory block to be freed
+ */
+extern void TEE_Free(const void *buffer);
+
+/**
+ * Copies size bytes from one object to another
+ *
+ * The TEE_MemMove function copies size bytes from the object pointed to by src
+ * into the object pointed to by dest. Note that the buffers dest and src can
+ * reside in any kinds of memory, including shared memory.
+ *
+ * @param[in] dest A pointer to the destination buffer
+ * @param[in] src A pointer to the source buffer
+ * @param[in] size The number of bytes to be copied
+ */
+void TEE_MemMove(void* dest, const void* src, uint32_t size);
+
+/**
+ * Compares bytes of one object to another
+ *
+ * The TEE_MemCompare function compares the first size bytes of the object
+ * pointed to by buffer1 to the first size bytes of the object pointed to by
+ * buffer2. Note that buffer1 and buffer2 can reside in any kinds of memory,
+ * including shared memory.
+ *
+ * @param[in] buffer1 A pointer to the first buffer
+ * @param[in] buffer2 A pointer to the second buffer
+ * @param[in] size The number of bytes to be compared
+ *
+ * @return The sign of a non-zero return value is determined by the sign of the
+ * difference between the values of the first pair of bytes (both interpreted as
+ * type uint8_t) that differ in the objects being compared.
+ *
+ * + If the first byte that differs is higher in buffer1, then return an integer
+ * greater than zero.
+ *
+ * + If the first size bytes of the two buffers are identical, then return zero.
+ *
+ * + If the first byte that differs is higher in buffer2, then return an integer
+ * lower than zero.
+ */
+int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size);
+
+/**
+ * Writes the byte x into the object
+ *
+ * The TEE_MemFill function writes the byte x (converted to a uint8_t) into the
+ * first size bytes of the object pointed to by buffer. Note that buffer can
+ * reside in any kinds of memory, including shared memory.
+ *
+ * @param[in] buffer A pointer to the destination buffer
+ * @param[in] x The value to be set
+ * @param[in] size The number of bytes to be set
+ */
+void TEE_MemFill(void* buffer, uint32_t x, uint32_t size);
+
+/******************************************************************************
+ *  5 Trusted Storage API for Data and Keys
+ ******************************************************************************/
+
+/******************************************************************************
+ *  5.2 Data Types
+ ******************************************************************************/
+
+typedef struct {
+       uint32_t attributeID;
+       union {
+               struct {
+                       const void* buffer;
+                       size_t length;
+               } ref;
+               struct {
+                       uint32_t a, b;
+               } value;
+       } content;
+} TEE_Attribute;
+
+typedef struct {
+       uint32_t objectType;
+       uint32_t objectSize;
+       uint32_t maxObjectSize;
+       uint32_t objectUsage;
+       uint32_t dataSize;
+       uint32_t dataPosition;
+       uint32_t handleFlags;
+} TEE_ObjectInfo;
+
+typedef enum {
+       TEE_DATA_SEEK_SET = 0, TEE_DATA_SEEK_CUR, TEE_DATA_SEEK_END
+} TEE_Whence;
+
+typedef struct __TEE_ObjectHandle* TEE_ObjectHandle;
+
+typedef struct __TEE_ObjectEnumHandle* TEE_ObjectEnumHandle;
+
+/******************************************************************************
+ *  5.3 Constants
+ ******************************************************************************/
+
+#define TEE_STORAGE_PRIVATE                    0x00000001
+
+// Data Flag Constants
+#define TEE_DATA_FLAG_ACCESS_READ              0x00000001
+#define TEE_DATA_FLAG_ACCESS_WRITE             0x00000002
+#define TEE_DATA_FLAG_ACCESS_WRITE_META        0x00000004
+#define TEE_DATA_FLAG_SHARE_READ               0x00000010
+#define TEE_DATA_FLAG_SHARE_WRITE              0x00000020
+#define TEE_DATA_FLAG_CREATE                   0x00000200
+#define TEE_DATA_FLAG_EXCLUSIVE                        0x00000400
+
+// Usage Constants
+#define TEE_USAGE_EXTRACTABLE                  0x00000001
+#define TEE_USAGE_ENCRYPT                      0x00000002
+#define TEE_USAGE_DECRYPT                      0x00000004
+#define TEE_USAGE_MAC                          0x00000008
+#define TEE_USAGE_SIGN                         0x00000010
+#define TEE_USAGE_VERIFY                       0x00000020
+#define TEE_USAGE_DERIVE                       0x00000040
+
+// Handle Flag Constants
+#define TEE_HANDLE_FLAG_PERSISTENT             0x00010000
+#define TEE_HANDLE_FLAG_INITIALIZED            0x00020000
+#define TEE_HANDLE_FLAG_KEY_SET                        0x00040000
+#define TEE_HANDLE_FLAG_EXPECT_TWO_KEYS                0x00080000
+
+// Operation Constants
+#define TEE_OPERATION_CIPHER                   1
+#define TEE_OPERATION_MAC                      3
+#define TEE_OPERATION_AE                       4
+#define TEE_OPERATION_DIGEST                   5
+#define TEE_OPERATION_ASYMMETRIC_CIPHER                6
+#define TEE_OPERATION_ASYMMETRIC_SIGNATURE     7
+#define TEE_OPERATION_KEY_DERIVATION           8
+
+// Miscellaneous Constants
+#define TEE_DATA_MAX_POSITION                  0xFFFFFFFF
+#define TEE_OBJECT_ID_MAX_LEN                  64
+
+/******************************************************************************
+ *  5.4 Generic Object Functions
+ ******************************************************************************/
+
+/**
+ * Returns the characteristics of an object
+ *
+ * The TEE_GetObjectInfo function returns the characteristics of an object.
+ *
+ * @param[in] object Handle of the object
+ * @param[in] objectInfo Pointer to a structure filled with the object
+ * information
+ */
+void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo* objectInfo);
+
+/**
+ * Restricts the object usage
+ *
+ * The TEE_RestrictObjectUsage function restricts the object usage flags of an
+ * object handle to contain at most the flags passed in the objectUsage
+ * parameter.
+ *
+ * @param[in] object: Handle on an object
+ * @param[in] objectUsage: New object usage, an OR combination of one or more of
+ * the TEE_USAGE_XXX constants
+ */
+void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage);
+
+/**
+ * Extracts one buffer attribute from an object
+ *
+ * The TEE_GetObjectBufferAttribute function extracts one buffer attribute from
+ * an object.
+ *
+ * Panic Reasons
+ *
+ * + object is not a valid opened object handle.
+ *
+ * + The object is not initialized.
+ *
+ * + Bit [29] of attributeID is not set to 0, so the attribute is not a buffer
+ * attribute
+ *
+ * + Bit [28] of attributeID is set to 1, denoting a protected attribute, and
+ * the object usage does not contain the TEE_USAGE_EXTRACTABLE flag.
+ *
+ * @param[in] object: Handle of the object
+ * @param[in] attributeID: Identifier of the attribute to retrieve
+ * @param[in] buffer, size: Output buffer to get the content of the attribute
+ *
+ * @return TEE_SUCCESS: In case of success; TEE_ERROR_ITEM_NOT_FOUND: If the
+ * attribute is not found on this object or if the object is a transient
+ * uninitialized object; TEE_ERROR_SHORT_BUFFER: If buffer is NULL or too small
+ * to contain the key part
+ */
+TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
+    uint32_t attributeID,
+    void* buffer,
+    size_t* size);
+
+/**
+ * Extracts a value attribute from an object
+ *
+ * The TEE_GetObjectValueAttribute function extracts a value attribute from an
+ * object.
+ *
+ * Panic Reasons
+ * + object is not a valid opened object handle.
+ *
+ * + The object is not initialized.
+ *
+ * + Bit [29] of attributeID is not set to 1, so the attribute is not a value
+ * attribute.
+ *
+ * + Bit [28] of attributeID is set to 1, denoting a protected attribute, and
+ * the object usage does not contain the TEE_USAGE_EXTRACTABLE flag.
+ *
+ * @param[in] object Handle of the object
+ *
+ * @param[in] attributeID Identifier of the attribute to retrieve
+ *
+ * @param[in] a, @param[in] b Pointers on the placeholders filled with the
+ * attribute field a and b. Each can be NULL if the corresponding field is not
+ * of interest to the caller.
+ *
+ * @return TEE_SUCCESS: In case of success; TEE_ERROR_ITEM_NOT_FOUND: If the
+ * attribute is not found on this object or if the object is a transient
+ * uninitialized object; TEE_ERROR_ACCESS_DENIED: For an attempt to extract a
+ * secret part of a non-extractable container
+ */
+TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
+    uint32_t attributeID,
+    uint32_t* a,
+    uint32_t* b);
+
+/**
+ * closes an opened object handle
+ *
+ * The TEE_CloseObject function closes an opened object handle. The object can
+ * be persistent or transient.
+ * Panic Reasons object is not a valid opened object handle and is not equal to
+ * TEE_HANDLE_NULL.
+ *
+ * @param[in] object Handle on the object to close. If set to TEE_HANDLE_NULL,
+ * does nothing.
+ */
+void TEE_CloseObject(TEE_ObjectHandle object);
+
+/******************************************************************************
+ *  5.5 Transient Object Functions
+ ******************************************************************************/
+
+/**
+ * Allocates an uninitialized transient object
+ *
+ * The TEE_AllocateTransientObject function allocates an uninitialized transient
+ * object, i.e., a container for attributes. Transient objects are used to hold
+ * a cryptographic object (key or key-pair). The object type and the maximum
+ * object characteristic size must be specified so that all the container
+ * resources can be pre-allocated. Note that a compliant Implementation must
+ * implement all the object types, algorithms, and object sizes
+ *
+ * @param[in] objectType: Type of uninitialized object container to be created
+ * @param[in] maxObjectSize: Size of the object. The interpretation of this
+ * parameter depends on the object type.
+ * @param[out] object: Filled with a handle on the newly created key container
+ *
+ * @return TEE_SUCCESS: On success; TEE_ERROR_OUT_OF_MEMORY: If not enough
+ * resources are available to allocate the object handle;
+ * TEE_ERROR_NOT_SUPPORTED: If the object size is not supported.
+ */TEE_Result TEE_AllocateTransientObject(uint32_t objectType,
+    uint32_t maxObjectSize,
+    TEE_ObjectHandle* object);
+
+/*
+ * Description
+ * The TEE_FreeTransientObject function deallocates a transient object previously allocated with TEE_AllocateTransientObject.
+ * After this function has been called, the object handle is no longer valid and all resources associated with the transient object
+ * must have been reclaimed.
+ * If the object is initialized, the object attributes are cleared before the object is deallocated.
+ * This function cannot fail. It does nothing if object is TEE_HANDLE_NULL.
+ * Parameters
+ * + object: Handle on the object to free
+ * Panic Reasons
+ * + object is not a valid opened object handle and is not equal to TEE_HANDLE_NULL.
+ */
+void TEE_FreeTransientObject(TEE_ObjectHandle object);
+
+/*
+ * Description
+ * The TEE_ResetTransientObject function resets a transient object to its initial state after allocation.
+ * If the object is currently initialized, the function clears the object of all its material.
+ * The object is then uninitialized again.
+ * In any case, the function resets the key usage of the container to 0xFFFFFFFFF.
+ * This function does nothing if object is set to TEE_HANDLE_NULL.
+ * Parameters
+ * + object: Handle on a transient object to reset
+ * Panic Reasons
+ * + object is not a valid opened object handle and is not equal to TEE_HANDLE_NULL.
+ */
+void TEE_ResetTransientObject(TEE_ObjectHandle object);
+
+/*
+ * Description
+ * The TEE_PopulateTransientObject function populates an uninitialized object container
+ * with object attributes passed by the TA in the attrs parameter.
+ * Parameters
+ * + object: Handle on an already created transient and uninitialized object
+ * + attrs, attrCount: Array of object attributes
+ * Return Value
+ * + TEE_SUCCESS: In case of success. In this case, the content of the object MUST be initialized.
+ * + TEE_ERROR_BAD_PARAMETERS: If an incorrect or inconsistent attribute value is detected.
+ *     In this case, the content of the object container MUST remain uninitialized.
+ * Panic Reasons
+ * + object is not a valid opened object handle that is transient and uninitialized.
+ * + Some mandatory attribute is missing.
+ */
+TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
+    const TEE_Attribute* attrs,
+    uint32_t attrCount);
+
+/*
+ * Description
+ * The TEE_InitRefAttribute and TEE_InitValueAttribute helper functions can be used to populate a single
+ * attribute either with a reference to a buffer or with integer values.
+ *
+ */
+
+void TEE_InitRefAttribute(TEE_Attribute* attr,
+    uint32_t attributeID,
+    const void* buffer,
+    size_t length);
+
+void TEE_InitValueAttribute(TEE_Attribute* attr,
+    uint32_t attributeID,
+    uint32_t a,
+    uint32_t b);
+
+/*
+ * Description
+ * The TEE_CopyObjectAttributes function populates an uninitialized object handle with the attributes of another object handle;
+ * that is, it populates the attributes of destObject with the attributes of srcObject. It is most useful in the following situations:
+ * Parameters
+ * + destObject: Handle on an uninitialized transient object
+ * + srcObject: Handle on an initialized object
+ * Panic Reasons
+ * + srcObject is not initialized.
+ * + destObject is not uninitialized.
+ * + The type and size of srcObject and destObject are not compatible.
+ * */
+void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
+    TEE_ObjectHandle srcObject);
+
+/*
+ * Description
+ * The TEE_GenerateKey function generates a random key or a key-pair and populates a transient key object with the generated key material.
+ * Parameters
+ * + object: Handle on an uninitialized transient key to populate with the generated key
+ * + keySize: Requested key size. Must be less than or equal to the maximum size of the object container.
+ * + params, paramCount: Parameters for the key generation
+ * Return Value
+ * + TEE_SUCCESS: On success
+ * + TEE_ERROR_BAD_PARAMETERS: If an incorrect or inconsistent attribute is detected
+ * Panic Reasons
+ * + object is not a valid opened object handle that is transient and uninitialized.
+ * + keySize is too large.
+ + A mandatory parameter is missing.
+ */
+TEE_Result TEE_GenerateKey(TEE_ObjectHandle object,
+    uint32_t keySize,
+    const TEE_Attribute* params,
+    uint32_t paramCount);
+
+/******************************************************************************
+ *  5.6 Persistent Object Functions
+ ******************************************************************************/
+
+TEE_Result TEE_OpenPersistentObject(uint32_t storageID,
+    const void* objectID,
+    size_t objectIDLen,
+    uint32_t flags,
+    TEE_ObjectHandle* object);
+
+TEE_Result TEE_CreatePersistentObject(uint32_t storageID,
+    const void* objectID,
+    size_t objectIDLen,
+    uint32_t flags,
+    TEE_ObjectHandle attributes,
+    const void* initialData,
+    size_t initialDataLen,
+    TEE_ObjectHandle* object);
+TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
+    const void* newObjectID,
+    size_t newObjectIDLen);
+void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object);
+
+/******************************************************************************
+ * 5.7 Persistent Object Enumeration Functions
+ ******************************************************************************/
+
+TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle* objectEnumerator);
+void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator);
+void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator);
+TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator,
+    uint32_t storageID);
+TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
+    TEE_ObjectInfo* objectInfo,
+    void* objectID,
+    size_t* objectIDLen);
+
+/******************************************************************************
+ * 5.8 Data Stream Access Functions
+ ******************************************************************************/
+
+TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object,
+    void* buffer,
+    size_t size,
+    uint32_t* count);
+TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object,
+    const void* buffer,
+    size_t size);
+TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size);
+TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object,
+    int32_t offset,
+    TEE_Whence whence);
+
+TEE_Result storage_to_disk(void);
+TEE_Result storage_from_disk(void);
+
+/******************************************************************************
+ * 6 Cryptographic Operations API
+ ******************************************************************************/
+
+/******************************************************************************
+ * 6.1 Data Types
+ ******************************************************************************/
+
+typedef enum {
+       TEE_MODE_ENCRYPT, // Encryption mode
+       TEE_MODE_DECRYPT, // Decryption mode
+       TEE_MODE_SIGN,    // Signature generation mode
+       TEE_MODE_VERIFY,  // Signature verification mode
+       TEE_MODE_MAC,     // MAC mode
+       TEE_MODE_DIGEST,  // Digest mode
+       TEE_MODE_DERIVE   // Key derivation mode
+} TEE_OperationMode;
+
+typedef struct {
+       uint32_t algorithm;
+       uint32_t operationClass;
+       uint32_t mode;
+       uint32_t digestLength;
+       uint32_t maxKeySize;
+       uint32_t keySize;
+       uint32_t requiredKeyUsage;
+       uint32_t handleState;
+} TEE_OperationInfo;
+
+typedef struct __TEE_OperationHandle* TEE_OperationHandle;
+
+/******************************************************************************
+ * 6.2 Generic Operation Functions
+ ******************************************************************************/
+
+TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation,
+    uint32_t algorithm,
+    uint32_t mode,
+    uint32_t maxKeySize);
+void TEE_FreeOperation(TEE_OperationHandle operation);
+void TEE_GetOperationInfo(TEE_OperationHandle operation,
+    TEE_OperationInfo* operationInfo);
+void TEE_ResetOperation(TEE_OperationHandle operation);
+TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation,
+    TEE_ObjectHandle key);
+TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation,
+    TEE_ObjectHandle key1,
+    TEE_ObjectHandle key2);
+void TEE_CopyOperation(TEE_OperationHandle dstOperation,
+    TEE_OperationHandle srcOperation);
+
+/******************************************************************************
+ * 6.3 Message Digest Functions
+ ******************************************************************************/
+
+void TEE_DigestUpdate(TEE_OperationHandle operation,
+    const void* chunk,
+    size_t chunkSize);
+TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation,
+    const void* chunk,
+    size_t chunkLen,
+    void* hash,
+    size_t *hashLen);
+
+/******************************************************************************
+ * 6.4 Symmetric Cipher Functions
+ ******************************************************************************/
+
+void TEE_CipherInit(TEE_OperationHandle operation, const void* IV, size_t IVLen);
+TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t *destLen);
+TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t *destLen);
+
+/******************************************************************************
+ * 6.5 MAC Functions
+ ******************************************************************************/
+
+void TEE_MACInit(TEE_OperationHandle operation, const void* IV, size_t IVLen);
+void TEE_MACUpdate(TEE_OperationHandle operation,
+    const void* chunk,
+    size_t chunkSize);
+TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation,
+    const void* message,
+    size_t messageLen,
+    void* mac,
+    size_t *macLen);
+TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation,
+    const void* message,
+    size_t messageLen,
+    const void* mac,
+    size_t *macLen);
+
+/******************************************************************************
+ * 6.6 Authenticated Encryption Functions
+ ******************************************************************************/
+
+TEE_Result TEE_AEInit(TEE_OperationHandle operation,
+    const void* nonce,
+    size_t nonceLen,
+    uint32_t tagLen,
+    uint32_t AADLen,
+    uint32_t payloadLen);
+void TEE_AEUpdateAAD(TEE_OperationHandle operation,
+    const void* AADdata,
+    size_t AADdataLen);
+TEE_Result TEE_AEUpdate(TEE_OperationHandle operation,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t *destLen);
+TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t* destLen,
+    void* tag,
+    size_t* tagLen);
+TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t *destLen,
+    void* tag,
+    size_t tagLen);
+
+/******************************************************************************
+ * 6.7 Asymmetric Functions
+ ******************************************************************************/
+
+TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation,
+    const TEE_Attribute* params,
+    uint32_t paramCount,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t *destLen);
+
+TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation,
+    const TEE_Attribute* params,
+    uint32_t paramCount,
+    const void* srcData,
+    size_t srcLen,
+    void* destData,
+    size_t *destLen);
+TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation,
+    const TEE_Attribute* params,
+    uint32_t paramCount,
+    const void* digest,
+    size_t digestLen,
+    void* signature,
+    size_t *signatureLen);
+TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,
+    const TEE_Attribute* params,
+    uint32_t paramCount,
+    const void* digest,
+    size_t digestLen,
+    void* signature,
+    size_t signatureLen);
+
+/******************************************************************************
+ * 6.8 Key Derivation Functions
+ ******************************************************************************/
+
+void TEE_DeriveKey(TEE_OperationHandle operation,
+    const TEE_Attribute* params,
+    uint32_t paramCount,
+    TEE_ObjectHandle derivedKey);
+
+/******************************************************************************
+ * 6.9 Random Data Generation Function
+ ******************************************************************************/
+
+void TEE_GenerateRandom(void* randomBuffer, size_t randomBufferLen);
+
+/******************************************************************************
+ * 6.10 Cryptographic Algorithms Specification
+ ******************************************************************************/
+
+typedef enum {
+       TEE_ALG_AES_ECB_NOPAD = 0x10000010,
+       TEE_ALG_AES_CBC_NOPAD = 0x10000110,
+       TEE_ALG_AES_CTR = 0x10000210,
+       TEE_ALG_AES_CTS = 0x10000310,
+       TEE_ALG_AES_XTS = 0x10000410,
+       TEE_ALG_AES_CBC_MAC_NOPAD = 0x30000110,
+       TEE_ALG_AES_CBC_MAC_PKCS5 = 0x30000510,
+       TEE_ALG_AES_CMAC = 0x30000610,
+       TEE_ALG_AES_CCM = 0x40000710,
+       TEE_ALG_AES_GCM = 0x40000810,
+       TEE_ALG_DES_ECB_NOPAD = 0x10000011,
+       TEE_ALG_DES_CBC_NOPAD = 0x10000111,
+       TEE_ALG_DES_CBC_MAC_NOPAD = 0x30000111,
+       TEE_ALG_DES_CBC_MAC_PKCS5 = 0x30000511,
+       TEE_ALG_DES3_ECB_NOPAD = 0x10000013,
+       TEE_ALG_DES3_CBC_NOPAD = 0x10000113,
+       TEE_ALG_DES3_CBC_MAC_NOPAD = 0x30000113,
+       TEE_ALG_DES3_CBC_MAC_PKCS5 = 0x30000513,
+       TEE_ALG_RSASSA_PKCS1_V1_5_MD5 = 0x70001830,
+       TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 = 0x70002830,
+       TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 = 0x70003830,
+       TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 = 0x70004830,
+       TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 = 0x70005830,
+       TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 = 0x70006830,
+       TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 = 0x70212930,
+       TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 = 0x70313930,
+       TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 = 0x70414930,
+       TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 = 0x70515930,
+       TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 = 0x70616930,
+       TEE_ALG_RSAES_PKCS1_V1_5 = 0x60000130,
+       TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1 = 0x60212230,
+       TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224 = 0x60213230,
+       TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256 = 0x60214230,
+       TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384 = 0x60215230,
+       TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512 = 0x60216230,
+       TEE_ALG_RSA_NOPAD = 0x60000030,
+       TEE_ALG_DSA_SHA1 = 0x70002131,
+       TEE_ALG_DH_DERIVE_SHARED_SECRET = 0x80000032,
+       TEE_ALG_MD5 = 0x50000001,
+       TEE_ALG_SHA1 = 0x50000002,
+       TEE_ALG_SHA224 = 0x50000003,
+       TEE_ALG_SHA256 = 0x50000004,
+       TEE_ALG_SHA384 = 0x50000005,
+       TEE_ALG_SHA512 = 0x50000006,
+       TEE_ALG_HMAC_MD5 = 0x30000001,
+       TEE_ALG_HMAC_SHA1 = 0x30000002,
+       TEE_ALG_HMAC_SHA224 = 0x30000003,
+       TEE_ALG_HMAC_SHA256 = 0x30000004,
+       TEE_ALG_HMAC_SHA384 = 0x30000005,
+       TEE_ALG_HMAC_SHA512 = 0x30000006,
+#ifdef ECC_IMPLEMENTATION
+       TEE_ALG_ECDSA_P160 = 0x70000041,               //P160
+       TEE_ALG_ECDSA_P192 = 0x70001041,               //P192
+       TEE_ALG_ECDSA_P224 = 0x70002041,               //P224
+       TEE_ALG_ECDSA_P256 = 0x70003041,               //P256
+       TEE_ALG_ECDSA_P384 = 0x70004041,               //P384
+       TEE_ALG_ECDSA_P521 = 0x70005041,               //P521
+       TEE_ALG_ECDH_P192 = 0x80001042,               //P192
+       TEE_ALG_ECDH_P224 = 0x80002042,               //P224
+       TEE_ALG_ECDH_P256 = 0x80003042,               //P256
+       TEE_ALG_ECDH_P384 = 0x80004042,               //P384
+       TEE_ALG_ECDH_P521 = 0x80005042,               //P521
+#endif // ECC_IMPLEMENTATION
+#ifdef NON_GP_PADDING
+       TEE_ALG_AES_ECB_PKCS5 = 0x11000010,
+       TEE_ALG_AES_ECB_PKCS7 = 0x12000010,
+       TEE_ALG_AES_ECB_ISO9797_M1 = 0x13000010,
+       TEE_ALG_AES_ECB_ISO9797_M2 = 0x14000010,
+       TEE_ALG_AES_CBC_PKCS5 = 0x11000110,
+       TEE_ALG_AES_CBC_PKCS7 = 0x12000110,
+       TEE_ALG_AES_CBC_ISO9797_M1 = 0x13000110,
+       TEE_ALG_AES_CBC_ISO9797_M2 = 0x14000110,
+       TEE_ALG_AES_CTR_NOPAD = 0x15000210,
+#endif
+} TEE_CRYPTO_ALGORITHMS;
+
+typedef enum {
+       TEE_TYPE_AES = 0xA0000010,
+       TEE_TYPE_DES = 0xA0000011,
+       TEE_TYPE_DES3 = 0xA0000013,
+       TEE_TYPE_HMAC_MD5 = 0xA0000001,
+       TEE_TYPE_HMAC_SHA1 = 0xA0000002,
+       TEE_TYPE_HMAC_SHA224 = 0xA0000003,
+       TEE_TYPE_HMAC_SHA256 = 0xA0000004,
+       TEE_TYPE_HMAC_SHA384 = 0xA0000005,
+       TEE_TYPE_HMAC_SHA512 = 0xA0000006,
+       TEE_TYPE_RSA_PUBLIC_KEY = 0xA0000030,
+       TEE_TYPE_RSA_KEYPAIR = 0xA1000030,
+       TEE_TYPE_DSA_PUBLIC_KEY = 0xA0000031,
+       TEE_TYPE_DSA_KEYPAIR = 0xA1000031,
+       TEE_TYPE_DH_KEYPAIR = 0xA1000032,
+#ifdef ECC_IMPLEMENTATION
+       TEE_TYPE_ECDSA_PUBLIC_KEY = 0xA0000033,
+       TEE_TYPE_ECDSA_KEYPAIR = 0xA1000033,
+       TEE_TYPE_ECDH_KEYPAIR = 0xA1000034,
+#endif // ECC_IMPLEMENTATION
+       TEE_TYPE_GENERIC_SECRET = 0xA0000000,
+       TEE_TYPE_CERT_ROOT_GSL = 0xA00000A0,     // GPD System Loader root Certificate
+       TEE_TYPE_CERT_ROOT_AP = 0xA00000A1,    //Application provider root Certificate
+       TEE_TYPE_CERT_ROOT_CRL = 0xA00000A2,             //Certificate type CRL
+       TEE_TYPE_CERT_GENERAL_AP1 = 0xA00000A3
+// more for application certificate?
+} TEE_OBJECT_TYPES;
+
+/******************************************************************************
+ *  6.11 Object or Operation Attributes
+ ******************************************************************************/
+
+typedef enum {
+       TEE_ATTR_SECRET_VALUE = 0xC0000000,
+       TEE_ATTR_RSA_MODULUS = 0xD0000130,
+       TEE_ATTR_RSA_PUBLIC_EXPONENT = 0xD0000230,
+       TEE_ATTR_RSA_PRIVATE_EXPONENT = 0xC0000330,
+       TEE_ATTR_RSA_PRIME1 = 0xC0000430,
+       TEE_ATTR_RSA_PRIME2 = 0xC0000530,
+       TEE_ATTR_RSA_EXPONENT1 = 0xC0000630,
+       TEE_ATTR_RSA_EXPONENT2 = 0xC0000730,
+       TEE_ATTR_RSA_COEFFICIENT = 0xC0000830,
+       TEE_ATTR_DSA_PRIME = 0xD0001031,
+       TEE_ATTR_DSA_SUBPRIME = 0xD0001131,
+       TEE_ATTR_DSA_BASE = 0xD0001231,
+       TEE_ATTR_DSA_PUBLIC_VALUE = 0xD0000131,
+       TEE_ATTR_DSA_PRIVATE_VALUE = 0xC0000231,
+       TEE_ATTR_DH_PRIME = 0xD0001032,
+       TEE_ATTR_DH_SUBPRIME = 0xD0001132,
+       TEE_ATTR_DH_BASE = 0xD0001232,
+       TEE_ATTR_DH_X_BITS = 0xF0001332,
+       TEE_ATTR_DH_PUBLIC_VALUE = 0xD0000132,
+       TEE_ATTR_DH_PRIVATE_VALUE = 0xC0000232,
+       TEE_ATTR_RSA_OAEP_LABEL = 0xD0000930,
+       TEE_ATTR_RSA_PSS_SALT_LENGTH = 0xF0000A30,
+
+#ifdef ECC_IMPLEMENTATION
+       TEE_ATTR_ECDSA_PRIME = 0xD0001041,
+       TEE_ATTR_ECDSA_COFF_A = 0xD0001141,
+       TEE_ATTR_ECDSA_COFF_B = 0xD0001241,
+       TEE_ATTR_ECDSA_GENERATOR_X = 0xD0001341,
+       TEE_ATTR_ECDSA_GENERATOR_Y = 0xD0001441,
+       TEE_ATTR_ECDSA_ORDER = 0xD0001541,
+       TEE_ATTR_ECDSA_PUBLIC_VALUE_X = 0xD0002141,
+       TEE_ATTR_ECDSA_PUBLIC_VALUE_Y = 0xD0003141,
+       TEE_ATTR_ECDSA_PRIVATE_VALUE = 0xC0000241,
+#endif // ECC_IMPLEMENTATION
+
+//Certificate attribute start
+       TEE_ATTR_CERT_RAW = 0xD0000A01,
+       TEE_ATTR_CERT_TBS = 0xD0000A02,
+       TEE_ATTR_CERT_VERSION = 0xF0000A01,
+       TEE_ATTR_CERT_SERIAL = 0xD0000A03,
+       TEE_ATTR_CERT_SIG_OID1 = 0xD0000A04,
+       TEE_ATTR_CERT_ISSUER_RAW = 0xD0000A05,
+       TEE_ATTR_CERT_SUBJECT_RAW = 0xD0000A06,
+       TEE_ATTR_CERT_ISSUER = 0xD0000A07,
+       TEE_ATTR_CERT_SUBJECT = 0xD0000A08,
+       TEE_ATTR_CERT_VALID_FROM = 0xD0000A09,
+       TEE_ATTR_CERT_VALID_TO = 0xD0000A0A,
+       TEE_ATTR_CERT_PK_OID = 0xD0000A0B,
+       TEE_ATTR_CERT_ISSUER_ID = 0xD0000A0C,
+       TEE_ATTR_CERT_SUBJECT_ID = 0xD0000A0D,
+       TEE_ATTR_CERT_V3EXT = 0xD0000A0E,
+       TEE_ATTR_CERT_EXT_TYPE = 0xF0000A02,
+       TEE_ATTR_CERT_CA_ISTRUE = 0xF0000A03,
+       TEE_ATTR_CERT_MAX_PATHLEN = 0xF0000A04,
+       TEE_ATTR_CERT_KEY_USAGE = 0xF0000A05,
+       TEE_ATTR_CERT_EXT_KEY_USAGE = 0xD0000A0F,
+       TEE_ATTR_CERT_KEY_NS_TYPE = 0xF0000A06,
+       TEE_ATTR_CERT_SIG_OID2 = 0xD0000A10,
+       TEE_ATTR_CERT_SIG = 0xD0000A11,
+       TEE_ATTR_CERT_SIG_ALGO = 0xF0000A07,
+       TEE_ATTR_CERT_NEXT_CHAIN = 0xD0000A12,
+       //Certificate attribute end
+
+       TEE_ATTR_FLAG_VALUE = 0x20000000,
+       TEE_ATTR_FLAG_PUBLIC = 0x10000000
+} TEE_OBJECT_ATTRIBUTES;
+
+/******************************************************************************
+ *  7 Time API
+ ******************************************************************************/
+
+/******************************************************************************
+ *  7.1 Data Types
+ ******************************************************************************/
+
+typedef struct {
+       uint32_t seconds;
+       uint32_t millis;
+} TEE_Time;
+
+/******************************************************************************
+ *  7.2 Time Functions
+ ******************************************************************************/
+
+void TEE_GetSystemTime(TEE_Time* time);
+TEE_Result TEE_Wait(uint32_t timeout);
+TEE_Result TEE_GetTAPersistentTime(TEE_Time* time);
+TEE_Result TEE_SetTAPersistentTime(TEE_Time* time);
+void TEE_GetREETime(TEE_Time* time);
+
+/******************************************************************************
+ *  8 TEE Arithmetical API
+ ******************************************************************************/
+
+/******************************************************************************
+ *  8.3 Data Types
+ ******************************************************************************/
+
+typedef uint32_t TEE_BigInt;
+typedef uint32_t TEE_BigIntFMMContext;
+typedef uint32_t TEE_BigIntFMM;
+
+/******************************************************************************
+ * 8.4 Memory Allocation and Size of Objects
+ ******************************************************************************/
+
+#define TEE_BigIntSizeInU32(n) ((((n)+31)/32)+2+4)
+
+size_t TEE_BigIntFMMContextSizeInU32(const size_t modulusSizeInBits);
+size_t TEE_BigIntFMMSizeInU32(size_t modulusSizeInBits);
+
+/******************************************************************************
+ * 8.5 Initialization Functions
+ ******************************************************************************/
+
+void TEE_BigIntInit(TEE_BigInt* value, size_t length/*in uint32_t*/);
+void TEE_BigIntInitFMMContext(TEE_BigIntFMMContext* context,
+    size_t len,
+    const TEE_BigInt* modulus);
+void TEE_BigIntInitFMM(TEE_BigIntFMM* object, size_t len);
+
+/******************************************************************************
+ * 8.6 Converter Functions
+ ******************************************************************************/
+
+TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt* dest,
+    const uint8_t* buffer,
+    const size_t sz_buffer,
+    const int32_t sign);
+TEE_Result TEE_BigIntConvertToOctetString(void* buffer,
+    size_t* sz_buffer_out,
+    const TEE_BigInt* value);
+void TEE_BigIntConvertFromS32(TEE_BigInt* result, int32_t input);
+TEE_Result TEE_BigIntConvertToS32(int32_t* result, const TEE_BigInt* input);
+
+/******************************************************************************
+ * 8.7 Logical Operations
+ ******************************************************************************/
+
+int32_t TEE_BigIntCmp(const TEE_BigInt* op1, const TEE_BigInt* op2);
+int32_t TEE_BigIntCmpS32(const TEE_BigInt* value1, int32_t value2);
+void TEE_BigIntShiftRight(TEE_BigInt* destination,
+    const TEE_BigInt* source,
+    size_t bits);
+bool TEE_BigIntGetBit(const TEE_BigInt* object, uint32_t index);
+uint32_t TEE_BigIntGetBitCount(const TEE_BigInt* object);
+
+/******************************************************************************
+ * 8.8 Basic Arithmetic Operations
+ ******************************************************************************/
+
+void TEE_BigIntAdd(TEE_BigInt* dest,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2);
+void TEE_BigIntSub(TEE_BigInt* dest,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2);
+void TEE_BigIntNeg(TEE_BigInt* dest, const TEE_BigInt* op);
+void TEE_BigIntMul(TEE_BigInt* dest,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2);
+void TEE_BigIntSquare(TEE_BigInt* dest, const TEE_BigInt* op);
+void TEE_BigIntDiv(TEE_BigInt* dest_q,
+    TEE_BigInt* dest_r,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2);
+
+/******************************************************************************
+ * 8.9 Modular Arithmetic Operations
+ ******************************************************************************/
+
+void TEE_BigIntMod(TEE_BigInt* dest, const TEE_BigInt* op, const TEE_BigInt* n);
+void TEE_BigIntAddMod(TEE_BigInt* dest,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2,
+    const TEE_BigInt* n);
+void TEE_BigIntSubMod(TEE_BigInt* dest,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2,
+    const TEE_BigInt* n);
+void TEE_BigIntMulMod(TEE_BigInt* dest,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2,
+    const TEE_BigInt* n);
+void TEE_BigIntSquareMod(TEE_BigInt* dest,
+    const TEE_BigInt* op,
+    const TEE_BigInt* n);
+void TEE_BigIntInvMod(TEE_BigInt* dest,
+    const TEE_BigInt* op,
+    const TEE_BigInt* n);
+
+/******************************************************************************
+ * 8.10 Other Arithmetic Operations
+ ******************************************************************************/
+
+bool TEE_BigIntRelativePrime(const TEE_BigInt* op1, const TEE_BigInt* op2);
+void TEE_BigIntComputeExtendedGcd(TEE_BigInt* gcd,
+    TEE_BigInt* u,
+    TEE_BigInt* v,
+    const TEE_BigInt* op1,
+    const TEE_BigInt* op2);
+int32_t TEE_BigIntIsProbablePrime(const TEE_BigInt* op,
+    uint32_t confidenceLevel);
+
+/******************************************************************************
+ * 8.11 Fast Modular Multiplication Operations
+ ******************************************************************************/
+
+void TEE_BigIntConvertToFMM(TEE_BigIntFMM* dest,
+    const TEE_BigInt* src,
+    const TEE_BigInt* n,
+    const TEE_BigIntFMMContext* context);
+void TEE_BigIntConvertFromFMM(TEE_BigInt* dest,
+    const TEE_BigIntFMM* src,
+    const TEE_BigInt* n,
+    const TEE_BigIntFMMContext* context);
+void TEE_BigIntComputeFMM(TEE_BigIntFMM* dest,
+    const TEE_BigIntFMM* op1,
+    const TEE_BigIntFMM* op2,
+    const TEE_BigInt* n,
+    const TEE_BigIntFMMContext* context);
+
+int polar_rand(void * rng_state, unsigned char *output, size_t len);
+
+#ifdef CERTIFICATES_API
+/************************************************************************************
+ * Certificates API
+ *************************************************************************************/
+
+/*
+ * Description
+ *                  Root Certificate Shall be stored as a file in a Persistent
+ *                  object hence we shall parse the Root certificate into the
+ *                  Transient object from Persistent object.
+ *                  As a part of populating transient field the certificate shall
+ *                  parsed and verified.
+ *
+ *  Object                   transient object to be used for holding parsed certificate.
+ *  name                    persistent object ID (Persistent Object Identifirer)
+ *
+ * \return          TEE_SUCCESS if certificate parsed successfully, TEE_ERROR_XXXX
+ *                  error if unsuccessful.
+ *
+ * \Panic           If the Certificate is not part of the transient object.
+ */
+TEE_Result TEE_ParseVerifyRootCertFile(TEE_ObjectHandle Object,
+    const char* name);
+
+/*
+ * Description
+ *                  Certificate passed as a pointer to buffer shall be parsed
+ *                  into a Transient object
+ *                  The verification of the parsed certificate is done in a
+ *                  seperately step as it will need device root Certificate
+ *                  for verification as we know the passed Certificate shall
+ *                  be either just one Certificate or can be Certificate chain.
+ *                  The parsed certificate shall be the part of Transient Object
+ *                  ready for verification.
+ *
+ *  Object                   transient object to be used for holding parsed certificate.
+ *  buf                        buffer holding the raw certificate data
+ *  buflen                   size of the buffer
+ *
+ * \return          TEE_SUCCESS if all certificates parsed successfully, TEE_ERROR_XXXX
+ *                  error if unsuccessful.
+ *
+ * \Panic           If the Certificate is not part of the transient object.
+ */
+TEE_Result TEE_ParseCert(TEE_ObjectHandle Object,
+    const unsigned char* buf,
+    size_t buflen);
+
+/*
+ * Description
+ *                  The Certificate Revocation List (CRL) is optional parameter and
+ *                  is used to check whether a certificate is revoked by a
+ *                  Certificate Authority.
+ *                  The CRL is passed as a pointer to buffer (in a RAW format)
+ *                  and is parsed and stored in Transient Object.
+ *
+ *  Object                   transient object to be used for holding parsed CRL.
+ *  buf                        buffer holding the raw CRL data
+ *  buflen                   size of the buffer
+ *
+ * \return          TEE_SUCCESS if CRL parsed successfully, TEE_ERROR_CRL_PARSING
+ *                  error if unsuccessful.
+ *
+ * \Panic           If the CRL is not part of the transient object.
+ */
+TEE_Result TEE_ParseCrl(TEE_ObjectHandle Object,
+    const unsigned char* buf,
+    size_t buflen);
+
+/*
+ * Description
+ *                  The Certificate Revocation List (CRL) Shall be stored as a file
+ *                  in Persistent object hence we shall parse and populate the
+ *                  transient Object.
+ *
+ *  Object                   transient object to be used for holding parsed CRL.
+ *  name                    persistent object ID (Persistent Object Identifirer)
+ *
+ * \return          TEE_SUCCESS if CRL parsed successfully, TEE_ERROR_xx
+ *                  error if unsuccessful.
+ *
+ * \Panic           If the CRL is not part of the transient object.
+ */
+TEE_Result TEE_ParseCrlfile(TEE_ObjectHandle Object, const char* name);
+
+/*
+ * Description
+ *                  Store the certificate DN in printable form into buf
+ *
+ *  Object                    transient object with parsed Certificate.
+ *  output                    Output buffer holding DN string
+ *
+ * \return          TEE_SUCCESS if successfully, TEE_ERROR_xx error if unsuccessful.
+ *
+ * \Panic           If the Certificate is not part of the transient object.
+ */
+TEE_Result TEE_CertDNgets(TEE_ObjectHandle Object,
+    char * const output,
+    size_t* size);
+
+/*
+ * Description
+ *                  Check the Certificate time against system time
+ *
+ *  Object                    transient object with parsed Certificate.
+ *
+ * \return          TEE_SUCCESS if successfully, TEE_ERROR_xx error if unsuccessful.
+ *
+ * \Panic           If the Certificate is not part of the transient object.
+ */
+TEE_Result TEE_CheckTimeExpired(TEE_ObjectHandle Object);
+
+/*
+ * Description
+ *                  Verify the certificate or certificate chain signature.
+ *                  Populate the attribute field on if the certificate,
+ *                  certificate chain is verified successfully.
+ *
+ *  Appobj                    transient object to be used for holding parsed certificate to be verified.
+ *  CAobj                     transient object holding root certificate.
+ *  CRLobj                    transient object holding crl.
+ *
+ * \return          TEE_SUCCESS if certificate verified successfully, TEE_ERROR_XXXX
+ *                  error if unsuccessful.
+ *
+ * \Panic           If the Certificate, root certificate, CRL is not part of the
+ *                  respective transient object.
+ */
+TEE_Result TEE_CertVerify(TEE_ObjectHandle Appobj,
+    TEE_ObjectHandle CAobj,
+    TEE_ObjectHandle CRLobj);
+
+/* No Plans for Key handling files at the moment.
+ TEE_Result TEE_ParseKey(TEE_ObjectHandle obj_hndl, const unsigned char *key, size_t keylen);
+ TEE_Result TEE_ParseKeyFile(TEE_ObjectHandle obj_hndl , const char *path); // TEE_ObjectHandle keyObject);
+ TEE_Result TEE_ParsePublicKey(TEE_ObjectHandle obj_hndl, const unsigned char *key, size_t keylen);
+ TEE_Result TEE_ParsePublicKeyFile(TEE_ObjectHandle obj_hndl , const char *path); //TEE_ObjectHandle PublicKeyObject);
+ TEE_Result TEE_ParseDHM(TEE_ObjectHandle obj_hndl, const unsigned char *dhmin, size_t dhminlen);
+ TEE_Result TEE_ParseDHMfile(TEE_ObjectHandle obj_hndl, const char *path);
+ */
+
+#endif
+
+// Secure Objects API
+/*
+ * Description
+ *             encrypt and sign input data
+ *
+ * in          input buffer
+ * in_len      input buffer length
+ * out         output buffer (can be set to NULL in combination with *out_len = 0 for getting required output buffer size
+ * out_len     [in/out] output buffer length
+ * key         crypto key
+ * key_len     key length
+ * ta_uuid     optional pointer to TA UUID (calling TA or delegated TA). If NULL no Access Control by TA UUID will be used
+ * one_session_so if non 0 use Session ID Access Control
+ *
+ * return          TEE_SUCCESS if data was successfully wraped or TEE_ERROR_XXXX  error if unsuccessful.
+ */
+TEE_Result TEE_pWrapSO(const unsigned char * in,
+    size_t in_len,
+    unsigned char * out,
+    size_t * out_len,
+    const unsigned char * key,
+    size_t key_len,
+    TEE_UUID * ta_uuid,
+    int one_session_so);
+
+/*
+ * Description
+ *             decrypt and verify wrapped data
+ *
+ * in          input buffer
+ * in_len      input buffer length
+ * out         output buffer (can be set to NULL in combination with *out_len = 0 for getting required output buffer size
+ * out_len     [in/out] output buffer length
+ * key         crypto key
+ * key_len     key length
+ *
+ * return          TEE_SUCCESS if data was successfully unwraped or TEE_ERROR_XXXX  error if unsuccessful.
+ */
+TEE_Result TEE_pUnwrapSO(const unsigned char * in,
+    size_t in_len,
+    unsigned char * out,
+    size_t * out_len,
+    const unsigned char * key,
+    size_t key_len);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif // _TEE_INTERNAL_API_H
diff --git a/include/include/tee_sim_command.h b/include/include/tee_sim_command.h
new file mode 100755 (executable)
index 0000000..2133842
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  tee_sim_command.h
+ *
+ *    Description:  TEEC Connection Header file
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:43:30  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef __TEE_SIM_COMMAND_H__
+#define __TEE_SIM_COMMAND_H__
+
+#include "tee_internal_api.h"
+
+typedef enum {
+       COMMANDINVALID = -1,
+       CREATE = 0,
+       OPENSESSION,
+       INVOKECOMMAND,
+       CLOSESESSION,
+       DESTROY,
+       REQCANCEL
+} SIM_COMMAND;
+
+typedef struct {
+       uint32_t operationID;
+       uint32_t paramTypes;
+       TEE_Param params[4];
+       uint32_t shmID[4];
+} Operation;
+
+typedef struct {
+       uint32_t sessionID;
+       TEE_Result returnValue;
+} CreateTAEntryPointData;
+
+typedef struct {
+       uint32_t sessionID;
+} DestroyTAEntryPointData;
+
+typedef struct {
+       uint32_t sessionID;
+       Operation op;
+       TEE_Result returnValue;
+       uint32_t returnOrigin;
+} OpenTASessionData;
+
+typedef struct {
+       uint32_t sessionID;
+       uint32_t commandID;
+       Operation op;
+       TEE_Result returnValue;
+       uint32_t returnOrigin;
+} InvokeTACommandData;
+
+typedef struct {
+       uint32_t sessionID;
+} CloseTASessionData;
+
+typedef struct {
+       uint32_t sessionID;
+       uint32_t operationID;
+       TEE_Result returnValue;
+       uint32_t returnOrigin;
+
+} RequestTACancelData;
+
+#endif /* __TEE_SIM_COMMAND_H__ */
diff --git a/include/include/teec_data.h b/include/include/teec_data.h
new file mode 100755 (executable)
index 0000000..b673eb9
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  teec_data.h
+ *
+ *    Description:  TEEC Data Header file
+ *
+ *        Version:  1.0
+ *        Created:  16 April 2015 12:43:30  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#include "tee_client_api.h"
+
+#ifndef __TEEC_DATA_H__
+#define __TEEC_DATA_H__
+
+typedef struct {
+       uint32_t shmKey;
+       size_t size;
+       uint32_t offset;
+} MemoryRefData;
+
+typedef union {
+       MemoryRefData mem;
+       TEEC_Value value;
+} ParamData;
+
+typedef struct {
+       uint32_t paramTypes;
+       ParamData params[4];
+       uint32_t OperationID;
+} OperationData;
+
+typedef struct {
+       size_t size;
+       uint32_t flags;
+       uint32_t shmKey;
+} SharedMemoryData;
+
+typedef struct {
+       uint32_t contextID;
+       uint32_t nameLength;
+       char TEEName[MAX_CONTEXT_NAME_LEN];
+       TEEC_Result returnValue;
+} InitContextData;
+
+typedef struct {
+       uint32_t contextID;
+       uint32_t sessionID;
+       TEEC_UUID uuid;
+       uint32_t connMeth;
+       uint32_t connData;
+       OperationData operation;
+       uint32_t returnOrigin;
+       TEEC_Result returnValue;
+} OpenSessionData;
+
+typedef struct {
+       uint32_t contextID;
+       SharedMemoryData sharedMem;
+       TEEC_Result returnValue;
+} RegSharedMemData;
+
+typedef struct {
+       uint32_t contextID;
+       uint32_t sessionID;
+       uint32_t commandID;
+       OperationData operation;
+       uint32_t returnOrigin;
+       TEEC_Result returnValue;
+} InvokeCommandData;
+
+typedef struct {
+       uint32_t contextID;
+       uint32_t sessionID;
+       uint32_t operationID;
+} ReqCancellationData;
+
+typedef struct {
+       uint32_t contextID;
+       SharedMemoryData sharedMem;
+} RelSharedMemData;
+
+typedef struct {
+       uint32_t contextID;
+       uint32_t sessionID;
+} CloseSessionData;
+
+typedef struct {
+       uint32_t contextID;
+} FinalizeContextData;
+
+#endif /* __TEEC_DATA_H__ */
diff --git a/include/include/teestub_command_data.h b/include/include/teestub_command_data.h
new file mode 100755 (executable)
index 0000000..e4c8c06
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  teestub_command_data.h
+ *
+ *    Description:  TEEStub Data Header file
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:43:30  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna Devale
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#include "tee_internal_api.h"
+#include "teec_data.h"
+
+#ifndef __TEESTUB_COMMAND_DATA_H__
+#define __TEESTUB_COMMAND_DATA_H__
+
+typedef OperationData IntTAOperationData;
+
+typedef struct {
+       TEE_UUID destination;
+       uint32_t cancelTimeOut;
+       IntTAOperationData operation;
+       uint32_t session;
+       uint32_t returnOrigin;
+       uint32_t returnValue;
+} IntTAOpenSessionData;
+
+typedef struct {
+       uint32_t session;
+       uint32_t cancelTimeOut;
+       uint32_t commandID;
+       IntTAOperationData operation;
+       uint32_t returnOrigin;
+       uint32_t returnValue;
+} IntTAInvokeCommandData;
+
+typedef struct {
+       uint32_t accessFlags;
+       void *buffer;
+       uint32_t size;
+} IntTACheckMemoryCommandData;
+
+typedef struct {
+       uint32_t session;
+
+} IntTACloseSessionData;
+
+typedef struct {
+       TEE_Result panicCode;
+} IntTAPanicData;
+#endif /* __TEESTUB_COMMAND_DATA_H__ */
diff --git a/log/.cproject b/log/.cproject
new file mode 100755 (executable)
index 0000000..a63706f
--- /dev/null
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.22061592">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.22061592" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings>
+                                       <externalSetting>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/Logger"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/log"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/Logger/Debug"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/log/Debug"/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="Logger" srcPrefixMapping="" srcRootPath=""/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="log" srcPrefixMapping="" srcRootPath=""/>
+                                       </externalSetting>
+                               </externalSettings>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.22061592" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug.22061592">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.22061592." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.696479445" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1525231821" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder buildPath="${workspace_loc:/Logger}/Debug" id="cdt.managedbuild.target.gnu.builder.base.1368910591" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.1123812988" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.278305994" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.1245115915" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.1988049835" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.compiler.base.1491782358" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1795359117" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.1814885249" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.misc.other.903115694" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <option id="gnu.c.compiler.option.dialect.std.908716910" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2040279156" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool command="g++" id="cdt.managedbuild.tool.gnu.c.linker.base.1528577487" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
+                                                               <option id="gnu.c.link.option.ldflags.1245884491" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="" valueType="string"/>
+                                                               <option defaultValue="true" id="gnu.c.link.option.shared.1199277723" name="Shared (-shared)" superClass="gnu.c.link.option.shared" valueType="boolean"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1105556212" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1651312217" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <option defaultValue="true" id="gnu.cpp.link.option.shared.1118663071" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" valueType="boolean"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.1646186425" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1334487070" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.638078193">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.638078193" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.autotools.core.ErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.errorparsers.xlc.XlcErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.638078193" name="Release" parent="cdt.managedbuild.config.gnu.cross.exe.release.638078193">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.638078193." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.50306192" name="Cross GCC">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.323273796" isAbstract="false" osList="all"/>
+                                                       <builder buildPath="${workspace_loc:/Logger}/Release" id="cdt.managedbuild.builder.gnu.cross.827654407" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder"/>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="Logger.cdt.managedbuild.target.gnu.cross.exe.365261303" name="Executable"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.638078193;cdt.managedbuild.config.gnu.cross.exe.release.638078193.;cdt.managedbuild.tool.gnu.cross.c.compiler.1723518035;cdt.managedbuild.tool.gnu.c.compiler.input.10300952">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.22061592;cdt.managedbuild.config.gnu.cross.exe.debug.22061592.;cdt.managedbuild.tool.gnu.cross.c.compiler.1585292653;cdt.managedbuild.tool.gnu.c.compiler.input.95891595">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope"/>
+</cproject>
diff --git a/log/.gitignore b/log/.gitignore
new file mode 100755 (executable)
index 0000000..3df573f
--- /dev/null
@@ -0,0 +1 @@
+/Debug/
diff --git a/log/.project b/log/.project
new file mode 100755 (executable)
index 0000000..d1a8b53
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>log</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/log/.settings/language.settings.xml b/log/.settings/language.settings.xml
new file mode 100755 (executable)
index 0000000..6b3365f
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.22061592" name="Debug">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1745672306367" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.638078193" name="Release">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="770102726360458300" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.22061592.1318202039" name="Windows-Debug">
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1745672306367" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>
+                               <language-scope id="org.eclipse.cdt.core.g++"/>
+                       </provider>
+               </extension>
+       </configuration>
+</project>
diff --git a/log/.settings/org.eclipse.cdt.core.prefs b/log/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..a945b31
--- /dev/null
@@ -0,0 +1,13 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.1318202039/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.1318202039/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.1318202039/PATH/value=C\:/Program Files/Java/jre1.8.0_40/bin/server;C/Program Files/Java/jre1.8.0_40/bin;C\:/Program Files/Java/jre1.8.0_40/lib/amd64;C\:\\Program Files (x86)\\Black Duck Software\\protexIP\\bin;C\:\\Program Files\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files (x86)\\QuickTime\\QTSystem\\;C\:\\Program Files (x86)\\Java\\jre7\\bin; C\:\\cygwin64\\bin;C\:\\Program Files\\doxygen\\bin;D\:\\eclipse;C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\Program Files (x86)\\Java\\jre1.8.0_45\\bin;C\:\\Program Files\\eclipse;C\:/Program Files/Java/jre1.8.0_31/bin/server;C\:/Program Files/Java/jre1.8.0_31/bin;C\:/Program Files/Java/jre1.8.0_31/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\csvn\\bin\\;C\:\\csvn\\Python25\\;C\:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files\\Diskeeper Corporation\\ExpressCache\\;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x64;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files (x86)\\WinSCP\\;C\:\\Program Files (x86)\\PuTTY;C\:\\Program Files\\Microsoft\\Web Platform Installer\\;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C\:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;C\:\\Program Files (x86)\\doxygen\\bin;C\:\\Program Files (x86)\\sfk168;C\:\\Program Files (x86)\\vlc-2.1.0;C\:\\Python27\\Scripts;C\:\\Program Files (x86)\\GnuWin32\\bin;C\:\\Python27;C\:\\Program Files (x86)\\Subversion\\bin;c\:\\Program Files\\Synergy;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\MinGW\\lib\\gcc\\mingw32\\4.8.1;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C\:\\Program Files (x86)\\GitExtensions\\;C\:\\Program Files\\Perforce;c\:\\Program Files\\Java\\jre1.8.0_31\\bin\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\tizen-sdk\\ide;${Path};D\:\\samsung-tv-sdk\\tools\\i386-linux-gnueabi-gcc-4.6\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.1318202039/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.1318202039/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.695503171/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592.695503171/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\GitExtensions\\;D\:\\Tizen\\tizen-sdk\\tools;D\:\\Android\\android-sdk\\platform-tools;D\:\\Android\\android-ndk-r10c;C\:\\Program Files\\Perforce;D\:\\eclipse\\eclipse-rcp-luna-SR1-win32-x86_64;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\bin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\mingbin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.22061592/appendContributed=true
diff --git a/log/log.c b/log/log.c
new file mode 100755 (executable)
index 0000000..67c7f3e
--- /dev/null
+++ b/log/log.c
@@ -0,0 +1,200 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  log.c
+ *
+ *    Description:  logger for Simulator
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "log.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+static int32_t gdebug_level = 0xff;
+static int32_t gmodule_level = 0xfffffff;
+//static const char* gtag = "TA_SDK";
+
+/*-----------------------------------------------------------------------------
+ *  Functions
+ *-----------------------------------------------------------------------------*/
+/*
+ * This method is used to set module level and debug level to debug
+ *
+ * @param      dbg_level
+ *                             [IN] enum value of DebugLevel
+ *
+ * @param      mdl_level
+ *                             [IN] enum value of ModuleLevel
+ *
+ * @return     void
+ */
+__attribute__ ((visibility("default")))
+void SetDebugAndModuleLevel(IN const int32_t module_level,
+    IN const int32_t debug_level) {
+       if (module_level < UTILS || module_level > ALL_MODULES
+           || debug_level < INFO_LEVEL_LOG || debug_level > VERBOSE_LEVEL_LOG) {
+               return;
+       }
+       /*
+        * set global variables for module level and debug level
+        */
+       gmodule_level = module_level;
+       gdebug_level = debug_level;
+       return;
+}
+
+/*
+ * This method is to get debug level set
+ *
+ * @param      dbg_level
+ *                             [IN] enum value of DebugLevel
+ *
+ * @return     const char pointer
+ */
+const char* GetDebugLevel(IN int32_t dbg_level) {
+       switch (dbg_level) {
+               case INFO_LEVEL_LOG:
+                       return "INFO";
+               case PACKET_LEVEL_LOG:
+                       return "PACKET";
+               case ERROR_LEVEL_LOG:
+                       return "ERROR";
+               case DEBUG_LEVEL_LOG:
+                       return "DEBUG";
+               case SECURED_LEVEL_LOG:
+                       return "SECURED";
+               case VERBOSE_LEVEL_LOG:
+                       return "VERBOSE";
+               default:
+                       return "";
+       }
+}
+
+/*
+ * This method is to get module for which debug is set
+ *
+ * @param      mdl_level
+ *                             [IN] enum value of ModuleLevel
+ *
+ * @return     const char pointer
+ */
+const char* GetModuleLevel(IN int32_t module_level) {
+       switch (module_level) {
+               case UTILS:
+                       return "UTILS";
+               case SIM_DAEMON:
+                       return "SIM_DAEMON";
+               case TEEC_LIB:
+                       return "TEEC_LIB";
+               case TEE_STUB:
+                       return "TEE_STUB";
+               case SSF_LIB:
+                       return "SSF_LIB";
+               default:
+                       return "TA_SDK";
+       }
+}
+
+/*
+ * This method is used to print the debug logs
+ *
+ * @param      function_name
+ *                             [IN] name of the fuction
+ *
+ * @param      line_no
+ *                             [IN] line number of debug statement
+ *
+ * @param      module_level
+ *                             [IN] enum value of ModuleLevel
+ *
+ * @param      dbg_level
+ *                             [IN] enum value of DebugLevel
+ *
+ * @param      message
+ *                             [IN] message which needs to be displayed
+ *
+ * @return     void
+ */
+__attribute__ ((visibility("default")))
+void PrintLog(IN const char* function_name, IN const int32_t line_no,
+    IN int32_t module_level, IN int32_t debug_level, IN const char* message,
+    ...) {
+#ifndef _ANDROID_NDK
+       if (0 == (module_level & gmodule_level)
+           || 0 == (debug_level & gdebug_level)) {
+               return;
+       }
+#endif
+       const char* module = GetModuleLevel(module_level);
+       va_list variable_list;
+       va_start(variable_list, message);
+#if defined(__TIZEN__)
+       char buf[512] = {0,};
+       vsnprintf(buf, 511, message, variable_list);
+       switch(debug_level)
+       {
+               case INFO_LEVEL_LOG:
+               LOG(LOG_INFO, TA_SDK_TAG, "[%s][%s:%d]%s", module, function_name, line_no, buf);
+               break;
+               case PACKET_LEVEL_LOG:
+               LOG(LOG_DEBUG, TA_SDK_TAG, "[%s][%s:%d]%s", module, function_name, line_no, buf);
+               break;
+               case ERROR_LEVEL_LOG:
+               LOG(LOG_ERROR, TA_SDK_TAG, "[%s][%s:%d]%s", module, function_name, line_no, buf);
+               break;
+               case DEBUG_LEVEL_LOG:
+               case SECURED_LEVEL_LOG:
+               case VERBOSE_LEVEL_LOG:
+               LOG(LOG_DEBUG, TA_SDK_TAG, "[%s][%s:%d]%s", module, function_name, line_no, buf);
+               break;
+               default:
+               LOG(LOG_DEBUG, TA_SDK_TAG, "[%s][%s:%d]%s", module, function_name, line_no, buf);
+               break;
+       }
+#elif defined(_ANDROID_NDK)
+       char buf[512] = {'\0'};
+       vsnprintf(buf, sizeof(buf), message, variable_list);
+       switch(debug_level)
+       {
+               case INFO_LEVEL_LOG:
+               __android_log_print(ANDROID_LOG_INFO, gtag, "[%s] %s: %d: %s\n", module, function_name, line_no, buf);
+               break;
+               case ERROR_LEVEL_LOG:
+               __android_log_print(ANDROID_LOG_ERROR, gtag, "[%s] %s: %d: %s\n", module, function_name, line_no, buf);
+               break;
+               case DEBUG_LEVEL_LOG:
+               __android_log_print(ANDROID_LOG_WARN, gtag, "[%s] %s: %d: %s\n", module, function_name, line_no, buf);
+               break;
+               case SECURED_LEVEL_LOG:
+               __android_log_print(ANDROID_LOG_DEBUG, gtag, "[%s] %s: %d: %s\n", module, function_name, line_no, buf);
+               break;
+               default:
+//                     __android_log_print(ANDROID_LOG_VERBOSE, gtag, "[%s]%s: %d: %s\n", module,  function_name, line_no, buf);
+               break;
+       }
+#else
+       const char* severity = GetDebugLevel(debug_level);
+       printf("[%s] [%s] %s: %d: ", module, severity, function_name, line_no);
+       vprintf(message, variable_list);
+       printf("\n");
+#endif
+       va_end(variable_list);
+       return;
+}
diff --git a/log/log.h b/log/log.h
new file mode 100755 (executable)
index 0000000..534ae68
--- /dev/null
+++ b/log/log.h
@@ -0,0 +1,164 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  log.h
+ *
+ *    Description:  This file provides log APIs for debugging
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef LOG_H
+#define LOG_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <stdint.h>
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define IN
+#define INCONST
+#define INOUT
+#define OUT
+
+#define _LOGGING
+
+#ifdef _WIN
+typedef int int8_t;
+typedef int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+typedef long long unsigned uint64_t;
+typedef int timer_t;
+#endif
+
+#ifdef __TIZEN__
+#include <dlog.h>
+#define TA_SDK_TAG     "TA_SDK"
+#endif
+
+#ifdef _ANDROID_NDK
+#include <android/log.h>
+#endif
+
+#ifdef _WIN
+#define __attribute__(...)
+#endif
+
+/*
+ * Enum to identify Debug level
+ */
+typedef enum {
+       INFO_LEVEL_LOG = 0x01,
+       PACKET_LEVEL_LOG = 0x02,
+       ERROR_LEVEL_LOG = 0x04,
+       DEBUG_LEVEL_LOG = 0x08,
+       SECURED_LEVEL_LOG = 0x10,
+       VERBOSE_LEVEL_LOG = 0xFF,
+} DebugLevel;
+
+/*
+ * Enum to identify Module name
+ */
+typedef enum {
+       UTILS = 0x01,
+       SIM_DAEMON = 0x02,
+       TEEC_LIB = 0x04,
+       TEE_STUB = 0x08,
+       TEST = 0x10,
+       SSF_LIB = 0x11,
+       ALL_MODULES = 0xFFFFFFF,
+} ModuleLevel;
+
+#ifdef _LOGGING
+
+#define _LOG(module_level,debug_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,debug_level,__VA_ARGS__)
+
+#define LOGE(module_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,ERROR_LEVEL_LOG,__VA_ARGS__)
+#define LOGV(module_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,VERBOSE_LEVEL_LOG,__VA_ARGS__)
+#define LOGD(module_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,DEBUG_LEVEL_LOG,__VA_ARGS__)
+#define LOGI(module_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,SECURED_LEVEL_LOG,__VA_ARGS__)
+#define LOGS(module_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,INFO_LEVEL_LOG,__VA_ARGS__)
+#define LOGP(module_level,...) PrintLog(__FUNCTION__,__LINE__,module_level,PACKET_LEVEL_LOG,__VA_ARGS__)
+
+#else //ifdef _LOGGING
+
+#define LOGE(module_level,...)
+#define LOGV(module_level,...)
+#define LOGD(module_level,...)
+#define LOGI(module_level,...)
+#define LOGS(module_level,...)
+#define LOGP(module_level,...)
+
+#endif //ifdef _LOGGING
+
+/*
+ * This method is to get debug level set
+ *
+ * @param      dbg_level
+ *                             [IN] enum value of DebugLevel
+ *
+ * @return     const char pointer
+ */
+const char* GetDebugLevel(IN int32_t dbg_level);
+
+/*
+ * This method is to get module for which debug is set
+ *
+ * @param      mdl_level
+ *                             [IN] enum value of ModuleLevel
+ *
+ * @return     const char pointer
+ */
+const char* GetModuleLevel(IN int32_t mdl_level);
+
+/*
+ * This method is used to set module level and debug level to debug
+ *
+ * @param      dbg_level
+ *                             [IN] enum value of DebugLevel
+ *
+ * @param      mdl_level
+ *                             [IN] enum value of ModuleLevel
+ *
+ * @return     void
+ */
+void SetDebugAndModuleLevel(IN const int32_t module_level,
+    IN const int32_t debug_level);
+
+/*
+ * This method is used to print the debug logs
+ *
+ * @param      function_name
+ *                             [IN] name of the fuction
+ *
+ * @param      line_no
+ *                             [IN] line number of debug statement
+ *
+ * @param      module_level
+ *                             [IN] enum value of ModuleLevel
+ *
+ * @param      dbg_level
+ *                             [IN] enum value of DebugLevel
+ *
+ * @param      message
+ *                             [IN] message which needs to be displayed
+ *
+ * @return     void
+ */
+void PrintLog(IN const char* function_name, IN const int32_t line_no,
+    IN int32_t module_level, IN int32_t debug_level, IN const char* message,
+    ...);
+
+#endif
diff --git a/osal/.cproject b/osal/.cproject
new file mode 100755 (executable)
index 0000000..afa393f
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings>
+                                       <externalSetting>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/osal"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/osal/Debug"/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="osal" srcPrefixMapping="" srcRootPath=""/>
+                                       </externalSetting>
+                               </externalSettings>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461" name="Debug" parent="cdt.managedbuild.config.gnu.mingw.exe.debug">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.1098230543" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.2046657970" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder buildPath="${workspace_loc:/osal}/Debug" id="cdt.managedbuild.target.gnu.builder.base.852073503" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.683218385" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.484179188" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.1788699893" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.427771760" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.compiler.base.50852542" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1927765158" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.363222342" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.misc.other.204150072" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -lrt" valueType="string"/>
+                                                               <option id="gnu.c.compiler.option.dialect.std.662880302" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1326146637" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool command="g++" id="cdt.managedbuild.tool.gnu.c.linker.base.2125370077" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base">
+                                                               <option id="gnu.c.link.option.ldflags.270047876" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="" valueType="string"/>
+                                                               <option id="gnu.c.link.option.libs.1489092091" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
+                                                                       <listOptionValue builtIn="false" value="pthread"/>
+                                                               </option>
+                                                               <option defaultValue="true" id="gnu.c.link.option.shared.1572248236" name="Shared (-shared)" superClass="gnu.c.link.option.shared" valueType="boolean"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.377743256" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1202083690" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <option defaultValue="true" id="gnu.cpp.link.option.shared.551422496" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" valueType="boolean"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.1241635498" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1006412495" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.mingw.exe.release.99121785">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.mingw.exe.release.99121785" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.mingw.exe.release.99121785" name="Release" parent="cdt.managedbuild.config.gnu.mingw.exe.release">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.mingw.exe.release.99121785." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.mingw.exe.release.198600730" name="MinGW GCC" superClass="cdt.managedbuild.toolchain.gnu.mingw.exe.release">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.mingw.exe.release.867187915" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.mingw.exe.release"/>
+                                                       <builder buildPath="${workspace_loc:/osal}/Release" id="cdt.managedbuild.tool.gnu.builder.mingw.base.43725964" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CDT Internal Builder" superClass="cdt.managedbuild.tool.gnu.builder.mingw.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.mingw.exe.release.1776024952" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.mingw.exe.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.964018656" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.mingw.base.1354475206" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.mingw.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.release.1870542191" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.mingw.exe.release">
+                                                               <option id="gnu.cpp.compiler.mingw.exe.release.option.optimization.level.1016272793" name="Optimization Level" superClass="gnu.cpp.compiler.mingw.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.mingw.exe.release.option.debugging.level.1747364844" name="Debug Level" superClass="gnu.cpp.compiler.mingw.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release.1472875309" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release">
+                                                               <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.mingw.exe.release.option.optimization.level.1210593423" name="Optimization Level" superClass="gnu.c.compiler.mingw.exe.release.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.mingw.exe.release.option.debugging.level.431291840" name="Debug Level" superClass="gnu.c.compiler.mingw.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.813639972" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.release.889485427" name="MinGW C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.mingw.exe.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.254968520" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.release.1679441852" name="MinGW C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.mingw.exe.release"/>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="osal.cdt.managedbuild.target.gnu.mingw.exe.758522854" name="Executable" projectType="cdt.managedbuild.target.gnu.mingw.exe"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461;cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461.;cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.debug.2080933537;cdt.managedbuild.tool.gnu.c.compiler.input.860399400">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.mingw.exe.release.99121785;cdt.managedbuild.config.gnu.mingw.exe.release.99121785.;cdt.managedbuild.tool.gnu.c.compiler.mingw.exe.release.1472875309;cdt.managedbuild.tool.gnu.c.compiler.input.813639972">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope" versionNumber="2">
+               <configuration configurationName="Windows-Debug">
+                       <resource resourceType="PROJECT" workspacePath="/osal"/>
+               </configuration>
+               <configuration configurationName="Debug">
+                       <resource resourceType="PROJECT" workspacePath="/osal"/>
+               </configuration>
+               <configuration configurationName="Release">
+                       <resource resourceType="PROJECT" workspacePath="/osal"/>
+               </configuration>
+       </storageModule>
+</cproject>
diff --git a/osal/.gitignore b/osal/.gitignore
new file mode 100755 (executable)
index 0000000..3df573f
--- /dev/null
@@ -0,0 +1 @@
+/Debug/
diff --git a/osal/.project b/osal/.project
new file mode 100755 (executable)
index 0000000..1d29a11
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>osal</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/osal/.settings/org.eclipse.cdt.core.prefs b/osal/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..bb01593
--- /dev/null
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461.1612701246/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461.1612701246/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461.1612701246/PATH/value=C\:/Program Files/Java/jre1.8.0_40/bin/server;C\:/Program Files/Java/jre1.8.0_40/bin;C\:/Program Files/Java/jre1.8.0_40/lib/amd64;C\:\\Program Files (x86)\\Black Duck Software\\protexIP\\bin;C\:\\Program Files\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files (x86)\\QuickTime\\QTSystem\\;C\:\\Program Files (x86)\\Java\\jre7\\bin; C\:\\cygwin64\\bin;C\:\\Program Files\\doxygen\\bin;D\:\\eclipse;C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\Program Files (x86)\\Java\\jre1.8.0_45\\bin;C\:\\Program Files\\eclipse;C\:/Program Files/Java/jre1.8.0_31/bin/server;C\:/Program Files/Java/jre1.8.0_31/bin;C\:/Program Files/Java/jre1.8.0_31/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\csvn\\bin\\;C\:\\csvn\\Python25\\;C\:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files\\Diskeeper Corporation\\ExpressCache\\;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x64;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files (x86)\\WinSCP\\;C\:\\Program Files (x86)\\PuTTY;C\:\\Program Files\\Microsoft\\Web Platform Installer\\;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C\:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;C\:\\Program Files (x86)\\doxygen\\bin;C\:\\Program Files (x86)\\sfk168;C\:\\Program Files (x86)\\vlc-2.1.0;C\:\\Python27\\Scripts;C\:\\Program Files (x86)\\GnuWin32\\bin;C\:\\Python27;C\:\\Program Files (x86)\\Subversion\\bin;c\:\\Program Files\\Synergy;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\MinGW\\lib\\gcc\\mingw32\\4.8.1;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C\:\\Program Files (x86)\\GitExtensions\\;C\:\\Program Files\\Perforce;c\:\\Program Files\\Java\\jre1.8.0_31\\bin\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\tizen-sdk\\ide;${Path};D\:\\samsung-tv-sdk\\tools\\i386-linux-gnueabi-gcc-4.6\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461.1612701246/append=true
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461.1612701246/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\GitExtensions\\;D\:\\Tizen\\tizen-sdk\\tools;D\:\\Android\\android-sdk\\platform-tools;D\:\\Android\\android-ndk-r10c;C\:\\Program Files\\Perforce;D\:\\eclipse\\eclipse-rcp-luna-SR1-win32-x86_64;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\bin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\mingbin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/append=true
+environment/project/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/appendContributed=true
diff --git a/osal/.settings/org.eclipse.cdt.managedbuilder.core.prefs b/osal/.settings/org.eclipse.cdt.managedbuilder.core.prefs
new file mode 100755 (executable)
index 0000000..16b7426
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/CPATH/delimiter=;
+environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/CPATH/operation=remove
+environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/C_INCLUDE_PATH/delimiter=;
+environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/C_INCLUDE_PATH/operation=remove
+environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/append=true
+environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.mingw.exe.debug.1210907461/appendContributed=true
diff --git a/osal/OsaCommon.c b/osal/OsaCommon.c
new file mode 100755 (executable)
index 0000000..e2ef8be
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaCommon.c
+ *
+ *    Description:  Common functions
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "OsaLinuxUser.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+//     Global Timer Datatypes
+void timer_handler(int iJunk);
+
+typedef void (*tHandler)(int data);
+
+typedef void (*TimerProcT)(void* pvdata);
+
+struct Timerdata {
+       unsigned int stop_timer;
+       unsigned int start_timer;
+       struct itimerval iTval_t;
+       TimerProcT callback;
+       void* pvTmpdata;
+
+};
+struct Timerdata Timer_data_t;
+
+/*-----------------------------------------------------------------------------
+ *  Functions
+ *-----------------------------------------------------------------------------*/
+void * OsaMalloc(unsigned int size) {
+       return malloc(size);
+}
+
+void *OsaFree(void *pbuf) {
+       if (pbuf != NULL) {
+               free(pbuf);
+               pbuf = NULL;
+       }
+       return pbuf;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       InitTimerData
+ // Detail Description : This function initialises the timer data structure.
+ //
+ // Return Data Type   : void
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+void InitTimerData(void) {
+       Timer_data_t.stop_timer = FALSE;
+       Timer_data_t.start_timer = FALSE;
+
+       memset(&Timer_data_t.iTval_t, 0, sizeof(struct itimerval));
+
+       Timer_data_t.callback = NULL;
+
+       Timer_data_t.pvTmpdata = NULL;
+
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerCreate
+ // Detail Description :       This function creates the timer.It initialises the
+ //                    timer data and sets the callback function to be called
+ //                    upon timer expiry.
+ //
+ // Return Data Type   : ErrorType.
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerCreate(int* pTimerId, int periodic, int s32Time,
+    void (*entry)(void* data), void* pvAr) {
+       unsigned int uiDiv, uiRem;
+       struct sigaction Action_t;
+
+       uiDiv = s32Time / 1000;
+       uiRem = s32Time % 1000;
+
+       if (Timer_data_t.start_timer != TRUE) {
+
+               // Initialize the Timer data structure
+               InitTimerData();
+
+               /*
+                * Fill the structure with the periodic or one shot  time
+                * interval after which a function has to be called
+                */
+
+               if (periodic == OSAL_TIMER_PERODIC) {
+                       Timer_data_t.iTval_t.it_interval.tv_sec = uiDiv;
+                       Timer_data_t.iTval_t.it_interval.tv_usec = uiRem * 1000;
+                       Timer_data_t.iTval_t.it_value.tv_sec = uiDiv;
+                       Timer_data_t.iTval_t.it_value.tv_usec = uiRem * 1000;
+               } else {
+                       Timer_data_t.iTval_t.it_interval.tv_sec = 0;
+                       Timer_data_t.iTval_t.it_interval.tv_usec = 0;
+                       Timer_data_t.iTval_t.it_value.tv_sec = uiDiv;
+                       Timer_data_t.iTval_t.it_value.tv_usec = uiRem * 1000;
+
+               }
+
+               /*
+                * Set Signal handler
+                */
+
+               Action_t.sa_handler = (tHandler)timer_handler;
+               Timer_data_t.callback = (entry);
+               Timer_data_t.pvTmpdata = pvAr;
+
+               sigemptyset(&(Action_t.sa_mask));/*No other signal blocked*/
+
+               /*
+                * Add SIGALRM in the list
+                */
+               if (sigaddset(&(Action_t.sa_mask), SIGALRM) < 0) {
+                       //PrintError("In OsaTimerCreate() : Could Not Stop \n");
+                       return OSAL_ERROR;
+               }
+
+               /*
+                * Unblock the SIGALRM,if it is blocked
+                */
+               if (sigprocmask(SIG_UNBLOCK, &(Action_t.sa_mask), NULL) < 0) {
+                       //PrintError("In OsaTimerCreate() : Could not mask the Signal \n");
+                       return OSAL_ERROR;
+               }
+
+               /*
+                * Set the Global vairable.
+                *
+                */
+               //stop_timer = FALSE;
+               Timer_data_t.stop_timer = FALSE;
+
+               /*
+                * Restore the signal previous  setting
+                */
+               /* OSAL_080922 : before SA_SIGINFO was used. */
+               Action_t.sa_flags = SA_RESTART;
+
+               sigaction(SIGALRM, &Action_t, NULL);
+               return OSAL_OK;
+       } else {
+               return OSAL_ERROR;
+       }
+
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerStart
+ // Detail Description : This function starts the already created timer .
+ //
+ // Return Data Type   :       ErrorType.
+ /
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerStart(int iTimerId) {
+       /* The timer is started  */
+       if (Timer_data_t.start_timer != TRUE) {
+               if (setitimer(ITIMER_REAL, &Timer_data_t.iTval_t, NULL) < 0) {
+                       //PrintError("In OsaTimerStart() : OsaTimerStart  failed \n ");
+                       return OSAL_ERROR;
+               }
+               Timer_data_t.start_timer = TRUE;
+               return OSAL_OK;
+       } else {
+               return OSAL_ERROR;
+       }
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerStop
+ // Detail Description : This function stops the current running timer .
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerStop(int iTimerId) {
+       //struct sigaction Action_t;
+       //Action_t.sa_flags = 0;
+       struct itimerval trivial_it; /* OSAL_080918_1 */
+
+       if (Timer_data_t.start_timer == FALSE) {
+               //PrintError("In OsaTimerStop() : Timer not yet started  \n");
+               return OSAL_ERROR;
+       }
+
+       /* OSAL_080920 : Don't block the alarm signal */
+#if 0
+       /* OSAL_080918_2 : init signal set variable */
+       sigemptyset(&(Action_t.sa_mask));
+
+       /*
+        * Add SIGALRM in the signal List
+        */
+       if(sigaddset(&(Action_t.sa_mask),SIGALRM) <0)
+       {
+               PrintError("In OsaTimerStop() : Could Not Stop \n");
+               return OSAL_ERROR;
+       }
+       /*
+        * Block SIGALRM
+        */
+       if(sigprocmask(SIG_BLOCK,&(Action_t.sa_mask),NULL) <0)
+       {
+               PrintError("In OsaTimerStop() : Could not mask the Signal \n");
+               return OSAL_ERROR;
+       }
+#endif
+
+       /* OSAL_080918_1 : stop interval timer after alarm signal blocked */
+       trivial_it.it_value.tv_sec = 0;
+       trivial_it.it_value.tv_usec = 0;
+       if (setitimer(ITIMER_REAL, &trivial_it, NULL) == -1) {
+               //PrintError("OsaTimerStop failed\n ");
+               return OSAL_ERROR;
+       }
+
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerDelete
+ // Detail Description : This function deletes the current timer .
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerDelete(int iTimerId) {
+       //struct sigaction Action_t;
+       struct itimerval iTmpval_t;
+
+       //Action_t.sa_flags = 0;
+
+       if (Timer_data_t.start_timer == FALSE) {
+               //PrintError("In OsaTimerDelete() : No timer present to be deleted  \n");
+               return OSAL_ERROR;
+       }
+
+       iTmpval_t.it_interval.tv_sec = 0;
+       iTmpval_t.it_interval.tv_usec = 0;
+       iTmpval_t.it_value.tv_sec = 0;
+       iTmpval_t.it_value.tv_usec = 0;
+
+       /* The Timer is deleted  */
+
+       if (setitimer(ITIMER_REAL, &iTmpval_t, NULL) < 0) {
+               //PrintError("In OsaTimerDelete() : pOsaTimerDelete failed \n");
+               return -1;
+       }
+       Timer_data_t.stop_timer = TRUE;
+       Timer_data_t.start_timer = FALSE;
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerRestart
+ // Detail Description : This function restarts the stopped timer .
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerRestart(int iTimerId) {
+       struct sigaction Action_t;
+       if (Timer_data_t.stop_timer == TRUE) {
+               //PrintError("In OsaTimerRestart() : Has been stopped   forever \n");
+               return OSAL_ERROR;
+       }
+
+       /* OSAL_080918_1 :
+        reset it_value to keep the first expiration after restart */
+       if (setitimer(ITIMER_REAL, &Timer_data_t.iTval_t, NULL) == -1) {
+               //PrintError("OsaTimerRestart failed\n ");
+               return OSAL_ERROR;
+       }
+
+       /* OSAL_080918_2 : init signal set variable */
+       sigemptyset(&(Action_t.sa_mask));
+       sigaddset(&(Action_t.sa_mask), SIGALRM);
+
+       Action_t.sa_flags = 0;
+       if (sigprocmask(SIG_UNBLOCK, &(Action_t.sa_mask), NULL) < 0) {
+               //PrintError("In OsaTimerRestart() : Could Not Start Again \n");
+               return OSAL_ERROR;
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       timer_handler
+ // Detail Description : Private timer_handler
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+void timer_handler(int iJunk) {
+       (Timer_data_t.callback)(Timer_data_t.pvTmpdata);
+
+}
+
+void OsaWait(int mSecs) {
+       unsigned int delay = mSecs * 1000;
+       usleep(delay);
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaCurrentTime
+ // Detail Description : This API returns the current time in _milliseconds_
+ //                                 using CPU timer
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : 
+ //    (Linux OsaCurrentTime, OsaCurrentTimeVal function)
+ //    1) kernel should support the high-resolution clocksource.
+ //            Otherwise, the maximum resolution is only 1 or 10 mili sec.
+ //            Default clocksource of arm linux kernel is system tick timer.
+ //    2) In some cases, time-warp can be occur. (time goes back in 10 milliseconds or less)
+ //            When system lose the timer tick interrupt.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+unsigned int OsaCurrentTime(void) {
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts); // SoC_D00003324
+
+       return (unsigned int)((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000));
+}
+
+/* COMMON_070709-2 */
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaCurrentTimeVal
+ // Detail Description : This function returns the current timeval using CPU clock
+ // Return Data Type   : pOsaTime_t (1st argument)
+ //
+ // Programming Note   : See "Programming note" in the OsaCurrentTime function
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+void OsaCurrentTimeVal(pOsaTime_t pTimeVal) {
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts); // SoC_D00003324
+
+       pTimeVal->Sec = ts.tv_sec;
+       pTimeVal->NanoSec = ts.tv_nsec;
+
+}
+
+/* COMMON_070709-2 */
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaDiffTimeVal
+ // Detail Description : Subtract pVal2 to pVal1, stores result to pResult
+ // Return Data Type   : pOsaTime_t (1st argument)
+ //
+ // Programming Note   : If pVal2 is less than pVal1, result is 0.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+void OsaDiffTimeVal(pOsaTime_t pResult, const pOsaTime_t pVal1,
+    const pOsaTime_t pVal2) {
+       /* no negative result */
+       if ((pVal2->Sec < pVal1->Sec)
+           || ((pVal1->Sec == pVal2->Sec) && (pVal2->NanoSec < pVal1->NanoSec))) {
+               pResult->Sec = 0;
+               pResult->NanoSec = 0;
+               return;
+       }
+
+       pResult->Sec = pVal2->Sec - pVal1->Sec;
+
+       /* perform the carry */
+       if (pVal2->NanoSec < pVal1->NanoSec) {
+               pResult->Sec--;
+               pResult->NanoSec = pVal2->NanoSec + 1000000000 - pVal1->NanoSec;
+       } else {
+               pResult->NanoSec = pVal2->NanoSec - pVal1->NanoSec;
+       }
+}
+
+int OsaGetTicksPerSecond(void) {
+       /* return OS Timer frequency(usually 100hz). */
+       return 100;
+}
+
diff --git a/osal/OsaIpc.c b/osal/OsaIpc.c
new file mode 100755 (executable)
index 0000000..57bb384
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaIpc.c
+ *
+ *    Description:  Semaphore and Shared Memory implementation
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "OsaLinuxUser.h"
+
+key_t OsaGetKey(const char pcName[10]) {
+       uid_t uid;
+       key_t key;
+       int i, len, acc;
+       char aName[10];
+
+       memset(aName, 0x00, 10);
+       memcpy(aName, pcName, 9);
+
+       uid = 1; //getuid();
+       acc = 0;
+       len = strlen(aName);
+
+       for (i = 0; i < len; i++) {
+               acc <<= 1;
+               acc = acc + aName[i];
+       }
+       key = (uid << 16) | (acc & 0x0000FFFF);
+
+       return (key);
+}
+
+/*
+ // -------------------------------------------------------------------
+ //                     Shared Memory Implementation
+ // -------------------------------------------------------------------
+ */
+int OsaShmCreate(const char pcName[10], unsigned int u32ShmSegSize,
+    int* ps32ShmId) {
+       key_t key = (key_t)OsaGetKey(pcName);
+
+       if (NULL == ps32ShmId) {
+               return OSAL_ERROR;
+       }
+
+       *ps32ShmId = shmget(key, u32ShmSegSize, IPC_CREAT | IPC_EXCL | 0666);
+       if (*ps32ShmId == -1) {
+               if (errno == EEXIST) {
+                       *ps32ShmId = shmget(key, u32ShmSegSize, 0666);
+                       return OSAL_EXIST;
+               } else {
+                       return OSAL_ERROR;
+               }
+       }
+
+       return OSAL_OK;
+}
+
+int OsaShmDelete(int s32ShmId) {
+       if (shmctl(s32ShmId, IPC_RMID, NULL) == -1) {
+               return OSAL_ERROR;
+       }
+
+       return OSAL_OK;
+}
+
+int OsaShmAttach(int s32ShmId, void** pShmAddr) {
+       if (NULL == pShmAddr) {
+               return OSAL_ERROR;
+       }
+
+       *pShmAddr = (void*)shmat(s32ShmId, NULL, 0);
+
+       if (*pShmAddr == (void*)-1) {
+               return OSAL_ERROR;
+       }
+
+       return OSAL_OK;
+}
+
+int OsaShmDetach(const void *pShmAddr) {
+       if (NULL == pShmAddr) {
+               return OSAL_ERROR;
+       }
+
+       if (shmdt(pShmAddr) == -1) {
+               //PrintError("Error in Detaching");
+               return OSAL_ERROR;
+       }
+
+       return OSAL_OK;
+}
+
+/*
+ // -------------------------------------------------------------------
+ //                     Semaphore Implementation(System V)
+ // -------------------------------------------------------------------
+ */
+union semun {
+       int val;
+       struct semid_ds *buf;
+       unsigned short *array;
+};
+
+typedef struct _UlOsaSem {
+       int iSemId;
+       int iAttribute;
+       int iCount;
+       char bName[16];
+       key_t semKey;
+} UlOsaSem_t;
+
+typedef struct {
+       int bUsed;
+       key_t semKey;
+       int s32Count;
+} OsaNamedSemMgr_t;
+
+#define MAX_NAMEDSEM_MGR 256
+
+static int UlOsaNamedSemCreate(const char pcName[10], int iCount,
+    int iAttribute, unsigned int* puiSmid) {
+       int iRetVal = OSAL_OK;
+       UlOsaSem_t* sem;
+       key_t semKey;
+
+       sem = (UlOsaSem_t*)malloc(sizeof(*sem));
+       if (!sem) {
+               //PrintError ("UlOsaSemCreate, Out of memory!\n");
+               return OSAL_ERROR;
+       }
+
+       semKey = OsaGetKey(pcName);
+
+       sem->iSemId = semget(semKey, 1, IPC_CREAT | IPC_EXCL | 0666);
+
+       if (sem->iSemId != -1) {
+               union semun semUnion;
+
+               semUnion.val = iCount;
+               if (semctl(sem->iSemId, 0, SETVAL, semUnion) == -1) {
+                       semctl(sem->iSemId, 0, IPC_RMID, NULL);
+                       free(sem);
+                       //PrintError ("UlOsaSemCreate, semctl Failed!\n");
+                       return OSAL_ERROR;
+               }
+       } else {
+               if (errno == EEXIST) {
+                       sem->iSemId = semget(semKey, 1, 0);
+                       iRetVal = OSAL_EXIST;
+               } else {
+                       free(sem);
+                       //PrintError ("UlOsaSemCreate, semget Failed!\n");
+                       return OSAL_ERROR;
+               }
+       }
+
+       sem->iAttribute = iAttribute;
+       sem->iCount = iCount;
+       sem->semKey = semKey;
+
+       memcpy((void*)sem->bName, (const void*)pcName, (size_t)10);
+       sem->bName[10] = '\0';
+
+       *puiSmid = (unsigned int)sem;
+
+       return iRetVal;
+}
+
+#if 0  // unused funciton Á¦°Å.
+static int UlOsaNamedSemDelete(unsigned int uiSmid)
+{
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+
+       if (!sem)
+       {
+               return OSAL_ERROR;
+       }
+
+       if (semctl (sem->iSemId, 0, IPC_RMID, NULL) == -1)
+       {
+               return OSAL_ERROR;
+       }
+
+       free((void*)uiSmid);
+
+       return OSAL_OK;
+}
+#endif
+
+static int UlOsaNamedSemGet(unsigned int uiSmid, int iFlags, int iTimeout) {
+       struct sembuf semBuf;
+       struct timespec ts;
+       struct timeval tv;
+
+       int ret;
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       if (iFlags == OSAL_SEM_NOWAIT) {
+               semBuf.sem_num = 0;
+               semBuf.sem_op = 0;
+               semBuf.sem_flg = IPC_NOWAIT;
+
+               ret = semop(sem->iSemId, &semBuf, 1);
+       } else if (iTimeout == 0) {
+               /* wait _inifinite_ */
+               //PrintDbg ("UlOsaSemGet-infinite(%s).\n", sem->bName);
+               semBuf.sem_num = 0;
+               semBuf.sem_op = -1;
+               semBuf.sem_flg = SEM_UNDO;
+
+               ret = OSAL_FAILURE_RETRY(semop(sem->iSemId, &semBuf, 1));
+       } else {
+               /* with _timeout_ */
+               //PrintDbg ("UlOsaSemGet-timeout(%s).\n", sem->bName);
+               if (iTimeout < 0) {
+                       //PrintError ("UlOsaSemGet-timeout: invalid arg!\n");
+                       return OSAL_ERROR;
+               }
+
+               gettimeofday(&tv, NULL);
+               tv.tv_sec += iTimeout / 1000000;
+               tv.tv_usec += iTimeout % 1000000;
+               if (tv.tv_usec >= 1000000) {
+                       tv.tv_sec += tv.tv_usec / 1000000;
+                       tv.tv_usec %= 1000000;
+               }
+               ts.tv_sec = tv.tv_sec;
+               ts.tv_nsec = tv.tv_usec * 1000;
+
+               ret = OSAL_FAILURE_RETRY(semtimedop(sem->iSemId, &semBuf, 1, &ts));
+       }
+
+       /* result */
+       if (ret == 0) {
+               //PrintDbg ("UlOsaSemGet(%s) success.\n", sem->bName);
+               return OSAL_OK;
+       } else {
+               if (iFlags == OSAL_SEM_NOWAIT && errno == EAGAIN) {
+                       //PrintError ("UlOsaSemGet-nowait: now locked, failed to get.\n");
+                       return OSAL_ERROR;
+               } else if (iTimeout > 0 && errno == EAGAIN) {
+                       //PrintError ("UlOsaSemGet-timeout(%s): time-out\n",    sem->bName);
+                       return OSAL_ERR_TIMEOUT;
+               } else {
+                       //PrintError ("UlOsaSemGet error, errno=%d\n", errno);
+                       return OSAL_ERROR;
+               }
+       }
+
+}
+static int UlOsaNamedSemRelease(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+       struct sembuf semBuf;
+
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       //PrintDbg ("UlOsaSemRelease(%s)\n", sem->bName);
+       semBuf.sem_num = 0;
+       semBuf.sem_op = 1;
+       semBuf.sem_flg = SEM_UNDO;
+
+       if (semop(sem->iSemId, &semBuf, 1) == -1) {
+               //PrintError ("UlOsaSemRelease(%s) error! errno=%d.\n", sem->bName, errno);
+               return OSAL_ERROR;
+       } else {
+               return OSAL_OK;
+       }
+}
+
+static int UlOsaNamedSemReset(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+       union semun semUnion;
+
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       //PrintDbg ("UlOsaSemReset(%s).\n", sem->bName);
+       semUnion.val = sem->iCount;
+       if (semctl(sem->iSemId, 0, SETVAL, semUnion) == -1) {
+               //PrintError ("UlOsaSemReset, semctl Failed!\n");
+               return OSAL_ERROR;
+       }
+
+       return OSAL_OK;
+}
+
+static int UlOsaNamedSemGetval(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+       int n;
+
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+       n = semctl(sem->iSemId, 0, GETVAL, NULL);
+       if (n == -1) {
+               //PrintError ("UlOsaSemGetval, semctl Failed!\n");
+               return OSAL_ERROR;
+       } else {
+               //PrintDbg ("UlOsaSemGetval(%s): now %d\n", sem->bName, n);
+               return (int)n;
+       }
+}
+
+int OsaNamedSemCreate(const char bName[10], int iCount, int iAttribute,
+    unsigned int* puiSmid) {
+       return UlOsaNamedSemCreate(bName, iCount, iAttribute, puiSmid);
+}
+
+int OsaNamedSemGet(unsigned int uiSmid, int iFlags, int iTimeout) {
+       return UlOsaNamedSemGet(uiSmid, iFlags, iTimeout);
+}
+
+int OsaNamedSemRelease(unsigned int uiSmid) {
+       return UlOsaNamedSemRelease(uiSmid);
+}
+
+int OsaNamedSemDelete(unsigned int uiSmid) { // Deleting Semaphore : Never USE!!! - junhyeong.kim, sukki.min 12.04.20
+//return UlOsaNamedSemDelete (uiSmid);
+       return -1;
+}
+
+int OsaNamedSemGetval(unsigned int uiSmid) {
+       return UlOsaNamedSemGetval(uiSmid);
+}
+
+int OsaNamedSemReset(unsigned int uiSmid) {
+       return UlOsaNamedSemReset(uiSmid);
+}
+
diff --git a/osal/OsaLinuxUser.h b/osal/OsaLinuxUser.h
new file mode 100755 (executable)
index 0000000..af517b1
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaLinuxUser.h
+ *
+ *    Description:  This file includes linux header for user mode.
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef _LINUXUSER_H_
+#define _LINUXUSER_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <bits/local_lim.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include <time.h>              // posix queue
+#include <mqueue.h>   // posix queue
+#include <semaphore.h>
+#include <sys/types.h>  // system V IPC
+#include <sys/ipc.h>    // system V IPC        
+#include <sys/msg.h>    // system V IPC
+#include <sys/sem.h>
+#include<sys/time.h>
+#include <assert.h>
+#include <sys/prctl.h>
+#include <sys/shm.h>
+
+#include "Osal.h"
+
+#endif
+
diff --git a/osal/OsaQueue.c b/osal/OsaQueue.c
new file mode 100755 (executable)
index 0000000..15e3ef9
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaQueue.c
+ *
+ *    Description:  Implementation of POSIX Message queue
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "OsaLinuxUser.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+//it should provide the same APIs in OsaSys5MQueue.c because it was provided before
+typedef struct _osaMsgBuf_t {
+       long msgType;
+       char msgBuf[MAXML];
+} osaMsgBuf_t;
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      : OsaQueueCreate()
+ // Detail Description : 
+ //              
+ //              
+ //              
+ //
+ // Return Data Type   : Error Type. 
+ //
+ // Programming Note   :   
+ //            
+ //---------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueCreate(const char bName[10], unsigned int uiFlags,
+    unsigned int uiMaxnum, unsigned int uiMaxlen, unsigned int* puiQid) {
+#ifndef __NO_OS__      
+#ifdef POSIX_QUEUE
+       struct mq_attr MqAttr;
+       mqd_t QuId;
+
+       if (puiQid == NULL)
+       {
+               PrintDbg("Null Argument(s) \n");
+               return OSAL_ERROR;
+       }
+
+       MqAttr.mq_maxmsg = uiMaxnum;
+       MqAttr.mq_msgsize = uiMaxlen;
+
+       if((QuId = mq_open(bName, uiFlags, 0 ,&MqAttr)) < 0)
+       {
+               perror("mq_open() Failed: \n");
+               return errno;
+       }
+       *puiQid = (unsigned int)QuId;
+#else /* SYS5 MSG QUEUE*/
+       /*
+        uiFlags ; IPC_CREAT or IPC_CREAT | IPC_EXCL    
+        */
+       struct msqid_ds tSetMqAttr;
+
+       if (uiMaxnum == OSAL_DEFAULT_Q_NUM || uiMaxnum > MAXNBM) {
+               uiMaxnum = MAXNBM;
+       }
+
+       if (uiMaxlen == OSAL_DEFAULT_Q_LEN || uiMaxlen > MAXML) {
+               uiMaxlen = MAXML;
+       }
+
+       *puiQid = msgget(IPC_PRIVATE/*OsaGetKeyMQ(bName)*/, (int)uiFlags);
+       if (((int)*puiQid) == -1) //IPC_CREATE
+           {
+               perror("In OsaQueueCreate() : msgget: msgget failed");
+               //PrintError("In OsaQueueCreate() : Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+
+       /* Get the current value from the structure for the message queue and copy it in buf_t*/
+       if (msgctl((int)(*puiQid), IPC_STAT, &tSetMqAttr) == -1) {
+               perror("In OsaQueueCreate() : msgctl: msgctl failed");
+               //PrintError("In OsaQueueCreate() : Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+
+       /*SET the values of the message structure member using IPC_SET*/
+       tSetMqAttr.msg_qbytes = (unsigned long int)(uiMaxnum * uiMaxlen);
+
+       if (msgctl((int)(*puiQid), IPC_SET, &tSetMqAttr) == -1) {
+               perror("In OsaQueueCreate() : msgctl: msgctl failed");
+               //PrintError("In OsaQueueCreate() : Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+
+#endif /*END OF POSIX MSG QUEUE*/
+#endif
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      : OsaQueueClose()
+ // Detail Description : This is inconformance with POSIX standard. POSIX treats
+ //                      as a file
+ //
+ // Return Data Type   : Error Type
+ //
+ // Programming Note   : None
+ //---------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueClose(unsigned int uiQid) {
+#ifdef POSIX_QUEUE
+       if (mq_close((mqd_t)uiQid) < 0)
+       {
+               perror("mq_close() Failed :\n");
+               return ((int)errno);
+       }
+       return OSAL_OK;
+#endif
+       return OSAL_OK;
+}/*OsaQueueClose*/
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      : OsaQueueDelete()
+ // Detail Description : It deletes the Queue created using the puiQid and releases
+ //          allocated resources for the message queue.
+ //
+ // Return Data Type   : Error Type
+ //
+ // Programming Note   : None
+ //---------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueDelete(const char* bName, unsigned int uiQid) {
+#ifndef __NO_OS__              
+#ifdef POSIX_QUEUE
+       if (mq_unlink(bName) < 0)
+       {
+               perror("mq_unlink() Failed :\n");
+               return ((int)errno);
+       }
+#else /*SYS5 MSG QUEUE*/
+       // bName is not applicable in this case
+
+       if (msgctl((int)uiQid, IPC_RMID, NULL) == -1) {
+               perror("In OsaQueueDelete(): msgctl: msgctl failed");
+               //PrintError("In OsaQueueDelete(): Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+
+#endif /* EOF POSIX_QUEUE */
+#endif
+       return OSAL_OK;
+
+} //End if OsalQueueDelete
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      : OsaQueueSend
+ // Detail Description : This function  sends messages on  queues. 
+ //
+ // Return Data Type   : ErrorTypes
+ //
+ // Programming Note   : 
+ //--------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueSend(unsigned int uiQid, unsigned int uiFlags, void* pvMsg_buf,
+    unsigned int uiMsgLen, unsigned int uiPriority, pOsaTime_t ptTimeOut)
+
+{
+#ifndef __NO_OS__
+#ifdef POSIX_QUEUE
+
+       unsigned int err_no;
+       struct mq_attr tMqAttr;
+
+       if (uiFlags & OSAL_Q_NOWAIT)
+       {
+               tMqAttr.mq_flags = O_NONBLOCK;
+
+               if((err_no = mq_setattr((mqd_t)uiQid, &tMqAttr, (struct mq_attr *)NULL)) < 0)
+               {
+                       ////PrintError("mq_setattr(): mq_setattr() Failed errno=%d\n",err_no,0,0,0,0,0); //COMMON_071024_1
+                       return (OSAL_ERROR);
+               }
+       }
+
+       if ((err_no=mq_send((mqd_t)uiQid, (const char *)pvMsg_buf, uiMsgLen, uiPriority)) < 0)
+       {
+               ////PrintError("mq_send():Failed errno=%d qid=%x flag=%d\n",err_no,uiQid,uiFlags,0,0,0); //COMMON_071024_1
+               return (OSAL_ERROR);
+       }
+
+#else /*SYS5 MSG QUEUE*/
+       /*
+        uiFlags : IPC_NOWAIT , ZERO
+        pMsgLen: len - sizeof(int);
+        */
+       osaMsgBuf_t osaMsg;
+       int ret;
+
+       if (uiMsgLen > MAXML) {
+               ////PrintError("Message length exceeds max limit of %d\n",MAXML); //COMMON_071024_1
+               return OSAL_ERROR;
+       }
+
+       //Copy the message into OsaMsgStructure
+       osaMsg.msgType = 1; /* Should always be > 0*/
+       memcpy((void *)osaMsg.msgBuf, pvMsg_buf, uiMsgLen);
+
+       /* OSAL_080714 */
+       ret = OSAL_FAILURE_RETRY(
+           msgsnd((int )uiQid, (void* )&osaMsg, uiMsgLen, (int )uiFlags));
+       if (ret != 0) {
+               //perror("In OsaQueueSend () : msgsnd failed"); //COMMON_071024_1
+               ////PrintError("In OsaQueueSend() : Error no. : %d\n",errno); //COMMON_071024_1
+               return ((int)errno);
+       }
+#endif 
+
+#endif /* EOF POSIX_QUEUE */
+
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      : OsaQueueReceive
+ // Detail Description : It recieves  the messages  from the Message queue 
+ //
+ // Return Data Type   : Error Tyoe 
+ //
+ // Programming Note   : 
+ //--------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueReceive(unsigned int uiQid, unsigned int uiFlags, void* pvMsgBuf,
+    unsigned int uiBufLen, unsigned int* pMsgLen, pOsaTime_t ptTimeOut)
+
+{
+#ifndef __NO_OS__      
+#ifdef POSIX_QUEUE
+       /*
+        uiFlags : IPC_NOWAIT , ZERO
+        */
+#if 0  
+       struct timespec absTimeOut;
+#endif 
+       struct mq_attr tMqAttr;
+       int uiMsgLen =0;
+
+       if (uiFlags & OSAL_Q_NOWAIT)
+       {
+               tMqAttr.mq_flags = O_NONBLOCK;
+       }
+       else
+       {
+               tMqAttr.mq_flags = 0;
+       }
+#if 0
+       if (ptTimeOut && (!(uiFlags & OSAL_Q_NOWAIT)))
+       {
+               absTimeOut.tv_sec = ptTimeOut->Sec;
+               absTimeOut.tv_nsec = ptTimeOut->NanoSec;
+       }
+       else
+       {
+               absTimeOut.tv_sec = 0;
+               absTimeOut.tv_nsec = 0;
+       }
+#endif 
+       if(mq_setattr((mqd_t)uiQid, &tMqAttr, (struct mq_attr *)NULL) < 0)
+       {
+               perror("OsaQueueSend(): mq_setattr() Failed \n");
+               return ((int)errno);
+       }
+
+       if ((uiMsgLen = mq_receive((mqd_t)uiQid, (char *)pvMsgBuf, uiBufLen,
+                                                       (unsigned int *)NULL)) < 0)
+       {
+               perror("OsaQueueReceive(): mq_receive() Failed \n");
+               return ((int)errno);
+       }
+
+       // Update the received message length
+       *pMsgLen = uiMsgLen;
+#else /*SYS5 MSG QUEUE*/
+       /*
+        uiFlags : IPC_NOWAIT, MSG_NOERROR
+        buf_len : len - sizeof(int);
+        */
+
+       int iRet = 0;
+       osaMsgBuf_t osaMsg;
+
+       /*
+        type field is always ZERO as oldest message on the queue is to be returned .
+        */
+       /* OSAL_080714 */
+       iRet = OSAL_FAILURE_RETRY(
+           msgrcv((int)uiQid,(void*)&osaMsg, uiBufLen,OSAL_ZERO , (int)uiFlags));
+
+       if (iRet == -1) {
+               *pMsgLen = OSAL_ZERO;
+               pvMsgBuf = NULL;
+
+               if (errno != ENOMSG) {
+                       perror("In OsaQueueReceive() : msgrcv failed");
+                       //PrintError("In OsaQueueReceive() : Msg id %d, Error no. : %d\n", uiQid, errno);
+               }
+               return ((int)errno);
+       } else {
+               *pMsgLen = iRet;
+               memcpy(pvMsgBuf, (void *)osaMsg.msgBuf, (unsigned int)iRet);
+       }
+#endif
+#endif /* EOF POSIX_QUEUE */
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      : OsaQueueGetinfo
+ // Detail Description : It gets Message queue info .
+ //
+ // Return Data Type   : Error Type
+ //
+ // Programming Note   : It only get the number of messages in the queue(mqlen)
+ //          and maximum message length allowed (maxlen).  
+ //---------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueGetinfo(unsigned int uiQid, void* pvBuf) {
+#ifndef __NO_OS__
+#ifdef POSIX_QUEUE
+       struct mq_attr tMqAttr;
+
+       if (pvBuf == NULL)
+       {
+               //PrintError("Null Argument(s) \n");
+               return OSAL_ERROR;
+       }
+
+       if (mq_getattr((mqd_t)uiQid, &tMqAttr) , 0)
+       {
+               perror("OsaQueueGetinfo(): mq_getattr() Failed \n");
+               return ((int)errno);
+       }
+
+       ((pOsaQueueInfo_t)pvBuf)->flags = tMqAttr.mq_flags;
+       ((pOsaQueueInfo_t)pvBuf)->mqlen = tMqAttr.mq_curmsgs;
+       ((pOsaQueueInfo_t)pvBuf)->mqmax = tMqAttr.mq_maxmsg;
+       ((pOsaQueueInfo_t)pvBuf)->maxlen = tMqAttr.mq_msgsize;
+#else /*SYS5 MSG QUEUE*/
+       struct msqid_ds buf;
+       struct QueueInfo *data_t;
+
+       if (pvBuf == NULL) {
+               return OSAL_ERROR;
+       }
+
+       data_t = (struct QueueInfo*)pvBuf;
+
+       if (msgctl((int)uiQid, IPC_STAT, &buf) < 0) {
+               perror("In OsaQueueGetinfo() : msgctl: msgctl failed");
+               //PrintError("In OsaQueueGetinfo() : Error no. : %d\n",errno);
+               return ((int)errno);
+
+       }
+
+       data_t->flags = 0;
+       data_t->wqlen = 0;
+       data_t->wtid = 0;
+       data_t->mqlen = buf.msg_qnum;
+       data_t->mqmax = 0;
+       data_t->tid_ntfy = 0;
+       data_t->ev_ntfy = 0;
+       data_t->maxlen = buf.msg_qbytes;
+#endif
+#endif /* EOF POSIX_QUEUE */
+
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //---------------------------------------------------------------------------------
+ // Function Name      :   OsalQueueSetinfo 
+ // Detail Description :   it sets the corresponding Info for the queue  
+ //
+ // Return Data Type   :   ErrorType
+ //
+ // Programming Note   :   
+ //---------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaQueueSetinfo(unsigned int uiQid, void* pvBuf) {
+#ifndef __NO_OS__
+#ifdef POSIX_QUEUE
+
+       struct mq_attr tMqAttr;
+
+       if (pvBuf == NULL)
+       {
+               //PrintError("Null Argument(s) \n");
+               return OSAL_ERROR;
+       }
+
+       tMqAttr.mq_flags = ((pOsaQueueInfo_t)pvBuf)->flags;
+
+       if (mq_setattr((mqd_t)uiQid, &tMqAttr, (struct mq_attr *)NULL) , 0)
+       {
+               perror("OsaQueueGetinfo(): mq_getattr() Failed \n");
+               return ((int)errno);
+       }
+#else /*SYS5 MSG QUEUE*/
+       struct msqid_ds buf;
+       struct QueueInfo *data_t;
+
+       if (pvBuf == NULL) {
+               return OSAL_ERROR;
+       }
+
+       data_t = (struct QueueInfo*)pvBuf;
+
+       msgctl((int)uiQid, IPC_STAT, &buf);
+       buf.msg_qbytes = data_t->maxlen;
+
+       if (msgctl((int)uiQid, IPC_SET, &buf) < 0) {
+               perror("In OsaQueueGetinfo() : msgctl: msgctl failed");
+               //PrintError("In OsaQueueGetinfo() : Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+#endif
+#endif /* EOF POSIX_QUEUE */
+
+       return OSAL_OK;
+}
+
diff --git a/osal/OsaSem.c b/osal/OsaSem.c
new file mode 100755 (executable)
index 0000000..eaef3e1
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaSem.c
+ *
+ *    Description:  Semaphore and Mutex implementation
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "OsaLinuxUser.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+/* OSA_070901 : Replace System V semaphore with POSIX semaphore API. */
+typedef struct _UlOsaSem {
+       sem_t sem;
+       int iAttribute;
+       int iCount;
+       char bName[16];
+} UlOsaSem_t;
+
+/*-----------------------------------------------------------------------------
+ *  Functions
+ *-----------------------------------------------------------------------------*/
+/* TODO: apply iAttribute */
+// COMMON_071008_1
+static int UlOsaSemCreate(const char bName[10], int iCount, int iAttribute,
+    unsigned int* puiSmid) {
+       UlOsaSem_t* sem;
+
+       sem = (UlOsaSem_t*)malloc(sizeof(*sem));
+       if (!sem) {
+               //PrintError ("UlOsaSemCreate, Out of memory!\n");
+               return OSAL_ERROR;
+       }
+
+       if (sem_init(&sem->sem, 1, (unsigned int)iCount) < 0) {
+               //PrintError ("UlOsaSemCreate, sem_init Failed!\n");
+               free(sem);
+               return OSAL_ERROR;
+       }
+
+       sem->iAttribute = iAttribute;
+       sem->iCount = iCount;
+
+       memcpy((void*)sem->bName, (const void*)bName, (size_t)10);
+       sem->bName[10] = '\0';
+
+       *puiSmid = (unsigned int)sem;
+
+       return OSAL_OK;
+}
+
+static int UlOsaSemDelete(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       sem_destroy(&sem->sem);
+       free(sem);
+
+       return OSAL_OK;
+}
+
+static int UlOsaSemGet(unsigned int uiSmid, int iFlags, int iTimeout) {
+       int ret;
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       if (iFlags == OSAL_SEM_NOWAIT) {
+               /* no wait */
+               //PrintDbg ("UlOsaSemGet-nowait(%s).\n", sem->bName);
+               ret = sem_trywait(&sem->sem);
+       } else if (iTimeout == 0) {
+               /* wait _inifinite_ */
+               //PrintDbg ("UlOsaSemGet-infinite(%s).\n", sem->bName);
+               ret = OSAL_FAILURE_RETRY(sem_wait(&sem->sem));
+       } else {
+               /* with _timeout_ */
+               //PrintDbg ("UlOsaSemGet-timeout(%s).\n", sem->bName);
+               if (iTimeout < 0) {
+                       //PrintError ("UlOsaSemGet-timeout: invalid arg!\n");
+                       return OSAL_ERROR;
+               }
+#if 0
+               struct timeval tv;
+
+               gettimeofday (&tv, NULL);
+               tv.tv_sec += iTimeout / 1000000;
+               tv.tv_usec += iTimeout % 1000000;
+               if (tv.tv_usec >= 1000000)
+               {
+                       tv.tv_sec += tv.tv_usec / 1000000;
+                       tv.tv_usec %= 1000000;
+               }
+               ts.tv_sec = tv.tv_sec;
+               ts.tv_nsec = tv.tv_usec * 1000;
+
+               ret = OSAL_FAILURE_RETRY(sem_timedwait (&sem->sem, &ts));
+#endif
+               do // SoC_D00003324
+               {
+                       ret = sem_trywait(&sem->sem);
+                       if (ret != 0 && errno == EAGAIN) {
+                               usleep(10000);
+                               iTimeout -= 10000;
+                       } else  // No-Error + Error without EAGAIN
+                       {
+                               break;
+                       }
+               } while (iTimeout > 0);
+       }
+
+       /* result */
+       if (ret == 0) {
+               //PrintDbg ("UlOsaSemGet(%s) success.\n", sem->bName);
+               return OSAL_OK;
+       } else {
+               if (iFlags == OSAL_SEM_NOWAIT && errno == EAGAIN) {
+//                     PrintError ("UlOsaSemGet-nowait: now locked, failed to get.\n");
+                       return OSAL_ERROR;
+               } else if (iFlags == OSAL_SEM_WAIT && iTimeout <= 0) {// Before : cond - (iTimeout > 0 && errno == ETIMEDOUT)
+                                                                     //PrintError ("UlOsaSemGet-timeout(%s): time-out\n",sem->bName);
+                       return OSAL_ERR_TIMEOUT;
+               } else {
+                       //PrintError ("UlOsaSemGet error, errno=%d\n", errno);
+                       return OSAL_ERROR;
+               }
+       }
+}
+
+static int UlOsaSemRelease(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       //PrintDbg ("UlOsaSemRelease(%s)\n", sem->bName);
+       if (sem_post(&sem->sem) != 0) {
+               //PrintError ("UlOsaSemRelease(%s) error! errno=%d.\n", sem->bName, errno);
+               return OSAL_ERROR;
+       } else {
+               return OSAL_OK;
+       }
+}
+
+static int UlOsaSemReset(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+       //PrintDbg ("UlOsaSemReset(%s).\n", sem->bName);
+
+       /* For threads currently blocked, the effect of destroying is not defined in POSIX.
+        Currently, this will not release any blocked threads. */
+       if (sem_destroy(&sem->sem) < 0) {
+               //PrintError ("UlOsaSemReset, sem_destroy errno=%d\n", errno);
+               return OSAL_ERROR;
+       }
+
+       /* re-init */
+       sem_init(&sem->sem, 1, (unsigned int)sem->iCount);
+
+       return OSAL_OK;
+}
+
+static int UlOsaSemGetval(unsigned int uiSmid) {
+       UlOsaSem_t *sem = (UlOsaSem_t*)uiSmid;
+       int n;
+       if (!sem) {
+               return OSAL_ERROR;
+       }
+
+       if (sem_getvalue(&sem->sem, &n) != 0) {
+               //PrintError ("UlOsaSemGetval(%s), sem_getvalue errno=%d\n", sem->bName, errno);
+               return OSAL_ERROR;
+       } else {
+               //PrintDbg ("UlOsaSemGetval(%s): now %d\n", sem->bName, n);
+               return (int)n;
+       }
+}
+
+/**
+ * @brief      Create a semaphore object.
+ * @remarks    the semaphore value shall be incremented more than initial value.
+ * @param      bName [in] semaphore name, for debugging.               
+ * @param      iCount [in] initial semaphore value                     
+ * @param      iAttribute [in] not used now implementation.
+ * @param      puiSmid [out] semaphore object ID.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemCreate(const char bName[10], int iCount, int iAttribute,
+    unsigned int* puiSmid) {
+       /* OSA_070901 */
+       return UlOsaSemCreate(bName, iCount, iAttribute, puiSmid);
+}
+
+/**
+ * @brief      Lock a semaphore.
+ * @remarks perform a semaphore lock operation.
+ * @param      uiSmid [in] semaphore object ID created by OsaSemCreate.
+ * @param      iFlags [in] [OSAL_SEM_NOWAIT | OSAL_SEM_WAIT]
+ - OSAL_SEM_NOWAIT : lock the semaphore only if the semaphore value is
+ currently not locked. otherwise, return OSAL_ERROR.                           
+ - OSAL_SEM_WAIT : lock the semaphore. If the semaphore values is
+ currently locked, the calling thread shall be blocked.
+ In linux kernel mode, iFlags is not used, always wait infinitely.
+ * @param      iTimeout [in] timeout value in _microsecond_.
+ Only affected when iFlags is OSAL_SEM_WAIT.
+ - 0 :  wait infinitely.
+ - positive value : wait will be terminated when expires and return OSAL_ERR_TIMEOUT.
+ - negative value : error.
+ * @retval     [OSAL_OK | OSAL_ERROR | OSAL_ERR_TIMEOUT]
+ */
+int OsaSemGet(unsigned int uiSmid, int iFlags, int iTimeout) {
+       /* OSA_070901 */
+       return UlOsaSemGet(uiSmid, iFlags, iTimeout);
+}
+
+/**
+ * @brief      Unlock a semaphore
+ * @remarks    If the semaphore value is positive currently, then no threads were
+ blocked by semaphore and simply semaphore value is incremented.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemRelease(unsigned int uiSmid) {
+       /* OSA_070901 */
+       return UlOsaSemRelease(uiSmid);
+}
+
+/**
+ * @brief      Destroy a semaphore object.
+ * @remarks    It is unsafe if any thread is currently blocked by the semaphore.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemDelete(unsigned int uiSmid) {
+       /* OSA_070901 */
+       return UlOsaSemDelete(uiSmid);
+}
+
+/**
+ * @brief      Get the current semaphore value
+ * @remarks    If the semaphore is locked, returns zero or negative value.
+ Only implemented in linux user mode.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemGetval(unsigned int uiSmid) {
+       /* OSA_070901 */
+       return UlOsaSemGetval(uiSmid);
+}
+
+/**
+ * @brief      Reset the semaphore to initial state.
+ * @remarks    Set the semaphore value to iCount that given by OsaSemCreate().
+ Blocked threads by this semaphore shall not released if initial
+ value was zero or negative. If initial value was positive,
+ same number(semaphore value) of threads shall be released.
+ Only implemented in linux user mode.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemReset(unsigned int uiSmid) {
+       /* OSA_070901 */
+       return UlOsaSemReset(uiSmid);
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      : OsaMutCreate 
+ // Detail Description : This function is used to creat a mutex.  
+ //              Mutex attributes can be either "Fast" mutex, "Recursive
+ //              mutexes or "Error checking " mutex .
+ //              piMutid is the pointer to the new mutex ID created else 
+ //              is NULL. 
+ //              
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaMutCreate(const char bName[10], int iAttributes, unsigned int* puiMutid) {
+       pthread_mutexattr_t attr_t;
+       pthread_mutex_t* pmutex_t;
+
+       if (puiMutid == NULL) {
+               //PrintError("In OsaMutCreate() : NULL PTR ERROR");
+               return OSAL_ERROR;
+       }
+
+       pmutex_t = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+       if (pmutex_t) {
+               pthread_mutexattr_init(&attr_t);
+
+               switch (iAttributes) {
+                       case OSAL_MU_RECURSIVE:
+                               pthread_mutexattr_settype(&attr_t, PTHREAD_MUTEX_RECURSIVE_NP);
+                               pthread_mutex_init(pmutex_t, (const pthread_mutexattr_t *)&attr_t);
+                               break;
+                       case OSAL_MU_NOERROR:
+                               pthread_mutexattr_settype(&attr_t, PTHREAD_MUTEX_ERRORCHECK_NP);
+                               pthread_mutex_init(pmutex_t, (const pthread_mutexattr_t *)&attr_t);
+                               break;
+                       default:
+                               pthread_mutex_init(pmutex_t, NULL);
+                               break;
+               }
+
+               (*puiMutid) = (unsigned int)pmutex_t;
+
+               pthread_mutexattr_destroy(&attr_t);
+       } else {
+               //PrintError("In OsaMutCreate() : No memory");
+               return OSAL_ERROR;
+       }
+
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      : OsaMutDelete  
+ // Detail Description : This function deletes the Mutex with corresponding
+ //              mutex ID .
+ //              This function deallocates any system resources allocated 
+ //              by the system for use by this task for this Mutex.
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaMutDelete(unsigned int uiMutid) {
+       int iRet;
+
+       pthread_mutex_t* pmutex_t = (pthread_mutex_t *)uiMutid;
+       if (pmutex_t == NULL) {
+               return OSAL_OK;
+       }
+
+       iRet = pthread_mutex_destroy(pmutex_t);
+       if (iRet < 0) {
+               perror("In OsaMutDelete() :  failed ");
+               //PrintError("Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+
+       free(pmutex_t);
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      : OsaMutRelease  
+ // Detail Description : This function unlocks the mutex.  
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None  
+ //
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaMutRelease(unsigned int uiMutid) {
+       int iRet;
+
+       pthread_mutex_t* pmutex_t = (pthread_mutex_t *)uiMutid;
+       iRet = pthread_mutex_unlock(pmutex_t);
+       if (iRet < 0) {
+               perror("In OsaMutRelease() :  failed ");
+               //PrintError("Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      : OsaMutGet  
+ // Detail Description : This function locks the mutex.  
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaMutGet(unsigned int uiMutid, int iFlags, int iTimeout) {
+       int iRet;
+       pthread_mutex_t* pmutex_t = (pthread_mutex_t *)uiMutid;
+       iRet = pthread_mutex_lock(pmutex_t);
+       if (iRet < 0) {
+               perror("In OsaMutGet() :  failed ");
+               //PrintError("Error no. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+// $$$
+//-----------------------------------------------------------------------------
+// Function Name      : OsaMutTryGet
+// Detail Description : This function locks the mutex.  But if the mutex is
+//                      already locked, it returns immediately with error.
+//
+// Return Data Type   : ErrorType
+//
+// Programming Note   : None.
+//------------------------------------------------------------------------------
+// $$$
+int OsaMutTryGet(unsigned int uiMutid, int iFlags, int iTimeout) {
+       int iRet;
+
+       pthread_mutex_t* pmutex_t = (pthread_mutex_t *)uiMutid;
+       iRet = pthread_mutex_trylock(pmutex_t);
+       if (iRet) {
+               return ((int)iRet);
+       }
+       return OSAL_OK;
+}
+
diff --git a/osal/OsaSignal.c b/osal/OsaSignal.c
new file mode 100755 (executable)
index 0000000..59144c1
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaSignal.c
+ *
+ *    Description:  Signal implementation
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "OsaLinuxUser.h"
+
+/*-----------------------------------------------------------------------------
+ *  Functions
+ *-----------------------------------------------------------------------------*/
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaSigProcmask 
+ // Detail Description : Examine and/or change the list  of  currently  blocked
+ //                            signals
+ //
+ // Return Data Type   :       ErrorType 
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaSigProcmask(int iMode, const unsigned int* puiNewmask,
+    unsigned int* puiOldmask) {
+       int iRet;
+       iRet = sigprocmask(iMode, (const sigset_t *)puiNewmask,
+           (sigset_t*)puiOldmask);
+       if (iRet) {
+               perror("SigProcMask:  SigProcMask Failed  ");
+               //PrintError("Error No. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaSigSuspend 
+ // Detail Description : Suspend the task until delivery of a signal 
+ //
+ // Return Data Type   :       ErroType  
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaSigSuspend(unsigned int* puiPending) {
+       int iRet;
+
+       iRet = sigpending((sigset_t *)puiPending);
+       if (iRet) {
+               perror("SigSuspend: SigSuspend INTR  ");
+               //PrintError("Error No. : %d\n",errno);
+               return ((int)errno);
+
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaSigTimedwait 
+ // Detail Description : Wait for a signal 
+ //
+ // Return Data Type   : ErrorType 
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+
+int OsaSigTimedwait(void) {
+       int iRet;
+       iRet = pause();
+       if (iRet) {
+               perror("TimeWait: TimeWait INTR  ");
+               //PrintError("Error No. : %d\n",errno);
+               return ((int)errno);
+
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaSigSetmask 
+ // Detail Description : Set the signal mask
+ //
+ // Return Data Type   :       ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaSigSetmask(int iSigno) {
+       struct sigaction Action_t;
+
+       Action_t.sa_flags = 0;
+
+       if (sigaddset(&(Action_t.sa_mask), iSigno) < 0) {
+               perror("sigaddset:  sigaddset Failed  ");
+               //PrintError("Error No. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaKill 
+ // Detail Description : Send a kill  signal to a task 
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaKill(int iId, int iSigno) {
+       if (kill(iId, iSigno) < 0) {
+               perror("KILL: Error  ");
+               return OSAL_ERROR;
+       }
+       return OSAL_OK;
+}
diff --git a/osal/OsaTask.c b/osal/OsaTask.c
new file mode 100755 (executable)
index 0000000..492a437
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  OsaTask.c
+ *
+ *    Description:  Thread implementation
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "OsaLinuxUser.h"
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define TASK_COMM_LEN  16
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+typedef void (*pEntry_f)(void*);
+
+typedef struct {
+       char aName[TASK_COMM_LEN];
+       pEntry_f pEntryFunc;
+       void* pArg;
+} ThreadParam_t;
+
+/*-----------------------------------------------------------------------------
+ *  Functions
+ *-----------------------------------------------------------------------------*/
+static void* _thread_start_handler(void* pArg) {
+       int iRet;
+       ThreadParam_t sThreadParam;
+
+       if (NULL == pArg) {
+               return 0;
+       }
+       sThreadParam = *((ThreadParam_t*)pArg);
+       free(pArg);
+
+       iRet = prctl(PR_SET_NAME, sThreadParam.aName, 0, 0, 0);
+       if (iRet) {
+               perror("In OsaTaskSpawn() :  prctl() Failed\n ");
+               //PrintError("In OsaTaskSpawn() : prctl() error no. : %d\n", iRet);
+       }
+
+       (*sThreadParam.pEntryFunc)(sThreadParam.pArg);
+       return 0;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTaskSpawn
+ // Detail Description : This API function creates and activates a new task
+ //                    with a specified priority and options. It returns
+ //                    a system-assigned ID.
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTaskSpawn(const char* pName, unsigned int* puiTid, int iPriority,
+    int iStacksize, unsigned int uiMode, void* pEntryPt, int iArg1, int iArg2,
+    int iArg3, int iArg4, void* pvArg5) {
+
+#define OSAL_SCHED_POLICY SCHED_FIFO
+
+       int iRet;
+       pthread_t curThread = pthread_self();
+       pthread_t createThread;
+       pthread_attr_t tattr_t;
+       struct sched_param param_t;
+       int curThreadPolicy;
+       int createThreadPolicy = OSAL_SCHED_POLICY;
+       ThreadParam_t* pThreadParam;
+
+       pthread_getschedparam(curThread, &curThreadPolicy, &param_t);
+
+       if (iPriority == 0) {
+               createThreadPolicy = SCHED_OTHER;
+       } else if (iPriority > sched_get_priority_max(OSAL_SCHED_POLICY)) {
+               iPriority = sched_get_priority_max(OSAL_SCHED_POLICY);
+       } else if (iPriority < sched_get_priority_min(OSAL_SCHED_POLICY)) {
+               iPriority = sched_get_priority_min(OSAL_SCHED_POLICY);
+       }
+
+       if (iStacksize < OSAL_DEFAULT_STSZ) {
+               iStacksize = OSAL_DEFAULT_STSZ;
+       }
+
+       /* set thread parameters: name, entry func and argument. */
+       pThreadParam = (ThreadParam_t*)malloc(sizeof(ThreadParam_t));
+
+       if (NULL == pThreadParam) {
+               perror("Memory Allocation Failed : \n");
+               return OSAL_ERROR;
+       }
+
+       memset(pThreadParam->aName, 0x00, TASK_COMM_LEN);
+       strncpy(pThreadParam->aName, pName, (TASK_COMM_LEN - 1));
+       pThreadParam->pEntryFunc = (pEntry_f)pEntryPt;
+       pThreadParam->pArg = pvArg5;
+
+       /* set stack size : 16Kbyte */
+       if (iStacksize <= PTHREAD_STACK_MIN) {
+               iRet = pthread_create(&createThread, (pthread_attr_t *)NULL,
+                   _thread_start_handler, (void*)pThreadParam);
+               if (iRet) {
+                       *puiTid = (unsigned int)NULL;
+                       free(pThreadParam);
+                       perror("In OsaTaskSpawn() :  pthread create Failed\n ");
+                       //PrintError("In OsaTaskSpawn() : error no. : %d\n", iRet);
+                       return ((int)iRet);
+               }
+       }
+       // set Stakc size by iStacksize, using pthread_attr_t
+       else {
+               iRet = pthread_attr_init(&tattr_t);
+               if (iRet) {
+                       *puiTid = (unsigned int)NULL;
+                       free(pThreadParam);
+                       perror("In OsaTaskSpawn() : pthread attr init  Failed\n ");
+                       //PrintError("In OsaTaskSpawn() : error no. : %d\n", iRet);
+                       return ((int)iRet);
+               }
+               iRet = pthread_attr_setstacksize(&tattr_t, (unsigned int)iStacksize);
+               if (iRet) {
+                       *puiTid = (unsigned int)NULL;
+                       free(pThreadParam);
+                       perror("In OsaTaskSpawn() : pthread attr setstacksize Failed\n ");
+                       //PrintError("In OsaTaskSpawn() : error no. : %d\n", iRet);
+                       pthread_attr_destroy(&tattr_t);
+                       return ((int)iRet);
+               }
+               iRet = pthread_create(&createThread, (pthread_attr_t *)&tattr_t,
+                   _thread_start_handler, (void*)pThreadParam);
+               if (iRet) {
+                       *puiTid = (unsigned int)NULL;
+                       free(pThreadParam);
+                       perror("In OsaTaskSpawn() :  pthread create Failed\n ");
+                       //PrintError("In OsaTaskSpawn() : error no. : %d\n", iRet);
+                       pthread_attr_destroy(&tattr_t);
+                       return ((int)iRet);
+               }
+
+               pthread_attr_destroy(&tattr_t);
+       }
+
+       /* Set Priority by iPriority , if different from parent priority  */
+       if (iPriority != param_t.__sched_priority) {
+               param_t.__sched_priority = iPriority;
+               iRet = pthread_setschedparam(createThread, createThreadPolicy, &param_t);
+               if (iRet) {
+                       *puiTid = (unsigned int)NULL;
+                       perror("In OsaTaskSpawn() :  pthread setschedparam Failed\n ");
+                       //PrintError("In OsaTaskSpawn() : error no. : %d\n", iRet);
+                       pthread_kill(createThread, (int)NULL);
+                       return ((int)iRet);
+               }
+       }
+
+       iRet = pthread_detach(createThread);
+       if (iRet) {
+               *puiTid = (unsigned int)NULL;
+               perror("In OsaTaskSpawn() :  pthread_detach Failed\n ");
+               //PrintError("In OsaTaskSpawn() : detach error no. : %d\n", iRet);
+               pthread_kill(createThread, (int)NULL);
+               return ((int)iRet);
+       }
+       *puiTid = (unsigned int)createThread;
+
+       //PrintDbg("%s thread created policy: %d, priority %d\n", pName, createThreadPolicy, iPriority);
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaExit 
+ // Detail Description : This function terminates the calling thread.
+ //
+ // Return Data Type   : Void
+ //
+ // Programming Note   : None. 
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+void OsaExit(int iStatus) {
+       pthread_exit(0);
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTaskDelete 
+ // Detail Description : This function terminates the thread having the 
+ //                            corresponding thread ID .  
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTaskDelete(unsigned int uiTid) {
+       int iRet = 0;
+       iRet = pthread_cancel((pthread_t)uiTid);
+       if (iRet) {
+               perror("In OsaTaskDelete() : TaskDelete  Failed ");
+               //PrintError("In OsaTaskDelete() : error no. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTaskSetPriority 
+ // Detail Description : This function sets the Priority for the created thread.
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.  
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTaskSetPriority(unsigned int uiTid, int iNewpriority) {
+       int iRet, iPolicy;
+       struct sched_param param_t;
+       /* sched_priority will be the priority of the thread */
+       param_t.sched_priority = iNewpriority;
+       /* only supported policy, others will result in ENOTSUP */
+       iPolicy = SCHED_FIFO;
+       /* scheduling parameters of target thread */
+       iRet = pthread_setschedparam(uiTid, iPolicy, &param_t);
+       if (iRet) {
+               perror("In OsaTaskSetPriority() : TaskSetPriority  set Failed ");
+               //PrintError("In  OsaTaskSetPriority() : error no. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      : OsaTaskGetPriority 
+ // Detail Description : This function gets the corresponding priority of the
+ //                            supplied thread ID .  
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+
+int OsaTaskGetPriority(unsigned int uiTid, int* piPriority) {
+       int iRet, iPolicy = 0;
+       struct sched_param param_t;
+       iRet = pthread_getschedparam(uiTid, (int *)&iPolicy, &param_t);
+       if (iRet) {
+               piPriority = NULL;
+               perror("In OsaTaskGetPriority() : TaskGetPriority Failed ");
+               //PrintError("In OsaTaskGetPriority() : error no. : %d\n",errno);
+               return ((int)errno);
+       }
+       *piPriority = param_t.sched_priority;
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTaskNanosleep 
+ // Detail Description : This function makes the thread to sleep for nanosec
+ //                    precision.  
+ //
+ // Return Data Type   :       ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+
+int OsaTaskNanosleep(int iNanosec) {
+       struct timespec timeSpec_t, timeSpecRem_t;
+       int iRetval;
+
+       timeSpec_t.tv_sec = 0;
+
+       if (iNanosec > OSAL_NSEC_MAX) {
+               iNanosec = OSAL_NSEC_MAX;
+       }
+
+       timeSpec_t.tv_nsec = iNanosec;
+
+       iRetval = nanosleep(&timeSpec_t, &timeSpecRem_t);
+
+       if (iRetval) {
+               perror("TaskNanoSleep: TaskNanoSleep Failed ");
+               //PrintError("Error No. : %d\n",errno);
+               return ((int)errno);
+
+       }
+
+       return OSAL_OK;
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTaskGetId 
+ // Detail Description : This function get the current thread ID.  
+ //
+ // Return Data Type   : Current thread ID .
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTaskGetId(void) {
+       return ((pthread_t)pthread_self());
+}
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTaskDelaymsecs 
+ // Detail Description : This function makes the thread to sleep for millisec
+ //                    precision.  
+ //
+ // Return Data Type   :       ErrorType
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTaskDelaymsecs(unsigned int uiMsec) {
+       unsigned int uiDiv, uiRem;
+       struct timespec timeSpec_t, timeSpecRem_t;
+       int iRetval;
+
+       uiDiv = uiMsec / 1000;
+       uiRem = uiMsec % 1000;
+
+       timeSpec_t.tv_sec = uiDiv;
+       timeSpec_t.tv_nsec = uiRem * 1000000;
+
+       iRetval = nanosleep(&timeSpec_t, &timeSpecRem_t);
+
+       if (iRetval) {
+               perror("In OsaTaskDelaymsecs() : TaskNanoSleep Failed ");
+               //PrintError("In OsaTaskDelaymsecs() : error no. : %d\n",errno);
+               return ((int)errno);
+       }
+       return OSAL_OK;
+}
+
+/*****************************************************************************
+ ** OsaTaskDelayticks -
+ *****************************************************************************/
+int OsaTaskDelayticks(int iTicks) {
+       struct timespec ts, tsr;
+       unsigned int hz;
+       int ret;
+
+       hz = OsaGetTicksPerSecond();
+       ts.tv_sec = iTicks / hz;
+       ts.tv_nsec = (iTicks % hz) * (1000 * 1000 * 1000 / hz);
+
+       for (;;) {
+               ret = nanosleep(&ts, &tsr);
+               if (ret == 0) {
+                       return OSAL_OK;
+               } else if (errno == EINTR) {
+                       ts = tsr;
+               } else {
+                       return OSAL_ERROR;
+               }
+       }
+}
+
+/*****************************************************************************
+ ** OsaTaskSuspend-
+ *****************************************************************************/
+int OsaTaskSuspend(unsigned int uiTid) {
+       //Not Implemented
+       return OSAL_OK;
+
+}
+
+/*****************************************************************************
+ ** OsaTaskResume-
+ *****************************************************************************/
+int OsaTaskResume(unsigned int uiTid) {
+       //Not Implemented
+       return OSAL_OK;
+
+}
+
+/*****************************************************************************
+ ** OsaTaskRestart-
+ *****************************************************************************/
+int OsaTaskRestart(unsigned int uiTid) {
+       //Not Implemented
+       return OSAL_OK;
+}
diff --git a/osal/Osal.h b/osal/Osal.h
new file mode 100755 (executable)
index 0000000..d7ef083
--- /dev/null
@@ -0,0 +1,459 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  Osal.h
+ *
+ *    Description:  OSAL header file
+ *
+ *        Version:  1.0
+ *        Created:  26 March 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef _OSAL_H_
+#define _OSAL_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#if defined(__KERNEL__)
+#include <linux/fs.h>
+#else
+
+#include <signal.h>
+#include <sys/ipc.h>
+#include <mqueue.h> 
+
+#endif
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#ifndef TRUE
+#define TRUE           1
+#endif
+
+#ifndef FALSE
+#define FALSE          0
+#endif
+
+#define OSAL_OK                        0x00
+#define OSAL_EXIST             -2
+#define OSAL_ERROR             -1
+#define OSAL_ZERO              0x00
+
+#if !defined(__KERNEL__)
+#if defined(_GNU_SOURCE)
+#define OSAL_FAILURE_RETRY(expr)       TEMP_FAILURE_RETRY(expr)
+#else
+#define OSAL_FAILURE_RETRY(expr)                       \
+       ({ long int _ret;                                               \
+       do _ret = (long int) (expr);                    \
+       while (_ret == -1L && errno == EINTR);  \
+       _ret; })
+#endif /* _GNU_SOURCE */
+#endif /*!__KERNEL__ */
+
+#if defined(__KERNEL__)
+#define OSA_Q_NOWAIT           0x1
+#define OSA_Q_WAIT                     0x2
+#elif defined(POSIX_QUEUE) //user mode, posix queue                            
+#define OSA_Q_NOWAIT           O_NONBLOCK                      
+#define OSA_Q_WAIT                     0x00                                    
+#elif defined(__NO_OS__)
+#define OSA_Q_NOWAIT 0
+#define OSA_Q_WAIT 0
+#else  //user mode, system v ipc
+#define OSA_Q_NOWAIT           IPC_NOWAIT
+#define OSA_Q_WAIT                     0x00
+#endif 
+
+#define OSAL_ERR_TIMEOUT       0x37
+#define OSAL_ERR_NOMSG         0x01
+
+#define OSAL_TIMER_PERODIC     1
+#define OSAL_TIMER_ONESHOT     0
+#define OSAL_NSEC_MAX          999999999
+
+#if defined(__KERNEL__) // Linux kernel mode 
+#define OSAL_MIN_STSZ          (16*1024)       /*kthread min statck size*/
+#else // Linux user mode
+#undef  PTHREAD_STACK_MIN              ///* PTHREAD_STACK_MIN is defined in <pthread.h>, It's configure stack limit in  pthread
+#define PTHREAD_STACK_MIN      (16*1024)
+#define OSAL_MIN_STSZ          PTHREAD_STACK_MIN       
+#endif
+
+#define OSAL_MAX_STSZ          (16*1024)
+#define OSAL_DEFAULT_STSZ      OSAL_MIN_STSZ
+#define OSAL_DEFAULT_PRIORITY  0
+
+#define MAXNBM                         1024    //5
+#define MAXML                          8192    
+#define OSAL_DEFAULT_Q_NUM     1
+#define OSAL_DEFAULT_Q_LEN     1
+
+#define OSAL_Q_NOWAIT          OSA_Q_NOWAIT
+#define OSAL_Q_WAIT                    OSA_Q_WAIT
+
+#define OSAL_Q_CREAT           O_CREAT
+#define OSAL_Q_EXCL                    O_EXCL
+
+//Mutex
+#define OSAL_MU_RECURSIVE      0x00000001
+#define OSAL_MU_NOERROR        0x00000002
+#define OSAL_MU_DEFAULT                0x00000000
+
+//Semaphore
+#define OSAL_SINGLE_SEM                1
+#define OSAL_SEM_CREAT         IPC_CREAT
+#define OSAL_SEM_EXCL          IPC_EXCL
+#define OSAL_SEM_WAIT          -1
+#define OSAL_SEM_NOWAIT        0
+#define OSAL_DEFAULT_SEMVAL    1
+
+// Signal 
+#define OSAL_SIG_BLOCK         SIG_BLOCK
+#define OSAL_SIG_UNBLOCK       SIG_UNBLOCK
+#define OSAL_SIG_SETMASK       SIG_SETMASK
+
+#if defined(__KERNEL__)
+#define OSAL_ASSERT(expression) \
+                       { \
+                               if(!expression){ \
+                                       panic("Assertion: \"%s\" failed, in file %s, line %d\n", \
+                               #expression, __FILE__, __LINE__); \
+                               } \
+                       }
+#else
+#define OSAL_ASSERT(expression) assert(expression)
+#endif 
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+typedef struct QueueInfo {
+       char name[10]; /* name of the queue */
+       unsigned int flags; /* queue attributes */
+       unsigned int wqlen; /* number of waiting tasks */
+       unsigned int wtid; /* ID of the first waiting task */
+       unsigned int mqlen; /* number of messages in the queue */
+       unsigned int mqmax; /* max number of messages allowed */
+       unsigned int tid_ntfy; /* task to be notified of message arrival */
+       unsigned int ev_ntfy; /* events to post to notify message arrival */
+       unsigned int maxlen; /* maximum message length allowed */
+} OsaQueueInfo_t, *pOsaQueueInfo_t;
+
+typedef struct _Osa_Time {
+       unsigned int Sec;
+       unsigned int NanoSec;
+} OsaTime_t, *pOsaTime_t;
+
+typedef enum {
+       CACHE_FLUSH = 0, CACHE_INVALIDE, CACHE_CLEAN, CACHE_FLUSH_ALL,
+} OsaCacheCtrl_t;
+
+typedef struct _cache_io_param {
+       OsaCacheCtrl_t type;
+       unsigned int startAddr;
+       unsigned int endAddr;
+} ioCacheData_t, *pioCacheData_t;
+
+/*-----------------------------------------------------------------------------
+ *  Functions
+ *-----------------------------------------------------------------------------*/
+int OsaTaskSpawn(const char* pName, unsigned int* puiTid, int iPriority,
+    int iStacksize, unsigned int uiMode, void* pvEntryPt, int iArg1, int iArg2,
+    int iArg3, int iArg4, void* pvArg5);
+
+/* stop a running thread (called by "killer") */
+int OsaTaskDelete(unsigned int uiTid);
+
+/* cleanup thread environment (called by thread upon receiving termination signal) */
+void OsaExitKthread(void* pvArg);
+
+/* setup thread environment (called by new thread) */
+void OsaInitKthread(void* pvArg);
+
+int OsaTaskGetId(void);
+
+/**
+ * @brief      Create a semaphore object.
+ * @remarks    the semaphore value shall be incremented more than initial value.
+ * @param      bName [in] semaphore name, for debugging.               
+ * @param      iCount [in] initial semaphore value                     
+ * @param      iAttribute [in] not used now implementation.
+ * @param      puiSmid [out] semaphore object ID.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemCreate(const char bName[10], int iCount, int iAttribute,
+    unsigned int* puiSmid); // COMMON_071008_1
+
+/**
+ * @brief      Lock a semaphore.
+ * @remarks perform a semaphore lock operation.
+ * @param      uiSmid [in] semaphore object ID created by OsaSemCreate.
+ * @param      iFlags [in] [OSAL_SEM_NOWAIT | OSAL_SEM_WAIT]
+ - OSAL_SEM_NOWAIT : lock the semaphore only if the semaphore value is
+ currently not locked. otherwise, return OSAL_ERROR.                           
+ - OSAL_SEM_WAIT : lock the semaphore. If the semaphore values is
+ currently locked, the calling thread shall be blocked.
+ In linux kernel mode, iFlags is not used, always wait infinitely.
+ * @param      iTimeout [in] timeout value in _microsecond_.
+ Only affected when iFlags is OSAL_SEM_WAIT.
+ - 0 :  wait infinitely.
+ - positive value : wait will be terminated when expires and return OSAL_ERR_TIMEOUT.
+ - negative value : error.
+ * @retval     [OSAL_OK | OSAL_ERROR | OSAL_ERR_TIMEOUT]
+ */
+int OsaSemGet(unsigned int uiSmid, int iFlags, int iTimeout);
+
+/**
+ * @brief      Unlock a semaphore
+ * @remarks    If the semaphore value is positive currently, then no threads were
+ blocked by semaphore and simply semaphore value is incremented.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemRelease(unsigned int uiSmid);
+
+/**
+ * @brief      Destroy a semaphore object.
+ * @remarks    It is unsafe if any thread is currently blocked by the semaphore.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemDelete(unsigned int uiSmid);
+
+/**
+ * @brief      Get the current semaphore value
+ * @remarks    If the semaphore is locked, returns zero or negative value.
+ Only implemented in linux user mode.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemGetval(unsigned int uiSmid);
+
+/**
+ * @brief      Reset the semaphore to initial state.
+ * @remarks    Set the semaphore value to iCount that given by OsaSemCreate().
+ Blocked threads by this semaphore shall not released if initial
+ value was zero or negative. If initial value was positive,
+ same number(semaphore value) of threads shall be released.
+ Only implemented in linux user mode.
+ * @param      uiSmid [id] semaphore object ID created by OsaSemCreate.
+ * @retval     [OSAL_OK | OSAL_ERROR]
+ */
+int OsaSemReset(unsigned int uiSmid);
+
+//Mutex
+int OsaMutCreate(const char bName[10], int iAttributes, unsigned int* pvArg);
+
+int OsaMutDelete(unsigned int uiSmid);
+
+int OsaMutRelease(unsigned int uiSmid);
+
+int OsaMutGet(unsigned int uiSmid, int iFlags, int iTimeout);
+
+//Queue
+int OsaQueueCreate(const char name[10], unsigned int flags, unsigned int maxnum,
+    unsigned int maxlen, unsigned int* pqid);
+int OsaQueueOpen(unsigned int uiQid);
+int OsaQueueClose(unsigned int uiQid);
+
+int OsaQueueSend(unsigned int uiQid, unsigned int uiFlags, void* pvMsg_buf,
+    unsigned int uiMsgLen, unsigned int uiPriority, pOsaTime_t ptTimeOut);
+int OsaQueueReceive(unsigned int uiQid, unsigned int uiFlags, void* pvMsgBuf,
+    unsigned int uiBufLen, unsigned int* pMsgLen, pOsaTime_t ptTimeOut);
+
+int OsaQueueDelete(const char* bName, unsigned int uiQid);
+
+//Timer
+void OsaWait(int mSecs);
+unsigned long OsaGetTick(void);
+unsigned int OsaCurrentTime(void);
+void * OsaMalloc(unsigned int size);
+void * OsaFree(void *pbuf);
+int OsaTaskDelaymsecs(unsigned int);
+int OsaTaskSetPriority(unsigned int uiTid, int iNewpriority);
+int OsaTaskGetPriority(unsigned int uiTid, int* piPriority);
+
+int OsaTaskDelayticks(int iTicks);
+int OsaGetTicksPerSecond(void);
+void OsaCurrentTimeVal(pOsaTime_t pTimeVal);
+void OsaDiffTimeVal(pOsaTime_t pResult, const pOsaTime_t pVal1,
+    const pOsaTime_t pVal2);
+
+int OsaIrqSet(unsigned int irq, void (*handler)(void), unsigned int priority,
+    const char *name, unsigned int isShared);
+void OsaIrqFree(unsigned int irq, unsigned int isShared, void (*handler)(void));
+void OsaIrqDisable(unsigned int irq);
+void OsaIrqEnable(unsigned int irq);
+void OsaIrqPendClear(unsigned int irq);
+
+#if defined(__KERNEL__)
+unsigned int OsaIrqGetCount(unsigned int irq);
+void OsaIrqResetCount(void);
+#endif
+
+#if defined(__KERNEL__)
+void OsaModule_Open(void);
+void OsaModule_Close(void);
+int OsaModule_RegisterDev(const char* devname,int iminor_cnt,struct file_operations *fp_op);
+int OsaModule_UnRegisterDev(unsigned int devId, const char* devname,int iminor_cnt);
+int OsaModule_Remap_page_range(struct vm_area_struct *vma,unsigned int uiaddr);
+
+/*added by tukho.kim@samsung.com 080714 */
+/*modified by tukho.kim@samsung.com 090818 */
+
+/* OSAL_100928_1: Support outer cache handling(flush_all)
+ * OSAL_DCACHE_XXX are not supported. Do not use. */
+#if 0
+#include <asm/cacheflush.h>
+
+#define OSAL_DCACHE_FLUSH()    __cpuc_flush_kern_all()
+
+#define OSAL_DCACHE_FLUSH_RANGE(start, end) \
+                       dmac_flush_range((const void*) start, (const void*) end)
+
+#define OSAL_DCACHE_INVAL(start, end) \
+                       dmac_inv_range((const void*) start, (const void*) end)
+
+#define OSAL_DCACHE_CLEAN(start, end) \
+                       dmac_clean_range((const void*) start, (const void*) end)
+
+/*modified by tukho.kim@samsung.com 090818 end*/
+#endif
+
+/* OSAL_100928_1: Support outer cache handling(flush_all)
+ * OSAL_DCACHE_XXX are not supported. Do not use. */
+static void __attribute__((unused)) staOsaWarnDeprecatedFunction(const char *func, const char *caller)
+{
+       printk (KERN_WARNING "[WARNING]\n");
+       printk (KERN_WARNING "\tcaller=%s. %s is not support. Do not use!\n", caller, func);
+}
+
+#define OSAL_DCACHE_FLUSH()                            staOsaWarnDeprecatedFunction("OSAL_DCACHE_FLUSH", __FUNCTION__)
+#define OSAL_DCACHE_FLUSH_RANGE(start, end) staOsaWarnDeprecatedFunction("OSAL_DCACHE_FLUSH_RANGE", __FUNCTION__)
+#define OSAL_DCACHE_INVAL(start, end)          staOsaWarnDeprecatedFunction("OSAL_DCACHE_INVAL", __FUNCTION__)
+#define OSAL_DCACHE_CLEAN(start, end)          staOsaWarnDeprecatedFunction("OSAL_DCACHE_CLEAN", __FUNCTION__)
+
+#endif
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerCreate
+ // Detail Description :       This function creates the timer.It initialises the
+ //                    timer data and sets the callback function to be called
+ //                    upon timer expiry.
+ //
+ // Return Data Type   : ErrorType.
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerCreate(int* pTimerId, int periodic, int time,
+    void (*entry)(void* data), void* pvAr);
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerStart
+ // Detail Description : This function starts the already created timer .
+ //
+ // Return Data Type   :       ErrorType.
+ /
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerStart(int iTimerId);
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerStop
+ // Detail Description : This function stops the current running timer .
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   :       None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerStop(int iTimerId);
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerDelete
+ // Detail Description : This function deletes the current timer .
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerDelete(int iTimerId);
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Function Name      :       OsaTimerRestart
+ // Detail Description : This function restarts the stopped timer .
+ //
+ // Return Data Type   : ErrorType
+ //
+ // Programming Note   : None.
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaTimerRestart(int iTimerId);
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // Shared memory related API
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaShmCreate(const char pName[10], unsigned int u32ShmSegSize,
+    int* ps32ShmId);
+int OsaShmDelete(int s32ShmId);
+int OsaShmAttach(int s32ShmId, void** pShmAddr);
+int OsaShmDetach(const void *pShmAddr);
+
+/*
+ // $$$
+ //-----------------------------------------------------------------------------
+ // System V(or POSIX named) semaphore related API
+ //------------------------------------------------------------------------------
+ // $$$
+ */
+int OsaNamedSemCreate(const char pName[10], int iCount, int iAttribute,
+    unsigned int* puiSemId);
+int OsaNamedSemGet(unsigned int uiSemId, int iFlags, int iTimeout);
+int OsaNamedSemRelease(unsigned int uiSemId);
+int OsaNamedSemDelete(unsigned int uiSemId);
+int OsaNamedSemGetval(unsigned int uiSemId);
+int OsaNamedSemReset(unsigned int uiSemId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OSAL_H */
+
diff --git a/simulatordaemon/.cproject b/simulatordaemon/.cproject
new file mode 100755 (executable)
index 0000000..8fc762f
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.base.1317704860" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.base">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.804710905" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
+                                                       <builder buildPath="${workspace_loc:/SimulatorDaemon}/Debug" id="cdt.managedbuild.target.gnu.builder.base.1602772270" keepEnvironmentInBuildfile="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.544721433" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1411537939" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.808657098" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.1502454376" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.dialect.std.1069308124" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.default" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.other.other.511184497" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <option id="gnu.cpp.compiler.option.include.paths.1347812268" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/include/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/TABinaryManager}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1024568601" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.compiler.base.863311813" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.553642465" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.852260649" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.misc.other.1434586586" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <option id="gnu.c.compiler.option.include.paths.689902965" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/include/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/TABinaryManager}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2076773858" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.base.1809959578" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.cpp.linker.base.1844136556" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base">
+                                                               <option id="gnu.cpp.link.option.libs.763950546" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
+                                                                       <listOptionValue builtIn="false" value="rt"/>
+                                                                       <listOptionValue builtIn="false" value="log"/>
+                                                                       <listOptionValue builtIn="false" value="osal"/>
+                                                                       <listOptionValue builtIn="false" value="pthread"/>
+                                                                       <listOptionValue builtIn="false" value="boost_system"/>
+                                                                       <listOptionValue builtIn="false" value="boost_thread"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.link.option.flags.1688958719" name="Linker flags" superClass="gnu.cpp.link.option.flags" value=" --sysroot=&quot;..\..\..\toolchain\windows\i386-linux-gnueabi-gcc-4.6\lib\gcc\i386-linux-gnueabi\4.6.4&quot;" valueType="string"/>
+                                                               <option id="gnu.cpp.link.option.paths.616602733" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log/Debug}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal/Debug}&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1278937528" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.base.2115481220" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1563062597" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.release.957195020">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.release.957195020" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.release.957195020" name="Release" parent="cdt.managedbuild.config.gnu.cross.exe.release">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.release.957195020." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.release.1285717501" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
+                                                       <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1919135169" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
+                                                       <builder buildPath="${workspace_loc:/SimulatorDaemon}/Release" id="cdt.managedbuild.builder.gnu.cross.1940733045" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.builder.gnu.cross"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.83014739" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
+                                                               <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.200060028" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.debugging.level.1833869591" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1448564109" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.560701241" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.324820445" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.debugging.level.2044627448" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1943870465" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.2053461635" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2077924424" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.303500759" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1767144989" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1371968400" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.60242678" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="SimulatorDaemon.cdt.managedbuild.target.gnu.cross.exe.1952556034" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope"/>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356;cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.;cdt.managedbuild.tool.gnu.cross.c.compiler.171117265;cdt.managedbuild.tool.gnu.c.compiler.input.1725641490">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132;cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132.;cdt.managedbuild.tool.gnu.cpp.compiler.base.279265743;cdt.managedbuild.tool.gnu.cpp.compiler.input.1983374070">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356;cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.2028279967;cdt.managedbuild.tool.gnu.cpp.compiler.input.656717701">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132;cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132.;cdt.managedbuild.tool.gnu.c.compiler.base.500981930;cdt.managedbuild.tool.gnu.c.compiler.input.1416643488">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.957195020;cdt.managedbuild.config.gnu.cross.exe.release.957195020.;cdt.managedbuild.tool.gnu.cross.c.compiler.83014739;cdt.managedbuild.tool.gnu.c.compiler.input.1448564109">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.release.957195020;cdt.managedbuild.config.gnu.cross.exe.release.957195020.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.560701241;cdt.managedbuild.tool.gnu.cpp.compiler.input.1943870465">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+</cproject>
diff --git a/simulatordaemon/.gitignore b/simulatordaemon/.gitignore
new file mode 100755 (executable)
index 0000000..3df573f
--- /dev/null
@@ -0,0 +1 @@
+/Debug/
diff --git a/simulatordaemon/.project b/simulatordaemon/.project
new file mode 100755 (executable)
index 0000000..d1ea21c
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>SimulatorDaemon</name>
+       <comment></comment>
+       <projects>
+               <project>TEECLib</project>
+               <project>TEEStub</project>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/simulatordaemon/.settings/language.settings.xml b/simulatordaemon/.settings/language.settings.xml
new file mode 100755 (executable)
index 0000000..53ab1a6
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<project>\r
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.1895221356" name="Debug">\r
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">\r
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>\r
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>\r
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>\r
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" ref="shared-provider"/>\r
+               </extension>\r
+       </configuration>\r
+       <configuration id="cdt.managedbuild.config.gnu.cross.exe.release.957195020" name="Release">\r
+               <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">\r
+                       <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>\r
+                       <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>\r
+                       <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>\r
+                       <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1399846139505" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">\r
+                               <language-scope id="org.eclipse.cdt.core.gcc"/>\r
+                               <language-scope id="org.eclipse.cdt.core.g++"/>\r
+                       </provider>\r
+               </extension>\r
+       </configuration>\r
+</project>\r
diff --git a/simulatordaemon/.settings/org.eclipse.cdt.core.prefs b/simulatordaemon/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..71eacce
--- /dev/null
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132/PATH/value=C\:/Program Files/Java/jre1.8.0_40/bin/server;C\:/Program Files/Java/jre1.8.0_40/bin;C\:/Program Files/Java/jre1.8.0_40/lib/amd64;C\:\\Program Files (x86)\\Black Duck Software\\protexIP\\bin;C\:\\Program Files\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Program Files (x86)\\Common Files\\Microsoft Shared\\Windows Live;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files (x86)\\QuickTime\\QTSystem\\;C\:\\Program Files (x86)\\Java\\jre7\\bin; C\:\\cygwin64\\bin;C\:\\Program Files\\doxygen\\bin;D\:\\eclipse;C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\Program Files (x86)\\Java\\jre1.8.0_45\\bin;C\:\\Program Files\\eclipse;C\:/Program Files/Java/jre1.8.0_31/bin/server;C\:/Program Files/Java/jre1.8.0_31/bin;C\:/Program Files/Java/jre1.8.0_31/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\csvn\\bin\\;C\:\\csvn\\Python25\\;C\:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files\\Diskeeper Corporation\\ExpressCache\\;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x64;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files (x86)\\WinSCP\\;C\:\\Program Files (x86)\\PuTTY;C\:\\Program Files\\Microsoft\\Web Platform Installer\\;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C\:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;C\:\\Program Files (x86)\\doxygen\\bin;C\:\\Program Files (x86)\\sfk168;C\:\\Program Files (x86)\\vlc-2.1.0;C\:\\Python27\\Scripts;C\:\\Program Files (x86)\\GnuWin32\\bin;C\:\\Python27;C\:\\Program Files (x86)\\Subversion\\bin;c\:\\Program Files\\Synergy;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\MinGW\\lib\\gcc\\mingw32\\4.8.1;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C\:\\Program Files (x86)\\GitExtensions\\;C\:\\Program Files\\Perforce;c\:\\Program Files\\Java\\jre1.8.0_31\\bin\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;D\:\\samsung-tv-sdk\\ide;${Path};D\:\\samsung-tv-sdk\\tools\\i386-linux-gnueabi-gcc-4.6\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\bin;D\:\\samsung-tv-sdk\\tools\\mingw\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356.743154132/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\GitExtensions\\;D\:\\Tizen\\tizen-sdk\\tools;D\:\\Android\\android-sdk\\platform-tools;D\:\\Android\\android-ndk-r10c;C\:\\Program Files\\Perforce;D\:\\eclipse\\eclipse-rcp-luna-SR1-win32-x86_64;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\bin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\mingbin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356/append=true
+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.1895221356/appendContributed=true
diff --git a/simulatordaemon/inc/ClientCommands/CommandBase.h b/simulatordaemon/inc/ClientCommands/CommandBase.h
new file mode 100755 (executable)
index 0000000..10e8b37
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandBase.h
+ *
+ *    Description:  CommandBase Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDBASE_H_
+#define COMMANDBASE_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_command.h"
+#include "tee_client_api.h"
+#include "teec_data.h"
+#include "teestub_command_data.h"
+#include "boost/shared_ptr.hpp"
+#include "log.h"
+#include "OsaLinuxUser.h"
+
+class TEEContext;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandBase {
+protected:
+       TEEContext *pTEECtx;
+public:
+       /**
+        * Command Base for command pattern handling the commands received from
+        * TEECLib.
+        * @param TEECtx object associated with command
+        */
+       CommandBase(TEEContext *TEECtx) :
+                       pTEECtx(TEECtx) {
+
+       }
+       /**
+        * Command Base Execute for commands received from TEECLib.
+        * @param none
+        */
+       virtual void execute() = 0;
+       ~CommandBase() {
+       }
+};
+
+typedef boost::shared_ptr<CommandBase> CommandBasePtr;
+
+#endif /* COMMANDBASE_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandCloseSession.h b/simulatordaemon/inc/ClientCommands/CommandCloseSession.h
new file mode 100755 (executable)
index 0000000..61f40bb
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCloseSession.h
+ *
+ *    Description:  CommandCloseSession Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDCLOSESESSION_H_
+#define COMMANDCLOSESESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandCloseSession:
+    public CommandBase {
+public:
+       CloseSessionData data;
+       CommandCloseSession(CloseSessionData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandCloseSession();
+};
+
+#endif /* COMMANDCLOSESESSION_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandCloseTASession.h b/simulatordaemon/inc/ClientCommands/CommandCloseTASession.h
new file mode 100755 (executable)
index 0000000..031b5cb
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCloseTASession.h
+ *
+ *    Description:  CommandCloseTASession Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDCLOSETASESSION_H_
+#define COMMANDCLOSETASESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandCloseTASession:
+    public CommandBase {
+public:
+       IntTACloseSessionData data;
+       CommandCloseTASession(IntTACloseSessionData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandCloseTASession();
+};
+
+#endif /* COMMANDCLOSETASESSION_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandFinContext.h b/simulatordaemon/inc/ClientCommands/CommandFinContext.h
new file mode 100755 (executable)
index 0000000..820c650
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandFinContext.h
+ *
+ *    Description:  CommandFinContext Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDFINCONTEXT_H_
+#define COMMANDFINCONTEXT_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandFinContext:
+    public CommandBase {
+public:
+       FinalizeContextData data;
+       CommandFinContext(FinalizeContextData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandFinContext();
+};
+
+#endif /* COMMANDFINCONTEXT_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandInitContext.h b/simulatordaemon/inc/ClientCommands/CommandInitContext.h
new file mode 100755 (executable)
index 0000000..f3f536c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandInitContext.h
+ *
+ *    Description:  CommandInitContext Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDINITCONTEXT_H_
+#define COMMANDINITCONTEXT_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandInitContext:
+    public CommandBase {
+public:
+       InitContextData data;
+       CommandInitContext(InitContextData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandInitContext();
+};
+
+#endif /* COMMANDINITCONTEXT_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandInvokeCommand.h b/simulatordaemon/inc/ClientCommands/CommandInvokeCommand.h
new file mode 100755 (executable)
index 0000000..efb0f3b
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandInvokeCommand.h
+ *
+ *    Description:  CommandInvokeCommand Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDINVOKECOMMAND_H_
+#define COMMANDINVOKECOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandInvokeCommand:
+    public CommandBase {
+public:
+       InvokeCommandData data;
+       CommandInvokeCommand(InvokeCommandData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandInvokeCommand();
+
+};
+
+#endif /* COMMANDINVOKECOMMAND_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandInvokeTACommand.h b/simulatordaemon/inc/ClientCommands/CommandInvokeTACommand.h
new file mode 100755 (executable)
index 0000000..6eac1c0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandInvokeTACommand.h
+ *
+ *    Description:  CommandInvokeTACommand Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDINVOKETACOMMAND_H_
+#define COMMANDINVOKETACOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandInvokeTACommand:
+    public CommandBase {
+public:
+       IntTAInvokeCommandData data;
+       CommandInvokeTACommand(IntTAInvokeCommandData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandInvokeTACommand();
+
+};
+
+#endif /* COMMANDINVOKETACOMMAND_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandOpenSession.h b/simulatordaemon/inc/ClientCommands/CommandOpenSession.h
new file mode 100755 (executable)
index 0000000..b17e979
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOpenSession.h
+ *
+ *    Description:  CommandOpenSession Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDOPENSESSION_H_
+#define COMMANDOPENSESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandOpenSession:
+    public CommandBase {
+public:
+       OpenSessionData data;
+       CommandOpenSession(OpenSessionData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandOpenSession();
+};
+
+#endif /* COMMANDOPENSESSION_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandOpenTASession.h b/simulatordaemon/inc/ClientCommands/CommandOpenTASession.h
new file mode 100755 (executable)
index 0000000..e193cd7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOpenTASession.h
+ *
+ *    Description:  CommandOpenTASession Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDOPENTASESSION_H_
+#define COMMANDOPENTASESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandOpenTASession:
+    public CommandBase {
+public:
+       IntTAOpenSessionData data;
+       CommandOpenTASession(IntTAOpenSessionData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandOpenTASession();
+};
+
+#endif /* COMMANDOPENTASESSION_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandPanic.h b/simulatordaemon/inc/ClientCommands/CommandPanic.h
new file mode 100755 (executable)
index 0000000..e979e60
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandPanic.h
+ *
+ *    Description:  CommandPanic Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDPANIC_H_
+#define COMMANDPANIC_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandPanic:
+    public CommandBase {
+public:
+       IntTAPanicData data;
+       CommandPanic(IntTAPanicData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandPanic();
+
+};
+
+#endif /* COMMANDPANIC_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandRegSharedMem.h b/simulatordaemon/inc/ClientCommands/CommandRegSharedMem.h
new file mode 100755 (executable)
index 0000000..d1da1f5
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandRegSharedMem.h
+ *
+ *    Description:  CommandRegSharedMem Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDREGSHAREDMEM_H_
+#define COMMANDREGSHAREDMEM_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandRegSharedMem:
+    public CommandBase {
+public:
+       RegSharedMemData data;
+       CommandRegSharedMem(RegSharedMemData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandRegSharedMem();
+
+};
+
+#endif /* COMMANDREGSHAREDMEM_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandRelSharedMem.h b/simulatordaemon/inc/ClientCommands/CommandRelSharedMem.h
new file mode 100755 (executable)
index 0000000..6f34322
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandRelSharedMem.h
+ *
+ *    Description:  CommandRelSharedMem Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDRELSHAREDMEM_H_
+#define COMMANDRELSHAREDMEM_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandRelSharedMem:
+    public CommandBase {
+public:
+       RelSharedMemData data;
+       CommandRelSharedMem(RelSharedMemData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandRelSharedMem();
+
+};
+
+#endif /* COMMANDRELSHAREDMEM_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/CommandReqCancellation.h b/simulatordaemon/inc/ClientCommands/CommandReqCancellation.h
new file mode 100755 (executable)
index 0000000..fe69843
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandReqCancellation.h
+ *
+ *    Description:  CommandReqCancellation Header file
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef COMMANDREQCANCELLATION_H_
+#define COMMANDREQCANCELLATION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "CommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class CommandReqCancellation:
+    public CommandBase {
+public:
+       ReqCancellationData data;
+       CommandReqCancellation(ReqCancellationData data, TEEContext *TEECtx);
+       void execute();
+       virtual ~CommandReqCancellation();
+
+};
+
+#endif /* COMMANDREQCANCELLATION_H_ */
diff --git a/simulatordaemon/inc/ClientCommands/MakeCommand.h b/simulatordaemon/inc/ClientCommands/MakeCommand.h
new file mode 100755 (executable)
index 0000000..ca653bf
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  MakeCommand.h
+ *
+ *    Description:  MakeCommand Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef MAKECOMMAND_H_
+#define MAKECOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <boost/shared_ptr.hpp>
+#include "CommandCloseSession.h"
+#include "CommandCloseTASession.h"
+#include "CommandInitContext.h"
+#include "CommandFinContext.h"
+#include "CommandInvokeCommand.h"
+#include "CommandInvokeTACommand.h"
+#include "CommandOpenSession.h"
+#include "CommandOpenTASession.h"
+#include "CommandRegSharedMem.h"
+#include "CommandRelSharedMem.h"
+#include "CommandReqCancellation.h"
+#include "CommandPanic.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class MakeCommand {
+private:
+       MakeCommand();
+public:
+       static CommandBasePtr getCommand(TEE_CMD command, void* data,
+           TEEContext *TEECtx);
+       static uint32_t getDataSize(TEE_CMD command);
+       virtual ~MakeCommand();
+};
+
+#endif /* MAKECOMMAND_H_ */
diff --git a/simulatordaemon/inc/ConnectionSession.h b/simulatordaemon/inc/ConnectionSession.h
new file mode 100755 (executable)
index 0000000..53e02c3
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ConnectionSession.h
+ *
+ *    Description:  Connection handler for Simulator Daemon server
+ *
+ *        Version:  1.0
+ *        Created:  16 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_CONNECTIONSESSION_H)
+#define _CONNECTIONSESSION_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <syslog.h>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <vector>
+#include "tee_client_api.h"
+#include "ioService.h"
+#include "ClientCommands/MakeCommand.h"
+#include "TEEContext.h"
+#include "IConnectionSession.h"
+
+using namespace std;
+
+// COMPILE TIME CHECK TO SEE IF UNIX DOMAIN SOCKETS ARE AVAILABLE ON SYSTEM
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+using boost::asio::local::stream_protocol;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ConnectionSession: public boost::enable_shared_from_this<ConnectionSession>, public IConnectionSession
+{
+public:
+       pthread_mutex_t connLock;
+       typedef boost::shared_ptr<ConnectionSession> session_ptr;
+       static session_ptr create(boost::asio::io_service& io_service)
+       {
+               return session_ptr(new ConnectionSession(io_service));
+       }
+       ConnectionSession(boost::asio::io_service& io_service):
+       clientSocket(io_service)
+       {
+               pthread_mutex_init(&connLock, NULL);
+               currentState = CMD_READ;
+               TEECtx = NULL;
+               command = INVALID;
+       }
+       stream_protocol::socket& socket()
+       {
+               return clientSocket;
+       }
+       void start();
+       TEEC_Result write(TEE_CMD command, char* data, size_t size);
+       ~ConnectionSession();
+private:
+       TEEContext *TEECtx;
+       void handleRead(const boost::system::error_code& error,
+                       size_t bytes_transferred);
+       // The socket used to communicate with the client.
+       stream_protocol::socket clientSocket;
+       // Buffer used to store data received from the client.
+       boost::array<char, 1024> clientData;
+       states currentState;
+       vector<char> commandData;
+       TEE_CMD command;
+};
+
+#else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+# error Unix domain/local sockets not available on this platform.
+#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+#endif /* _CONNECTIONSESSION_H */
+
diff --git a/simulatordaemon/inc/IConnectionSession.h b/simulatordaemon/inc/IConnectionSession.h
new file mode 100644 (file)
index 0000000..046a69b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  IConnectionSession.h
+ *
+ *    Description:  Interface for Connection handler for Simulator Daemon server
+ *
+ *        Version:  1.0
+ *        Created:  27 August 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_ICONNECTIONSESSION_H)
+#define _ICONNECTIONSESSION_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_command.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class IConnectionSession {
+public:
+       virtual TEEC_Result write(TEE_CMD command, char* data, size_t size) = 0;
+       virtual ~IConnectionSession() {}
+};
+
+#endif /* _ICONNECTIONSESSION_H */
+
diff --git a/simulatordaemon/inc/ISession.h b/simulatordaemon/inc/ISession.h
new file mode 100644 (file)
index 0000000..766c719
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ISession.h
+ *
+ *    Description:  Interface class for Session Header file
+ *
+ *        Version:  1.0
+ *        Created:  25 August 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_ISESSION_H)
+#define _ISESSION_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <boost/shared_ptr.hpp>
+#include "tee_command.h"
+#include "teestub_command_data.h"
+#include "ITAInstance.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+
+class ISession {
+public:
+       virtual TEEC_Result createSession(OpenSessionData data) = 0;
+       virtual TEEC_Result handleCommand(InvokeCommandData data) = 0;
+       virtual TEEC_Result finalize(uint32_t contextID) = 0;
+       virtual void handleCancel(ReqCancellationData data) = 0;
+       virtual bool checkInternal() = 0;
+       virtual uint32_t getContextID() = 0;
+       virtual uint32_t getSessionID() = 0;
+       virtual TAInstancePtr getTAInstance() = 0;
+       virtual TEEC_Result writeResponse(TEE_CMD command, char* data, size_t size) = 0;
+       virtual void detachFromContext() = 0;
+       virtual ~ISession() {}
+};
+
+#endif  //_ISESSION_H
diff --git a/simulatordaemon/inc/ITAInstance.h b/simulatordaemon/inc/ITAInstance.h
new file mode 100644 (file)
index 0000000..f797c6c
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ITAInstance.h
+ *
+ *    Description:  Interface for TAInstance Header file
+ *
+ *        Version:  1.0
+ *        Created:  26 August 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_ITAINSTANCE_H)
+#define _ITAINSTANCE_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <cstring>
+#include <boost/shared_ptr.hpp>
+#include "teec_data.h"
+#include "tee_sim_command.h"
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define RETRY_COUNT 10000000
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+/* In order to handle TA crash situations, a map is created containing all
+ * the pending commands for the TA instance. Union cmdData is the value type
+ * for storing the data to be sent in response
+ */
+union cmdData {
+       OpenTASessionData osdata;
+       InvokeTACommandData icdata;
+       RequestTACancelData rcdata;
+       CloseTASessionData csdata;
+};
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+
+class ISession;
+
+class ITAInstance {
+public:
+       virtual TEEC_Result sendRequestToTA(SIM_COMMAND cmd, void* data, uint32_t size) = 0;
+       virtual void receiveResponseFromTA() = 0;
+       virtual TEEC_Result receiveCreateResponse() = 0;
+       virtual TEEC_Result connecttoTA(std::stringstream& str) = 0;
+       virtual bool checkKeepAlive() = 0;
+       virtual bool getCreated() = 0;
+       virtual void setCreated(bool value) = 0;
+       virtual pid_t getPID() = 0;
+       virtual void takeSessionMapLock() = 0;
+       virtual void releaseSessionMapLock() = 0;
+       virtual void eraseSessionMap(uint32_t sessID) = 0;
+       virtual uint32_t getSessionMapSize() = 0;
+       virtual void insertSessionMap(ISession* session) = 0;
+       virtual void eraseCommand(SIM_COMMAND cmd, uint32_t sessID) = 0;
+       virtual void insertCommand(SIM_COMMAND cmd, cmdData data) = 0;
+       virtual void killTA() = 0;
+       virtual void cleanup() = 0;
+       virtual ~ITAInstance() {}
+};
+
+typedef boost::shared_ptr<ITAInstance> TAInstancePtr;
+
+#endif  //_ITAINSTANCE_H
diff --git a/simulatordaemon/inc/ResponseCommands/ResCommandBase.h b/simulatordaemon/inc/ResponseCommands/ResCommandBase.h
new file mode 100755 (executable)
index 0000000..b19b71f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandBase.h
+ *
+ *    Description:  ResCommandBase Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef RESCOMMANDBASE_H_
+#define RESCOMMANDBASE_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <map>
+#include <pthread.h>
+#include <boost/shared_ptr.hpp>
+#include "tee_command.h"
+#include "tee_client_api.h"
+#include "teec_data.h"
+#include "tee_sim_command.h"
+#include "teestub_command_data.h"
+#include "ISession.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ResCommandBase {
+protected:
+       std::map<uint32_t, ISession*> *pSessionMap;
+public:
+       /**
+        * Command Base for command pattern handling the responses received from TEEStub.
+        * @param SessionMap to find the session associated with command
+        */
+       ResCommandBase(std::map<uint32_t, ISession*> *sessionMap) :
+                       pSessionMap(sessionMap) {
+       }
+       virtual void execute() = 0;
+       ~ResCommandBase() {
+       }
+};
+
+typedef boost::shared_ptr<ResCommandBase> ResCommandBasePtr;
+
+#endif /* RESCOMMANDBASE_H_ */
diff --git a/simulatordaemon/inc/ResponseCommands/ResCommandCloseSession.h b/simulatordaemon/inc/ResponseCommands/ResCommandCloseSession.h
new file mode 100755 (executable)
index 0000000..4642b9b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandCloseSession.h
+ *
+ *    Description:  ResCommandCloseSession Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef RESCOMMANDCLOSESESSION_H_
+#define RESCOMMANDCLOSESESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResCommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ResCommandCloseSession:
+    public ResCommandBase {
+public:
+       CloseTASessionData *data;
+       ResCommandCloseSession(CloseTASessionData *data,
+           std::map<uint32_t, ISession*> *sessionMap);
+       void execute();
+       virtual ~ResCommandCloseSession();
+};
+
+#endif /* RESCOMMANDCLOSESESSION_H_ */
diff --git a/simulatordaemon/inc/ResponseCommands/ResCommandInvokeCommand.h b/simulatordaemon/inc/ResponseCommands/ResCommandInvokeCommand.h
new file mode 100755 (executable)
index 0000000..18c8714
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandInvokeCommand.h
+ *
+ *    Description:  ResCommandInvokeCommand Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef RESCOMMANDINVOKECOMMAND_H_
+#define RESCOMMANDINVOKECOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResCommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ResCommandInvokeCommand:
+    public ResCommandBase {
+public:
+       InvokeTACommandData *data;
+       ResCommandInvokeCommand(InvokeTACommandData *data,
+           std::map<uint32_t, ISession*> *sessionMap);
+       void execute();
+       virtual ~ResCommandInvokeCommand();
+
+};
+
+#endif /* RESCOMMANDINVOKECOMMAND_H_ */
diff --git a/simulatordaemon/inc/ResponseCommands/ResCommandOpenSession.h b/simulatordaemon/inc/ResponseCommands/ResCommandOpenSession.h
new file mode 100755 (executable)
index 0000000..15de38b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandOpenSession.h
+ *
+ *    Description:  ResCommandOpenSession Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#ifndef RESCOMMANDOPENSESSION_H_
+#define RESCOMMANDOPENSESSION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResCommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ResCommandOpenSession:
+    public ResCommandBase {
+public:
+       OpenTASessionData *data;
+       ResCommandOpenSession(OpenTASessionData *data,
+           std::map<uint32_t, ISession*> *sessionMap);
+       void execute();
+       virtual ~ResCommandOpenSession();
+};
+
+#endif /* RESCOMMANDOPENSESSION_H_ */
diff --git a/simulatordaemon/inc/ResponseCommands/ResCommandReqCancellation.h b/simulatordaemon/inc/ResponseCommands/ResCommandReqCancellation.h
new file mode 100755 (executable)
index 0000000..fa42c04
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandReqCancellation.h
+ *
+ *    Description:  ResCommandReqCancellation Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef RESCOMMANDREQCANCELLATION_H_
+#define RESCOMMANDREQCANCELLATION_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResCommandBase.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ResCommandReqCancellation:
+    public ResCommandBase {
+public:
+       ReqCancellationData *data;
+       ResCommandReqCancellation(ReqCancellationData *data,
+           std::map<uint32_t, ISession*> *sessionMap);
+       void execute();
+       virtual ~ResCommandReqCancellation();
+
+};
+
+#endif /* RESCOMMANDREQCANCELLATION_H_ */
diff --git a/simulatordaemon/inc/ResponseCommands/ResMakeCommand.h b/simulatordaemon/inc/ResponseCommands/ResMakeCommand.h
new file mode 100755 (executable)
index 0000000..b6b28e3
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResMakeCommand.h
+ *
+ *    Description:  ResMakeCommand Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef RESMAKECOMMAND_H_
+#define RESMAKECOMMAND_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+#include "ResCommandCloseSession.h"
+#include "ResCommandInvokeCommand.h"
+#include "ResCommandOpenSession.h"
+#include "ResCommandReqCancellation.h"
+#include "tee_command.h"
+#include "tee_sim_command.h"
+#include "teestub_command_data.h"
+#include "ISession.h"
+#include "log.h"
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ResMakeCommand {
+private:
+       ResMakeCommand();
+public:
+       static ResCommandBasePtr getCommand(SIM_COMMAND command, void* data,
+           std::map<uint32_t, ISession*> *sessionMap);
+       static uint32_t getDataSize(SIM_COMMAND command);
+       virtual ~ResMakeCommand();
+};
+
+#endif /* RESMAKECOMMAND_H_ */
diff --git a/simulatordaemon/inc/Session.h b/simulatordaemon/inc/Session.h
new file mode 100755 (executable)
index 0000000..8569059
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  Session.h
+ *
+ *    Description:  Session Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_SESSION_H)
+#define _SESSION_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <pthread.h>
+#include <cstdlib>
+#include "ISession.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+
+class TEEContext;
+
+class Session : public ISession {
+private:
+       // Session ID assigned to the Session
+       uint32_t mSessionID;
+       // Context associated with the Session
+       TEEContext* mContext;
+       // TA instance associated with the Session
+       TAInstancePtr mTAInstance;
+public:
+       Session(TEEContext* TEECtx);
+       TEEC_Result createSession(OpenSessionData data);
+       TEEC_Result handleCommand(InvokeCommandData data);
+       TEEC_Result finalize(uint32_t contextID);
+       void handleCancel(ReqCancellationData data);
+       bool checkInternal();
+       uint32_t getContextID();
+       uint32_t getSessionID();
+       TAInstancePtr getTAInstance();
+       TEEC_Result writeResponse(TEE_CMD command, char* data, size_t size);
+       void detachFromContext();
+       ~Session();
+};
+
+#endif  //_SESSION_H
diff --git a/simulatordaemon/inc/SimulatorDaemonServer.h b/simulatordaemon/inc/SimulatorDaemonServer.h
new file mode 100755 (executable)
index 0000000..b0a8ec5
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SimulatorDaemonServer.h
+ *
+ *    Description:  SimulatorDaemonServer Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#if !defined(_SIMULATORDAEMONSERVER_H)
+#define _SIMULATORDAEMONSERVER_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ConnectionSession.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class SimulatorDaemonServer {
+public:
+       SimulatorDaemonServer(boost::asio::io_service& io_service,
+           const std::string& file);
+private:
+       void startAccept(void);
+       void handleAccept(ConnectionSession::session_ptr new_session,
+           const boost::system::error_code& error);
+       boost::asio::io_service& mem_io_service;
+       stream_protocol::acceptor acceptor;
+};
+
+#endif  //_SIMULATORDAEMONSERVER_H
diff --git a/simulatordaemon/inc/TAFactory.h b/simulatordaemon/inc/TAFactory.h
new file mode 100755 (executable)
index 0000000..e3916c3
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAFactory.h
+ *
+ *    Description:  TAFactory Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_TAFACTORY_H)
+#define _TAFACTORY_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <list>
+#include <pthread.h>
+#include <time.h>
+#include <spawn.h>
+#include <sys/wait.h>
+#include <sstream>
+#include <stdlib.h>
+#include "ISession.h"
+#include "TAInstance.h"
+#include "TABinaryManager.h"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class TAFactory {
+public:
+       pthread_rwlock_t mTAInstanceMapLock;
+       multimap<string, TAInstancePtr> mTAInstanceMap;
+       static TAFactory* getInstance();
+       TAInstancePtr getTAInstance(TEEC_UUID TAUUID, ISession* session);
+private:
+       static TAFactory *instance;
+       // instLock for TA Instance ID
+       pthread_rwlock_t instIDLock;
+       uint32_t InstID;
+       TAFactory();
+       bool checkIfTARunning(string TAUUID);
+       TAInstancePtr createUninitalizedTAInstance(string TAUUID, ISession* session);
+       bool launchTA(string TAUUID, std::stringstream& str, bool debug, pid_t& pid);
+       static void* waitForChild(void *pid);
+       void cleanupTAInstance(pid_t PID);
+       ~TAFactory();
+};
+
+#endif  //_TAFACTORY_H
diff --git a/simulatordaemon/inc/TAInstance.h b/simulatordaemon/inc/TAInstance.h
new file mode 100755 (executable)
index 0000000..ebdf60f
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAInstance.h
+ *
+ *    Description:  TAInstance Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_TAINSTANCE_H)
+#define _TAINSTANCE_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <cstdlib>
+#include <map>
+#include <vector>
+#include <sys/types.h>
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include "ITAInstance.h"
+#include "ioService.h"
+#include "tee_client_api.h"
+
+using namespace std;
+
+// COMPILE TIME CHECK TO SEE IF UNIX DOMAIN SOCKETS ARE AVAILABLE ON SYSTEM
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+using boost::asio::local::stream_protocol;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class TAInstance: public boost::enable_shared_from_this<TAInstance>, public ITAInstance {
+public:
+       TAInstance(uint32_t pid, bool alive, bool debug, uint32_t InstID, boost::asio::io_service& client_io_service);
+       TEEC_Result sendRequestToTA(SIM_COMMAND cmd, void* data, uint32_t size);
+       void receiveResponseFromTA();
+       TEEC_Result receiveCreateResponse();
+       TEEC_Result connecttoTA(std::stringstream& str);
+       bool checkKeepAlive();
+       bool getCreated();
+       void setCreated(bool value);
+       pid_t getPID();
+       void takeSessionMapLock();
+       void releaseSessionMapLock();
+       void eraseSessionMap(uint32_t sessID);
+       uint32_t getSessionMapSize();
+       void insertSessionMap(ISession* session);
+       void eraseCommand(SIM_COMMAND cmd, uint32_t sessID);
+       void insertCommand(SIM_COMMAND cmd, cmdData data);
+       void killTA();
+       void cleanup();
+       ~TAInstance();
+private:
+       // pthread lock for Session Map
+       pthread_rwlock_t mSessionMapLock;
+       // pthread lock for Command Map
+       pthread_rwlock_t mCommandMapLock;
+       // Member variable to check if the instance is reused or being newly created
+       bool isCreated;
+       // Member variable to check if the TA is launched in debug or release mode
+       bool isDebug;
+       /* Member variable to check if the instance has to be deleted or not if no
+        * session is associated with it
+        */
+       bool isKeepAlive;
+       // Member variable to store the PID of the launched TA
+       pid_t mPID;
+       // Instance ID assigned to the TA instance
+       uint32_t mTAInstanceID;
+       // Map containing the Sessions associated with the TA instance
+       map<uint32_t, ISession*> mSessionMap;
+       /* Map containing all the pending commands (commands sent to TA and waiting
+        * for response)
+        */
+       multimap<SIM_COMMAND, cmdData> mCommandMap;
+       pthread_mutex_t sendLock;
+       stream_protocol::socket mTAConnectionSocket;
+       boost::array<char, 1024> readData;
+       vector<char> commandData;
+       SIM_COMMAND command;
+       states currentState;
+       int32_t setSocketOpt(struct timeval timeout);
+       void handleRead(const boost::system::error_code& error,
+                       size_t bytes_transferred);
+       void closeConnectionToTA();
+};
+
+
+#else // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+# error Unix domain/local sockets not available on this platform.
+#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+
+#endif  //_TAINSTANCE_H
diff --git a/simulatordaemon/inc/TEEContext.h b/simulatordaemon/inc/TEEContext.h
new file mode 100755 (executable)
index 0000000..ac0669f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TEEContext.h
+ *
+ *    Description:  TEEContext Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_TEECONTEXT_H)
+#define _TEECONTEXT_H
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <map>
+#include <list>
+#include <iostream>
+#include <string>
+#include <string.h>
+#include "log.h"
+#include "Session.h"
+#include "tee_command.h"
+#include "IConnectionSession.h"
+
+using namespace std;
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define TEENAME "Simulator"
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+
+class TEEContext {
+private:
+       pthread_rwlock_t mShmListLock;
+       list<uint32_t> mShmList;
+public:
+       pthread_rwlock_t mSessionMapLock;
+       map<uint32_t, ISession*> mSessionMap;
+       // Connection session instance associated with the TEEContext instance
+       IConnectionSession* mConnSess;
+       // ContextID assigned to the instance
+       uint32_t mContextID;
+       /* For TA internal APIs support, dummy Context is created and for recognizing
+        * the context as dummy isInternal member variable is used
+        */
+       bool isInternal;
+       TEEContext(uint32_t contextID, IConnectionSession* connSession);
+       TEEC_Result initContext(InitContextData* data);
+       void finContext(FinalizeContextData data);
+       TEEC_Result openSession(OpenSessionData data);
+       TEEC_Result closeSession(CloseSessionData data);
+       TEEC_Result invokeCommand(InvokeCommandData data);
+       TEEC_Result openTASession(IntTAOpenSessionData data);
+       void closeTASession(IntTACloseSessionData data);
+       TEEC_Result invokeTACommand(IntTAInvokeCommandData data);
+       TEEC_Result registerSharedMemory(RegSharedMemData data);
+       TEEC_Result releaseSharedMemory(RelSharedMemData data);
+       void reqCancel(ReqCancellationData data);
+       ~TEEContext();
+};
+
+#endif  //_TEECONTEXT_H
diff --git a/simulatordaemon/inc/ioService.h b/simulatordaemon/inc/ioService.h
new file mode 100755 (executable)
index 0000000..e539a4e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ioService.h
+ *
+ *    Description:  ioService Header file
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+
+#include <iostream>
+#include <boost/asio.hpp>
+#include "log.h"
+#include "OsaLinuxUser.h"
+
+#if !defined(_IOSERVICE_H)
+#define _IOSERVICE_H
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+typedef enum {
+       CMD_READ, DATA_READ,
+} states;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class ioService {
+public:
+       static boost::asio::io_service& getInstance();
+private:
+       static boost::asio::io_service io_service;
+};
+
+#endif  //_IOSERVICE_H
diff --git a/simulatordaemon/inc/path.h b/simulatordaemon/inc/path.h
new file mode 100755 (executable)
index 0000000..2aac940
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  path.h
+ *
+ *    Description:  path details
+ *
+ *        Version:  1.0
+ *        Created:  29 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#if !defined(_PATH_H)
+#define _PATH_H
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+
+// shm path to be created for Shared memory functionality support
+#define SHM_PATH "/tmp/shm"
+// socket path for connection with Simulator Daemon
+#define SIMDAEMON_PATH "/tmp/simdaemon"
+
+#endif  //_PATH_H
diff --git a/simulatordaemon/src/ClientCommands/CommandCloseSession.cpp b/simulatordaemon/src/ClientCommands/CommandCloseSession.cpp
new file mode 100755 (executable)
index 0000000..98795bc
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCloseSession.cpp
+ *
+ *    Description:  CommandCloseSession class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandCloseSession.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * CloseSession command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandCloseSession::CommandCloseSession(CloseSessionData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * CloseSession command execute.
+ * @param none
+ */
+void CommandCloseSession::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->closeSession(data);
+       if (result != TEEC_SUCCESS) {
+               //Communication error - CA exited
+               FinalizeContextData fdata;
+               fdata.contextID = data.contextID;
+               pTEECtx->finContext(fdata);
+               delete pTEECtx;
+       }
+}
+
+CommandCloseSession::~CommandCloseSession() {
+
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandCloseTASession.cpp b/simulatordaemon/src/ClientCommands/CommandCloseTASession.cpp
new file mode 100755 (executable)
index 0000000..dc0ee4c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandCloseTASession.cpp
+ *
+ *    Description:  CommandCloseTASession class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandCloseTASession.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * CloseTASession command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandCloseTASession::CommandCloseTASession(IntTACloseSessionData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * CloseTASession command execute.
+ * @param none
+ */
+void CommandCloseTASession::execute() {
+       pTEECtx->closeTASession(data);
+}
+
+CommandCloseTASession::~CommandCloseTASession() {
+
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandFinContext.cpp b/simulatordaemon/src/ClientCommands/CommandFinContext.cpp
new file mode 100755 (executable)
index 0000000..5d6a407
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandFinContext.cpp
+ *
+ *    Description:  CommandFinContext class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandFinContext.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * FinalizeContext command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandFinContext::CommandFinContext(FinalizeContextData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * FinalizeContext command execute.
+ * @param none
+ */
+void CommandFinContext::execute() {
+       pTEECtx->finContext(data);
+}
+
+CommandFinContext::~CommandFinContext() {
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandInitContext.cpp b/simulatordaemon/src/ClientCommands/CommandInitContext.cpp
new file mode 100755 (executable)
index 0000000..2914b96
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandInitContext.cpp
+ *
+ *    Description:  CommandInitContext class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandInitContext.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * InitializeContext command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandInitContext::CommandInitContext(InitContextData data, TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * InitializeContext command execute.
+ * @param none
+ */
+void CommandInitContext::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->initContext(&data);
+       if (result != TEEC_SUCCESS) delete pTEECtx;
+}
+
+CommandInitContext::~CommandInitContext() {
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandInvokeCommand.cpp b/simulatordaemon/src/ClientCommands/CommandInvokeCommand.cpp
new file mode 100755 (executable)
index 0000000..7d60242
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandInvokeCommand.cpp
+ *
+ *    Description:  CommandInvokeCommand class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandInvokeCommand.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * InvokeCommand command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandInvokeCommand::CommandInvokeCommand(InvokeCommandData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * InvokeCommand command execute.
+ * @param none
+ */
+void CommandInvokeCommand::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->invokeCommand(data);
+       if (result != TEEC_SUCCESS) {
+               FinalizeContextData fdata;
+               fdata.contextID = data.contextID;
+               pTEECtx->finContext(fdata);
+               delete pTEECtx;
+       }
+}
+
+CommandInvokeCommand::~CommandInvokeCommand() {
+
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandInvokeTACommand.cpp b/simulatordaemon/src/ClientCommands/CommandInvokeTACommand.cpp
new file mode 100755 (executable)
index 0000000..cd240c8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandInvokeTACommand.cpp
+ *
+ *    Description:  CommandInvokeTACommand class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandInvokeTACommand.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * InvokeTACommand command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandInvokeTACommand::CommandInvokeTACommand(IntTAInvokeCommandData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * InvokeCommand command execute.
+ * @param none
+ */
+void CommandInvokeTACommand::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->invokeTACommand(data);
+       if (result != TEEC_SUCCESS) {
+               delete pTEECtx;
+       }
+}
+
+CommandInvokeTACommand::~CommandInvokeTACommand() {
+
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandOpenSession.cpp b/simulatordaemon/src/ClientCommands/CommandOpenSession.cpp
new file mode 100755 (executable)
index 0000000..80ebfdc
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOpenSession.cpp
+ *
+ *    Description:  CommandOpenSession class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandOpenSession.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * OpenSession command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandOpenSession::CommandOpenSession(OpenSessionData data, TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * OpenSession command execute.
+ * @param none
+ */
+CommandOpenSession::~CommandOpenSession() {
+}
+
+void CommandOpenSession::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->openSession(data);
+       if (result != TEEC_SUCCESS) {
+               FinalizeContextData fdata;
+               fdata.contextID = data.contextID;
+               pTEECtx->finContext(fdata);
+               delete pTEECtx;
+       }
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandOpenTASession.cpp b/simulatordaemon/src/ClientCommands/CommandOpenTASession.cpp
new file mode 100755 (executable)
index 0000000..8e35480
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandOpenTASession.cpp
+ *
+ *    Description:  CommandOpenTASession class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandOpenTASession.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * OpenTASession command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandOpenTASession::CommandOpenTASession(IntTAOpenSessionData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * OpenTASession command execute.
+ * @param none
+ */
+CommandOpenTASession::~CommandOpenTASession() {
+
+}
+
+void CommandOpenTASession::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->openTASession(data);
+       if (result != TEEC_SUCCESS) {
+               delete pTEECtx;
+       }
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandPanic.cpp b/simulatordaemon/src/ClientCommands/CommandPanic.cpp
new file mode 100755 (executable)
index 0000000..2766f71
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandPanic.cpp
+ *
+ *    Description:  CommandPanic class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandPanic.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Panic command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandPanic::CommandPanic(IntTAPanicData data, TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * Panic command execute.
+ * @param none
+ */
+void CommandPanic::execute() {
+       //TODO: Handle TA Panic
+       return;
+}
+
+CommandPanic::~CommandPanic() {
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandRegSharedMem.cpp b/simulatordaemon/src/ClientCommands/CommandRegSharedMem.cpp
new file mode 100755 (executable)
index 0000000..f8774ab
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandRegSharedMem.cpp
+ *
+ *    Description:  CommandRegSharedMem class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandRegSharedMem.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * RegisterSharedMemory command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandRegSharedMem::CommandRegSharedMem(RegSharedMemData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * RegisterSharedMemory command execute.
+ * @param none
+ */
+void CommandRegSharedMem::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->registerSharedMemory(data);
+       if (result != TEEC_SUCCESS) {
+               LOGE(SIM_DAEMON, "Register Shared Memory response write to CA FAILED");
+               FinalizeContextData fdata;
+               fdata.contextID = data.contextID;
+               pTEECtx->finContext(fdata);
+               delete pTEECtx;
+       }
+}
+
+CommandRegSharedMem::~CommandRegSharedMem() {
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandRelSharedMem.cpp b/simulatordaemon/src/ClientCommands/CommandRelSharedMem.cpp
new file mode 100755 (executable)
index 0000000..955f834
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandRelSharedMem.cpp
+ *
+ *    Description:  CommandRelSharedMem class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandRelSharedMem.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * ReleaseSharedMemory command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandRelSharedMem::CommandRelSharedMem(RelSharedMemData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * ReleaseSharedMemory command execute.
+ * @param none
+ */
+void CommandRelSharedMem::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       result = pTEECtx->releaseSharedMemory(data);
+       if (result != TEEC_SUCCESS) {
+               LOGE(SIM_DAEMON, "Release Shared Memory response write to CA FAILED");
+               FinalizeContextData fdata;
+               fdata.contextID = data.contextID;
+               pTEECtx->finContext(fdata);
+               delete pTEECtx;
+       }
+}
+
+CommandRelSharedMem::~CommandRelSharedMem() {
+}
diff --git a/simulatordaemon/src/ClientCommands/CommandReqCancellation.cpp b/simulatordaemon/src/ClientCommands/CommandReqCancellation.cpp
new file mode 100755 (executable)
index 0000000..afc721c
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  CommandReqCancellation.cpp
+ *
+ *    Description:  CommandReqCancellation class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/CommandReqCancellation.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * RequestCancellation command handling.
+ * @param data received from TEECLib
+ * @param TEECtx object associated with command
+ */
+CommandReqCancellation::CommandReqCancellation(ReqCancellationData data,
+    TEEContext *TEECtx) :
+               CommandBase(TEECtx) {
+       this->data = data;
+}
+
+/**
+ * RequestCancellation command execute.
+ * @param none
+ */
+void CommandReqCancellation::execute() {
+       pTEECtx->reqCancel(data);
+}
+
+CommandReqCancellation::~CommandReqCancellation() {
+}
diff --git a/simulatordaemon/src/ClientCommands/MakeCommand.cpp b/simulatordaemon/src/ClientCommands/MakeCommand.cpp
new file mode 100755 (executable)
index 0000000..4d660a4
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  MakeCommand.cpp
+ *
+ *    Description:  MakeCommand class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ClientCommands/MakeCommand.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Creates a command object based on the type of command passed in
+ * @param command name of command from enum TEE_CMD
+ * @param data pointer to structure defining the command in TEE_CMD
+ * @param TEECtx object associated with command
+ */
+CommandBasePtr MakeCommand::getCommand(TEE_CMD teecmd, void* teedata,
+    TEEContext *TEECtx) {
+
+       LOGD(SIM_DAEMON, "Entry");
+       CommandBasePtr command;
+       switch (teecmd) {
+               case INITIALIZE_CONTEXT: {
+                       InitContextData data;
+                       data = *(reinterpret_cast<InitContextData*>(teedata));
+                       command = CommandBasePtr(new CommandInitContext(data, TEECtx));
+                       break;
+               }
+               case FINALIZE_CONTEXT: {
+                       FinalizeContextData data;
+                       data = *(reinterpret_cast<FinalizeContextData*>(teedata));
+                       command = CommandBasePtr(new CommandFinContext(data, TEECtx));
+                       break;
+               }
+               case OPEN_SESSION: {
+                       OpenSessionData data;
+                       data = *(reinterpret_cast<OpenSessionData*>(teedata));
+                       command = CommandBasePtr(new CommandOpenSession(data, TEECtx));
+                       break;
+               }
+               case INVOKE_COMMAND: {
+                       InvokeCommandData data;
+                       data = *(reinterpret_cast<InvokeCommandData*>(teedata));
+                       command = CommandBasePtr(new CommandInvokeCommand(data, TEECtx));
+                       break;
+               }
+               case CLOSE_SESSION: {
+                       CloseSessionData data;
+                       data = *(reinterpret_cast<CloseSessionData*>(teedata));
+                       command = CommandBasePtr(new CommandCloseSession(data, TEECtx));
+                       break;
+               }
+               case OPEN_TA_SESSION: {
+                       IntTAOpenSessionData data;
+                       data = *(reinterpret_cast<IntTAOpenSessionData*>(teedata));
+                       command = CommandBasePtr(new CommandOpenTASession(data, TEECtx));
+                       break;
+               }
+               case INVOKE_TA_COMMAND: {
+                       IntTAInvokeCommandData data;
+                       data = *(reinterpret_cast<IntTAInvokeCommandData*>(teedata));
+                       command = CommandBasePtr(new CommandInvokeTACommand(data, TEECtx));
+                       break;
+               }
+               case CLOSE_TA_SESSION: {
+                       IntTACloseSessionData data;
+                       data = *(reinterpret_cast<IntTACloseSessionData*>(teedata));
+                       command = CommandBasePtr(new CommandCloseTASession(data, TEECtx));
+                       break;
+               }
+               case REQUEST_CANCELLATION: {
+                       ReqCancellationData data;
+                       data = *(reinterpret_cast<ReqCancellationData*>(teedata));
+                       command = CommandBasePtr(new CommandReqCancellation(data, TEECtx));
+                       break;
+               }
+               case REGISTER_SHARED_MEMORY: {
+                       RegSharedMemData data;
+                       data = *(reinterpret_cast<RegSharedMemData*>(teedata));
+                       command = CommandBasePtr(new CommandRegSharedMem(data, TEECtx));
+                       break;
+               }
+               case RELEASE_SHARED_MEMORY: {
+                       RelSharedMemData data;
+                       data = *(reinterpret_cast<RelSharedMemData*>(teedata));
+                       command = CommandBasePtr(new CommandRelSharedMem(data, TEECtx));
+                       break;
+               }
+               case PANIC: {
+                       IntTAPanicData data;
+                       data = *(reinterpret_cast<IntTAPanicData*>(teedata));
+                       command = CommandBasePtr(new CommandPanic(data, TEECtx));
+                       break;
+               }
+               default: {
+                       command.reset();
+                       break;
+               }
+       }
+       return command;
+}
+
+MakeCommand::~MakeCommand() {
+
+}
+
+/**
+ * Calculates size of data expected based on command received
+ * @param command TEE_CMD to be executed on TA
+ * @return size of data in bytes based on command.
+ * A return size of -1 means invalid command. For a valid command
+ * return size will always be positive integer.
+ *
+ */
+uint32_t MakeCommand::getDataSize(TEE_CMD command) {
+
+       uint32_t size = -1;
+       switch (command) {
+               case INITIALIZE_CONTEXT:
+                       size = sizeof(InitContextData);
+                       LOGD(SIM_DAEMON, "[TEEC] InitContextData Size: %d", size);
+                       break;
+               case OPEN_SESSION:
+                       size = sizeof(OpenSessionData);
+                       LOGD(SIM_DAEMON, "[TEEC] OpenSessionData Size: %d", size);
+                       break;
+               case REGISTER_SHARED_MEMORY:
+                       size = sizeof(RegSharedMemData);
+                       LOGD(SIM_DAEMON, "[TEEC] RegSharedMemData Size: %d", size);
+                       break;
+               case INVOKE_COMMAND:
+                       size = sizeof(InvokeCommandData);
+                       LOGD(SIM_DAEMON, "[TEEC] InvokeCommandData Size: %d", size);
+                       break;
+               case RELEASE_SHARED_MEMORY:
+                       size = sizeof(RelSharedMemData);
+                       LOGD(SIM_DAEMON, "[TEEC] RelSharedMemData Size: %d", size);
+                       break;
+               case CLOSE_SESSION:
+                       size = sizeof(CloseSessionData);
+                       LOGD(SIM_DAEMON, "[TEEC] CloseSessionData Size: %d", size);
+                       break;
+               case FINALIZE_CONTEXT:
+                       size = sizeof(FinalizeContextData);
+                       LOGD(SIM_DAEMON, "[TEEC] FinalizeContextData Size: %d", size);
+                       break;
+               case REQUEST_CANCELLATION:
+                       size = sizeof(ReqCancellationData);
+                       LOGD(SIM_DAEMON, "[TEEC] ReqCancellationData Size: %d", size);
+                       break;
+               case OPEN_TA_SESSION:
+                       size = sizeof(IntTAOpenSessionData);
+                       LOGD(SIM_DAEMON, "[TEEC] IntTAOpenSessionData Size: %d", size);
+                       break;
+               case INVOKE_TA_COMMAND:
+                       size = sizeof(IntTAInvokeCommandData);
+                       LOGD(SIM_DAEMON, "[TEEC] IntTAInvokeCommandData Size: %d", size);
+                       break;
+               case CLOSE_TA_SESSION:
+                       size = sizeof(IntTACloseSessionData);
+                       LOGD(SIM_DAEMON, "[TEEC] IntTACloseSessionData Size: %d", size);
+                       break;
+               case CHECK_MEMORY:
+                       //      size = sizeof(CheckMemoryData);
+                       LOGD(SIM_DAEMON, "[TEEC] CheckMemoryData Size: %d", size);
+                       break;
+               case PANIC:
+                       size = sizeof(IntTAPanicData);
+                       LOGD(SIM_DAEMON, "[TEEC] PanicData Size: %d", size);
+                       break;
+               default:
+                       size = -1;
+                       break;
+       }
+       return size;
+}
diff --git a/simulatordaemon/src/ConnectionSession.cpp b/simulatordaemon/src/ConnectionSession.cpp
new file mode 100755 (executable)
index 0000000..759eab4
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ConnectionSession.cpp
+ *
+ *    Description:  ConnectionSession class
+ *
+ *        Version:  1.0
+ *        Created:  16 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ConnectionSession.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+// Lock for Context ID to be assigned to Context
+pthread_rwlock_t ctxIDLock = PTHREAD_RWLOCK_INITIALIZER;
+// Context ID to be assigned to Context
+uint32_t ctxID = 21;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+
+/**
+ * On starting the server and accepting a connection, read some data from the socket.
+ * * @param none
+ */
+void ConnectionSession::start() {
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Create a new Context
+       pthread_rwlock_wrlock(&ctxIDLock);
+       TEECtx = new TEEContext(ctxID, this);
+       // Increment the Context ID to be assigned to next Context
+       ctxID++;
+       if (ctxID == 0) ctxID++;
+       pthread_rwlock_unlock(&ctxIDLock);
+       currentState = CMD_READ;
+       // read exactly 1 byte to identify the command and execute callback when
+       // command is received
+       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+           boost::asio::transfer_exactly(1),
+           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+               boost::asio::placeholders::error,
+               boost::asio::placeholders::bytes_transferred));
+}
+
+/**
+ * On asynchronously reading from socket, this call back is executed.
+ * @param error Boost error code and error message object
+ * @param bytes_transferred Number of bytes read from the socket
+ */
+void ConnectionSession::handleRead(const boost::system::error_code& error,
+    size_t bytes_transferred) {
+       LOGD(SIM_DAEMON, "Entry");
+
+       if (!error) {
+               /**
+                * A simple small state machine to parse command and handle its
+                * call back to TEECLib interface
+                * The state machine identifies the command. If valid, finds out how
+                * many bytes of data to be read further else if invalid, exits the Simulator Daemon.
+                *
+                * Later, exact number of identified size of data is read from
+                * stream and stored.
+                */
+               switch (currentState) {
+                       case CMD_READ: {
+                               // Identify command
+                               command = (TEE_CMD)clientData.at(0);
+                               LOGD(SIM_DAEMON, "Command received: %d", (uint32_t )command);
+
+                               // Calculate pending numbers of bytes pending to be read only for commands
+                               int32_t data_size = MakeCommand::getDataSize(command);
+
+                               if (data_size > 0) {
+                                       currentState = DATA_READ;
+                                       // read remaining bytes related to received valid command
+                                       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+                                           boost::asio::transfer_exactly(data_size),
+                                           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+
+                               else if (-1 == data_size) {
+                                       // else case is invalid command
+                                       // TODO: Identify the correct behavior; what to do when invalid command is received?
+                                       LOGE(SIM_DAEMON, "Invalid command received!");
+                               } else if (0 == data_size) {
+
+                                       // reset state to read new command
+                                       currentState = CMD_READ;
+                                       // read command and register callback to read data
+                                       boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+                                           boost::asio::transfer_exactly(1),
+                                           boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+                               break;
+                       } //case
+
+                       case DATA_READ: {
+                               // At this pointer data is completely read
+                               // clear the vector for the first time and copy client data received
+                               commandData.clear();
+                               for (uint32_t i = 0; i < clientData.size(); i++) {
+                                       commandData.push_back(clientData.at(i));
+                               }
+                               string tempData(commandData.begin(), commandData.end());
+
+                               // Call the TEEContext object to handle commands
+                               CommandBasePtr ptr = MakeCommand::getCommand(command,
+                                   (void*)tempData.c_str(), TEECtx);
+
+                               if (!ptr == false) {
+                                       ptr->execute();
+                               } else {
+                                       LOGE(SIM_DAEMON, "Command not found");
+                               }
+
+                               // reset state to read new command
+                               currentState = CMD_READ;
+                               // read command and register callback to read data
+                               boost::asio::async_read(clientSocket, boost::asio::buffer(clientData),
+                                   boost::asio::transfer_exactly(1),
+                                   boost::bind(&ConnectionSession::handleRead, shared_from_this(),
+                                       boost::asio::placeholders::error,
+                                       boost::asio::placeholders::bytes_transferred));
+                               break;
+                       } //case
+               } //switch
+       } else {
+               LOGE(SIM_DAEMON, "Error in reading from CA");
+               LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
+               LOGE(SIM_DAEMON, "Response returned with error code %s",
+                   error.category().name());
+               // Call the TEEContext object to cleanup
+               FinalizeContextData data;
+               data.contextID = 0;
+               CommandBasePtr ptr = MakeCommand::getCommand(FINALIZE_CONTEXT,
+                                   (void*)&data, TEECtx);
+               if (!ptr == false) {
+                       ptr->execute();
+               } else {
+                       LOGE(SIM_DAEMON, "Command not found");
+               }
+       }
+}
+
+/**
+ * Synchronous write to the socket.
+ * @param command to be sent to TEECLib
+ * @param data to be sent to TEECLib
+ * @param size of data to be sent to TEECLib
+ */
+TEEC_Result ConnectionSession::write(TEE_CMD cmd, char* data, size_t size) {
+       LOGD(SIM_DAEMON, "Entry");
+
+       TEEC_Result result = TEEC_ERROR_COMMUNICATION;
+       boost::system::error_code error = boost::asio::error::host_not_found;
+       pthread_mutex_lock (&connLock);
+       // Send command to TEECLib for CA
+       boost::asio::write(clientSocket,
+           boost::asio::buffer((char*)&cmd, sizeof(char)),
+           boost::asio::transfer_all(), error);
+
+       if ((!error) && (size != 0)) {
+               // Send command data to TEECLib for CA
+               boost::asio::write(clientSocket, boost::asio::buffer(data, size),
+                   boost::asio::transfer_all(), error);
+               if (!error)
+                       result = TEEC_SUCCESS;
+               else {
+                       LOGE(SIM_DAEMON, "Error in writing Data to CA");
+                       LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
+                       LOGE(SIM_DAEMON, "Response returned with error code %s",
+                           error.category().name());
+               }
+       } else {
+               LOGE(SIM_DAEMON, "Error in writing Command to CA");
+               LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
+               LOGE(SIM_DAEMON, "Response returned with error code %s",
+                   error.category().name());
+       }
+       pthread_mutex_unlock(&connLock);
+       return result;
+}
+
+ConnectionSession::~ConnectionSession() {
+       LOGD(SIM_DAEMON, "Entry");
+       // Destory the lock for write (connLock)
+       pthread_mutex_destroy (&connLock);
+       // delete Context
+       delete TEECtx;
+       TEECtx = NULL;
+}
diff --git a/simulatordaemon/src/RemoteSystemsTempFiles/.project b/simulatordaemon/src/RemoteSystemsTempFiles/.project
new file mode 100755 (executable)
index 0000000..5447a64
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>RemoteSystemsTempFiles</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.rse.ui.remoteSystemsTempNature</nature>
+       </natures>
+</projectDescription>
diff --git a/simulatordaemon/src/ResponseCommands/ResCommandCloseSession.cpp b/simulatordaemon/src/ResponseCommands/ResCommandCloseSession.cpp
new file mode 100755 (executable)
index 0000000..479ac9c
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandCloseSession.cpp
+ *
+ *    Description:  ResCommandCloseSession class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResponseCommands/ResCommandCloseSession.h"
+#include "ConnectionSession.h"
+#include "TAFactory.h"
+#include "ITAInstance.h"
+#include "ISession.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * CloseSession response command handling.
+ * @param data received from TEEStub
+ * @param Session Map to find out the Session object associated with command
+ */
+ResCommandCloseSession::ResCommandCloseSession(CloseTASessionData *data,
+    std::map<uint32_t, ISession*> *sessionMap) :
+               ResCommandBase(sessionMap) {
+       this->data = data;
+}
+
+/**
+ * CloseSession response command execute.
+ * @param none
+ */
+void ResCommandCloseSession::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       TAFactory *TAFact = TAFactory::getInstance();
+       if (NULL == TAFact) {
+               // This error should not come
+               LOGE(SIM_DAEMON, "TA Factory instance creation failed. Check logs for further info");
+               return;
+       }
+       map<uint32_t, ISession*>::iterator it;
+       it = pSessionMap->find(data->sessionID);
+       if (it != pSessionMap->end()) {
+               ISession* session = it->second;
+               (session->getTAInstance())->takeSessionMapLock();
+               pSessionMap->erase(it);
+               multimap<string, TAInstancePtr>::iterator itTAMap;
+               pthread_rwlock_wrlock(&TAFact->mTAInstanceMapLock);
+               for (itTAMap = TAFact->mTAInstanceMap.begin();
+                   itTAMap != TAFact->mTAInstanceMap.end(); ++itTAMap) {
+                       if (itTAMap->second == session->getTAInstance()) {
+                               if (pSessionMap->size() == 0) {
+                                       if ((session->getTAInstance())->checkKeepAlive() != true) {
+                                               DestroyTAEntryPointData ddata;
+                                               memset(&ddata, 0, sizeof(DestroyTAEntryPointData));
+                                               ddata.sessionID = data->sessionID;
+                                               result = (session->getTAInstance())->sendRequestToTA(DESTROY,
+                                                   (void*)&ddata, sizeof(DestroyTAEntryPointData));
+                                               if (result != TEEC_SUCCESS) {
+                                                       LOGE(SIM_DAEMON, "Destroy sendRequestToTA FAILED");
+                                                       (session->getTAInstance())->killTA();
+                                               }
+                                       } else break;
+                               }
+                               TAFact->mTAInstanceMap.erase(itTAMap);
+                               break;
+                       }
+               }
+               pthread_rwlock_unlock(&TAFact->mTAInstanceMapLock);
+               session->getTAInstance()->releaseSessionMapLock();
+               if (session->getContextID() != 0) {
+                       if (session->checkInternal()) {
+                               IntTACloseSessionData cdata;
+                               memset(&cdata, 0, sizeof(IntTACloseSessionData));
+                               cdata.session = data->sessionID;
+                               result = session->writeResponse(CLOSE_TA_SESSION,
+                                   (char*)&cdata, sizeof(IntTACloseSessionData));
+                               if (result != TEEC_SUCCESS) {
+                                       LOGE(SIM_DAEMON, "Close Session response write to TA FAILED");
+                               }
+                       } else {
+                               CloseSessionData cdata;
+                               memset(&cdata, 0, sizeof(CloseSessionData));
+                               cdata.contextID = session->getContextID();
+                               cdata.sessionID = data->sessionID;
+                               result = session->writeResponse(CLOSE_SESSION, (char*)&cdata,
+                                   sizeof(CloseSessionData));
+                               if (result != TEEC_SUCCESS) {
+                                       LOGE(SIM_DAEMON, "Close Session response write to CA FAILED");
+                               }
+                       }
+                       session->detachFromContext();
+               }
+               session->getTAInstance()->eraseCommand(CLOSESESSION, data->sessionID);
+               delete session;
+       } else {
+               // This error should not come
+               LOGE(SIM_DAEMON, "SessionID: %d not found in map", data->sessionID);
+       }
+}
+
+ResCommandCloseSession::~ResCommandCloseSession() {
+
+}
diff --git a/simulatordaemon/src/ResponseCommands/ResCommandInvokeCommand.cpp b/simulatordaemon/src/ResponseCommands/ResCommandInvokeCommand.cpp
new file mode 100755 (executable)
index 0000000..e26e6b4
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandInvokeCommand.cpp
+ *
+ *    Description:  ResCommandInvokeCommand class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResponseCommands/ResCommandInvokeCommand.h"
+#include "ConnectionSession.h"
+#include "ITAInstance.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * InvokeCommand response command handling.
+ * @param data received from TEEStub
+ * @param Session Map to find out the Session object associated with command
+ */
+ResCommandInvokeCommand::ResCommandInvokeCommand(InvokeTACommandData *data,
+    std::map<uint32_t, ISession*> *sessionMap) :
+               ResCommandBase(sessionMap) {
+       this->data = data;
+}
+
+/**
+ * InvokeCommand response command execute.
+ * @param none
+ */
+void ResCommandInvokeCommand::execute() {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       uint32_t i, type;
+       map<uint32_t, ISession*>::iterator it;
+       it = pSessionMap->find(data->sessionID);
+       if ((it != pSessionMap->end()) && (it->second->getContextID() != 0)) {
+               if (it->second->checkInternal()) {
+                       IntTAInvokeCommandData idata;
+                       memset(&idata, 0, sizeof(IntTAInvokeCommandData));
+                       idata.operation.paramTypes = data->op.paramTypes;
+                       for (i = 0; i < 4; i++) {
+                               type = ((data->op.paramTypes) >> (8 * i)) & 0x7f;
+                               if ((type == TEEC_VALUE_INPUT) || (type == TEEC_VALUE_OUTPUT)
+                                   || (type == TEEC_VALUE_INOUT)) {
+                                       idata.operation.params[i].value.a = data->op.params[i].value.a;
+                                       idata.operation.params[i].value.b = data->op.params[i].value.b;
+                               } else if (type == TEEC_NONE) {
+                                       // No operation data
+                               } else {
+                                       idata.operation.params[i].mem.size = data->op.params[i].memref.size;
+                                       idata.operation.params[i].mem.shmKey = data->op.shmID[i];
+                               }
+                       }
+                       idata.returnValue = data->returnValue;
+                       idata.returnOrigin = data->returnOrigin;
+                       idata.session = data->sessionID;
+
+                       idata.commandID = data->commandID;
+                       result = it->second->writeResponse(INVOKE_TA_COMMAND,
+                           (char*)&idata, sizeof(IntTAInvokeCommandData));
+                       if (result != TEEC_SUCCESS) {
+                               LOGE(SIM_DAEMON, "Invoke Command response write to TA FAILED");
+                       }
+               } else {
+                       InvokeCommandData idata;
+                       memset(&idata, 0, sizeof(InvokeCommandData));
+                       idata.contextID = it->second->getContextID();
+                       idata.operation.paramTypes = data->op.paramTypes;
+                       for (i = 0; i < 4; i++) {
+                               type = ((data->op.paramTypes) >> (8 * i)) & 0x7f;
+                               if ((type == TEEC_VALUE_INPUT) || (type == TEEC_VALUE_OUTPUT)
+                                   || (type == TEEC_VALUE_INOUT)) {
+                                       idata.operation.params[i].value.a = data->op.params[i].value.a;
+                                       idata.operation.params[i].value.b = data->op.params[i].value.b;
+                               } else if (type == TEEC_NONE) {
+                                       // No operation data
+                               } else {
+                                       idata.operation.params[i].mem.size = data->op.params[i].memref.size;
+                                       idata.operation.params[i].mem.shmKey = data->op.shmID[i];
+                               }
+                       }
+                       idata.returnValue = data->returnValue;
+                       idata.returnOrigin = data->returnOrigin;
+                       idata.sessionID = data->sessionID;
+
+                       idata.commandID = data->commandID;
+                       result = it->second->writeResponse(INVOKE_COMMAND,
+                           (char*)&idata, sizeof(InvokeCommandData));
+                       if (result != TEEC_SUCCESS) {
+                               LOGE(SIM_DAEMON, "Invoke Command response write to CA FAILED");
+                       }
+               }
+               it->second->getTAInstance()->eraseCommand(INVOKECOMMAND, data->sessionID);
+       } else {
+               // This error should not come
+               LOGE(SIM_DAEMON, "SessionID: %d not found in map", data->sessionID);
+       }
+}
+
+ResCommandInvokeCommand::~ResCommandInvokeCommand() {
+
+}
diff --git a/simulatordaemon/src/ResponseCommands/ResCommandOpenSession.cpp b/simulatordaemon/src/ResponseCommands/ResCommandOpenSession.cpp
new file mode 100755 (executable)
index 0000000..c1debd6
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandOpenSession.cpp
+ *
+ *    Description:  ResCommandOpenSession class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResponseCommands/ResCommandOpenSession.h"
+#include "ConnectionSession.h"
+#include "ITAInstance.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * OpenSession response command handling.
+ * @param data received from TEEStub
+ * @param Session Map to find out the Session object associated with command
+ */
+ResCommandOpenSession::ResCommandOpenSession(OpenTASessionData *data,
+    std::map<uint32_t, ISession*> *sessionMap) :
+               ResCommandBase(sessionMap) {
+       this->data = data;
+}
+
+/**
+ * OpenSession response command execute.
+ * @param none
+ */
+void ResCommandOpenSession::execute() {
+       uint32_t i, type;
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       map<uint32_t, ISession*>::iterator it;
+       it = pSessionMap->find(data->sessionID);
+       if ((it != pSessionMap->end()) && (it->second->getContextID() != 0)) {
+               if (it->second->checkInternal()) {
+                       IntTAOpenSessionData odata;
+                       memset(&odata, 0, sizeof(IntTAOpenSessionData));
+                       odata.operation.paramTypes = data->op.paramTypes;
+                       for (i = 0; i < 4; i++) {
+                               type = ((data->op.paramTypes) >> (8 * i)) & 0x7f;
+                               if ((type == TEEC_VALUE_INPUT) || (type == TEEC_VALUE_OUTPUT)
+                                   || (type == TEEC_VALUE_INOUT)) {
+                                       odata.operation.params[i].value.a = data->op.params[i].value.a;
+                                       odata.operation.params[i].value.b = data->op.params[i].value.b;
+                               } else if (type == TEEC_NONE) {
+                                       // No operation data
+                               } else {
+                                       odata.operation.params[i].mem.size = data->op.params[i].memref.size;
+                                       odata.operation.params[i].mem.shmKey = data->op.shmID[i];
+                               }
+                       }
+                       odata.returnValue = data->returnValue;
+                       odata.returnOrigin = data->returnOrigin;
+                       odata.session = data->sessionID;
+
+                       result = it->second->writeResponse(OPEN_TA_SESSION,
+                           (char*)&odata, sizeof(IntTAOpenSessionData));
+                       if (result != TEEC_SUCCESS) {
+                               LOGE(SIM_DAEMON, "Open Session response write to TA FAILED");
+                       }
+               } else {
+                       OpenSessionData odata;
+                       memset(&odata, 0, sizeof(OpenSessionData));
+                       odata.contextID = it->second->getContextID();
+                       odata.operation.paramTypes = data->op.paramTypes;
+                       for (i = 0; i < 4; i++) {
+                               type = ((data->op.paramTypes) >> (8 * i)) & 0x7f;
+                               if ((type == TEEC_VALUE_INPUT) || (type == TEEC_VALUE_OUTPUT)
+                                   || (type == TEEC_VALUE_INOUT)) {
+                                       odata.operation.params[i].value.a = data->op.params[i].value.a;
+                                       odata.operation.params[i].value.b = data->op.params[i].value.b;
+                               } else if (type == TEEC_NONE) {
+                                       // No operation data
+                               } else {
+                                       odata.operation.params[i].mem.size = data->op.params[i].memref.size;
+                                       odata.operation.params[i].mem.shmKey = data->op.shmID[i];
+                               }
+                       }
+                       odata.returnValue = data->returnValue;
+                       odata.returnOrigin = data->returnOrigin;
+                       odata.sessionID = data->sessionID;
+
+                       result = it->second->writeResponse(OPEN_SESSION,
+                           (char*)&odata, sizeof(OpenSessionData));
+                       if (result != TEEC_SUCCESS) {
+                               LOGE(SIM_DAEMON, "Open Session response write to CA FAILED");
+                       }
+               }
+               it->second->getTAInstance()->eraseCommand(OPENSESSION, data->sessionID);
+       } else {
+               // This error should not come
+               LOGE(SIM_DAEMON, "SessionID: %d not found in map", data->sessionID);
+       }
+}
+
+ResCommandOpenSession::~ResCommandOpenSession() {
+}
diff --git a/simulatordaemon/src/ResponseCommands/ResCommandReqCancellation.cpp b/simulatordaemon/src/ResponseCommands/ResCommandReqCancellation.cpp
new file mode 100755 (executable)
index 0000000..4a22539
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResCommandReqCancellation.cpp
+ *
+ *    Description:  ResCommandReqCancellation class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResponseCommands/ResCommandReqCancellation.h"
+#include "ConnectionSession.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * ReqCancel response command handling.
+ * @param data received from TEEStub
+ * @param Session Map to find out the Session object associated with command
+ */
+ResCommandReqCancellation::ResCommandReqCancellation(ReqCancellationData *data,
+    std::map<uint32_t, ISession*> *sessionMap) :
+               ResCommandBase(sessionMap) {
+       this->data = data;
+}
+
+/**
+ * ReqCancel response command execute.
+ * @param none
+ */
+ResCommandReqCancellation::~ResCommandReqCancellation() {
+}
+
+void ResCommandReqCancellation::execute() {
+       //Not supported in current design
+       return;
+}
diff --git a/simulatordaemon/src/ResponseCommands/ResMakeCommand.cpp b/simulatordaemon/src/ResponseCommands/ResMakeCommand.cpp
new file mode 100755 (executable)
index 0000000..8b90d28
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ResMakeCommand.cpp
+ *
+ *    Description:  ResMakeCommand class
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ResponseCommands/ResMakeCommand.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Creates a command object based on the type of command passed in
+ * @param command name of command from enum SIM_COMMAND
+ * @param data pointer to structure defining the command in SIM_COMMAND
+ */
+ResCommandBasePtr ResMakeCommand::getCommand(SIM_COMMAND tacmd, void* tadata,
+    std::map<uint32_t, ISession*> *sessionMap) {
+
+       ResCommandBasePtr command;
+       switch (tacmd) {
+               case OPENSESSION: {
+                       OpenTASessionData *data;
+                       data = (reinterpret_cast<OpenTASessionData*>(tadata));
+                       command = ResCommandBasePtr(new ResCommandOpenSession(data, sessionMap));
+                       break;
+               }
+               case INVOKECOMMAND: {
+                       InvokeTACommandData *data;
+                       data = (reinterpret_cast<InvokeTACommandData*>(tadata));
+                       command = ResCommandBasePtr(
+                           new ResCommandInvokeCommand(data, sessionMap));
+                       break;
+               }
+               case CLOSESESSION: {
+                       CloseTASessionData *data;
+                       data = (reinterpret_cast<CloseTASessionData*>(tadata));
+                       command = ResCommandBasePtr(new ResCommandCloseSession(data, sessionMap));
+                       break;
+               }
+               case REQCANCEL: {
+                       ReqCancellationData *data;
+                       data = (reinterpret_cast<ReqCancellationData*>(tadata));
+                       command = ResCommandBasePtr(
+                           new ResCommandReqCancellation(data, sessionMap));
+                       break;
+               }
+               default: {
+                       command.reset();
+                       break;
+               }
+       }
+       return command;
+}
+
+ResMakeCommand::~ResMakeCommand() {
+
+}
+
+/**
+ * Calculates size of data expected based on command received
+ * @param command SIM_COMMAND to be executed
+ * @return size of data in bytes based on command.
+ * A return size of -1 means invalid command. For a valid command
+ * return size will always be positive integer.
+ *
+ */
+uint32_t ResMakeCommand::getDataSize(SIM_COMMAND command) {
+
+       uint32_t size = -1;
+       switch (command) {
+               case CREATE:
+                       size = sizeof(CreateTAEntryPointData);
+                       LOGD(SIM_DAEMON, "[TA] CreateTAEntryPoint Size: %d", size);
+                       break;
+               case DESTROY:
+                       size = sizeof(DestroyTAEntryPointData);
+                       LOGD(SIM_DAEMON, "[TA] DestroyTAEntryPoint Size: %d", size);
+                       break;
+               case OPENSESSION:
+                       size = sizeof(OpenTASessionData);
+                       LOGD(SIM_DAEMON, "[TA] OpenTASessionData Size: %d", size);
+                       break;
+               case INVOKECOMMAND:
+                       size = sizeof(InvokeTACommandData);
+                       LOGD(SIM_DAEMON, "[TA] InvokeTACommandData Size: %d", size);
+                       break;
+               case CLOSESESSION:
+                       size = sizeof(CloseTASessionData);
+                       LOGD(SIM_DAEMON, "[TA] CloseTASessionData Size: %d", size);
+                       break;
+               case REQCANCEL:
+                       size = sizeof(RequestTACancelData);
+                       LOGD(SIM_DAEMON, "[TA] RequestTACancelData Size: %d", size);
+                       break;
+               default:
+                       size = -1;
+                       break;
+       }
+       return size;
+}
diff --git a/simulatordaemon/src/Session.cpp b/simulatordaemon/src/Session.cpp
new file mode 100755 (executable)
index 0000000..0739089
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  Session.cpp
+ *
+ *    Description:  Session class
+ *
+ *        Version:  1.0
+ *        Created:  27 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "Session.h"
+#include "TAFactory.h"
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Session constructer. Session is created for each OpenSession call
+ * @param TEECtx Context instance associated with the session
+ */
+Session::Session(TEEContext* TEECtx) {
+       LOGD(SIM_DAEMON, "Entry");
+       mContext = TEECtx;
+       mSessionID = -1;
+}
+
+bool Session::checkInternal() {
+       return mContext->isInternal;
+}
+
+uint32_t Session::getContextID() {
+       LOGD(SIM_DAEMON, "Entry");
+       if (mContext != NULL) {
+               LOGD(SIM_DAEMON, "Entry");
+               return mContext->mContextID;
+       } else {
+               return 0;
+        }
+}
+
+uint32_t Session::getSessionID() {
+       return mSessionID;
+}
+
+TAInstancePtr Session::getTAInstance() {
+       return mTAInstance;
+}
+
+void Session::detachFromContext() {
+       /* Find the Session instance in the session map */
+       map<uint32_t, ISession*>::iterator it;
+       pthread_rwlock_wrlock(&mContext->mSessionMapLock);
+       it = mContext->mSessionMap.find(mSessionID);
+       if (it == mContext->mSessionMap.end()) {
+               LOGE(SIM_DAEMON, "Session not found");
+               pthread_rwlock_unlock(&mContext->mSessionMapLock);
+               return;
+       }
+       mContext->mSessionMap.erase(it);
+       pthread_rwlock_unlock(&mContext->mSessionMapLock);
+}
+
+TEEC_Result Session::writeResponse(TEE_CMD command, char* data, size_t size) {
+       return mContext->mConnSess->write(command, data, size);
+}
+/**
+ * Session initializer. Called after Session constructor to initialize a
+ * session
+ * @param data OpenSessionData type of data for opening a session
+ */
+TEEC_Result Session::createSession(OpenSessionData data) {
+
+       uint32_t i, type;
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Get TA factory instance
+       TAFactory *TAFact = TAFactory::getInstance();
+       // Update member variable mSessionID with the assigned session ID
+       mSessionID = data.sessionID;
+
+       //Check if the TA is to be launched in Debug mode, Kill alive TA process
+       TAInstancePtr TAInst;
+
+       TABinaryManager *TABin = TABinaryManager::getInstance();
+       if(TABin == NULL) {
+               LOGE(SIM_DAEMON, "Creating TABinaryManager Instance FAILED - ");
+               return TEEC_ERROR_GENERIC;
+       }
+       string TAUUID = TABin->getUUIDAsString(data.uuid);
+       string argvPort = TABin->getPort(TAUUID);
+
+       if (argvPort != "") {
+               pthread_rwlock_wrlock(&TAFact->mTAInstanceMapLock);
+               multimap<string, TAInstancePtr>::iterator itr;
+               itr = TAFact->mTAInstanceMap.find(TAUUID);
+               if (itr != TAFact->mTAInstanceMap.end()) {
+                       mTAInstance = itr->second;
+                       LOGD(SIM_DAEMON, "KILL pid = %d", mTAInstance->getPID());
+                       mTAInstance->killTA();
+                       TAFact->mTAInstanceMap.erase(itr);
+               }
+               pthread_rwlock_unlock(&TAFact->mTAInstanceMapLock);
+       }
+
+       // Get TA instance from TA Factory and update member variable mTAInstance
+       pthread_rwlock_wrlock(&TAFact->mTAInstanceMapLock);
+       mTAInstance = TAFact->getTAInstance(data.uuid, this);
+       pthread_rwlock_unlock(&TAFact->mTAInstanceMapLock);
+       if (!mTAInstance == true) { // failure
+               LOGE(SIM_DAEMON, "Creating Trusted Application Instance FAILED - "
+                               "TA not launched/Create FAILED");
+               return TEEC_ERROR_BAD_PARAMETERS;
+       }
+
+       /* Check if TAInstance is newly created or an old instance is being re-used.
+        * If new instance then wait for CREATE command response from the TA, else
+        * directly send OpenSession request.
+        * TaInstance member variable isCreated is used to find if the TAInstance is
+        * newly created or re-used.
+        */
+       if (mTAInstance->getCreated() == false) {
+               result = mTAInstance->receiveCreateResponse();
+               if (TEEC_SUCCESS != result) { // failure
+                       LOGE(SIM_DAEMON, "Create TA entry point FAILED");
+                       pthread_rwlock_wrlock(&TAFact->mTAInstanceMapLock);
+                       multimap<string, TAInstancePtr>::iterator it;
+                       for (it = TAFact->mTAInstanceMap.begin();
+                           it != TAFact->mTAInstanceMap.end(); ++it) {
+                               if (it->second == mTAInstance) {
+                                       // Kill the TA process
+                                       mTAInstance->killTA();
+                                       // Erase the instance from TAFactory's Instance map
+                                       TAFact->mTAInstanceMap.erase(it);
+                                       break;
+                               }
+                       }
+                       pthread_rwlock_unlock(&TAFact->mTAInstanceMapLock);
+                       return result;
+               }
+
+               // Set the isCreated flag to true
+               mTAInstance->setCreated(true);
+               // Start asynchronous recieve from the TA
+               mTAInstance->receiveResponseFromTA();
+       }
+
+       // Generate OpenTASessionData to be sent to TA
+       OpenTASessionData tdata;
+       memset(&tdata, 0, sizeof(OpenTASessionData));
+       tdata.sessionID = data.sessionID;
+       tdata.op.paramTypes = data.operation.paramTypes;
+       tdata.returnValue = data.returnValue;
+       tdata.returnOrigin = data.returnOrigin;
+       for (i = 0; i < 4; i++) {
+               type = ((data.operation.paramTypes) >> (8 * i)) & 0x7f;
+               if ((type == TEEC_VALUE_INPUT) || (type == TEEC_VALUE_OUTPUT)
+                   || (type == TEEC_VALUE_INOUT)) {
+                       tdata.op.params[i].value.a = data.operation.params[i].value.a;
+                       tdata.op.params[i].value.b = data.operation.params[i].value.b;
+               } else if (type == TEEC_NONE) {
+                       // No operation data
+               } else {
+                       tdata.op.params[i].memref.size = data.operation.params[i].mem.size;
+                       tdata.op.shmID[i] = data.operation.params[i].mem.shmKey;
+               }
+       }
+       // Send OPENSESSION request to TA
+       result = mTAInstance->sendRequestToTA(OPENSESSION, (void*)&tdata,
+           sizeof(OpenTASessionData));
+       if (result != TEEC_SUCCESS) { // failure
+               LOGE(SIM_DAEMON, "OpenSession sendRequestToTA FAILED\n");
+       } else { // success
+               cmdData sdata;
+               sdata.osdata = tdata;
+               // Add the command in TA Instance's command map
+               mTAInstance->insertCommand(OPENSESSION, sdata);
+       }
+       return result;
+}
+
+/**
+ * Session command handler. Called for each InvokeCommand request in a session
+ * @param data InvokeCommandData type of data for invoking a command
+ */
+TEEC_Result Session::handleCommand(InvokeCommandData data) {
+       LOGD(SIM_DAEMON, "Entry");
+       uint32_t i, type;
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+
+       // Generate InvokeTACommandData to be sent to TA
+       InvokeTACommandData idata;
+       memset(&idata, 0, sizeof(InvokeTACommandData));
+       idata.commandID = data.commandID;
+       idata.returnOrigin = data.returnOrigin;
+       idata.returnValue = data.returnValue;
+       idata.sessionID = data.sessionID;
+       idata.op.operationID = data.operation.OperationID;
+       idata.op.paramTypes = data.operation.paramTypes;
+
+       for (i = 0; i < 4; i++) {
+               type = ((data.operation.paramTypes) >> (8 * i)) & 0x7f;
+               if ((type == TEEC_VALUE_INPUT) || (type == TEEC_VALUE_OUTPUT)
+                   || (type == TEEC_VALUE_INOUT)) {
+                       idata.op.params[i].value.a = data.operation.params[i].value.a;
+                       idata.op.params[i].value.b = data.operation.params[i].value.b;
+               } else if (type == TEEC_NONE) {
+                       // No operation data
+               } else {
+                       idata.op.params[i].memref.size = data.operation.params[i].mem.size;
+                       idata.op.shmID[i] = data.operation.params[i].mem.shmKey;
+               }
+       }
+
+       // Send INVOKECOMMAND request to TA
+       result = mTAInstance->sendRequestToTA(INVOKECOMMAND, (void*)&idata,
+           sizeof(InvokeTACommandData));
+       if (result != TEEC_SUCCESS) { // failure
+               LOGE(SIM_DAEMON, "InvokeCommand sendRequestToTA FAILED");
+       } else { // success
+               cmdData sdata;
+               sdata.icdata = idata;
+               // Add the command in TA Instance's command map
+               mTAInstance->insertCommand(INVOKECOMMAND, sdata);
+       }
+       return result;
+}
+
+/**
+ * Session cancellation handler. Called for each RequestCancellation request
+ * in a session
+ * @param data ReqCancellationData type of data for cancelling an operation
+ */
+void Session::handleCancel(ReqCancellationData data) {
+       LOGD(SIM_DAEMON, "Entry");
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+
+       // Generate RequestTACancelData to be sent to TA
+       RequestTACancelData rdata;
+       memset(&rdata, 0, sizeof(RequestTACancelData));
+       rdata.returnOrigin = TEEC_ORIGIN_TEE;
+       rdata.returnValue = TEEC_ERROR_COMMUNICATION;
+       rdata.sessionID = data.sessionID;
+       rdata.operationID = data.operationID;
+
+       // Send REQCANCEL request to TA
+       result = mTAInstance->sendRequestToTA(REQCANCEL, (void*)&rdata,
+           sizeof(RequestTACancelData));
+       if (result != TEEC_SUCCESS) { // failure
+               LOGE(SIM_DAEMON, "Request Cancellation sendRequestToTA FAILED");
+       } else { // success
+               cmdData sdata;
+               sdata.rcdata = rdata;
+               // Add the command in TA Instance's command map
+               mTAInstance->insertCommand(REQCANCEL, sdata);
+       }
+}
+
+/**
+ * Session clean up. Called before Session destructor to clean the session
+ */
+TEEC_Result Session::finalize(uint32_t contextID) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Get TA Factory insatnce
+       TAFactory *TAFact = TAFactory::getInstance();
+       // Generate CloseTASessionData to be sent to TA
+       CloseTASessionData cdata;
+       memset(&cdata, 0, sizeof(CloseTASessionData));
+       cdata.sessionID = mSessionID;
+       if (contextID == 0) {
+               mContext = NULL;
+       }
+       // Send CLOSESESSION request to TA
+       result = mTAInstance->sendRequestToTA(CLOSESESSION, (void*)&cdata,
+           sizeof(CloseTASessionData));
+       if (result != TEEC_SUCCESS) { //failure
+               LOGE(SIM_DAEMON, "CloseSession sendRequestToTA FAILED");
+
+               // remove the session from the TA Instance's Session Map
+               mTAInstance->takeSessionMapLock();
+               mTAInstance->eraseSessionMap(mSessionID);
+
+               multimap<string, TAInstancePtr>::iterator itTAMap;
+
+               /* Check if this is the last session associated with the TA Instance.
+                * If it is the last instance then check for KeepAlive flag.
+                */
+               pthread_rwlock_wrlock(&TAFact->mTAInstanceMapLock);
+               for (itTAMap = TAFact->mTAInstanceMap.begin();
+                   itTAMap != TAFact->mTAInstanceMap.end(); ++itTAMap) {
+                       if (itTAMap->second == mTAInstance) {
+                               /* If this is the last session associated with TA then check for
+                                * KeepAlive flag else DESTROY command is anyways not to be sent
+                                */
+                               if (mTAInstance->getSessionMapSize() == 0) {
+                                       /* Check if TAInstance is KeepAlive or not and if this is the last .
+                                        * If instance is KeepAlive then do not send DESTROY command else
+                                        * send DESTROY command to TA
+                                        * TaInstance member variable isKeepAlive is used to find if the
+                                        * TAInstance is KeepAlive or not.
+                                        */
+                                       if (mTAInstance->checkKeepAlive() != true) {
+                                               // Generate DestroyTAEntryPointData to be sent to TA
+                                               DestroyTAEntryPointData ddata;
+                                               memset(&ddata, 0, sizeof(DestroyTAEntryPointData));
+                                               ddata.sessionID = mSessionID;
+
+                                               // Send DESTROY command to TA
+                                               result = mTAInstance->sendRequestToTA(DESTROY, (void*)&ddata,
+                                                   sizeof(DestroyTAEntryPointData));
+                                               if (result != TEEC_SUCCESS) { // failure
+                                                       LOGE(SIM_DAEMON, "Destroy sendRequestToTA FAILED");
+                                                       mTAInstance->killTA();
+                                               }
+                                       } else break;
+                               }
+                               // Erase TA Instance from TA FActory's Instance map
+                               TAFact->mTAInstanceMap.erase(itTAMap);
+                               break;
+                       }
+               }
+               pthread_rwlock_unlock(&TAFact->mTAInstanceMapLock);
+               mTAInstance->releaseSessionMapLock();
+       } else { // success
+               cmdData sdata;
+               sdata.csdata = cdata;
+               // Add the command in TA Instance's command map
+               mTAInstance->insertCommand(CLOSESESSION, sdata);
+       }
+       return result;
+}
+
+/**
+ * Session destructor. Delete the Session instance
+ */
+Session::~Session() {
+       LOGD(SIM_DAEMON, "Entry");
+}
diff --git a/simulatordaemon/src/SimulatorDaemon.cpp b/simulatordaemon/src/SimulatorDaemon.cpp
new file mode 100755 (executable)
index 0000000..560721c
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SimulatorDaemon.cpp
+ *
+ *    Description:  SimulatorDaemon main file
+ *
+ *        Version:  1.0
+ *        Created:  16 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "path.h"
+#include "SimulatorDaemonServer.h"
+
+/*-----------------------------------------------------------------------------
+ *  Local functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Create shm file for shared memory implementation (IPC)
+ */
+void initializeShm() {
+       LOGD(SIM_DAEMON, "Entry");
+       ::unlink(SHM_PATH);
+       int fd = creat(SHM_PATH, S_IRWXU);
+       if (-1 == fd) {
+               LOGE(SIM_DAEMON, "shm file creation failed");
+               exit(0);
+       }
+       close(fd);
+}
+
+/**
+ * Starts the Simulator Daemon as server which listens for connection from
+ * TEECLib
+ * @param io_service
+ */
+void startServer(boost::asio::io_service& io_service) {
+       LOGD(SIM_DAEMON, "Entry");
+       try {
+               io_service.run();
+       } catch (std::exception& e) {
+               LOGE(SIM_DAEMON, "Exception: %s", e.what());
+       }
+}
+
+/**
+ * Stops the Simulator Daemon server
+ */
+void stopServer(boost::asio::io_service& io_service) {
+       LOGD(SIM_DAEMON, "Entry");
+       io_service.stop();
+}
+
+/**
+ * main function for Simulator Daemon
+ * @return
+ */
+int main() {
+       LOGD(SIM_DAEMON, "Entry");
+       uint32_t result = 0;
+       try {
+               ::unlink(SIMDAEMON_PATH);
+               //initializeShm();
+               SimulatorDaemonServer s(ioService::getInstance(), SIMDAEMON_PATH);
+               // Once the server is started, it exits only after the
+               // connection is lost or gracefully disconnected.
+               startServer(ioService::getInstance());
+               syslog(LOG_INFO | LOG_USER, "Daemon stopped");
+       } catch (std::exception& e) {
+               syslog(LOG_ERR | LOG_USER, "Exception: %s", e.what());
+               LOGE(SIM_DAEMON, "Exception: %s", e.what());
+       }
+       stopServer(ioService::getInstance());
+       return result;
+}
diff --git a/simulatordaemon/src/SimulatorDaemonServer.cpp b/simulatordaemon/src/SimulatorDaemonServer.cpp
new file mode 100755 (executable)
index 0000000..7d06878
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  SimulatorDaemonServer.cpp
+ *
+ *    Description:  SimulatorDaemonServer class
+ *
+ *        Version:  1.0
+ *        Created:  16 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "SimulatorDaemonServer.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Accepts a new connection from local machine on a UDS
+ * @param io_service provides OS abstraction for async communication
+ * @param file path to Unix Domain Socket represented by a local file
+ */
+SimulatorDaemonServer::SimulatorDaemonServer(
+    boost::asio::io_service& io_service, const std::string& file) :
+               mem_io_service(io_service),
+                   acceptor(io_service, stream_protocol::endpoint(file)) {
+       startAccept();
+}
+
+/**
+ * Method to start accepting a new connection
+ * @param none
+ */
+void SimulatorDaemonServer::startAccept() {
+       LOGD(SIM_DAEMON, "Entry");
+       ConnectionSession::session_ptr new_session = ConnectionSession::create(
+           acceptor.get_io_service());
+
+       acceptor.async_accept(new_session->socket(),
+           boost::bind(&SimulatorDaemonServer::handleAccept, this, new_session,
+               boost::asio::placeholders::error));
+}
+
+/**
+ * Call back for boost acceptor.async_accept() to handle a new connection
+ * @param new_session a pointer to a session
+ * @param error error code if any occurred
+ */
+void SimulatorDaemonServer::handleAccept(
+    ConnectionSession::session_ptr new_session,
+    const boost::system::error_code& error) {
+       LOGD(SIM_DAEMON, "Entry");
+       if (!error) {
+               new_session->start();
+       }
+       startAccept();
+}
diff --git a/simulatordaemon/src/TABinaryManager/.cproject b/simulatordaemon/src/TABinaryManager/.cproject
new file mode 100755 (executable)
index 0000000..552414a
--- /dev/null
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1387057985">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1387057985" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1387057985" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1387057985." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.264151431" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1778433447" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
+                                                       <builder buildPath="${workspace_loc:/TABinaryManager}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1976083820" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.1741226582" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.2094013692" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
+                                                               <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1309992195" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.2020033622" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.include.paths.1391568520" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../include&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1279811077" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.504852593" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.3210225" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.exe.debug.option.debugging.level.868896617" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.include.paths.2088594785" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/../../include&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.282093250" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.890751619" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1964298696" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1512562246" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.1413692380" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1816631522" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.2135834575">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.2135834575" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.2135834575" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.exe.release.2135834575." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1536149188" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1704351775" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
+                                                       <builder buildPath="${workspace_loc:/TABinaryManager}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.442356954" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.826963037" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1117234295" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
+                                                               <option id="gnu.cpp.compiler.exe.release.option.optimization.level.1830312239" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.exe.release.option.debugging.level.531196860" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.30623186" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1772762467" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
+                                                               <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.539473700" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.exe.release.option.debugging.level.1592849836" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1355740397" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.111218786" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.66507244" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1436401063" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1935560556" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.2144352029" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="TABinaryManager.cdt.managedbuild.target.gnu.exe.1762861770" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1387057985;cdt.managedbuild.config.gnu.exe.debug.1387057985.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.504852593;cdt.managedbuild.tool.gnu.c.compiler.input.282093250">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.2135834575;cdt.managedbuild.config.gnu.exe.release.2135834575.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1117234295;cdt.managedbuild.tool.gnu.cpp.compiler.input.30623186">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1387057985;cdt.managedbuild.config.gnu.exe.debug.1387057985.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.2094013692;cdt.managedbuild.tool.gnu.cpp.compiler.input.1279811077">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.2135834575;cdt.managedbuild.config.gnu.exe.release.2135834575.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1772762467;cdt.managedbuild.tool.gnu.c.compiler.input.1355740397">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope"/>
+</cproject>
diff --git a/simulatordaemon/src/TABinaryManager/.project b/simulatordaemon/src/TABinaryManager/.project
new file mode 100755 (executable)
index 0000000..51cfe9c
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>TABinaryManager</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+       <linkedResources>
+               <link>
+                       <name>include</name>
+                       <type>2</type>
+                       <locationURI>virtual:/virtual</locationURI>
+               </link>
+               <link>
+                       <name>include/tee_command.h</name>
+                       <type>1</type>
+                       <locationURI>PARENT-2-PROJECT_LOC/include/tee_command.h</locationURI>
+               </link>
+               <link>
+                       <name>include/tee_internal_api.h</name>
+                       <type>1</type>
+                       <locationURI>PARENT-2-PROJECT_LOC/include/tee_internal_api.h</locationURI>
+               </link>
+               <link>
+                       <name>include/tee_sim_command.h</name>
+                       <type>1</type>
+                       <locationURI>PARENT-2-PROJECT_LOC/include/tee_sim_command.h</locationURI>
+               </link>
+               <link>
+                       <name>include/tee_client_api.h</name>
+                       <type>1</type>
+                       <locationURI>PARENT-2-PROJECT_LOC/include/tee_client_api.h</locationURI>
+               </link>
+               <link>
+                       <name>include/teec_data.h</name>
+                       <type>1</type>
+                       <locationURI>PARENT-2-PROJECT_LOC/include/teec_data.h</locationURI>
+               </link>
+               <link>
+                       <name>include/teestub_command_data.h</name>
+                       <type>1</type>
+                       <locationURI>PARENT-2-PROJECT_LOC/include/teestub_command_data.h</locationURI>
+               </link>
+       </linkedResources>
+</projectDescription>
diff --git a/simulatordaemon/src/TABinaryManager/Config.h b/simulatordaemon/src/TABinaryManager/Config.h
new file mode 100755 (executable)
index 0000000..110e0bd
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  Config.h
+ *
+ *    Description:  Configuration details
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define TA_STORE_PATH "/tmp/tastore/"
+#define TA_UUID_LIST_PATH "/tmp/tastore/uuidlist.list"
+
+#endif /* CONFIG_H_ */
diff --git a/simulatordaemon/src/TABinaryManager/Debug/TABinaryManager b/simulatordaemon/src/TABinaryManager/Debug/TABinaryManager
new file mode 100755 (executable)
index 0000000..27a5b72
Binary files /dev/null and b/simulatordaemon/src/TABinaryManager/Debug/TABinaryManager differ
diff --git a/simulatordaemon/src/TABinaryManager/Debug/TABinaryManager.d b/simulatordaemon/src/TABinaryManager/Debug/TABinaryManager.d
new file mode 100755 (executable)
index 0000000..93160c3
--- /dev/null
@@ -0,0 +1,13 @@
+TABinaryManager.d: ../TABinaryManager.cpp ../TABinaryManager.h \
+ ../TAManifest.h ../TAUnpack.h ../Config.h \
+ /home/krishna/TASDKCode/Simulator/TABinaryManager/TABinaryManager/../../include/tee_internal_api.h
+
+../TABinaryManager.h:
+
+../TAManifest.h:
+
+../TAUnpack.h:
+
+../Config.h:
+
+/home/krishna/TASDKCode/Simulator/TABinaryManager/TABinaryManager/../../include/tee_internal_api.h:
diff --git a/simulatordaemon/src/TABinaryManager/Debug/TAManifest.d b/simulatordaemon/src/TABinaryManager/Debug/TAManifest.d
new file mode 100755 (executable)
index 0000000..aed1eaa
--- /dev/null
@@ -0,0 +1,10 @@
+TAManifest.d: ../TAManifest.cpp ../TAManifest.h ../rapidxml/rapidxml.hpp \
+ ../rapidxml/rapidxml_utils.hpp ../rapidxml/rapidxml.hpp
+
+../TAManifest.h:
+
+../rapidxml/rapidxml.hpp:
+
+../rapidxml/rapidxml_utils.hpp:
+
+../rapidxml/rapidxml.hpp:
diff --git a/simulatordaemon/src/TABinaryManager/Debug/TAUnpack.d b/simulatordaemon/src/TABinaryManager/Debug/TAUnpack.d
new file mode 100755 (executable)
index 0000000..3c6b7be
--- /dev/null
@@ -0,0 +1,3 @@
+TAUnpack.d: ../TAUnpack.cpp ../TAUnpack.h
+
+../TAUnpack.h:
diff --git a/simulatordaemon/src/TABinaryManager/Debug/TestMain.d b/simulatordaemon/src/TABinaryManager/Debug/TestMain.d
new file mode 100755 (executable)
index 0000000..9f653a9
--- /dev/null
@@ -0,0 +1,13 @@
+TestMain.d: ../TestMain.cpp ../TABinaryManager.h ../TAManifest.h \
+ ../TAUnpack.h ../Config.h \
+ /home/krishna/TASDKCode/Simulator/TABinaryManager/TABinaryManager/../../include/tee_internal_api.h
+
+../TABinaryManager.h:
+
+../TAManifest.h:
+
+../TAUnpack.h:
+
+../Config.h:
+
+/home/krishna/TASDKCode/Simulator/TABinaryManager/TABinaryManager/../../include/tee_internal_api.h:
diff --git a/simulatordaemon/src/TABinaryManager/Debug/makefile b/simulatordaemon/src/TABinaryManager/Debug/makefile
new file mode 100755 (executable)
index 0000000..70390a8
--- /dev/null
@@ -0,0 +1,58 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+-include ../makefile.init
+
+RM := rm -rf
+
+# All of the sources participating in the build are defined here
+-include sources.mk
+-include subdir.mk
+-include objects.mk
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(strip $(CC_DEPS)),)
+-include $(CC_DEPS)
+endif
+ifneq ($(strip $(C++_DEPS)),)
+-include $(C++_DEPS)
+endif
+ifneq ($(strip $(C_UPPER_DEPS)),)
+-include $(C_UPPER_DEPS)
+endif
+ifneq ($(strip $(CXX_DEPS)),)
+-include $(CXX_DEPS)
+endif
+ifneq ($(strip $(CPP_DEPS)),)
+-include $(CPP_DEPS)
+endif
+ifneq ($(strip $(C_DEPS)),)
+-include $(C_DEPS)
+endif
+endif
+
+-include ../makefile.defs
+
+# Add inputs and outputs from these tool invocations to the build variables 
+
+# All Target
+all: TABinaryManager
+
+# Tool invocations
+TABinaryManager: $(OBJS) $(USER_OBJS)
+       @echo 'Building target: $@'
+       @echo 'Invoking: GCC C++ Linker'
+       g++  -o "TABinaryManager" $(OBJS) $(USER_OBJS) $(LIBS)
+       @echo 'Finished building target: $@'
+       @echo ' '
+
+# Other Targets
+clean:
+       -$(RM) $(CC_DEPS)$(C++_DEPS)$(EXECUTABLES)$(C_UPPER_DEPS)$(CXX_DEPS)$(OBJS)$(CPP_DEPS)$(C_DEPS) TABinaryManager
+       -@echo ' '
+
+.PHONY: all clean dependents
+.SECONDARY:
+
+-include ../makefile.targets
diff --git a/simulatordaemon/src/TABinaryManager/Debug/objects.mk b/simulatordaemon/src/TABinaryManager/Debug/objects.mk
new file mode 100755 (executable)
index 0000000..742c2da
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
diff --git a/simulatordaemon/src/TABinaryManager/Debug/sources.mk b/simulatordaemon/src/TABinaryManager/Debug/sources.mk
new file mode 100755 (executable)
index 0000000..a7f166f
--- /dev/null
@@ -0,0 +1,27 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+C_UPPER_SRCS := 
+CXX_SRCS := 
+C++_SRCS := 
+OBJ_SRCS := 
+CC_SRCS := 
+ASM_SRCS := 
+CPP_SRCS := 
+C_SRCS := 
+O_SRCS := 
+S_UPPER_SRCS := 
+CC_DEPS := 
+C++_DEPS := 
+EXECUTABLES := 
+C_UPPER_DEPS := 
+CXX_DEPS := 
+OBJS := 
+CPP_DEPS := 
+C_DEPS := 
+
+# Every subdirectory with source files must be described here
+SUBDIRS := \
+. \
+
diff --git a/simulatordaemon/src/TABinaryManager/Debug/subdir.mk b/simulatordaemon/src/TABinaryManager/Debug/subdir.mk
new file mode 100755 (executable)
index 0000000..8160197
--- /dev/null
@@ -0,0 +1,33 @@
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+# Add inputs and outputs from these tool invocations to the build variables 
+CPP_SRCS += \
+../TABinaryManager.cpp \
+../TAManifest.cpp \
+../TAUnpack.cpp \
+../TestMain.cpp 
+
+OBJS += \
+./TABinaryManager.o \
+./TAManifest.o \
+./TAUnpack.o \
+./TestMain.o 
+
+CPP_DEPS += \
+./TABinaryManager.d \
+./TAManifest.d \
+./TAUnpack.d \
+./TestMain.d 
+
+
+# Each subdirectory must supply rules for building sources it contributes
+%.o: ../%.cpp
+       @echo 'Building file: $<'
+       @echo 'Invoking: GCC C++ Compiler'
+       g++ -I"/home/krishna/TASDKCode/Simulator/TABinaryManager/TABinaryManager/../../include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
+       @echo 'Finished building: $<'
+       @echo ' '
+
+
diff --git a/simulatordaemon/src/TABinaryManager/TABinaryManager.cpp b/simulatordaemon/src/TABinaryManager/TABinaryManager.cpp
new file mode 100755 (executable)
index 0000000..7c15c5a
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TABinaryManager.cpp
+ *
+ *    Description:  TABinaryManager class
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TABinaryManager.h"
+#include <iostream>
+#include <fstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <algorithm>
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+TABinaryManager *TABinaryManager::instance = NULL;
+pthread_rwlock_t binaryMapLock;
+map<string, StructBinaryInfo> binaryMap;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Checks if a characters is part of base64 encoding character set
+ * @param c character to be verified
+ * @return true if conformant to base64 charset else false
+ */
+bool TABinaryManager::is_base64(unsigned char c) {
+       return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+/**
+ * Thanks to: René Nyffenegger
+ * Reused from: http://www.adp-gmbh.ch/cpp/common/base64.html
+ * License Notice:
+ * Copyright (C) 2004-2008 René Nyffenegger
+ *
+ *  This source code is provided 'as-is', without any express or implied
+ *  warranty. In no event will the author be held liable for any damages
+ *  arising from the use of this software.
+ *
+ *  Permission is granted to anyone to use this software for any purpose,
+ *  including commercial applications, and to alter it and redistribute it
+ *  freely, subject to the following restrictions:
+ *
+ *  1. The origin of this source code must not be misrepresented; you must not
+ *     claim that you wrote the original source code. If you use this source code
+ *     in a product, an acknowledgment in the product documentation would be
+ *     appreciated but is not required.
+ *
+ *  2. Altered source versions must be plainly marked as such, and must not be
+ *     misrepresented as being the original source code.
+ *
+ *  3. This notice may not be removed or altered from any source distribution.
+ *
+ *  René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+ *
+ * @param encoded_string
+ * @return
+ */
+string TABinaryManager::base64_decode(std::string const& encoded_string) {
+       int in_len = encoded_string.size();
+       int i = 0;
+       int j = 0;
+       int in_ = 0;
+       unsigned char char_array_4[4], char_array_3[3];
+       std::string ret;
+
+       while (in_len-- && (encoded_string[in_] != '=')
+           && is_base64(encoded_string[in_])) {
+               char_array_4[i++] = encoded_string[in_];
+               in_++;
+               if (i == 4) {
+                       for (i = 0; i < 4; i++)
+                               char_array_4[i] = base64_chars.find(char_array_4[i]);
+                       char_array_3[0] = (char_array_4[0] << 2)
+                           + ((char_array_4[1] & 0x30) >> 4);
+                       char_array_3[1] = ((char_array_4[1] & 0xf) << 4)
+                           + ((char_array_4[2] & 0x3c) >> 2);
+                       char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+                       for (i = 0; (i < 3); i++)
+                               ret += char_array_3[i];
+                       i = 0;
+               }
+       }
+       if (i) {
+               for (j = i; j < 4; j++)
+                       char_array_4[j] = 0;
+               for (j = 0; j < 4; j++)
+                       char_array_4[j] = base64_chars.find(char_array_4[j]);
+               char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+               char_array_3[1] = ((char_array_4[1] & 0xf) << 4)
+                   + ((char_array_4[2] & 0x3c) >> 2);
+               char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+               for (j = 0; (j < i - 1); j++)
+                       ret += char_array_3[j];
+       }
+       return ret;
+}
+
+
+/**
+ * This is the constructor of TABinaryManger.
+ */
+TABinaryManager::TABinaryManager() {
+       //Stat for mod time
+
+       /// Constant charset of base64 encoding
+       base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                       "abcdefghijklmnopqrstuvwxyz"
+                       "0123456789+/";
+
+       struct stat attr;
+       if (stat(TA_UUID_LIST_PATH, &attr) == -1) {
+               LOGE(SIM_DAEMON, "stat FAILED %d", errno);
+       }
+       lastModTimeUUIDList = attr.st_mtime;
+       pthread_rwlock_init(&binaryMapLock, NULL);
+       pthread_mutex_init(&taLock, NULL);
+}
+
+/**
+ * This function returns the TA Binary Manager instance if already created
+ * else creates the instance and returns it
+ */
+TABinaryManager* TABinaryManager::getInstance() {
+       if (NULL == instance) {
+           try {
+                   instance = new TABinaryManager();
+               }catch (std::bad_alloc &ba) {
+                   return NULL;
+           }
+       }
+       return instance;
+}
+
+/**
+ * This function reads UUID list file and unpacks files to their respective
+ * locations.
+ * @return On successful completion of above operations returns true else false.
+ * It is very important to check for return value from this function.
+ */
+bool TABinaryManager::readUUIDList() {
+       LOGD(SIM_DAEMON, "");
+       string line;
+       struct flock fl = {F_RDLCK, SEEK_SET, 0, 0, 0};
+
+       fl.l_pid = getpid();
+
+       // Open file
+       int fd = open(TA_UUID_LIST_PATH, O_RDONLY);
+
+       if (fd == -1) return false;
+       FILE *fp = fdopen(fd, "r");
+       if (fcntl(fd, F_SETLKW, &fl) == -1) {
+               perror("fcntl");
+               fclose(fp);
+               return false;
+       }
+       pthread_rwlock_wrlock(&binaryMapLock);
+
+       //wh
+       std::ifstream uuidFileStream(TA_UUID_LIST_PATH);
+       std::string str;
+       if(uuidFileStream) {
+               getline(uuidFileStream, str);
+               line = line + str;
+       }
+       
+       /*
+       int ch = fgetc(fp);
+       while ((ch != '\n') && (ch != EOF)) {
+               line = line + ch;
+               ch = fgetc(fp);
+       }*/
+       
+       while (line != "") {
+               line = line + "\0";
+               StructBinaryInfo info;
+
+               char* data = (char*)OsaMalloc((strlen(line.c_str()) + 1) * sizeof(char));
+               char* uuid_data;
+               strncpy(data, line.c_str(), (strlen(line.c_str()) + 1) * sizeof(char));
+               uuid_data = strtok(data, ",");
+               const string uuid(data);
+               if (uuid_data != NULL) {
+                       char* port_data;
+                       port_data = strtok(NULL, ",");
+                       if (port_data != NULL) {
+                               string port(port_data);
+                               info.port = port;
+                       } else info.port = "";
+               }
+               //cout << "UUID: " << uuid << endl;
+               //cout << "port: " << info.port << endl;
+               // Open file
+               FILE *fpTA=fopen((string(TA_STORE_PATH) + "ta.tmp").c_str(),"r+");
+               if (flock(fileno(fpTA),LOCK_EX) != 0) { // do an exclusive lock
+                   LOGE(SIM_DAEMON, "Failed to lock the file");
+               }
+               pthread_mutex_lock(&taLock);
+               if (unpackBinary(uuid, info)) {
+                       binaryMap[uuid] = info;
+               }
+               pthread_mutex_unlock(&taLock);
+               if (flock(fileno(fpTA),LOCK_UN) != 0) {
+                   LOGE(SIM_DAEMON, "Failed to unlock the file");
+               }
+               fclose(fpTA);
+               OsaFree(data);
+
+               line = "";
+
+               if(uuidFileStream) {
+                       getline(uuidFileStream, str);
+                       line = line + str;      
+               }
+
+               /*
+               ch = fgetc(fp);
+               while ((ch != '\n') && (ch != EOF)) {
+                       line = line + ch;
+                       ch = fgetc(fp);
+               }*/
+
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       fl.l_type = F_UNLCK;
+       if (fcntl(fd, F_SETLKW, &fl) == -1) {
+               perror("fcntl");
+               fclose(fp);
+               return false;
+       }
+       if(uuidFileStream)
+               uuidFileStream.close();
+       fclose(fp);
+       return true;
+}
+
+/**
+ * This function decrypts the TA Binary image
+ * @param uuid TA UUID in string format
+ * @param info TA Binary info
+ */
+void TABinaryManager::decryptImage(StructBinaryInfo& info) {
+       string cipher = "-aes-256-cbc";
+       string secret = base64_decode (info.manifest.taencryption.model.plainkeydata);
+       string keyhashFilename = info.imagePath + ".keyhash";
+       secret.erase(secret.size()-2);
+       string keyHash = "echo -n " + secret + " | openssl dgst -sha256 | awk '{print $2}' > " + keyhashFilename;
+       cout << keyHash << endl;
+       system(keyHash.c_str());
+
+       string line;
+       ifstream myfile(keyhashFilename.c_str());
+       if (myfile.is_open()) {
+               getline(myfile, line);
+               //cout << "line " << line << endl;
+               myfile.close();
+       }
+    
+    // hash of Keydata is not required.
+       string dec_command = "openssl enc " + cipher + " -d -nopad -nosalt -K " + secret
+           + " -in " + info.imagePath + " -out " + info.imagePath
+           + "_dec -iv 0000000000000000";
+       //std::cout << dec_command << std::endl;
+       system(dec_command.c_str());
+       string removeEncImage = "rm -f " + info.imagePath;
+       //std::cout << removeEncImage << std::endl;
+       system(removeEncImage.c_str());
+       string renameDecImage = "mv " + info.imagePath + "_dec " + info.imagePath;
+       //std::cout << renameDecImage << std::endl;
+       system(renameDecImage.c_str());
+       string removeKeyHash = "rm -f " + keyhashFilename;
+       //std::cout << removeEncImage << std::endl;
+       system(removeKeyHash.c_str());
+}
+
+/**
+ * This function reads unpacks files to their respective locations.
+ * It also reads manifest file and keeps it ready for queries on fields
+ * in manifest.
+ * @param uuid TA UUID in string format
+ * @param info TA Binary info
+ * @return On successful completion of above operations returns true else false.
+ * It is very important to check for return value from this function.
+ */
+bool TABinaryManager::unpackBinary(const string &uuid, StructBinaryInfo& info) {
+       TAUnpack* unpacker = TAUnpack::getInstance();
+       bool ret = false;
+       LOGE(SIM_DAEMON, "");
+       if (0 == unpacker->unpackTA(string(TA_STORE_PATH), uuid)) {
+               // 1. Set binary info
+               info.path = string(TA_STORE_PATH) + uuid;
+               info.extractpath = string(TA_STORE_PATH) + uuid + "-ext/";
+               info.imagePath = info.extractpath + uuid + ".image";
+               info.manifestPath = info.extractpath + uuid + ".manifest";
+               // 2. Parse manifest and store results
+               info.manifest.processXML(info.manifestPath);
+               // 3. Decrypt image using secret value in manifest
+               if (info.manifest.properties.extension.launchMode == "debug")
+                 decryptImage(info);
+
+               string s = "chmod +x " + info.imagePath;
+               system(s.c_str());
+
+               ret = true;
+       }
+       return ret;
+}
+
+/**
+ * This is the main function of TABinaryManger. This function reads UUID list file
+ * and unpacks files to their respective locations. It also reads manifest file and
+ * keeps it ready for queries on fields in manifest.
+ * @return On successful completion of above operations returns true else false.
+ * It is very important to check for return value from this function.
+ */
+bool TABinaryManager::initBinaryManager() {
+       LOGD(SIM_DAEMON, "");
+       return readUUIDList();
+}
+
+/**
+ * Check if TA is single instance
+ * @param[in] uuid UUID of TA
+ * @param[out] isSingleInstance returns value from this parameter.
+ * @return -1 if uuid is not found else on success 0
+ */
+
+int TABinaryManager::isSingleInstance(string uuid, bool &SingleInstance) {
+       checkUUIDUpdate();
+       pthread_rwlock_wrlock(&binaryMapLock);
+       map<string, StructBinaryInfo>::iterator it = binaryMap.find(uuid);
+       StructBinaryInfo value;
+       int ret = -1;
+       if (it != binaryMap.end()) {
+               //element found;
+               value = it->second;
+               ret = 0;
+               SingleInstance = value.manifest.properties.general.singleInstance;
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       return ret;
+}
+
+/**
+ * Check if TA is KeepAlive
+ * @param[in] uuid UUID of TA
+ * @param[out] isKeepAlive returns value from this parameter.
+ * @return -1 if uuid is not found else on success 0
+ */
+
+int TABinaryManager::isKeepAlive(string uuid, bool &KeepAlive) {
+       checkUUIDUpdate();
+       pthread_rwlock_wrlock(&binaryMapLock);
+       map<string, StructBinaryInfo>::iterator it = binaryMap.find(uuid);
+       StructBinaryInfo value;
+       int ret = -1;
+       if (it != binaryMap.end()) {
+               //element found;
+               value = it->second;
+               ret = 0;
+               KeepAlive = value.manifest.properties.general.instanceKeepAlive;
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       return ret;
+}
+
+/**
+ * Check if TA is multi instance type
+ * @param[in] uuid UUID of TA
+ * @param[out] isMultipleSession returns value from this parameter.
+ * @return -1 if uuid is not found else on success 0
+ */
+int TABinaryManager::isMultipleSession(string uuid, bool &MultipleSession) {
+       checkUUIDUpdate();
+       pthread_rwlock_wrlock(&binaryMapLock);
+       map<string, StructBinaryInfo>::iterator it = binaryMap.find(uuid);
+       StructBinaryInfo value;
+       int ret = -1;
+       if (it != binaryMap.end()) {
+               //element found;
+               value = it->second;
+               ret = 0;
+               MultipleSession = value.manifest.properties.general.multiSession;
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       return ret;
+}
+
+/**
+ * Get TA executable image path
+ * @param uuid UUID of TA
+ * @return Empty string if UUID doesn't exist, else path to TA
+ */
+string TABinaryManager::getImagePath(string uuid) {
+       checkUUIDUpdate();
+       pthread_rwlock_wrlock(&binaryMapLock);
+       map<string, StructBinaryInfo>::iterator it = binaryMap.find(uuid);
+       StructBinaryInfo value;
+       string ret = "";
+       if (it != binaryMap.end()) {
+               //element found;
+               value = it->second;
+               ret = value.imagePath;
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       return ret;
+}
+
+/**
+ * Constant to TA Manifest object
+ * @param uuid UUID of TA
+ * @return NULL pointer if
+ */
+const TAManifest* TABinaryManager::getManifest(string uuid) {
+       checkUUIDUpdate();
+       pthread_rwlock_wrlock(&binaryMapLock);
+       map<string, StructBinaryInfo>::iterator it = binaryMap.find(uuid);
+       TAManifest *returnValue = NULL;
+       if (it != binaryMap.end()) {
+               //element found;
+               returnValue = &(it->second.manifest);
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       return returnValue;
+}
+
+/**
+ * Constant to port string
+ * @param uuid UUID of TA
+ * @return NULL pointer if
+ */
+string TABinaryManager::getPort(string uuid) {
+       pthread_rwlock_wrlock(&binaryMapLock);
+       map<string, StructBinaryInfo>::iterator it = binaryMap.find(uuid);
+       string returnValue = "";
+       if (it != binaryMap.end()) {
+               returnValue = it->second.port;
+       }
+       pthread_rwlock_unlock(&binaryMapLock);
+       return returnValue;
+}
+
+/**
+ * Converts UUID from TEEC_UUID to a string
+ * @return string of TEEC_UUID
+ */
+string TABinaryManager::getUUIDAsString(TEEC_UUID uuid) {
+       checkUUIDUpdate();
+       // E.g. returns a string in the format 79B7778897894a7aA2BEB60155EEF5F3
+       std::stringstream strStream;
+       strStream << IntToHex(uuid.timeLow);
+       strStream << IntToHex(uuid.timeMid);
+       strStream << IntToHex(uuid.timeHiAndVersion);
+       for (int i = 0; i < 8; i++) {
+               strStream << IntToHex((short)uuid.clockSeqAndNode[i], 2);
+       }
+       return strStream.str();
+}
+
+/**
+ * This function checks for UUID update and reads the list in case of update
+ */
+void TABinaryManager::checkUUIDUpdate() {
+       struct stat attr;
+       if (stat(TA_UUID_LIST_PATH, &attr) == -1) {
+               LOGE(SIM_DAEMON, "stat FAILED");
+               return;
+       }
+       if (lastModTimeUUIDList != attr.st_mtime) {
+               readUUIDList();
+               if (stat(TA_UUID_LIST_PATH, &attr) == -1) {
+                       LOGE(SIM_DAEMON, "stat FAILED");
+                       return;
+               }
+               lastModTimeUUIDList = attr.st_mtime;
+       }
+}
+
+TABinaryManager::~TABinaryManager() {
+       pthread_rwlock_destroy(&binaryMapLock);
+       pthread_mutex_destroy(&taLock);
+       delete instance;
+}
diff --git a/simulatordaemon/src/TABinaryManager/TABinaryManager.h b/simulatordaemon/src/TABinaryManager/TABinaryManager.h
new file mode 100755 (executable)
index 0000000..00cfb90
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TABinaryManager.h
+ *
+ *    Description:  TABinaryManager header file
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TABINARYMANAGER_H_
+#define TABINARYMANAGER_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <string>
+#include <string.h>
+#include <map>
+#include <sstream>
+#include <iomanip>
+#include <fcntl.h>
+#include "log.h"
+#include "OsaLinuxUser.h"
+#include "tee_client_api.h"
+#include "TAManifest.h"
+#include "TAUnpack.h"
+#include "Config.h"
+#include "tee_internal_api.h"
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+typedef struct {
+       string path;
+       string extractpath;
+       string imagePath;
+       string manifestPath;
+       TAManifest manifest;
+       string port;
+} StructBinaryInfo;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class TABinaryManager {
+
+private:
+       static TABinaryManager *instance;
+       std::string base64_chars;
+       // map < string uuid, StructBinaryInfo>
+       map<string, StructBinaryInfo> binaryMap;
+       time_t lastModTimeUUIDList;
+       TABinaryManager();
+       bool readUUIDList();
+       bool unpackBinary(const string &uuid, StructBinaryInfo& info);
+       template<typename T>
+       std::string IntToHex(T i, int width = sizeof(T) * 2) {
+               std::stringstream stream;
+               stream << std::setfill('0') << std::setw(width) << std::hex << i;
+               return stream.str();
+       }
+       void checkUUIDUpdate();
+       void decryptImage(StructBinaryInfo& info);
+       string base64_decode(std::string const& encoded_string);
+       bool is_base64(unsigned char c);
+public:
+       /**
+        * Gets pointer to singleton instance of TABinaryManager.
+        * Perform lazy creation of TABinaryManager. During lazy init,
+        * it also performs init of TABinaryManager where if UUID list XML is
+        * not readable then getInstance fails.
+        * @return Pointer to instance on successful initialization.
+        * Else null pointer on error
+        */
+       pthread_mutex_t taLock;
+       static TABinaryManager* getInstance();
+       bool initBinaryManager();
+
+       /*
+        * Query functions on Binary Manager
+        */
+       int isSingleInstance(string uuid, bool &SingleInstance);
+       int isMultipleSession(string uuid, bool &MultipleSession);
+       string getImagePath(string uuid);
+       const TAManifest* getManifest(string uuid);
+       string getUUIDAsString(TEEC_UUID uuid);
+       string getPort(string uuid);
+       int isKeepAlive(string uuid, bool &KeepAlive);
+
+       virtual ~TABinaryManager();
+};
+
+#endif /* TABINARYMANAGER_H_ */
diff --git a/simulatordaemon/src/TABinaryManager/TAManifest.cpp b/simulatordaemon/src/TABinaryManager/TAManifest.cpp
new file mode 100755 (executable)
index 0000000..ae14cbe
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAManifest.cpp
+ *
+ *    Description:  TAManifest class
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TAManifest.h"
+#include "rapidxml/rapidxml.hpp"
+#include "rapidxml/rapidxml_utils.hpp"
+#include <sstream>
+#include <iostream>
+
+using namespace rapidxml;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+
+TAManifest::TAManifest() {
+
+}
+
+bool TAManifest::processXML(const string &xmlManifestPath) {
+
+       bool ret = false;
+       // Open file
+       std::ifstream xmlfile(xmlManifestPath.c_str());
+       std::stringstream buffer;
+       buffer << xmlfile.rdbuf();
+       xmlfile.close();
+       std::string content(buffer.str());
+       //cout << content << endl;
+       // Create xml DOM
+       xml_document<> doc;
+       // Parse XML from file and populate doc
+       doc.parse<0>((char*)content.c_str());
+       try {
+               // 1. PROPERTIES
+               xml_node<> *node = doc.first_node("manifest")->first_node("properties");
+               {
+                       stringstream sstream;
+                       // GENERAL
+                       xml_node<> *propertiesGeneral = node->first_node("general");
+                       properties.general.appID = string(
+                           propertiesGeneral->first_attribute("appID")->value());
+                       properties.general.singleInstance =
+                           string(propertiesGeneral->first_attribute("singleInstance")->value())
+                               .compare("true") == 0 ? true : false;
+                       properties.general.multiSession =
+                           string(propertiesGeneral->first_attribute("multiSession")->value())
+                               .compare("true") == 0 ? true : false;
+                       properties.general.instanceKeepAlive =
+                           string(
+                               propertiesGeneral->first_attribute("instanceKeepAlive")->value())
+                               .compare("true") == 0 ? true : false;
+
+                       sstream.clear();
+                       sstream.str(
+                           string(propertiesGeneral->first_attribute("stackSize")->value()));
+                       sstream >> properties.general.stackSize;
+
+                       sstream.clear();
+                       sstream.str(
+                           string(propertiesGeneral->first_attribute("dataSize")->value()));
+                       sstream >> properties.general.dataSize;
+                       // EXTENSION
+                       xml_node<> *propertiesExtension = node->first_node("extension");
+                       properties.extension.appName = string(
+                           propertiesExtension->first_attribute("appName")->value());
+                       properties.extension.appVersion = string(
+                           propertiesExtension->first_attribute("appVersion")->value());
+                       /*properties.extension.type = string(
+                           propertiesExtension->first_attribute("type")->value());
+                       properties.extension.zone = string(
+                           propertiesExtension->first_attribute("zone")->value());*/
+                       properties.extension.sdkVersion = string(
+                           propertiesExtension->first_attribute("sdkVersion")->value());
+                       // Removed, taEncrypion flag used now
+                       //properties.extension.secret = string(
+                       //    propertiesExtension->first_attribute("secret")->value());
+                       properties.extension.launchMode = string(
+                           propertiesExtension->first_attribute("launchMode")->value());
+
+               }
+               // 2. POLICY
+               node = doc.first_node("manifest")->first_node("policy");
+               {
+                       // PRIVILEGE
+                       xml_node<> *policyPrivilege = node->first_node("privilege");
+                       policy.privilegeName = string(
+                           policyPrivilege->first_attribute("name")->value());
+                       // PROTECTION DOMAIN
+                       xml_node<> *policyProtectionDomain = node->first_node("protectionDomain");
+                       policy.protectionDomain.createDomain = string(
+                           policyProtectionDomain->first_node("createDomain")->first_attribute(
+                               "name")->value());
+                       policy.protectionDomain.allowedDomain = string(
+                           policyProtectionDomain->first_node("allowedDomain")->first_attribute(
+                               "name")->value());
+                       // PERMISSION - vector
+                       xml_node<> *policyPermission = node->first_node("permission");
+                       for (xml_node<> *childnode = policyPermission->first_node(
+                           "uses-permission"); childnode; childnode =
+                           childnode->next_sibling()) {
+                               //std::cout << "[SIM_DAEMON] Permission vector: " << string(childnode->first_attribute("name")->value()) << endl;
+                               policy.usesPermission.push_back(
+                                   string(childnode->first_attribute("name")->value()));
+                       }
+               }
+               // 3. TA ENC
+               node = doc.first_node("manifest")->first_node("taEncryption");
+               {
+                       // MODEL
+                       xml_node<> *model = node->first_node("model");
+                       taencryption.model.modelName = string(
+                               model->first_node("modelName")->first_attribute("value")->value());
+                       taencryption.model.plainkeydata =  string(
+                                       model->first_node("plainkeydata")->first_attribute("value")->value());
+               }
+               // 4. INFORMATION
+               node = doc.first_node("manifest")->first_node("information");
+               {
+                       information.description = string(
+                           node->first_node("description")->value());
+                       information.author = string(node->first_node("author")->value());
+                       information.terms = string(node->first_node("terms")->value());
+                       information.copyright = string(node->first_node("copyright")->value());
+
+               }
+               ret = true;
+       }
+       // Catch rapid xml errors
+       catch (rapidxml::parse_error &e) {
+               std::cout << "[SIM_DAEMON] RAPID_XML EXCEPTION" << e.what() << endl;
+       }
+       return ret;
+}
+
+// This is just for debug
+void TAManifest::printProcessedData() const {
+       std::cout << "[SIM_DAEMON] XML DUMP:" << endl;
+       std::cout << "[SIM_DAEMON] properties.general.appID: "
+           << properties.general.appID << endl;
+       std::cout << "[SIM_DAEMON] properties.general.dataSize: "
+           << properties.general.dataSize << endl;
+       std::cout << "[SIM_DAEMON] properties.general.instanceKeepAlive: "
+           << properties.general.instanceKeepAlive << endl;
+       std::cout << "[SIM_DAEMON] properties.general.multiSession: "
+           << properties.general.multiSession << endl;
+       std::cout << "[SIM_DAEMON] properties.general.singleInstance: "
+           << properties.general.singleInstance << endl;
+       std::cout << "[SIM_DAEMON] properties.general.stackSize: "
+           << properties.general.stackSize << endl << endl;
+
+       std::cout << "[SIM_DAEMON] properties.general.singleInstance: "
+           << properties.extension.appName << endl;
+       std::cout << "[SIM_DAEMON] properties.extension.appVersion: "
+           << properties.extension.appVersion << endl;
+       std::cout << "[SIM_DAEMON] properties.extension.launchMode: "
+           << properties.extension.launchMode << endl;
+       std::cout << "[SIM_DAEMON] properties.extension.sdkVersion: "
+           << properties.extension.sdkVersion << endl;
+       // REMOVED
+       //std::cout << "[SIM_DAEMON] properties.extension.secret: "
+       //    << properties.extension.secret << endl;
+       /*std::cout << "[SIM_DAEMON] properties.extension.type: "
+           << properties.extension.type << endl;
+       std::cout << "[SIM_DAEMON] properties.extension.zone: "
+           << properties.extension.zone << endl << endl;*/
+
+       std::cout << "[SIM_DAEMON] policy.privilegeName: " << policy.privilegeName
+           << endl;
+       std::cout << "[SIM_DAEMON] " << policy.protectionDomain.allowedDomain << endl;
+       std::cout << "[SIM_DAEMON] " << policy.protectionDomain.createDomain << endl;
+       for (unsigned int i = 0; i < policy.usesPermission.size(); i++) {
+               std::cout << "[SIM_DAEMON] \tpolicy.usesPermission: "
+                   << policy.usesPermission[i] << endl;
+       }
+       cout << endl;
+
+       std::cout << "[SIM_DAEMON] taencryption.model.modelName: " << taencryption.model.modelName
+                   << endl;
+       std::cout << "[SIM_DAEMON] taencryption.model.plainkeydata: " << taencryption.model.plainkeydata
+                           << endl;
+       std::cout << "[SIM_DAEMON] information.author: " << information.author
+           << endl;
+       std::cout << "[SIM_DAEMON] information.copyright: " << information.copyright
+           << endl;
+       std::cout << "[SIM_DAEMON] information.description: "
+           << information.description << endl;
+       std::cout << "[SIM_DAEMON] information.terms: " << information.terms << endl;
+
+}
+
+TAManifest::~TAManifest() {
+
+}
+
diff --git a/simulatordaemon/src/TABinaryManager/TAManifest.h b/simulatordaemon/src/TABinaryManager/TAManifest.h
new file mode 100755 (executable)
index 0000000..da7edcd
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAManifest.h
+ *
+ *    Description:  TAManifest header file
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TAMANIFEST_H_
+#define TAMANIFEST_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <string>
+#include <vector>
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+typedef struct {
+       string appID;
+       bool singleInstance;
+       bool multiSession;
+       bool instanceKeepAlive;
+       unsigned int stackSize;
+       unsigned int dataSize;
+} StructPropertiesGeneral;
+
+typedef struct {
+       string modelName;
+       string plainkeydata;
+} StructModel;
+
+typedef struct {
+       StructModel model;
+} StructTaEncryption;
+
+typedef struct {
+       string appName;
+       string appVersion;
+       //string type;
+       //string zone;
+       string sdkVersion;
+       //string secret; //Removed
+       string launchMode;
+} StructPropertiesExtension;
+
+
+
+typedef struct {
+       StructPropertiesGeneral general;
+       StructPropertiesExtension extension;
+} StructProperties;
+
+typedef struct {
+       string createDomain;
+       string allowedDomain;
+} StructPolicyProtectionDomain;
+
+typedef struct {
+       string privilegeName;
+       StructPolicyProtectionDomain protectionDomain;
+       vector<string> usesPermission;
+} StructPolicy;
+
+typedef struct {
+       string description;
+       string author;
+       string terms;
+       string copyright;
+} StructInformation;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+
+class TAManifest {
+
+public:
+       StructProperties properties;
+       StructPolicy policy;
+       StructTaEncryption taencryption;
+       StructInformation information;
+
+public:
+       TAManifest();
+       bool processXML(const string &xmlManifest);
+       void printProcessedData() const;
+       virtual ~TAManifest();
+
+};
+#endif /* TAMANIFEST_H_ */
diff --git a/simulatordaemon/src/TABinaryManager/TAUnpack.cpp b/simulatordaemon/src/TABinaryManager/TAUnpack.cpp
new file mode 100755 (executable)
index 0000000..26c3da9
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAUnpack.cpp
+ *
+ *    Description:  TAUnpack class
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TAUnpack.h"
+#include <iostream>
+#include <fstream>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <log.h>
+
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+TAUnpack *TAUnpack::instance = NULL;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+TAUnpack::TAUnpack() {
+
+}
+
+TAUnpack* TAUnpack::getInstance() {
+       if (instance == NULL) {
+               instance = new TAUnpack();
+       }
+       return instance;
+}
+
+/**
+ * Unpacks a TA from its package into header, image, manifest, cert and sign
+ * @param path path to directory where uuid is placed. path should end with trailing /
+ * @param uuid uuid of package
+ * @return -1 on error otherwise 0
+ */
+int TAUnpack::unpackTA(string path, string uuid) {
+       LOGD(SIM_DAEMON, "");
+       TAPackageHeaderV2 packageHeader;
+       memset(&packageHeader, 0, sizeof(TAPackageHeaderV2));
+       // Open file
+       string path_to_file = path + uuid;
+       ifstream tapackage(path_to_file.c_str(), ios::in | ios::binary);
+       // Create directory for UUID
+       string extract_dir_path = path + uuid + "-ext/";
+       struct stat info;
+       if (stat(extract_dir_path.c_str(), &info) != 0) {
+               if (0 != mkdir(extract_dir_path.c_str(), 0777)) {
+                       LOGE(SIM_DAEMON, "mkdir failed");
+                       return -1;
+               }
+       }
+
+       if (!tapackage.is_open()) {
+               LOGE(SIM_DAEMON, "Already open - failed");
+               return -1; //> unable to open file
+       }
+       // 1. Read header
+       tapackage.read((char*)&packageHeader, sizeof(TAPackageHeaderV2));
+       if (tapackage.fail()) {
+               LOGE(SIM_DAEMON, "Read failed");
+               return -1;
+       }
+       // fixHeaderEndianness(&packageHeader);
+       // 2. Verify header
+       if (SECURITY_HEADER_MAGIC1 == packageHeader.magic1 &&
+       SECURITY_HEADER_MAGIC2 == packageHeader.magic2) {
+               // 3. Read image and write to FS
+               tapackage.seekg(packageHeader.image_offset);
+               char *imagedump = new char[packageHeader.image_size];
+               tapackage.read(imagedump, packageHeader.image_size);
+               if (tapackage.fail()) {
+                       LOGE(SIM_DAEMON, "Read failed");
+                       return -1;
+               }
+               string removeImage = "rm -f " + extract_dir_path + uuid + ".image";
+               system(removeImage.c_str());
+               ofstream image((extract_dir_path + uuid + ".image").c_str(),
+                   ios::out | ios::binary);
+               ofstream manifest((extract_dir_path + uuid + ".manifest").c_str(),
+                   ios::out | ios::binary);
+               image.write(imagedump, packageHeader.image_size);
+               image.flush();
+               delete[] imagedump;
+
+               // 4. Read manifest and write to FS
+               tapackage.seekg(packageHeader.manifest_offset);
+               char *manifestdump = new char[packageHeader.manifest_size];
+               tapackage.read(manifestdump, packageHeader.manifest_size);
+               if (tapackage.fail()) {
+                       LOGE(SIM_DAEMON, "Read failed");
+                       return -1;
+               }
+               //manifest.write(manifestdump, sizeWithoutPadding(manifestdump, packageHeader.manifest_size));
+               manifest.write(manifestdump, packageHeader.manifest_size);
+               manifest.flush();
+               delete[] manifestdump;
+       } else {
+               LOGE(SIM_DAEMON, "Header verification failed");
+               return -1;
+       }
+
+       return 0;
+}
+
+void TAUnpack::fixHeaderEndianness(TAPackageHeaderV2* header) {
+
+       char* headerptr = (char*)header;
+       for (unsigned int i = 0; i < sizeof(TAPackageHeaderV2); i +=
+           sizeof(unsigned int)) {
+               char temp1 = headerptr[i];
+               char temp2 = headerptr[i + 1];
+               headerptr[i] = headerptr[i + 3];
+               headerptr[i + 1] = headerptr[i + 2];
+               headerptr[i + 3] = temp1;
+               headerptr[i + 2] = temp2;
+       }
+
+}
+
+/**
+ * Returns unpadded data size
+ * @param paddedData
+ * @param paddedSize
+ * @return size of unpadded data = padded data size - padding size
+ */
+unsigned int TAUnpack::sizeWithoutPadding(const char* paddedData,
+    unsigned int paddedSize) {
+
+       unsigned int paddingSize = 0;
+
+       for (unsigned int i = paddedSize - 1; (i > 0 && 0 == paddedData[i]); i--) {
+               paddingSize++;
+       }
+
+       return (paddedSize - paddingSize);
+}
+
+TAUnpack::~TAUnpack() {
+       delete instance;
+}
+
diff --git a/simulatordaemon/src/TABinaryManager/TAUnpack.h b/simulatordaemon/src/TABinaryManager/TAUnpack.h
new file mode 100755 (executable)
index 0000000..0602570
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAUnpack.h
+ *
+ *    Description:  TAUnpack header file
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef TAUNPACK_H_
+#define TAUNPACK_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <string>
+using namespace std;
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define PAGE_SIZE                              (1024)
+#define SECURITY_HEADER_MAGIC1 (0x736D6153)
+#define SECURITY_HEADER_MAGIC2 (0x2E676E75)
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+typedef struct {
+       unsigned int magic1;
+       unsigned int magic2;
+       unsigned int version;
+       unsigned int reserve;
+       unsigned int image_offset;
+       unsigned int image_size;
+       unsigned int sign_offset;
+       unsigned int sign_size;
+} TAPackageHeaderV1;
+
+typedef struct {
+       unsigned int magic1;
+       unsigned int magic2;
+       unsigned int version;
+       unsigned int reserve;
+       unsigned int image_offset;
+       unsigned int image_size;
+       unsigned int manifest_offset;
+       unsigned int manifest_size;
+       unsigned int cert_offset;
+       unsigned int cert_size;
+       unsigned int sign_offset;
+       unsigned int sign_size;
+} TAPackageHeaderV2;
+
+/*-----------------------------------------------------------------------------
+ *  Class definitions
+ *-----------------------------------------------------------------------------*/
+class TAUnpack {
+private:
+       TAUnpack();
+       static TAUnpack *instance;
+       void fixHeaderEndianness(TAPackageHeaderV2 *header);
+       unsigned int sizeWithoutPadding(const char* paddedData,
+           unsigned int paddedSize);
+public:
+       static TAUnpack* getInstance();
+       int unpackTA(string path, string uuid);
+       virtual ~TAUnpack();
+};
+
+#endif /* TAUNPACK_H_ */
diff --git a/simulatordaemon/src/TABinaryManager/TestMain.cpp b/simulatordaemon/src/TABinaryManager/TestMain.cpp
new file mode 100755 (executable)
index 0000000..5497925
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * TestMain.cpp
+ *
+ *  Created on: 05-May-2015
+ *      Author: krishna
+ */
+
+#include <stdio.h>
+#include <iostream>
+#include "TABinaryManager.h"
+#include "TAManifest.h"
+#include "TAUnpack.h"
+#include "Config.h"
+using namespace std;
+
+int test_main() {
+       int inp = 100;
+       std::cout << "[SIM_DAEMON] 0. Exit" << std::endl;
+       std::cout << "[SIM_DAEMON] 1. Unpack TA" << std::endl;
+       std::cout << "[SIM_DAEMON] 2. Process and display manifest" << std::endl;
+       std::cout << "[SIM_DAEMON] 3. Execute image" << std::endl;
+       cout
+           << "4. TA Binary Manager (Read UUID List, unpack all of the binaries, keep meta data ready)"
+           << std::endl;
+
+       try {
+               while (inp != 0) {
+                       std::cout << "[SIM_DAEMON] Enter Choice: " << std::endl;
+
+                       scanf("%d", &inp);
+
+                       switch (inp) {
+                               // Unpack TA
+                               case 1: {
+                                       TAUnpack *unpacker = TAUnpack::getInstance();
+                                       unpacker->unpackTA(TA_STORE_PATH, "0000-0000-0000-0000000000c7");
+                                       break;
+                               }
+                                       // Manifest test
+                               case 2: {
+                                       TAManifest manifest;
+                                       manifest.processXML(
+                                           string(
+                                               TA_STORE_PATH"0000-0000-0000-0000000000c7-ext/0000-0000-0000-0000000000c7.manifest"));
+                                       manifest.printProcessedData();
+                                       break;
+                               }
+                                       // Execute image
+                               case 3: {
+
+                                       break;
+                               }
+                                       // Test TA Binary Manager
+                               case 4: {
+                                       TABinaryManager *bm = TABinaryManager::getInstance();
+                                       if (bm->initBinaryManager()) {
+                                               std::cout << "[SIM_DAEMON] Binary Manager successfully initialized"
+                                                   << std::endl;
+                                               std::cout
+                                                   << "[SIM_DAEMON] Image Path of 0000-0000-0000-0000000000c7: "
+                                                   << bm->getImagePath("0000-0000-0000-0000000000c7") << std::endl;
+                                               std::cout
+                                                   << "[SIM_DAEMON] Image Path of 0000-0000-0000-0000001234d5: "
+                                                   << bm->getImagePath("0000-0000-0000-0000001234d5") << std::endl;
+                                               std::cout
+                                                   << "[SIM_DAEMON] Image Path of 0000-0000-0000-0000004567c8: "
+                                                   << bm->getImagePath("0000-0000-0000-0000004567c8") << std::endl;
+                                               bm->getManifest("0000-0000-0000-0000004567c8")->printProcessedData();
+
+                                       }
+                                       break;
+                               }
+
+                       }
+               }
+       } catch (std::exception& e) {
+               LOGE(SIM_DAEMON, "Exception: %s", e.what());
+       }
+       return 0;
+}
diff --git a/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml.hpp b/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml.hpp
new file mode 100755 (executable)
index 0000000..e3e8981
--- /dev/null
@@ -0,0 +1,2396 @@
+#ifndef RAPIDXML_HPP_INCLUDED
+#define RAPIDXML_HPP_INCLUDED
+
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+// Version 1.13
+// Revision $DateTime: 2009/05/13 01:46:17 $
+//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation
+
+// If standard library is disabled, user must provide implementations of required functions and typedefs
+#if !defined(RAPIDXML_NO_STDLIB)
+#include <cstdlib>      // For std::size_t
+#include <cassert>      // For assert
+#include <new>          // For placement new
+#endif
+
+// On MSVC, disable "conditional expression is constant" warning (level 4). 
+// This warning is almost impossible to avoid with certain types of templated code
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4127)   // Conditional expression is constant
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// RAPIDXML_PARSE_ERROR
+
+#if defined(RAPIDXML_NO_EXCEPTIONS)
+
+#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); }
+
+namespace rapidxml
+{
+       //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, 
+       //! this function is called to notify user about the error.
+       //! It must be defined by the user.
+       //! <br><br>
+       //! This function cannot return. If it does, the results are undefined.
+       //! <br><br>
+       //! A very simple definition might look like that:
+       //! <pre>
+       //! void %rapidxml::%parse_error_handler(const char *what, void *where)
+       //! {
+       //!     LOGD(SIM_DAEMON, "Parse error: %s", what);
+       //!     std::abort();
+       //! }
+       //! </pre>
+       //! \param what Human readable description of the error.
+       //! \param where Pointer to character data where error was detected.
+       void parse_error_handler(const char *what, void *where);
+}
+
+#else
+
+#include <exception>    // For std::exception
+
+#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
+
+namespace rapidxml {
+
+//! Parse error exception. 
+//! This exception is thrown by the parser when an error occurs. 
+//! Use what() function to get human-readable error message. 
+//! Use where() function to get a pointer to position within source text where error was detected.
+//! <br><br>
+//! If throwing exceptions by the parser is undesirable, 
+//! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included.
+//! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception.
+//! This function must be defined by the user.
+//! <br><br>
+//! This class derives from <code>std::exception</code> class.
+class parse_error:
+    public std::exception {
+
+public:
+
+       //! Constructs parse error
+       parse_error(const char *what, void *where) :
+                       m_what(what), m_where(where) {
+       }
+
+       //! Gets human readable description of error.
+       //! \return Pointer to null terminated description of the error.
+       virtual const char *what() const throw () {
+               return m_what;
+       }
+
+       //! Gets pointer to character data where error happened.
+       //! Ch should be the same as char type of xml_document that produced the error.
+       //! \return Pointer to location within the parsed string where error occured.
+       template<class Ch>
+       Ch *where() const {
+               return reinterpret_cast<Ch *>(m_where);
+       }
+
+private:
+
+       const char *m_what;
+       void *m_where;
+
+};
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// Pool sizes
+
+#ifndef RAPIDXML_STATIC_POOL_SIZE
+// Size of static memory block of memory_pool.
+// Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+// No dynamic memory allocations are performed by memory_pool until static memory is exhausted.
+#define RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef RAPIDXML_DYNAMIC_POOL_SIZE
+// Size of dynamic memory block of memory_pool.
+// Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+// After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.
+#define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef RAPIDXML_ALIGNMENT
+// Memory allocation alignment.
+// Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.
+// All memory allocations for nodes, attributes and strings will be aligned to this value.
+// This must be a power of 2 and at least 1, otherwise memory_pool will not work.
+#define RAPIDXML_ALIGNMENT sizeof(void *)
+#endif
+
+namespace rapidxml {
+// Forward declarations
+template<class Ch> class xml_node;
+template<class Ch> class xml_attribute;
+template<class Ch> class xml_document;
+
+//! Enumeration listing all node types produced by the parser.
+//! Use xml_node::type() function to query node type.
+enum node_type {
+       node_document,      //!< A document node. Name and value are empty.
+       node_element, //!< An element node. Name contains element name. Value contains text of first data node.
+       node_data,        //!< A data node. Name is empty. Value contains data text.
+       node_cdata,      //!< A CDATA node. Name is empty. Value contains data text.
+       node_comment, //!< A comment node. Name is empty. Value contains comment text.
+       node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
+       node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
+       node_pi   //!< A PI node. Name contains target. Value contains instructions.
+};
+
+///////////////////////////////////////////////////////////////////////
+// Parsing flags
+
+//! Parse flag instructing the parser to not create data nodes. 
+//! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_data_nodes = 0x1;
+
+//! Parse flag instructing the parser to not use text of first data node as a value of parent element.
+//! Can be combined with other flags by use of | operator.
+//! Note that child data nodes of element node take precendence over its value when printing. 
+//! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored.
+//! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_element_values = 0x2;
+
+//! Parse flag instructing the parser to not place zero terminators after strings in the source text.
+//! By default zero terminators are placed, modifying source text.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_string_terminators = 0x4;
+
+//! Parse flag instructing the parser to not translate entities in the source text.
+//! By default entities are translated, modifying source text.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_entity_translation = 0x8;
+
+//! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters.
+//! By default, UTF-8 handling is enabled.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_utf8 = 0x10;
+
+//! Parse flag instructing the parser to create XML declaration node.
+//! By default, declaration node is not created.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_declaration_node = 0x20;
+
+//! Parse flag instructing the parser to create comments nodes.
+//! By default, comment nodes are not created.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_comment_nodes = 0x40;
+
+//! Parse flag instructing the parser to create DOCTYPE node.
+//! By default, doctype node is not created.
+//! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_doctype_node = 0x80;
+
+//! Parse flag instructing the parser to create PI nodes.
+//! By default, PI nodes are not created.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_pi_nodes = 0x100;
+
+//! Parse flag instructing the parser to validate closing tag names. 
+//! If not set, name inside closing tag is irrelevant to the parser.
+//! By default, closing tags are not validated.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_validate_closing_tags = 0x200;
+
+//! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes.
+//! By default, whitespace is not trimmed. 
+//! This flag does not cause the parser to modify source text.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_trim_whitespace = 0x400;
+
+//! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character.
+//! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag.
+//! By default, whitespace is not normalized. 
+//! If this flag is specified, source text will be modified.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_normalize_whitespace = 0x800;
+
+// Compound flags
+
+//! Parse flags which represent default behaviour of the parser. 
+//! This is always equal to 0, so that all other flags can be simply ored together.
+//! Normally there is no need to inconveniently disable flags by anding with their negated (~) values.
+//! This also means that meaning of each flag is a <i>negation</i> of the default setting. 
+//! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default,
+//! and using the flag will disable it.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_default = 0;
+
+//! A combination of parse flags that forbids any modifications of the source text. 
+//! This also results in faster parsing. However, note that the following will occur:
+//! <ul>
+//! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li>
+//! <li>entities will not be translated</li>
+//! <li>whitespace will not be normalized</li>
+//! </ul>
+//! See xml_document::parse() function.
+const int parse_non_destructive = parse_no_string_terminators
+    | parse_no_entity_translation;
+
+//! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
+
+//! A combination of parse flags resulting in largest amount of data being extracted. 
+//! This usually results in slowest parsing.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_full = parse_declaration_node | parse_comment_nodes
+    | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
+
+///////////////////////////////////////////////////////////////////////
+// Internals
+
+//! \cond internal
+namespace internal {
+
+// Struct that contains lookup tables for the parser
+// It must be a template to allow correct linking (because it has static data members, which are defined in a header file).
+template<int Dummy>
+struct lookup_tables {
+       static const unsigned char lookup_whitespace[256];       // Whitespace table
+       static const unsigned char lookup_node_name[256];         // Node name table
+       static const unsigned char lookup_text[256];                   // Text table
+       static const unsigned char lookup_text_pure_no_ws[256];        // Text table
+       static const unsigned char lookup_text_pure_with_ws[256];      // Text table
+       static const unsigned char lookup_attribute_name[256]; // Attribute name table
+       static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote
+       static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote
+       static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes
+       static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes
+       static const unsigned char lookup_digits[256];                  // Digits
+       static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters
+};
+
+// Find length of the string
+template<class Ch>
+inline std::size_t measure(const Ch *p) {
+       const Ch *tmp = p;
+       while (*tmp)
+               ++tmp;
+       return tmp - p;
+}
+
+// Compare strings for equality
+template<class Ch>
+inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2,
+    std::size_t size2, bool case_sensitive) {
+       if (size1 != size2) return false;
+       if (case_sensitive) {
+               for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+                       if (*p1 != *p2) return false;
+       } else {
+               for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+                       if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)]
+                           != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
+                         return false;
+       }
+       return true;
+}
+}
+//! \endcond
+
+///////////////////////////////////////////////////////////////////////
+// Memory pool
+
+//! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation.
+//! In most cases, you will not need to use this class directly. 
+//! However, if you need to create nodes manually or modify names/values of nodes, 
+//! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. 
+//! Not only is this faster than allocating them by using <code>new</code> operator, 
+//! but also their lifetime will be tied to the lifetime of document, 
+//! possibly simplyfing memory management. 
+//! <br><br>
+//! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. 
+//! You can also call allocate_string() function to allocate strings.
+//! Such strings can then be used as names or values of nodes without worrying about their lifetime.
+//! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called, 
+//! or when the pool is destroyed.
+//! <br><br>
+//! It is also possible to create a standalone memory_pool, and use it 
+//! to allocate nodes, whose lifetime will not be tied to any document.
+//! <br><br>
+//! Pool maintains <code>RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory. 
+//! Until static memory is exhausted, no dynamic memory allocations are done.
+//! When static memory is exhausted, pool allocates additional blocks of memory of size <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> each,
+//! by using global <code>new[]</code> and <code>delete[]</code> operators. 
+//! This behaviour can be changed by setting custom allocation routines. 
+//! Use set_allocator() function to set them.
+//! <br><br>
+//! Allocations for nodes, attributes and strings are aligned at <code>RAPIDXML_ALIGNMENT</code> bytes.
+//! This value defaults to the size of pointer on target architecture.
+//! <br><br>
+//! To obtain absolutely top performance from the parser,
+//! it is important that all nodes are allocated from a single, contiguous block of memory.
+//! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably.
+//! If required, you can tweak <code>RAPIDXML_STATIC_POOL_SIZE</code>, <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>RAPIDXML_ALIGNMENT</code> 
+//! to obtain best wasted memory to performance compromise.
+//! To do it, define their values before rapidxml.hpp file is included.
+//! \param Ch Character type of created nodes. 
+template<class Ch = char>
+class memory_pool {
+
+public:
+
+       //! \cond internal
+       typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory
+       typedef void (free_func)(void *); // Type of user-defined function used to free memory
+       //! \endcond
+
+       //! Constructs empty pool with default allocator functions.
+       memory_pool() :
+                       m_alloc_func(0), m_free_func(0) {
+               init();
+       }
+
+       //! Destroys pool and frees all the memory. 
+       //! This causes memory occupied by nodes allocated by the pool to be freed.
+       //! Nodes allocated from the pool are no longer valid.
+       ~memory_pool() {
+               clear();
+       }
+
+       //! Allocates a new node from the pool, and optionally assigns name and value to it. 
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+       //! will call rapidxml::parse_error_handler() function.
+       //! \param type Type of node to create.
+       //! \param name Name to assign to the node, or 0 to assign no name.
+       //! \param value Value to assign to the node, or 0 to assign no value.
+       //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+       //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+       //! \return Pointer to allocated node. This pointer will never be NULL.
+       xml_node<Ch> *allocate_node(node_type type, const Ch *name = 0,
+           const Ch *value = 0, std::size_t name_size = 0,
+           std::size_t value_size = 0) {
+               void *memory = allocate_aligned(sizeof(xml_node<Ch> ));
+               xml_node<Ch> *node = new (memory) xml_node<Ch>(type);
+               if (name) {
+                       if (name_size > 0)
+                               node->name(name, name_size);
+                       else node->name(name);
+               }
+               if (value) {
+                       if (value_size > 0)
+                               node->value(value, value_size);
+                       else node->value(value);
+               }
+               return node;
+       }
+
+       //! Allocates a new attribute from the pool, and optionally assigns name and value to it.
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+       //! will call rapidxml::parse_error_handler() function.
+       //! \param name Name to assign to the attribute, or 0 to assign no name.
+       //! \param value Value to assign to the attribute, or 0 to assign no value.
+       //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+       //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+       //! \return Pointer to allocated attribute. This pointer will never be NULL.
+       xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
+           std::size_t name_size = 0, std::size_t value_size = 0) {
+               void *memory = allocate_aligned(sizeof(xml_attribute<Ch> ));
+               xml_attribute<Ch> *attribute = new (memory) xml_attribute<Ch>;
+               if (name) {
+                       if (name_size > 0)
+                               attribute->name(name, name_size);
+                       else attribute->name(name);
+               }
+               if (value) {
+                       if (value_size > 0)
+                               attribute->value(value, value_size);
+                       else attribute->value(value);
+               }
+               return attribute;
+       }
+
+       //! Allocates a char array of given size from the pool, and optionally copies a given string to it.
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+       //! will call rapidxml::parse_error_handler() function.
+       //! \param source String to initialize the allocated memory with, or 0 to not initialize it.
+       //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.
+       //! \return Pointer to allocated char array. This pointer will never be NULL.
+       Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) {
+               assert(source || size); // Either source or size (or both) must be specified
+               if (size == 0) size = internal::measure(source) + 1;
+               Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
+               if (source) for (std::size_t i = 0; i < size; ++i)
+                       result[i] = source[i];
+               return result;
+       }
+
+       //! Clones an xml_node and its hierarchy of child nodes and attributes.
+       //! Nodes and attributes are allocated from this memory pool.
+       //! Names and values are not cloned, they are shared between the clone and the source.
+       //! Result node can be optionally specified as a second parameter, 
+       //! in which case its contents will be replaced with cloned source node.
+       //! This is useful when you want to clone entire document.
+       //! \param source Node to clone.
+       //! \param result Node to put results in, or 0 to automatically allocate result node
+       //! \return Pointer to cloned node. This pointer will never be NULL.
+       xml_node<Ch> *clone_node(const xml_node<Ch> *source,
+           xml_node<Ch> *result = 0) {
+               // Prepare result node
+               if (result) {
+                       result->remove_all_attributes();
+                       result->remove_all_nodes();
+                       result->type(source->type());
+               } else result = allocate_node(source->type());
+
+               // Clone name and value
+               result->name(source->name(), source->name_size());
+               result->value(source->value(), source->value_size());
+
+               // Clone child nodes and attributes
+               for (xml_node<Ch> *child = source->first_node(); child;
+                   child = child->next_sibling())
+                       result->append_node(clone_node(child));
+               for (xml_attribute<Ch> *attr = source->first_attribute(); attr;
+                   attr = attr->next_attribute())
+                       result->append_attribute(
+                           allocate_attribute(attr->name(), attr->value(), attr->name_size(),
+                               attr->value_size()));
+
+               return result;
+       }
+
+       //! Clears the pool. 
+       //! This causes memory occupied by nodes allocated by the pool to be freed.
+       //! Any nodes or strings allocated from the pool will no longer be valid.
+       void clear() {
+               while (m_begin != m_static_memory) {
+                       char *previous_begin = reinterpret_cast<header *>(align(m_begin))
+                           ->previous_begin;
+                       if (m_free_func)
+                               m_free_func(m_begin);
+                       else delete[] m_begin;
+                       m_begin = previous_begin;
+               }
+               init();
+       }
+
+       //! Sets or resets the user-defined memory allocation functions for the pool.
+       //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined.
+       //! Allocation function must not return invalid pointer on failure. It should either throw,
+       //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program. 
+       //! If it returns invalid pointer, results are undefined.
+       //! <br><br>
+       //! User defined allocation functions must have the following forms:
+       //! <br><code>
+       //! <br>void *allocate(std::size_t size);
+       //! <br>void free(void *pointer);
+       //! </code><br>
+       //! \param af Allocation function, or 0 to restore default function
+       //! \param ff Free function, or 0 to restore default function
+       void set_allocator(alloc_func *af, free_func *ff) {
+               assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet
+               m_alloc_func = af;
+               m_free_func = ff;
+       }
+
+private:
+
+       struct header {
+               char *previous_begin;
+       };
+
+       void init() {
+               m_begin = m_static_memory;
+               m_ptr = align(m_begin);
+               m_end = m_static_memory + sizeof(m_static_memory);
+       }
+
+       char *align(char *ptr) {
+               std::size_t alignment = ((RAPIDXML_ALIGNMENT
+                   - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1)))
+                   & (RAPIDXML_ALIGNMENT - 1));
+               return ptr + alignment;
+       }
+
+       char *allocate_raw(std::size_t size) {
+               // Allocate
+               void *memory;
+               if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[]
+               {
+                       memory = m_alloc_func(size);
+                       assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
+               } else {
+                       memory = new char[size];
+#ifdef RAPIDXML_NO_EXCEPTIONS
+                       if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc
+                       RAPIDXML_PARSE_ERROR("out of memory", 0);
+#endif
+               }
+               return static_cast<char *>(memory);
+       }
+
+       void *allocate_aligned(std::size_t size) {
+               // Calculate aligned pointer
+               char *result = align(m_ptr);
+
+               // If not enough memory left in current pool, allocate a new pool
+               if (result + size > m_end) {
+                       // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE)
+                       std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;
+                       if (pool_size < size) pool_size = size;
+
+                       // Allocate
+                       std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2)
+                           + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation
+                       char *raw_memory = allocate_raw(alloc_size);
+
+                       // Setup new pool in allocated memory
+                       char *pool = align(raw_memory);
+                       header *new_header = reinterpret_cast<header *>(pool);
+                       new_header->previous_begin = m_begin;
+                       m_begin = raw_memory;
+                       m_ptr = pool + sizeof(header);
+                       m_end = raw_memory + alloc_size;
+
+                       // Calculate aligned pointer again using new pool
+                       result = align(m_ptr);
+               }
+
+               // Update pool and return aligned pointer
+               m_ptr = result + size;
+               return result;
+       }
+
+       char *m_begin;                 // Start of raw memory making up current pool
+       char *m_ptr;                              // First free byte in current pool
+       char *m_end;                 // One past last available byte in current pool
+       char m_static_memory[RAPIDXML_STATIC_POOL_SIZE];    // Static raw memory
+       alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used
+       free_func *m_free_func;      // Free function, or 0 if default is to be used
+};
+
+///////////////////////////////////////////////////////////////////////////
+// XML base
+
+//! Base class for xml_node and xml_attribute implementing common functions: 
+//! name(), name_size(), value(), value_size() and parent().
+//! \param Ch Character type to use
+template<class Ch = char>
+class xml_base {
+
+public:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Construction & destruction
+
+       // Construct a base with empty name, value and parent
+       xml_base() :
+                       m_name(0), m_value(0), m_parent(0) {
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node data access
+
+       //! Gets name of the node. 
+       //! Interpretation of name depends on type of node.
+       //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+       //! <br><br>
+       //! Use name_size() function to determine length of the name.
+       //! \return Name of node, or empty string if node has no name.
+       Ch *name() const {
+               return m_name ? m_name : nullstr();
+       }
+
+       //! Gets size of node name, not including terminator character.
+       //! This function works correctly irrespective of whether name is or is not zero terminated.
+       //! \return Size of node name, in characters.
+       std::size_t name_size() const {
+               return m_name ? m_name_size : 0;
+       }
+
+       //! Gets value of node. 
+       //! Interpretation of value depends on type of node.
+       //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+       //! <br><br>
+       //! Use value_size() function to determine length of the value.
+       //! \return Value of node, or empty string if node has no value.
+       Ch *value() const {
+               return m_value ? m_value : nullstr();
+       }
+
+       //! Gets size of node value, not including terminator character.
+       //! This function works correctly irrespective of whether value is or is not zero terminated.
+       //! \return Size of node value, in characters.
+       std::size_t value_size() const {
+               return m_value ? m_value_size : 0;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node modification
+
+       //! Sets name of node to a non zero-terminated string.
+       //! See \ref ownership_of_strings.
+       //! <br><br>
+       //! Note that node does not own its name or value, it only stores a pointer to it. 
+       //! It will not delete or otherwise free the pointer on destruction.
+       //! It is reponsibility of the user to properly manage lifetime of the string.
+       //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+       //! on destruction of the document the string will be automatically freed.
+       //! <br><br>
+       //! Size of name must be specified separately, because name does not have to be zero terminated.
+       //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+       //! \param name Name of node to set. Does not have to be zero terminated.
+       //! \param size Size of name, in characters. This does not include zero terminator, if one is present.
+       void name(const Ch *name, std::size_t size) {
+               m_name = const_cast<Ch *>(name);
+               m_name_size = size;
+       }
+
+       //! Sets name of node to a zero-terminated string.
+       //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t).
+       //! \param name Name of node to set. Must be zero terminated.
+       void name(const Ch *name) {
+               this->name(name, internal::measure(name));
+       }
+
+       //! Sets value of node to a non zero-terminated string.
+       //! See \ref ownership_of_strings.
+       //! <br><br>
+       //! Note that node does not own its name or value, it only stores a pointer to it. 
+       //! It will not delete or otherwise free the pointer on destruction.
+       //! It is reponsibility of the user to properly manage lifetime of the string.
+       //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+       //! on destruction of the document the string will be automatically freed.
+       //! <br><br>
+       //! Size of value must be specified separately, because it does not have to be zero terminated.
+       //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+       //! <br><br>
+       //! If an element has a child node of type node_data, it will take precedence over element value when printing.
+       //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.
+       //! \param value value of node to set. Does not have to be zero terminated.
+       //! \param size Size of value, in characters. This does not include zero terminator, if one is present.
+       void value(const Ch *value, std::size_t size) {
+               m_value = const_cast<Ch *>(value);
+               m_value_size = size;
+       }
+
+       //! Sets value of node to a zero-terminated string.
+       //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t).
+       //! \param value Vame of node to set. Must be zero terminated.
+       void value(const Ch *value) {
+               this->value(value, internal::measure(value));
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Related nodes access
+
+       //! Gets node parent.
+       //! \return Pointer to parent node, or 0 if there is no parent.
+       xml_node<Ch> *parent() const {
+               return m_parent;
+       }
+
+protected:
+
+       // Return empty string
+       static Ch *nullstr() {
+               static Ch zero = Ch('\0');
+               return &zero;
+       }
+
+       Ch *m_name;                         // Name of node, or 0 if no name
+       Ch *m_value;                        // Value of node, or 0 if no value
+       std::size_t m_name_size;     // Length of node name, or undefined of no name
+       std::size_t m_value_size;  // Length of node value, or undefined if no value
+       xml_node<Ch> *m_parent;             // Pointer to parent node, or 0 if none
+
+};
+
+//! Class representing attribute node of XML document. 
+//! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base).
+//! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. 
+//! Thus, this text must persist in memory for the lifetime of attribute.
+//! \param Ch Character type to use.
+template<class Ch = char>
+class xml_attribute:
+    public xml_base<Ch> {
+
+       friend class xml_node<Ch> ;
+
+public:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Construction & destruction
+
+       //! Constructs an empty attribute with the specified type. 
+       //! Consider using memory_pool of appropriate xml_document if allocating attributes manually.
+       xml_attribute() {
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Related nodes access
+
+       //! Gets document of which attribute is a child.
+       //! \return Pointer to document that contains this attribute, or 0 if there is no parent document.
+       xml_document<Ch> *document() const {
+               if (xml_node<Ch> *node = this->parent()) {
+                       while (node->parent())
+                               node = node->parent();
+                       return
+                           node->type() == node_document ?
+                               static_cast<xml_document<Ch> *>(node) : 0;
+               } else return 0;
+       }
+
+       //! Gets previous attribute, optionally matching attribute name. 
+       //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *previous_attribute(const Ch *name = 0,
+           std::size_t name_size = 0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute;
+                           attribute = attribute->m_prev_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return this->m_parent ? m_prev_attribute : 0;
+       }
+
+       //! Gets next attribute, optionally matching attribute name. 
+       //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *next_attribute(const Ch *name = 0, std::size_t name_size =
+           0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_next_attribute; attribute;
+                           attribute = attribute->m_next_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return this->m_parent ? m_next_attribute : 0;
+       }
+
+private:
+
+       xml_attribute<Ch> *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero
+       xml_attribute<Ch> *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero
+
+};
+
+///////////////////////////////////////////////////////////////////////////
+// XML node
+
+//! Class representing a node of XML document. 
+//! Each node may have associated name and value strings, which are available through name() and value() functions. 
+//! Interpretation of name and value depends on type of the node.
+//! Type of node can be determined by using type() function.
+//! <br><br>
+//! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. 
+//! Thus, this text must persist in the memory for the lifetime of node.
+//! \param Ch Character type to use.
+template<class Ch = char>
+class xml_node:
+    public xml_base<Ch> {
+
+public:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Construction & destruction
+
+       //! Constructs an empty node with the specified type. 
+       //! Consider using memory_pool of appropriate document to allocate nodes manually.
+       //! \param type Type of node to construct.
+       xml_node(node_type type) :
+                       m_type(type), m_first_node(0), m_first_attribute(0) {
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node data access
+
+       //! Gets type of node.
+       //! \return Type of node.
+       node_type type() const {
+               return m_type;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Related nodes access
+
+       //! Gets document of which node is a child.
+       //! \return Pointer to document that contains this node, or 0 if there is no parent document.
+       xml_document<Ch> *document() const {
+               xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
+               while (node->parent())
+                       node = node->parent();
+               return
+                   node->type() == node_document ? static_cast<xml_document<Ch> *>(node) :
+                                                   0;
+       }
+
+       //! Gets first child node, optionally matching node name.
+       //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found child, or 0 if not found.
+       xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *child = m_first_node; child;
+                           child = child->next_sibling())
+                               if (internal::compare(child->name(), child->name_size(), name,
+                                   name_size, case_sensitive)) return child;
+                       return 0;
+               } else return m_first_node;
+       }
+
+       //! Gets last child node, optionally matching node name. 
+       //! Behaviour is undefined if node has no children.
+       //! Use first_node() to test if node has children.
+       //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found child, or 0 if not found.
+       xml_node<Ch> *last_node(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               assert(m_first_node); // Cannot query for last child if node has no children
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *child = m_last_node; child;
+                           child = child->previous_sibling())
+                               if (internal::compare(child->name(), child->name_size(), name,
+                                   name_size, case_sensitive)) return child;
+                       return 0;
+               } else return m_last_node;
+       }
+
+       //! Gets previous sibling node, optionally matching node name. 
+       //! Behaviour is undefined if node has no parent.
+       //! Use parent() to test if node has a parent.
+       //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found sibling, or 0 if not found.
+       xml_node<Ch> *previous_sibling(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               assert(this->m_parent); // Cannot query for siblings if node has no parent
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *sibling = m_prev_sibling; sibling;
+                           sibling = sibling->m_prev_sibling)
+                               if (internal::compare(sibling->name(), sibling->name_size(), name,
+                                   name_size, case_sensitive)) return sibling;
+                       return 0;
+               } else return m_prev_sibling;
+       }
+
+       //! Gets next sibling node, optionally matching node name. 
+       //! Behaviour is undefined if node has no parent.
+       //! Use parent() to test if node has a parent.
+       //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found sibling, or 0 if not found.
+       xml_node<Ch> *next_sibling(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               assert(this->m_parent); // Cannot query for siblings if node has no parent
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *sibling = m_next_sibling; sibling;
+                           sibling = sibling->m_next_sibling)
+                               if (internal::compare(sibling->name(), sibling->name_size(), name,
+                                   name_size, case_sensitive)) return sibling;
+                       return 0;
+               } else return m_next_sibling;
+       }
+
+       //! Gets first attribute of node, optionally matching attribute name.
+       //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *first_attribute(const Ch *name = 0, std::size_t name_size =
+           0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_first_attribute; attribute;
+                           attribute = attribute->m_next_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return m_first_attribute;
+       }
+
+       //! Gets last attribute of node, optionally matching attribute name.
+       //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *last_attribute(const Ch *name = 0, std::size_t name_size =
+           0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_last_attribute; attribute;
+                           attribute = attribute->m_prev_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return m_first_attribute ? m_last_attribute : 0;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node modification
+
+       //! Sets type of node.
+       //! \param type Type of node to set.
+       void type(node_type type) {
+               m_type = type;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node manipulation
+
+       //! Prepends a new child node.
+       //! The prepended child becomes the first child, and all existing children are moved one position back.
+       //! \param child Node to prepend.
+       void prepend_node(xml_node<Ch> *child) {
+               assert(child && !child->parent() && child->type() != node_document);
+               if (first_node()) {
+                       child->m_next_sibling = m_first_node;
+                       m_first_node->m_prev_sibling = child;
+               } else {
+                       child->m_next_sibling = 0;
+                       m_last_node = child;
+               }
+               m_first_node = child;
+               child->m_parent = this;
+               child->m_prev_sibling = 0;
+       }
+
+       //! Appends a new child node. 
+       //! The appended child becomes the last child.
+       //! \param child Node to append.
+       void append_node(xml_node<Ch> *child) {
+               assert(child && !child->parent() && child->type() != node_document);
+               if (first_node()) {
+                       child->m_prev_sibling = m_last_node;
+                       m_last_node->m_next_sibling = child;
+               } else {
+                       child->m_prev_sibling = 0;
+                       m_first_node = child;
+               }
+               m_last_node = child;
+               child->m_parent = this;
+               child->m_next_sibling = 0;
+       }
+
+       //! Inserts a new child node at specified place inside the node. 
+       //! All children after and including the specified node are moved one position back.
+       //! \param where Place where to insert the child, or 0 to insert at the back.
+       //! \param child Node to insert.
+       void insert_node(xml_node<Ch> *where, xml_node<Ch> *child) {
+               assert(!where || where->parent() == this);
+               assert(child && !child->parent() && child->type() != node_document);
+               if (where == m_first_node)
+                       prepend_node(child);
+               else if (where == 0)
+                       append_node(child);
+               else {
+                       child->m_prev_sibling = where->m_prev_sibling;
+                       child->m_next_sibling = where;
+                       where->m_prev_sibling->m_next_sibling = child;
+                       where->m_prev_sibling = child;
+                       child->m_parent = this;
+               }
+       }
+
+       //! Removes first child node. 
+       //! If node has no children, behaviour is undefined.
+       //! Use first_node() to test if node has children.
+       void remove_first_node() {
+               assert(first_node());
+               xml_node<Ch> *child = m_first_node;
+               m_first_node = child->m_next_sibling;
+               if (child->m_next_sibling)
+                       child->m_next_sibling->m_prev_sibling = 0;
+               else m_last_node = 0;
+               child->m_parent = 0;
+       }
+
+       //! Removes last child of the node. 
+       //! If node has no children, behaviour is undefined.
+       //! Use first_node() to test if node has children.
+       void remove_last_node() {
+               assert(first_node());
+               xml_node<Ch> *child = m_last_node;
+               if (child->m_prev_sibling) {
+                       m_last_node = child->m_prev_sibling;
+                       child->m_prev_sibling->m_next_sibling = 0;
+               } else m_first_node = 0;
+               child->m_parent = 0;
+       }
+
+       //! Removes specified child from the node
+       // \param where Pointer to child to be removed.
+       void remove_node(xml_node<Ch> *where) {
+               assert(where && where->parent() == this);
+               assert(first_node());
+               if (where == m_first_node)
+                       remove_first_node();
+               else if (where == m_last_node)
+                       remove_last_node();
+               else {
+                       where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
+                       where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
+                       where->m_parent = 0;
+               }
+       }
+
+       //! Removes all child nodes (but not attributes).
+       void remove_all_nodes() {
+               for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
+                       node->m_parent = 0;
+               m_first_node = 0;
+       }
+
+       //! Prepends a new attribute to the node.
+       //! \param attribute Attribute to prepend.
+       void prepend_attribute(xml_attribute<Ch> *attribute) {
+               assert(attribute && !attribute->parent());
+               if (first_attribute()) {
+                       attribute->m_next_attribute = m_first_attribute;
+                       m_first_attribute->m_prev_attribute = attribute;
+               } else {
+                       attribute->m_next_attribute = 0;
+                       m_last_attribute = attribute;
+               }
+               m_first_attribute = attribute;
+               attribute->m_parent = this;
+               attribute->m_prev_attribute = 0;
+       }
+
+       //! Appends a new attribute to the node.
+       //! \param attribute Attribute to append.
+       void append_attribute(xml_attribute<Ch> *attribute) {
+               assert(attribute && !attribute->parent());
+               if (first_attribute()) {
+                       attribute->m_prev_attribute = m_last_attribute;
+                       m_last_attribute->m_next_attribute = attribute;
+               } else {
+                       attribute->m_prev_attribute = 0;
+                       m_first_attribute = attribute;
+               }
+               m_last_attribute = attribute;
+               attribute->m_parent = this;
+               attribute->m_next_attribute = 0;
+       }
+
+       //! Inserts a new attribute at specified place inside the node. 
+       //! All attributes after and including the specified attribute are moved one position back.
+       //! \param where Place where to insert the attribute, or 0 to insert at the back.
+       //! \param attribute Attribute to insert.
+       void insert_attribute(xml_attribute<Ch> *where,
+           xml_attribute<Ch> *attribute) {
+               assert(!where || where->parent() == this);
+               assert(attribute && !attribute->parent());
+               if (where == m_first_attribute)
+                       prepend_attribute(attribute);
+               else if (where == 0)
+                       append_attribute(attribute);
+               else {
+                       attribute->m_prev_attribute = where->m_prev_attribute;
+                       attribute->m_next_attribute = where;
+                       where->m_prev_attribute->m_next_attribute = attribute;
+                       where->m_prev_attribute = attribute;
+                       attribute->m_parent = this;
+               }
+       }
+
+       //! Removes first attribute of the node. 
+       //! If node has no attributes, behaviour is undefined.
+       //! Use first_attribute() to test if node has attributes.
+       void remove_first_attribute() {
+               assert(first_attribute());
+               xml_attribute<Ch> *attribute = m_first_attribute;
+               if (attribute->m_next_attribute) {
+                       attribute->m_next_attribute->m_prev_attribute = 0;
+               } else m_last_attribute = 0;
+               attribute->m_parent = 0;
+               m_first_attribute = attribute->m_next_attribute;
+       }
+
+       //! Removes last attribute of the node. 
+       //! If node has no attributes, behaviour is undefined.
+       //! Use first_attribute() to test if node has attributes.
+       void remove_last_attribute() {
+               assert(first_attribute());
+               xml_attribute<Ch> *attribute = m_last_attribute;
+               if (attribute->m_prev_attribute) {
+                       attribute->m_prev_attribute->m_next_attribute = 0;
+                       m_last_attribute = attribute->m_prev_attribute;
+               } else m_first_attribute = 0;
+               attribute->m_parent = 0;
+       }
+
+       //! Removes specified attribute from node.
+       //! \param where Pointer to attribute to be removed.
+       void remove_attribute(xml_attribute<Ch> *where) {
+               assert(first_attribute() && where->parent() == this);
+               if (where == m_first_attribute)
+                       remove_first_attribute();
+               else if (where == m_last_attribute)
+                       remove_last_attribute();
+               else {
+                       where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
+                       where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
+                       where->m_parent = 0;
+               }
+       }
+
+       //! Removes all attributes of node.
+       void remove_all_attributes() {
+               for (xml_attribute<Ch> *attribute = first_attribute(); attribute;
+                   attribute = attribute->m_next_attribute)
+                       attribute->m_parent = 0;
+               m_first_attribute = 0;
+       }
+
+private:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Restrictions
+
+       // No copying
+       xml_node(const xml_node &);
+       void operator =(const xml_node &);
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Data members
+
+       // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.
+       // This is required for maximum performance, as it allows the parser to omit initialization of 
+       // unneded/redundant values.
+       //
+       // The rules are as follows:
+       // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively
+       // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage
+       // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage
+
+       node_type m_type;                       // Type of node; always valid
+       xml_node<Ch> *m_first_node; // Pointer to first child node, or 0 if none; always valid
+       xml_node<Ch> *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero
+       xml_attribute<Ch> *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid
+       xml_attribute<Ch> *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero
+       xml_node<Ch> *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+       xml_node<Ch> *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+
+};
+
+///////////////////////////////////////////////////////////////////////////
+// XML document
+
+//! This class represents root of the DOM hierarchy. 
+//! It is also an xml_node and a memory_pool through public inheritance.
+//! Use parse() function to build a DOM tree from a zero-terminated XML text string.
+//! parse() function allocates memory for nodes and attributes by using functions of xml_document, 
+//! which are inherited from memory_pool.
+//! To access root node of the document, use the document itself, as if it was an xml_node.
+//! \param Ch Character type to use.
+template<class Ch = char>
+class xml_document:
+    public xml_node<Ch>, public memory_pool<Ch> {
+
+public:
+
+       //! Constructs empty XML document
+       xml_document() :
+                       xml_node<Ch>(node_document) {
+       }
+
+       //! Parses zero-terminated XML string according to given flags.
+       //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.
+       //! The string must persist for the lifetime of the document.
+       //! In case of error, rapidxml::parse_error exception will be thrown.
+       //! <br><br>
+       //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning.
+       //! Make sure that data is zero-terminated.
+       //! <br><br>
+       //! Document can be parsed into multiple times. 
+       //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.
+       //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.
+       template<int Flags>
+       void parse(Ch *text) {
+               assert(text);
+
+               // Remove current contents
+               this->remove_all_nodes();
+               this->remove_all_attributes();
+
+               // Parse BOM, if any
+               parse_bom<Flags>(text);
+
+               // Parse children
+               while (1) {
+                       // Skip whitespace before node
+                       skip<whitespace_pred, Flags>(text);
+                       if (*text == 0) break;
+
+                       // Parse and append new child
+                       if (*text == Ch('<')) {
+                               ++text;     // Skip '<'
+                               if (xml_node<Ch> *node = parse_node<Flags>(text))
+                                 this->append_node(node);
+                       } else
+                       RAPIDXML_PARSE_ERROR("expected <", text);
+               }
+
+       }
+
+       //! Clears the document by deleting all nodes and clearing the memory pool.
+       //! All nodes owned by document pool are destroyed.
+       void clear() {
+               this->remove_all_nodes();
+               this->remove_all_attributes();
+               memory_pool<Ch>::clear();
+       }
+
+private:
+
+       ///////////////////////////////////////////////////////////////////////
+       // Internal character utility functions
+
+       // Detect whitespace character
+       struct whitespace_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect node name character
+       struct node_name_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect attribute name character
+       struct attribute_name_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect text character (PCDATA)
+       struct text_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect text character (PCDATA) that does not require processing
+       struct text_pure_no_ws_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect text character (PCDATA) that does not require processing
+       struct text_pure_with_ws_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect attribute value character
+       template<Ch Quote>
+       struct attribute_value_pred {
+               static unsigned char test(Ch ch) {
+                       if (Quote == Ch('\''))
+                         return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];
+                       if (Quote == Ch('\"'))
+                         return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];
+                       return 0;   // Should never be executed, to avoid warnings on Comeau
+               }
+       };
+
+       // Detect attribute value character
+       template<Ch Quote>
+       struct attribute_value_pure_pred {
+               static unsigned char test(Ch ch) {
+                       if (Quote == Ch('\''))
+                         return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
+                       if (Quote == Ch('\"'))
+                         return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
+                       return 0;   // Should never be executed, to avoid warnings on Comeau
+               }
+       };
+
+       // Insert coded character, using UTF8 or 8-bit ASCII
+       template<int Flags>
+       static void insert_coded_character(Ch *&text, unsigned long code) {
+               if (Flags & parse_no_utf8) {
+                       // Insert 8-bit ASCII character
+                       // Todo: possibly verify that code is less than 256 and use replacement char otherwise?
+                       text[0] = static_cast<unsigned char>(code);
+                       text += 1;
+               } else {
+                       // Insert UTF8 sequence
+                       if (code < 0x80)    // 1 byte sequence
+                           {
+                               text[0] = static_cast<unsigned char>(code);
+                               text += 1;
+                       } else if (code < 0x800)  // 2 byte sequence
+                           {
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[0] = static_cast<unsigned char>(code | 0xC0);
+                               text += 2;
+                       } else if (code < 0x10000)    // 3 byte sequence
+                           {
+                               text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[0] = static_cast<unsigned char>(code | 0xE0);
+                               text += 3;
+                       } else if (code < 0x110000)   // 4 byte sequence
+                           {
+                               text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[0] = static_cast<unsigned char>(code | 0xF0);
+                               text += 4;
+                       } else  // Invalid, only codes up to 0x10FFFF are allowed in Unicode
+                       {
+                               RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
+                       }
+               }
+       }
+
+       // Skip characters until predicate evaluates to true
+       template<class StopPred, int Flags>
+       static void skip(Ch *&text) {
+               Ch *tmp = text;
+               while (StopPred::test(*tmp))
+                       ++tmp;
+               text = tmp;
+       }
+
+       // Skip characters until predicate evaluates to true while doing the following:
+       // - replacing XML character entity references with proper characters (&apos; &amp; &quot; &lt; &gt; &#...;)
+       // - condensing whitespace sequences to single space character
+       template<class StopPred, class StopPredPure, int Flags>
+       static Ch *skip_and_expand_character_refs(Ch *&text) {
+               // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip
+               if (Flags & parse_no_entity_translation
+                   && !(Flags & parse_normalize_whitespace)
+                   && !(Flags & parse_trim_whitespace)) {
+                       skip<StopPred, Flags>(text);
+                       return text;
+               }
+
+               // Use simple skip until first modification is detected
+               skip<StopPredPure, Flags>(text);
+
+               // Use translation skip
+               Ch *src = text;
+               Ch *dest = src;
+               while (StopPred::test(*src)) {
+                       // If entity translation is enabled    
+                       if (!(Flags & parse_no_entity_translation)) {
+                               // Test if replacement is needed
+                               if (src[0] == Ch('&')) {
+                                       switch (src[1]) {
+
+                                               // &amp; &apos;
+                                               case Ch('a'):
+                                                       if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) {
+                                                               *dest = Ch('&');
+                                                               ++dest;
+                                                               src += 5;
+                                                               continue;
+                                                       }
+                                                       if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s')
+                                                           && src[5] == Ch(';')) {
+                                                               *dest = Ch('\'');
+                                                               ++dest;
+                                                               src += 6;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &quot;
+                                               case Ch('q'):
+                                                       if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t')
+                                                           && src[5] == Ch(';')) {
+                                                               *dest = Ch('"');
+                                                               ++dest;
+                                                               src += 6;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &gt;
+                                               case Ch('g'):
+                                                       if (src[2] == Ch('t') && src[3] == Ch(';')) {
+                                                               *dest = Ch('>');
+                                                               ++dest;
+                                                               src += 4;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &lt;
+                                               case Ch('l'):
+                                                       if (src[2] == Ch('t') && src[3] == Ch(';')) {
+                                                               *dest = Ch('<');
+                                                               ++dest;
+                                                               src += 4;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &#...; - assumes ASCII
+                                               case Ch('#'):
+                                                       if (src[2] == Ch('x')) {
+                                                               unsigned long code = 0;
+                                                               src += 3;   // Skip &#x
+                                                               while (1) {
+                                                                       unsigned char digit =
+                                                                           internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                                                                       if (digit == 0xFF) break;
+                                                                       code = code * 16 + digit;
+                                                                       ++src;
+                                                               }
+                                                               insert_coded_character<Flags>(dest, code); // Put character in output
+                                                       } else {
+                                                               unsigned long code = 0;
+                                                               src += 2;   // Skip &#
+                                                               while (1) {
+                                                                       unsigned char digit =
+                                                                           internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                                                                       if (digit == 0xFF) break;
+                                                                       code = code * 10 + digit;
+                                                                       ++src;
+                                                               }
+                                                               insert_coded_character<Flags>(dest, code); // Put character in output
+                                                       }
+                                                       if (*src == Ch(';'))
+                                                               ++src;
+                                                       else
+                                                       RAPIDXML_PARSE_ERROR("expected ;", src);
+                                                       continue;
+
+                                                       // Something else
+                                               default:
+                                                       // Ignore, just copy '&' verbatim
+                                                       break;
+
+                                       }
+                               }
+                       }
+
+                       // If whitespace condensing is enabled
+                       if (Flags & parse_normalize_whitespace) {
+                               // Test if condensing is needed                 
+                               if (whitespace_pred::test(*src)) {
+                                       *dest = Ch(' ');
+                                       ++dest;    // Put single space in dest
+                                       ++src;                      // Skip first whitespace char
+                                       // Skip remaining whitespace chars
+                                       while (whitespace_pred::test(*src))
+                                               ++src;
+                                       continue;
+                               }
+                       }
+
+                       // No replacement, only copy character
+                       *dest++ = *src++;
+
+               }
+
+               // Return new end
+               text = src;
+               return dest;
+
+       }
+
+       ///////////////////////////////////////////////////////////////////////
+       // Internal parsing functions
+
+       // Parse BOM, if any
+       template<int Flags>
+       void parse_bom(Ch *&text) {
+               // UTF-8?
+               if (static_cast<unsigned char>(text[0]) == 0xEF
+                   && static_cast<unsigned char>(text[1]) == 0xBB
+                   && static_cast<unsigned char>(text[2]) == 0xBF) {
+                       text += 3;      // Skup utf-8 bom
+               }
+       }
+
+       // Parse XML declaration (<?xml...)
+       template<int Flags>
+       xml_node<Ch> *parse_xml_declaration(Ch *&text) {
+               // If parsing of declaration is disabled
+               if (!(Flags & parse_declaration_node)) {
+                       // Skip until end of declaration
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {
+                               if (!text[0])
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 2;    // Skip '?>'
+                       return 0;
+               }
+
+               // Create declaration
+               xml_node<Ch> *declaration = this->allocate_node(node_declaration);
+
+               // Skip whitespace before attributes or ?>
+               skip<whitespace_pred, Flags>(text);
+
+               // Parse declaration attributes
+               parse_node_attributes<Flags>(text, declaration);
+
+               // Skip ?>
+               if (text[0] != Ch('?') || text[1] != Ch('>'))
+               RAPIDXML_PARSE_ERROR("expected ?>", text);
+               text += 2;
+
+               return declaration;
+       }
+
+       // Parse XML comment (<!--...)
+       template<int Flags>
+       xml_node<Ch> *parse_comment(Ch *&text) {
+               // If parsing of comments is disabled
+               if (!(Flags & parse_comment_nodes)) {
+                       // Skip until end of comment
+                       while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {
+                               if (!text[0])
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 3;     // Skip '-->'
+                       return 0;      // Do not produce comment node
+               }
+
+               // Remember value start
+               Ch *value = text;
+
+               // Skip until end of comment
+               while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {
+                       if (!text[0])
+                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                       ++text;
+               }
+
+               // Create comment node
+               xml_node<Ch> *comment = this->allocate_node(node_comment);
+               comment->value(value, text - value);
+
+               // Place zero terminator after comment value
+               if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');
+
+               text += 3;     // Skip '-->'
+               return comment;
+       }
+
+       // Parse DOCTYPE
+       template<int Flags>
+       xml_node<Ch> *parse_doctype(Ch *&text) {
+               // Remember value start
+               Ch *value = text;
+
+               // Skip to >
+               while (*text != Ch('>')) {
+                       // Determine character type
+                       switch (*text) {
+
+                               // If '[' encountered, scan for matching ending ']' using naive algorithm with depth
+                               // This works for all W3C test files except for 2 most wicked
+                               case Ch('['): {
+                                       ++text;     // Skip '['
+                                       int depth = 1;
+                                       while (depth > 0) {
+                                               switch (*text) {
+                                                       case Ch('['):
+                                                               ++depth;
+                                                               break;
+                                                       case Ch(']'):
+                                                               --depth;
+                                                               break;
+                                                       case 0:
+                                                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                                               }
+                                               ++text;
+                                       }
+                                       break;
+                               }
+
+                                       // Error on end of text
+                               case Ch('\0'):
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+                                       // Other character, skip it
+                               default:
+                                       ++text;
+
+                       }
+               }
+
+               // If DOCTYPE nodes enabled
+               if (Flags & parse_doctype_node) {
+                       // Create a new doctype node
+                       xml_node<Ch> *doctype = this->allocate_node(node_doctype);
+                       doctype->value(value, text - value);
+
+                       // Place zero terminator after value
+                       if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');
+
+                       text += 1;      // skip '>'
+                       return doctype;
+               } else {
+                       text += 1;      // skip '>'
+                       return 0;
+               }
+
+       }
+
+       // Parse PI
+       template<int Flags>
+       xml_node<Ch> *parse_pi(Ch *&text) {
+               // If creation of PI nodes is enabled
+               if (Flags & parse_pi_nodes) {
+                       // Create pi node
+                       xml_node<Ch> *pi = this->allocate_node(node_pi);
+
+                       // Extract PI target name
+                       Ch *name = text;
+                       skip<node_name_pred, Flags>(text);
+                       if (text == name)
+                       RAPIDXML_PARSE_ERROR("expected PI target", text);
+                       pi->name(name, text - name);
+
+                       // Skip whitespace between pi target and pi
+                       skip<whitespace_pred, Flags>(text);
+
+                       // Remember start of pi
+                       Ch *value = text;
+
+                       // Skip to '?>'
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {
+                               if (*text == Ch('\0'))
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+
+                       // Set pi value (verbatim, no entity expansion or whitespace normalization)
+                       pi->value(value, text - value);
+
+                       // Place zero terminator after name and value
+                       if (!(Flags & parse_no_string_terminators)) {
+                               pi->name()[pi->name_size()] = Ch('\0');
+                               pi->value()[pi->value_size()] = Ch('\0');
+                       }
+
+                       text += 2;                          // Skip '?>'
+                       return pi;
+               } else {
+                       // Skip to '?>'
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {
+                               if (*text == Ch('\0'))
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 2;    // Skip '?>'
+                       return 0;
+               }
+       }
+
+       // Parse and append data
+       // Return character that ends data.
+       // This is necessary because this character might have been overwritten by a terminating 0
+       template<int Flags>
+       Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start) {
+               // Backup to contents start if whitespace trimming is disabled
+               if (!(Flags & parse_trim_whitespace)) text = contents_start;
+
+               // Skip until end of data
+               Ch *value = text, *end;
+               if (Flags & parse_normalize_whitespace)
+                       end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred,
+                           Flags>(text);
+               else end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred,
+                   Flags>(text);
+
+               // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >
+               if (Flags & parse_trim_whitespace) {
+                       if (Flags & parse_normalize_whitespace) {
+                               // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end
+                               if (*(end - 1) == Ch(' ')) --end;
+                       } else {
+                               // Backup until non-whitespace character is found
+                               while (whitespace_pred::test(*(end - 1)))
+                                       --end;
+                       }
+               }
+
+               // If characters are still left between end and value (this test is only necessary if normalization is enabled)
+               // Create new data node
+               if (!(Flags & parse_no_data_nodes)) {
+                       xml_node<Ch> *data = this->allocate_node(node_data);
+                       data->value(value, end - value);
+                       node->append_node(data);
+               }
+
+               // Add data to parent node if no data exists yet
+               if (!(Flags & parse_no_element_values))
+                 if (*node->value() == Ch('\0')) node->value(value, end - value);
+
+               // Place zero terminator after value
+               if (!(Flags & parse_no_string_terminators)) {
+                       Ch ch = *text;
+                       *end = Ch('\0');
+                       return ch; // Return character that ends data; this is required because zero terminator overwritten it
+               }
+
+               // Return character that ends data
+               return *text;
+       }
+
+       // Parse CDATA
+       template<int Flags>
+       xml_node<Ch> *parse_cdata(Ch *&text) {
+               // If CDATA is disabled
+               if (Flags & parse_no_data_nodes) {
+                       // Skip until end of cdata
+                       while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {
+                               if (!text[0])
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 3;      // Skip ]]>
+                       return 0;       // Do not produce CDATA node
+               }
+
+               // Skip until end of cdata
+               Ch *value = text;
+               while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {
+                       if (!text[0])
+                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                       ++text;
+               }
+
+               // Create new cdata node
+               xml_node<Ch> *cdata = this->allocate_node(node_cdata);
+               cdata->value(value, text - value);
+
+               // Place zero terminator after value
+               if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');
+
+               text += 3;      // Skip ]]>
+               return cdata;
+       }
+
+       // Parse element node
+       template<int Flags>
+       xml_node<Ch> *parse_element(Ch *&text) {
+               // Create element node
+               xml_node<Ch> *element = this->allocate_node(node_element);
+
+               // Extract element name
+               Ch *name = text;
+               skip<node_name_pred, Flags>(text);
+               if (text == name)
+               RAPIDXML_PARSE_ERROR("expected element name", text);
+               element->name(name, text - name);
+
+               // Skip whitespace between element name and attributes or >
+               skip<whitespace_pred, Flags>(text);
+
+               // Parse attributes, if any
+               parse_node_attributes<Flags>(text, element);
+
+               // Determine ending type
+               if (*text == Ch('>')) {
+                       ++text;
+                       parse_node_contents<Flags>(text, element);
+               } else if (*text == Ch('/')) {
+                       ++text;
+                       if (*text != Ch('>'))
+                       RAPIDXML_PARSE_ERROR("expected >", text);
+                       ++text;
+               } else
+               RAPIDXML_PARSE_ERROR("expected >", text);
+
+               // Place zero terminator after name
+               if (!(Flags & parse_no_string_terminators))
+                 element->name()[element->name_size()] = Ch('\0');
+
+               // Return parsed element
+               return element;
+       }
+
+       // Determine node type, and parse it
+       template<int Flags>
+       xml_node<Ch> *parse_node(Ch *&text) {
+               // Parse proper node type
+               switch (text[0]) {
+
+                       // <...
+                       default:
+                               // Parse and append element node
+                               return parse_element<Flags>(text);
+
+                               // <?...
+                       case Ch('?'):
+                               ++text;     // Skip ?
+                               if ((text[0] == Ch('x') || text[0] == Ch('X'))
+                                   && (text[1] == Ch('m') || text[1] == Ch('M'))
+                                   && (text[2] == Ch('l') || text[2] == Ch('L'))
+                                   && whitespace_pred::test(text[3])) {
+                                       // '<?xml ' - xml declaration
+                                       text += 4;      // Skip 'xml '
+                                       return parse_xml_declaration<Flags>(text);
+                               } else {
+                                       // Parse PI
+                                       return parse_pi<Flags>(text);
+                               }
+
+                               // <!...
+                       case Ch('!'):
+
+                               // Parse proper subset of <! node
+                               switch (text[1]) {
+
+                                       // <!-
+                                       case Ch('-'):
+                                               if (text[2] == Ch('-')) {
+                                                       // '<!--' - xml comment
+                                                       text += 3;     // Skip '!--'
+                                                       return parse_comment<Flags>(text);
+                                               }
+                                               break;
+
+                                               // <![
+                                       case Ch('['):
+                                               if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A')
+                                                   && text[5] == Ch('T') && text[6] == Ch('A')
+                                                   && text[7] == Ch('[')) {
+                                                       // '<![CDATA[' - cdata
+                                                       text += 8;     // Skip '![CDATA['
+                                                       return parse_cdata<Flags>(text);
+                                               }
+                                               break;
+
+                                               // <!D
+                                       case Ch('D'):
+                                               if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T')
+                                                   && text[5] == Ch('Y') && text[6] == Ch('P')
+                                                   && text[7] == Ch('E') && whitespace_pred::test(text[8])) {
+                                                       // '<!DOCTYPE ' - doctype
+                                                       text += 9;      // skip '!DOCTYPE '
+                                                       return parse_doctype<Flags>(text);
+                                               }
+
+                               }   // switch
+
+                               // Attempt to skip other, unrecognized node types starting with <!
+                               ++text;     // Skip !
+                               while (*text != Ch('>')) {
+                                       if (*text == 0)
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                                       ++text;
+                               }
+                               ++text;     // Skip '>'
+                               return 0;   // No node recognized
+
+               }
+       }
+
+       // Parse contents of the node - children, data etc.
+       template<int Flags>
+       void parse_node_contents(Ch *&text, xml_node<Ch> *node) {
+               // For all children and text
+               while (1) {
+                       // Skip whitespace between > and node contents
+                       Ch *contents_start = text; // Store start of node contents before whitespace is skipped
+                       skip<whitespace_pred, Flags>(text);
+                       Ch next_char = *text;
+
+                       // After data nodes, instead of continuing the loop, control jumps here.
+                       // This is because zero termination inside parse_and_append_data() function
+                       // would wreak havoc with the above code.
+                       // Also, skipping whitespace after data nodes is unnecessary.
+                       after_data_node:
+
+                       // Determine what comes next: node closing, child node, data node, or 0?
+                       switch (next_char) {
+
+                               // Node closing or child node
+                               case Ch('<'):
+                                       if (text[1] == Ch('/')) {
+                                               // Node closing
+                                               text += 2;      // Skip '</'
+                                               if (Flags & parse_validate_closing_tags) {
+                                                       // Skip and validate closing tag name
+                                                       Ch *closing_name = text;
+                                                       skip<node_name_pred, Flags>(text);
+                                                       if (!internal::compare(node->name(), node->name_size(),
+                                                           closing_name, text - closing_name, true))
+                                                       RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
+                                               } else {
+                                                       // No validation, just skip name
+                                                       skip<node_name_pred, Flags>(text);
+                                               }
+                                               // Skip remaining whitespace after node name
+                                               skip<whitespace_pred, Flags>(text);
+                                               if (*text != Ch('>'))
+                                               RAPIDXML_PARSE_ERROR("expected >", text);
+                                               ++text;     // Skip '>'
+                                               return;     // Node closed, finished parsing contents
+                                       } else {
+                                               // Child node
+                                               ++text;     // Skip '<'
+                                               if (xml_node<Ch> *child = parse_node<Flags>(text))
+                                                 node->append_node(child);
+                                       }
+                                       break;
+
+                                       // End of data - error
+                               case Ch('\0'):
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+                                       // Data node
+                               default:
+                                       next_char = parse_and_append_data<Flags>(node, text, contents_start);
+                                       goto after_data_node;
+                                       // Bypass regular processing after data nodes
+
+                       }
+               }
+       }
+
+       // Parse XML attributes of the node
+       template<int Flags>
+       void parse_node_attributes(Ch *&text, xml_node<Ch> *node) {
+               // For all attributes 
+               while (attribute_name_pred::test(*text)) {
+                       // Extract attribute name
+                       Ch *name = text;
+                       ++text;     // Skip first character of attribute name
+                       skip<attribute_name_pred, Flags>(text);
+                       if (text == name)
+                       RAPIDXML_PARSE_ERROR("expected attribute name", name);
+
+                       // Create new attribute
+                       xml_attribute<Ch> *attribute = this->allocate_attribute();
+                       attribute->name(name, text - name);
+                       node->append_attribute(attribute);
+
+                       // Skip whitespace after attribute name
+                       skip<whitespace_pred, Flags>(text);
+
+                       // Skip =
+                       if (*text != Ch('='))
+                       RAPIDXML_PARSE_ERROR("expected =", text);
+                       ++text;
+
+                       // Add terminating zero after name
+                       if (!(Flags & parse_no_string_terminators))
+                         attribute->name()[attribute->name_size()] = 0;
+
+                       // Skip whitespace after =
+                       skip<whitespace_pred, Flags>(text);
+
+                       // Skip quote and remember if it was ' or "
+                       Ch quote = *text;
+                       if (quote != Ch('\'') && quote != Ch('"'))
+                       RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+                       ++text;
+
+                       // Extract attribute value and expand char refs in it
+                       Ch *value = text, *end;
+                       const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes
+                       if (quote == Ch('\''))
+                               end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>,
+                                   attribute_value_pure_pred<Ch('\'')>, AttFlags>(text);
+                       else end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>,
+                           attribute_value_pure_pred<Ch('"')>, AttFlags>(text);
+
+                       // Set attribute value
+                       attribute->value(value, end - value);
+
+                       // Make sure that end quote is present
+                       if (*text != quote)
+                       RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+                       ++text;     // Skip quote
+
+                       // Add terminating zero after value
+                       if (!(Flags & parse_no_string_terminators))
+                         attribute->value()[attribute->value_size()] = 0;
+
+                       // Skip whitespace after attribute value
+                       skip<whitespace_pred, Flags>(text);
+               }
+       }
+
+};
+
+//! \cond internal
+namespace internal {
+
+// Whitespace (space \n \r \t)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,  // 0
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
+    };
+
+// Node name (anything but space \n \r \t / > ? \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_node_name[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Text (i.e. PCDATA) (anything but < \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_text[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Text (i.e. PCDATA) that does not require processing when ws normalization is disabled 
+// (anything but < \0 &)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled
+// (anything but < \0 & space \n \r \t)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute name (anything but space \n \r \t / < > = ? ! \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with single quote (anything but ' \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with single quote that does not require processing (anything but ' \0 &)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with double quote (anything but " \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with double quote that does not require processing (anything but " \0 &)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Digits (dec and hex, 255 denotes end of numeric character reference)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_digits[256] = {
+    // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 0
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 1
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 2
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255,
+    255,  // 3
+    255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 4
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 5
+    255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 6
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 7
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 8
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 9
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // A
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // B
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // C
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // D
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // E
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255   // F
+    };
+
+// Upper case conversion
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_upcase[256] = {
+    // 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  A   B   C   D   E   F
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+    15,   // 0
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+    31,   // 1
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+    47,   // 2
+    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+    63,   // 3
+    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+    79,   // 4
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+    95,   // 5
+    96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+    79,   // 6
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126,
+    127,  // 7
+    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+    143,  // 8
+    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+    159,  // 9
+    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+    175,  // A
+    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
+    191,  // B
+    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
+    207,  // C
+    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
+    223,  // D
+    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
+    239,  // E
+    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+    255   // F
+    };
+}
+//! \endcond
+
+}
+
+// Undefine internal macros
+#undef RAPIDXML_PARSE_ERROR
+
+// On MSVC, restore warnings state
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_iterators.hpp b/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_iterators.hpp
new file mode 100755 (executable)
index 0000000..478609a
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED
+#define RAPIDXML_ITERATORS_HPP_INCLUDED
+
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+// Version 1.13
+// Revision $DateTime: 2009/05/13 01:46:17 $
+//! \file rapidxml_iterators.hpp This file contains rapidxml iterators
+
+#include "rapidxml.hpp"
+
+namespace rapidxml {
+
+//! Iterator of child nodes of xml_node
+template<class Ch>
+class node_iterator {
+
+public:
+
+       typedef typename xml_node<Ch> value_type;
+       typedef typename xml_node<Ch> &reference;
+       typedef typename xml_node<Ch> *pointer;
+       typedef std::ptrdiff_t difference_type;
+       typedef std::bidirectional_iterator_tag iterator_category;
+
+       node_iterator() :
+                       m_node(0) {
+       }
+
+       node_iterator(xml_node<Ch> *node) :
+                       m_node(node->first_node()) {
+       }
+
+       reference operator *() const {
+               assert(m_node);
+               return *m_node;
+       }
+
+       pointer operator->() const {
+               assert(m_node);
+               return m_node;
+       }
+
+       node_iterator& operator++() {
+               assert(m_node);
+               m_node = m_node->next_sibling();
+               return *this;
+       }
+
+       node_iterator operator++(int) {
+               node_iterator tmp = *this;
+               ++this;
+               return tmp;
+       }
+
+       node_iterator& operator--() {
+               assert(m_node && m_node->previous_sibling());
+               m_node = m_node->previous_sibling();
+               return *this;
+       }
+
+       node_iterator operator--(int) {
+               node_iterator tmp = *this;
+               ++this;
+               return tmp;
+       }
+
+       bool operator ==(const node_iterator<Ch> &rhs) {
+               return m_node == rhs.m_node;
+       }
+
+       bool operator !=(const node_iterator<Ch> &rhs) {
+               return m_node != rhs.m_node;
+       }
+
+private:
+
+       xml_node<Ch> *m_node;
+
+};
+
+//! Iterator of child attributes of xml_node
+template<class Ch>
+class attribute_iterator {
+
+public:
+
+       typedef typename xml_attribute<Ch> value_type;
+       typedef typename xml_attribute<Ch> &reference;
+       typedef typename xml_attribute<Ch> *pointer;
+       typedef std::ptrdiff_t difference_type;
+       typedef std::bidirectional_iterator_tag iterator_category;
+
+       attribute_iterator() :
+                       m_attribute(0) {
+       }
+
+       attribute_iterator(xml_node<Ch> *node) :
+                       m_attribute(node->first_attribute()) {
+       }
+
+       reference operator *() const {
+               assert(m_attribute);
+               return *m_attribute;
+       }
+
+       pointer operator->() const {
+               assert(m_attribute);
+               return m_attribute;
+       }
+
+       attribute_iterator& operator++() {
+               assert(m_attribute);
+               m_attribute = m_attribute->next_attribute();
+               return *this;
+       }
+
+       attribute_iterator operator++(int) {
+               attribute_iterator tmp = *this;
+               ++this;
+               return tmp;
+       }
+
+       attribute_iterator& operator--() {
+               assert(m_attribute && m_attribute->previous_attribute());
+               m_attribute = m_attribute->previous_attribute();
+               return *this;
+       }
+
+       attribute_iterator operator--(int) {
+               attribute_iterator tmp = *this;
+               ++this;
+               return tmp;
+       }
+
+       bool operator ==(const attribute_iterator<Ch> &rhs) {
+               return m_attribute == rhs.m_attribute;
+       }
+
+       bool operator !=(const attribute_iterator<Ch> &rhs) {
+               return m_attribute != rhs.m_attribute;
+       }
+
+private:
+
+       xml_attribute<Ch> *m_attribute;
+
+};
+
+}
+
+#endif
diff --git a/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_print.hpp b/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_print.hpp
new file mode 100755 (executable)
index 0000000..8cc696f
--- /dev/null
@@ -0,0 +1,426 @@
+#ifndef RAPIDXML_PRINT_HPP_INCLUDED
+#define RAPIDXML_PRINT_HPP_INCLUDED
+
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+// Version 1.13
+// Revision $DateTime: 2009/05/13 01:46:17 $
+//! \file rapidxml_print.hpp This file contains rapidxml printer implementation
+
+#include "rapidxml.hpp"
+
+// Only include streams if not disabled
+#ifndef RAPIDXML_NO_STREAMS
+#include <ostream>
+#include <iterator>
+#endif
+
+namespace rapidxml {
+
+///////////////////////////////////////////////////////////////////////
+// Printing flags
+
+const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.
+
+///////////////////////////////////////////////////////////////////////
+// Internal
+
+//! \cond internal
+namespace internal {
+
+///////////////////////////////////////////////////////////////////////////
+// Internal character operations
+
+// Copy characters from given range to given output iterator
+template<class OutIt, class Ch>
+inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out) {
+       while (begin != end)
+               *out++ = *begin++;
+       return out;
+}
+
+// Copy characters from given range to given output iterator and expand
+// characters into references (&lt; &gt; &apos; &quot; &amp;)
+template<class OutIt, class Ch>
+inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand,
+    OutIt out) {
+       while (begin != end) {
+               if (*begin == noexpand) {
+                       *out++ = *begin;    // No expansion, copy character
+               } else {
+                       switch (*begin) {
+                               case Ch('<'):
+                                       *out++ = Ch('&');
+                                       *out++ = Ch('l');
+                                       *out++ = Ch('t');
+                                       *out++ = Ch(';');
+                                       break;
+                               case Ch('>'):
+                                       *out++ = Ch('&');
+                                       *out++ = Ch('g');
+                                       *out++ = Ch('t');
+                                       *out++ = Ch(';');
+                                       break;
+                               case Ch('\''):
+                                       *out++ = Ch('&');
+                                       *out++ = Ch('a');
+                                       *out++ = Ch('p');
+                                       *out++ = Ch('o');
+                                       *out++ = Ch('s');
+                                       *out++ = Ch(';');
+                                       break;
+                               case Ch('"'):
+                                       *out++ = Ch('&');
+                                       *out++ = Ch('q');
+                                       *out++ = Ch('u');
+                                       *out++ = Ch('o');
+                                       *out++ = Ch('t');
+                                       *out++ = Ch(';');
+                                       break;
+                               case Ch('&'):
+                                       *out++ = Ch('&');
+                                       *out++ = Ch('a');
+                                       *out++ = Ch('m');
+                                       *out++ = Ch('p');
+                                       *out++ = Ch(';');
+                                       break;
+                               default:
+                                       *out++ = *begin;    // No expansion, copy character
+                       }
+               }
+               ++begin;    // Step to next character
+       }
+       return out;
+}
+
+// Fill given output iterator with repetitions of the same character
+template<class OutIt, class Ch>
+inline OutIt fill_chars(OutIt out, int n, Ch ch) {
+       for (int i = 0; i < n; ++i)
+               *out++ = ch;
+       return out;
+}
+
+// Find character
+template<class Ch, Ch ch>
+inline bool find_char(const Ch *begin, const Ch *end) {
+       while (begin != end)
+               if (*begin++ == ch) return true;
+       return false;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Internal printing operations
+
+// Print node
+template<class OutIt, class Ch>
+inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       // Print proper node type
+       switch (node->type()) {
+
+               // Document
+               case node_document:
+                       out = print_children(out, node, flags, indent);
+                       break;
+
+                       // Element
+               case node_element:
+                       out = print_element_node(out, node, flags, indent);
+                       break;
+
+                       // Data
+               case node_data:
+                       out = print_data_node(out, node, flags, indent);
+                       break;
+
+                       // CDATA
+               case node_cdata:
+                       out = print_cdata_node(out, node, flags, indent);
+                       break;
+
+                       // Declaration
+               case node_declaration:
+                       out = print_declaration_node(out, node, flags, indent);
+                       break;
+
+                       // Comment
+               case node_comment:
+                       out = print_comment_node(out, node, flags, indent);
+                       break;
+
+                       // Doctype
+               case node_doctype:
+                       out = print_doctype_node(out, node, flags, indent);
+                       break;
+
+                       // Pi
+               case node_pi:
+                       out = print_pi_node(out, node, flags, indent);
+                       break;
+
+                       // Unknown
+               default:
+                       assert(0);
+                       break;
+       }
+
+       // If indenting not disabled, add line break after node
+       if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out;
+
+       // Return modified iterator
+       return out;
+}
+
+// Print children of the node                               
+template<class OutIt, class Ch>
+inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       for (xml_node<Ch> *child = node->first_node(); child;
+           child = child->next_sibling())
+               out = print_node(out, child, flags, indent);
+       return out;
+}
+
+// Print attributes of the node
+template<class OutIt, class Ch>
+inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags) {
+       for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute;
+           attribute = attribute->next_attribute()) {
+               if (attribute->name() && attribute->value()) {
+                       // Print attribute name
+                       *out = Ch(' '), ++out;
+                       out = copy_chars(attribute->name(),
+                           attribute->name() + attribute->name_size(), out);
+                       *out = Ch('='), ++out;
+                       // Print attribute value using appropriate quote type
+                       if (find_char<Ch, Ch('"')>(attribute->value(),
+                           attribute->value() + attribute->value_size())) {
+                               *out = Ch('\''), ++out;
+                               out = copy_and_expand_chars(attribute->value(),
+                                   attribute->value() + attribute->value_size(), Ch('"'), out);
+                               *out = Ch('\''), ++out;
+                       } else {
+                               *out = Ch('"'), ++out;
+                               out = copy_and_expand_chars(attribute->value(),
+                                   attribute->value() + attribute->value_size(), Ch('\''), out);
+                               *out = Ch('"'), ++out;
+                       }
+               }
+       }
+       return out;
+}
+
+// Print data node
+template<class OutIt, class Ch>
+inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       assert(node->type() == node_data);
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       out = copy_and_expand_chars(node->value(), node->value() + node->value_size(),
+           Ch(0), out);
+       return out;
+}
+
+// Print data node
+template<class OutIt, class Ch>
+inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       assert(node->type() == node_cdata);
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       *out = Ch('<');
+       ++out;
+       *out = Ch('!');
+       ++out;
+       *out = Ch('[');
+       ++out;
+       *out = Ch('C');
+       ++out;
+       *out = Ch('D');
+       ++out;
+       *out = Ch('A');
+       ++out;
+       *out = Ch('T');
+       ++out;
+       *out = Ch('A');
+       ++out;
+       *out = Ch('[');
+       ++out;
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);
+       *out = Ch(']');
+       ++out;
+       *out = Ch(']');
+       ++out;
+       *out = Ch('>');
+       ++out;
+       return out;
+}
+
+// Print element node
+template<class OutIt, class Ch>
+inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       assert(node->type() == node_element);
+
+       // Print element name and attributes, if any
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       *out = Ch('<'), ++out;
+       out = copy_chars(node->name(), node->name() + node->name_size(), out);
+       out = print_attributes(out, node, flags);
+
+       // If node is childless
+       if (node->value_size() == 0 && !node->first_node()) {
+               // Print childless node tag ending
+               *out = Ch('/'), ++out;
+               *out = Ch('>'), ++out;
+       } else {
+               // Print normal node tag ending
+               *out = Ch('>'), ++out;
+
+               // Test if node contains a single data node only (and no other nodes)
+               xml_node<Ch> *child = node->first_node();
+               if (!child) {
+                       // If node has no children, only print its value without indenting
+                       out = copy_and_expand_chars(node->value(),
+                           node->value() + node->value_size(), Ch(0), out);
+               } else if (child->next_sibling() == 0 && child->type() == node_data) {
+                       // If node has a sole data child, only print its value without indenting
+                       out = copy_and_expand_chars(child->value(),
+                           child->value() + child->value_size(), Ch(0), out);
+               } else {
+                       // Print all children with full indenting
+                       if (!(flags & print_no_indenting)) *out = Ch('\n'), ++out;
+                       out = print_children(out, node, flags, indent + 1);
+                       if (!(flags & print_no_indenting))
+                         out = fill_chars(out, indent, Ch('\t'));
+               }
+
+               // Print node end
+               *out = Ch('<'), ++out;
+               *out = Ch('/'), ++out;
+               out = copy_chars(node->name(), node->name() + node->name_size(), out);
+               *out = Ch('>'), ++out;
+       }
+       return out;
+}
+
+// Print declaration node
+template<class OutIt, class Ch>
+inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node,
+    int flags, int indent) {
+       // Print declaration start
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       *out = Ch('<'), ++out;
+       *out = Ch('?'), ++out;
+       *out = Ch('x'), ++out;
+       *out = Ch('m'), ++out;
+       *out = Ch('l'), ++out;
+
+       // Print attributes
+       out = print_attributes(out, node, flags);
+
+       // Print declaration end
+       *out = Ch('?'), ++out;
+       *out = Ch('>'), ++out;
+
+       return out;
+}
+
+// Print comment node
+template<class OutIt, class Ch>
+inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       assert(node->type() == node_comment);
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       *out = Ch('<'), ++out;
+       *out = Ch('!'), ++out;
+       *out = Ch('-'), ++out;
+       *out = Ch('-'), ++out;
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);
+       *out = Ch('-'), ++out;
+       *out = Ch('-'), ++out;
+       *out = Ch('>'), ++out;
+       return out;
+}
+
+// Print doctype node
+template<class OutIt, class Ch>
+inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       assert(node->type() == node_doctype);
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       *out = Ch('<'), ++out;
+       *out = Ch('!'), ++out;
+       *out = Ch('D'), ++out;
+       *out = Ch('O'), ++out;
+       *out = Ch('C'), ++out;
+       *out = Ch('T'), ++out;
+       *out = Ch('Y'), ++out;
+       *out = Ch('P'), ++out;
+       *out = Ch('E'), ++out;
+       *out = Ch(' '), ++out;
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);
+       *out = Ch('>'), ++out;
+       return out;
+}
+
+// Print pi node
+template<class OutIt, class Ch>
+inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags,
+    int indent) {
+       assert(node->type() == node_pi);
+       if (!(flags & print_no_indenting)) out = fill_chars(out, indent, Ch('\t'));
+       *out = Ch('<'), ++out;
+       *out = Ch('?'), ++out;
+       out = copy_chars(node->name(), node->name() + node->name_size(), out);
+       *out = Ch(' '), ++out;
+       out = copy_chars(node->value(), node->value() + node->value_size(), out);
+       *out = Ch('?'), ++out;
+       *out = Ch('>'), ++out;
+       return out;
+}
+
+}
+//! \endcond
+
+///////////////////////////////////////////////////////////////////////////
+// Printing
+
+//! Prints XML to given output iterator.
+//! \param out Output iterator to print to.
+//! \param node Node to be printed. Pass xml_document to print entire document.
+//! \param flags Flags controlling how XML is printed.
+//! \return Output iterator pointing to position immediately after last character of printed text.
+template<class OutIt, class Ch>
+inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0) {
+       return internal::print_node(out, &node, flags, 0);
+}
+
+#ifndef RAPIDXML_NO_STREAMS
+
+//! Prints XML to given output stream.
+//! \param out Output stream to print to.
+//! \param node Node to be printed. Pass xml_document to print entire document.
+//! \param flags Flags controlling how XML is printed.
+//! \return Output stream.
+template<class Ch>
+inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out,
+    const xml_node<Ch> &node, int flags = 0) {
+       print(std::ostream_iterator < Ch > (out), node, flags);
+       return out;
+}
+
+//! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
+//! \param out Output stream to print to.
+//! \param node Node to be printed.
+//! \return Output stream.
+template<class Ch>
+inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out,
+    const xml_node<Ch> &node) {
+       return print(out, node);
+}
+
+#endif
+
+}
+
+#endif
diff --git a/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_utils.hpp b/simulatordaemon/src/TABinaryManager/rapidxml/rapidxml_utils.hpp
new file mode 100755 (executable)
index 0000000..53fe0de
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef RAPIDXML_UTILS_HPP_INCLUDED
+#define RAPIDXML_UTILS_HPP_INCLUDED
+
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+// Version 1.13
+// Revision $DateTime: 2009/05/13 01:46:17 $
+//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful
+//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective.
+
+#include "rapidxml.hpp"
+#include <vector>
+#include <string>
+#include <fstream>
+#include <stdexcept>
+
+namespace rapidxml {
+
+//! Represents data loaded from a file
+template<class Ch = char>
+class file {
+
+public:
+
+       //! Loads file into the memory. Data will be automatically destroyed by the destructor.
+       //! \param filename Filename to load.
+       file(const char *filename) {
+               using namespace std;
+
+               // Open stream
+               basic_ifstream<Ch> stream(filename, ios::binary);
+               if (!stream) throw runtime_error(string("cannot open file ") + filename);
+               stream.unsetf(ios::skipws);
+
+               // Determine stream size
+               stream.seekg(0, ios::end);
+               size_t size = stream.tellg();
+               stream.seekg(0);
+
+               // Load data and add terminating 0
+               m_data.resize(size + 1);
+               stream.read(&m_data.front(), static_cast<streamsize>(size));
+               m_data[size] = 0;
+       }
+
+       //! Loads file into the memory. Data will be automatically destroyed by the destructor
+       //! \param stream Stream to load from
+       file(std::basic_istream<Ch> &stream) {
+               using namespace std;
+
+               // Load data and add terminating 0
+               stream.unsetf(ios::skipws);
+               m_data.assign(istreambuf_iterator < Ch > (stream),
+                   istreambuf_iterator<Ch>());
+               if (stream.fail() || stream.bad())
+                 throw runtime_error("error reading stream");
+               m_data.push_back(0);
+       }
+
+       //! Gets file data.
+       //! \return Pointer to data of file.
+       Ch *data() {
+               return &m_data.front();
+       }
+
+       //! Gets file data.
+       //! \return Pointer to data of file.
+       const Ch *data() const {
+               return &m_data.front();
+       }
+
+       //! Gets file data size.
+       //! \return Size of file data, in characters.
+       std::size_t size() const {
+               return m_data.size();
+       }
+
+private:
+
+       std::vector<Ch> m_data;   // File data
+
+};
+
+//! Counts children of node. Time complexity is O(n).
+//! \return Number of children of node
+template<class Ch>
+inline std::size_t count_children(xml_node<Ch> *node) {
+       xml_node<Ch> *child = node->first_node();
+       std::size_t count = 0;
+       while (child) {
+               ++count;
+               child = child->next_sibling();
+       }
+       return count;
+}
+
+//! Counts attributes of node. Time complexity is O(n).
+//! \return Number of attributes of node
+template<class Ch>
+inline std::size_t count_attributes(xml_node<Ch> *node) {
+       xml_attribute<Ch> *attr = node->first_attribute();
+       std::size_t count = 0;
+       while (attr) {
+               ++count;
+               attr = attr->next_attribute();
+       }
+       return count;
+}
+
+}
+
+#endif
diff --git a/simulatordaemon/src/TAFactory.cpp b/simulatordaemon/src/TAFactory.cpp
new file mode 100755 (executable)
index 0000000..2572bd8
--- /dev/null
@@ -0,0 +1,440 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAFactory.cpp
+ *
+ *    Description:  TAFactory class
+ *
+ *        Version:  1.0
+ *        Created:  28 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TAFactory.h"
+#include "ResponseCommands/ResMakeCommand.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+// instLock for TA Factory instance
+pthread_mutex_t instLock;
+// Initialize TA Factory instance as NULL
+TAFactory *TAFactory::instance = NULL;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * TAFactory constructer. TA Factory Instance is created
+ */
+TAFactory::TAFactory() {
+       // Starting value for TA Instance ID set to 101
+       InstID = 101;
+
+       /* Initialize the lock for TA Instance Map (mTAInstanceMap), instance ID
+        * (instID) and TA Factory instance (instance)
+        */
+       pthread_rwlock_init(&mTAInstanceMapLock, NULL);
+       pthread_rwlock_init(&instIDLock, NULL);
+       pthread_mutex_init(&instLock, NULL);
+}
+
+/**
+ * Get TA Factory Instance. If called for first time then create a TA Factory
+ * instance and return the instance else return the already created instance.
+ */
+TAFactory* TAFactory::getInstance() {
+
+       LOGD(SIM_DAEMON, "Entry");
+       pthread_mutex_lock(&instLock);
+       bool result;
+
+       // Check if the instance is not yet craeted
+       if (NULL == instance) {
+               // Create a new instance of TA Binary Manager
+               TABinaryManager *TABin = TABinaryManager::getInstance();
+               // Initialize TA Binary Manager
+               result = TABin->initBinaryManager();
+               if (true != result) {
+                       LOGD(SIM_DAEMON, "initBinaryManager FAILED");
+                       pthread_mutex_unlock(&instLock);
+                       return instance;
+               }
+               // Create a new instance of TA Factory
+               instance = new TAFactory();
+       }
+       pthread_mutex_unlock(&instLock);
+       return instance;
+}
+
+/**
+ * Get a TA Instance for the UUID sent as the argument
+ * @param uuid TEEC_UUID for the TA instance to be returned
+ * @param session Session which requested the TA Instance to be associated
+ * with it
+ */
+TAInstancePtr TAFactory::getTAInstance(TEEC_UUID uuid, ISession* session) {
+
+       TAInstancePtr TAInst;
+       bool result;
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Get TA Binary Manager instance
+       TABinaryManager *TABin = TABinaryManager::getInstance();
+       // Get TEEC_UUID format uuid converted to string form
+       string TAUUID = TABin->getUUIDAsString(uuid);
+
+       // Change to upper char. TA list has upper char.
+       locale loc;
+    for (size_t i=0; i<TAUUID.length(); ++i)
+       TAUUID[i] = toupper(TAUUID[i],loc);
+
+
+       if ((!checkIfTARunning(TAUUID))
+           || ((TABin->isSingleInstance(TAUUID, result) == 0) && (result == false))) {
+               /* TA instance is not already alive or is Multi Instance, Create a new TA
+                * Instance
+                */
+               TAInst = createUninitalizedTAInstance(TAUUID, session);
+               if (!TAInst == true) {
+                       LOGE(SIM_DAEMON, "Creating Trusted Application Instance FAILED");
+                       return TAInstancePtr();
+               }
+       } else if ((TABin->isSingleInstance(TAUUID, result) == 0)
+           && (result == true)) {
+               // TA is Single Instance and alive
+               if (TABin->isMultipleSession(TAUUID, result) < 0) {
+                       LOGE(SIM_DAEMON, "TA not in list");
+                       return TAInstancePtr();
+               } else {
+                       multimap<string, TAInstancePtr>::iterator it;
+                       // Find alive TA Instance in TA Factory's Instance Map
+                       it = mTAInstanceMap.find(TAUUID);
+                       if (it != mTAInstanceMap.end()) {
+                               TAInst = it->second;
+                               TAInst->takeSessionMapLock();
+                               if ((result == true)
+                                               || ((result == false) && (it->second->getSessionMapSize() == 0))) {
+                                       /* TA is alive Single Instance and either it is MultiSession or
+                                        * has no session associated to it
+                                        */
+
+                                       if (!TAInst == true) {
+                                               LOGE(SIM_DAEMON, "Creating Trusted Application Instance FAILED");
+                                               TAInst->releaseSessionMapLock();
+                                               return TAInstancePtr();
+                                       }
+                                       TAInst->releaseSessionMapLock();
+                               } else {
+                                       LOGE(SIM_DAEMON, "TA Single Instance Single Session - "
+                                                       "multiple connections not supported");
+                                       TAInst->releaseSessionMapLock();
+                                       return TAInstancePtr();
+                               }
+                       } else {
+                               LOGE(SIM_DAEMON, "Trusted Application Instance not found.");
+                               return TAInstancePtr();
+                       }
+               }
+       } else {
+               LOGE(SIM_DAEMON, "TA not in list");
+               return TAInstancePtr();
+       }
+       TAInst->takeSessionMapLock();
+       // Add session to the Session Map of TA Instance
+       TAInst->insertSessionMap(session);
+       TAInst->releaseSessionMapLock();
+       return TAInst;
+}
+
+/**
+ * Check if TA already alive. Return true if it is present in the TA Instance
+ * Map else return false
+ * @param TAUUID TA UUID in string form
+ */
+bool TAFactory::checkIfTARunning(string TAUUID) {
+
+       LOGD(SIM_DAEMON, "Entry");
+       bool result = false;
+
+       // Find TA UUID in the TA Instance Map
+       multimap<string, TAInstancePtr>::iterator itr;
+       itr = mTAInstanceMap.find(TAUUID);
+       if (itr != mTAInstanceMap.end()) result = true;
+       return result;
+}
+
+/**
+ * Create a new TA Instance by launching the TA specified by TA UUID
+ * @param TAUUID TA UUID in string form
+ * @param session Session which requested the TA Instance to be associated
+ * with it
+ */
+TAInstancePtr TAFactory::createUninitalizedTAInstance(string TAUUID,
+               ISession* session) {
+
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Initialize PID to -1
+       pid_t pid = -1;
+       // Set default values for TA configuration variables
+       bool debug = false;
+       bool alive = false;
+       bool singleInst = false;
+       TEEC_Result result = TEEC_ERROR_COMMUNICATION;
+
+       TABinaryManager *TABin = TABinaryManager::getInstance();
+       pthread_rwlock_wrlock(&instIDLock);
+
+       /* Generate the endpoint name using UUID and Instance ID to be sent to
+        * TEEStub for socket connection
+        */
+       std::stringstream str;
+       str << TAUUID << "-";
+       str << InstID;
+
+       if (launchTA(TAUUID, str, debug, pid)) {
+               // TA is launched successfully, Create a new instance of TAInstance class
+
+               /* Check if TA is to be keep alive and accordingly set TAInstance's
+                * member variable isKeepAlive
+                */
+               if (TABin->isSingleInstance(TAUUID, singleInst) < 0) {
+                       LOGE(SIM_DAEMON, "TA not in list");
+                       pthread_rwlock_unlock(&instIDLock);
+                       return TAInstancePtr();
+               } else if (singleInst == true) {
+                       /* If TA is single Instance and KeepAlive then set TAInstance's member
+                        * variable isKeepAlive to true.
+                        * Even if TA is KeepAlive but MultiInstance, set TAInstance's member
+                        * variable isKeepAlive to false.
+                        */
+                       if (TABin->isKeepAlive(TAUUID, alive) < 0) {
+                               LOGE(SIM_DAEMON, "TA not in list");
+                               // Kill the launched TA
+                               if (pid > 0) {
+                                       kill(pid, SIGKILL);
+                                       while (kill(pid, 0) != -1);
+                                       LOGD(SIM_DAEMON, "TA process exited");
+                               }
+                               pthread_rwlock_unlock(&instIDLock);
+                               return TAInstancePtr();
+                       }
+               }
+
+               /* Update TAInstance's member variable isDebug according to the property
+                * set in manifest file for TA
+                * Update TAInstance's member variable mTAInstanceID with the assigned
+                * Instance ID
+                */
+
+               // Update TAInstance member variable mPID with the launched TA PID
+               TAInstancePtr TAInst;
+               TAInst = TAInstancePtr(new TAInstance(pid, alive, debug, InstID, ioService::getInstance()));
+               // Increment the Instance ID variable for assigning to next TA Instance
+               InstID++;
+               if (TEEC_SUCCESS != TAInst->connecttoTA(str)) {
+                       LOGE(SIM_DAEMON, "Connection to TA FAILED");
+                       TAInst->killTA();
+                       pthread_rwlock_unlock(&instIDLock);
+                       return TAInstancePtr();
+               }
+               // Connected to TA through socket
+
+               /* Check if TAInstance is newly created or an old instance is being re-used.
+                * If new instance then send CREATE command to the TA.
+                * TaInstance member variable isCreated is used to find if the TAInstance is
+                * newly created or re-used.
+                */
+               if (TAInst->getCreated() == false) {
+                       /* TA is launched uninitialised and CreateTAEntryPoint has not been
+                        * called yet for this TA Instance, send request for CreateTAEntryPoint
+                        */
+                       CreateTAEntryPointData cdata;
+                       memset(&cdata, 0, sizeof(CreateTAEntryPointData));
+                       cdata.sessionID = session->getSessionID();
+                       cdata.returnValue = TEE_ERROR_GENERIC;
+
+                       // Send CREATE command to TA
+                       result = TAInst->sendRequestToTA(CREATE, (void*)&cdata,
+                           sizeof(CreateTAEntryPointData));
+                       if (result != TEEC_SUCCESS) {
+                               LOGE(SIM_DAEMON, "Create sendRequestToTA FAILED\n");
+                               // Kill the launched TA
+                               TAInst->killTA();
+                               pthread_rwlock_unlock(&instIDLock);
+                               return TAInstancePtr();
+                       }
+               }
+               pthread_rwlock_unlock(&instIDLock);
+
+               // Add the TAInstance in the TA Factory's TA Instance Map
+               mTAInstanceMap.insert(pair<string, TAInstancePtr>(TAUUID, TAInst));
+               return TAInst;
+       }
+       pthread_rwlock_unlock(&instIDLock);
+       return TAInstancePtr();
+}
+
+/**
+ * Thread routine for handling TA exit (immature/mature exit)
+ * @param pid pointer to the PID of the launched TA
+ */
+void* TAFactory::waitForChild(void *pid) {
+
+       pid_t PID = *(pid_t*)pid;
+       int32_t childStatus;
+
+       // Wait for PID to exit
+       waitpid(PID, &childStatus, 0);
+       LOGD(SIM_DAEMON, "PID %d exited", PID);
+       if (instance != NULL) {
+               // Clean (handle immature termination of) TA
+               instance->cleanupTAInstance(PID);
+       }
+       return NULL;
+}
+
+/**
+ * Clean (handle immature termination of) TA by sending response for all the
+ * pending commands for the TA and deleting the TA instance
+ * @param pid pointer to the PID of the exited TA
+ */
+void TAFactory::cleanupTAInstance(pid_t PID) {
+
+       LOGD(SIM_DAEMON, "Entry");
+       TAInstancePtr Inst;
+
+       // Find the TA instance associated with the argument PID
+       multimap<string, TAInstancePtr>::iterator itInstanceMap;
+       for (itInstanceMap = mTAInstanceMap.begin();
+           itInstanceMap != mTAInstanceMap.end(); itInstanceMap++) {
+               if (itInstanceMap->second->getPID() == PID) {
+                       Inst = itInstanceMap->second;
+                       break;
+               }
+       }
+
+       if (!Inst == false) {
+               /* TA instance is found for the PID argument.
+                * Check if there are any commands pending for TA response and send the
+                * failure response back to CA if the response is pending and TA has exited
+                */
+               Inst->cleanup();
+               // Remove the TA Instance from the TA Instance Map maintained in TA Factory
+               pthread_rwlock_wrlock(&mTAInstanceMapLock);
+               multimap<string, TAInstancePtr>::iterator itMap;
+               for (itMap = mTAInstanceMap.begin(); itMap != mTAInstanceMap.end();
+                   ++itMap) {
+                       if (itMap->second == Inst) {
+                               mTAInstanceMap.erase(itMap);
+                               break;
+                       }
+               }
+               pthread_rwlock_unlock(&mTAInstanceMapLock);
+       }
+}
+
+/**
+ * Launch the TA instance
+ * @param TAUUID TA UUID is string format
+ * @param str string containing the endpoint name to be passed as an argument
+ * to TA while launching
+ * @param debug debug flag
+ * @param pid PID to be update for launched TA
+ */
+bool TAFactory::launchTA(string TAUUID, std::stringstream& str, bool debug,
+    pid_t& pid) {
+
+       int32_t result = -1;
+       pthread_t thread;
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Get TABinaryManager instance
+       TABinaryManager *TABin = TABinaryManager::getInstance();
+       // Get TA Image path for launching
+       string argvPath = TABin->getImagePath(TAUUID);
+       if ("" == argvPath) {
+               LOGE(SIM_DAEMON, "Trusted Application does not exist");
+               return false;
+       }
+       char *envp[1];
+
+       // Argument to be passed to TA main (TEEStub main)
+       string argvName = str.str().c_str();
+
+       // Get the port to be assigned to TA if TA is to be launched in debug mode
+       string argvPort = TABin->getPort(TAUUID);
+
+       pthread_mutex_lock(&TABin->taLock);
+       //Check if the TA is to be launched in debug mode or release mode
+       if (argvPort != "") { // DEBUG MODE
+               debug = true;
+               char *argv[5];
+               string argvGDB = "/usr/bin/gdbserver";
+               string argvHost = "localhost:" + argvPort;
+
+               argv[0] = &argvGDB[0];
+               argv[1] = &argvHost[0];
+               argv[2] = &argvPath[0];
+               argv[3] = &argvName[0];
+               argv[4] = NULL;
+
+               // fork TA with GDB
+               pid = fork();
+               if (0 == pid) {
+                       LOGD(SIM_DAEMON, "In Child Process");
+                       execv(argv[0], argv);
+                       LOGE(SIM_DAEMON, "Launching Trusted Application FAILED");
+                       pthread_mutex_unlock(&TABin->taLock);
+                       return false;
+               }
+               LOGD(SIM_DAEMON, "In Parent Process");
+       } else { //RELEASE MODE
+               char *argv[3];
+               argv[0] = &argvPath[0];
+               argv[1] = &argvName[0];
+               argv[2] = NULL;
+               envp[0] = NULL;
+
+               // Spawn TA
+               result = posix_spawn(&pid, argv[0], NULL, NULL, argv, envp);
+               if (result == 0) {
+                       LOGD(SIM_DAEMON, "TA pid: %i\n", pid);
+                       LOGD(SIM_DAEMON, "Launched Trusted Application");
+               } else {
+                       LOGE(SIM_DAEMON, "Launching Trusted Application FAILED");
+                       pthread_mutex_unlock(&TABin->taLock);
+                       return false;
+               }
+       }
+       pthread_mutex_unlock(&TABin->taLock);
+       // Create a thread to wait for TA exit
+       pthread_attr_t attr;
+       int s = pthread_attr_init(&attr);
+       if (s != 0)
+               LOGE(SIM_DAEMON, "pthread_attr_init");
+       s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+       if (s != 0)
+               LOGE(SIM_DAEMON, "pthread_attr_setdetachstate");
+       pthread_create(&thread, &attr, TAFactory::waitForChild, (void *)&pid);
+       return true;
+}
+
+TAFactory::~TAFactory() {
+       /* Destroy the locks created for TAInstance map (mTAInstanceMap), Instance
+        * Id (InstID) and TA Factory Instance (instance)
+        */
+       pthread_rwlock_destroy(&mTAInstanceMapLock);
+       pthread_rwlock_destroy(&instIDLock);
+       pthread_mutex_destroy(&instLock);
+}
diff --git a/simulatordaemon/src/TAInstance.cpp b/simulatordaemon/src/TAInstance.cpp
new file mode 100755 (executable)
index 0000000..f8733a7
--- /dev/null
@@ -0,0 +1,444 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TAInstance.cpp
+ *
+ *    Description:  TAInstance class
+ *
+ *        Version:  1.0
+ *        Created:  28 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TAInstance.h"
+#include "ResponseCommands/ResMakeCommand.h"
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * TAInstance constructer. TA Instance is created for each launched TA instance
+ * @param client_io_service IO service to handle the connection with TA
+ */
+TAInstance::TAInstance(uint32_t pid, bool alive, bool debug, uint32_t InstID, boost::asio::io_service& client_io_service) :
+mTAConnectionSocket(client_io_service) {
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Initialize the lock for Session map (mSessionMap)
+       pthread_rwlock_init(&mSessionMapLock, NULL);
+       // Initialize the lock for Command map (mCommandMap)
+       pthread_rwlock_init(&mCommandMapLock, NULL);
+       // Initialize the lock for sendRequesttoTA (sendLock)
+       pthread_mutex_init(&sendLock, NULL);
+       // Set the config variables to default
+       isCreated = false;
+       isKeepAlive = alive;
+       isDebug = debug;
+       mPID = pid;
+       mTAInstanceID = InstID;
+       mCommandMap.clear();
+}
+
+bool TAInstance::checkKeepAlive() {
+       return isKeepAlive;
+}
+
+bool TAInstance::getCreated() {
+       return isCreated;
+}
+
+void TAInstance::setCreated(bool value) {
+       isCreated = value;
+}
+
+pid_t TAInstance::getPID() {
+       return mPID;
+}
+
+void TAInstance::takeSessionMapLock() {
+       pthread_rwlock_wrlock(&mSessionMapLock);
+}
+
+void TAInstance::releaseSessionMapLock() {
+       pthread_rwlock_unlock(&mSessionMapLock);
+}
+
+void TAInstance::eraseSessionMap(uint32_t sessID) {
+       map<uint32_t, ISession*>::iterator it;
+       // remove the session from the TA Instance's Session Map
+       it = mSessionMap.find(sessID);
+       mSessionMap.erase(it);
+}
+
+uint32_t TAInstance::getSessionMapSize() {
+       return mSessionMap.size();
+}
+
+void TAInstance::insertSessionMap(ISession* session) {
+       mSessionMap[session->getSessionID()] = session;
+}
+
+void TAInstance::insertCommand(SIM_COMMAND cmd, cmdData data) {
+       pthread_rwlock_wrlock(&mCommandMapLock);
+       mCommandMap.insert(pair<SIM_COMMAND, cmdData>(cmd, data));
+       pthread_rwlock_unlock(&mCommandMapLock);
+}
+
+void TAInstance::eraseCommand(SIM_COMMAND cmd, uint32_t sessID) {
+       multimap<SIM_COMMAND, cmdData>::iterator it;
+       pthread_rwlock_wrlock(&mCommandMapLock);
+       for (it = mCommandMap.begin();
+                       it != mCommandMap.end(); ++it) {
+               if ((it->first == cmd) && (it->second.csdata.sessionID == sessID)) {
+                       mCommandMap.erase(it);
+                       break;
+               }
+       }
+       pthread_rwlock_unlock(&mCommandMapLock);
+}
+
+void TAInstance::killTA() {
+       if (mPID > 0) {
+               kill(mPID, SIGKILL);
+               while (kill(mPID, 0) != -1);
+               LOGD(SIM_DAEMON, "TA process exited");
+       }
+}
+
+void TAInstance::cleanup() {
+       LOGD(SIM_DAEMON, "Entry");
+       multimap<SIM_COMMAND, cmdData>::iterator it;
+       for (it = mCommandMap.begin(); mCommandMap.size() != 0;) {
+               ResCommandBasePtr ptr;
+               /* Switch case to find the command which is pending and accordingly
+                * obtain the handle (ResMakeCommandPtr) to send the reponse to CA
+                */
+               switch (it->first) {
+                       case OPENSESSION:
+                               it->second.osdata.returnValue = TEEC_ERROR_TARGET_DEAD;
+                               ptr = ResMakeCommand::getCommand(it->first,
+                                               reinterpret_cast<void*>(&(it->second.osdata)),
+                                               &mSessionMap);
+                               break;
+                       case INVOKECOMMAND:
+                               it->second.icdata.returnValue = TEEC_ERROR_TARGET_DEAD;
+                               ptr = ResMakeCommand::getCommand(it->first,
+                                               reinterpret_cast<void*>(&(it->second.icdata)),
+                                               &mSessionMap);
+                               break;
+                       case REQCANCEL:
+                               ptr = ResMakeCommand::getCommand(it->first,
+                                               reinterpret_cast<void*>(&(it->second.rcdata)),
+                                               &mSessionMap);
+                               break;
+                       case CLOSESESSION:
+                               ptr = ResMakeCommand::getCommand(it->first,
+                                               reinterpret_cast<void*>(&(it->second.csdata)),
+                                               &mSessionMap);
+                               break;
+                       case COMMANDINVALID:
+                       case CREATE:
+                       case DESTROY:
+                       default:
+                               LOGE(SIM_DAEMON, "Invalid Command");
+                               break;
+               }
+               if (!ptr == false) {
+                       // Call the Session object to handle commands
+                       ptr->execute();
+               } else {
+                       LOGE(SIM_DAEMON, "Command not found");
+               }
+       }
+}
+
+/**
+ * Connect to TA as a client using the socket name created from UUID and
+ * Instance ID
+ * @param str Socket name
+ */
+TEEC_Result TAInstance::connecttoTA(std::stringstream& str) {
+
+       unsigned long int retry_count = 0;
+       try {
+               boost::system::error_code error = boost::asio::error::host_not_found;
+               stream_protocol::endpoint ep(string("/tmp/") + str.str());
+
+               LOGD(SIM_DAEMON, "Connect to TEEStub");
+               // Try to connect to TA RETRY_COUNT number of times
+               while (error && (retry_count < RETRY_COUNT)) {
+#if 0
+                       LOGD(SIM_DAEMON, "Trying to connect to TEEStub");
+                       LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
+                       LOGE(SIM_DAEMON, "Response returned with error code %s",
+                                       error.category().name());
+#endif
+                       mTAConnectionSocket.close();
+                       mTAConnectionSocket.connect(ep, error);
+                       retry_count++;
+               }
+               if (retry_count < RETRY_COUNT) {
+                       // Connection successful
+                       LOGD(SIM_DAEMON, "Connected to TEEStub");
+                       return TEEC_SUCCESS;
+               } else {
+                       // Retry count exceeded, connection failed
+                       LOGE(SIM_DAEMON, "Connection to TEEStub timed out");
+                       return TEEC_ERROR_COMMUNICATION;
+               }
+       } catch (std::exception& e) {
+               std::cerr << "Exception: " << e.what() << "\n";
+               return TEEC_ERROR_COMMUNICATION;
+       }
+}
+
+/**
+ * Send data to TA instance
+ * @param cmd Command enum
+ * @param data Data to be sent to TA
+ * @param size Size of data
+ */
+TEEC_Result TAInstance::sendRequestToTA(SIM_COMMAND cmd, void* data,
+    uint32_t size) {
+
+       LOGD(SIM_DAEMON, "Instance ID: %d", mTAInstanceID);
+       TEEC_Result result = TEEC_ERROR_TARGET_DEAD;
+       boost::system::error_code error = boost::asio::error::host_not_found;
+
+       pthread_mutex_lock (&sendLock);
+       // Send command to TEEStub for TA
+       boost::asio::write(mTAConnectionSocket,
+           boost::asio::buffer((char*)&cmd, sizeof(char)), error);
+       if ((!error) && (size != 0)) {
+               // Send command data to TEEStub for TA
+               boost::asio::write(mTAConnectionSocket,
+                   boost::asio::buffer((char*)data, size), error);
+               if (!error)
+                       result = TEEC_SUCCESS;
+               else {
+                       LOGE(SIM_DAEMON, "Error in writing Data to TA");
+                       LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
+                       LOGE(SIM_DAEMON, "Response returned with error code %s",
+                           error.category().name());
+               }
+       } else {
+               LOGE(SIM_DAEMON, "Error in writing Command to TA");
+               LOGE(SIM_DAEMON, "Response returned with error code %d", error.value());
+               LOGE(SIM_DAEMON, "Response returned with error code %s",
+                   error.category().name());
+       }
+       pthread_mutex_unlock(&sendLock);
+       return result;
+}
+
+/**
+ * Register an asynchronous callback to continuously receive data from TA
+ */
+void TAInstance::receiveResponseFromTA() {
+
+       currentState = CMD_READ;
+       /* Register an asynchronous callback 'handleRead' to continuously receive
+        * data from TA */
+       boost::asio::async_read(mTAConnectionSocket, boost::asio::buffer(readData),
+           boost::asio::transfer_exactly(1),
+           boost::bind(&TAInstance::handleRead, shared_from_this(),
+               boost::asio::placeholders::error,
+               boost::asio::placeholders::bytes_transferred));
+}
+
+/**
+ * On asynchronously reading from socket, this call back is executed.
+ * @param error Boost error code and error message object
+ * @param bytes_transferred Number of bytes read from the socket
+ */
+void TAInstance::handleRead(const boost::system::error_code& error,
+    size_t bytes_transferred) {
+
+       if (!error) {
+               /**
+                * A simple small state machine to parse command and handle its
+                * call back to TEECLib interface
+                * The state machine identifies the command. If valid, finds out how
+                * many bytes of data to be read further else if invalid, exits the
+                * Simulator Daemon.
+                *
+                * Later, exact number of identified size of data is read from
+                * stream and stored.
+                */
+               switch (currentState) {
+                       case CMD_READ: {
+                               // Identify command
+                               command = (SIM_COMMAND)readData.at(0);
+                               LOGD(SIM_DAEMON, "Command received: %d", (uint32_t )command);
+
+                               /* Calculate pending numbers of bytes pending to be read only for
+                                * commands
+                                */
+                               int32_t data_size = ResMakeCommand::getDataSize(command);
+
+                               if (data_size > 0) {
+                                       currentState = DATA_READ;
+                                       // read remaining bytes related to received valid command
+                                       boost::asio::async_read(mTAConnectionSocket,
+                                           boost::asio::buffer(readData),
+                                           boost::asio::transfer_exactly(data_size),
+                                           boost::bind(&TAInstance::handleRead, shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+                               else if (-1 == data_size) {
+                                       // else case is invalid command
+                                       /* TODO: Identify the correct behavior;
+                                        * what to do when invalid command is received?
+                                        */
+                                       LOGE(SIM_DAEMON, "Invalid command received!");
+                               } else if (0 == data_size) {
+                                       // reset state to read new command
+                                       currentState = CMD_READ;
+                                       // read command and register callback to read data
+                                       boost::asio::async_read(mTAConnectionSocket,
+                                           boost::asio::buffer(readData), boost::asio::transfer_exactly(1),
+                                           boost::bind(&TAInstance::handleRead, shared_from_this(),
+                                               boost::asio::placeholders::error,
+                                               boost::asio::placeholders::bytes_transferred));
+                               }
+                               break;
+                       } //case
+
+                       case DATA_READ: {
+                               // At this pouint32_t  data is completely read
+                               // clear the vector for the first time and copy server data received
+                               commandData.clear();
+                               for (uint32_t i = 0; i < readData.size(); i++) {
+                                       commandData.push_back(readData.at(i));
+                               }
+                               string tempData(commandData.begin(), commandData.end());
+
+                               // Get the Session object
+                               ResCommandBasePtr ptr = ResMakeCommand::getCommand(command,
+                                   (void*)tempData.c_str(), &mSessionMap);
+
+                               if (!ptr == false) {
+                                       // Call the Session object to handle commands
+                                       ptr->execute();
+                               } else {
+                                       LOGE(SIM_DAEMON, "Command not found");
+                               }
+
+                               // reset state to read new command
+                               currentState = CMD_READ;
+                               // read command and register callback to read data
+                               boost::asio::async_read(mTAConnectionSocket,
+                                   boost::asio::buffer(readData), boost::asio::transfer_exactly(1),
+                                   boost::bind(&TAInstance::handleRead, shared_from_this(),
+                                       boost::asio::placeholders::error,
+                                       boost::asio::placeholders::bytes_transferred));
+
+                               break;
+                       } //case
+               } //switch
+       }
+}
+
+/**
+ * Function call to set socket receive timeout
+ * @param timeout Timeout value to be set for the socket receive
+ */
+int32_t TAInstance::setSocketOpt(struct timeval timeout) {
+
+       int32_t result = 0;
+       if (isDebug == false) {
+               LOGD(SIM_DAEMON, "Entry");
+               //Set socket timeout for mTAConnectionSocket
+               result = setsockopt(mTAConnectionSocket.native(), SOL_SOCKET, SO_RCVTIMEO,
+                   (char*)&timeout, sizeof(timeout));
+               if (result < 0) {
+                       LOGE(SIM_DAEMON, "setsockopt timeout = %d FAILED", timeout.tv_usec);
+               }
+       }
+       return result;
+}
+
+/**
+ * Function call to receive create command response from TA instance
+ */
+TEEC_Result TAInstance::receiveCreateResponse() {
+
+       TEEC_Result result = TEEC_ERROR_COMMUNICATION;
+       boost::system::error_code ec = boost::asio::error::host_not_found;
+       struct timeval timeout;
+
+       //Set Socket timeout to 30 ms for receiving Create response
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 30000;
+
+       LOGD(SIM_DAEMON, "Entry");
+       if (!setSocketOpt(timeout)) {
+               // If no error is setting socket timeout, receive response command
+               boost::asio::read(mTAConnectionSocket, boost::asio::buffer(readData),
+                   boost::asio::transfer_exactly(1), ec);
+               if (!ec) {
+                       /* If no error is receiving create command response command,
+                        * receive response data */
+                       boost::asio::read(mTAConnectionSocket, boost::asio::buffer(readData),
+                           boost::asio::transfer_exactly(sizeof(CreateTAEntryPointData)), ec);
+                       if (!ec)
+                               result = TEEC_SUCCESS;
+                       else
+                       LOGE(SIM_DAEMON, "read data FAILED");
+               } else
+               LOGE(SIM_DAEMON, "read command FAILED");
+       } else {
+               LOGE(SIM_DAEMON, "Setting timeout failed");
+               return result;
+       }
+       //Set Socket timeout to default after receiving Create response
+       timeout.tv_usec = 0;
+       if (0 != setSocketOpt(timeout)) {
+               result = TEEC_ERROR_COMMUNICATION;
+               LOGE(SIM_DAEMON, "Setting timeout failed");
+       }
+       return result;
+}
+
+/**
+ * Function call to close socket connection with TA
+ */
+void TAInstance::closeConnectionToTA() {
+       LOGD(SIM_DAEMON, "Entry");
+       TEEC_Result result = TEEC_ERROR_COMMUNICATION;
+
+       boost::system::error_code ec;
+       
+       mTAConnectionSocket.close(ec);
+       if(!ec)
+               result = TEEC_SUCCESS;
+       else
+               LOGE(SIM_DAEMON, "TA Connection close FAILED");
+}
+
+/**
+ * TAInstance destructer. TA Instance is deleted when TA destroy command is
+ * called.
+ */
+TAInstance::~TAInstance() {
+       LOGD(SIM_DAEMON, "Entry");
+
+       // Close connection with TA
+       closeConnectionToTA();
+       // Destroy the lock created for Session map (mSessionMap)
+       pthread_rwlock_destroy (&mSessionMapLock);
+       // Destroy the lock created for Command map (mCommandMap)
+       pthread_rwlock_destroy (&mCommandMapLock);
+       // Destory the lock for sendRequesttoTA (sendLock)
+       pthread_mutex_destroy (&sendLock);
+}
diff --git a/simulatordaemon/src/TEEContext.cpp b/simulatordaemon/src/TEEContext.cpp
new file mode 100755 (executable)
index 0000000..3e352f7
--- /dev/null
@@ -0,0 +1,544 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  TEEContext.cpp
+ *
+ *    Description:  TEEContext class
+ *
+ *        Version:  1.0
+ *        Created:  16 April 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "TEEContext.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+pthread_rwlock_t sessIDLock = PTHREAD_RWLOCK_INITIALIZER;
+uint32_t sessID = 51;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * TEEContext constructer. TA Context is created for each InitContext API
+ * call from CA
+ * @param contextID ID for Context reference
+ * @param connSession ConnectionSession instance associated with the context
+ */
+TEEContext::TEEContext(uint32_t contextID, IConnectionSession* connSession) {
+
+       LOGD(SIM_DAEMON, "ContextID: %d", contextID);
+
+       /* Initialize the locks for shared memory list (mShmList) and Session map
+        * (mSessionMap) */
+       pthread_rwlock_init(&mShmListLock, NULL);
+       pthread_rwlock_init(&mSessionMapLock, NULL);
+
+       mConnSess = connSession;
+       mContextID = contextID;
+       isInternal = false;
+       /* Clear the shared memory list (mShmList) and Session map (mSessionMap) */
+       mSessionMap.clear();
+       mShmList.clear();
+}
+
+/**
+ * On InitContext API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for InitContext
+ */
+TEEC_Result TEEContext::initContext(InitContextData* data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Initialize Context is a request from CA, so the member variable
+        * isInternal of TEEContext is set to false.
+        */
+       isInternal = false;
+
+       /* Check if the TEEName is proper or not */
+       if (data->nameLength != 0) {
+               string TName(data->TEEName);
+
+               if (TName.compare(TEENAME) != 0) {
+                       data->returnValue = TEEC_ERROR_BAD_PARAMETERS;
+                       /* Write the response back to TEECLIB in case of failure */
+                       result = mConnSess->write(INITIALIZE_CONTEXT, (char*)data,
+                           sizeof(InitContextData));
+                       if (result != TEEC_SUCCESS) {
+                               LOGE(SIM_DAEMON, "Initialize Context response write to CA FAILED");
+                       }
+                       return result;
+               }
+       }
+       data->contextID = mContextID;
+       data->returnValue = TEEC_SUCCESS;
+
+       /* Write the response back to TEECLIB */
+       result = mConnSess->write(INITIALIZE_CONTEXT, (char*)data,
+           sizeof(InitContextData));
+       if (result != TEEC_SUCCESS) {
+               LOGE(SIM_DAEMON, "Initialize Context response write to CA FAILED");
+       }
+       return result;
+}
+
+/**
+ * On FinalizeContext API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for FinalizeContext
+ */
+void TEEContext::finContext(FinalizeContextData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Check if the Session map is empty i.e. if all the Sessions have
+        * been closed. If not closed, print an error, close the sessions in the
+        * list and clear the list.
+        */
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       if (!mSessionMap.empty()) {
+               LOGE(SIM_DAEMON, "Session running in the context\n");
+               pthread_rwlock_unlock(&mSessionMapLock);
+               map<uint32_t, ISession*>::iterator it;
+               for (it = mSessionMap.begin(); it != mSessionMap.end(); ++it) {
+                       CloseSessionData cdata;
+                       cdata.contextID = data.contextID;
+                       cdata.sessionID = it->first;
+                       result = closeSession(cdata);
+                       if (TEE_SUCCESS != result) {
+                               LOGE(SIM_DAEMON, "Finalize Context - close session FAILED Session ID = %d\n", it->first);
+                       }
+               }
+               pthread_rwlock_wrlock(&mSessionMapLock);
+               mSessionMap.clear();
+       }
+       pthread_rwlock_unlock(&mSessionMapLock);
+
+       /* Check if the Shared memory list is empty i.e. if all the memories have
+        * been released. If not released, print an error and clear the list.
+        */
+       pthread_rwlock_wrlock(&mShmListLock);
+       if (!mShmList.empty()) {
+               LOGE(SIM_DAEMON, "WSM not released");
+               mShmList.clear();
+       }
+       pthread_rwlock_unlock(&mShmListLock);
+
+       if (data.contextID != 0) {
+               /* Write the response back to TEECLIB */
+               result = mConnSess->write(FINALIZE_CONTEXT, (char*)&data,
+                   sizeof(FinalizeContextData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Finalize Context response write to CA FAILED");
+               }
+       }
+}
+
+/**
+ * On OpenSession API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for OpenSession
+ */
+TEEC_Result TEEContext::openSession(OpenSessionData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+
+       LOGD(SIM_DAEMON, "Entry");
+       data.returnOrigin = TEEC_ORIGIN_TEE;
+       data.returnValue = TEEC_ERROR_GENERIC;
+       pthread_rwlock_wrlock(&sessIDLock);
+       data.sessionID = sessID;
+       sessID++;
+       pthread_rwlock_unlock(&sessIDLock);
+
+       /* Create a new Session instance */
+       ISession *mSession = new Session(this);
+
+       /* Call session createSession function to handle open session request */
+       result = mSession->createSession(data);
+       if (TEEC_SUCCESS != result) {
+               LOGE(SIM_DAEMON, "Open Command FAILED");
+               delete mSession;
+               data.returnValue = result;
+
+               /* Write the response back to TEECLIB in case of failure */
+               result = mConnSess->write(OPEN_SESSION, (char*)&data,
+                   sizeof(OpenSessionData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Open Session response write to CA FAILED");
+               }
+               return result;
+       }
+       if (mSession->getTAInstance() == NULL) {
+               LOGE(SIM_DAEMON, "Creating Trusted Application Instance FAILED");
+               delete mSession;
+               data.returnValue = TEEC_ERROR_BAD_PARAMETERS;
+
+               /* Write the response back to TEECLIB in case of failure */
+               result = mConnSess->write(OPEN_SESSION, (char*)&data,
+                   sizeof(OpenSessionData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Open Session response write to CA FAILED");
+               }
+               return result;
+       }
+       /* Write the response back to TEECLIB in case of failure */
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       mSessionMap[data.sessionID] = mSession;
+       pthread_rwlock_unlock(&mSessionMapLock);
+       return result;
+}
+
+/**
+ * On InvokeCommand API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for InvokeCommand
+ */
+TEEC_Result TEEContext::invokeCommand(InvokeCommandData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+       data.returnOrigin = TEEC_ORIGIN_TEE;
+       data.returnValue = TEEC_ERROR_GENERIC;
+
+       /* Find the Session instance in the session map */
+       map<uint32_t, ISession*>::iterator it;
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       it = mSessionMap.find(data.sessionID);
+       if (it == mSessionMap.end()) {
+               LOGE(SIM_DAEMON, "Session not found");
+               pthread_rwlock_unlock(&mSessionMapLock);
+               return result;
+       }
+       pthread_rwlock_unlock(&mSessionMapLock);
+
+       /* Call session handleCommand function to handle invoke command request */
+       if (NULL != it->second) {
+               LOGD(SIM_DAEMON, "Entry");
+               result = it->second->handleCommand(data);
+               if (TEEC_SUCCESS == result) {
+                       return result;
+               }
+       } else {
+               result = TEEC_ERROR_TARGET_DEAD;
+       }
+       LOGE(SIM_DAEMON, "Invoke Command FAILED");
+       data.returnValue = result;
+       /* Write the response back to TEECLIB in case of failure */
+       result = mConnSess->write(INVOKE_COMMAND, (char*)&data,
+           sizeof(InvokeCommandData));
+       if (result != TEEC_SUCCESS) {
+               LOGE(SIM_DAEMON, "Invoke Command response write to CA FAILED");
+       }
+       return result;
+}
+
+/**
+ * On RequestCancellation API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for RequestCancellation
+ */
+void TEEContext::reqCancel(ReqCancellationData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Find the Session instance in the session map */
+       map<uint32_t, ISession*>::iterator it;
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       it = mSessionMap.find(data.sessionID);
+       if (it == mSessionMap.end()) {
+               LOGE(SIM_DAEMON, "Session not found");
+               pthread_rwlock_unlock(&mSessionMapLock);
+               return;
+       }
+
+       /* Call session handleCancel function to handle cancellation request */
+       pthread_rwlock_unlock(&mSessionMapLock);
+       if (NULL != it->second) {
+               LOGD(SIM_DAEMON, "Entry");
+               it->second->handleCancel(data);
+       }
+
+       /* Write the response back to TEECLIB */
+       result = mConnSess->write(REQUEST_CANCELLATION, (char*)&data,
+           sizeof(ReqCancellationData));
+       if (result != TEEC_SUCCESS) {
+               LOGE(SIM_DAEMON, "Request Cancellation response write to CA FAILED");
+       }
+}
+
+/**
+ * On CloseSession API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for CloseSession
+ */
+TEEC_Result TEEContext::closeSession(CloseSessionData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Find the Session instance in the session map */
+       map<uint32_t, ISession*>::iterator it;
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       it = mSessionMap.find(data.sessionID);
+       if (it == mSessionMap.end()) {
+               LOGE(SIM_DAEMON, "Session not found");
+               pthread_rwlock_unlock(&mSessionMapLock);
+               return result;
+       }
+       LOGE(SIM_DAEMON, "Session pointer 0x%x", it->second);
+
+       /* Call session finalize function to handle close session request */
+       if (NULL != it->second) {
+               LOGD(SIM_DAEMON, "Entry");
+               result = it->second->finalize(data.contextID);
+               if (result == TEEC_SUCCESS) {
+                       return result;
+               } else {
+                       it->second = NULL;
+               }
+       } else {
+               result = TEEC_ERROR_TARGET_DEAD;
+       }
+
+       LOGE(SIM_DAEMON, "Close Command FAILED");
+       delete it->second;
+       if (data.contextID != 0) {
+               /* Write the response back to TEECLIB in case of failure */
+               result = mConnSess->write(CLOSE_SESSION, (char*)&data,
+                   sizeof(CloseSessionData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Close Session response write to CA FAILED");
+               }
+       }
+       pthread_rwlock_unlock(&mSessionMapLock);
+       return result;
+}
+
+/**
+ * On OpenTASession API call from TA, SSFLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from SSFLib
+ * @param data data sent from SSFLib for OpenTASession
+ */
+TEEC_Result TEEContext::openTASession(IntTAOpenSessionData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* OpenTASession is a request from TA, so the member variable isInternal of
+        * TEEContext is set to true
+        */
+       isInternal = true;
+       OpenSessionData sdata;
+       sdata.returnOrigin = data.returnOrigin = TEEC_ORIGIN_TEE;
+       sdata.returnValue = data.returnValue = TEEC_ERROR_GENERIC;
+
+       /* Assign a Session ID number to the Session instance to be created */
+       pthread_rwlock_wrlock(&sessIDLock);
+       sdata.sessionID = data.session = sessID;
+       sessID++;
+       pthread_rwlock_unlock(&sessIDLock);
+
+       sdata.connMeth = TEEC_LOGIN_PUBLIC;
+       sdata.operation = data.operation;
+       memcpy(&sdata.uuid, &data.destination, sizeof(TEEC_UUID));
+
+       /* Create a new Session instance */
+       ISession *mSession = new Session(this);
+
+       /* Call session createSession function to handle open session request */
+       result = mSession->createSession(sdata);
+       if (TEEC_SUCCESS != result) {
+               LOGE(SIM_DAEMON, "Open TA command FAILED");
+               delete mSession;
+               data.returnValue = result;
+
+               /* Write the response back to SSFLIB in case of failure */
+               result = mConnSess->write(OPEN_TA_SESSION, (char*)&data,
+                   sizeof(IntTAOpenSessionData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Open TA Session response write to CA FAILED");
+               }
+               return result;
+       }
+       if (mSession->getTAInstance() == NULL) {
+               LOGE(SIM_DAEMON, "Creating Trusted Application Instance FAILED");
+               delete mSession;
+               data.returnValue = TEEC_ERROR_BAD_PARAMETERS;
+               /* Write the response back to SSFLIB in case of failure */
+               result = mConnSess->write(OPEN_TA_SESSION, (char*)&data,
+                   sizeof(IntTAOpenSessionData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Open TA Session response write to CA FAILED");
+               }
+               return result;
+       }
+       /* Add the Session instance in the session map */
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       mSessionMap[sdata.sessionID] = mSession;
+       pthread_rwlock_unlock(&mSessionMapLock);
+       return result;
+}
+
+/**
+ * On CloseTASession API call from TA, SSFLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from SSFLib
+ * @param data data sent from SSFLib for CloseTASession
+ */
+void TEEContext::closeTASession(IntTACloseSessionData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       map<uint32_t, ISession*>::iterator it;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Find the Session instance in the session map */
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       it = mSessionMap.find(data.session);
+       if (it == mSessionMap.end()) {
+               LOGE(SIM_DAEMON, "Session not found");
+               pthread_rwlock_unlock(&mSessionMapLock);
+               return;
+       }
+
+       /* Call session finalize function to handle close session request */
+       result = it->second->finalize(mContextID);
+       if (result != TEEC_SUCCESS) {
+               LOGE(SIM_DAEMON, "Close TA Command FAILED");
+               delete it->second;
+               /* Write the response back to SSFLIB */
+               result = mConnSess->write(CLOSE_TA_SESSION, (char*)&data,
+                   sizeof(IntTACloseSessionData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Close TA Session response write to CA FAILED");
+               }
+       }
+       /* Remove the Session instance from the session map */
+       mSessionMap.erase(it);
+       pthread_rwlock_unlock(&mSessionMapLock);
+}
+
+/**
+ * On InvokeTACommand API call from TA, SSFLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from SSFLib
+ * @param data data sent from SSFLib for InvokeTACommand
+ */
+TEEC_Result TEEContext::invokeTACommand(IntTAInvokeCommandData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       data.returnOrigin = TEEC_ORIGIN_TEE;
+       data.returnValue = TEEC_ERROR_GENERIC;
+
+       InvokeCommandData idata;
+       idata.commandID = data.commandID;
+       idata.operation = data.operation;
+       idata.returnOrigin = TEEC_ORIGIN_TEE;
+       idata.returnValue = TEEC_ERROR_GENERIC;
+       idata.sessionID = data.session;
+
+       /* Find the Session instance in the session map */
+       map<uint32_t, ISession*>::iterator it;
+       pthread_rwlock_wrlock(&mSessionMapLock);
+       it = mSessionMap.find(data.session);
+       if (it == mSessionMap.end()) {
+               LOGE(SIM_DAEMON, "Session not found");
+               pthread_rwlock_unlock(&mSessionMapLock);
+               return result;
+       }
+       pthread_rwlock_unlock(&mSessionMapLock);
+
+       /* Call session handle command function to handle invoke command request */
+       result = it->second->handleCommand(idata);
+       if (TEEC_SUCCESS != result) {
+               LOGE(SIM_DAEMON, "Invoke TA Command FAILED");
+               data.returnValue = result;
+               /* Write the response back to SSFLIB */
+               result = mConnSess->write(INVOKE_TA_COMMAND, (char*)&data,
+                   sizeof(IntTAInvokeCommandData));
+               if (result != TEEC_SUCCESS) {
+                       LOGE(SIM_DAEMON, "Invoke TA Session response write to CA FAILED");
+               }
+       }
+       return result;
+}
+
+/**
+ * On RegisterSharedMemory API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for RegisterSharedMemory
+ */
+TEEC_Result TEEContext::registerSharedMemory(RegSharedMemData data) {
+
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Add the shared memory in the list */
+       pthread_rwlock_wrlock(&mShmListLock);
+       mShmList.push_back(data.sharedMem.shmKey);
+       pthread_rwlock_unlock(&mShmListLock);
+       data.returnValue = TEEC_SUCCESS;
+
+       /* Write the response back to TEECLib */
+       result = mConnSess->write(REGISTER_SHARED_MEMORY, (char*)&data,
+           sizeof(RegSharedMemData));
+       return result;
+}
+
+/**
+ * On ReleaseSharedMemory API call from CA, TEECLib sends command and data to
+ * Simulator Daemon, on this command this function is executed with the data
+ * sent from TEECLib
+ * @param data data sent from TEECLib for ReleaseSharedmemory
+ */
+TEEC_Result TEEContext::releaseSharedMemory(RelSharedMemData data) {
+       TEEC_Result result = TEEC_ERROR_GENERIC;
+       LOGD(SIM_DAEMON, "Entry");
+
+       /* Remove the shared memory for the list */
+       pthread_rwlock_wrlock(&mShmListLock);
+       mShmList.remove(data.sharedMem.shmKey);
+       pthread_rwlock_unlock(&mShmListLock);
+
+       /* Write the response back to TEECLib */
+       result = mConnSess->write(RELEASE_SHARED_MEMORY, (char*)&data,
+           sizeof(RelSharedMemData));
+       return result;
+}
+
+/**
+ * TEEContext destructer.
+ */
+TEEContext::~TEEContext() {
+       LOGD(SIM_DAEMON, "ContextID: %d", mContextID);
+       /* Destroy the locks created for shared memory list (mShmList) and
+        * Session map (mSessionMap). */
+       pthread_rwlock_destroy(&mShmListLock);
+       pthread_rwlock_destroy(&mSessionMapLock);
+}
diff --git a/simulatordaemon/src/ioService.cpp b/simulatordaemon/src/ioService.cpp
new file mode 100755 (executable)
index 0000000..f20061c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ioService.cpp
+ *
+ *    Description:  ioService class
+ *
+ *        Version:  1.0
+ *        Created:  05 May 2015 12:42:03  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  CHERYL (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <ioService.h>
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+boost::asio::io_service ioService::io_service;
+
+/*-----------------------------------------------------------------------------
+ *  Member functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * Get ioService Instance.
+ * return the io_service instance.
+ */
+boost::asio::io_service& ioService::getInstance() {
+       // return the io_service instance
+       return io_service;
+}
diff --git a/simulatordaemon/src/rapidxml/rapidxml.hpp b/simulatordaemon/src/rapidxml/rapidxml.hpp
new file mode 100755 (executable)
index 0000000..234f577
--- /dev/null
@@ -0,0 +1,2396 @@
+#ifndef RAPIDXML_HPP_INCLUDED
+#define RAPIDXML_HPP_INCLUDED
+
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+// Version 1.13
+// Revision $DateTime: 2009/05/13 01:46:17 $
+//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation
+
+// If standard library is disabled, user must provide implementations of required functions and typedefs
+#if !defined(RAPIDXML_NO_STDLIB)
+#include <cstdlib>      // For std::size_t
+#include <cassert>      // For assert
+#include <new>          // For placement new
+#endif
+
+// On MSVC, disable "conditional expression is constant" warning (level 4). 
+// This warning is almost impossible to avoid with certain types of templated code
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4127)   // Conditional expression is constant
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// RAPIDXML_PARSE_ERROR
+
+#if defined(RAPIDXML_NO_EXCEPTIONS)
+
+#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); }
+
+namespace rapidxml
+{
+       //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, 
+       //! this function is called to notify user about the error.
+       //! It must be defined by the user.
+       //! <br><br>
+       //! This function cannot return. If it does, the results are undefined.
+       //! <br><br>
+       //! A very simple definition might look like that:
+       //! <pre>
+       //! void %rapidxml::%parse_error_handler(const char *what, void *where)
+       //! {
+       //!     LOGE(SIM_DAEMON, "Parse error: %s", what);
+       //!     std::abort();
+       //! }
+       //! </pre>
+       //! \param what Human readable description of the error.
+       //! \param where Pointer to character data where error was detected.
+       void parse_error_handler(const char *what, void *where);
+}
+
+#else
+
+#include <exception>    // For std::exception
+
+#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
+
+namespace rapidxml {
+
+//! Parse error exception. 
+//! This exception is thrown by the parser when an error occurs. 
+//! Use what() function to get human-readable error message. 
+//! Use where() function to get a pointer to position within source text where error was detected.
+//! <br><br>
+//! If throwing exceptions by the parser is undesirable, 
+//! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included.
+//! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception.
+//! This function must be defined by the user.
+//! <br><br>
+//! This class derives from <code>std::exception</code> class.
+class parse_error:
+    public std::exception {
+
+public:
+
+       //! Constructs parse error
+       parse_error(const char *what, void *where) :
+                       m_what(what), m_where(where) {
+       }
+
+       //! Gets human readable description of error.
+       //! \return Pointer to null terminated description of the error.
+       virtual const char *what() const throw () {
+               return m_what;
+       }
+
+       //! Gets pointer to character data where error happened.
+       //! Ch should be the same as char type of xml_document that produced the error.
+       //! \return Pointer to location within the parsed string where error occured.
+       template<class Ch>
+       Ch *where() const {
+               return reinterpret_cast<Ch *>(m_where);
+       }
+
+private:
+
+       const char *m_what;
+       void *m_where;
+
+};
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// Pool sizes
+
+#ifndef RAPIDXML_STATIC_POOL_SIZE
+// Size of static memory block of memory_pool.
+// Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+// No dynamic memory allocations are performed by memory_pool until static memory is exhausted.
+#define RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef RAPIDXML_DYNAMIC_POOL_SIZE
+// Size of dynamic memory block of memory_pool.
+// Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+// After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.
+#define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef RAPIDXML_ALIGNMENT
+// Memory allocation alignment.
+// Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.
+// All memory allocations for nodes, attributes and strings will be aligned to this value.
+// This must be a power of 2 and at least 1, otherwise memory_pool will not work.
+#define RAPIDXML_ALIGNMENT sizeof(void *)
+#endif
+
+namespace rapidxml {
+// Forward declarations
+template<class Ch> class xml_node;
+template<class Ch> class xml_attribute;
+template<class Ch> class xml_document;
+
+//! Enumeration listing all node types produced by the parser.
+//! Use xml_node::type() function to query node type.
+enum node_type {
+       node_document,      //!< A document node. Name and value are empty.
+       node_element, //!< An element node. Name contains element name. Value contains text of first data node.
+       node_data,        //!< A data node. Name is empty. Value contains data text.
+       node_cdata,      //!< A CDATA node. Name is empty. Value contains data text.
+       node_comment, //!< A comment node. Name is empty. Value contains comment text.
+       node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
+       node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
+       node_pi   //!< A PI node. Name contains target. Value contains instructions.
+};
+
+///////////////////////////////////////////////////////////////////////
+// Parsing flags
+
+//! Parse flag instructing the parser to not create data nodes. 
+//! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_data_nodes = 0x1;
+
+//! Parse flag instructing the parser to not use text of first data node as a value of parent element.
+//! Can be combined with other flags by use of | operator.
+//! Note that child data nodes of element node take precendence over its value when printing. 
+//! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored.
+//! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_element_values = 0x2;
+
+//! Parse flag instructing the parser to not place zero terminators after strings in the source text.
+//! By default zero terminators are placed, modifying source text.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_string_terminators = 0x4;
+
+//! Parse flag instructing the parser to not translate entities in the source text.
+//! By default entities are translated, modifying source text.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_entity_translation = 0x8;
+
+//! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters.
+//! By default, UTF-8 handling is enabled.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_no_utf8 = 0x10;
+
+//! Parse flag instructing the parser to create XML declaration node.
+//! By default, declaration node is not created.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_declaration_node = 0x20;
+
+//! Parse flag instructing the parser to create comments nodes.
+//! By default, comment nodes are not created.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_comment_nodes = 0x40;
+
+//! Parse flag instructing the parser to create DOCTYPE node.
+//! By default, doctype node is not created.
+//! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_doctype_node = 0x80;
+
+//! Parse flag instructing the parser to create PI nodes.
+//! By default, PI nodes are not created.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_pi_nodes = 0x100;
+
+//! Parse flag instructing the parser to validate closing tag names. 
+//! If not set, name inside closing tag is irrelevant to the parser.
+//! By default, closing tags are not validated.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_validate_closing_tags = 0x200;
+
+//! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes.
+//! By default, whitespace is not trimmed. 
+//! This flag does not cause the parser to modify source text.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_trim_whitespace = 0x400;
+
+//! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character.
+//! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag.
+//! By default, whitespace is not normalized. 
+//! If this flag is specified, source text will be modified.
+//! Can be combined with other flags by use of | operator.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_normalize_whitespace = 0x800;
+
+// Compound flags
+
+//! Parse flags which represent default behaviour of the parser. 
+//! This is always equal to 0, so that all other flags can be simply ored together.
+//! Normally there is no need to inconveniently disable flags by anding with their negated (~) values.
+//! This also means that meaning of each flag is a <i>negation</i> of the default setting. 
+//! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default,
+//! and using the flag will disable it.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_default = 0;
+
+//! A combination of parse flags that forbids any modifications of the source text. 
+//! This also results in faster parsing. However, note that the following will occur:
+//! <ul>
+//! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li>
+//! <li>entities will not be translated</li>
+//! <li>whitespace will not be normalized</li>
+//! </ul>
+//! See xml_document::parse() function.
+const int parse_non_destructive = parse_no_string_terminators
+    | parse_no_entity_translation;
+
+//! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
+
+//! A combination of parse flags resulting in largest amount of data being extracted. 
+//! This usually results in slowest parsing.
+//! <br><br>
+//! See xml_document::parse() function.
+const int parse_full = parse_declaration_node | parse_comment_nodes
+    | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
+
+///////////////////////////////////////////////////////////////////////
+// Internals
+
+//! \cond internal
+namespace internal {
+
+// Struct that contains lookup tables for the parser
+// It must be a template to allow correct linking (because it has static data members, which are defined in a header file).
+template<int Dummy>
+struct lookup_tables {
+       static const unsigned char lookup_whitespace[256];       // Whitespace table
+       static const unsigned char lookup_node_name[256];         // Node name table
+       static const unsigned char lookup_text[256];                   // Text table
+       static const unsigned char lookup_text_pure_no_ws[256];        // Text table
+       static const unsigned char lookup_text_pure_with_ws[256];      // Text table
+       static const unsigned char lookup_attribute_name[256]; // Attribute name table
+       static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote
+       static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote
+       static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes
+       static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes
+       static const unsigned char lookup_digits[256];                  // Digits
+       static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters
+};
+
+// Find length of the string
+template<class Ch>
+inline std::size_t measure(const Ch *p) {
+       const Ch *tmp = p;
+       while (*tmp)
+               ++tmp;
+       return tmp - p;
+}
+
+// Compare strings for equality
+template<class Ch>
+inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2,
+    std::size_t size2, bool case_sensitive) {
+       if (size1 != size2) return false;
+       if (case_sensitive) {
+               for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+                       if (*p1 != *p2) return false;
+       } else {
+               for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+                       if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)]
+                           != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
+                         return false;
+       }
+       return true;
+}
+}
+//! \endcond
+
+///////////////////////////////////////////////////////////////////////
+// Memory pool
+
+//! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation.
+//! In most cases, you will not need to use this class directly. 
+//! However, if you need to create nodes manually or modify names/values of nodes, 
+//! you are encouraged to use memory_pool of relevant xml_document to allocate the memory. 
+//! Not only is this faster than allocating them by using <code>new</code> operator, 
+//! but also their lifetime will be tied to the lifetime of document, 
+//! possibly simplyfing memory management. 
+//! <br><br>
+//! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool. 
+//! You can also call allocate_string() function to allocate strings.
+//! Such strings can then be used as names or values of nodes without worrying about their lifetime.
+//! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called, 
+//! or when the pool is destroyed.
+//! <br><br>
+//! It is also possible to create a standalone memory_pool, and use it 
+//! to allocate nodes, whose lifetime will not be tied to any document.
+//! <br><br>
+//! Pool maintains <code>RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory. 
+//! Until static memory is exhausted, no dynamic memory allocations are done.
+//! When static memory is exhausted, pool allocates additional blocks of memory of size <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> each,
+//! by using global <code>new[]</code> and <code>delete[]</code> operators. 
+//! This behaviour can be changed by setting custom allocation routines. 
+//! Use set_allocator() function to set them.
+//! <br><br>
+//! Allocations for nodes, attributes and strings are aligned at <code>RAPIDXML_ALIGNMENT</code> bytes.
+//! This value defaults to the size of pointer on target architecture.
+//! <br><br>
+//! To obtain absolutely top performance from the parser,
+//! it is important that all nodes are allocated from a single, contiguous block of memory.
+//! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably.
+//! If required, you can tweak <code>RAPIDXML_STATIC_POOL_SIZE</code>, <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>RAPIDXML_ALIGNMENT</code> 
+//! to obtain best wasted memory to performance compromise.
+//! To do it, define their values before rapidxml.hpp file is included.
+//! \param Ch Character type of created nodes. 
+template<class Ch = char>
+class memory_pool {
+
+public:
+
+       //! \cond internal
+       typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory
+       typedef void (free_func)(void *); // Type of user-defined function used to free memory
+       //! \endcond
+
+       //! Constructs empty pool with default allocator functions.
+       memory_pool() :
+                       m_alloc_func(0), m_free_func(0) {
+               init();
+       }
+
+       //! Destroys pool and frees all the memory. 
+       //! This causes memory occupied by nodes allocated by the pool to be freed.
+       //! Nodes allocated from the pool are no longer valid.
+       ~memory_pool() {
+               clear();
+       }
+
+       //! Allocates a new node from the pool, and optionally assigns name and value to it. 
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+       //! will call rapidxml::parse_error_handler() function.
+       //! \param type Type of node to create.
+       //! \param name Name to assign to the node, or 0 to assign no name.
+       //! \param value Value to assign to the node, or 0 to assign no value.
+       //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+       //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+       //! \return Pointer to allocated node. This pointer will never be NULL.
+       xml_node<Ch> *allocate_node(node_type type, const Ch *name = 0,
+           const Ch *value = 0, std::size_t name_size = 0,
+           std::size_t value_size = 0) {
+               void *memory = allocate_aligned(sizeof(xml_node<Ch> ));
+               xml_node<Ch> *node = new (memory) xml_node<Ch>(type);
+               if (name) {
+                       if (name_size > 0)
+                               node->name(name, name_size);
+                       else node->name(name);
+               }
+               if (value) {
+                       if (value_size > 0)
+                               node->value(value, value_size);
+                       else node->value(value);
+               }
+               return node;
+       }
+
+       //! Allocates a new attribute from the pool, and optionally assigns name and value to it.
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+       //! will call rapidxml::parse_error_handler() function.
+       //! \param name Name to assign to the attribute, or 0 to assign no name.
+       //! \param value Value to assign to the attribute, or 0 to assign no value.
+       //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+       //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+       //! \return Pointer to allocated attribute. This pointer will never be NULL.
+       xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
+           std::size_t name_size = 0, std::size_t value_size = 0) {
+               void *memory = allocate_aligned(sizeof(xml_attribute<Ch> ));
+               xml_attribute<Ch> *attribute = new (memory) xml_attribute<Ch>;
+               if (name) {
+                       if (name_size > 0)
+                               attribute->name(name, name_size);
+                       else attribute->name(name);
+               }
+               if (value) {
+                       if (value_size > 0)
+                               attribute->value(value, value_size);
+                       else attribute->value(value);
+               }
+               return attribute;
+       }
+
+       //! Allocates a char array of given size from the pool, and optionally copies a given string to it.
+       //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+       //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+       //! will call rapidxml::parse_error_handler() function.
+       //! \param source String to initialize the allocated memory with, or 0 to not initialize it.
+       //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.
+       //! \return Pointer to allocated char array. This pointer will never be NULL.
+       Ch *allocate_string(const Ch *source = 0, std::size_t size = 0) {
+               assert(source || size); // Either source or size (or both) must be specified
+               if (size == 0) size = internal::measure(source) + 1;
+               Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
+               if (source) for (std::size_t i = 0; i < size; ++i)
+                       result[i] = source[i];
+               return result;
+       }
+
+       //! Clones an xml_node and its hierarchy of child nodes and attributes.
+       //! Nodes and attributes are allocated from this memory pool.
+       //! Names and values are not cloned, they are shared between the clone and the source.
+       //! Result node can be optionally specified as a second parameter, 
+       //! in which case its contents will be replaced with cloned source node.
+       //! This is useful when you want to clone entire document.
+       //! \param source Node to clone.
+       //! \param result Node to put results in, or 0 to automatically allocate result node
+       //! \return Pointer to cloned node. This pointer will never be NULL.
+       xml_node<Ch> *clone_node(const xml_node<Ch> *source,
+           xml_node<Ch> *result = 0) {
+               // Prepare result node
+               if (result) {
+                       result->remove_all_attributes();
+                       result->remove_all_nodes();
+                       result->type(source->type());
+               } else result = allocate_node(source->type());
+
+               // Clone name and value
+               result->name(source->name(), source->name_size());
+               result->value(source->value(), source->value_size());
+
+               // Clone child nodes and attributes
+               for (xml_node<Ch> *child = source->first_node(); child;
+                   child = child->next_sibling())
+                       result->append_node(clone_node(child));
+               for (xml_attribute<Ch> *attr = source->first_attribute(); attr;
+                   attr = attr->next_attribute())
+                       result->append_attribute(
+                           allocate_attribute(attr->name(), attr->value(), attr->name_size(),
+                               attr->value_size()));
+
+               return result;
+       }
+
+       //! Clears the pool. 
+       //! This causes memory occupied by nodes allocated by the pool to be freed.
+       //! Any nodes or strings allocated from the pool will no longer be valid.
+       void clear() {
+               while (m_begin != m_static_memory) {
+                       char *previous_begin = reinterpret_cast<header *>(align(m_begin))
+                           ->previous_begin;
+                       if (m_free_func)
+                               m_free_func(m_begin);
+                       else delete[] m_begin;
+                       m_begin = previous_begin;
+               }
+               init();
+       }
+
+       //! Sets or resets the user-defined memory allocation functions for the pool.
+       //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined.
+       //! Allocation function must not return invalid pointer on failure. It should either throw,
+       //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program. 
+       //! If it returns invalid pointer, results are undefined.
+       //! <br><br>
+       //! User defined allocation functions must have the following forms:
+       //! <br><code>
+       //! <br>void *allocate(std::size_t size);
+       //! <br>void free(void *pointer);
+       //! </code><br>
+       //! \param af Allocation function, or 0 to restore default function
+       //! \param ff Free function, or 0 to restore default function
+       void set_allocator(alloc_func *af, free_func *ff) {
+               assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet
+               m_alloc_func = af;
+               m_free_func = ff;
+       }
+
+private:
+
+       struct header {
+               char *previous_begin;
+       };
+
+       void init() {
+               m_begin = m_static_memory;
+               m_ptr = align(m_begin);
+               m_end = m_static_memory + sizeof(m_static_memory);
+       }
+
+       char *align(char *ptr) {
+               std::size_t alignment = ((RAPIDXML_ALIGNMENT
+                   - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1)))
+                   & (RAPIDXML_ALIGNMENT - 1));
+               return ptr + alignment;
+       }
+
+       char *allocate_raw(std::size_t size) {
+               // Allocate
+               void *memory;
+               if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[]
+               {
+                       memory = m_alloc_func(size);
+                       assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
+               } else {
+                       memory = new char[size];
+#ifdef RAPIDXML_NO_EXCEPTIONS
+                       if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc
+                       RAPIDXML_PARSE_ERROR("out of memory", 0);
+#endif
+               }
+               return static_cast<char *>(memory);
+       }
+
+       void *allocate_aligned(std::size_t size) {
+               // Calculate aligned pointer
+               char *result = align(m_ptr);
+
+               // If not enough memory left in current pool, allocate a new pool
+               if (result + size > m_end) {
+                       // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE)
+                       std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;
+                       if (pool_size < size) pool_size = size;
+
+                       // Allocate
+                       std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2)
+                           + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation
+                       char *raw_memory = allocate_raw(alloc_size);
+
+                       // Setup new pool in allocated memory
+                       char *pool = align(raw_memory);
+                       header *new_header = reinterpret_cast<header *>(pool);
+                       new_header->previous_begin = m_begin;
+                       m_begin = raw_memory;
+                       m_ptr = pool + sizeof(header);
+                       m_end = raw_memory + alloc_size;
+
+                       // Calculate aligned pointer again using new pool
+                       result = align(m_ptr);
+               }
+
+               // Update pool and return aligned pointer
+               m_ptr = result + size;
+               return result;
+       }
+
+       char *m_begin;                 // Start of raw memory making up current pool
+       char *m_ptr;                              // First free byte in current pool
+       char *m_end;                 // One past last available byte in current pool
+       char m_static_memory[RAPIDXML_STATIC_POOL_SIZE];    // Static raw memory
+       alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used
+       free_func *m_free_func;      // Free function, or 0 if default is to be used
+};
+
+///////////////////////////////////////////////////////////////////////////
+// XML base
+
+//! Base class for xml_node and xml_attribute implementing common functions: 
+//! name(), name_size(), value(), value_size() and parent().
+//! \param Ch Character type to use
+template<class Ch = char>
+class xml_base {
+
+public:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Construction & destruction
+
+       // Construct a base with empty name, value and parent
+       xml_base() :
+                       m_name(0), m_value(0), m_parent(0) {
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node data access
+
+       //! Gets name of the node. 
+       //! Interpretation of name depends on type of node.
+       //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+       //! <br><br>
+       //! Use name_size() function to determine length of the name.
+       //! \return Name of node, or empty string if node has no name.
+       Ch *name() const {
+               return m_name ? m_name : nullstr();
+       }
+
+       //! Gets size of node name, not including terminator character.
+       //! This function works correctly irrespective of whether name is or is not zero terminated.
+       //! \return Size of node name, in characters.
+       std::size_t name_size() const {
+               return m_name ? m_name_size : 0;
+       }
+
+       //! Gets value of node. 
+       //! Interpretation of value depends on type of node.
+       //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+       //! <br><br>
+       //! Use value_size() function to determine length of the value.
+       //! \return Value of node, or empty string if node has no value.
+       Ch *value() const {
+               return m_value ? m_value : nullstr();
+       }
+
+       //! Gets size of node value, not including terminator character.
+       //! This function works correctly irrespective of whether value is or is not zero terminated.
+       //! \return Size of node value, in characters.
+       std::size_t value_size() const {
+               return m_value ? m_value_size : 0;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node modification
+
+       //! Sets name of node to a non zero-terminated string.
+       //! See \ref ownership_of_strings.
+       //! <br><br>
+       //! Note that node does not own its name or value, it only stores a pointer to it. 
+       //! It will not delete or otherwise free the pointer on destruction.
+       //! It is reponsibility of the user to properly manage lifetime of the string.
+       //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+       //! on destruction of the document the string will be automatically freed.
+       //! <br><br>
+       //! Size of name must be specified separately, because name does not have to be zero terminated.
+       //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+       //! \param name Name of node to set. Does not have to be zero terminated.
+       //! \param size Size of name, in characters. This does not include zero terminator, if one is present.
+       void name(const Ch *name, std::size_t size) {
+               m_name = const_cast<Ch *>(name);
+               m_name_size = size;
+       }
+
+       //! Sets name of node to a zero-terminated string.
+       //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t).
+       //! \param name Name of node to set. Must be zero terminated.
+       void name(const Ch *name) {
+               this->name(name, internal::measure(name));
+       }
+
+       //! Sets value of node to a non zero-terminated string.
+       //! See \ref ownership_of_strings.
+       //! <br><br>
+       //! Note that node does not own its name or value, it only stores a pointer to it. 
+       //! It will not delete or otherwise free the pointer on destruction.
+       //! It is reponsibility of the user to properly manage lifetime of the string.
+       //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+       //! on destruction of the document the string will be automatically freed.
+       //! <br><br>
+       //! Size of value must be specified separately, because it does not have to be zero terminated.
+       //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+       //! <br><br>
+       //! If an element has a child node of type node_data, it will take precedence over element value when printing.
+       //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.
+       //! \param value value of node to set. Does not have to be zero terminated.
+       //! \param size Size of value, in characters. This does not include zero terminator, if one is present.
+       void value(const Ch *value, std::size_t size) {
+               m_value = const_cast<Ch *>(value);
+               m_value_size = size;
+       }
+
+       //! Sets value of node to a zero-terminated string.
+       //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t).
+       //! \param value Vame of node to set. Must be zero terminated.
+       void value(const Ch *value) {
+               this->value(value, internal::measure(value));
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Related nodes access
+
+       //! Gets node parent.
+       //! \return Pointer to parent node, or 0 if there is no parent.
+       xml_node<Ch> *parent() const {
+               return m_parent;
+       }
+
+protected:
+
+       // Return empty string
+       static Ch *nullstr() {
+               static Ch zero = Ch('\0');
+               return &zero;
+       }
+
+       Ch *m_name;                         // Name of node, or 0 if no name
+       Ch *m_value;                        // Value of node, or 0 if no value
+       std::size_t m_name_size;     // Length of node name, or undefined of no name
+       std::size_t m_value_size;  // Length of node value, or undefined if no value
+       xml_node<Ch> *m_parent;             // Pointer to parent node, or 0 if none
+
+};
+
+//! Class representing attribute node of XML document. 
+//! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base).
+//! Note that after parse, both name and value of attribute will point to interior of source text used for parsing. 
+//! Thus, this text must persist in memory for the lifetime of attribute.
+//! \param Ch Character type to use.
+template<class Ch = char>
+class xml_attribute:
+    public xml_base<Ch> {
+
+       friend class xml_node<Ch> ;
+
+public:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Construction & destruction
+
+       //! Constructs an empty attribute with the specified type. 
+       //! Consider using memory_pool of appropriate xml_document if allocating attributes manually.
+       xml_attribute() {
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Related nodes access
+
+       //! Gets document of which attribute is a child.
+       //! \return Pointer to document that contains this attribute, or 0 if there is no parent document.
+       xml_document<Ch> *document() const {
+               if (xml_node<Ch> *node = this->parent()) {
+                       while (node->parent())
+                               node = node->parent();
+                       return
+                           node->type() == node_document ?
+                               static_cast<xml_document<Ch> *>(node) : 0;
+               } else return 0;
+       }
+
+       //! Gets previous attribute, optionally matching attribute name. 
+       //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *previous_attribute(const Ch *name = 0,
+           std::size_t name_size = 0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute;
+                           attribute = attribute->m_prev_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return this->m_parent ? m_prev_attribute : 0;
+       }
+
+       //! Gets next attribute, optionally matching attribute name. 
+       //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *next_attribute(const Ch *name = 0, std::size_t name_size =
+           0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_next_attribute; attribute;
+                           attribute = attribute->m_next_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return this->m_parent ? m_next_attribute : 0;
+       }
+
+private:
+
+       xml_attribute<Ch> *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero
+       xml_attribute<Ch> *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero
+
+};
+
+///////////////////////////////////////////////////////////////////////////
+// XML node
+
+//! Class representing a node of XML document. 
+//! Each node may have associated name and value strings, which are available through name() and value() functions. 
+//! Interpretation of name and value depends on type of the node.
+//! Type of node can be determined by using type() function.
+//! <br><br>
+//! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing. 
+//! Thus, this text must persist in the memory for the lifetime of node.
+//! \param Ch Character type to use.
+template<class Ch = char>
+class xml_node:
+    public xml_base<Ch> {
+
+public:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Construction & destruction
+
+       //! Constructs an empty node with the specified type. 
+       //! Consider using memory_pool of appropriate document to allocate nodes manually.
+       //! \param type Type of node to construct.
+       xml_node(node_type type) :
+                       m_type(type), m_first_node(0), m_first_attribute(0) {
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node data access
+
+       //! Gets type of node.
+       //! \return Type of node.
+       node_type type() const {
+               return m_type;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Related nodes access
+
+       //! Gets document of which node is a child.
+       //! \return Pointer to document that contains this node, or 0 if there is no parent document.
+       xml_document<Ch> *document() const {
+               xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
+               while (node->parent())
+                       node = node->parent();
+               return
+                   node->type() == node_document ? static_cast<xml_document<Ch> *>(node) :
+                                                   0;
+       }
+
+       //! Gets first child node, optionally matching node name.
+       //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found child, or 0 if not found.
+       xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *child = m_first_node; child;
+                           child = child->next_sibling())
+                               if (internal::compare(child->name(), child->name_size(), name,
+                                   name_size, case_sensitive)) return child;
+                       return 0;
+               } else return m_first_node;
+       }
+
+       //! Gets last child node, optionally matching node name. 
+       //! Behaviour is undefined if node has no children.
+       //! Use first_node() to test if node has children.
+       //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found child, or 0 if not found.
+       xml_node<Ch> *last_node(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               assert(m_first_node); // Cannot query for last child if node has no children
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *child = m_last_node; child;
+                           child = child->previous_sibling())
+                               if (internal::compare(child->name(), child->name_size(), name,
+                                   name_size, case_sensitive)) return child;
+                       return 0;
+               } else return m_last_node;
+       }
+
+       //! Gets previous sibling node, optionally matching node name. 
+       //! Behaviour is undefined if node has no parent.
+       //! Use parent() to test if node has a parent.
+       //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found sibling, or 0 if not found.
+       xml_node<Ch> *previous_sibling(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               assert(this->m_parent); // Cannot query for siblings if node has no parent
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *sibling = m_prev_sibling; sibling;
+                           sibling = sibling->m_prev_sibling)
+                               if (internal::compare(sibling->name(), sibling->name_size(), name,
+                                   name_size, case_sensitive)) return sibling;
+                       return 0;
+               } else return m_prev_sibling;
+       }
+
+       //! Gets next sibling node, optionally matching node name. 
+       //! Behaviour is undefined if node has no parent.
+       //! Use parent() to test if node has a parent.
+       //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found sibling, or 0 if not found.
+       xml_node<Ch> *next_sibling(const Ch *name = 0, std::size_t name_size = 0,
+           bool case_sensitive = true) const {
+               assert(this->m_parent); // Cannot query for siblings if node has no parent
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_node<Ch> *sibling = m_next_sibling; sibling;
+                           sibling = sibling->m_next_sibling)
+                               if (internal::compare(sibling->name(), sibling->name_size(), name,
+                                   name_size, case_sensitive)) return sibling;
+                       return 0;
+               } else return m_next_sibling;
+       }
+
+       //! Gets first attribute of node, optionally matching attribute name.
+       //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *first_attribute(const Ch *name = 0, std::size_t name_size =
+           0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_first_attribute; attribute;
+                           attribute = attribute->m_next_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return m_first_attribute;
+       }
+
+       //! Gets last attribute of node, optionally matching attribute name.
+       //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+       //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+       //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+       //! \return Pointer to found attribute, or 0 if not found.
+       xml_attribute<Ch> *last_attribute(const Ch *name = 0, std::size_t name_size =
+           0, bool case_sensitive = true) const {
+               if (name) {
+                       if (name_size == 0) name_size = internal::measure(name);
+                       for (xml_attribute<Ch> *attribute = m_last_attribute; attribute;
+                           attribute = attribute->m_prev_attribute)
+                               if (internal::compare(attribute->name(), attribute->name_size(), name,
+                                   name_size, case_sensitive)) return attribute;
+                       return 0;
+               } else return m_first_attribute ? m_last_attribute : 0;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node modification
+
+       //! Sets type of node.
+       //! \param type Type of node to set.
+       void type(node_type type) {
+               m_type = type;
+       }
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Node manipulation
+
+       //! Prepends a new child node.
+       //! The prepended child becomes the first child, and all existing children are moved one position back.
+       //! \param child Node to prepend.
+       void prepend_node(xml_node<Ch> *child) {
+               assert(child && !child->parent() && child->type() != node_document);
+               if (first_node()) {
+                       child->m_next_sibling = m_first_node;
+                       m_first_node->m_prev_sibling = child;
+               } else {
+                       child->m_next_sibling = 0;
+                       m_last_node = child;
+               }
+               m_first_node = child;
+               child->m_parent = this;
+               child->m_prev_sibling = 0;
+       }
+
+       //! Appends a new child node. 
+       //! The appended child becomes the last child.
+       //! \param child Node to append.
+       void append_node(xml_node<Ch> *child) {
+               assert(child && !child->parent() && child->type() != node_document);
+               if (first_node()) {
+                       child->m_prev_sibling = m_last_node;
+                       m_last_node->m_next_sibling = child;
+               } else {
+                       child->m_prev_sibling = 0;
+                       m_first_node = child;
+               }
+               m_last_node = child;
+               child->m_parent = this;
+               child->m_next_sibling = 0;
+       }
+
+       //! Inserts a new child node at specified place inside the node. 
+       //! All children after and including the specified node are moved one position back.
+       //! \param where Place where to insert the child, or 0 to insert at the back.
+       //! \param child Node to insert.
+       void insert_node(xml_node<Ch> *where, xml_node<Ch> *child) {
+               assert(!where || where->parent() == this);
+               assert(child && !child->parent() && child->type() != node_document);
+               if (where == m_first_node)
+                       prepend_node(child);
+               else if (where == 0)
+                       append_node(child);
+               else {
+                       child->m_prev_sibling = where->m_prev_sibling;
+                       child->m_next_sibling = where;
+                       where->m_prev_sibling->m_next_sibling = child;
+                       where->m_prev_sibling = child;
+                       child->m_parent = this;
+               }
+       }
+
+       //! Removes first child node. 
+       //! If node has no children, behaviour is undefined.
+       //! Use first_node() to test if node has children.
+       void remove_first_node() {
+               assert(first_node());
+               xml_node<Ch> *child = m_first_node;
+               m_first_node = child->m_next_sibling;
+               if (child->m_next_sibling)
+                       child->m_next_sibling->m_prev_sibling = 0;
+               else m_last_node = 0;
+               child->m_parent = 0;
+       }
+
+       //! Removes last child of the node. 
+       //! If node has no children, behaviour is undefined.
+       //! Use first_node() to test if node has children.
+       void remove_last_node() {
+               assert(first_node());
+               xml_node<Ch> *child = m_last_node;
+               if (child->m_prev_sibling) {
+                       m_last_node = child->m_prev_sibling;
+                       child->m_prev_sibling->m_next_sibling = 0;
+               } else m_first_node = 0;
+               child->m_parent = 0;
+       }
+
+       //! Removes specified child from the node
+       // \param where Pointer to child to be removed.
+       void remove_node(xml_node<Ch> *where) {
+               assert(where && where->parent() == this);
+               assert(first_node());
+               if (where == m_first_node)
+                       remove_first_node();
+               else if (where == m_last_node)
+                       remove_last_node();
+               else {
+                       where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
+                       where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
+                       where->m_parent = 0;
+               }
+       }
+
+       //! Removes all child nodes (but not attributes).
+       void remove_all_nodes() {
+               for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
+                       node->m_parent = 0;
+               m_first_node = 0;
+       }
+
+       //! Prepends a new attribute to the node.
+       //! \param attribute Attribute to prepend.
+       void prepend_attribute(xml_attribute<Ch> *attribute) {
+               assert(attribute && !attribute->parent());
+               if (first_attribute()) {
+                       attribute->m_next_attribute = m_first_attribute;
+                       m_first_attribute->m_prev_attribute = attribute;
+               } else {
+                       attribute->m_next_attribute = 0;
+                       m_last_attribute = attribute;
+               }
+               m_first_attribute = attribute;
+               attribute->m_parent = this;
+               attribute->m_prev_attribute = 0;
+       }
+
+       //! Appends a new attribute to the node.
+       //! \param attribute Attribute to append.
+       void append_attribute(xml_attribute<Ch> *attribute) {
+               assert(attribute && !attribute->parent());
+               if (first_attribute()) {
+                       attribute->m_prev_attribute = m_last_attribute;
+                       m_last_attribute->m_next_attribute = attribute;
+               } else {
+                       attribute->m_prev_attribute = 0;
+                       m_first_attribute = attribute;
+               }
+               m_last_attribute = attribute;
+               attribute->m_parent = this;
+               attribute->m_next_attribute = 0;
+       }
+
+       //! Inserts a new attribute at specified place inside the node. 
+       //! All attributes after and including the specified attribute are moved one position back.
+       //! \param where Place where to insert the attribute, or 0 to insert at the back.
+       //! \param attribute Attribute to insert.
+       void insert_attribute(xml_attribute<Ch> *where,
+           xml_attribute<Ch> *attribute) {
+               assert(!where || where->parent() == this);
+               assert(attribute && !attribute->parent());
+               if (where == m_first_attribute)
+                       prepend_attribute(attribute);
+               else if (where == 0)
+                       append_attribute(attribute);
+               else {
+                       attribute->m_prev_attribute = where->m_prev_attribute;
+                       attribute->m_next_attribute = where;
+                       where->m_prev_attribute->m_next_attribute = attribute;
+                       where->m_prev_attribute = attribute;
+                       attribute->m_parent = this;
+               }
+       }
+
+       //! Removes first attribute of the node. 
+       //! If node has no attributes, behaviour is undefined.
+       //! Use first_attribute() to test if node has attributes.
+       void remove_first_attribute() {
+               assert(first_attribute());
+               xml_attribute<Ch> *attribute = m_first_attribute;
+               if (attribute->m_next_attribute) {
+                       attribute->m_next_attribute->m_prev_attribute = 0;
+               } else m_last_attribute = 0;
+               attribute->m_parent = 0;
+               m_first_attribute = attribute->m_next_attribute;
+       }
+
+       //! Removes last attribute of the node. 
+       //! If node has no attributes, behaviour is undefined.
+       //! Use first_attribute() to test if node has attributes.
+       void remove_last_attribute() {
+               assert(first_attribute());
+               xml_attribute<Ch> *attribute = m_last_attribute;
+               if (attribute->m_prev_attribute) {
+                       attribute->m_prev_attribute->m_next_attribute = 0;
+                       m_last_attribute = attribute->m_prev_attribute;
+               } else m_first_attribute = 0;
+               attribute->m_parent = 0;
+       }
+
+       //! Removes specified attribute from node.
+       //! \param where Pointer to attribute to be removed.
+       void remove_attribute(xml_attribute<Ch> *where) {
+               assert(first_attribute() && where->parent() == this);
+               if (where == m_first_attribute)
+                       remove_first_attribute();
+               else if (where == m_last_attribute)
+                       remove_last_attribute();
+               else {
+                       where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
+                       where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
+                       where->m_parent = 0;
+               }
+       }
+
+       //! Removes all attributes of node.
+       void remove_all_attributes() {
+               for (xml_attribute<Ch> *attribute = first_attribute(); attribute;
+                   attribute = attribute->m_next_attribute)
+                       attribute->m_parent = 0;
+               m_first_attribute = 0;
+       }
+
+private:
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Restrictions
+
+       // No copying
+       xml_node(const xml_node &);
+       void operator =(const xml_node &);
+
+       ///////////////////////////////////////////////////////////////////////////
+       // Data members
+
+       // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.
+       // This is required for maximum performance, as it allows the parser to omit initialization of 
+       // unneded/redundant values.
+       //
+       // The rules are as follows:
+       // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively
+       // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage
+       // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage
+
+       node_type m_type;                       // Type of node; always valid
+       xml_node<Ch> *m_first_node; // Pointer to first child node, or 0 if none; always valid
+       xml_node<Ch> *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero
+       xml_attribute<Ch> *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid
+       xml_attribute<Ch> *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero
+       xml_node<Ch> *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+       xml_node<Ch> *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+
+};
+
+///////////////////////////////////////////////////////////////////////////
+// XML document
+
+//! This class represents root of the DOM hierarchy. 
+//! It is also an xml_node and a memory_pool through public inheritance.
+//! Use parse() function to build a DOM tree from a zero-terminated XML text string.
+//! parse() function allocates memory for nodes and attributes by using functions of xml_document, 
+//! which are inherited from memory_pool.
+//! To access root node of the document, use the document itself, as if it was an xml_node.
+//! \param Ch Character type to use.
+template<class Ch = char>
+class xml_document:
+    public xml_node<Ch>, public memory_pool<Ch> {
+
+public:
+
+       //! Constructs empty XML document
+       xml_document() :
+                       xml_node<Ch>(node_document) {
+       }
+
+       //! Parses zero-terminated XML string according to given flags.
+       //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.
+       //! The string must persist for the lifetime of the document.
+       //! In case of error, rapidxml::parse_error exception will be thrown.
+       //! <br><br>
+       //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning.
+       //! Make sure that data is zero-terminated.
+       //! <br><br>
+       //! Document can be parsed into multiple times. 
+       //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.
+       //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.
+       template<int Flags>
+       void parse(Ch *text) {
+               assert(text);
+
+               // Remove current contents
+               this->remove_all_nodes();
+               this->remove_all_attributes();
+
+               // Parse BOM, if any
+               parse_bom<Flags>(text);
+
+               // Parse children
+               while (1) {
+                       // Skip whitespace before node
+                       skip<whitespace_pred, Flags>(text);
+                       if (*text == 0) break;
+
+                       // Parse and append new child
+                       if (*text == Ch('<')) {
+                               ++text;     // Skip '<'
+                               if (xml_node<Ch> *node = parse_node<Flags>(text))
+                                 this->append_node(node);
+                       } else
+                       RAPIDXML_PARSE_ERROR("expected <", text);
+               }
+
+       }
+
+       //! Clears the document by deleting all nodes and clearing the memory pool.
+       //! All nodes owned by document pool are destroyed.
+       void clear() {
+               this->remove_all_nodes();
+               this->remove_all_attributes();
+               memory_pool<Ch>::clear();
+       }
+
+private:
+
+       ///////////////////////////////////////////////////////////////////////
+       // Internal character utility functions
+
+       // Detect whitespace character
+       struct whitespace_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect node name character
+       struct node_name_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect attribute name character
+       struct attribute_name_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect text character (PCDATA)
+       struct text_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect text character (PCDATA) that does not require processing
+       struct text_pure_no_ws_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect text character (PCDATA) that does not require processing
+       struct text_pure_with_ws_pred {
+               static unsigned char test(Ch ch) {
+                       return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];
+               }
+       };
+
+       // Detect attribute value character
+       template<Ch Quote>
+       struct attribute_value_pred {
+               static unsigned char test(Ch ch) {
+                       if (Quote == Ch('\''))
+                         return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];
+                       if (Quote == Ch('\"'))
+                         return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];
+                       return 0;   // Should never be executed, to avoid warnings on Comeau
+               }
+       };
+
+       // Detect attribute value character
+       template<Ch Quote>
+       struct attribute_value_pure_pred {
+               static unsigned char test(Ch ch) {
+                       if (Quote == Ch('\''))
+                         return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
+                       if (Quote == Ch('\"'))
+                         return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
+                       return 0;   // Should never be executed, to avoid warnings on Comeau
+               }
+       };
+
+       // Insert coded character, using UTF8 or 8-bit ASCII
+       template<int Flags>
+       static void insert_coded_character(Ch *&text, unsigned long code) {
+               if (Flags & parse_no_utf8) {
+                       // Insert 8-bit ASCII character
+                       // Todo: possibly verify that code is less than 256 and use replacement char otherwise?
+                       text[0] = static_cast<unsigned char>(code);
+                       text += 1;
+               } else {
+                       // Insert UTF8 sequence
+                       if (code < 0x80)    // 1 byte sequence
+                           {
+                               text[0] = static_cast<unsigned char>(code);
+                               text += 1;
+                       } else if (code < 0x800)  // 2 byte sequence
+                           {
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[0] = static_cast<unsigned char>(code | 0xC0);
+                               text += 2;
+                       } else if (code < 0x10000)    // 3 byte sequence
+                           {
+                               text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[0] = static_cast<unsigned char>(code | 0xE0);
+                               text += 3;
+                       } else if (code < 0x110000)   // 4 byte sequence
+                           {
+                               text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF);
+                               code >>= 6;
+                               text[0] = static_cast<unsigned char>(code | 0xF0);
+                               text += 4;
+                       } else  // Invalid, only codes up to 0x10FFFF are allowed in Unicode
+                       {
+                               RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
+                       }
+               }
+       }
+
+       // Skip characters until predicate evaluates to true
+       template<class StopPred, int Flags>
+       static void skip(Ch *&text) {
+               Ch *tmp = text;
+               while (StopPred::test(*tmp))
+                       ++tmp;
+               text = tmp;
+       }
+
+       // Skip characters until predicate evaluates to true while doing the following:
+       // - replacing XML character entity references with proper characters (&apos; &amp; &quot; &lt; &gt; &#...;)
+       // - condensing whitespace sequences to single space character
+       template<class StopPred, class StopPredPure, int Flags>
+       static Ch *skip_and_expand_character_refs(Ch *&text) {
+               // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip
+               if (Flags & parse_no_entity_translation
+                   && !(Flags & parse_normalize_whitespace)
+                   && !(Flags & parse_trim_whitespace)) {
+                       skip<StopPred, Flags>(text);
+                       return text;
+               }
+
+               // Use simple skip until first modification is detected
+               skip<StopPredPure, Flags>(text);
+
+               // Use translation skip
+               Ch *src = text;
+               Ch *dest = src;
+               while (StopPred::test(*src)) {
+                       // If entity translation is enabled    
+                       if (!(Flags & parse_no_entity_translation)) {
+                               // Test if replacement is needed
+                               if (src[0] == Ch('&')) {
+                                       switch (src[1]) {
+
+                                               // &amp; &apos;
+                                               case Ch('a'):
+                                                       if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';')) {
+                                                               *dest = Ch('&');
+                                                               ++dest;
+                                                               src += 5;
+                                                               continue;
+                                                       }
+                                                       if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s')
+                                                           && src[5] == Ch(';')) {
+                                                               *dest = Ch('\'');
+                                                               ++dest;
+                                                               src += 6;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &quot;
+                                               case Ch('q'):
+                                                       if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t')
+                                                           && src[5] == Ch(';')) {
+                                                               *dest = Ch('"');
+                                                               ++dest;
+                                                               src += 6;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &gt;
+                                               case Ch('g'):
+                                                       if (src[2] == Ch('t') && src[3] == Ch(';')) {
+                                                               *dest = Ch('>');
+                                                               ++dest;
+                                                               src += 4;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &lt;
+                                               case Ch('l'):
+                                                       if (src[2] == Ch('t') && src[3] == Ch(';')) {
+                                                               *dest = Ch('<');
+                                                               ++dest;
+                                                               src += 4;
+                                                               continue;
+                                                       }
+                                                       break;
+
+                                                       // &#...; - assumes ASCII
+                                               case Ch('#'):
+                                                       if (src[2] == Ch('x')) {
+                                                               unsigned long code = 0;
+                                                               src += 3;   // Skip &#x
+                                                               while (1) {
+                                                                       unsigned char digit =
+                                                                           internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                                                                       if (digit == 0xFF) break;
+                                                                       code = code * 16 + digit;
+                                                                       ++src;
+                                                               }
+                                                               insert_coded_character<Flags>(dest, code); // Put character in output
+                                                       } else {
+                                                               unsigned long code = 0;
+                                                               src += 2;   // Skip &#
+                                                               while (1) {
+                                                                       unsigned char digit =
+                                                                           internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+                                                                       if (digit == 0xFF) break;
+                                                                       code = code * 10 + digit;
+                                                                       ++src;
+                                                               }
+                                                               insert_coded_character<Flags>(dest, code); // Put character in output
+                                                       }
+                                                       if (*src == Ch(';'))
+                                                               ++src;
+                                                       else
+                                                       RAPIDXML_PARSE_ERROR("expected ;", src);
+                                                       continue;
+
+                                                       // Something else
+                                               default:
+                                                       // Ignore, just copy '&' verbatim
+                                                       break;
+
+                                       }
+                               }
+                       }
+
+                       // If whitespace condensing is enabled
+                       if (Flags & parse_normalize_whitespace) {
+                               // Test if condensing is needed                 
+                               if (whitespace_pred::test(*src)) {
+                                       *dest = Ch(' ');
+                                       ++dest;    // Put single space in dest
+                                       ++src;                      // Skip first whitespace char
+                                       // Skip remaining whitespace chars
+                                       while (whitespace_pred::test(*src))
+                                               ++src;
+                                       continue;
+                               }
+                       }
+
+                       // No replacement, only copy character
+                       *dest++ = *src++;
+
+               }
+
+               // Return new end
+               text = src;
+               return dest;
+
+       }
+
+       ///////////////////////////////////////////////////////////////////////
+       // Internal parsing functions
+
+       // Parse BOM, if any
+       template<int Flags>
+       void parse_bom(Ch *&text) {
+               // UTF-8?
+               if (static_cast<unsigned char>(text[0]) == 0xEF
+                   && static_cast<unsigned char>(text[1]) == 0xBB
+                   && static_cast<unsigned char>(text[2]) == 0xBF) {
+                       text += 3;      // Skup utf-8 bom
+               }
+       }
+
+       // Parse XML declaration (<?xml...)
+       template<int Flags>
+       xml_node<Ch> *parse_xml_declaration(Ch *&text) {
+               // If parsing of declaration is disabled
+               if (!(Flags & parse_declaration_node)) {
+                       // Skip until end of declaration
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {
+                               if (!text[0])
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 2;    // Skip '?>'
+                       return 0;
+               }
+
+               // Create declaration
+               xml_node<Ch> *declaration = this->allocate_node(node_declaration);
+
+               // Skip whitespace before attributes or ?>
+               skip<whitespace_pred, Flags>(text);
+
+               // Parse declaration attributes
+               parse_node_attributes<Flags>(text, declaration);
+
+               // Skip ?>
+               if (text[0] != Ch('?') || text[1] != Ch('>'))
+               RAPIDXML_PARSE_ERROR("expected ?>", text);
+               text += 2;
+
+               return declaration;
+       }
+
+       // Parse XML comment (<!--...)
+       template<int Flags>
+       xml_node<Ch> *parse_comment(Ch *&text) {
+               // If parsing of comments is disabled
+               if (!(Flags & parse_comment_nodes)) {
+                       // Skip until end of comment
+                       while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {
+                               if (!text[0])
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 3;     // Skip '-->'
+                       return 0;      // Do not produce comment node
+               }
+
+               // Remember value start
+               Ch *value = text;
+
+               // Skip until end of comment
+               while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>')) {
+                       if (!text[0])
+                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                       ++text;
+               }
+
+               // Create comment node
+               xml_node<Ch> *comment = this->allocate_node(node_comment);
+               comment->value(value, text - value);
+
+               // Place zero terminator after comment value
+               if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');
+
+               text += 3;     // Skip '-->'
+               return comment;
+       }
+
+       // Parse DOCTYPE
+       template<int Flags>
+       xml_node<Ch> *parse_doctype(Ch *&text) {
+               // Remember value start
+               Ch *value = text;
+
+               // Skip to >
+               while (*text != Ch('>')) {
+                       // Determine character type
+                       switch (*text) {
+
+                               // If '[' encountered, scan for matching ending ']' using naive algorithm with depth
+                               // This works for all W3C test files except for 2 most wicked
+                               case Ch('['): {
+                                       ++text;     // Skip '['
+                                       int depth = 1;
+                                       while (depth > 0) {
+                                               switch (*text) {
+                                                       case Ch('['):
+                                                               ++depth;
+                                                               break;
+                                                       case Ch(']'):
+                                                               --depth;
+                                                               break;
+                                                       case 0:
+                                                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                                               }
+                                               ++text;
+                                       }
+                                       break;
+                               }
+
+                                       // Error on end of text
+                               case Ch('\0'):
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+                                       // Other character, skip it
+                               default:
+                                       ++text;
+
+                       }
+               }
+
+               // If DOCTYPE nodes enabled
+               if (Flags & parse_doctype_node) {
+                       // Create a new doctype node
+                       xml_node<Ch> *doctype = this->allocate_node(node_doctype);
+                       doctype->value(value, text - value);
+
+                       // Place zero terminator after value
+                       if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');
+
+                       text += 1;      // skip '>'
+                       return doctype;
+               } else {
+                       text += 1;      // skip '>'
+                       return 0;
+               }
+
+       }
+
+       // Parse PI
+       template<int Flags>
+       xml_node<Ch> *parse_pi(Ch *&text) {
+               // If creation of PI nodes is enabled
+               if (Flags & parse_pi_nodes) {
+                       // Create pi node
+                       xml_node<Ch> *pi = this->allocate_node(node_pi);
+
+                       // Extract PI target name
+                       Ch *name = text;
+                       skip<node_name_pred, Flags>(text);
+                       if (text == name)
+                       RAPIDXML_PARSE_ERROR("expected PI target", text);
+                       pi->name(name, text - name);
+
+                       // Skip whitespace between pi target and pi
+                       skip<whitespace_pred, Flags>(text);
+
+                       // Remember start of pi
+                       Ch *value = text;
+
+                       // Skip to '?>'
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {
+                               if (*text == Ch('\0'))
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+
+                       // Set pi value (verbatim, no entity expansion or whitespace normalization)
+                       pi->value(value, text - value);
+
+                       // Place zero terminator after name and value
+                       if (!(Flags & parse_no_string_terminators)) {
+                               pi->name()[pi->name_size()] = Ch('\0');
+                               pi->value()[pi->value_size()] = Ch('\0');
+                       }
+
+                       text += 2;                          // Skip '?>'
+                       return pi;
+               } else {
+                       // Skip to '?>'
+                       while (text[0] != Ch('?') || text[1] != Ch('>')) {
+                               if (*text == Ch('\0'))
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 2;    // Skip '?>'
+                       return 0;
+               }
+       }
+
+       // Parse and append data
+       // Return character that ends data.
+       // This is necessary because this character might have been overwritten by a terminating 0
+       template<int Flags>
+       Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start) {
+               // Backup to contents start if whitespace trimming is disabled
+               if (!(Flags & parse_trim_whitespace)) text = contents_start;
+
+               // Skip until end of data
+               Ch *value = text, *end;
+               if (Flags & parse_normalize_whitespace)
+                       end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred,
+                           Flags>(text);
+               else end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred,
+                   Flags>(text);
+
+               // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >
+               if (Flags & parse_trim_whitespace) {
+                       if (Flags & parse_normalize_whitespace) {
+                               // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end
+                               if (*(end - 1) == Ch(' ')) --end;
+                       } else {
+                               // Backup until non-whitespace character is found
+                               while (whitespace_pred::test(*(end - 1)))
+                                       --end;
+                       }
+               }
+
+               // If characters are still left between end and value (this test is only necessary if normalization is enabled)
+               // Create new data node
+               if (!(Flags & parse_no_data_nodes)) {
+                       xml_node<Ch> *data = this->allocate_node(node_data);
+                       data->value(value, end - value);
+                       node->append_node(data);
+               }
+
+               // Add data to parent node if no data exists yet
+               if (!(Flags & parse_no_element_values))
+                 if (*node->value() == Ch('\0')) node->value(value, end - value);
+
+               // Place zero terminator after value
+               if (!(Flags & parse_no_string_terminators)) {
+                       Ch ch = *text;
+                       *end = Ch('\0');
+                       return ch; // Return character that ends data; this is required because zero terminator overwritten it
+               }
+
+               // Return character that ends data
+               return *text;
+       }
+
+       // Parse CDATA
+       template<int Flags>
+       xml_node<Ch> *parse_cdata(Ch *&text) {
+               // If CDATA is disabled
+               if (Flags & parse_no_data_nodes) {
+                       // Skip until end of cdata
+                       while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {
+                               if (!text[0])
+                               RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                               ++text;
+                       }
+                       text += 3;      // Skip ]]>
+                       return 0;       // Do not produce CDATA node
+               }
+
+               // Skip until end of cdata
+               Ch *value = text;
+               while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>')) {
+                       if (!text[0])
+                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                       ++text;
+               }
+
+               // Create new cdata node
+               xml_node<Ch> *cdata = this->allocate_node(node_cdata);
+               cdata->value(value, text - value);
+
+               // Place zero terminator after value
+               if (!(Flags & parse_no_string_terminators)) *text = Ch('\0');
+
+               text += 3;      // Skip ]]>
+               return cdata;
+       }
+
+       // Parse element node
+       template<int Flags>
+       xml_node<Ch> *parse_element(Ch *&text) {
+               // Create element node
+               xml_node<Ch> *element = this->allocate_node(node_element);
+
+               // Extract element name
+               Ch *name = text;
+               skip<node_name_pred, Flags>(text);
+               if (text == name)
+               RAPIDXML_PARSE_ERROR("expected element name", text);
+               element->name(name, text - name);
+
+               // Skip whitespace between element name and attributes or >
+               skip<whitespace_pred, Flags>(text);
+
+               // Parse attributes, if any
+               parse_node_attributes<Flags>(text, element);
+
+               // Determine ending type
+               if (*text == Ch('>')) {
+                       ++text;
+                       parse_node_contents<Flags>(text, element);
+               } else if (*text == Ch('/')) {
+                       ++text;
+                       if (*text != Ch('>'))
+                       RAPIDXML_PARSE_ERROR("expected >", text);
+                       ++text;
+               } else
+               RAPIDXML_PARSE_ERROR("expected >", text);
+
+               // Place zero terminator after name
+               if (!(Flags & parse_no_string_terminators))
+                 element->name()[element->name_size()] = Ch('\0');
+
+               // Return parsed element
+               return element;
+       }
+
+       // Determine node type, and parse it
+       template<int Flags>
+       xml_node<Ch> *parse_node(Ch *&text) {
+               // Parse proper node type
+               switch (text[0]) {
+
+                       // <...
+                       default:
+                               // Parse and append element node
+                               return parse_element<Flags>(text);
+
+                               // <?...
+                       case Ch('?'):
+                               ++text;     // Skip ?
+                               if ((text[0] == Ch('x') || text[0] == Ch('X'))
+                                   && (text[1] == Ch('m') || text[1] == Ch('M'))
+                                   && (text[2] == Ch('l') || text[2] == Ch('L'))
+                                   && whitespace_pred::test(text[3])) {
+                                       // '<?xml ' - xml declaration
+                                       text += 4;      // Skip 'xml '
+                                       return parse_xml_declaration<Flags>(text);
+                               } else {
+                                       // Parse PI
+                                       return parse_pi<Flags>(text);
+                               }
+
+                               // <!...
+                       case Ch('!'):
+
+                               // Parse proper subset of <! node
+                               switch (text[1]) {
+
+                                       // <!-
+                                       case Ch('-'):
+                                               if (text[2] == Ch('-')) {
+                                                       // '<!--' - xml comment
+                                                       text += 3;     // Skip '!--'
+                                                       return parse_comment<Flags>(text);
+                                               }
+                                               break;
+
+                                               // <![
+                                       case Ch('['):
+                                               if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A')
+                                                   && text[5] == Ch('T') && text[6] == Ch('A')
+                                                   && text[7] == Ch('[')) {
+                                                       // '<![CDATA[' - cdata
+                                                       text += 8;     // Skip '![CDATA['
+                                                       return parse_cdata<Flags>(text);
+                                               }
+                                               break;
+
+                                               // <!D
+                                       case Ch('D'):
+                                               if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T')
+                                                   && text[5] == Ch('Y') && text[6] == Ch('P')
+                                                   && text[7] == Ch('E') && whitespace_pred::test(text[8])) {
+                                                       // '<!DOCTYPE ' - doctype
+                                                       text += 9;      // skip '!DOCTYPE '
+                                                       return parse_doctype<Flags>(text);
+                                               }
+
+                               }   // switch
+
+                               // Attempt to skip other, unrecognized node types starting with <!
+                               ++text;     // Skip !
+                               while (*text != Ch('>')) {
+                                       if (*text == 0)
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+                                       ++text;
+                               }
+                               ++text;     // Skip '>'
+                               return 0;   // No node recognized
+
+               }
+       }
+
+       // Parse contents of the node - children, data etc.
+       template<int Flags>
+       void parse_node_contents(Ch *&text, xml_node<Ch> *node) {
+               // For all children and text
+               while (1) {
+                       // Skip whitespace between > and node contents
+                       Ch *contents_start = text; // Store start of node contents before whitespace is skipped
+                       skip<whitespace_pred, Flags>(text);
+                       Ch next_char = *text;
+
+                       // After data nodes, instead of continuing the loop, control jumps here.
+                       // This is because zero termination inside parse_and_append_data() function
+                       // would wreak havoc with the above code.
+                       // Also, skipping whitespace after data nodes is unnecessary.
+                       after_data_node:
+
+                       // Determine what comes next: node closing, child node, data node, or 0?
+                       switch (next_char) {
+
+                               // Node closing or child node
+                               case Ch('<'):
+                                       if (text[1] == Ch('/')) {
+                                               // Node closing
+                                               text += 2;      // Skip '</'
+                                               if (Flags & parse_validate_closing_tags) {
+                                                       // Skip and validate closing tag name
+                                                       Ch *closing_name = text;
+                                                       skip<node_name_pred, Flags>(text);
+                                                       if (!internal::compare(node->name(), node->name_size(),
+                                                           closing_name, text - closing_name, true))
+                                                       RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
+                                               } else {
+                                                       // No validation, just skip name
+                                                       skip<node_name_pred, Flags>(text);
+                                               }
+                                               // Skip remaining whitespace after node name
+                                               skip<whitespace_pred, Flags>(text);
+                                               if (*text != Ch('>'))
+                                               RAPIDXML_PARSE_ERROR("expected >", text);
+                                               ++text;     // Skip '>'
+                                               return;     // Node closed, finished parsing contents
+                                       } else {
+                                               // Child node
+                                               ++text;     // Skip '<'
+                                               if (xml_node<Ch> *child = parse_node<Flags>(text))
+                                                 node->append_node(child);
+                                       }
+                                       break;
+
+                                       // End of data - error
+                               case Ch('\0'):
+                                       RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+
+                                       // Data node
+                               default:
+                                       next_char = parse_and_append_data<Flags>(node, text, contents_start);
+                                       goto after_data_node;
+                                       // Bypass regular processing after data nodes
+
+                       }
+               }
+       }
+
+       // Parse XML attributes of the node
+       template<int Flags>
+       void parse_node_attributes(Ch *&text, xml_node<Ch> *node) {
+               // For all attributes 
+               while (attribute_name_pred::test(*text)) {
+                       // Extract attribute name
+                       Ch *name = text;
+                       ++text;     // Skip first character of attribute name
+                       skip<attribute_name_pred, Flags>(text);
+                       if (text == name)
+                       RAPIDXML_PARSE_ERROR("expected attribute name", name);
+
+                       // Create new attribute
+                       xml_attribute<Ch> *attribute = this->allocate_attribute();
+                       attribute->name(name, text - name);
+                       node->append_attribute(attribute);
+
+                       // Skip whitespace after attribute name
+                       skip<whitespace_pred, Flags>(text);
+
+                       // Skip =
+                       if (*text != Ch('='))
+                       RAPIDXML_PARSE_ERROR("expected =", text);
+                       ++text;
+
+                       // Add terminating zero after name
+                       if (!(Flags & parse_no_string_terminators))
+                         attribute->name()[attribute->name_size()] = 0;
+
+                       // Skip whitespace after =
+                       skip<whitespace_pred, Flags>(text);
+
+                       // Skip quote and remember if it was ' or "
+                       Ch quote = *text;
+                       if (quote != Ch('\'') && quote != Ch('"'))
+                       RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+                       ++text;
+
+                       // Extract attribute value and expand char refs in it
+                       Ch *value = text, *end;
+                       const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes
+                       if (quote == Ch('\''))
+                               end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>,
+                                   attribute_value_pure_pred<Ch('\'')>, AttFlags>(text);
+                       else end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>,
+                           attribute_value_pure_pred<Ch('"')>, AttFlags>(text);
+
+                       // Set attribute value
+                       attribute->value(value, end - value);
+
+                       // Make sure that end quote is present
+                       if (*text != quote)
+                       RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+                       ++text;     // Skip quote
+
+                       // Add terminating zero after value
+                       if (!(Flags & parse_no_string_terminators))
+                         attribute->value()[attribute->value_size()] = 0;
+
+                       // Skip whitespace after attribute value
+                       skip<whitespace_pred, Flags>(text);
+               }
+       }
+
+};
+
+//! \cond internal
+namespace internal {
+
+// Whitespace (space \n \r \t)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,  // 0
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 8
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 9
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // A
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // B
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // C
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // D
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // E
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   // F
+    };
+
+// Node name (anything but space \n \r \t / > ? \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_node_name[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Text (i.e. PCDATA) (anything but < \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_text[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Text (i.e. PCDATA) that does not require processing when ws normalization is disabled 
+// (anything but < \0 &)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled
+// (anything but < \0 & space \n \r \t)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute name (anything but space \n \r \t / < > = ? ! \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with single quote (anything but ' \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with single quote that does not require processing (anything but ' \0 &)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with double quote (anything but " \0)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Attribute data with double quote that does not require processing (anything but " \0 &)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] = {
+// 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 0
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 1
+    1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 2
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 3
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 4
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 5
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 6
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 7
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F
+    };
+
+// Digits (dec and hex, 255 denotes end of numeric character reference)
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_digits[256] = {
+    // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 0
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 1
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 2
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255,
+    255,  // 3
+    255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 4
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 5
+    255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 6
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 7
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 8
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // 9
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // A
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // B
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // C
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // D
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255,  // E
+    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+    255   // F
+    };
+
+// Upper case conversion
+template<int Dummy>
+const unsigned char lookup_tables<Dummy>::lookup_upcase[256] = {
+    // 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  A   B   C   D   E   F
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+    15,   // 0
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+    31,   // 1
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+    47,   // 2
+    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
+    63,   // 3
+    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+    79,   // 4
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+    95,   // 5
+    96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+    79,   // 6
+    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126,
+    127,  // 7
+    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
+    143,  // 8
+    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
+    159,  // 9
+    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,
+    175,  // A
+    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
+    191,  // B
+    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206,
+    207,  // C
+    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222,
+    223,  // D
+    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
+    239,  // E
+    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+    255   // F
+    };
+}
+//! \endcond
+
+}
+
+// Undefine internal macros
+#undef RAPIDXML_PARSE_ERROR
+
+// On MSVC, restore warnings state
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/simulatordaemon/src/scripts/update_uuid_list.sh b/simulatordaemon/src/scripts/update_uuid_list.sh
new file mode 100755 (executable)
index 0000000..590b3aa
--- /dev/null
@@ -0,0 +1,1189 @@
+#!/bin/sh
+# This script creates a uuidlist.list file and populates it with TA UUID packages names.
+# Ths file is populated based on the existing files in directory /tmp/tastore/
+# UUID pattern is: ....-....-....-............
+# This script should be executed once all the TA packages are transferred to /tmp/tastore
+
+# Author: Krishna Devale 
+# Samsung R & D Institute, Bangalore
+# 7 May 2015
+
+#uuidfile="./tastore/uuidlist.list";
+uuidfile="/tmp/tastore/uuidlist.list";
+
+retval=""
+file="/tmp/fileLock"
+
+S=<<END
+f0VMRgEBAQAAAAAAAAAAAAIAAwABAAAAgIQECDQAAAB4xAAAAAAAADQAIAAIACgA
+JQAiAAYAAAA0AAAANIAECDSABAgAAQAAAAEAAAUAAAAEAAAAAwAAADQBAAA0gQQI
+NIEECBMAAAATAAAABAAAAAEAAAABAAAAAAAAAACABAgAgAQIoAgAAKAIAAAFAAAA
+ABAAAAEAAACgCAAAoJgECKCYBAg4AQAAQAEAAAYAAAAAEAAAAgAAALQIAAC0mAQI
+tJgECOgAAADoAAAABgAAAAQAAAAEAAAASAEAAEiBBAhIgQQIRAAAAEQAAAAEAAAA
+BAAAAFDldGScBwAAnIcECJyHBAg0AAAANAAAAAQAAAAEAAAAUeV0ZAAAAAAAAAAA
+AAAAAAAAAAAAAAAABgAAAAQAAAAvbGliL2xkLWxpbnV4LnNvLjIAAAQAAAAQAAAA
+AQAAAEdOVQAAAAAAAgAAAAYAAAAZAAAABAAAABQAAAADAAAAR05VAHrwVG/z4ZNY
+qrgWlL/85S9LsfKxAwAAAAsAAAAHAAAACgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA
+AwAAAAIAAAAEAAAABgAAAAUAAAAIAAAACQAAAAAAAAAAAAAAAAAAAAAAAAB+AAAA
+AAAAAAAAAAASAAAAcQAAAAAAAAAAAAAAEgAAABsAAAAAAAAAAAAAACAAAAAqAAAA
+AAAAAAAAAAAgAAAAiQAAAAAAAAAAAAAAEgAAAGUAAAAAAAAAAAAAABIAAAB4AAAA
+AAAAAAAAAAASAAAAbAAAAAAAAAAAAAAAEgAAAIMAAAAAAAAAAAAAABIAAABgAAAA
+AAAAAAAAAAASAAAAAGxpYnJ0LnNvLjEAbGlic3RkYysrLnNvLjYAX19nbW9uX3N0
+YXJ0X18AX0p2X1JlZ2lzdGVyQ2xhc3NlcwBsaWJtLnNvLjYAbGliZ2NjX3Muc28u
+MQBsaWJjLnNvLjYAZXhpdABwZXJyb3IAcHV0cwBnZXRwaWQAY2xvc2UAb3BlbgBm
+Y250bABfX2xpYmNfc3RhcnRfbWFpbgBHTElCQ18yLjAAAAAAAgACAAAAAAACAAIA
+AgACAAIAAgABAAEAVgAAABAAAAAAAAAAEGlpDQAAAgCbAAAAAAAAAJyZBAgGAwAA
+rJkECAcBAACwmQQIBwIAALSZBAgHAwAAuJkECAcFAAC8mQQIBwYAAMCZBAgHBwAA
+xJkECAcIAADImQQIBwkAAMyZBAgHCgAAU4PsCOgAAAAAW4HD7xUAAIuD/P///4XA
+dAXoSQAAAOhEAQAA6D8DAACDxAhbwwAAAAAAAAAAAAD/NaSZBAj/JaiZBAgAAAAA
+/yWsmQQIaAAAAADp4P////8lsJkECGgIAAAA6dD/////JbSZBAhoEAAAAOnA////
+/yW4mQQIaBgAAADpsP////8lvJkECGggAAAA6aD/////JcCZBAhoKAAAAOmQ////
+/yXEmQQIaDAAAADpgP////8lyJkECGg4AAAA6XD/////JcyZBAhoQAAAAOlg////
+Me1eieGD5PBQVFJoAIcECGiQhgQIUVZoNIUECOh/////9JCQkJCQkJCQkJCQkJCQ
+VYnlU4PsBIA92JkECAB1P6HcmQQIu6yYBAiB66iYBAjB+wKD6wE52HMejbYAAAAA
+g8ABo9yZBAj/FIWomAQIodyZBAg52HLoxgXYmQQIAYPEBFtdw410JgCNvCcAAAAA
+VYnlg+wYobCYBAiFwHQSuAAAAACFwHQJxwQksJgECP/QycOQVYnlV1aD5PCD7DBm
+x0QkHAEAZsdEJB4AAMdEJCAAAAAAx0QkJAAAAADHRCQoAAAAAOiW/v//iUQkKIN9
+CAJ0GMcEJGCHBAjo0P7//8cEJAEAAADo5P7//8dEJAQCAAAAxwQkcYcECOhQ/v//
+iUQkLIN8JCz/D5TAhMB0GMcEJIyHBAjodP7//8cEJAEAAADoqP7//4tFDIPABIsA
+icK4kYcECLkCAAAAidaJx/OmD5fCD5LAidEowYnID77AhcB1Po1EJByJRCQIx0Qk
+BAcAAACLRCQsiQQk6E/+//+D+P8PlMCEwHRdxwQkk4cECOgJ/v//xwQkAQAAAOg9
+/v//ZsdEJBwCAI1EJByJRCQIx0QkBAYAAACLRCQsiQQk6Ar+//+D+P8PlMCEwHQY
+xwQkk4cECOjE/f//xwQkAQAAAOj4/f//i0QkLIkEJOi8/f//uAAAAACNZfheX13D
+VVdWU+hpAAAAgcMHEwAAg+wci2wkMI27AP///+j3/P//jYMA////KcfB/wKF/3Qp
+MfaNtgAAAACLRCQ4iSwkiUQkCItEJDSJRCQE/5SzAP///4PGATn+dd+DxBxbXl9d
+w+sNkJCQkJCQkJCQkJCQkPPDixwkw5CQkJCQkJCQkJBVieVTg+wEoaCYBAiD+P90
+E7ugmAQIZpCD6wT/0IsDg/j/dfSDxARbXcOQkFOD7AjoAAAAAFuBw1sSAADoX/3/
+/4PECFvDAAADAAAAAQACAEludmFsaWQgYXJndW1lbnQAL3RtcC90YXN0b3JlL3V1
+aWRsaXN0Lmxpc3QAb3BlbgAwAGZjbnRsAAAAAAEbAzswAAAABQAAAET8//9MAAAA
+mP3//3AAAAD0/v//nAAAAGT////YAAAAZv///+wAAAAUAAAAAAAAAAF6UgABfAgB
+GwwEBIgBAAAgAAAAHAAAAPD7//+gAAAAAA4IRg4MSg8LdAR4AD8aOyoyJCIoAAAA
+QAAAACD9//9cAQAAAEEOCIUCQg0FboYEhwMDKAHGQcdBDAQExQAAADgAAABsAAAA
+UP7//2EAAAAAQQ4IhQJBDgyHA0EOEIYEQQ4UgwVODjACSg4UQQ4Qw0EODMZBDgjH
+QQ4ExRAAAACoAAAAhP7//wIAAAAAAAAAEAAAALwAAABy/v//BAAAAAAAAAAAAAAA
+/////wAAAAD/////AAAAAAAAAAABAAAAAQAAAAEAAAAMAAAAAQAAAD4AAAABAAAA
+SAAAAAEAAABWAAAADAAAAKiDBAgNAAAAPIcECAQAAACMgQQIBQAAAHyCBAgGAAAA
+zIEECAoAAAClAAAACwAAABAAAAAVAAAAAAAAAAMAAACgmQQIAgAAAEgAAAAUAAAA
+EQAAABcAAABggwQIEQAAAFiDBAgSAAAACAAAABMAAAAIAAAA/v//bziDBAj///9v
+AQAAAPD//28igwQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAALSYBAgAAAAAAAAAAPaDBAgGhAQIFoQECCaEBAg2hAQI
+RoQECFaEBAhmhAQIdoQECAAAAAAAAAAAR0NDOiAoTGluYXJvIEdDQyA0LjYtMjAx
+My4wNSkgNC42LjQAHAAAAAIAAAAAAAQAAAAAADSFBAhcAQAAAAAAAAAAAABFAQAA
+AgAAAAAABAGeAAAABA4AAABNAAAANIUECJCGBAgAAAAAAAAAAAIEB0AAAAACAQiH
+AAAAAgIHuwAAAAIEBzsAAAACAQaJAAAAAgIFrAAAAAMEBWludAACCAUAAAAAAggH
+NgAAAAQuAAAAAo1zAAAAAgQFBQAAAATiAAAAAo9TAAAABQSLAAAAAgEGkAAAAAbc
+AAAAEAOY5QAAAAciAAAAA5pMAAAAAiMAB5UAAAADm0wAAAACIwIHzgAAAAOdaAAA
+AAIjBAfWAAAAA55oAAAAAiMIB4EAAAADo3oAAAACIwwACAEpAAAAAQhTAAAANIUE
+CJCGBAgAAAAAQgEAAAm2AAAAAQhTAAAAApEACeoAAAABCEIBAAACkQQKP4UECImG
+BAgLZmwAAQqSAAAAAnQcC2ZkAAELUwAAAAJ0LAAABQSFAAAAAAERASUOEwsDDhsO
+EQESARAGQwYAAAIkAAsLPgsDDgAAAyQACws+CwMIAAAEFgADDjoLOwtJEwAABQ8A
+CwtJEwAABhMBAw4LCzoLOwsBEwAABw0AAw46CzsLSRM4CgAACC4BPwwDDjoLOwtJ
+ExEBEgFABgETAAAJBQADDjoLOwtJEwIKAAAKCwERARIBAAALNAADCDoLOwtJEwIK
+AAAAVAUAAAIAJAUAAAEB+w4NAAEBAQEAAAABAAABLi4vc3JjAEQ6XHNhbXN1bmct
+dHYtc2RrXHBsYXRmb3Jtc1xyb290c3RyYXBzXG1vYmlsZS0yLjMtZW11bGF0b3Iu
+Y29yZS91c3IvaW5jbHVkZS9iaXRzAEQ6XHNhbXN1bmctdHYtc2RrXHBsYXRmb3Jt
+c1xyb290c3RyYXBzXG1vYmlsZS0yLjMtZW11bGF0b3IuY29yZS91c3IvaW5jbHVk
+ZQBEOlxzYW1zdW5nLXR2LXNka1xwbGF0Zm9ybXNccm9vdHN0cmFwc1xtb2JpbGUt
+Mi4zLWVtdWxhdG9yLmNvcmUvdXNyL2luY2x1ZGUvc3lzAEQ6XHNhbXN1bmctdHYt
+c2RrXHBsYXRmb3Jtc1xyb290c3RyYXBzXG1vYmlsZS0yLjMtZW11bGF0b3IuY29y
+ZS91c3IvaW5jbHVkZS9nbnUAZDpcc2Ftc3VuZy10di1zZGtcdG9vbHNcaTM4Ni1s
+aW51eC1nbnVlYWJpLWdjYy00LjZcYmluXC4uL2xpYi9nY2MvaTM4Ni1saW51eC1n
+bnVlYWJpLzQuNi40L2luY2x1ZGUARDpcc2Ftc3VuZy10di1zZGtccGxhdGZvcm1z
+XHJvb3RzdHJhcHNcbW9iaWxlLTIuMy1lbXVsYXRvci5jb3JlL3Vzci9pbmNsdWRl
+L2xpbnV4AEQ6XHNhbXN1bmctdHYtc2RrXHBsYXRmb3Jtc1xyb290c3RyYXBzXG1v
+YmlsZS0yLjMtZW11bGF0b3IuY29yZS91c3IvaW5jbHVkZS9hc20ARDpcc2Ftc3Vu
+Zy10di1zZGtccGxhdGZvcm1zXHJvb3RzdHJhcHNcbW9iaWxlLTIuMy1lbXVsYXRv
+ci5jb3JlL3Vzci9pbmNsdWRlL2FzbS1nZW5lcmljAABmaWxlTG9jay5jcHAAAQAA
+dHlwZXMuaAACAABmY250bC5oAAIAAHN0ZGlvLmgAAwAAZmVhdHVyZXMuaAADAABw
+cmVkZWZzLmgAAgAAY2RlZnMuaAAEAAB3b3Jkc2l6ZS5oAAIAAHN0dWJzLmgABQAA
+c3R1YnMtMzIuaAAFAABzdGRkZWYuaAAGAAB0eXBlc2l6ZXMuaAACAABsaWJpby5o
+AAMAAF9HX2NvbmZpZy5oAAMAAHdjaGFyLmgAAwAAc3RkYXJnLmgABgAAc3RkaW9f
+bGltLmgAAgAAc3lzX2Vycmxpc3QuaAACAABzdGRsaWIuaAADAAB3YWl0ZmxhZ3Mu
+aAACAAB3YWl0c3RhdHVzLmgAAgAAZW5kaWFuLmgAAwAAZW5kaWFuLmgAAgAAYnl0
+ZXN3YXAuaAACAAB4bG9jYWxlLmgAAwAAdHlwZXMuaAAEAAB0aW1lLmgAAwAAc2Vs
+ZWN0LmgABAAAc2VsZWN0LmgAAgAAc2lnc2V0LmgAAgAAdGltZS5oAAIAAHN5c21h
+Y3Jvcy5oAAQAAHB0aHJlYWR0eXBlcy5oAAIAAGFsbG9jYS5oAAMAAGVycm5vLmgA
+AwAAZXJybm8uaAACAABlcnJuby5oAAcAAGVycm5vLmgACAAAZXJybm8uaAAJAABl
+cnJuby1iYXNlLmgACQAAZmNudGwuaAADAAB1aW8uaAACAABzdGF0LmgAAgAAdW5p
+c3RkLmgAAwAAcG9zaXhfb3B0LmgAAgAAZW52aXJvbm1lbnRzLmgAAgAAY29uZm5h
+bWUuaAACAABnZXRvcHQuaAADAABzdHJpbmcuaAADAAAAAAUCNIUECBmuAiYVkme7
+vQIkE7u9Ai0TAiYTu752AiYTu728WQIHAAEBbG9uZyBsb25nIGludAAuLi9zcmMv
+ZmlsZUxvY2suY3BwAGxfdHlwZQBtYWluAF9fb2ZmX3QAbG9uZyBsb25nIHVuc2ln
+bmVkIGludABDOlxVc2Vyc1xjaGVyeWwuYlx3b3Jrc3BhY2VTaW11bGF0b3JcZmls
+ZUxvY2tcRGVidWcAbF9waWQAdW5zaWduZWQgY2hhcgBsX3doZW5jZQBHTlUgQysr
+IDQuNi40AHNob3J0IGludABhcmdjAHNob3J0IHVuc2lnbmVkIGludABsX3N0YXJ0
+AGxfbGVuAGZsb2NrAF9fcGlkX3QAYXJndgAAAAAAAQAAAAIAdAQBAAAAAwAAAAIA
+dAgDAAAAWwEAAAIAdQhbAQAAXAEAAAIAdAQAAAAAAAAAAAEAX19TVERDX18gMQAB
+AF9fY3BsdXNwbHVzIDEAAQBfX1NURENfSE9TVEVEX18gMQABAF9fR05VQ19fIDQA
+AQBfX0dOVUNfTUlOT1JfXyA2AAEAX19HTlVDX1BBVENITEVWRUxfXyA0AAEAX19W
+RVJTSU9OX18gIjQuNi40IgABAF9fRklOSVRFX01BVEhfT05MWV9fIDAAAQBfX1NJ
+WkVPRl9JTlRfXyA0AAEAX19TSVpFT0ZfTE9OR19fIDQAAQBfX1NJWkVPRl9MT05H
+X0xPTkdfXyA4AAEAX19TSVpFT0ZfU0hPUlRfXyAyAAEAX19TSVpFT0ZfRkxPQVRf
+XyA0AAEAX19TSVpFT0ZfRE9VQkxFX18gOAABAF9fU0laRU9GX0xPTkdfRE9VQkxF
+X18gMTIAAQBfX1NJWkVPRl9TSVpFX1RfXyA0AAEAX19DSEFSX0JJVF9fIDgAAQBf
+X0JJR0dFU1RfQUxJR05NRU5UX18gMTYAAQBfX09SREVSX0xJVFRMRV9FTkRJQU5f
+XyAxMjM0AAEAX19PUkRFUl9CSUdfRU5ESUFOX18gNDMyMQABAF9fT1JERVJfUERQ
+X0VORElBTl9fIDM0MTIAAQBfX0JZVEVfT1JERVJfXyBfX09SREVSX0xJVFRMRV9F
+TkRJQU5fXwABAF9fRkxPQVRfV09SRF9PUkRFUl9fIF9fT1JERVJfTElUVExFX0VO
+RElBTl9fAAEAX19TSVpFT0ZfUE9JTlRFUl9fIDQAAQBfX0dOVUdfXyA0AAEAX19T
+SVpFX1RZUEVfXyB1bnNpZ25lZCBpbnQAAQBfX1BUUkRJRkZfVFlQRV9fIGludAAB
+AF9fV0NIQVJfVFlQRV9fIGxvbmcgaW50AAEAX19XSU5UX1RZUEVfXyB1bnNpZ25l
+ZCBpbnQAAQBfX0lOVE1BWF9UWVBFX18gbG9uZyBsb25nIGludAABAF9fVUlOVE1B
+WF9UWVBFX18gbG9uZyBsb25nIHVuc2lnbmVkIGludAABAF9fQ0hBUjE2X1RZUEVf
+XyBzaG9ydCB1bnNpZ25lZCBpbnQAAQBfX0NIQVIzMl9UWVBFX18gdW5zaWduZWQg
+aW50AAEAX19TSUdfQVRPTUlDX1RZUEVfXyBpbnQAAQBfX0lOVDhfVFlQRV9fIHNp
+Z25lZCBjaGFyAAEAX19JTlQxNl9UWVBFX18gc2hvcnQgaW50AAEAX19JTlQzMl9U
+WVBFX18gaW50AAEAX19JTlQ2NF9UWVBFX18gbG9uZyBsb25nIGludAABAF9fVUlO
+VDhfVFlQRV9fIHVuc2lnbmVkIGNoYXIAAQBfX1VJTlQxNl9UWVBFX18gc2hvcnQg
+dW5zaWduZWQgaW50AAEAX19VSU5UMzJfVFlQRV9fIHVuc2lnbmVkIGludAABAF9f
+VUlOVDY0X1RZUEVfXyBsb25nIGxvbmcgdW5zaWduZWQgaW50AAEAX19JTlRfTEVB
+U1Q4X1RZUEVfXyBzaWduZWQgY2hhcgABAF9fSU5UX0xFQVNUMTZfVFlQRV9fIHNo
+b3J0IGludAABAF9fSU5UX0xFQVNUMzJfVFlQRV9fIGludAABAF9fSU5UX0xFQVNU
+NjRfVFlQRV9fIGxvbmcgbG9uZyBpbnQAAQBfX1VJTlRfTEVBU1Q4X1RZUEVfXyB1
+bnNpZ25lZCBjaGFyAAEAX19VSU5UX0xFQVNUMTZfVFlQRV9fIHNob3J0IHVuc2ln
+bmVkIGludAABAF9fVUlOVF9MRUFTVDMyX1RZUEVfXyB1bnNpZ25lZCBpbnQAAQBf
+X1VJTlRfTEVBU1Q2NF9UWVBFX18gbG9uZyBsb25nIHVuc2lnbmVkIGludAABAF9f
+SU5UX0ZBU1Q4X1RZUEVfXyBzaWduZWQgY2hhcgABAF9fSU5UX0ZBU1QxNl9UWVBF
+X18gaW50AAEAX19JTlRfRkFTVDMyX1RZUEVfXyBpbnQAAQBfX0lOVF9GQVNUNjRf
+VFlQRV9fIGxvbmcgbG9uZyBpbnQAAQBfX1VJTlRfRkFTVDhfVFlQRV9fIHVuc2ln
+bmVkIGNoYXIAAQBfX1VJTlRfRkFTVDE2X1RZUEVfXyB1bnNpZ25lZCBpbnQAAQBf
+X1VJTlRfRkFTVDMyX1RZUEVfXyB1bnNpZ25lZCBpbnQAAQBfX1VJTlRfRkFTVDY0
+X1RZUEVfXyBsb25nIGxvbmcgdW5zaWduZWQgaW50AAEAX19JTlRQVFJfVFlQRV9f
+IGludAABAF9fVUlOVFBUUl9UWVBFX18gdW5zaWduZWQgaW50AAEAX19HWFhfV0VB
+S19fIDEAAQBfX0RFUFJFQ0FURUQgMQABAF9fR1hYX1JUVEkgMQABAF9fRVhDRVBU
+SU9OUyAxAAEAX19HWFhfQUJJX1ZFUlNJT04gMTAwMgABAF9fU0NIQVJfTUFYX18g
+MTI3AAEAX19TSFJUX01BWF9fIDMyNzY3AAEAX19JTlRfTUFYX18gMjE0NzQ4MzY0
+NwABAF9fTE9OR19NQVhfXyAyMTQ3NDgzNjQ3TAABAF9fTE9OR19MT05HX01BWF9f
+IDkyMjMzNzIwMzY4NTQ3NzU4MDdMTAABAF9fV0NIQVJfTUFYX18gMjE0NzQ4MzY0
+N0wAAQBfX1dDSEFSX01JTl9fICgtX19XQ0hBUl9NQVhfXyAtIDEpAAEAX19XSU5U
+X01BWF9fIDQyOTQ5NjcyOTVVAAEAX19XSU5UX01JTl9fIDBVAAEAX19QVFJESUZG
+X01BWF9fIDIxNDc0ODM2NDcAAQBfX1NJWkVfTUFYX18gNDI5NDk2NzI5NVUAAQBf
+X0lOVE1BWF9NQVhfXyA5MjIzMzcyMDM2ODU0Nzc1ODA3TEwAAQBfX0lOVE1BWF9D
+KGMpIGMgIyMgTEwAAQBfX1VJTlRNQVhfTUFYX18gMTg0NDY3NDQwNzM3MDk1NTE2
+MTVVTEwAAQBfX1VJTlRNQVhfQyhjKSBjICMjIFVMTAABAF9fU0lHX0FUT01JQ19N
+QVhfXyAyMTQ3NDgzNjQ3AAEAX19TSUdfQVRPTUlDX01JTl9fICgtX19TSUdfQVRP
+TUlDX01BWF9fIC0gMSkAAQBfX0lOVDhfTUFYX18gMTI3AAEAX19JTlQxNl9NQVhf
+XyAzMjc2NwABAF9fSU5UMzJfTUFYX18gMjE0NzQ4MzY0NwABAF9fSU5UNjRfTUFY
+X18gOTIyMzM3MjAzNjg1NDc3NTgwN0xMAAEAX19VSU5UOF9NQVhfXyAyNTUAAQBf
+X1VJTlQxNl9NQVhfXyA2NTUzNQABAF9fVUlOVDMyX01BWF9fIDQyOTQ5NjcyOTVV
+AAEAX19VSU5UNjRfTUFYX18gMTg0NDY3NDQwNzM3MDk1NTE2MTVVTEwAAQBfX0lO
+VF9MRUFTVDhfTUFYX18gMTI3AAEAX19JTlQ4X0MoYykgYwABAF9fSU5UX0xFQVNU
+MTZfTUFYX18gMzI3NjcAAQBfX0lOVDE2X0MoYykgYwABAF9fSU5UX0xFQVNUMzJf
+TUFYX18gMjE0NzQ4MzY0NwABAF9fSU5UMzJfQyhjKSBjAAEAX19JTlRfTEVBU1Q2
+NF9NQVhfXyA5MjIzMzcyMDM2ODU0Nzc1ODA3TEwAAQBfX0lOVDY0X0MoYykgYyAj
+IyBMTAABAF9fVUlOVF9MRUFTVDhfTUFYX18gMjU1AAEAX19VSU5UOF9DKGMpIGMA
+AQBfX1VJTlRfTEVBU1QxNl9NQVhfXyA2NTUzNQABAF9fVUlOVDE2X0MoYykgYwAB
+AF9fVUlOVF9MRUFTVDMyX01BWF9fIDQyOTQ5NjcyOTVVAAEAX19VSU5UMzJfQyhj
+KSBjICMjIFUAAQBfX1VJTlRfTEVBU1Q2NF9NQVhfXyAxODQ0Njc0NDA3MzcwOTU1
+MTYxNVVMTAABAF9fVUlOVDY0X0MoYykgYyAjIyBVTEwAAQBfX0lOVF9GQVNUOF9N
+QVhfXyAxMjcAAQBfX0lOVF9GQVNUMTZfTUFYX18gMjE0NzQ4MzY0NwABAF9fSU5U
+X0ZBU1QzMl9NQVhfXyAyMTQ3NDgzNjQ3AAEAX19JTlRfRkFTVDY0X01BWF9fIDky
+MjMzNzIwMzY4NTQ3NzU4MDdMTAABAF9fVUlOVF9GQVNUOF9NQVhfXyAyNTUAAQBf
+X1VJTlRfRkFTVDE2X01BWF9fIDQyOTQ5NjcyOTVVAAEAX19VSU5UX0ZBU1QzMl9N
+QVhfXyA0Mjk0OTY3Mjk1VQABAF9fVUlOVF9GQVNUNjRfTUFYX18gMTg0NDY3NDQw
+NzM3MDk1NTE2MTVVTEwAAQBfX0lOVFBUUl9NQVhfXyAyMTQ3NDgzNjQ3AAEAX19V
+SU5UUFRSX01BWF9fIDQyOTQ5NjcyOTVVAAEAX19GTFRfRVZBTF9NRVRIT0RfXyAy
+AAEAX19ERUNfRVZBTF9NRVRIT0RfXyAyAAEAX19GTFRfUkFESVhfXyAyAAEAX19G
+TFRfTUFOVF9ESUdfXyAyNAABAF9fRkxUX0RJR19fIDYAAQBfX0ZMVF9NSU5fRVhQ
+X18gKC0xMjUpAAEAX19GTFRfTUlOXzEwX0VYUF9fICgtMzcpAAEAX19GTFRfTUFY
+X0VYUF9fIDEyOAABAF9fRkxUX01BWF8xMF9FWFBfXyAzOAABAF9fRkxUX0RFQ0lN
+QUxfRElHX18gOQABAF9fRkxUX01BWF9fIDMuNDAyODIzNDY2Mzg1Mjg4NTk4MTJl
+KzM4RgABAF9fRkxUX01JTl9fIDEuMTc1NDk0MzUwODIyMjg3NTA3OTdlLTM4RgAB
+AF9fRkxUX0VQU0lMT05fXyAxLjE5MjA5Mjg5NTUwNzgxMjUwMDAwZS03RgABAF9f
+RkxUX0RFTk9STV9NSU5fXyAxLjQwMTI5ODQ2NDMyNDgxNzA3MDkyZS00NUYAAQBf
+X0ZMVF9IQVNfREVOT1JNX18gMQABAF9fRkxUX0hBU19JTkZJTklUWV9fIDEAAQBf
+X0ZMVF9IQVNfUVVJRVRfTkFOX18gMQABAF9fREJMX01BTlRfRElHX18gNTMAAQBf
+X0RCTF9ESUdfXyAxNQABAF9fREJMX01JTl9FWFBfXyAoLTEwMjEpAAEAX19EQkxf
+TUlOXzEwX0VYUF9fICgtMzA3KQABAF9fREJMX01BWF9FWFBfXyAxMDI0AAEAX19E
+QkxfTUFYXzEwX0VYUF9fIDMwOAABAF9fREJMX0RFQ0lNQUxfRElHX18gMTcAAQBf
+X0RCTF9NQVhfXyBkb3VibGUoMS43OTc2OTMxMzQ4NjIzMTU3MDgxNWUrMzA4TCkA
+AQBfX0RCTF9NSU5fXyBkb3VibGUoMi4yMjUwNzM4NTg1MDcyMDEzODMwOWUtMzA4
+TCkAAQBfX0RCTF9FUFNJTE9OX18gZG91YmxlKDIuMjIwNDQ2MDQ5MjUwMzEzMDgw
+ODVlLTE2TCkAAQBfX0RCTF9ERU5PUk1fTUlOX18gZG91YmxlKDQuOTQwNjU2NDU4
+NDEyNDY1NDQxNzdlLTMyNEwpAAEAX19EQkxfSEFTX0RFTk9STV9fIDEAAQBfX0RC
+TF9IQVNfSU5GSU5JVFlfXyAxAAEAX19EQkxfSEFTX1FVSUVUX05BTl9fIDEAAQBf
+X0xEQkxfTUFOVF9ESUdfXyA2NAABAF9fTERCTF9ESUdfXyAxOAABAF9fTERCTF9N
+SU5fRVhQX18gKC0xNjM4MSkAAQBfX0xEQkxfTUlOXzEwX0VYUF9fICgtNDkzMSkA
+AQBfX0xEQkxfTUFYX0VYUF9fIDE2Mzg0AAEAX19MREJMX01BWF8xMF9FWFBfXyA0
+OTMyAAEAX19ERUNJTUFMX0RJR19fIDIxAAEAX19MREJMX01BWF9fIDEuMTg5NzMx
+NDk1MzU3MjMxNzY1MDJlKzQ5MzJMAAEAX19MREJMX01JTl9fIDMuMzYyMTAzMTQz
+MTEyMDkzNTA2MjZlLTQ5MzJMAAEAX19MREJMX0VQU0lMT05fXyAxLjA4NDIwMjE3
+MjQ4NTUwNDQzNDAxZS0xOUwAAQBfX0xEQkxfREVOT1JNX01JTl9fIDMuNjQ1MTk5
+NTMxODgyNDc0NjAyNTNlLTQ5NTFMAAEAX19MREJMX0hBU19ERU5PUk1fXyAxAAEA
+X19MREJMX0hBU19JTkZJTklUWV9fIDEAAQBfX0xEQkxfSEFTX1FVSUVUX05BTl9f
+IDEAAQBfX0RFQzMyX01BTlRfRElHX18gNwABAF9fREVDMzJfTUlOX0VYUF9fICgt
+OTQpAAEAX19ERUMzMl9NQVhfRVhQX18gOTcAAQBfX0RFQzMyX01JTl9fIDFFLTk1
+REYAAQBfX0RFQzMyX01BWF9fIDkuOTk5OTk5RTk2REYAAQBfX0RFQzMyX0VQU0lM
+T05fXyAxRS02REYAAQBfX0RFQzMyX1NVQk5PUk1BTF9NSU5fXyAwLjAwMDAwMUUt
+OTVERgABAF9fREVDNjRfTUFOVF9ESUdfXyAxNgABAF9fREVDNjRfTUlOX0VYUF9f
+ICgtMzgyKQABAF9fREVDNjRfTUFYX0VYUF9fIDM4NQABAF9fREVDNjRfTUlOX18g
+MUUtMzgzREQAAQBfX0RFQzY0X01BWF9fIDkuOTk5OTk5OTk5OTk5OTk5RTM4NERE
+AAEAX19ERUM2NF9FUFNJTE9OX18gMUUtMTVERAABAF9fREVDNjRfU1VCTk9STUFM
+X01JTl9fIDAuMDAwMDAwMDAwMDAwMDAxRS0zODNERAABAF9fREVDMTI4X01BTlRf
+RElHX18gMzQAAQBfX0RFQzEyOF9NSU5fRVhQX18gKC02MTQyKQABAF9fREVDMTI4
+X01BWF9FWFBfXyA2MTQ1AAEAX19ERUMxMjhfTUlOX18gMUUtNjE0M0RMAAEAX19E
+RUMxMjhfTUFYX18gOS45OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlF
+NjE0NERMAAEAX19ERUMxMjhfRVBTSUxPTl9fIDFFLTMzREwAAQBfX0RFQzEyOF9T
+VUJOT1JNQUxfTUlOX18gMC4wMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
+MDFFLTYxNDNETAABAF9fUkVHSVNURVJfUFJFRklYX18gAAEAX19VU0VSX0xBQkVM
+X1BSRUZJWF9fIAABAF9fR05VQ19HTlVfSU5MSU5FX18gMQABAF9fTk9fSU5MSU5F
+X18gMQABAF9fR0NDX0hBVkVfRFdBUkYyX0NGSV9BU00gMQABAF9fUFJBR01BX1JF
+REVGSU5FX0VYVE5BTUUgMQABAF9fU0laRU9GX1dDSEFSX1RfXyA0AAEAX19TSVpF
+T0ZfV0lOVF9UX18gNAABAF9fU0laRU9GX1BUUkRJRkZfVF9fIDQAAQBfX2kzODYg
+MQABAF9faTM4Nl9fIDEAAQBpMzg2IDEAAQBfX2dudV9saW51eF9fIDEAAQBfX2xp
+bnV4IDEAAQBfX2xpbnV4X18gMQABAGxpbnV4IDEAAQBfX3VuaXggMQABAF9fdW5p
+eF9fIDEAAQB1bml4IDEAAQBfX0VMRl9fIDEAAQBfX0RFQ0lNQUxfQklEX0ZPUk1B
+VF9fIDEAAQBfR05VX1NPVVJDRSAxAAMAAQMBBAEbX1NURElPX0ggMQADHAUBFV9G
+RUFUVVJFU19IIDEAAmFfX1VTRV9JU09DOTkAAmJfX1VTRV9JU09DOTUAAmNfX1VT
+RV9QT1NJWAACZF9fVVNFX1BPU0lYMgACZV9fVVNFX1BPU0lYMTk5MzA5AAJmX19V
+U0VfUE9TSVgxOTk1MDYAAmdfX1VTRV9YT1BFTgACaF9fVVNFX1hPUEVOX0VYVEVO
+REVEAAJpX19VU0VfVU5JWDk4AAJqX19VU0VfWE9QRU4ySwACa19fVVNFX1hPUEVO
+MktYU0kAAmxfX1VTRV9YT1BFTjJLOAACbV9fVVNFX1hPUEVOMks4WFNJAAJuX19V
+U0VfTEFSR0VGSUxFAAJvX19VU0VfTEFSR0VGSUxFNjQAAnBfX1VTRV9GSUxFX09G
+RlNFVDY0AAJxX19VU0VfQlNEAAJyX19VU0VfU1ZJRAACc19fVVNFX01JU0MAAnRf
+X1VTRV9BVEZJTEUAAnVfX1VTRV9HTlUAAnZfX1VTRV9SRUVOVFJBTlQAAndfX1VT
+RV9GT1JUSUZZX0xFVkVMAAJ4X19GQVZPUl9CU0QAAnlfX0tFUk5FTF9TVFJJQ1Rf
+TkFNRVMAAX5fX0tFUk5FTF9TVFJJQ1RfTkFNRVMgAAGCAV9fVVNFX0FOU0kgMQAB
+jAFfX0dOVUNfUFJFUkVRKG1haixtaW4pICgoX19HTlVDX18gPDwgMTYpICsgX19H
+TlVDX01JTk9SX18gPj0gKChtYWopIDw8IDE2KSArIChtaW4pKQACnAFfSVNPQzk1
+X1NPVVJDRQABnQFfSVNPQzk1X1NPVVJDRSAxAAKeAV9JU09DOTlfU09VUkNFAAGf
+AV9JU09DOTlfU09VUkNFIDEAAqABX1BPU0lYX1NPVVJDRQABoQFfUE9TSVhfU09V
+UkNFIDEAAqIBX1BPU0lYX0NfU09VUkNFAAGjAV9QT1NJWF9DX1NPVVJDRSAyMDA4
+MDlMAAKkAV9YT1BFTl9TT1VSQ0UAAaUBX1hPUEVOX1NPVVJDRSA3MDAAAqYBX1hP
+UEVOX1NPVVJDRV9FWFRFTkRFRAABpwFfWE9QRU5fU09VUkNFX0VYVEVOREVEIDEA
+AqgBX0xBUkdFRklMRTY0X1NPVVJDRQABqQFfTEFSR0VGSUxFNjRfU09VUkNFIDEA
+AqoBX0JTRF9TT1VSQ0UAAasBX0JTRF9TT1VSQ0UgMQACrAFfU1ZJRF9TT1VSQ0UA
+Aa0BX1NWSURfU09VUkNFIDEAAq4BX0FURklMRV9TT1VSQ0UAAa8BX0FURklMRV9T
+T1VSQ0UgMQABwQFfX1VTRV9JU09DOTkgMQABxwFfX1VTRV9JU09DOTUgMQAB3AFf
+X1VTRV9QT1NJWCAxAAHgAV9fVVNFX1BPU0lYMiAxAAHkAV9fVVNFX1BPU0lYMTk5
+MzA5IDEAAegBX19VU0VfUE9TSVgxOTk1MDYgMQAB7AFfX1VTRV9YT1BFTjJLIDEA
+Au0BX19VU0VfSVNPQzk1AAHuAV9fVVNFX0lTT0M5NSAxAALvAV9fVVNFX0lTT0M5
+OQAB8AFfX1VTRV9JU09DOTkgMQAB9AFfX1VTRV9YT1BFTjJLOCAxAAL1AV9BVEZJ
+TEVfU09VUkNFAAH2AV9BVEZJTEVfU09VUkNFIDEAAfoBX19VU0VfWE9QRU4gMQAB
+/AFfX1VTRV9YT1BFTl9FWFRFTkRFRCAxAAH9AV9fVVNFX1VOSVg5OCAxAAL+AV9M
+QVJHRUZJTEVfU09VUkNFAAH/AV9MQVJHRUZJTEVfU09VUkNFIDEAAYICX19VU0Vf
+WE9QRU4ySzggMQABgwJfX1VTRV9YT1BFTjJLOFhTSSAxAAGFAl9fVVNFX1hPUEVO
+MksgMQABhgJfX1VTRV9YT1BFTjJLWFNJIDEAAocCX19VU0VfSVNPQzk1AAGIAl9f
+VVNFX0lTT0M5NSAxAAKJAl9fVVNFX0lTT0M5OQABigJfX1VTRV9JU09DOTkgMQAB
+lAJfX1VTRV9MQVJHRUZJTEUgMQABmAJfX1VTRV9MQVJHRUZJTEU2NCAxAAGgAl9f
+VVNFX01JU0MgMQABpAJfX1VTRV9CU0QgMQABqAJfX1VTRV9TVklEIDEAAawCX19V
+U0VfQVRGSUxFIDEAAbACX19VU0VfR05VIDEAAb8CX19VU0VfRk9SVElGWV9MRVZF
+TCAwAAPDAgYBGF9QUkVERUZTX0ggAAEbX19TVERDX0lFQ181NTlfXyAxAAEcX19T
+VERDX0lFQ181NTlfQ09NUExFWF9fIDEABAHGAl9fU1REQ19JU09fMTA2NDZfXyAy
+MDAwMDlMAALOAl9fR05VX0xJQlJBUllfXwABzwJfX0dOVV9MSUJSQVJZX18gNgAB
+0wJfX0dMSUJDX18gMgAB1AJfX0dMSUJDX01JTk9SX18gMTMAAdYCX19HTElCQ19Q
+UkVSRVEobWFqLG1pbikgKChfX0dMSUJDX18gPDwgMTYpICsgX19HTElCQ19NSU5P
+Ul9fID49ICgobWFqKSA8PCAxNikgKyAobWluKSkAAd4CX19HTElCQ19IQVZFX0xP
+TkdfTE9ORyAxAAPkAgcBFV9TWVNfQ0RFRlNfSCAxAAIkX19QAAIlX19QTVQAATNf
+X1RIUk9XIHRocm93ICgpAAE0X19OVEgoZmN0KSBmY3QgdGhyb3cgKCkAAUpfX1Ao
+YXJncykgYXJncwABS19fUE1UKGFyZ3MpIGFyZ3MAAVBfX0NPTkNBVCh4LHkpIHgg
+IyMgeQABUV9fU1RSSU5HKHgpICN4AAFUX19wdHJfdCB2b2lkICoAAVVfX2xvbmdf
+ZG91YmxlX3QgbG9uZyBkb3VibGUAAVpfX0JFR0lOX0RFQ0xTIGV4dGVybiAiQyIg
+ewABW19fRU5EX0RFQ0xTIH0AAXJfX0JFR0lOX05BTUVTUEFDRV9TVEQgAAFzX19F
+TkRfTkFNRVNQQUNFX1NURCAAAXRfX1VTSU5HX05BTUVTUEFDRV9TVEQobmFtZSkg
+AAF1X19CRUdJTl9OQU1FU1BBQ0VfQzk5IAABdl9fRU5EX05BTUVTUEFDRV9DOTkg
+AAF3X19VU0lOR19OQU1FU1BBQ0VfQzk5KG5hbWUpIAABfV9fYm91bmRlZCAAAX5f
+X3VuYm91bmRlZCAAAX9fX3B0cnZhbHVlIAABhAFfX2JvcyhwdHIpIF9fYnVpbHRp
+bl9vYmplY3Rfc2l6ZSAocHRyLCBfX1VTRV9GT1JUSUZZX0xFVkVMID4gMSkAAYUB
+X19ib3MwKHB0cikgX19idWlsdGluX29iamVjdF9zaXplIChwdHIsIDApAAGIAV9f
+d2FybmRlY2wobmFtZSxtc2cpIGV4dGVybiB2b2lkIG5hbWUgKHZvaWQpIF9fYXR0
+cmlidXRlX18oKF9fd2FybmluZ19fIChtc2cpKSkAAYoBX193YXJuYXR0cihtc2cp
+IF9fYXR0cmlidXRlX18oKF9fd2FybmluZ19fIChtc2cpKSkAAYsBX19lcnJvcmRl
+Y2wobmFtZSxtc2cpIGV4dGVybiB2b2lkIG5hbWUgKHZvaWQpIF9fYXR0cmlidXRl
+X18oKF9fZXJyb3JfXyAobXNnKSkpAAGWAV9fZmxleGFyciBbXQABsQFfX1JFRElS
+RUNUKG5hbWUscHJvdG8sYWxpYXMpIG5hbWUgcHJvdG8gX19hc21fXyAoX19BU01O
+QU1FICgjYWxpYXMpKQABswFfX1JFRElSRUNUX05USChuYW1lLHByb3RvLGFsaWFz
+KSBuYW1lIHByb3RvIF9fVEhST1cgX19hc21fXyAoX19BU01OQU1FICgjYWxpYXMp
+KQABuQFfX0FTTU5BTUUoY25hbWUpIF9fQVNNTkFNRTIgKF9fVVNFUl9MQUJFTF9Q
+UkVGSVhfXywgY25hbWUpAAG6AV9fQVNNTkFNRTIocHJlZml4LGNuYW1lKSBfX1NU
+UklORyAocHJlZml4KSBjbmFtZQABzwFfX2F0dHJpYnV0ZV9tYWxsb2NfXyBfX2F0
+dHJpYnV0ZV9fICgoX19tYWxsb2NfXykpAAHYAV9fYXR0cmlidXRlX3B1cmVfXyBf
+X2F0dHJpYnV0ZV9fICgoX19wdXJlX18pKQAB4QFfX2F0dHJpYnV0ZV91c2VkX18g
+X19hdHRyaWJ1dGVfXyAoKF9fdXNlZF9fKSkAAeIBX19hdHRyaWJ1dGVfbm9pbmxp
+bmVfXyBfX2F0dHJpYnV0ZV9fICgoX19ub2lubGluZV9fKSkAAeoBX19hdHRyaWJ1
+dGVfZGVwcmVjYXRlZF9fIF9fYXR0cmlidXRlX18gKChfX2RlcHJlY2F0ZWRfXykp
+AAH2AV9fYXR0cmlidXRlX2Zvcm1hdF9hcmdfXyh4KSBfX2F0dHJpYnV0ZV9fICgo
+X19mb3JtYXRfYXJnX18gKHgpKSkAAYACX19hdHRyaWJ1dGVfZm9ybWF0X3N0cmZt
+b25fXyhhLGIpIF9fYXR0cmlidXRlX18gKChfX2Zvcm1hdF9fIChfX3N0cmZtb25f
+XywgYSwgYikpKQABiQJfX25vbm51bGwocGFyYW1zKSBfX2F0dHJpYnV0ZV9fICgo
+X19ub25udWxsX18gcGFyYW1zKSkAAZECX19hdHRyaWJ1dGVfd2Fybl91bnVzZWRf
+cmVzdWx0X18gX19hdHRyaWJ1dGVfXyAoKF9fd2Fybl91bnVzZWRfcmVzdWx0X18p
+KQABmgJfX3d1ciAAAZ8CX19hbHdheXNfaW5saW5lIF9faW5saW5lIF9fYXR0cmli
+dXRlX18gKChfX2Fsd2F5c19pbmxpbmVfXykpAAGoAl9fZXh0ZXJuX2lubGluZSBl
+eHRlcm4gX19pbmxpbmUgX19hdHRyaWJ1dGVfXyAoKF9fZ251X2lubGluZV9fKSkA
+AaoCX19leHRlcm5fYWx3YXlzX2lubGluZSBleHRlcm4gX19hbHdheXNfaW5saW5l
+IF9fYXR0cmlidXRlX18gKChfX2dudV9pbmxpbmVfXywgX19hcnRpZmljaWFsX18p
+KQABvgJfX3ZhX2FyZ19wYWNrKCkgX19idWlsdGluX3ZhX2FyZ19wYWNrICgpAAG/
+Al9fdmFfYXJnX3BhY2tfbGVuKCkgX19idWlsdGluX3ZhX2FyZ19wYWNrX2xlbiAo
+KQAB1gJfX3Jlc3RyaWN0X2FyciAAA+ECCAETX19XT1JEU0laRSAzMgAEAfcCX19M
+REJMX1JFRElSMShuYW1lLHByb3RvLGFsaWFzKSBuYW1lIHByb3RvAAH4Al9fTERC
+TF9SRURJUihuYW1lLHByb3RvKSBuYW1lIHByb3RvAAH5Al9fTERCTF9SRURJUjFf
+TlRIKG5hbWUscHJvdG8sYWxpYXMpIG5hbWUgcHJvdG8gX19USFJPVwAB+gJfX0xE
+QkxfUkVESVJfTlRIKG5hbWUscHJvdG8pIG5hbWUgcHJvdG8gX19USFJPVwAB+wJf
+X0xEQkxfUkVESVJfREVDTChuYW1lKSAAAf0CX19SRURJUkVDVF9MREJMKG5hbWUs
+cHJvdG8sYWxpYXMpIF9fUkVESVJFQ1QgKG5hbWUsIHByb3RvLCBhbGlhcykAAf4C
+X19SRURJUkVDVF9OVEhfTERCTChuYW1lLHByb3RvLGFsaWFzKSBfX1JFRElSRUNU
+X05USCAobmFtZSwgcHJvdG8sIGFsaWFzKQAEA4QDCQMECAETX19XT1JEU0laRSAz
+MgAEAwcKAQpfX3N0dWJfX19rZXJuZWxfY29zbCAAAQtfX3N0dWJfX19rZXJuZWxf
+c2lubCAAAQxfX3N0dWJfX19rZXJuZWxfdGFubCAAAQ1fX3N0dWJfY2hmbGFncyAA
+AQ5fX3N0dWJfZmF0dGFjaCAAAQ9fX3N0dWJfZmNoZmxhZ3MgAAEQX19zdHViX2Zk
+ZXRhY2ggAAERX19zdHViX2d0dHkgAAESX19zdHViX2xjaG1vZCAAARNfX3N0dWJf
+cmV2b2tlIAABFF9fc3R1Yl9zZXRsb2dpbiAAARVfX3N0dWJfc2lncmV0dXJuIAAB
+Fl9fc3R1Yl9zc3RrIAABF19fc3R1Yl9zdHR5IAAEBAQBIF9fbmVlZF9zaXplX3Qg
+AAEhX19uZWVkX05VTEwgAAMiCwG7AV9fc2l6ZV90X18gAAG8AV9fU0laRV9UX18g
+AAG9AV9TSVpFX1QgAAG+AV9TWVNfU0laRV9UX0ggAAG/AV9UX1NJWkVfIAABwAFf
+VF9TSVpFIAABwQFfX1NJWkVfVCAAAcIBX1NJWkVfVF8gAAHDAV9CU0RfU0laRV9U
+XyAAAcQBX1NJWkVfVF9ERUZJTkVEXyAAAcUBX1NJWkVfVF9ERUZJTkVEIAABxgFf
+QlNEX1NJWkVfVF9ERUZJTkVEXyAAAccBX1NJWkVfVF9ERUNMQVJFRCAAAcgBX19f
+aW50X3NpemVfdF9oIAAByQFfR0NDX1NJWkVfVCAAAcoBX1NJWkVUXyAAAc4BX19z
+aXplX3QgAALqAV9fbmVlZF9zaXplX3QAAo0DTlVMTAABjwNOVUxMIF9fbnVsbAAC
+mANfX25lZWRfTlVMTAAEAyQCARlfQklUU19UWVBFU19IIDEAAxwIARNfX1dPUkRT
+SVpFIDMyAAQBY19fUzE2X1RZUEUgc2hvcnQgaW50AAFkX19VMTZfVFlQRSB1bnNp
+Z25lZCBzaG9ydCBpbnQAAWVfX1MzMl9UWVBFIGludAABZl9fVTMyX1RZUEUgdW5z
+aWduZWQgaW50AAFnX19TTE9OR1dPUkRfVFlQRSBsb25nIGludAABaF9fVUxPTkdX
+T1JEX1RZUEUgdW5zaWduZWQgbG9uZyBpbnQAAWpfX1NRVUFEX1RZUEUgX19xdWFk
+X3QAAWtfX1VRVUFEX1RZUEUgX191X3F1YWRfdAABbF9fU1dPUkRfVFlQRSBpbnQA
+AW1fX1VXT1JEX1RZUEUgdW5zaWduZWQgaW50AAFuX19TTE9ORzMyX1RZUEUgbG9u
+ZyBpbnQAAW9fX1VMT05HMzJfVFlQRSB1bnNpZ25lZCBsb25nIGludAABcF9fUzY0
+X1RZUEUgX19xdWFkX3QAAXFfX1U2NF9UWVBFIF9fdV9xdWFkX3QAAXRfX1NURF9U
+WVBFIF9fZXh0ZW5zaW9uX18gdHlwZWRlZgADgwEMARlfQklUU19UWVBFU0laRVNf
+SCAxAAEeX19ERVZfVF9UWVBFIF9fVVFVQURfVFlQRQABH19fVUlEX1RfVFlQRSBf
+X1UzMl9UWVBFAAEgX19HSURfVF9UWVBFIF9fVTMyX1RZUEUAASFfX0lOT19UX1RZ
+UEUgX19VTE9OR1dPUkRfVFlQRQABIl9fSU5PNjRfVF9UWVBFIF9fVVFVQURfVFlQ
+RQABI19fTU9ERV9UX1RZUEUgX19VMzJfVFlQRQABJF9fTkxJTktfVF9UWVBFIF9f
+VVdPUkRfVFlQRQABJV9fT0ZGX1RfVFlQRSBfX1NMT05HV09SRF9UWVBFAAEmX19P
+RkY2NF9UX1RZUEUgX19TUVVBRF9UWVBFAAEnX19QSURfVF9UWVBFIF9fUzMyX1RZ
+UEUAAShfX1JMSU1fVF9UWVBFIF9fVUxPTkdXT1JEX1RZUEUAASlfX1JMSU02NF9U
+X1RZUEUgX19VUVVBRF9UWVBFAAEqX19CTEtDTlRfVF9UWVBFIF9fU0xPTkdXT1JE
+X1RZUEUAAStfX0JMS0NOVDY0X1RfVFlQRSBfX1NRVUFEX1RZUEUAASxfX0ZTQkxL
+Q05UX1RfVFlQRSBfX1VMT05HV09SRF9UWVBFAAEtX19GU0JMS0NOVDY0X1RfVFlQ
+RSBfX1VRVUFEX1RZUEUAAS5fX0ZTRklMQ05UX1RfVFlQRSBfX1VMT05HV09SRF9U
+WVBFAAEvX19GU0ZJTENOVDY0X1RfVFlQRSBfX1VRVUFEX1RZUEUAATBfX0lEX1Rf
+VFlQRSBfX1UzMl9UWVBFAAExX19DTE9DS19UX1RZUEUgX19TTE9OR1dPUkRfVFlQ
+RQABMl9fVElNRV9UX1RZUEUgX19TTE9OR1dPUkRfVFlQRQABM19fVVNFQ09ORFNf
+VF9UWVBFIF9fVTMyX1RZUEUAATRfX1NVU0VDT05EU19UX1RZUEUgX19TTE9OR1dP
+UkRfVFlQRQABNV9fREFERFJfVF9UWVBFIF9fUzMyX1RZUEUAATZfX1NXQkxLX1Rf
+VFlQRSBfX1NMT05HV09SRF9UWVBFAAE3X19LRVlfVF9UWVBFIF9fUzMyX1RZUEUA
+AThfX0NMT0NLSURfVF9UWVBFIF9fUzMyX1RZUEUAATlfX1RJTUVSX1RfVFlQRSB2
+b2lkICoAATpfX0JMS1NJWkVfVF9UWVBFIF9fU0xPTkdXT1JEX1RZUEUAATtfX0ZT
+SURfVF9UWVBFIHN0cnVjdCB7IGludCBfX3ZhbFsyXTsgfQABPF9fU1NJWkVfVF9U
+WVBFIF9fU1dPUkRfVFlQRQABP19fRkRfU0VUU0laRSAxMDI0AAQCwwFfX1NURF9U
+WVBFAAQBJV9fbmVlZF9GSUxFIAABJl9fbmVlZF9fX0ZJTEUgAAE5X19GSUxFX2Rl
+ZmluZWQgMQACO19fbmVlZF9GSUxFAAFDX19fX0ZJTEVfZGVmaW5lZCAxAAJFX19u
+ZWVkX19fRklMRQABSV9TVERJT19VU0VTX0lPU1RSRUFNIAADSw0BHl9JT19TVERJ
+T19IIAADIA4BBV9HX2NvbmZpZ19oIDEAAQpfX25lZWRfc2l6ZV90IAABDl9fbmVl
+ZF9OVUxMIAADDwsC6gFfX25lZWRfc2l6ZV90AAKNA05VTEwAAY8DTlVMTCBfX251
+bGwAApgDX19uZWVkX05VTEwABAEQX19uZWVkX21ic3RhdGVfdCAAAxQPAVFfX21i
+c3RhdGVfdF9kZWZpbmVkIDEAAmFfX25lZWRfbWJzdGF0ZV90AAKBB19fbmVlZF9t
+YnN0YXRlX3QAAoIHX19uZWVkX3dpbnRfdAAEARVfR19zaXplX3Qgc2l6ZV90AAEg
+X0dfc3NpemVfdCBfX3NzaXplX3QAASFfR19vZmZfdCBfX29mZl90AAEiX0dfb2Zm
+NjRfdCBfX29mZjY0X3QAASNfR19waWRfdCBfX3BpZF90AAEkX0dfdWlkX3QgX191
+aWRfdAABJV9HX3djaGFyX3Qgd2NoYXJfdAABJl9HX3dpbnRfdCB3aW50X3QAASdf
+R19zdGF0NjQgc3RhdDY0AAE6X0dfSEFWRV9CT09MIDEAAT5fR19IQVZFX0FURVhJ
+VCAxAAE/X0dfSEFWRV9TWVNfQ0RFRlMgMQABQF9HX0hBVkVfU1lTX1dBSVQgMQAB
+QV9HX05FRURfU1REQVJHX0ggMQABQl9HX3ZhX2xpc3QgX19nbnVjX3ZhX2xpc3QA
+AURfR19IQVZFX1BSSU5URl9GUCAxAAFFX0dfSEFWRV9NTUFQIDEAAUZfR19IQVZF
+X01SRU1BUCAxAAFHX0dfSEFWRV9MT05HX0RPVUJMRV9JTyAxAAFIX0dfSEFWRV9J
+T19GSUxFX09QRU4gMQABSV9HX0hBVkVfSU9fR0VUTElORV9JTkZPIDEAAUtfR19J
+T19JT19GSUxFX1ZFUlNJT04gMHgyMDAwMQABTV9HX09QRU42NCBfX29wZW42NAAB
+Tl9HX0xTRUVLNjQgX19sc2VlazY0AAFPX0dfTU1BUDY0IF9fbW1hcDY0AAFQX0df
+RlNUQVQ2NChmZCxidWYpIF9fZnhzdGF0NjQgKF9TVEFUX1ZFUiwgZmQsIGJ1ZikA
+AVNfR19IQVZFX1NUX0JMS1NJWkUgZGVmaW5lZCAoX1NUQVRCVUZfU1RfQkxLU0la
+RSkAAVVfR19CVUZTSVogODE5MgABWF9HX05BTUVTX0hBVkVfVU5ERVJTQ09SRSAw
+AAFZX0dfVlRBQkxFX0xBQkVMX0hBU19MRU5HVEggMQABWl9HX1VTSU5HX1RIVU5L
+UyAxAAFbX0dfVlRBQkxFX0xBQkVMX1BSRUZJWCAiX192dF8iAAFcX0dfVlRBQkxF
+X0xBQkVMX1BSRUZJWF9JRCBfX3Z0XwABYF9HX0FSR1MoQVJHTElTVCkgQVJHTElT
+VAAEASJfSU9fcG9zX3QgX0dfZnBvc190AAEjX0lPX2Zwb3NfdCBfR19mcG9zX3QA
+ASRfSU9fZnBvczY0X3QgX0dfZnBvczY0X3QAASVfSU9fc2l6ZV90IF9HX3NpemVf
+dAABJl9JT19zc2l6ZV90IF9HX3NzaXplX3QAASdfSU9fb2ZmX3QgX0dfb2ZmX3QA
+AShfSU9fb2ZmNjRfdCBfR19vZmY2NF90AAEpX0lPX3BpZF90IF9HX3BpZF90AAEq
+X0lPX3VpZF90IF9HX3VpZF90AAErX0lPX2ljb252X3QgX0dfaWNvbnZfdAABLF9J
+T19IQVZFX1NZU19XQUlUIF9HX0hBVkVfU1lTX1dBSVQAAS1fSU9fSEFWRV9TVF9C
+TEtTSVpFIF9HX0hBVkVfU1RfQkxLU0laRQABLl9JT19CVUZTSVogX0dfQlVGU0la
+AAEvX0lPX3ZhX2xpc3QgX0dfdmFfbGlzdAABMF9JT193aW50X3QgX0dfd2ludF90
+AAE0X19uZWVkX19fdmFfbGlzdCAAAzUQAiJfX25lZWRfX192YV9saXN0AAEnX19H
+TlVDX1ZBX0xJU1QgAAQCN19JT192YV9saXN0AAE4X0lPX3ZhX2xpc3QgX19nbnVj
+X3ZhX2xpc3QAAUxfUEFSQU1TKHByb3RvcykgX19QKHByb3RvcykAAVRfSU9fVU5J
+RklFRF9KVU1QVEFCTEVTIDEAAVpFT0YgKC0xKQABaV9JT1NfSU5QVVQgMQABal9J
+T1NfT1VUUFVUIDIAAWtfSU9TX0FURU5EIDQAAWxfSU9TX0FQUEVORCA4AAFtX0lP
+U19UUlVOQyAxNgABbl9JT1NfTk9DUkVBVEUgMzIAAW9fSU9TX05PUkVQTEFDRSA2
+NAABcF9JT1NfQklOIDEyOAABeF9JT19NQUdJQyAweEZCQUQwMDAwAAF5X09MRF9T
+VERJT19NQUdJQyAweEZBQkMwMDAwAAF6X0lPX01BR0lDX01BU0sgMHhGRkZGMDAw
+MAABe19JT19VU0VSX0JVRiAxAAF8X0lPX1VOQlVGRkVSRUQgMgABfV9JT19OT19S
+RUFEUyA0AAF+X0lPX05PX1dSSVRFUyA4AAF/X0lPX0VPRl9TRUVOIDB4MTAAAYAB
+X0lPX0VSUl9TRUVOIDB4MjAAAYEBX0lPX0RFTEVURV9ET05UX0NMT1NFIDB4NDAA
+AYIBX0lPX0xJTktFRCAweDgwAAGDAV9JT19JTl9CQUNLVVAgMHgxMDAAAYQBX0lP
+X0xJTkVfQlVGIDB4MjAwAAGFAV9JT19USUVEX1BVVF9HRVQgMHg0MDAAAYYBX0lP
+X0NVUlJFTlRMWV9QVVRUSU5HIDB4ODAwAAGHAV9JT19JU19BUFBFTkRJTkcgMHgx
+MDAwAAGIAV9JT19JU19GSUxFQlVGIDB4MjAwMAABiQFfSU9fQkFEX1NFRU4gMHg0
+MDAwAAGKAV9JT19VU0VSX0xPQ0sgMHg4MDAwAAGMAV9JT19GTEFHUzJfTU1BUCAx
+AAGNAV9JT19GTEFHUzJfTk9UQ0FOQ0VMIDIAAZEBX0lPX0ZMQUdTMl9VU0VSX1dC
+VUYgOAABlwFfSU9fU0tJUFdTIDAxAAGYAV9JT19MRUZUIDAyAAGZAV9JT19SSUdI
+VCAwNAABmgFfSU9fSU5URVJOQUwgMDEwAAGbAV9JT19ERUMgMDIwAAGcAV9JT19P
+Q1QgMDQwAAGdAV9JT19IRVggMDEwMAABngFfSU9fU0hPV0JBU0UgMDIwMAABnwFf
+SU9fU0hPV1BPSU5UIDA0MDAAAaABX0lPX1VQUEVSQ0FTRSAwMTAwMAABoQFfSU9f
+U0hPV1BPUyAwMjAwMAABogFfSU9fU0NJRU5USUZJQyAwNDAwMAABowFfSU9fRklY
+RUQgMDEwMDAwAAGkAV9JT19VTklUQlVGIDAyMDAwMAABpQFfSU9fU1RESU8gMDQw
+MDAwAAGmAV9JT19ET05UX0NMT1NFIDAxMDAwMDAAAacBX0lPX0JPT0xBTFBIQSAw
+MjAwMDAwAAGRAl9JT19maWxlX2ZsYWdzIF9mbGFncwABrgJfX0hBVkVfQ09MVU1O
+IAAB3gJfSU9fc3RkaW4gKChfSU9fRklMRSopKCZfSU9fMl8xX3N0ZGluXykpAAHf
+Al9JT19zdGRvdXQgKChfSU9fRklMRSopKCZfSU9fMl8xX3N0ZG91dF8pKQAB4AJf
+SU9fc3RkZXJyICgoX0lPX0ZJTEUqKSgmX0lPXzJfMV9zdGRlcnJfKSkAAaoDX0lP
+X0JFKGV4cHIscmVzKSBfX2J1aWx0aW5fZXhwZWN0ICgoZXhwciksIHJlcykAAa8D
+X0lPX2dldGNfdW5sb2NrZWQoX2ZwKSAoX0lPX0JFICgoX2ZwKS0+X0lPX3JlYWRf
+cHRyID49IChfZnApLT5fSU9fcmVhZF9lbmQsIDApID8gX191ZmxvdyAoX2ZwKSA6
+ICoodW5zaWduZWQgY2hhciAqKSAoX2ZwKS0+X0lPX3JlYWRfcHRyKyspAAGyA19J
+T19wZWVrY191bmxvY2tlZChfZnApIChfSU9fQkUgKChfZnApLT5fSU9fcmVhZF9w
+dHIgPj0gKF9mcCktPl9JT19yZWFkX2VuZCwgMCkgJiYgX191bmRlcmZsb3cgKF9m
+cCkgPT0gRU9GID8gRU9GIDogKih1bnNpZ25lZCBjaGFyICopIChfZnApLT5fSU9f
+cmVhZF9wdHIpAAG2A19JT19wdXRjX3VubG9ja2VkKF9jaCxfZnApIChfSU9fQkUg
+KChfZnApLT5fSU9fd3JpdGVfcHRyID49IChfZnApLT5fSU9fd3JpdGVfZW5kLCAw
+KSA/IF9fb3ZlcmZsb3cgKF9mcCwgKHVuc2lnbmVkIGNoYXIpIChfY2gpKSA6ICh1
+bnNpZ25lZCBjaGFyKSAoKihfZnApLT5fSU9fd3JpdGVfcHRyKysgPSAoX2NoKSkp
+AAHJA19JT19mZW9mX3VubG9ja2VkKF9fZnApICgoKF9fZnApLT5fZmxhZ3MgJiBf
+SU9fRU9GX1NFRU4pICE9IDApAAHKA19JT19mZXJyb3JfdW5sb2NrZWQoX19mcCkg
+KCgoX19mcCktPl9mbGFncyAmIF9JT19FUlJfU0VFTikgIT0gMCkAAdQDX0lPX1BF
+TkRJTkdfT1VUUFVUX0NPVU5UKF9mcCkgKChfZnApLT5fSU9fd3JpdGVfcHRyIC0g
+KF9mcCktPl9JT193cml0ZV9iYXNlKQAB4gNfSU9fcGVla2MoX2ZwKSBfSU9fcGVl
+a2NfdW5sb2NrZWQgKF9mcCkAAeMDX0lPX2Zsb2NrZmlsZShfZnApIAAB5ANfSU9f
+ZnVubG9ja2ZpbGUoX2ZwKSAAAeUDX0lPX2Z0cnlsb2NrZmlsZShfZnApIAAB5gNf
+SU9fY2xlYW51cF9yZWdpb25fc3RhcnQoX2ZjdCxfZnApIAAB5wNfSU9fY2xlYW51
+cF9yZWdpb25fZW5kKF9Eb2l0KSAABAFRX1ZBX0xJU1RfREVGSU5FRCAAAV9fX29m
+Zl90X2RlZmluZWQgAAFjX19vZmY2NF90X2RlZmluZWQgAAFoX19zc2l6ZV90X2Rl
+ZmluZWQgAAF5X0lPRkJGIDAAAXpfSU9MQkYgMQABe19JT05CRiAyAAGAAUJVRlNJ
+WiBfSU9fQlVGU0laAAGNAVNFRUtfU0VUIDAAAY4BU0VFS19DVVIgMQABjwFTRUVL
+X0VORCAyAAGUAVBfdG1wZGlyICIvdG1wIgADoQERARhMX3RtcG5hbSAyMAABGVRN
+UF9NQVggMjM4MzI4AAEaRklMRU5BTUVfTUFYIDQwOTYAAR1MX2N0ZXJtaWQgOQAB
+H0xfY3VzZXJpZCA5AAIlRk9QRU5fTUFYAAEmRk9QRU5fTUFYIDE2AAQBqQFzdGRp
+biBzdGRpbgABqgFzdGRvdXQgc3Rkb3V0AAGrAXN0ZGVyciBzdGRlcnIAAaEEZ2V0
+YyhfZnApIF9JT19nZXRjIChfZnApAAHLBHB1dGMoX2NoLF9mcCkgX0lPX3B1dGMg
+KF9jaCwgX2ZwKQADzgYSBAQDAhMBHF9fbmVlZF9zaXplX3QgAAEeX19uZWVkX3dj
+aGFyX3QgAAEfX19uZWVkX05VTEwgAAMhCwLqAV9fbmVlZF9zaXplX3QAAYcCX193
+Y2hhcl90X18gAAGIAl9fV0NIQVJfVF9fIAABiQJfV0NIQVJfVCAAAYoCX1RfV0NI
+QVJfIAABiwJfVF9XQ0hBUiAAAYwCX19XQ0hBUl9UIAABjQJfV0NIQVJfVF8gAAGO
+Al9CU0RfV0NIQVJfVF8gAAGPAl9XQ0hBUl9UX0RFRklORURfIAABkAJfV0NIQVJf
+VF9ERUZJTkVEIAABkQJfV0NIQVJfVF9IIAABkgJfX19pbnRfd2NoYXJfdF9oIAAB
+kwJfX0lOVF9XQ0hBUl9UX0ggAAGUAl9HQ0NfV0NIQVJfVCAAAZUCX1dDSEFSX1Rf
+REVDTEFSRUQgAAKiAl9CU0RfV0NIQVJfVF8AAtcCX19uZWVkX3djaGFyX3QAAo0D
+TlVMTAABjwNOVUxMIF9fbnVsbAACmANfX25lZWRfTlVMTAAEASZfU1RETElCX0gg
+MQADKhQBGldOT0hBTkcgMQABG1dVTlRSQUNFRCAyAAEeV1NUT1BQRUQgMgABH1dF
+WElURUQgNAABIFdDT05USU5VRUQgOAABIVdOT1dBSVQgMHgwMTAwMDAwMAABI19f
+V05PVEhSRUFEIDB4MjAwMDAwMDAAASVfX1dBTEwgMHg0MDAwMDAwMAABJl9fV0NM
+T05FIDB4ODAwMDAwMDAABAMrFQEdX19XRVhJVFNUQVRVUyhzdGF0dXMpICgoKHN0
+YXR1cykgJiAweGZmMDApID4+IDgpAAEgX19XVEVSTVNJRyhzdGF0dXMpICgoc3Rh
+dHVzKSAmIDB4N2YpAAEjX19XU1RPUFNJRyhzdGF0dXMpIF9fV0VYSVRTVEFUVVMo
+c3RhdHVzKQABJl9fV0lGRVhJVEVEKHN0YXR1cykgKF9fV1RFUk1TSUcoc3RhdHVz
+KSA9PSAwKQABKV9fV0lGU0lHTkFMRUQoc3RhdHVzKSAoKChzaWduZWQgY2hhcikg
+KCgoc3RhdHVzKSAmIDB4N2YpICsgMSkgPj4gMSkgPiAwKQABLV9fV0lGU1RPUFBF
+RChzdGF0dXMpICgoKHN0YXR1cykgJiAweGZmKSA9PSAweDdmKQABMl9fV0lGQ09O
+VElOVUVEKHN0YXR1cykgKChzdGF0dXMpID09IF9fV19DT05USU5VRUQpAAE2X19X
+Q09SRURVTVAoc3RhdHVzKSAoKHN0YXR1cykgJiBfX1dDT1JFRkxBRykAATlfX1df
+RVhJVENPREUocmV0LHNpZykgKChyZXQpIDw8IDggfCAoc2lnKSkAATpfX1dfU1RP
+UENPREUoc2lnKSAoKHNpZykgPDwgOCB8IDB4N2YpAAE7X19XX0NPTlRJTlVFRCAw
+eGZmZmYAATxfX1dDT1JFRkxBRyAweDgwAANBFgEUX0VORElBTl9IIDEAASBfX0xJ
+VFRMRV9FTkRJQU4gMTIzNAABIV9fQklHX0VORElBTiA0MzIxAAEiX19QRFBfRU5E
+SUFOIDM0MTIAAyUXAQdfX0JZVEVfT1JERVIgX19MSVRUTEVfRU5ESUFOAAQBKl9f
+RkxPQVRfV09SRF9PUkRFUiBfX0JZVEVfT1JERVIAAS5MSVRUTEVfRU5ESUFOIF9f
+TElUVExFX0VORElBTgABL0JJR19FTkRJQU4gX19CSUdfRU5ESUFOAAEwUERQX0VO
+RElBTiBfX1BEUF9FTkRJQU4AATFCWVRFX09SREVSIF9fQllURV9PUkRFUgABNV9f
+TE9OR19MT05HX1BBSVIoSEksTE8pIExPLCBISQADPRgBGl9CSVRTX0JZVEVTV0FQ
+X0ggMQABHV9fYnN3YXBfY29uc3RhbnRfMTYoeCkgKCh1bnNpZ25lZCBzaG9ydCBp
+bnQpICgoKCh4KSA+PiA4KSAmIDB4ZmYpIHwgKCgoeCkgJiAweGZmKSA8PCA4KSkp
+AAEiX19ic3dhcF8xNih4KSAoX19leHRlbnNpb25fXyAoeyByZWdpc3RlciB1bnNp
+Z25lZCBzaG9ydCBpbnQgX192LCBfX3ggPSAodW5zaWduZWQgc2hvcnQgaW50KSAo
+eCk7IGlmIChfX2J1aWx0aW5fY29uc3RhbnRfcCAoX194KSkgX192ID0gX19ic3dh
+cF9jb25zdGFudF8xNiAoX194KTsgZWxzZSBfX2FzbV9fICgicm9ydyAkOCwgJXcw
+IiA6ICI9ciIgKF9fdikgOiAiMCIgKF9feCkgOiAiY2MiKTsgX192OyB9KSkAAT1f
+X2Jzd2FwX2NvbnN0YW50XzMyKHgpICgoKCh4KSAmIDB4ZmYwMDAwMDApID4+IDI0
+KSB8ICgoKHgpICYgMHgwMGZmMDAwMCkgPj4gOCkgfCAoKCh4KSAmIDB4MDAwMGZm
+MDApIDw8IDgpIHwgKCgoeCkgJiAweDAwMDAwMGZmKSA8PCAyNCkpAAFJX19ic3dh
+cF8zMih4KSAoX19leHRlbnNpb25fXyAoeyByZWdpc3RlciB1bnNpZ25lZCBpbnQg
+X192LCBfX3ggPSAoeCk7IGlmIChfX2J1aWx0aW5fY29uc3RhbnRfcCAoX194KSkg
+X192ID0gX19ic3dhcF9jb25zdGFudF8zMiAoX194KTsgZWxzZSBfX2FzbV9fICgi
+cm9ydyAkOCwgJXcwOyIgInJvcmwgJDE2LCAlMDsiICJyb3J3ICQ4LCAldzAiIDog
+Ij1yIiAoX192KSA6ICIwIiAoX194KSA6ICJjYyIpOyBfX3Y7IH0pKQABcF9fYnN3
+YXBfY29uc3RhbnRfNjQoeCkgKCgoKHgpICYgMHhmZjAwMDAwMDAwMDAwMDAwdWxs
+KSA+PiA1NikgfCAoKCh4KSAmIDB4MDBmZjAwMDAwMDAwMDAwMHVsbCkgPj4gNDAp
+IHwgKCgoeCkgJiAweDAwMDBmZjAwMDAwMDAwMDB1bGwpID4+IDI0KSB8ICgoKHgp
+ICYgMHgwMDAwMDBmZjAwMDAwMDAwdWxsKSA+PiA4KSB8ICgoKHgpICYgMHgwMDAw
+MDAwMGZmMDAwMDAwdWxsKSA8PCA4KSB8ICgoKHgpICYgMHgwMDAwMDAwMDAwZmYw
+MDAwdWxsKSA8PCAyNCkgfCAoKCh4KSAmIDB4MDAwMDAwMDAwMDAwZmYwMHVsbCkg
+PDwgNDApIHwgKCgoeCkgJiAweDAwMDAwMDAwMDAwMDAwZmZ1bGwpIDw8IDU2KSkA
+AXpfX2Jzd2FwXzY0KHgpIChfX2V4dGVuc2lvbl9fICh7IHVuaW9uIHsgX19leHRl
+bnNpb25fXyB1bnNpZ25lZCBsb25nIGxvbmcgaW50IF9fbGw7IHVuc2lnbmVkIGxv
+bmcgaW50IF9fbFsyXTsgfSBfX3csIF9fcjsgaWYgKF9fYnVpbHRpbl9jb25zdGFu
+dF9wICh4KSkgX19yLl9fbGwgPSBfX2Jzd2FwX2NvbnN0YW50XzY0ICh4KTsgZWxz
+ZSB7IF9fdy5fX2xsID0gKHgpOyBfX3IuX19sWzBdID0gX19ic3dhcF8zMiAoX193
+Ll9fbFsxXSk7IF9fci5fX2xbMV0gPSBfX2Jzd2FwXzMyIChfX3cuX19sWzBdKTsg
+fSBfX3IuX19sbDsgfSkpAAQBQGh0b2JlMTYoeCkgX19ic3dhcF8xNiAoeCkAAUFo
+dG9sZTE2KHgpICh4KQABQmJlMTZ0b2goeCkgX19ic3dhcF8xNiAoeCkAAUNsZTE2
+dG9oKHgpICh4KQABRWh0b2JlMzIoeCkgX19ic3dhcF8zMiAoeCkAAUZodG9sZTMy
+KHgpICh4KQABR2JlMzJ0b2goeCkgX19ic3dhcF8zMiAoeCkAAUhsZTMydG9oKHgp
+ICh4KQABSmh0b2JlNjQoeCkgX19ic3dhcF82NCAoeCkAAUtodG9sZTY0KHgpICh4
+KQABTGJlNjR0b2goeCkgX19ic3dhcF82NCAoeCkAAU1sZTY0dG9oKHgpICh4KQAE
+AWR3X3Rlcm1zaWcgX193YWl0X3Rlcm1pbmF0ZWQuX193X3Rlcm1zaWcAAWV3X2Nv
+cmVkdW1wIF9fd2FpdF90ZXJtaW5hdGVkLl9fd19jb3JlZHVtcAABZndfcmV0Y29k
+ZSBfX3dhaXRfdGVybWluYXRlZC5fX3dfcmV0Y29kZQABZ3dfc3RvcHNpZyBfX3dh
+aXRfc3RvcHBlZC5fX3dfc3RvcHNpZwABaHdfc3RvcHZhbCBfX3dhaXRfc3RvcHBl
+ZC5fX3dfc3RvcHZhbAAEATdfX1dBSVRfSU5UKHN0YXR1cykgKCooaW50ICopICYo
+c3RhdHVzKSkAAUBfX1dBSVRfU1RBVFVTIHZvaWQgKgABQV9fV0FJVF9TVEFUVVNf
+REVGTiB2b2lkICoAAVVXRVhJVFNUQVRVUyhzdGF0dXMpIF9fV0VYSVRTVEFUVVMg
+KF9fV0FJVF9JTlQgKHN0YXR1cykpAAFWV1RFUk1TSUcoc3RhdHVzKSBfX1dURVJN
+U0lHIChfX1dBSVRfSU5UIChzdGF0dXMpKQABV1dTVE9QU0lHKHN0YXR1cykgX19X
+U1RPUFNJRyAoX19XQUlUX0lOVCAoc3RhdHVzKSkAAVhXSUZFWElURUQoc3RhdHVz
+KSBfX1dJRkVYSVRFRCAoX19XQUlUX0lOVCAoc3RhdHVzKSkAAVlXSUZTSUdOQUxF
+RChzdGF0dXMpIF9fV0lGU0lHTkFMRUQgKF9fV0FJVF9JTlQgKHN0YXR1cykpAAFa
+V0lGU1RPUFBFRChzdGF0dXMpIF9fV0lGU1RPUFBFRCAoX19XQUlUX0lOVCAoc3Rh
+dHVzKSkAAVxXSUZDT05USU5VRUQoc3RhdHVzKSBfX1dJRkNPTlRJTlVFRCAoX19X
+QUlUX0lOVCAoc3RhdHVzKSkAAW9fX2xkaXZfdF9kZWZpbmVkIDEAAXtfX2xsZGl2
+X3RfZGVmaW5lZCAxAAGBAVJBTkRfTUFYIDIxNDc0ODM2NDcAAYYBRVhJVF9GQUlM
+VVJFIDEAAYcBRVhJVF9TVUNDRVNTIDAAAYsBTUJfQ1VSX01BWCAoX19jdHlwZV9n
+ZXRfbWJfY3VyX21heCAoKSkAA+wBGQEWX1hMT0NBTEVfSCAxAAQDwAIaARhfU1lT
+X1RZUEVTX0ggMQABKV9fdV9jaGFyX2RlZmluZWQgAAE1X19pbm9fdF9kZWZpbmVk
+IAABOV9faW5vNjRfdF9kZWZpbmVkIAABPl9fZGV2X3RfZGVmaW5lZCAAAUNfX2dp
+ZF90X2RlZmluZWQgAAFIX19tb2RlX3RfZGVmaW5lZCAAAU1fX25saW5rX3RfZGVm
+aW5lZCAAAVJfX3VpZF90X2RlZmluZWQgAAFkX19waWRfdF9kZWZpbmVkIAABal9f
+aWRfdF9kZWZpbmVkIAABdl9fZGFkZHJfdF9kZWZpbmVkIAABfF9fa2V5X3RfZGVm
+aW5lZCAAAYABX19uZWVkX2Nsb2NrX3QgAAGCAV9fbmVlZF90aW1lX3QgAAGDAV9f
+bmVlZF90aW1lcl90IAABhAFfX25lZWRfY2xvY2tpZF90IAADhQEbATZfX2Nsb2Nr
+X3RfZGVmaW5lZCAxAAJDX19uZWVkX2Nsb2NrX3QAAUZfX3RpbWVfdF9kZWZpbmVk
+IDEAAlNfX25lZWRfdGltZV90AAFXX19jbG9ja2lkX3RfZGVmaW5lZCAxAAJfX19j
+bG9ja2lkX3RpbWVfdAABY19fdGltZXJfdF9kZWZpbmVkIDEAAmtfX25lZWRfdGlt
+ZXJfdAACf19fbmVlZF90aW1lc3BlYwAEAYoBX191c2Vjb25kc190X2RlZmluZWQg
+AAGOAV9fc3VzZWNvbmRzX3RfZGVmaW5lZCAAAZIBX19uZWVkX3NpemVfdCAAA5MB
+CwLqAV9fbmVlZF9zaXplX3QAApgDX19uZWVkX05VTEwABAG8AV9faW50Tl90KE4s
+TU9ERSkgdHlwZWRlZiBpbnQgaW50ICMjTiAjI190IF9fYXR0cmlidXRlX18gKChf
+X21vZGVfXyAoTU9ERSkpKQABvgFfX3VfaW50Tl90KE4sTU9ERSkgdHlwZWRlZiB1
+bnNpZ25lZCBpbnQgdV9pbnQgIyNOICMjX3QgX19hdHRyaWJ1dGVfXyAoKF9fbW9k
+ZV9fIChNT0RFKSkpAAHCAV9faW50OF90X2RlZmluZWQgAAHUAV9fQklUX1RZUEVT
+X0RFRklORURfXyAxAAPcARwBF19TWVNfU0VMRUNUX0ggMQADHx0BGV9fRkRfWkVS
+TyhmZHNwKSBkbyB7IGludCBfX2QwLCBfX2QxOyBfX2FzbV9fIF9fdm9sYXRpbGVf
+XyAoImNsZDsgcmVwOyBzdG9zbCIgOiAiPWMiIChfX2QwKSwgIj1EIiAoX19kMSkg
+OiAiYSIgKDApLCAiMCIgKHNpemVvZiAoZmRfc2V0KSAvIHNpemVvZiAoX19mZF9t
+YXNrKSksICIxIiAoJl9fRkRTX0JJVFMgKGZkc3ApWzBdKSA6ICJtZW1vcnkiKTsg
+fSB3aGlsZSAoMCkAATJfX0ZEX1NFVChkLHNldCkgKCh2b2lkKSAoX19GRFNfQklU
+UyAoc2V0KVtfX0ZERUxUIChkKV0gfD0gX19GRE1BU0sgKGQpKSkAATRfX0ZEX0NM
+UihkLHNldCkgKCh2b2lkKSAoX19GRFNfQklUUyAoc2V0KVtfX0ZERUxUIChkKV0g
+Jj0gfl9fRkRNQVNLIChkKSkpAAE2X19GRF9JU1NFVChkLHNldCkgKChfX0ZEU19C
+SVRTIChzZXQpW19fRkRFTFQgKGQpXSAmIF9fRkRNQVNLIChkKSkgIT0gMCkABAMi
+HgEWX1NJR1NFVF9IX3R5cGVzIDEAARxfU0lHU0VUX05XT1JEUyAoMTAyNCAvICg4
+ICogc2l6ZW9mICh1bnNpZ25lZCBsb25nIGludCkpKQAEASVfX3NpZ3NldF90X2Rl
+ZmluZWQgAAEqX19uZWVkX3RpbWVfdCAAAStfX25lZWRfdGltZXNwZWMgAAMsGwJD
+X19uZWVkX2Nsb2NrX3QAAlNfX25lZWRfdGltZV90AAJfX19jbG9ja2lkX3RpbWVf
+dAACa19fbmVlZF90aW1lcl90AAFyX190aW1lc3BlY19kZWZpbmVkIDEAAn9fX25l
+ZWRfdGltZXNwZWMABAEtX19uZWVkX3RpbWV2YWwgAAMuHwJEX19uZWVkX3RpbWV2
+YWwAAUZfU1RSVUNUX1RJTUVWQUwgMQAEAjpfX05GREJJVFMAAjtfX0ZERUxUAAI8
+X19GRE1BU0sAAT5fX05GREJJVFMgKDggKiAoaW50KSBzaXplb2YgKF9fZmRfbWFz
+aykpAAE/X19GREVMVChkKSAoKGQpIC8gX19ORkRCSVRTKQABQF9fRkRNQVNLKGQp
+ICgoX19mZF9tYXNrKSAxIDw8ICgoZCkgJSBfX05GREJJVFMpKQABSV9fRkRTX0JJ
+VFMoc2V0KSAoKHNldCktPmZkc19iaXRzKQABUUZEX1NFVFNJWkUgX19GRF9TRVRT
+SVpFAAFYTkZEQklUUyBfX05GREJJVFMAAV1GRF9TRVQoZmQsZmRzZXRwKSBfX0ZE
+X1NFVCAoZmQsIGZkc2V0cCkAAV5GRF9DTFIoZmQsZmRzZXRwKSBfX0ZEX0NMUiAo
+ZmQsIGZkc2V0cCkAAV9GRF9JU1NFVChmZCxmZHNldHApIF9fRkRfSVNTRVQgKGZk
+LCBmZHNldHApAAFgRkRfWkVSTyhmZHNldHApIF9fRkRfWkVSTyAoZmRzZXRwKQAE
+A98BIAEWX1NZU19TWVNNQUNST1NfSCAxAAFBbWFqb3IoZGV2KSBnbnVfZGV2X21h
+am9yIChkZXYpAAFCbWlub3IoZGV2KSBnbnVfZGV2X21pbm9yIChkZXYpAAFDbWFr
+ZWRldihtYWosbWluKSBnbnVfZGV2X21ha2VkZXYgKG1haiwgbWluKQAEAeYBX19i
+bGtzaXplX3RfZGVmaW5lZCAAAe0BX19ibGtjbnRfdF9kZWZpbmVkIAAB8QFfX2Zz
+YmxrY250X3RfZGVmaW5lZCAAAfUBX19mc2ZpbGNudF90X2RlZmluZWQgAAOPAiEB
+FF9CSVRTX1BUSFJFQURUWVBFU19IIDEAARZfX1NJWkVPRl9QVEhSRUFEX0FUVFJf
+VCAzNgABF19fU0laRU9GX1BUSFJFQURfTVVURVhfVCAyNAABGF9fU0laRU9GX1BU
+SFJFQURfTVVURVhBVFRSX1QgNAABGV9fU0laRU9GX1BUSFJFQURfQ09ORF9UIDQ4
+AAEaX19TSVpFT0ZfUFRIUkVBRF9DT05EX0NPTVBBVF9UIDEyAAEbX19TSVpFT0Zf
+UFRIUkVBRF9DT05EQVRUUl9UIDQAARxfX1NJWkVPRl9QVEhSRUFEX1JXTE9DS19U
+IDMyAAEdX19TSVpFT0ZfUFRIUkVBRF9SV0xPQ0tBVFRSX1QgOAABHl9fU0laRU9G
+X1BUSFJFQURfQkFSUklFUl9UIDIwAAEfX19TSVpFT0ZfUFRIUkVBRF9CQVJSSUVS
+QVRUUl9UIDQAAasBX19jbGVhbnVwX2ZjdF9hdHRyaWJ1dGUgX19hdHRyaWJ1dGVf
+XyAoKF9fcmVncGFybV9fICgxKSkpAAQEAdQDX19tYWxsb2NfYW5kX2NhbGxvY19k
+ZWZpbmVkIAAD8QMiARRfQUxMT0NBX0ggMQABGF9fbmVlZF9zaXplX3QgAAMZCwLq
+AV9fbmVlZF9zaXplX3QAApgDX19uZWVkX05VTEwABAIeYWxsb2NhAAEkYWxsb2Nh
+KHNpemUpIF9fYnVpbHRpbl9hbGxvY2EgKHNpemUpAAQB5QVfX0NPTVBBUl9GTl9U
+IAACwgdfX25lZWRfbWFsbG9jX2FuZF9jYWxsb2MABAMDIwEcX0VSUk5PX0ggMQAD
+JCQCFkVET00AAhdFSUxTRVEAAhhFUkFOR0UAAxklAQJfTElOVVhfRVJSTk9fSCAA
+AwQmAwEnAQJfQVNNX0dFTkVSSUNfRVJSTk9fSCAAAwQoAQJfQVNNX0dFTkVSSUNf
+RVJSTk9fQkFTRV9IIAABBEVQRVJNIDEAAQVFTk9FTlQgMgABBkVTUkNIIDMAAQdF
+SU5UUiA0AAEIRUlPIDUAAQlFTlhJTyA2AAEKRTJCSUcgNwABC0VOT0VYRUMgOAAB
+DEVCQURGIDkAAQ1FQ0hJTEQgMTAAAQ5FQUdBSU4gMTEAAQ9FTk9NRU0gMTIAARBF
+QUNDRVMgMTMAARFFRkFVTFQgMTQAARJFTk9UQkxLIDE1AAETRUJVU1kgMTYAARRF
+RVhJU1QgMTcAARVFWERFViAxOAABFkVOT0RFViAxOQABF0VOT1RESVIgMjAAARhF
+SVNESVIgMjEAARlFSU5WQUwgMjIAARpFTkZJTEUgMjMAARtFTUZJTEUgMjQAARxF
+Tk9UVFkgMjUAAR1FVFhUQlNZIDI2AAEeRUZCSUcgMjcAAR9FTk9TUEMgMjgAASBF
+U1BJUEUgMjkAASFFUk9GUyAzMAABIkVNTElOSyAzMQABI0VQSVBFIDMyAAEkRURP
+TSAzMwABJUVSQU5HRSAzNAAEAQZFREVBRExLIDM1AAEHRU5BTUVUT09MT05HIDM2
+AAEIRU5PTENLIDM3AAEJRU5PU1lTIDM4AAEKRU5PVEVNUFRZIDM5AAELRUxPT1Ag
+NDAAAQxFV09VTERCTE9DSyBFQUdBSU4AAQ1FTk9NU0cgNDIAAQ5FSURSTSA0MwAB
+D0VDSFJORyA0NAABEEVMMk5TWU5DIDQ1AAERRUwzSExUIDQ2AAESRUwzUlNUIDQ3
+AAETRUxOUk5HIDQ4AAEURVVOQVRDSCA0OQABFUVOT0NTSSA1MAABFkVMMkhMVCA1
+MQABF0VCQURFIDUyAAEYRUJBRFIgNTMAARlFWEZVTEwgNTQAARpFTk9BTk8gNTUA
+ARtFQkFEUlFDIDU2AAEcRUJBRFNMVCA1NwABHkVERUFETE9DSyBFREVBRExLAAEg
+RUJGT05UIDU5AAEhRU5PU1RSIDYwAAEiRU5PREFUQSA2MQABI0VUSU1FIDYyAAEk
+RU5PU1IgNjMAASVFTk9ORVQgNjQAASZFTk9QS0cgNjUAASdFUkVNT1RFIDY2AAEo
+RU5PTElOSyA2NwABKUVBRFYgNjgAASpFU1JNTlQgNjkAAStFQ09NTSA3MAABLEVQ
+Uk9UTyA3MQABLUVNVUxUSUhPUCA3MgABLkVET1RET1QgNzMAAS9FQkFETVNHIDc0
+AAEwRU9WRVJGTE9XIDc1AAExRU5PVFVOSVEgNzYAATJFQkFERkQgNzcAATNFUkVN
+Q0hHIDc4AAE0RUxJQkFDQyA3OQABNUVMSUJCQUQgODAAATZFTElCU0NOIDgxAAE3
+RUxJQk1BWCA4MgABOEVMSUJFWEVDIDgzAAE5RUlMU0VRIDg0AAE6RVJFU1RBUlQg
+ODUAATtFU1RSUElQRSA4NgABPEVVU0VSUyA4NwABPUVOT1RTT0NLIDg4AAE+RURF
+U1RBRERSUkVRIDg5AAE/RU1TR1NJWkUgOTAAAUBFUFJPVE9UWVBFIDkxAAFBRU5P
+UFJPVE9PUFQgOTIAAUJFUFJPVE9OT1NVUFBPUlQgOTMAAUNFU09DS1ROT1NVUFBP
+UlQgOTQAAURFT1BOT1RTVVBQIDk1AAFFRVBGTk9TVVBQT1JUIDk2AAFGRUFGTk9T
+VVBQT1JUIDk3AAFHRUFERFJJTlVTRSA5OAABSEVBRERSTk9UQVZBSUwgOTkAAUlF
+TkVURE9XTiAxMDAAAUpFTkVUVU5SRUFDSCAxMDEAAUtFTkVUUkVTRVQgMTAyAAFM
+RUNPTk5BQk9SVEVEIDEwMwABTUVDT05OUkVTRVQgMTA0AAFORU5PQlVGUyAxMDUA
+AU9FSVNDT05OIDEwNgABUEVOT1RDT05OIDEwNwABUUVTSFVURE9XTiAxMDgAAVJF
+VE9PTUFOWVJFRlMgMTA5AAFTRVRJTUVET1VUIDExMAABVEVDT05OUkVGVVNFRCAx
+MTEAAVVFSE9TVERPV04gMTEyAAFWRUhPU1RVTlJFQUNIIDExMwABV0VBTFJFQURZ
+IDExNAABWEVJTlBST0dSRVNTIDExNQABWUVTVEFMRSAxMTYAAVpFVUNMRUFOIDEx
+NwABW0VOT1ROQU0gMTE4AAFcRU5BVkFJTCAxMTkAAV1FSVNOQU0gMTIwAAFeRVJF
+TU9URUlPIDEyMQABX0VEUVVPVCAxMjIAAWFFTk9NRURJVU0gMTIzAAFiRU1FRElV
+TVRZUEUgMTI0AAFjRUNBTkNFTEVEIDEyNQABZEVOT0tFWSAxMjYAAWVFS0VZRVhQ
+SVJFRCAxMjcAAWZFS0VZUkVWT0tFRCAxMjgAAWdFS0VZUkVKRUNURUQgMTI5AAFq
+RU9XTkVSREVBRCAxMzAAAWtFTk9UUkVDT1ZFUkFCTEUgMTMxAAFtRVJGS0lMTCAx
+MzIAAW9FSFdQT0lTT04gMTMzAAQEBAEcRU5PVFNVUCBFT1BOT1RTVVBQAAEzZXJy
+bm8gKCpfX2Vycm5vX2xvY2F0aW9uICgpKQAEAiVfX25lZWRfRW1hdGgAAUZfX2Vy
+cm9yX3RfZGVmaW5lZCAxAAJIX19uZWVkX2Vycm9yX3QABAMEKQEZX0ZDTlRMX0gg
+MQADIgMDGyoBGF9CSVRTX1VJT19IIDEAAShVSU9fTUFYSU9WIDEwMjQABAEhT19B
+Q0NNT0RFIDAwMDMAASJPX1JET05MWSAwMAABI09fV1JPTkxZIDAxAAEkT19SRFdS
+IDAyAAElT19DUkVBVCAwMTAwAAEmT19FWENMIDAyMDAAASdPX05PQ1RUWSAwNDAw
+AAEoT19UUlVOQyAwMTAwMAABKU9fQVBQRU5EIDAyMDAwAAEqT19OT05CTE9DSyAw
+NDAwMAABK09fTkRFTEFZIE9fTk9OQkxPQ0sAASxPX1NZTkMgMDQwMTAwMDAAAS1P
+X0ZTWU5DIE9fU1lOQwABLk9fQVNZTkMgMDIwMDAwAAExT19ESVJFQ1RPUlkgMDIw
+MDAwMAABMk9fTk9GT0xMT1cgMDQwMDAwMAABM09fQ0xPRVhFQyAwMjAwMDAwMAAB
+Nk9fRElSRUNUIDA0MDAwMAABN09fTk9BVElNRSAwMTAwMDAwMAABPk9fRFNZTkMg
+MDEwMDAwAAE/T19SU1lOQyBPX1NZTkMAAUNPX0xBUkdFRklMRSAwMTAwMDAwAAFH
+Rl9EVVBGRCAwAAFIRl9HRVRGRCAxAAFJRl9TRVRGRCAyAAFKRl9HRVRGTCAzAAFL
+Rl9TRVRGTCA0AAFNRl9HRVRMSyA1AAFORl9TRVRMSyA2AAFPRl9TRVRMS1cgNwAB
+VUZfR0VUTEs2NCAxMgABVkZfU0VUTEs2NCAxMwABV0ZfU0VUTEtXNjQgMTQAAVpG
+X1NFVE9XTiA4AAFbRl9HRVRPV04gOQABX0ZfU0VUU0lHIDEwAAFgRl9HRVRTSUcg
+MTEAAWFGX1NFVE9XTl9FWCAxNQABYkZfR0VUT1dOX0VYIDE2AAFmRl9TRVRMRUFT
+RSAxMDI0AAFnRl9HRVRMRUFTRSAxMDI1AAFoRl9OT1RJRlkgMTAyNgABaUZfU0VU
+UElQRV9TWiAxMDMxAAFqRl9HRVRQSVBFX1NaIDEwMzIAAW1GX0RVUEZEX0NMT0VY
+RUMgMTAzMAABckZEX0NMT0VYRUMgMQABdUZfUkRMQ0sgMAABdkZfV1JMQ0sgMQAB
+d0ZfVU5MQ0sgMgABekZfRVhMQ0sgNAABe0ZfU0hMQ0sgOAABf0xPQ0tfU0ggMQAB
+gAFMT0NLX0VYIDIAAYEBTE9DS19OQiA0AAGDAUxPQ0tfVU4gOAABhwFMT0NLX01B
+TkQgMzIAAYgBTE9DS19SRUFEIDY0AAGJAUxPQ0tfV1JJVEUgMTI4AAGKAUxPQ0tf
+UlcgMTkyAAGPAUROX0FDQ0VTUyAweDAwMDAwMDAxAAGQAUROX01PRElGWSAweDAw
+MDAwMDAyAAGRAUROX0NSRUFURSAweDAwMDAwMDA0AAGSAUROX0RFTEVURSAweDAw
+MDAwMDA4AAGTAUROX1JFTkFNRSAweDAwMDAwMDEwAAGUAUROX0FUVFJJQiAweDAw
+MDAwMDIwAAGVAUROX01VTFRJU0hPVCAweDgwMDAwMDAwAAHGAUZBUFBFTkQgT19B
+UFBFTkQAAccBRkZTWU5DIE9fRlNZTkMAAcgBRkFTWU5DIE9fQVNZTkMAAckBRk5P
+TkJMT0NLIE9fTk9OQkxPQ0sAAcoBRk5ERUxBWSBPX05ERUxBWQABzwFQT1NJWF9G
+QURWX05PUk1BTCAwAAHQAVBPU0lYX0ZBRFZfUkFORE9NIDEAAdEBUE9TSVhfRkFE
+Vl9TRVFVRU5USUFMIDIAAdIBUE9TSVhfRkFEVl9XSUxMTkVFRCAzAAHTAVBPU0lY
+X0ZBRFZfRE9OVE5FRUQgNAAB1AFQT1NJWF9GQURWX05PUkVVU0UgNQAB2gFTWU5D
+X0ZJTEVfUkFOR0VfV0FJVF9CRUZPUkUgMQAB3QFTWU5DX0ZJTEVfUkFOR0VfV1JJ
+VEUgMgAB4AFTWU5DX0ZJTEVfUkFOR0VfV0FJVF9BRlRFUiA0AAHlAVNQTElDRV9G
+X01PVkUgMQAB5gFTUExJQ0VfRl9OT05CTE9DSyAyAAHpAVNQTElDRV9GX01PUkUg
+NAAB6gFTUExJQ0VfRl9HSUZUIDgAAe8BQVRfRkRDV0QgLTEwMAAB8gFBVF9TWU1M
+SU5LX05PRk9MTE9XIDB4MTAwAAHzAUFUX1JFTU9WRURJUiAweDIwMAAB9QFBVF9T
+WU1MSU5LX0ZPTExPVyAweDQwMAAB9gFBVF9OT19BVVRPTU9VTlQgMHg4MDAAAfgB
+QVRfRUFDQ0VTUyAweDIwMAAEASdfX25lZWRfdGltZXNwZWMgAAMoGwJDX19uZWVk
+X2Nsb2NrX3QAAlNfX25lZWRfdGltZV90AAJfX19jbG9ja2lkX3RpbWVfdAACa19f
+bmVlZF90aW1lcl90AAJ/X19uZWVkX3RpbWVzcGVjAAQDKSsBGF9CSVRTX1NUQVRf
+SCAxAAEbX1NUQVRfVkVSX0xJTlVYX09MRCAxAAEcX1NUQVRfVkVSX0tFUk5FTCAx
+AAEdX1NUQVRfVkVSX1NWUjQgMgABHl9TVEFUX1ZFUl9MSU5VWCAzAAEfX1NUQVRf
+VkVSIF9TVEFUX1ZFUl9MSU5VWAABIl9NS05PRF9WRVJfTElOVVggMQABI19NS05P
+RF9WRVJfU1ZSNCAyAAEkX01LTk9EX1ZFUiBfTUtOT0RfVkVSX0xJTlVYAAFMc3Rf
+YXRpbWUgc3RfYXRpbS50dl9zZWMAAU1zdF9tdGltZSBzdF9tdGltLnR2X3NlYwAB
+TnN0X2N0aW1lIHN0X2N0aW0udHZfc2VjAAGHAV9TVEFUQlVGX1NUX0JMS1NJWkUg
+AAGIAV9TVEFUQlVGX1NUX1JERVYgAAGKAV9TVEFUQlVGX1NUX05TRUMgAAGOAV9f
+U19JRk1UIDAxNzAwMDAAAZEBX19TX0lGRElSIDAwNDAwMDAAAZIBX19TX0lGQ0hS
+IDAwMjAwMDAAAZMBX19TX0lGQkxLIDAwNjAwMDAAAZQBX19TX0lGUkVHIDAxMDAw
+MDAAAZUBX19TX0lGSUZPIDAwMTAwMDAAAZYBX19TX0lGTE5LIDAxMjAwMDAAAZcB
+X19TX0lGU09DSyAwMTQwMDAwAAGbAV9fU19UWVBFSVNNUShidWYpICgoYnVmKS0+
+c3RfbW9kZSAtIChidWYpLT5zdF9tb2RlKQABnAFfX1NfVFlQRUlTU0VNKGJ1Zikg
+KChidWYpLT5zdF9tb2RlIC0gKGJ1ZiktPnN0X21vZGUpAAGdAV9fU19UWVBFSVNT
+SE0oYnVmKSAoKGJ1ZiktPnN0X21vZGUgLSAoYnVmKS0+c3RfbW9kZSkAAaEBX19T
+X0lTVUlEIDA0MDAwAAGiAV9fU19JU0dJRCAwMjAwMAABowFfX1NfSVNWVFggMDEw
+MDAAAaQBX19TX0lSRUFEIDA0MDAAAaUBX19TX0lXUklURSAwMjAwAAGmAV9fU19J
+RVhFQyAwMTAwAAGpAVVUSU1FX05PVyAoKDFsIDw8IDMwKSAtIDFsKQABqgFVVElN
+RV9PTUlUICgoMWwgPDwgMzApIC0gMmwpAAQBK1NfSUZNVCBfX1NfSUZNVAABLFNf
+SUZESVIgX19TX0lGRElSAAEtU19JRkNIUiBfX1NfSUZDSFIAAS5TX0lGQkxLIF9f
+U19JRkJMSwABL1NfSUZSRUcgX19TX0lGUkVHAAExU19JRklGTyBfX1NfSUZJRk8A
+ATRTX0lGTE5LIF9fU19JRkxOSwABN1NfSUZTT0NLIF9fU19JRlNPQ0sAATxTX0lT
+VUlEIF9fU19JU1VJRAABPVNfSVNHSUQgX19TX0lTR0lEAAFBU19JU1ZUWCBfX1Nf
+SVNWVFgAAURTX0lSVVNSIF9fU19JUkVBRAABRVNfSVdVU1IgX19TX0lXUklURQAB
+RlNfSVhVU1IgX19TX0lFWEVDAAFIU19JUldYVSAoX19TX0lSRUFEfF9fU19JV1JJ
+VEV8X19TX0lFWEVDKQABSlNfSVJHUlAgKFNfSVJVU1IgPj4gMykAAUtTX0lXR1JQ
+IChTX0lXVVNSID4+IDMpAAFMU19JWEdSUCAoU19JWFVTUiA+PiAzKQABTlNfSVJX
+WEcgKFNfSVJXWFUgPj4gMykAAVBTX0lST1RIIChTX0lSR1JQID4+IDMpAAFRU19J
+V09USCAoU19JV0dSUCA+PiAzKQABUlNfSVhPVEggKFNfSVhHUlAgPj4gMykAAVRT
+X0lSV1hPIChTX0lSV1hHID4+IDMpAAFbUl9PSyA0AAFcV19PSyAyAAFdWF9PSyAx
+AAFeRl9PSyAwAAFkU0VFS19TRVQgMAABZVNFRUtfQ1VSIDEAAWZTRUVLX0VORCAy
+AAG8AUZfVUxPQ0sgMAABvQFGX0xPQ0sgMQABvgFGX1RMT0NLIDIAAb8BRl9URVNU
+IDMABAMFLAEYX1VOSVNURF9IIDEAASNfUE9TSVhfVkVSU0lPTiAyMDA4MDlMAAE2
+X19QT1NJWDJfVEhJU19WRVJTSU9OIDIwMDgwOUwAAURfUE9TSVgyX1ZFUlNJT04g
+X19QT1NJWDJfVEhJU19WRVJTSU9OAAFIX1BPU0lYMl9DX0JJTkQgX19QT1NJWDJf
+VEhJU19WRVJTSU9OAAFMX1BPU0lYMl9DX0RFViBfX1BPU0lYMl9USElTX1ZFUlNJ
+T04AAVBfUE9TSVgyX1NXX0RFViBfX1BPU0lYMl9USElTX1ZFUlNJT04AAVRfUE9T
+SVgyX0xPQ0FMRURFRiBfX1BPU0lYMl9USElTX1ZFUlNJT04AAVhfWE9QRU5fVkVS
+U0lPTiA3MDAAAWJfWE9QRU5fWENVX1ZFUlNJT04gNAABZV9YT1BFTl9YUEcyIDEA
+AWZfWE9QRU5fWFBHMyAxAAFnX1hPUEVOX1hQRzQgMQABal9YT1BFTl9VTklYIDEA
+AW1fWE9QRU5fQ1JZUFQgMQABcV9YT1BFTl9FTkhfSTE4TiAxAAF0X1hPUEVOX0xF
+R0FDWSAxAAPLAS0BFV9CSVRTX1BPU0lYX09QVF9IIDEAARhfUE9TSVhfSk9CX0NP
+TlRST0wgMQABG19QT1NJWF9TQVZFRF9JRFMgMQABHl9QT1NJWF9QUklPUklUWV9T
+Q0hFRFVMSU5HIDIwMDgwOUwAASFfUE9TSVhfU1lOQ0hST05JWkVEX0lPIDIwMDgw
+OUwAASRfUE9TSVhfRlNZTkMgMjAwODA5TAABJ19QT1NJWF9NQVBQRURfRklMRVMg
+MjAwODA5TAABKl9QT1NJWF9NRU1MT0NLIDIwMDgwOUwAAS1fUE9TSVhfTUVNTE9D
+S19SQU5HRSAyMDA4MDlMAAEwX1BPU0lYX01FTU9SWV9QUk9URUNUSU9OIDIwMDgw
+OUwAATNfUE9TSVhfQ0hPV05fUkVTVFJJQ1RFRCAwAAE3X1BPU0lYX1ZESVNBQkxF
+ICdcMCcAATpfUE9TSVhfTk9fVFJVTkMgMQABPV9YT1BFTl9SRUFMVElNRSAxAAFA
+X1hPUEVOX1JFQUxUSU1FX1RIUkVBRFMgMQABQ19YT1BFTl9TSE0gMQABRl9QT1NJ
+WF9USFJFQURTIDIwMDgwOUwAAUlfUE9TSVhfUkVFTlRSQU5UX0ZVTkNUSU9OUyAx
+AAFKX1BPU0lYX1RIUkVBRF9TQUZFX0ZVTkNUSU9OUyAyMDA4MDlMAAFNX1BPU0lY
+X1RIUkVBRF9QUklPUklUWV9TQ0hFRFVMSU5HIDIwMDgwOUwAAVBfUE9TSVhfVEhS
+RUFEX0FUVFJfU1RBQ0tTSVpFIDIwMDgwOUwAAVNfUE9TSVhfVEhSRUFEX0FUVFJf
+U1RBQ0tBRERSIDIwMDgwOUwAAVZfUE9TSVhfVEhSRUFEX1BSSU9fSU5IRVJJVCAy
+MDA4MDlMAAFaX1BPU0lYX1RIUkVBRF9QUklPX1BST1RFQ1QgMjAwODA5TAABXl9Q
+T1NJWF9USFJFQURfUk9CVVNUX1BSSU9fSU5IRVJJVCAyMDA4MDlMAAFhX1BPU0lY
+X1RIUkVBRF9ST0JVU1RfUFJJT19QUk9URUNUIC0xAAFlX1BPU0lYX1NFTUFQSE9S
+RVMgMjAwODA5TAABaF9QT1NJWF9SRUFMVElNRV9TSUdOQUxTIDIwMDgwOUwAAWtf
+UE9TSVhfQVNZTkNIUk9OT1VTX0lPIDIwMDgwOUwAAWxfUE9TSVhfQVNZTkNfSU8g
+MQABbl9MRlNfQVNZTkNIUk9OT1VTX0lPIDEAAXBfUE9TSVhfUFJJT1JJVElaRURf
+SU8gMjAwODA5TAABc19MRlM2NF9BU1lOQ0hST05PVVNfSU8gMQABdl9MRlNfTEFS
+R0VGSUxFIDEAAXdfTEZTNjRfTEFSR0VGSUxFIDEAAXhfTEZTNjRfU1RESU8gMQAB
+e19QT1NJWF9TSEFSRURfTUVNT1JZX09CSkVDVFMgMjAwODA5TAABfl9QT1NJWF9D
+UFVUSU1FIDAAAYEBX1BPU0lYX1RIUkVBRF9DUFVUSU1FIDAAAYQBX1BPU0lYX1JF
+R0VYUCAxAAGHAV9QT1NJWF9SRUFERVJfV1JJVEVSX0xPQ0tTIDIwMDgwOUwAAYoB
+X1BPU0lYX1NIRUxMIDEAAY0BX1BPU0lYX1RJTUVPVVRTIDIwMDgwOUwAAZABX1BP
+U0lYX1NQSU5fTE9DS1MgMjAwODA5TAABkwFfUE9TSVhfU1BBV04gMjAwODA5TAAB
+lgFfUE9TSVhfVElNRVJTIDIwMDgwOUwAAZkBX1BPU0lYX0JBUlJJRVJTIDIwMDgw
+OUwAAZwBX1BPU0lYX01FU1NBR0VfUEFTU0lORyAyMDA4MDlMAAGfAV9QT1NJWF9U
+SFJFQURfUFJPQ0VTU19TSEFSRUQgMjAwODA5TAABogFfUE9TSVhfTU9OT1RPTklD
+X0NMT0NLIDAAAaUBX1BPU0lYX0NMT0NLX1NFTEVDVElPTiAyMDA4MDlMAAGoAV9Q
+T1NJWF9BRFZJU09SWV9JTkZPIDIwMDgwOUwAAasBX1BPU0lYX0lQVjYgMjAwODA5
+TAABrgFfUE9TSVhfUkFXX1NPQ0tFVFMgMjAwODA5TAABsQFfUE9TSVgyX0NIQVJf
+VEVSTSAyMDA4MDlMAAG0AV9QT1NJWF9TUE9SQURJQ19TRVJWRVIgLTEAAbUBX1BP
+U0lYX1RIUkVBRF9TUE9SQURJQ19TRVJWRVIgLTEAAbgBX1BPU0lYX1RSQUNFIC0x
+AAG5AV9QT1NJWF9UUkFDRV9FVkVOVF9GSUxURVIgLTEAAboBX1BPU0lYX1RSQUNF
+X0lOSEVSSVQgLTEAAbsBX1BPU0lYX1RSQUNFX0xPRyAtMQABvgFfUE9TSVhfVFlQ
+RURfTUVNT1JZX09CSkVDVFMgLTEABAPPAS4BK19QT1NJWF9WN19JTFAzMl9PRkYz
+MiAxAAEsX1BPU0lYX1Y3X0lMUDMyX09GRkJJRyAxAAEtX1BPU0lYX1Y2X0lMUDMy
+X09GRjMyIDEAAS5fUE9TSVhfVjZfSUxQMzJfT0ZGQklHIDEAAS9fWEJTNV9JTFAz
+Ml9PRkYzMiAxAAEwX1hCUzVfSUxQMzJfT0ZGQklHIDEAAT9fX0lMUDMyX09GRjMy
+X0NGTEFHUyAiLW0zMiIAAUBfX0lMUDMyX09GRkJJR19DRkxBR1MgIi1tMzIgLURf
+TEFSR0VGSUxFX1NPVVJDRSAtRF9GSUxFX09GRlNFVF9CSVRTPTY0IgABQV9fSUxQ
+MzJfT0ZGMzJfTERGTEFHUyAiLW0zMiIAAUJfX0lMUDMyX09GRkJJR19MREZMQUdT
+ICItbTMyIgABQ19fTFA2NF9PRkY2NF9DRkxBR1MgIi1tNjQiAAFEX19MUDY0X09G
+RjY0X0xERkxBR1MgIi1tNjQiAAQB0wFTVERJTl9GSUxFTk8gMAAB1AFTVERPVVRf
+RklMRU5PIDEAAdUBU1RERVJSX0ZJTEVOTyAyAAHhAV9fbmVlZF9zaXplX3QgAAHi
+AV9fbmVlZF9OVUxMIAAD4wELAuoBX19uZWVkX3NpemVfdAACjQNOVUxMAAGPA05V
+TEwgX19udWxsAAKYA19fbmVlZF9OVUxMAAQBjQJfX2ludHB0cl90X2RlZmluZWQg
+AAGUAl9fc29ja2xlbl90X2RlZmluZWQgAAGaAlJfT0sgNAABmwJXX09LIDIAAZwC
+WF9PSyAxAAGdAkZfT0sgMAABvwJMX1NFVCBTRUVLX1NFVAABwAJMX0lOQ1IgU0VF
+S19DVVIAAcECTF9YVE5EIFNFRUtfRU5EAAPeBC8BHV9QQ19MSU5LX01BWCBfUENf
+TElOS19NQVgAAR9fUENfTUFYX0NBTk9OIF9QQ19NQVhfQ0FOT04AASFfUENfTUFY
+X0lOUFVUIF9QQ19NQVhfSU5QVVQAASNfUENfTkFNRV9NQVggX1BDX05BTUVfTUFY
+AAElX1BDX1BBVEhfTUFYIF9QQ19QQVRIX01BWAABJ19QQ19QSVBFX0JVRiBfUENf
+UElQRV9CVUYAASlfUENfQ0hPV05fUkVTVFJJQ1RFRCBfUENfQ0hPV05fUkVTVFJJ
+Q1RFRAABK19QQ19OT19UUlVOQyBfUENfTk9fVFJVTkMAAS1fUENfVkRJU0FCTEUg
+X1BDX1ZESVNBQkxFAAEvX1BDX1NZTkNfSU8gX1BDX1NZTkNfSU8AATFfUENfQVNZ
+TkNfSU8gX1BDX0FTWU5DX0lPAAEzX1BDX1BSSU9fSU8gX1BDX1BSSU9fSU8AATVf
+UENfU09DS19NQVhCVUYgX1BDX1NPQ0tfTUFYQlVGAAE3X1BDX0ZJTEVTSVpFQklU
+UyBfUENfRklMRVNJWkVCSVRTAAE5X1BDX1JFQ19JTkNSX1hGRVJfU0laRSBfUENf
+UkVDX0lOQ1JfWEZFUl9TSVpFAAE7X1BDX1JFQ19NQVhfWEZFUl9TSVpFIF9QQ19S
+RUNfTUFYX1hGRVJfU0laRQABPV9QQ19SRUNfTUlOX1hGRVJfU0laRSBfUENfUkVD
+X01JTl9YRkVSX1NJWkUAAT9fUENfUkVDX1hGRVJfQUxJR04gX1BDX1JFQ19YRkVS
+X0FMSUdOAAFBX1BDX0FMTE9DX1NJWkVfTUlOIF9QQ19BTExPQ19TSVpFX01JTgAB
+Q19QQ19TWU1MSU5LX01BWCBfUENfU1lNTElOS19NQVgAAUVfUENfMl9TWU1MSU5L
+UyBfUENfMl9TWU1MSU5LUwABTF9TQ19BUkdfTUFYIF9TQ19BUkdfTUFYAAFOX1ND
+X0NISUxEX01BWCBfU0NfQ0hJTERfTUFYAAFQX1NDX0NMS19UQ0sgX1NDX0NMS19U
+Q0sAAVJfU0NfTkdST1VQU19NQVggX1NDX05HUk9VUFNfTUFYAAFUX1NDX09QRU5f
+TUFYIF9TQ19PUEVOX01BWAABVl9TQ19TVFJFQU1fTUFYIF9TQ19TVFJFQU1fTUFY
+AAFYX1NDX1RaTkFNRV9NQVggX1NDX1RaTkFNRV9NQVgAAVpfU0NfSk9CX0NPTlRS
+T0wgX1NDX0pPQl9DT05UUk9MAAFcX1NDX1NBVkVEX0lEUyBfU0NfU0FWRURfSURT
+AAFeX1NDX1JFQUxUSU1FX1NJR05BTFMgX1NDX1JFQUxUSU1FX1NJR05BTFMAAWBf
+U0NfUFJJT1JJVFlfU0NIRURVTElORyBfU0NfUFJJT1JJVFlfU0NIRURVTElORwAB
+Yl9TQ19USU1FUlMgX1NDX1RJTUVSUwABZF9TQ19BU1lOQ0hST05PVVNfSU8gX1ND
+X0FTWU5DSFJPTk9VU19JTwABZl9TQ19QUklPUklUSVpFRF9JTyBfU0NfUFJJT1JJ
+VElaRURfSU8AAWhfU0NfU1lOQ0hST05JWkVEX0lPIF9TQ19TWU5DSFJPTklaRURf
+SU8AAWpfU0NfRlNZTkMgX1NDX0ZTWU5DAAFsX1NDX01BUFBFRF9GSUxFUyBfU0Nf
+TUFQUEVEX0ZJTEVTAAFuX1NDX01FTUxPQ0sgX1NDX01FTUxPQ0sAAXBfU0NfTUVN
+TE9DS19SQU5HRSBfU0NfTUVNTE9DS19SQU5HRQABcl9TQ19NRU1PUllfUFJPVEVD
+VElPTiBfU0NfTUVNT1JZX1BST1RFQ1RJT04AAXRfU0NfTUVTU0FHRV9QQVNTSU5H
+IF9TQ19NRVNTQUdFX1BBU1NJTkcAAXZfU0NfU0VNQVBIT1JFUyBfU0NfU0VNQVBI
+T1JFUwABeF9TQ19TSEFSRURfTUVNT1JZX09CSkVDVFMgX1NDX1NIQVJFRF9NRU1P
+UllfT0JKRUNUUwABel9TQ19BSU9fTElTVElPX01BWCBfU0NfQUlPX0xJU1RJT19N
+QVgAAXxfU0NfQUlPX01BWCBfU0NfQUlPX01BWAABfl9TQ19BSU9fUFJJT19ERUxU
+QV9NQVggX1NDX0FJT19QUklPX0RFTFRBX01BWAABgAFfU0NfREVMQVlUSU1FUl9N
+QVggX1NDX0RFTEFZVElNRVJfTUFYAAGCAV9TQ19NUV9PUEVOX01BWCBfU0NfTVFf
+T1BFTl9NQVgAAYQBX1NDX01RX1BSSU9fTUFYIF9TQ19NUV9QUklPX01BWAABhgFf
+U0NfVkVSU0lPTiBfU0NfVkVSU0lPTgABiAFfU0NfUEFHRVNJWkUgX1NDX1BBR0VT
+SVpFAAGJAV9TQ19QQUdFX1NJWkUgX1NDX1BBR0VTSVpFAAGLAV9TQ19SVFNJR19N
+QVggX1NDX1JUU0lHX01BWAABjQFfU0NfU0VNX05TRU1TX01BWCBfU0NfU0VNX05T
+RU1TX01BWAABjwFfU0NfU0VNX1ZBTFVFX01BWCBfU0NfU0VNX1ZBTFVFX01BWAAB
+kQFfU0NfU0lHUVVFVUVfTUFYIF9TQ19TSUdRVUVVRV9NQVgAAZMBX1NDX1RJTUVS
+X01BWCBfU0NfVElNRVJfTUFYAAGYAV9TQ19CQ19CQVNFX01BWCBfU0NfQkNfQkFT
+RV9NQVgAAZoBX1NDX0JDX0RJTV9NQVggX1NDX0JDX0RJTV9NQVgAAZwBX1NDX0JD
+X1NDQUxFX01BWCBfU0NfQkNfU0NBTEVfTUFYAAGeAV9TQ19CQ19TVFJJTkdfTUFY
+IF9TQ19CQ19TVFJJTkdfTUFYAAGgAV9TQ19DT0xMX1dFSUdIVFNfTUFYIF9TQ19D
+T0xMX1dFSUdIVFNfTUFYAAGiAV9TQ19FUVVJVl9DTEFTU19NQVggX1NDX0VRVUlW
+X0NMQVNTX01BWAABpAFfU0NfRVhQUl9ORVNUX01BWCBfU0NfRVhQUl9ORVNUX01B
+WAABpgFfU0NfTElORV9NQVggX1NDX0xJTkVfTUFYAAGoAV9TQ19SRV9EVVBfTUFY
+IF9TQ19SRV9EVVBfTUFYAAGqAV9TQ19DSEFSQ0xBU1NfTkFNRV9NQVggX1NDX0NI
+QVJDTEFTU19OQU1FX01BWAABrQFfU0NfMl9WRVJTSU9OIF9TQ18yX1ZFUlNJT04A
+Aa8BX1NDXzJfQ19CSU5EIF9TQ18yX0NfQklORAABsQFfU0NfMl9DX0RFViBfU0Nf
+Ml9DX0RFVgABswFfU0NfMl9GT1JUX0RFViBfU0NfMl9GT1JUX0RFVgABtQFfU0Nf
+Ml9GT1JUX1JVTiBfU0NfMl9GT1JUX1JVTgABtwFfU0NfMl9TV19ERVYgX1NDXzJf
+U1dfREVWAAG5AV9TQ18yX0xPQ0FMRURFRiBfU0NfMl9MT0NBTEVERUYAAbwBX1ND
+X1BJSSBfU0NfUElJAAG+AV9TQ19QSUlfWFRJIF9TQ19QSUlfWFRJAAHAAV9TQ19Q
+SUlfU09DS0VUIF9TQ19QSUlfU09DS0VUAAHCAV9TQ19QSUlfSU5URVJORVQgX1ND
+X1BJSV9JTlRFUk5FVAABxAFfU0NfUElJX09TSSBfU0NfUElJX09TSQABxgFfU0Nf
+UE9MTCBfU0NfUE9MTAAByAFfU0NfU0VMRUNUIF9TQ19TRUxFQ1QAAcoBX1NDX1VJ
+T19NQVhJT1YgX1NDX1VJT19NQVhJT1YAAcwBX1NDX0lPVl9NQVggX1NDX0lPVl9N
+QVgAAc4BX1NDX1BJSV9JTlRFUk5FVF9TVFJFQU0gX1NDX1BJSV9JTlRFUk5FVF9T
+VFJFQU0AAdABX1NDX1BJSV9JTlRFUk5FVF9ER1JBTSBfU0NfUElJX0lOVEVSTkVU
+X0RHUkFNAAHSAV9TQ19QSUlfT1NJX0NPVFMgX1NDX1BJSV9PU0lfQ09UUwAB1AFf
+U0NfUElJX09TSV9DTFRTIF9TQ19QSUlfT1NJX0NMVFMAAdYBX1NDX1BJSV9PU0lf
+TSBfU0NfUElJX09TSV9NAAHYAV9TQ19UX0lPVl9NQVggX1NDX1RfSU9WX01BWAAB
+3AFfU0NfVEhSRUFEUyBfU0NfVEhSRUFEUwAB3gFfU0NfVEhSRUFEX1NBRkVfRlVO
+Q1RJT05TIF9TQ19USFJFQURfU0FGRV9GVU5DVElPTlMAAeABX1NDX0dFVEdSX1Jf
+U0laRV9NQVggX1NDX0dFVEdSX1JfU0laRV9NQVgAAeIBX1NDX0dFVFBXX1JfU0la
+RV9NQVggX1NDX0dFVFBXX1JfU0laRV9NQVgAAeQBX1NDX0xPR0lOX05BTUVfTUFY
+IF9TQ19MT0dJTl9OQU1FX01BWAAB5gFfU0NfVFRZX05BTUVfTUFYIF9TQ19UVFlf
+TkFNRV9NQVgAAegBX1NDX1RIUkVBRF9ERVNUUlVDVE9SX0lURVJBVElPTlMgX1ND
+X1RIUkVBRF9ERVNUUlVDVE9SX0lURVJBVElPTlMAAeoBX1NDX1RIUkVBRF9LRVlT
+X01BWCBfU0NfVEhSRUFEX0tFWVNfTUFYAAHsAV9TQ19USFJFQURfU1RBQ0tfTUlO
+IF9TQ19USFJFQURfU1RBQ0tfTUlOAAHuAV9TQ19USFJFQURfVEhSRUFEU19NQVgg
+X1NDX1RIUkVBRF9USFJFQURTX01BWAAB8AFfU0NfVEhSRUFEX0FUVFJfU1RBQ0tB
+RERSIF9TQ19USFJFQURfQVRUUl9TVEFDS0FERFIAAfIBX1NDX1RIUkVBRF9BVFRS
+X1NUQUNLU0laRSBfU0NfVEhSRUFEX0FUVFJfU1RBQ0tTSVpFAAH0AV9TQ19USFJF
+QURfUFJJT1JJVFlfU0NIRURVTElORyBfU0NfVEhSRUFEX1BSSU9SSVRZX1NDSEVE
+VUxJTkcAAfYBX1NDX1RIUkVBRF9QUklPX0lOSEVSSVQgX1NDX1RIUkVBRF9QUklP
+X0lOSEVSSVQAAfgBX1NDX1RIUkVBRF9QUklPX1BST1RFQ1QgX1NDX1RIUkVBRF9Q
+UklPX1BST1RFQ1QAAfoBX1NDX1RIUkVBRF9QUk9DRVNTX1NIQVJFRCBfU0NfVEhS
+RUFEX1BST0NFU1NfU0hBUkVEAAH9AV9TQ19OUFJPQ0VTU09SU19DT05GIF9TQ19O
+UFJPQ0VTU09SU19DT05GAAH/AV9TQ19OUFJPQ0VTU09SU19PTkxOIF9TQ19OUFJP
+Q0VTU09SU19PTkxOAAGBAl9TQ19QSFlTX1BBR0VTIF9TQ19QSFlTX1BBR0VTAAGD
+Al9TQ19BVlBIWVNfUEFHRVMgX1NDX0FWUEhZU19QQUdFUwABhQJfU0NfQVRFWElU
+X01BWCBfU0NfQVRFWElUX01BWAABhwJfU0NfUEFTU19NQVggX1NDX1BBU1NfTUFY
+AAGKAl9TQ19YT1BFTl9WRVJTSU9OIF9TQ19YT1BFTl9WRVJTSU9OAAGMAl9TQ19Y
+T1BFTl9YQ1VfVkVSU0lPTiBfU0NfWE9QRU5fWENVX1ZFUlNJT04AAY4CX1NDX1hP
+UEVOX1VOSVggX1NDX1hPUEVOX1VOSVgAAZACX1NDX1hPUEVOX0NSWVBUIF9TQ19Y
+T1BFTl9DUllQVAABkgJfU0NfWE9QRU5fRU5IX0kxOE4gX1NDX1hPUEVOX0VOSF9J
+MThOAAGUAl9TQ19YT1BFTl9TSE0gX1NDX1hPUEVOX1NITQABlwJfU0NfMl9DSEFS
+X1RFUk0gX1NDXzJfQ0hBUl9URVJNAAGZAl9TQ18yX0NfVkVSU0lPTiBfU0NfMl9D
+X1ZFUlNJT04AAZsCX1NDXzJfVVBFIF9TQ18yX1VQRQABngJfU0NfWE9QRU5fWFBH
+MiBfU0NfWE9QRU5fWFBHMgABoAJfU0NfWE9QRU5fWFBHMyBfU0NfWE9QRU5fWFBH
+MwABogJfU0NfWE9QRU5fWFBHNCBfU0NfWE9QRU5fWFBHNAABpQJfU0NfQ0hBUl9C
+SVQgX1NDX0NIQVJfQklUAAGnAl9TQ19DSEFSX01BWCBfU0NfQ0hBUl9NQVgAAakC
+X1NDX0NIQVJfTUlOIF9TQ19DSEFSX01JTgABqwJfU0NfSU5UX01BWCBfU0NfSU5U
+X01BWAABrQJfU0NfSU5UX01JTiBfU0NfSU5UX01JTgABrwJfU0NfTE9OR19CSVQg
+X1NDX0xPTkdfQklUAAGxAl9TQ19XT1JEX0JJVCBfU0NfV09SRF9CSVQAAbMCX1ND
+X01CX0xFTl9NQVggX1NDX01CX0xFTl9NQVgAAbUCX1NDX05aRVJPIF9TQ19OWkVS
+TwABtwJfU0NfU1NJWkVfTUFYIF9TQ19TU0laRV9NQVgAAbkCX1NDX1NDSEFSX01B
+WCBfU0NfU0NIQVJfTUFYAAG7Al9TQ19TQ0hBUl9NSU4gX1NDX1NDSEFSX01JTgAB
+vQJfU0NfU0hSVF9NQVggX1NDX1NIUlRfTUFYAAG/Al9TQ19TSFJUX01JTiBfU0Nf
+U0hSVF9NSU4AAcECX1NDX1VDSEFSX01BWCBfU0NfVUNIQVJfTUFYAAHDAl9TQ19V
+SU5UX01BWCBfU0NfVUlOVF9NQVgAAcUCX1NDX1VMT05HX01BWCBfU0NfVUxPTkdf
+TUFYAAHHAl9TQ19VU0hSVF9NQVggX1NDX1VTSFJUX01BWAABygJfU0NfTkxfQVJH
+TUFYIF9TQ19OTF9BUkdNQVgAAcwCX1NDX05MX0xBTkdNQVggX1NDX05MX0xBTkdN
+QVgAAc4CX1NDX05MX01TR01BWCBfU0NfTkxfTVNHTUFYAAHQAl9TQ19OTF9OTUFY
+IF9TQ19OTF9OTUFYAAHSAl9TQ19OTF9TRVRNQVggX1NDX05MX1NFVE1BWAAB1AJf
+U0NfTkxfVEVYVE1BWCBfU0NfTkxfVEVYVE1BWAAB1wJfU0NfWEJTNV9JTFAzMl9P
+RkYzMiBfU0NfWEJTNV9JTFAzMl9PRkYzMgAB2QJfU0NfWEJTNV9JTFAzMl9PRkZC
+SUcgX1NDX1hCUzVfSUxQMzJfT0ZGQklHAAHbAl9TQ19YQlM1X0xQNjRfT0ZGNjQg
+X1NDX1hCUzVfTFA2NF9PRkY2NAAB3QJfU0NfWEJTNV9MUEJJR19PRkZCSUcgX1ND
+X1hCUzVfTFBCSUdfT0ZGQklHAAHgAl9TQ19YT1BFTl9MRUdBQ1kgX1NDX1hPUEVO
+X0xFR0FDWQAB4gJfU0NfWE9QRU5fUkVBTFRJTUUgX1NDX1hPUEVOX1JFQUxUSU1F
+AAHkAl9TQ19YT1BFTl9SRUFMVElNRV9USFJFQURTIF9TQ19YT1BFTl9SRUFMVElN
+RV9USFJFQURTAAHnAl9TQ19BRFZJU09SWV9JTkZPIF9TQ19BRFZJU09SWV9JTkZP
+AAHpAl9TQ19CQVJSSUVSUyBfU0NfQkFSUklFUlMAAesCX1NDX0JBU0UgX1NDX0JB
+U0UAAe0CX1NDX0NfTEFOR19TVVBQT1JUIF9TQ19DX0xBTkdfU1VQUE9SVAAB7wJf
+U0NfQ19MQU5HX1NVUFBPUlRfUiBfU0NfQ19MQU5HX1NVUFBPUlRfUgAB8QJfU0Nf
+Q0xPQ0tfU0VMRUNUSU9OIF9TQ19DTE9DS19TRUxFQ1RJT04AAfMCX1NDX0NQVVRJ
+TUUgX1NDX0NQVVRJTUUAAfUCX1NDX1RIUkVBRF9DUFVUSU1FIF9TQ19USFJFQURf
+Q1BVVElNRQAB9wJfU0NfREVWSUNFX0lPIF9TQ19ERVZJQ0VfSU8AAfkCX1NDX0RF
+VklDRV9TUEVDSUZJQyBfU0NfREVWSUNFX1NQRUNJRklDAAH7Al9TQ19ERVZJQ0Vf
+U1BFQ0lGSUNfUiBfU0NfREVWSUNFX1NQRUNJRklDX1IAAf0CX1NDX0ZEX01HTVQg
+X1NDX0ZEX01HTVQAAf8CX1NDX0ZJRk8gX1NDX0ZJRk8AAYEDX1NDX1BJUEUgX1ND
+X1BJUEUAAYMDX1NDX0ZJTEVfQVRUUklCVVRFUyBfU0NfRklMRV9BVFRSSUJVVEVT
+AAGFA19TQ19GSUxFX0xPQ0tJTkcgX1NDX0ZJTEVfTE9DS0lORwABhwNfU0NfRklM
+RV9TWVNURU0gX1NDX0ZJTEVfU1lTVEVNAAGJA19TQ19NT05PVE9OSUNfQ0xPQ0sg
+X1NDX01PTk9UT05JQ19DTE9DSwABiwNfU0NfTVVMVElfUFJPQ0VTUyBfU0NfTVVM
+VElfUFJPQ0VTUwABjQNfU0NfU0lOR0xFX1BST0NFU1MgX1NDX1NJTkdMRV9QUk9D
+RVNTAAGPA19TQ19ORVRXT1JLSU5HIF9TQ19ORVRXT1JLSU5HAAGRA19TQ19SRUFE
+RVJfV1JJVEVSX0xPQ0tTIF9TQ19SRUFERVJfV1JJVEVSX0xPQ0tTAAGTA19TQ19T
+UElOX0xPQ0tTIF9TQ19TUElOX0xPQ0tTAAGVA19TQ19SRUdFWFAgX1NDX1JFR0VY
+UAABlwNfU0NfUkVHRVhfVkVSU0lPTiBfU0NfUkVHRVhfVkVSU0lPTgABmQNfU0Nf
+U0hFTEwgX1NDX1NIRUxMAAGbA19TQ19TSUdOQUxTIF9TQ19TSUdOQUxTAAGdA19T
+Q19TUEFXTiBfU0NfU1BBV04AAZ8DX1NDX1NQT1JBRElDX1NFUlZFUiBfU0NfU1BP
+UkFESUNfU0VSVkVSAAGhA19TQ19USFJFQURfU1BPUkFESUNfU0VSVkVSIF9TQ19U
+SFJFQURfU1BPUkFESUNfU0VSVkVSAAGjA19TQ19TWVNURU1fREFUQUJBU0UgX1ND
+X1NZU1RFTV9EQVRBQkFTRQABpQNfU0NfU1lTVEVNX0RBVEFCQVNFX1IgX1NDX1NZ
+U1RFTV9EQVRBQkFTRV9SAAGnA19TQ19USU1FT1VUUyBfU0NfVElNRU9VVFMAAakD
+X1NDX1RZUEVEX01FTU9SWV9PQkpFQ1RTIF9TQ19UWVBFRF9NRU1PUllfT0JKRUNU
+UwABqwNfU0NfVVNFUl9HUk9VUFMgX1NDX1VTRVJfR1JPVVBTAAGtA19TQ19VU0VS
+X0dST1VQU19SIF9TQ19VU0VSX0dST1VQU19SAAGvA19TQ18yX1BCUyBfU0NfMl9Q
+QlMAAbEDX1NDXzJfUEJTX0FDQ09VTlRJTkcgX1NDXzJfUEJTX0FDQ09VTlRJTkcA
+AbMDX1NDXzJfUEJTX0xPQ0FURSBfU0NfMl9QQlNfTE9DQVRFAAG1A19TQ18yX1BC
+U19NRVNTQUdFIF9TQ18yX1BCU19NRVNTQUdFAAG3A19TQ18yX1BCU19UUkFDSyBf
+U0NfMl9QQlNfVFJBQ0sAAbkDX1NDX1NZTUxPT1BfTUFYIF9TQ19TWU1MT09QX01B
+WAABuwNfU0NfU1RSRUFNUyBfU0NfU1RSRUFNUwABvQNfU0NfMl9QQlNfQ0hFQ0tQ
+T0lOVCBfU0NfMl9QQlNfQ0hFQ0tQT0lOVAABwANfU0NfVjZfSUxQMzJfT0ZGMzIg
+X1NDX1Y2X0lMUDMyX09GRjMyAAHCA19TQ19WNl9JTFAzMl9PRkZCSUcgX1NDX1Y2
+X0lMUDMyX09GRkJJRwABxANfU0NfVjZfTFA2NF9PRkY2NCBfU0NfVjZfTFA2NF9P
+RkY2NAABxgNfU0NfVjZfTFBCSUdfT0ZGQklHIF9TQ19WNl9MUEJJR19PRkZCSUcA
+AckDX1NDX0hPU1RfTkFNRV9NQVggX1NDX0hPU1RfTkFNRV9NQVgAAcsDX1NDX1RS
+QUNFIF9TQ19UUkFDRQABzQNfU0NfVFJBQ0VfRVZFTlRfRklMVEVSIF9TQ19UUkFD
+RV9FVkVOVF9GSUxURVIAAc8DX1NDX1RSQUNFX0lOSEVSSVQgX1NDX1RSQUNFX0lO
+SEVSSVQAAdEDX1NDX1RSQUNFX0xPRyBfU0NfVFJBQ0VfTE9HAAHUA19TQ19MRVZF
+TDFfSUNBQ0hFX1NJWkUgX1NDX0xFVkVMMV9JQ0FDSEVfU0laRQAB1gNfU0NfTEVW
+RUwxX0lDQUNIRV9BU1NPQyBfU0NfTEVWRUwxX0lDQUNIRV9BU1NPQwAB2ANfU0Nf
+TEVWRUwxX0lDQUNIRV9MSU5FU0laRSBfU0NfTEVWRUwxX0lDQUNIRV9MSU5FU0la
+RQAB2gNfU0NfTEVWRUwxX0RDQUNIRV9TSVpFIF9TQ19MRVZFTDFfRENBQ0hFX1NJ
+WkUAAdwDX1NDX0xFVkVMMV9EQ0FDSEVfQVNTT0MgX1NDX0xFVkVMMV9EQ0FDSEVf
+QVNTT0MAAd4DX1NDX0xFVkVMMV9EQ0FDSEVfTElORVNJWkUgX1NDX0xFVkVMMV9E
+Q0FDSEVfTElORVNJWkUAAeADX1NDX0xFVkVMMl9DQUNIRV9TSVpFIF9TQ19MRVZF
+TDJfQ0FDSEVfU0laRQAB4gNfU0NfTEVWRUwyX0NBQ0hFX0FTU09DIF9TQ19MRVZF
+TDJfQ0FDSEVfQVNTT0MAAeQDX1NDX0xFVkVMMl9DQUNIRV9MSU5FU0laRSBfU0Nf
+TEVWRUwyX0NBQ0hFX0xJTkVTSVpFAAHmA19TQ19MRVZFTDNfQ0FDSEVfU0laRSBf
+U0NfTEVWRUwzX0NBQ0hFX1NJWkUAAegDX1NDX0xFVkVMM19DQUNIRV9BU1NPQyBf
+U0NfTEVWRUwzX0NBQ0hFX0FTU09DAAHqA19TQ19MRVZFTDNfQ0FDSEVfTElORVNJ
+WkUgX1NDX0xFVkVMM19DQUNIRV9MSU5FU0laRQAB7ANfU0NfTEVWRUw0X0NBQ0hF
+X1NJWkUgX1NDX0xFVkVMNF9DQUNIRV9TSVpFAAHuA19TQ19MRVZFTDRfQ0FDSEVf
+QVNTT0MgX1NDX0xFVkVMNF9DQUNIRV9BU1NPQwAB8ANfU0NfTEVWRUw0X0NBQ0hF
+X0xJTkVTSVpFIF9TQ19MRVZFTDRfQ0FDSEVfTElORVNJWkUAAfQDX1NDX0lQVjYg
+X1NDX0lQVjYAAfYDX1NDX1JBV19TT0NLRVRTIF9TQ19SQVdfU09DS0VUUwAB+QNf
+U0NfVjdfSUxQMzJfT0ZGMzIgX1NDX1Y3X0lMUDMyX09GRjMyAAH7A19TQ19WN19J
+TFAzMl9PRkZCSUcgX1NDX1Y3X0lMUDMyX09GRkJJRwAB/QNfU0NfVjdfTFA2NF9P
+RkY2NCBfU0NfVjdfTFA2NF9PRkY2NAAB/wNfU0NfVjdfTFBCSUdfT0ZGQklHIF9T
+Q19WN19MUEJJR19PRkZCSUcAAYIEX1NDX1NTX1JFUExfTUFYIF9TQ19TU19SRVBM
+X01BWAABhQRfU0NfVFJBQ0VfRVZFTlRfTkFNRV9NQVggX1NDX1RSQUNFX0VWRU5U
+X05BTUVfTUFYAAGHBF9TQ19UUkFDRV9OQU1FX01BWCBfU0NfVFJBQ0VfTkFNRV9N
+QVgAAYkEX1NDX1RSQUNFX1NZU19NQVggX1NDX1RSQUNFX1NZU19NQVgAAYsEX1ND
+X1RSQUNFX1VTRVJfRVZFTlRfTUFYIF9TQ19UUkFDRV9VU0VSX0VWRU5UX01BWAAB
+jgRfU0NfWE9QRU5fU1RSRUFNUyBfU0NfWE9QRU5fU1RSRUFNUwABkQRfU0NfVEhS
+RUFEX1JPQlVTVF9QUklPX0lOSEVSSVQgX1NDX1RIUkVBRF9ST0JVU1RfUFJJT19J
+TkhFUklUAAGTBF9TQ19USFJFQURfUk9CVVNUX1BSSU9fUFJPVEVDVCBfU0NfVEhS
+RUFEX1JPQlVTVF9QUklPX1BST1RFQ1QAAZoEX0NTX1BBVEggX0NTX1BBVEgAAZ0E
+X0NTX1Y2X1dJRFRIX1JFU1RSSUNURURfRU5WUyBfQ1NfVjZfV0lEVEhfUkVTVFJJ
+Q1RFRF9FTlZTAAGeBF9DU19QT1NJWF9WNl9XSURUSF9SRVNUUklDVEVEX0VOVlMg
+X0NTX1Y2X1dJRFRIX1JFU1RSSUNURURfRU5WUwABoQRfQ1NfR05VX0xJQkNfVkVS
+U0lPTiBfQ1NfR05VX0xJQkNfVkVSU0lPTgABowRfQ1NfR05VX0xJQlBUSFJFQURf
+VkVSU0lPTiBfQ1NfR05VX0xJQlBUSFJFQURfVkVSU0lPTgABpgRfQ1NfVjVfV0lE
+VEhfUkVTVFJJQ1RFRF9FTlZTIF9DU19WNV9XSURUSF9SRVNUUklDVEVEX0VOVlMA
+AacEX0NTX1BPU0lYX1Y1X1dJRFRIX1JFU1RSSUNURURfRU5WUyBfQ1NfVjVfV0lE
+VEhfUkVTVFJJQ1RFRF9FTlZTAAGqBF9DU19WN19XSURUSF9SRVNUUklDVEVEX0VO
+VlMgX0NTX1Y3X1dJRFRIX1JFU1RSSUNURURfRU5WUwABqwRfQ1NfUE9TSVhfVjdf
+V0lEVEhfUkVTVFJJQ1RFRF9FTlZTIF9DU19WN19XSURUSF9SRVNUUklDVEVEX0VO
+VlMAAa4EX0NTX0xGU19DRkxBR1MgX0NTX0xGU19DRkxBR1MAAbAEX0NTX0xGU19M
+REZMQUdTIF9DU19MRlNfTERGTEFHUwABsgRfQ1NfTEZTX0xJQlMgX0NTX0xGU19M
+SUJTAAG0BF9DU19MRlNfTElOVEZMQUdTIF9DU19MRlNfTElOVEZMQUdTAAG2BF9D
+U19MRlM2NF9DRkxBR1MgX0NTX0xGUzY0X0NGTEFHUwABuARfQ1NfTEZTNjRfTERG
+TEFHUyBfQ1NfTEZTNjRfTERGTEFHUwABugRfQ1NfTEZTNjRfTElCUyBfQ1NfTEZT
+NjRfTElCUwABvARfQ1NfTEZTNjRfTElOVEZMQUdTIF9DU19MRlM2NF9MSU5URkxB
+R1MAAb8EX0NTX1hCUzVfSUxQMzJfT0ZGMzJfQ0ZMQUdTIF9DU19YQlM1X0lMUDMy
+X09GRjMyX0NGTEFHUwABwQRfQ1NfWEJTNV9JTFAzMl9PRkYzMl9MREZMQUdTIF9D
+U19YQlM1X0lMUDMyX09GRjMyX0xERkxBR1MAAcMEX0NTX1hCUzVfSUxQMzJfT0ZG
+MzJfTElCUyBfQ1NfWEJTNV9JTFAzMl9PRkYzMl9MSUJTAAHFBF9DU19YQlM1X0lM
+UDMyX09GRjMyX0xJTlRGTEFHUyBfQ1NfWEJTNV9JTFAzMl9PRkYzMl9MSU5URkxB
+R1MAAccEX0NTX1hCUzVfSUxQMzJfT0ZGQklHX0NGTEFHUyBfQ1NfWEJTNV9JTFAz
+Ml9PRkZCSUdfQ0ZMQUdTAAHJBF9DU19YQlM1X0lMUDMyX09GRkJJR19MREZMQUdT
+IF9DU19YQlM1X0lMUDMyX09GRkJJR19MREZMQUdTAAHLBF9DU19YQlM1X0lMUDMy
+X09GRkJJR19MSUJTIF9DU19YQlM1X0lMUDMyX09GRkJJR19MSUJTAAHNBF9DU19Y
+QlM1X0lMUDMyX09GRkJJR19MSU5URkxBR1MgX0NTX1hCUzVfSUxQMzJfT0ZGQklH
+X0xJTlRGTEFHUwABzwRfQ1NfWEJTNV9MUDY0X09GRjY0X0NGTEFHUyBfQ1NfWEJT
+NV9MUDY0X09GRjY0X0NGTEFHUwAB0QRfQ1NfWEJTNV9MUDY0X09GRjY0X0xERkxB
+R1MgX0NTX1hCUzVfTFA2NF9PRkY2NF9MREZMQUdTAAHTBF9DU19YQlM1X0xQNjRf
+T0ZGNjRfTElCUyBfQ1NfWEJTNV9MUDY0X09GRjY0X0xJQlMAAdUEX0NTX1hCUzVf
+TFA2NF9PRkY2NF9MSU5URkxBR1MgX0NTX1hCUzVfTFA2NF9PRkY2NF9MSU5URkxB
+R1MAAdcEX0NTX1hCUzVfTFBCSUdfT0ZGQklHX0NGTEFHUyBfQ1NfWEJTNV9MUEJJ
+R19PRkZCSUdfQ0ZMQUdTAAHZBF9DU19YQlM1X0xQQklHX09GRkJJR19MREZMQUdT
+IF9DU19YQlM1X0xQQklHX09GRkJJR19MREZMQUdTAAHbBF9DU19YQlM1X0xQQklH
+X09GRkJJR19MSUJTIF9DU19YQlM1X0xQQklHX09GRkJJR19MSUJTAAHdBF9DU19Y
+QlM1X0xQQklHX09GRkJJR19MSU5URkxBR1MgX0NTX1hCUzVfTFBCSUdfT0ZGQklH
+X0xJTlRGTEFHUwAB4ARfQ1NfUE9TSVhfVjZfSUxQMzJfT0ZGMzJfQ0ZMQUdTIF9D
+U19QT1NJWF9WNl9JTFAzMl9PRkYzMl9DRkxBR1MAAeIEX0NTX1BPU0lYX1Y2X0lM
+UDMyX09GRjMyX0xERkxBR1MgX0NTX1BPU0lYX1Y2X0lMUDMyX09GRjMyX0xERkxB
+R1MAAeQEX0NTX1BPU0lYX1Y2X0lMUDMyX09GRjMyX0xJQlMgX0NTX1BPU0lYX1Y2
+X0lMUDMyX09GRjMyX0xJQlMAAeYEX0NTX1BPU0lYX1Y2X0lMUDMyX09GRjMyX0xJ
+TlRGTEFHUyBfQ1NfUE9TSVhfVjZfSUxQMzJfT0ZGMzJfTElOVEZMQUdTAAHoBF9D
+U19QT1NJWF9WNl9JTFAzMl9PRkZCSUdfQ0ZMQUdTIF9DU19QT1NJWF9WNl9JTFAz
+Ml9PRkZCSUdfQ0ZMQUdTAAHqBF9DU19QT1NJWF9WNl9JTFAzMl9PRkZCSUdfTERG
+TEFHUyBfQ1NfUE9TSVhfVjZfSUxQMzJfT0ZGQklHX0xERkxBR1MAAewEX0NTX1BP
+U0lYX1Y2X0lMUDMyX09GRkJJR19MSUJTIF9DU19QT1NJWF9WNl9JTFAzMl9PRkZC
+SUdfTElCUwAB7gRfQ1NfUE9TSVhfVjZfSUxQMzJfT0ZGQklHX0xJTlRGTEFHUyBf
+Q1NfUE9TSVhfVjZfSUxQMzJfT0ZGQklHX0xJTlRGTEFHUwAB8ARfQ1NfUE9TSVhf
+VjZfTFA2NF9PRkY2NF9DRkxBR1MgX0NTX1BPU0lYX1Y2X0xQNjRfT0ZGNjRfQ0ZM
+QUdTAAHyBF9DU19QT1NJWF9WNl9MUDY0X09GRjY0X0xERkxBR1MgX0NTX1BPU0lY
+X1Y2X0xQNjRfT0ZGNjRfTERGTEFHUwAB9ARfQ1NfUE9TSVhfVjZfTFA2NF9PRkY2
+NF9MSUJTIF9DU19QT1NJWF9WNl9MUDY0X09GRjY0X0xJQlMAAfYEX0NTX1BPU0lY
+X1Y2X0xQNjRfT0ZGNjRfTElOVEZMQUdTIF9DU19QT1NJWF9WNl9MUDY0X09GRjY0
+X0xJTlRGTEFHUwAB+ARfQ1NfUE9TSVhfVjZfTFBCSUdfT0ZGQklHX0NGTEFHUyBf
+Q1NfUE9TSVhfVjZfTFBCSUdfT0ZGQklHX0NGTEFHUwAB+gRfQ1NfUE9TSVhfVjZf
+TFBCSUdfT0ZGQklHX0xERkxBR1MgX0NTX1BPU0lYX1Y2X0xQQklHX09GRkJJR19M
+REZMQUdTAAH8BF9DU19QT1NJWF9WNl9MUEJJR19PRkZCSUdfTElCUyBfQ1NfUE9T
+SVhfVjZfTFBCSUdfT0ZGQklHX0xJQlMAAf4EX0NTX1BPU0lYX1Y2X0xQQklHX09G
+RkJJR19MSU5URkxBR1MgX0NTX1BPU0lYX1Y2X0xQQklHX09GRkJJR19MSU5URkxB
+R1MAAYEFX0NTX1BPU0lYX1Y3X0lMUDMyX09GRjMyX0NGTEFHUyBfQ1NfUE9TSVhf
+VjdfSUxQMzJfT0ZGMzJfQ0ZMQUdTAAGDBV9DU19QT1NJWF9WN19JTFAzMl9PRkYz
+Ml9MREZMQUdTIF9DU19QT1NJWF9WN19JTFAzMl9PRkYzMl9MREZMQUdTAAGFBV9D
+U19QT1NJWF9WN19JTFAzMl9PRkYzMl9MSUJTIF9DU19QT1NJWF9WN19JTFAzMl9P
+RkYzMl9MSUJTAAGHBV9DU19QT1NJWF9WN19JTFAzMl9PRkYzMl9MSU5URkxBR1Mg
+X0NTX1BPU0lYX1Y3X0lMUDMyX09GRjMyX0xJTlRGTEFHUwABiQVfQ1NfUE9TSVhf
+VjdfSUxQMzJfT0ZGQklHX0NGTEFHUyBfQ1NfUE9TSVhfVjdfSUxQMzJfT0ZGQklH
+X0NGTEFHUwABiwVfQ1NfUE9TSVhfVjdfSUxQMzJfT0ZGQklHX0xERkxBR1MgX0NT
+X1BPU0lYX1Y3X0lMUDMyX09GRkJJR19MREZMQUdTAAGNBV9DU19QT1NJWF9WN19J
+TFAzMl9PRkZCSUdfTElCUyBfQ1NfUE9TSVhfVjdfSUxQMzJfT0ZGQklHX0xJQlMA
+AY8FX0NTX1BPU0lYX1Y3X0lMUDMyX09GRkJJR19MSU5URkxBR1MgX0NTX1BPU0lY
+X1Y3X0lMUDMyX09GRkJJR19MSU5URkxBR1MAAZEFX0NTX1BPU0lYX1Y3X0xQNjRf
+T0ZGNjRfQ0ZMQUdTIF9DU19QT1NJWF9WN19MUDY0X09GRjY0X0NGTEFHUwABkwVf
+Q1NfUE9TSVhfVjdfTFA2NF9PRkY2NF9MREZMQUdTIF9DU19QT1NJWF9WN19MUDY0
+X09GRjY0X0xERkxBR1MAAZUFX0NTX1BPU0lYX1Y3X0xQNjRfT0ZGNjRfTElCUyBf
+Q1NfUE9TSVhfVjdfTFA2NF9PRkY2NF9MSUJTAAGXBV9DU19QT1NJWF9WN19MUDY0
+X09GRjY0X0xJTlRGTEFHUyBfQ1NfUE9TSVhfVjdfTFA2NF9PRkY2NF9MSU5URkxB
+R1MAAZkFX0NTX1BPU0lYX1Y3X0xQQklHX09GRkJJR19DRkxBR1MgX0NTX1BPU0lY
+X1Y3X0xQQklHX09GRkJJR19DRkxBR1MAAZsFX0NTX1BPU0lYX1Y3X0xQQklHX09G
+RkJJR19MREZMQUdTIF9DU19QT1NJWF9WN19MUEJJR19PRkZCSUdfTERGTEFHUwAB
+nQVfQ1NfUE9TSVhfVjdfTFBCSUdfT0ZGQklHX0xJQlMgX0NTX1BPU0lYX1Y3X0xQ
+QklHX09GRkJJR19MSUJTAAGfBV9DU19QT1NJWF9WN19MUEJJR19PRkZCSUdfTElO
+VEZMQUdTIF9DU19QT1NJWF9WN19MUEJJR19PRkZCSUdfTElOVEZMQUdTAAGiBV9D
+U19WNl9FTlYgX0NTX1Y2X0VOVgABpAVfQ1NfVjdfRU5WIF9DU19WN19FTlYABAH5
+Bl9fbmVlZF9nZXRvcHQgAAP6BjACvwFfX25lZWRfZ2V0b3B0AAQB2ghURU1QX0ZB
+SUxVUkVfUkVUUlkoZXhwcmVzc2lvbikgKF9fZXh0ZW5zaW9uX18gKHsgbG9uZyBp
+bnQgX19yZXN1bHQ7IGRvIF9fcmVzdWx0ID0gKGxvbmcgaW50KSAoZXhwcmVzc2lv
+bik7IHdoaWxlIChfX3Jlc3VsdCA9PSAtMUwgJiYgZXJybm8gPT0gRUlOVFIpOyBf
+X3Jlc3VsdDsgfSkpAAQDBjEBGV9TVFJJTkdfSCAxAAEgX19uZWVkX3NpemVfdCAA
+ASFfX25lZWRfTlVMTCAAAyILAuoBX19uZWVkX3NpemVfdAACjQNOVUxMAAGPA05V
+TEwgX19udWxsAAKYA19fbmVlZF9OVUxMAAQBJl9fQ09SUkVDVF9JU09fQ1BQX1NU
+UklOR19IX1BST1RPIAABvQFzdHJkdXBhKHMpIChfX2V4dGVuc2lvbl9fICh7IF9f
+Y29uc3QgY2hhciAqX19vbGQgPSAocyk7IHNpemVfdCBfX2xlbiA9IHN0cmxlbiAo
+X19vbGQpICsgMTsgY2hhciAqX19uZXcgPSAoY2hhciAqKSBfX2J1aWx0aW5fYWxs
+b2NhIChfX2xlbik7IChjaGFyICopIG1lbWNweSAoX19uZXcsIF9fb2xkLCBfX2xl
+bik7IH0pKQABxwFzdHJuZHVwYShzLG4pIChfX2V4dGVuc2lvbl9fICh7IF9fY29u
+c3QgY2hhciAqX19vbGQgPSAocyk7IHNpemVfdCBfX2xlbiA9IHN0cm5sZW4gKF9f
+b2xkLCAobikpOyBjaGFyICpfX25ldyA9IChjaGFyICopIF9fYnVpbHRpbl9hbGxv
+Y2EgKF9fbGVuICsgMSk7IF9fbmV3W19fbGVuXSA9ICdcMCc7IChjaGFyICopIG1l
+bWNweSAoX19uZXcsIF9fb2xkLCBfX2xlbik7IH0pKQAEBAAALnN5bXRhYgAuc3Ry
+dGFiAC5zaHN0cnRhYgAuaW50ZXJwAC5ub3RlLkFCSS10YWcALm5vdGUuZ251LmJ1
+aWxkLWlkAC5oYXNoAC5keW5zeW0ALmR5bnN0cgAuZ251LnZlcnNpb24ALmdudS52
+ZXJzaW9uX3IALnJlbC5keW4ALnJlbC5wbHQALmluaXQALnRleHQALmZpbmkALnJv
+ZGF0YQAuZWhfZnJhbWVfaGRyAC5laF9mcmFtZQAuY3RvcnMALmR0b3JzAC5qY3IA
+LmR5bmFtaWMALmdvdAAuZ290LnBsdAAuZGF0YQAuYnNzAC5jb21tZW50AC5kZWJ1
+Z19hcmFuZ2VzAC5kZWJ1Z19pbmZvAC5kZWJ1Z19hYmJyZXYALmRlYnVnX2xpbmUA
+LmRlYnVnX3N0cgAuZGVidWdfbG9jAC5kZWJ1Z19tYWNpbmZvAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbAAAAAQAAAAIAAAA0gQQI
+NAEAABMAAAAAAAAAAAAAAAEAAAAAAAAAIwAAAAcAAAACAAAASIEECEgBAAAgAAAA
+AAAAAAAAAAAEAAAAAAAAADEAAAAHAAAAAgAAAGiBBAhoAQAAJAAAAAAAAAAAAAAA
+BAAAAAAAAABEAAAABQAAAAIAAACMgQQIjAEAAEAAAAAFAAAAAAAAAAQAAAAEAAAA
+SgAAAAsAAAACAAAAzIEECMwBAACwAAAABgAAAAEAAAAEAAAAEAAAAFIAAAADAAAA
+AgAAAHyCBAh8AgAApQAAAAAAAAAAAAAAAQAAAAAAAABaAAAA////bwIAAAAigwQI
+IgMAABYAAAAFAAAAAAAAAAIAAAACAAAAZwAAAP7//28CAAAAOIMECDgDAAAgAAAA
+BgAAAAEAAAAEAAAAAAAAAHYAAAAJAAAAAgAAAFiDBAhYAwAACAAAAAUAAAAAAAAA
+BAAAAAgAAAB/AAAACQAAAAIAAABggwQIYAMAAEgAAAAFAAAADAAAAAQAAAAIAAAA
+iAAAAAEAAAAGAAAAqIMECKgDAAAuAAAAAAAAAAAAAAAEAAAAAAAAAIMAAAABAAAA
+BgAAAOCDBAjgAwAAoAAAAAAAAAAAAAAAEAAAAAQAAACOAAAAAQAAAAYAAACAhAQI
+gAQAALwCAAAAAAAAAAAAABAAAAAAAAAAlAAAAAEAAAAGAAAAPIcECDwHAAAaAAAA
+AAAAAAAAAAAEAAAAAAAAAJoAAAABAAAAAgAAAFiHBAhYBwAAQQAAAAAAAAAAAAAA
+BAAAAAAAAACiAAAAAQAAAAIAAACchwQInAcAADQAAAAAAAAAAAAAAAQAAAAAAAAA
+sAAAAAEAAAACAAAA0IcECNAHAADQAAAAAAAAAAAAAAAEAAAAAAAAALoAAAABAAAA
+AwAAAKCYBAigCAAACAAAAAAAAAAAAAAABAAAAAAAAADBAAAAAQAAAAMAAAComAQI
+qAgAAAgAAAAAAAAAAAAAAAQAAAAAAAAAyAAAAAEAAAADAAAAsJgECLAIAAAEAAAA
+AAAAAAAAAAAEAAAAAAAAAM0AAAAGAAAAAwAAALSYBAi0CAAA6AAAAAYAAAAAAAAA
+BAAAAAgAAADWAAAAAQAAAAMAAACcmQQInAkAAAQAAAAAAAAAAAAAAAQAAAAEAAAA
+2wAAAAEAAAADAAAAoJkECKAJAAAwAAAAAAAAAAAAAAAEAAAABAAAAOQAAAABAAAA
+AwAAANCZBAjQCQAACAAAAAAAAAAAAAAABAAAAAAAAADqAAAACAAAAAMAAADYmQQI
+2AkAAAgAAAAAAAAAAAAAAAQAAAAAAAAA7wAAAAEAAAAwAAAAAAAAANgJAAAkAAAA
+AAAAAAAAAAABAAAAAQAAAPgAAAABAAAAAAAAAAAAAAD8CQAAIAAAAAAAAAAAAAAA
+AQAAAAAAAAAHAQAAAQAAAAAAAAAAAAAAHAoAAEkBAAAAAAAAAAAAAAEAAAAAAAAA
+EwEAAAEAAAAAAAAAAAAAAGULAACeAAAAAAAAAAAAAAABAAAAAAAAACEBAAABAAAA
+AAAAAAAAAAADDAAAWAUAAAAAAAAAAAAAAQAAAAAAAAAtAQAAAQAAADAAAAAAAAAA
+WxEAAO8AAAAAAAAAAAAAAAEAAAABAAAAOAEAAAEAAAAAAAAAAAAAAEoSAAA4AAAA
+AAAAAAAAAAABAAAAAAAAAEMBAAABAAAAAAAAAAAAAACCEgAAobAAAAAAAAAAAAAA
+AQAAAAAAAAARAAAAAwAAAAAAAAAAAAAAI8MAAFIBAAAAAAAAAAAAAAEAAAAAAAAA
+AQAAAAIAAAAAAAAAAAAAAEDKAADgBAAAJAAAADQAAAAEAAAAEAAAAAkAAAADAAAA
+AAAAAAAAAAAgzwAAZgIAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAADSBBAgAAAAAAwABAAAAAABIgQQIAAAAAAMAAgAAAAAAaIEECAAAAAADAAMA
+AAAAAIyBBAgAAAAAAwAEAAAAAADMgQQIAAAAAAMABQAAAAAAfIIECAAAAAADAAYA
+AAAAACKDBAgAAAAAAwAHAAAAAAA4gwQIAAAAAAMACAAAAAAAWIMECAAAAAADAAkA
+AAAAAGCDBAgAAAAAAwAKAAAAAACogwQIAAAAAAMACwAAAAAA4IMECAAAAAADAAwA
+AAAAAICEBAgAAAAAAwANAAAAAAA8hwQIAAAAAAMADgAAAAAAWIcECAAAAAADAA8A
+AAAAAJyHBAgAAAAAAwAQAAAAAADQhwQIAAAAAAMAEQAAAAAAoJgECAAAAAADABIA
+AAAAAKiYBAgAAAAAAwATAAAAAACwmAQIAAAAAAMAFAAAAAAAtJgECAAAAAADABUA
+AAAAAJyZBAgAAAAAAwAWAAAAAACgmQQIAAAAAAMAFwAAAAAA0JkECAAAAAADABgA
+AAAAANiZBAgAAAAAAwAZAAAAAAAAAAAAAAAAAAMAGgAAAAAAAAAAAAAAAAADABsA
+AAAAAAAAAAAAAAAAAwAcAAAAAAAAAAAAAAAAAAMAHQAAAAAAAAAAAAAAAAADAB4A
+AAAAAAAAAAAAAAAAAwAfAAAAAAAAAAAAAAAAAAMAIAAAAAAAAAAAAAAAAAADACEA
+AQAAAAAAAAAAAAAABADx/wwAAACgmAQIAAAAAAEAEgAaAAAAqJgECAAAAAABABMA
+KAAAALCYBAgAAAAAAQAUADUAAACwhAQIAAAAAAIADQBLAAAA2JkECAEAAAABABkA
+WgAAANyZBAgEAAAAAQAZAGgAAAAQhQQIAAAAAAIADQABAAAAAAAAAAAAAAAEAPH/
+dAAAAKSYBAgAAAAAAQASAIEAAACciAQIAAAAAAEAEQCPAAAAsJgECAAAAAABABQA
+mwAAABCHBAgAAAAAAgANALEAAAAAAAAAAAAAAAQA8f++AAAAoJkECAAAAAABABcA
+1AAAAKCYBAgAAAAAAAASAOUAAACgmAQIAAAAAAAAEgD4AAAAtJgECAAAAAABABUA
+AQEAANCZBAgAAAAAIAAYAAwBAAAAAAAAAAAAABIAAAAcAQAAAAAAAAAAAAASAAAA
+LgEAAACHBAgCAAAAEgANAD4BAACAhAQIAAAAABIADQBFAQAAAAAAAAAAAAAgAAAA
+VAEAAAAAAAAAAAAAIAAAAGgBAABYhwQIBAAAABEADwBvAQAAPIcECAAAAAASAA4A
+dQEAAAAAAAAAAAAAEgAAAJIBAAAAAAAAAAAAABIAAACkAQAAXIcECAQAAAARAA8A
+swEAANCZBAgAAAAAEAAYAMABAADUmQQIAAAAABECGADNAQAArJgECAAAAAARAhMA
+2gEAAJCGBAhhAAAAEgANAOoBAAAAAAAAAAAAABIAAAD7AQAA2JkECAAAAAAQAPH/
+BwIAAOCZBAgAAAAAEADx/wwCAAAAAAAAAAAAABIAAAAcAgAAAAAAAAAAAAASAAAA
+LQIAANiZBAgAAAAAEADx/zQCAAAAAAAAAAAAABIAAABEAgAAAocECAAAAAASAg0A
+WwIAADSFBAhcAQAAEgANAGACAACogwQIAAAAABIACwAAY3J0c3R1ZmYuYwBfX0NU
+T1JfTElTVF9fAF9fRFRPUl9MSVNUX18AX19KQ1JfTElTVF9fAF9fZG9fZ2xvYmFs
+X2R0b3JzX2F1eABjb21wbGV0ZWQuNTQ1MgBkdG9yX2lkeC41NDU0AGZyYW1lX2R1
+bW15AF9fQ1RPUl9FTkRfXwBfX0ZSQU1FX0VORF9fAF9fSkNSX0VORF9fAF9fZG9f
+Z2xvYmFsX2N0b3JzX2F1eABmaWxlTG9jay5jcHAAX0dMT0JBTF9PRkZTRVRfVEFC
+TEVfAF9faW5pdF9hcnJheV9lbmQAX19pbml0X2FycmF5X3N0YXJ0AF9EWU5BTUlD
+AGRhdGFfc3RhcnQAb3BlbkBAR0xJQkNfMi4wAGdldHBpZEBAR0xJQkNfMi4wAF9f
+bGliY19jc3VfZmluaQBfc3RhcnQAX19nbW9uX3N0YXJ0X18AX0p2X1JlZ2lzdGVy
+Q2xhc3NlcwBfZnBfaHcAX2ZpbmkAX19saWJjX3N0YXJ0X21haW5AQEdMSUJDXzIu
+MABwZXJyb3JAQEdMSUJDXzIuMABfSU9fc3RkaW5fdXNlZABfX2RhdGFfc3RhcnQA
+X19kc29faGFuZGxlAF9fRFRPUl9FTkRfXwBfX2xpYmNfY3N1X2luaXQAY2xvc2VA
+QEdMSUJDXzIuMABfX2Jzc19zdGFydABfZW5kAHB1dHNAQEdMSUJDXzIuMABmY250
+bEBAR0xJQkNfMi4wAF9lZGF0YQBleGl0QEBHTElCQ18yLjAAX19pNjg2LmdldF9w
+Y190aHVuay5ieABtYWluAF9pbml0AA==
+END
+echo $S 0 | openssl base64 -d
+for var in "$@"
+do
+       #Check if port parameter is present
+    uuid=`echo $var | awk -F',' '{print $1}'`
+    port=`echo $var | awk -F',' '{print $2}'`
+
+    # overwrite any preexisting UUID
+    #sedinput="'/$uuid/d'"
+    #echo $sedinput
+    #sed -i $sedinput $uuidfile
+    #test=`sed '/$uuid/d' $uuidfile`
+    test=`cat $uuidfile | grep -v "$uuid"`
+    #test=`awk '!/$uuid/' $uuidfile`
+    echo $test | sed 's/ /\
+/g' > $uuidfile
+
+       # just for testing script input
+       #echo $@ >> $uuidfile
+
+    #if port exists, test if it is blocked
+    if [ -n "$port" ]
+    then
+        #Test if port number is blocked
+        process=`netstat -nlp | grep $port | awk '{print $7}' | cut -d '/' -f 1`
+
+        # check if port is blocked and find empty port by looping
+        if [ -n "$process" ]; then
+            while [ -n "$process" ]
+            do
+                port=`expr $port + 1`
+                process=`netstat -nlp | grep $port | awk '{print $7}' | cut -d '/' -f 1`
+                var="$uuid,$port"
+            done
+            retval="$retval#$var"
+        fi
+    fi
+
+    echo $var >> $uuidfile
+done
+sed '/^$/d' $uuidfile > $uuidfile.temp && mv $uuidfile.temp $uuidfile
+echo $S 1 | openssl base64 -d
+echo $retval
+
+# OLD SCRIPT FILE BACKUP
+
+#uuidfile="/tmp/tastore/uuidlist.list";
+#rm -f $uuidfile;
+
+#for filename in $(find /tmp/tastore/ -maxdepth 1 -regex ".*/[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]" ! -name "*ext"); do 
+#strip off the complete path, retain only the file names
+#(echo "${filename:13}" >> $uuidfile); 
+#done
diff --git a/ssflib/.cproject b/ssflib/.cproject
new file mode 100755 (executable)
index 0000000..61f06db
--- /dev/null
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+       <storageModule moduleId="org.eclipse.cdt.core.settings">
+               <cconfiguration id="cdt.managedbuild.config.gnu.so.debug.345774484">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.so.debug.345774484" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+                               <externalSettings>
+                                       <externalSetting>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/ssflib"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/ssflib/Debug"/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="ssflib" srcPrefixMapping="" srcRootPath=""/>
+                                       </externalSetting>
+                               </externalSettings>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.so.debug.345774484" name="Debug" parent="cdt.managedbuild.config.gnu.so.debug">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.so.debug.345774484." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.so.debug.724333172" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.so.debug">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.so.debug.1195396167" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.so.debug"/>
+                                                       <builder buildPath="${workspace_loc:/ssflib}/Debug" id="cdt.managedbuild.target.gnu.builder.so.debug.1165963350" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.so.debug"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.292092467" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.cpp.compiler.so.debug.522417419" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.so.debug">
+                                                               <option id="gnu.cpp.compiler.so.debug.option.optimization.level.1175263382" name="Optimization Level" superClass="gnu.cpp.compiler.so.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.so.debug.option.debugging.level.1403018334" name="Debug Level" superClass="gnu.cpp.compiler.so.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.include.paths.1590505986" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/cryptocore/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/include/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/cryptocore/include/base}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/cryptocore/include/middle}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/swdss/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/uci/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.compiler.option.preprocessor.def.90361504" name="Defined symbols (-D)" superClass="gnu.cpp.compiler.option.preprocessor.def" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="_SECOS_SIM_"/>
+                                                                       <listOptionValue builtIn="false" value="__DEBUG__"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.compiler.option.other.other.615383641" name="Other flags" superClass="gnu.cpp.compiler.option.other.other" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.490209281" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.c.compiler.so.debug.1286888053" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.so.debug">
+                                                               <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.so.debug.option.optimization.level.14506067" name="Optimization Level" superClass="gnu.c.compiler.so.debug.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.so.debug.option.debugging.level.1155462764" name="Debug Level" superClass="gnu.c.compiler.so.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.include.paths.1007924686" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/cryptocore/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/include/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/cryptocore/include/base}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/cryptocore/include/middle}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/swdss/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/dep/uci/include}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                               </option>
+                                                               <option id="gnu.c.compiler.option.preprocessor.def.symbols.1387781538" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
+                                                                       <listOptionValue builtIn="false" value="_SECOS_SIM_"/>
+                                                                       <listOptionValue builtIn="false" value="__DEBUG__"/>
+                                                               </option>
+                                                               <option id="gnu.c.compiler.option.dialect.std.1886247567" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.misc.other.67457545" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.698578507" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.so.debug.1055228539" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.so.debug">
+                                                               <option defaultValue="true" id="gnu.c.link.so.debug.option.shared.948414804" name="Shared (-shared)" superClass="gnu.c.link.so.debug.option.shared" valueType="boolean"/>
+                                                       </tool>
+                                                       <tool command="i386-linux-gnueabi-g++" id="cdt.managedbuild.tool.gnu.cpp.linker.so.debug.942692866" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.so.debug">
+                                                               <option defaultValue="true" id="gnu.cpp.link.so.debug.option.shared.1632869434" name="Shared (-shared)" superClass="gnu.cpp.link.so.debug.option.shared" valueType="boolean"/>
+                                                               <option id="gnu.cpp.link.option.flags.784349351" name="Linker flags" superClass="gnu.cpp.link.option.flags" value="-Wl,-init,initializeSSF,-fini,deinitializeSSF -fmessage-length=0 --sysroot=&quot;..\..\..\toolchain\windows\i386-linux-gnueabi-gcc-4.6\lib\gcc\i386-linux-gnueabi\4.6.4&quot;" valueType="string"/>
+                                                               <option id="gnu.cpp.link.option.libs.900894438" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
+                                                                       <listOptionValue builtIn="false" value="boost_thread"/>
+                                                                       <listOptionValue builtIn="false" value="log"/>
+                                                                       <listOptionValue builtIn="false" value="osal"/>
+                                                                       <listOptionValue builtIn="false" value="rt"/>
+                                                               </option>
+                                                               <option id="gnu.cpp.link.option.paths.84119711" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/log/Debug}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/osal/Debug}&quot;"/>
+                                                               </option>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.705649219" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.so.debug.1121001432" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.so.debug">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.603221909" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+               <cconfiguration id="cdt.managedbuild.config.gnu.so.release.1065319080">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.so.release.1065319080" moduleId="org.eclipse.cdt.core.settings" name="Release">
+                               <externalSettings>
+                                       <externalSetting>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/ssflib"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/ssflib/Release"/>
+                                               <entry flags="RESOLVED" kind="libraryFile" name="ssflib" srcPrefixMapping="" srcRootPath=""/>
+                                       </externalSetting>
+                               </externalSettings>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration artifactExtension="so" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.so.release.1065319080" name="Release" parent="cdt.managedbuild.config.gnu.so.release">
+                                       <folderInfo id="cdt.managedbuild.config.gnu.so.release.1065319080." name="/" resourcePath="">
+                                               <toolChain id="cdt.managedbuild.toolchain.gnu.so.release.96914134" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.so.release">
+                                                       <targetPlatform id="cdt.managedbuild.target.gnu.platform.so.release.266292539" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.so.release"/>
+                                                       <builder buildPath="${workspace_loc:/ssflib}/Release" id="cdt.managedbuild.target.gnu.builder.so.release.1803253651" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.so.release"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.archiver.base.762351513" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.so.release.869375115" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.so.release">
+                                                               <option id="gnu.cpp.compiler.so.release.option.optimization.level.794680173" name="Optimization Level" superClass="gnu.cpp.compiler.so.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.so.release.option.debugging.level.330125485" name="Debug Level" superClass="gnu.cpp.compiler.so.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2080244167" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.compiler.so.release.1376863553" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.so.release">
+                                                               <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.so.release.option.optimization.level.871500826" name="Optimization Level" superClass="gnu.c.compiler.so.release.option.optimization.level" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.so.release.option.debugging.level.371571097" name="Debug Level" superClass="gnu.c.compiler.so.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1938486966" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.c.linker.so.release.1547081256" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.so.release">
+                                                               <option defaultValue="true" id="gnu.c.link.so.release.option.shared.1414878287" name="Shared (-shared)" superClass="gnu.c.link.so.release.option.shared" valueType="boolean"/>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.cpp.linker.so.release.975970434" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.so.release">
+                                                               <option defaultValue="true" id="gnu.cpp.link.so.release.option.shared.359295560" name="Shared (-shared)" superClass="gnu.cpp.link.so.release.option.shared" valueType="boolean"/>
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.964570105" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>
+                                                               </inputType>
+                                                       </tool>
+                                                       <tool id="cdt.managedbuild.tool.gnu.assembler.so.release.1714793705" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.so.release">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.748615996" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+               </cconfiguration>
+       </storageModule>
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+               <project id="ssflib.cdt.managedbuild.target.gnu.so.924169997" name="Shared Library" projectType="cdt.managedbuild.target.gnu.so"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.so.release.1065319080;cdt.managedbuild.config.gnu.so.release.1065319080.;cdt.managedbuild.tool.gnu.c.compiler.so.release.1376863553;cdt.managedbuild.tool.gnu.c.compiler.input.1938486966">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.so.debug.345774484;cdt.managedbuild.config.gnu.so.debug.345774484.;cdt.managedbuild.tool.gnu.cpp.compiler.so.debug.522417419;cdt.managedbuild.tool.gnu.cpp.compiler.input.490209281">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.so.release.1065319080;cdt.managedbuild.config.gnu.so.release.1065319080.;cdt.managedbuild.tool.gnu.cpp.compiler.so.release.869375115;cdt.managedbuild.tool.gnu.cpp.compiler.input.2080244167">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+               <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.so.debug.345774484;cdt.managedbuild.config.gnu.so.debug.345774484.;cdt.managedbuild.tool.gnu.c.compiler.so.debug.1286888053;cdt.managedbuild.tool.gnu.c.compiler.input.698578507">
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+               </scannerConfigBuildInfo>
+       </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope"/>
+</cproject>
diff --git a/ssflib/.gitignore b/ssflib/.gitignore
new file mode 100755 (executable)
index 0000000..3df573f
--- /dev/null
@@ -0,0 +1 @@
+/Debug/
diff --git a/ssflib/.project b/ssflib/.project
new file mode 100755 (executable)
index 0000000..ae8262f
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>ssflib</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+                       <triggers>clean,full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+                       <triggers>full,incremental,</triggers>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.cdt.core.cnature</nature>
+               <nature>org.eclipse.cdt.core.ccnature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+       </natures>
+</projectDescription>
diff --git a/ssflib/.settings/org.eclipse.cdt.core.prefs b/ssflib/.settings/org.eclipse.cdt.core.prefs
new file mode 100755 (executable)
index 0000000..5f794a6
--- /dev/null
@@ -0,0 +1,31 @@
+eclipse.preferences.version=1
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/CWD/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/CWD/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/CWD/value=${ProjDirPath}/Debug_Windows
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\Program Files (x86)\\Java\\jre1.8.0_45\\bin;C\:\\Program Files\\eclipse;C\:/Program Files/Java/jre1.8.0_31/bin/server;C\:/Program Files/Java/jre1.8.0_31/bin;C\:/Program Files/Java/jre1.8.0_31/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\csvn\\bin\\;C\:\\csvn\\Python25\\;C\:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files\\Diskeeper Corporation\\ExpressCache\\;C\:\\Program Files (x86)\\Windows Live\\Shared;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\3.0\\bin\\x64;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files (x86)\\WinSCP\\;C\:\\Program Files (x86)\\PuTTY;C\:\\Program Files\\Microsoft\\Web Platform Installer\\;C\:\\Program Files\\Microsoft SQL Server\\110\\Tools\\Binn\\;C\:\\Program Files (x86)\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\Tools\\Binn\\;C\:\\Program Files\\Microsoft SQL Server\\100\\DTS\\Binn\\;C\:\\Program Files (x86)\\doxygen\\bin;C\:\\Program Files (x86)\\sfk168;C\:\\Program Files (x86)\\vlc-2.1.0;C\:\\Python27\\Scripts;C\:\\Program Files (x86)\\GnuWin32\\bin;C\:\\Python27;C\:\\Program Files (x86)\\Subversion\\bin;c\:\\Program Files\\Synergy;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\MinGW\\lib\\gcc\\mingw32\\4.8.1;C\:\\Program Files (x86)\\Windows Kits\\8.1\\Windows Performance Toolkit\\;C\:\\Program Files (x86)\\GitExtensions\\;C\:\\Program Files\\Perforce;c\:\\Program Files\\Java\\jre1.8.0_31\\bin\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;D\:\\samsung-tv-sdk\\ide;D\:\\samsung-tv-sdk\\tasdk_ide\\tasdk_tools\\i386-linux-gnueabi-gcc-4.6\\bin;D\:\\samsung-tv-sdk\\tasdk_ide\\tasdk_tools\\mingw\\bin;D\:\\samsung-tv-sdk\\tasdk_ide\\tasdk_tools\\mingw\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/PWD/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/PWD/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/PWD/value=${ProjDirPath}/Debug_Windows
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/append=true
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484.12338249/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/CWD/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/CWD/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/CWD/value=${ProjDirPath}/Debug_Windows
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/PATH/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/PATH/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/PATH/value=C\:/Program Files/Java/jre1.8.0_45/bin/server;C\:/Program Files/Java/jre1.8.0_45/bin;C\:/Program Files/Java/jre1.8.0_45/lib/amd64;C\:\\ProgramData\\Oracle\\Java\\javapath;C\:\\Program Files (x86)\\AMD APP\\bin\\x86_64;C\:\\Program Files (x86)\\AMD APP\\bin\\x86;C\:\\Program Files (x86)\\Intel\\iCLS Client\\;C\:\\Program Files\\Intel\\iCLS Client\\;C\:\\Windows\\system32;C\:\\Windows;C\:\\Windows\\System32\\Wbem;C\:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\DAL;C\:\\Program Files (x86)\\Intel\\Intel(R) Management Engine Components\\IPT;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C\:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;C\:\\Program Files (x86)\\ATI Technologies\\ATI.ACE\\Core-Static;C\:\\Program Files\\Intel\\WiFi\\bin\\;C\:\\Program Files\\Common Files\\Intel\\WirelessCommon\\;C\:\\Program Files\\TortoiseSVN\\bin;C\:\\Program Files (x86)\\GitExtensions\\;D\:\\Tizen\\tizen-sdk\\tools;D\:\\Android\\android-sdk\\platform-tools;D\:\\Android\\android-ndk-r10c;C\:\\Program Files\\Perforce;D\:\\eclipse\\eclipse-rcp-luna-SR1-win32-x86_64;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\bin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\mingbin;${PWD}\\..\\..\\..\\toolchain\\windows\\i386-linux-gnueabi-gcc-4.6\\msys\\1.0\\bin
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/PWD/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/PWD/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/PWD/value=${ProjDirPath}/Debug_Windows
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/append=true
+environment/project/cdt.managedbuild.config.gnu.so.debug.345774484/appendContributed=true
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/CWD/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/CWD/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/CWD/value=${ProjDirPath}/Release_Windows
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/PWD/delimiter=;
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/PWD/operation=replace
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/PWD/value=${ProjDirPath}/Release_Windows
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/append=true
+environment/project/cdt.managedbuild.config.gnu.so.release.1065319080/appendContributed=true
diff --git a/ssflib/dep/cryptocore/include/CC_API.h b/ssflib/dep/cryptocore/include/CC_API.h
new file mode 100755 (executable)
index 0000000..dd04a73
--- /dev/null
@@ -0,0 +1,243 @@
+/**
+ * \file       CC_API.h
+ * @brief      API of samsung Crypto Library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jae Heung Lee
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/06
+ */
+
+#ifndef _CRYPTOCORE_API_H
+#define _CRYPTOCORE_API_H
+
+#include "CryptoCore.h"
+
+typedef union
+{
+       SDRM_X931Context        *x931ctx;                               //RNG : ANSI X9.31 Context
+       SDRM_MD5Context         *md5ctx;                                //Hash : MD5 Hash Context
+       SDRM_SHA1Context        *sha1ctx;                               //Hash : SHA1 Hash Context
+       SDRM_SHA224Context      *sha224ctx;                             //Hash : SHA224 Hash Context
+       SDRM_SHA256Context      *sha256ctx;                             //Hash : SHA256 Hash Context
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      *sha384ctx;                             //Hash : SHA384 Hash Context
+       SDRM_SHA512Context      *sha512ctx;                             //Hash : SHA512 Hash Context
+#endif //_OP64_NOTSUPPORTED
+       SDRM_CMACContext        *cmacctx;                               //MAC : C-MAC Context
+       SDRM_HMACContext        *hmacctx;                               //MAC : Hash MAC
+       SDRM_DHContext          *dhctx;                                 //Key Exchange : DH Key Exchange Protocol
+       SDRM_ECDHContext        *ecdhctx;                               //Key Exchange : EC-DH Key Exchange Protocol
+       SDRM_AESContext         *aesctx;                                //Symmetric Encryption : AES Encryption Context
+       SDRM_DESContext         *desctx;                                //Symmetric Encryption : DES Encryption Context
+       SDRM_TDESContext        *tdesctx;                               //Symmetric Encryption : Triple DES Encryption Context
+       SDRM_RC4Context         *rc4ctx;                                //Symmetric Encryption : RC4 Encryption Context
+       SDRM_SNOW2Context       *snow2ctx;                              //Symmetric Encryption : SNOW2 Encryption Context
+       SDRM_RSAContext         *rsactx;                                //Asymmetric Encryption and Signature : RSA Context
+       SDRM_DSAContext         *dsactx;                                //Digital Signature : DSA Signature Context
+       SDRM_ECDSAContext       *ecdsactx;                              //Digital Signature : EC-DSA Signature Context
+} CryptoCoreCTX;
+
+
+/**
+ * @brief      Parameter sturcture
+ *
+ * Crypto Library¸¦ ½±°Ô »ç¿ëÇϱâ À§ÇØ  »ç¿ëÇϴ Parameter structure
+ */
+typedef struct _CryptoCoreContainer
+{
+       int alg;                                                                                                                                                                /**<    Algorithm       */
+       CryptoCoreCTX *ctx;                                                                                                                                             /**<    Algorithm       */
+       
+       // Pseudo Random Number Generation (ANSI X9.17)
+       int (*PRNG_seed)  (struct _CryptoCoreContainer *crt, cc_u8 *seed);
+       int (*PRNG_get)   (struct _CryptoCoreContainer *crt, cc_u32 bitlength, cc_u8 *data);
+       
+       // Message Digest (MD5, SHA-1)
+       int (*MD_init)    (struct _CryptoCoreContainer *crt);
+       int (*MD_update)  (struct _CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+       int (*MD_final)   (struct _CryptoCoreContainer *crt, cc_u8 *output);
+       int (*MD_getHASH) (struct _CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+       
+       // Message Authentication Code (CMAC, HMAC MD5, HMAC SHA-1)
+       int (*MAC_init)   (struct _CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen);
+       int (*MAC_update) (struct _CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen);
+       int (*MAC_final)  (struct _CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen);
+       int (*MAC_getMAC) (struct _CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen);
+
+       // Key Exchange (DH, ECDH)
+       int (*DH_GenerateParam)         (struct _CryptoCoreContainer *crt, cc_u8* pPrime, cc_u32 nPrimeLen, cc_u8* pGenerator);
+       int (*DH_SetParam)                      (struct _CryptoCoreContainer *crt, cc_u8* pPrime, cc_u32 nPrimeLen, cc_u8* nGenerator, cc_u32 nGeneratorLen);
+       int (*DH_Gen1stPhaseKey)        (struct _CryptoCoreContainer *crt, cc_u8* pPriv, cc_u8* pPub);
+       int (*DH_GenAuthKey)            (struct _CryptoCoreContainer *crt, cc_u8* pPriv, cc_u8* pPub, cc_u8* pSharedSecret);
+       int (*ECDH_Gen1stPhaseKey)      (struct _CryptoCoreContainer *crt, cc_u8* pDH_Xk, cc_u8* pDH1stPhaseKey);
+       int (*ECDH_GenAuthKey)          (struct _CryptoCoreContainer *crt, cc_u8* pchXk, cc_u8* pchYv, cc_u8* pchKauth);
+       
+       // Symmetric Encryption (DES, 3DES, AES, RC4, SNOW)
+       // mode example : ENC_ECB, DEC_ECB, ENC_CBC, DEC_CBC, ...
+       int (*SE_init)    (struct _CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV);
+       int (*SE_process) (struct _CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+       int (*SE_final)   (struct _CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen);
+       // Simple AES Function
+       int (*SE_EncryptOneBlock)  (cc_u8 *cipherText, cc_u8 *plainText,        cc_u8 *UserKey);
+       int (*SE_DecryptOneBlock)  (cc_u8 *plainText, cc_u8 *cipherText,        cc_u8 *UserKey);
+
+       // Asymmetric Encryption (RSA, Elgamal, EC-Elgamal)
+       int (*AE_encrypt) (struct _CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+       int (*AE_decrypt) (struct _CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+       int (*AE_decryptByCRT) (struct _CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+       
+       // Digital Signature (DSA, EC-DSA)
+       int (*DS_sign)    (struct _CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen);
+       int (*DS_verify)  (struct _CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result);
+       int (*DSA_genParam)(
+               struct _CryptoCoreContainer *crt, cc_u32 T_Siz,
+               cc_u8 *DSA_P_Data, cc_u32 *DSA_P_Len,
+               cc_u8 *DSA_Q_Data, cc_u32 *DSA_Q_Len,
+               cc_u8 *DSA_G_Data, cc_u32 *DSA_G_Len
+       );
+       int (*DSA_setParam)(
+               struct _CryptoCoreContainer *crt,
+               cc_u8 *DSA_P_Data,      cc_u32 DSA_P_Len,
+               cc_u8 *DSA_Q_Data,      cc_u32 DSA_Q_Len,
+               cc_u8 *DSA_G_Data,      cc_u32 DSA_G_Len
+       );
+       int (*DSA_genKeypair)(
+               struct _CryptoCoreContainer *crt,
+               cc_u8 *DSA_Y_Data, cc_u32 *DSA_Y_Len,
+               cc_u8 *DSA_X_Data, cc_u32 *DSA_X_Len
+       );
+       int (*DSA_setKeyPair)(
+               struct _CryptoCoreContainer *crt,
+               cc_u8 *DSA_Y_Data,      cc_u32 DSA_Y_Len,
+               cc_u8 *DSA_X_Data,      cc_u32 DSA_X_Len
+       );
+
+       // RSA Support Functions
+       int (*RSA_genKeypair)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+               cc_u8* RSA_E_Data,   cc_u32 *RSA_E_Len,
+               cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len
+       );
+       int (*RSA_genKeypairWithEforCRT)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+               cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+               cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len,
+               cc_u8* RSA_P_Data,   cc_u32 *RSA_P_Len,
+               cc_u8* RSA_Q_Data,   cc_u32 *RSA_Q_Len,
+               cc_u8* RSA_DP_Data,   cc_u32 *RSA_DP_Len,
+               cc_u8* RSA_DQ_Data,   cc_u32 *RSA_DQ_Len,
+               cc_u8* RSA_QP_Data,   cc_u32 *RSA_QP_Len
+       );
+       int (*RSA_genKeypairWithE)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+               cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+               cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len
+       );
+       int (*RSA_genKeyDWithPQE)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+               cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+               cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+               cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+               cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len
+       );
+       int (*RSA_genKeypairForCRT)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_N_Data, cc_u32 *RSA_N_Len,
+               cc_u8* RSA_E_Data, cc_u32 *RSA_E_Len,
+               cc_u8* RSA_D_Data, cc_u32 *RSA_D_Len,
+               cc_u8* RSA_P_Data, cc_u32 *RSA_P_Len,
+               cc_u8* RSA_Q_Data, cc_u32 *RSA_Q_Len,
+               cc_u8* RSA_DmodP1_Data, cc_u32 *RSA_DmodP1_Len,
+               cc_u8* RSA_DmodQ1_Data, cc_u32 *RSA_DmodQ1_Len,
+               cc_u8* RSA_iQmodP_Data, cc_u32 *RSA_iQmodP_Len
+       );
+
+       int (*RSA_setKeypair)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+               cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+               cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len
+       );
+       int (*RSA_setKeypairForCRT)(
+               struct _CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+               cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+               cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+               cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len,
+               cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+               cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+               cc_u8* RSA_DmodP1_Data,   cc_u32 RSA_DmodP1_Len,
+               cc_u8* RSA_DmodQ1_Data,   cc_u32 RSA_DmodQ1_Len,
+               cc_u8* RSA_iQmodP_Data,   cc_u32 RSA_iQmodP_Len
+       );
+
+       // ECC Support Functions (EC-DSA, EC-Dlgamal)
+       int (*EC_setCurve)(
+               struct _CryptoCoreContainer *crt, cc_u16 Dimension, 
+               cc_u8* ECC_P_Data,   cc_u32 ECC_P_Len,
+               cc_u8* ECC_A_Data,   cc_u32 ECC_A_Len,
+               cc_u8* ECC_B_Data,   cc_u32 ECC_B_Len,
+               cc_u8* ECC_G_X_Data, cc_u32 ECC_G_X_Len,
+               cc_u8* ECC_G_Y_Data, cc_u32 ECC_G_Y_Len,
+               cc_u8* ECC_R_Data,   cc_u32 ECC_R_Len
+       );
+       int (*EC_genKeypair)(
+               struct _CryptoCoreContainer *crt,
+               cc_u8 *PrivateKey,  cc_u32 *PrivateKeyLen, 
+               cc_u8 *PublicKey_X, cc_u32 *PublicKey_XLen,
+               cc_u8 *PublicKey_Y, cc_u32 *PublicKey_YLen
+       );
+       int (*EC_setKeypair)(
+               struct _CryptoCoreContainer *crt,
+               cc_u8* PRIV_Data,  cc_u32 PRIV_Len,
+               cc_u8* PUB_X_Data, cc_u32 PUB_X_Len,
+               cc_u8* PUB_Y_Data, cc_u32 PUB_Y_Len
+       );
+
+} CryptoCoreContainer;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         create_CryptoCoreContainer
+ * @brief      memory allocation and initialize the CryptoCoreContainer sturcture
+ *
+ * @param      algorithm       [in]algorithm want to use
+ *
+ * @return     address of created sturcture
+ */
+CryptoCoreContainer ECRYPTO_API *create_CryptoCoreContainer(cc_u32 algorithm);
+
+/*
+ * @fn         destroy_CryptoCoreContainer
+ * @brief      free allocated memory
+ *
+ * @param      crt             [in]CryptoCoreContainer context
+ *
+ * @return     void
+ */
+void ECRYPTO_API destroy_CryptoCoreContainer(CryptoCoreContainer* crt);
+
+/*
+ * @fn         CCMalloc
+ * @brief      memory allocation and initialize for CryptoCore
+ *
+ * @param      crt             [in]size
+ */
+void ECRYPTO_API *CCMalloc(int siz);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/CC_Constants.h b/ssflib/dep/cryptocore/include/CC_Constants.h
new file mode 100755 (executable)
index 0000000..9195fe3
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+ * \file       CC_Constants.h
+ * @brief      define constants for crypto library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon, Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/09/28
+ * $Id$
+ */
+
+#ifndef _DRM_CONSTANTS_H
+#define _DRM_CONSTANTS_H
+
+#define SDRM_SHIFT_HALF                16                      /**<    common value at both of 32-bit and 64-bit machine       */
+#define SDRM_HIGH_HALF(A)      ((A) >> SDRM_SHIFT_HALF)
+#define SDRM_LOW_HALF(A)       ((A) & ((1 << SDRM_SHIFT_HALF) - 1))
+
+////////////////////////////////////////////////////////////////////////////
+// Algorithm Identifier
+////////////////////////////////////////////////////////////////////////////
+enum CryptoAlgorithm {
+       /*!     @brief  RNG Module      */
+       ID_X931                                                         = 1011,
+
+       /*!     @brief  Hash Algorithms */
+       ID_MD5                                                          = 1021,
+       ID_SHA1                                                         = 1022,
+       ID_SHA160                                                       = 1022,
+       ID_SHA256                                                       = 1023,
+#ifndef _OP64_NOTSUPPORTED
+       ID_SHA384                                                       = 1024,
+       ID_SHA512                                                       = 1025,
+#endif //_OP64_NOTSUPPORTED
+       ID_SHA224                                                       = 1026,
+
+       /*!     @brief  MAC Algorithms  */
+       ID_CMAC                                                         = 1031,
+       ID_HMD5                                                         = 1032,
+       ID_HSHA1                                                        = 1033,
+       ID_HSHA160                                                      = 1033,
+       ID_HSHA256                                                      = 1034,
+#ifndef _OP64_NOTSUPPORTED
+       ID_HSHA384                                                      = 1035,
+       ID_HSHA512                                                      = 1036,
+#endif //_OP64_NOTSUPPORTED
+       ID_HSHA224                                                      = 1037,
+
+       /*!     @brief  Symmetric Encryption Algorithms */
+       ID_AES                                                          = 1041,
+       ID_AES128                                                       = 1041,
+       ID_AES192                                                       = 1047,
+       ID_AES256                                                       = 1048,
+       ID_DES                                                          = 1042,
+       ID_TDES                                                         = 1043,
+       ID_TDES_EDE2                                            = 1043,
+       ID_TDES_EDE3                                            = 1044,
+       ID_RC4                                                          = 1045,
+       ID_SNOW2                                                        = 1046,
+
+       /*!     @brief  Asymmetric Encryption Algorithms        */
+       ID_RSA                                                          = 1051,
+       ID_RSA512                                                       = 1057,
+       ID_RSA1024                                                      = 1054,
+       ID_RSA2048                                                      = 1055,
+       ID_RSA3072                                                      = 1056,
+       ID_ELGAMAL                                                      = 1052,
+       ID_ECELGAMAL                                            = 1053,
+
+       /*!     @brief  Signature Algorithms    */
+       ID_DSA                                                          = 1061,
+       ID_ECDSA                                                        = 1062,
+
+       /*!     @brief  Key Exchange Algorithms */
+       ID_DH                                                           = 1071,
+       ID_ECDH                                                         = 1072,
+
+       /*!     @brief  Encryption/Decryption Mode of Operations        */
+       ID_ENC_ECB                                                      = 1111,
+       ID_ENC_CBC                                                      = 1112,
+       ID_ENC_CFB                                                      = 1113,
+       ID_ENC_OFB                                                      = 1114,
+       ID_ENC_CTR                                                      = 1115,
+
+       ID_DEC_ECB                                                      = 1121,
+       ID_DEC_CBC                                                      = 1122,
+       ID_DEC_CFB                                                      = 1123,
+       ID_DEC_OFB                                                      = 1124,
+       ID_DEC_CTR                                                      = 1125,
+
+       /*!     @brief  Symmetric Encryption/Decryption Padding Methods         */
+       ID_PKCS5                                                        = 1201,
+       ID_SSL_PADDING                                          = 1202,
+       ID_ZERO_PADDING                                         = 1203,
+       ID_NO_PADDING                                           = 1204,
+
+       /*!     @brief  Asymmetric Encryption/Decryption Padding Methods        */
+       ID_RSAES_PKCS15                                         = 1131,
+
+       ID_RSAES_OAEP                                           = 1132,
+       ID_RSAES_OAEP_MD5                                       = ID_RSAES_OAEP + (ID_MD5 << SDRM_SHIFT_HALF),
+       ID_RSAES_OAEP_SHA1                                      = ID_RSAES_OAEP + (ID_SHA1 << SDRM_SHIFT_HALF),
+       ID_RSAES_OAEP_SHA160                            = ID_RSAES_OAEP + (ID_SHA160 << SDRM_SHIFT_HALF),
+       ID_RSAES_OAEP_SHA224                            = ID_RSAES_OAEP + (ID_SHA224 << SDRM_SHIFT_HALF),
+       ID_RSAES_OAEP_SHA256                            = ID_RSAES_OAEP + (ID_SHA256 << SDRM_SHIFT_HALF),
+#ifndef _OP64_NOTSUPPORTED
+       ID_RSAES_OAEP_SHA384                            = ID_RSAES_OAEP + (ID_SHA384 << SDRM_SHIFT_HALF),
+       ID_RSAES_OAEP_SHA512                            = ID_RSAES_OAEP + (ID_SHA512 << SDRM_SHIFT_HALF),
+#endif
+
+       ID_RSASSA_PKCS15                                        = 1133,
+       ID_RSASSA_PKCS15_MD5                            = ID_RSASSA_PKCS15 + (ID_MD5 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PKCS15_SHA1                           = ID_RSASSA_PKCS15 + (ID_SHA1 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PKCS15_SHA160                         = ID_RSASSA_PKCS15 + (ID_SHA160 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PKCS15_SHA224                         = ID_RSASSA_PKCS15 + (ID_SHA224 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PKCS15_SHA256                         = ID_RSASSA_PKCS15 + (ID_SHA256 << SDRM_SHIFT_HALF),
+#ifndef _OP64_NOTSUPPORTED
+       ID_RSASSA_PKCS15_SHA384                         = ID_RSASSA_PKCS15 + (ID_SHA384 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PKCS15_SHA512                         = ID_RSASSA_PKCS15 + (ID_SHA512 << SDRM_SHIFT_HALF),
+#endif
+
+       ID_RSASSA_PSS                                           = 1134,
+       ID_RSASSA_PSS_MD5                                       = ID_RSASSA_PSS + (ID_MD5 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PSS_SHA1                                      = ID_RSASSA_PSS + (ID_SHA1 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PSS_SHA160                            = ID_RSASSA_PSS + (ID_SHA160 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PSS_SHA224                            = ID_RSASSA_PSS + (ID_SHA224 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PSS_SHA256                            = ID_RSASSA_PSS + (ID_SHA256 << SDRM_SHIFT_HALF),
+#ifndef _OP64_NOTSUPPORTED
+       ID_RSASSA_PSS_SHA384                            = ID_RSASSA_PSS + (ID_SHA384 << SDRM_SHIFT_HALF),
+       ID_RSASSA_PSS_SHA512                            = ID_RSASSA_PSS + (ID_SHA512 << SDRM_SHIFT_HALF)
+#endif
+};
+
+////////////////////////////////////////////////////////////////////////////
+// Constants Definitions
+////////////////////////////////////////////////////////////////////////////
+/*!    @brief  Endianness      */
+#define CRYPTO_LITTLE_ENDIAN                   0
+#define CRYPTO_BIG_ENDIAN                              1
+
+////////////////////////////////////////////////////////////////////////////
+// Crypto Error Code
+////////////////////////////////////////////////////////////////////////////
+#define CRYPTO_SUCCESS                                 0                               /**<    no error is occured     */
+#define CRYPTO_ERROR                                   -3000                   /**<    error is occured        */
+#define CRYPTO_MEMORY_ALLOC_FAIL               -3001                   /**<    malloc is failed        */
+#define CRYPTO_NULL_POINTER                            -3002                   /**<    parameter is null pointer       */
+#define CRYPTO_INVALID_ARGUMENT                        -3003                   /**<    argument is not correct */
+#define CRYPTO_MSG_TOO_LONG                            -3004                   /**<    length of input message is too long     */
+#define CRYPTO_VALID_SIGN                              CRYPTO_SUCCESS  /**<    valid sign      */
+#define CRYPTO_INVALID_SIGN                            -3011                   /**<    invalid sign    */
+#define CRYPTO_ISPRIME                                 CRYPTO_SUCCESS  /**<    prime number    */
+#define CRYPTO_INVERSE_NOT_EXIST               -3012                   /**<    inverse is no exists    */
+#define CRYPTO_NEGATIVE_INPUT                  -3013                   /**<    argument is negative    */
+#define CRYPTO_INFINITY_INPUT                  -3014                   /**<    input is infinity       */
+#define CRYPTO_BUFFER_TOO_SMALL                        -3015                   /**<    buffer to small */
+
+#endif
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/CC_Context.h b/ssflib/dep/cryptocore/include/CC_Context.h
new file mode 100755 (executable)
index 0000000..6d37833
--- /dev/null
@@ -0,0 +1,387 @@
+/**
+ * \file       CC_Context.h
+ * @brief      context definitions for samsung Crypto Library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon, Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/07
+ */
+
+#ifndef _DRM_CONTEXT_H
+#define _DRM_CONTEXT_H
+
+#include "CC_Type.h"
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for Big Number Operation
+////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief      Big number structure
+ *
+ * used for big number representation
+ */
+typedef struct {                                               
+       cc_u32 sign;                                            /**<    0 for positive, 1 for negative number   */
+       cc_u32 Length;                                          /**<    number of valid integers                                */
+       cc_u32 Size;                                            /**<    unsigned long size of allocated memory  */
+       cc_u32 *pData;                                          /**<    unsigned long array                                     */
+} SDRM_BIG_NUM;
+
+/**
+ * @brief      Parameter sturcture
+ *
+ * Montgomery ¾Ë°í¸®ÁòÀ» »ç¿ëÇϱâ À§ÇØ »ç¿ëÇϴ Parameter structure
+ */
+typedef struct {                                               /**<    Structure to keep parameters for Montgomery     */
+       cc_u32  ri;                                                     /**<    Length of Modulus                                                       */
+       SDRM_BIG_NUM    *R;                                     /**<    R^2 mod m                                                                       */
+       SDRM_BIG_NUM    *Mod;                           /**<    modulus                                                                         */
+       SDRM_BIG_NUM    *Inv_Mod;                       /**<    Inverse of Modulus                                                      */
+       cc_u32  N0;                                                     /**<    m'                                                                                      */
+} SDRM_BIG_MONT;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for Elliptic Curve Crypto System
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_ECC_BN_BUFSIZE                    19                              //allows max 256 bit curve(uint32_len * 2 + 3)
+#define SDRM_ECC_ALLOC_SIZE                    (sizeof(SDRM_BIG_NUM) + SDRM_ECC_BN_BUFSIZE * SDRM_SIZE_OF_DWORD)
+
+/**
+ * @brief      EC Point structure
+ *
+ * used for representation of one point at ECC curve
+ */
+typedef struct {
+               cc_u32                  IsInfinity;             /**<    if infinity , then 1  else 0            */
+               SDRM_BIG_NUM    *x;                             /**<    prime(1024 + 128i bits i=0..8)          */
+               SDRM_BIG_NUM    *y;                             /**<    subprime(128 + 32j bits j=0..4)         */
+               SDRM_BIG_NUM    *z;
+               SDRM_BIG_NUM    *z2;
+               SDRM_BIG_NUM    *z3;
+} SDRM_EC_POINT;
+
+/**
+ * @brief      ECC Context structure
+ *
+ * used for parameters for ECC curve
+ */
+typedef struct {
+               cc_u32                          uDimension;             /**<    Dimension                       */
+               SDRM_BIG_NUM            *ECC_p;                 /**<    GF(p)                           */
+               SDRM_BIG_NUM            *ECC_a;                 /**<    y^2 = x^3 + ax + b      */
+               SDRM_BIG_NUM            *ECC_b;
+               SDRM_BIG_NUM            *ECC_n;                 /**<    order of base point     */
+               SDRM_EC_POINT           *ECC_G;                 /**<    Base point                      */
+               SDRM_BIG_NUM            *PRIV_KEY;              /**<    private key                     */
+               SDRM_EC_POINT           *PUBLIC_KEY; 
+} SDRM_ECC_CTX;
+
+typedef SDRM_ECC_CTX           SDRM_ECDSAContext;
+typedef SDRM_ECC_CTX           SDRM_ECELContext;
+typedef SDRM_ECC_CTX           SDRM_ECDHContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for ANSI X9.31 PRNG
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_X931_SEED_SIZ             16
+
+/**
+ * @brief      X931 Context structure
+ *
+ * used for maintain seed vaule for random number generation
+ */
+typedef struct {
+       cc_u8 Seed[SDRM_X931_SEED_SIZ];                 /**<    Seed                    */
+} SDRM_X931Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for AES-128
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_AES_BLOCK_SIZ     16
+
+/**
+ * @brief      AES Context structure
+ *
+ * used for aes parameters
+ */
+typedef struct {
+       cc_u32  moo;                                                    /**<    mode of operations              */
+       cc_u32  padding;                                                /**<    padding method                  */
+       cc_u8   IV[SDRM_AES_BLOCK_SIZ];                 /**<    Initial Vector                  */
+       cc_u8   Block[SDRM_AES_BLOCK_SIZ];              /**<    remained msg block              */
+       cc_u32  BlockLen;                                               /**<    length of Block                 */
+       cc_u8   RoundKey[16*(14 + 1)];                  /**<    round key                               */
+       cc_u32  CTR_Count;                                              /**<    counter for CTR mode    */
+} SDRM_AESContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for SHA-1
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_SHA1_BLOCK_SIZ            20
+#define SDRM_SHA1_DATA_SIZE            64
+/**
+ * @brief      SHA1 Context structure
+ *
+ * used for SHA1 parameters
+ */
+typedef struct {
+       cc_u32 digest[SDRM_SHA1_BLOCK_SIZ / 4];         /**<    Message digest          */
+       cc_u32 countLo, countHi;                                        /**<    64-bit bit count        */
+       cc_u32 data[16];                                                        /**<    SHS data buffer         */
+       int Endianness;
+} SDRM_SHA1Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for SHA-256
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_SHA256_BLOCK_SIZ          32
+#define SDRM_SHA256_DATA_SIZE          (512 / 8)
+/**
+ * @brief      SHA256 Context structure
+ *
+ * used for SHA256 parameters
+ */
+typedef struct {
+    cc_u32 tot_len;
+    cc_u32 len;
+    cc_u8 block[2 * SDRM_SHA256_DATA_SIZE];
+    cc_u32 h[8];
+} SDRM_SHA256Context;
+
+#ifndef _OP64_NOTSUPPORTED
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for SHA-384
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_SHA384_BLOCK_SIZ          48
+#define SDRM_SHA384_DATA_SIZE          (1024 / 8)
+/**
+ * @brief      SHA384 Context structure
+ *
+ * used for SHA384 parameters
+ */
+typedef struct {
+    cc_u32 tot_len;
+    cc_u32 len;
+    cc_u8 block[2 * SDRM_SHA384_DATA_SIZE];
+    cc_u64 h[8];
+} SDRM_SHA384Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for SHA-512
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_SHA512_BLOCK_SIZ          64
+#define SDRM_SHA512_DATA_SIZE          SDRM_SHA384_DATA_SIZE
+/**
+ * @brief      SHA512 Context structure
+ *
+ * used for SHA512 parameters
+ */
+typedef SDRM_SHA384Context SDRM_SHA512Context;
+
+#endif //_OP64_NOTSUPPORTED
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for SHA-224
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_SHA224_BLOCK_SIZ          28
+#define SDRM_SHA224_DATA_SIZE          SDRM_SHA256_DATA_SIZE
+/**
+ * \brief      SHA224 Context structure
+ *
+ * used for SHA224 parameters
+ */
+typedef SDRM_SHA256Context SDRM_SHA224Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for MD5
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_MD5_BLOCK_SIZ             16
+#define SDRM_MD5_DATA_SIZE             64
+/**
+ * @brief      MD5 Context structure
+ *
+ * used for MD5 parameters
+ */
+typedef struct {
+       cc_u32  state[4];                                                       /**<    state *ABCD                                                             */
+       cc_u32  count[2];                                                       /**<    number of bits, modulo 2^64 (lsb first) */
+       cc_u8   buffer[64];                                                     /**<    input buffer                                                    */
+} SDRM_MD5Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for C-MAC Generation
+////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief      C-MAC Context structure
+ *
+ * used for aes parameters
+ */
+typedef struct {
+       cc_u8   IV[SDRM_AES_BLOCK_SIZ];                 /**<    Initial Vector          */
+       cc_u8   Block[SDRM_AES_BLOCK_SIZ];              /**<    remained msg block      */
+       cc_u32  BlockLen;                                                       /**<    length of Block         */
+       cc_u8   K1[SDRM_AES_BLOCK_SIZ];
+       cc_u8   K2[SDRM_AES_BLOCK_SIZ];
+       cc_u8   RoundKey[16*(10 + 1)];
+} SDRM_CMACContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for H-MAC Generation
+////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief      C-MAC Context structure
+ *
+ * used for aes parameters
+ */
+typedef struct {
+       cc_u32                          algorithm;                              /**<    algorithm                       */
+       SDRM_SHA1Context        *sha1_ctx;                              /**<    SHA-160 context         */
+       SDRM_SHA224Context      *sha224_ctx;                    /**<    SHA-224 context         */
+       SDRM_SHA256Context      *sha256_ctx;                    /**<    SHA-256 context         */
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      *sha384_ctx;                    /**<    SHA-384 context         */
+       SDRM_SHA512Context      *sha512_ctx;                    /**<    SHA-512 context         */
+#endif //_OP64_NOTSUPPORTED
+       SDRM_MD5Context         *md5_ctx;                               /**<    MD5 context                     */
+
+       cc_u32                          B;
+       cc_u8                           *k0;
+} SDRM_HMACContext;
+
+////////////////////////////////////////////////////////////////////
+// constant & context for RSA
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_RSA_BN_BUFSIZE            (RSA_KeyByteLen / 2 + 1)
+#define SDRM_RSA_ALLOC_SIZE            (sizeof(SDRM_BIG_NUM) + SDRM_RSA_BN_BUFSIZE * SDRM_SIZE_OF_DWORD)
+
+/**
+ * @brief      RSA Context structure
+ *
+ * used for rsa parameters
+ */
+typedef struct {
+       SDRM_BIG_NUM* n;                                        /**<    n value         */
+       SDRM_BIG_NUM* e;                                        /**<    public key      */
+       SDRM_BIG_NUM* d;                                        /**<    private key     */
+       SDRM_BIG_NUM* p;                                        /**<    p                       */
+       SDRM_BIG_NUM* q;                                        /**<    q                       */
+       SDRM_BIG_NUM* dmodp1;                           /**<    d mod p-1       */
+       SDRM_BIG_NUM* dmodq1;                           /**<    d mod q-1       */
+       SDRM_BIG_NUM* iqmodp;                           /**<    q^-1 mod p      */
+
+       cc_u32  crt_operation;                          /**<    CRT Algorithm indicator */
+       cc_u32  k;                                                      /**<    byte-length of n        */
+       cc_u32  pm;                                                     /**<    padding method          */
+       cc_u32  hash_algorithm;                         /**<    used hash algorithm for pkcs padding    */
+} SDRM_RSAContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for DSA
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_DSA_BN_BUFSIZE                    (128 / 2 + 1)
+#define SDRM_DSA_ALLOC_SIZE                    (sizeof(SDRM_BIG_NUM) + SDRM_DSA_BN_BUFSIZE * SDRM_SIZE_OF_DWORD)
+
+/**
+ * @brief      Parameter sturcture
+ *
+ * used for DSA parameters
+ */
+typedef struct {
+       SDRM_BIG_NUM* p;                                        /**<    'p' value - prime modulus       */
+       SDRM_BIG_NUM* q;                                        /**<    'q' value - prime Divisor       */
+       SDRM_BIG_NUM* al;                                       /**<    'alpha' value - generator       */
+       SDRM_BIG_NUM* y;                                        /**<    'y' value - public key          */
+       SDRM_BIG_NUM* a;                                        /**<    'a' value - private key         */
+} SDRM_DSAContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for RC4
+////////////////////////////////////////////////////////////////////////////
+typedef struct {
+       cc_u32 keyLen;
+
+       cc_u32  i;
+       cc_u32  j;
+
+       cc_u8   s[256];
+       cc_u8   key[32];
+} SDRM_RC4Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for SNOW2
+////////////////////////////////////////////////////////////////////////////
+typedef struct {
+       cc_u32  s[16];
+       cc_u32  r1;
+       cc_u32  r2;
+       cc_u32  keyStream;
+       cc_u32  usedKeyLen;
+
+       cc_u32  t;
+       cc_u32  endian;                                 //0 if little endian, 1 if bigendian
+
+} SDRM_SNOW2Context;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for DES
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_DES_BLOCK_SIZ     8
+
+/**
+ * @brief      DES Context structure
+ *
+ * used for aes parameters
+ */
+typedef struct {
+       cc_u32  moo;                                                    //mode of operations
+       cc_u32  padding;
+       cc_u8   IV[SDRM_DES_BLOCK_SIZ];                         //Initial Vector
+       cc_u8   UserKey[SDRM_DES_BLOCK_SIZ];
+       cc_u8   Block[SDRM_DES_BLOCK_SIZ];
+       cc_u32  BlockLen;
+       cc_u32  RoundKey[16][2];                                //each round key, expanded
+       cc_u32  CTR_Count;
+} SDRM_DESContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for Triple DES
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_TDES_BLOCK_SIZ    SDRM_DES_BLOCK_SIZ
+
+/**
+ * @brief      DES Context structure
+ *
+ * used for aes parameters
+ */
+typedef struct {
+       cc_u32  moo;                                                    //mode of operations
+       cc_u32  padding;
+       cc_u8   IV[SDRM_DES_BLOCK_SIZ];                         //Initial Vector
+       cc_u8   UserKey[SDRM_DES_BLOCK_SIZ * 3];
+       cc_u8   Block[SDRM_DES_BLOCK_SIZ];
+       cc_u32  BlockLen;
+       cc_u32  RoundKey[48][2];                                //each round key, expanded
+       cc_u32  CTR_Count;
+} SDRM_TDESContext;
+
+////////////////////////////////////////////////////////////////////////////
+// constant & context for Deffie-Hellman protocol
+////////////////////////////////////////////////////////////////////////////
+/**
+ * @brief      Diffie-Hellman Context structure
+ *
+ * used for dh parameters
+ */
+typedef struct {
+       unsigned int PrimeLen;                          /**<    length of prime */
+       SDRM_BIG_NUM* p;                                        /**<    Prime                   */
+       SDRM_BIG_NUM* g;                                        /**<    generator               */
+} SDRM_DHContext;
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/CC_Type.h b/ssflib/dep/cryptocore/include/CC_Type.h
new file mode 100755 (executable)
index 0000000..1de5240
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * \file       CC_Type.h
+ * @brief      data types for CryptoCore library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2008/08/26
+ */
+
+#ifndef _CC_TYPE_H_
+#define _CC_TYPE_H_
+
+/*!    @brief  1-byte data type        */
+typedef                unsigned char                                           cc_u8;
+
+/*!    @brief  2-byte data type        */
+typedef                unsigned short                                          cc_u16;
+
+/*!    @brief  4-byte data type        */
+typedef                unsigned int                                            cc_u32;
+
+#ifndef _OP64_NOTSUPPORTED
+
+/*!    @brief  8-byte data type        */
+#ifdef _WIN32
+       typedef         unsigned __int64                                cc_u64;
+#else
+       typedef         unsigned long long                              cc_u64;
+#endif         //_WIN32
+
+#endif         //_OP64_NOTSUPPORTED
+
+#endif         //_CC_TYPE_H_
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/CryptoCore.h b/ssflib/dep/cryptocore/include/CryptoCore.h
new file mode 100755 (executable)
index 0000000..0b50f13
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * \file       CryptoCore.h
+ * @brief      main header file of crypto library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : 
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/02
+ */
+
+#ifndef _CRYPTOCORE_H
+#define _CRYPTOCORE_H
+
+#ifdef _USRDLL
+       #if defined(CRYPTOLIB_EXPORTS)
+               #define ECRYPTO_API __declspec(dllexport)
+       #elif defined(CRYPTOLIB_IMPORTS)
+               #define ECRYPTO_API __declspec(dllimport)
+       #else
+               #define ECRYPTO_API
+       #endif
+#else
+       #define ECRYPTO_API
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+// Header File Include
+////////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include <string.h>
+#include "CC_Type.h"
+#include "drm_macro.h"
+#include "CC_Constants.h"
+#include "CC_Context.h"
+
+#ifdef _WIN32_WCE
+       #include <Winbase.h>
+#else
+       #include <time.h>
+#endif
+
+////////////////////////////////////////////////////////////////////////////
+// Global Variable
+////////////////////////////////////////////////////////////////////////////
+
+#endif
+
+/***************************** End of File *****************************/
+
diff --git a/ssflib/dep/cryptocore/include/base/cc_ANSI_x931.h b/ssflib/dep/cryptocore/include/base/cc_ANSI_x931.h
new file mode 100755 (executable)
index 0000000..4353322
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * \file       ANSI_x931.h
+ * @brief      Pseudorandom number generator based on a design described in ANSI X9.31
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Junbum Shin
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/23
+ */
+
+
+#ifndef _CCANSI_X931_H
+#define _CCANSI_X931_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <time.h>
+#include "CryptoCore.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_RNG_X931   
+ * @brief      generate random number with seed
+ *
+ * @param      Seed                            [in]seed for RNG System
+ * @param      bitLength                       [in]bit length of data to generate
+ * @param      data                            [out]generated data
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ */
+int    SDRM_RNG_X931(cc_u8 *Seed, cc_u32 bitLength, cc_u8 *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_aes.h b/ssflib/dep/cryptocore/include/base/cc_aes.h
new file mode 100755 (executable)
index 0000000..d969f74
--- /dev/null
@@ -0,0 +1,171 @@
+/**
+ * rijndael-alg-fst.h
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CCAES_H
+#define _CCAES_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_rijndaelKeySetupEnc
+ * @brief      Expand the cipher key into the encryption key schedule
+ *
+ * @param      rk                                      [out]expanded round key
+ * @param      cipherKey                       [in]user key
+ * @param      keyBits                         [in]bit-length of cipherKey
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_rijndaelKeySetupEnc(cc_u32 rk[/*4*(Nr + 1)*/], const cc_u8 cipherKey[], int keyBits);
+
+/*
+ * @fn         SDRM_rijndaelKeySetupDec
+ * @brief      Expand the cipher key into the decryption key schedule
+ *
+ * @param      rk                                      [out]expanded round key
+ * @param      cipherKey                       [in]user key
+ * @param      keyBits                         [in]bit-length of cipherKey
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_rijndaelKeySetupDec(cc_u32 rk[/*4*(Nr + 1)*/], const cc_u8 cipherKey[], int keyBits);
+
+/*
+ * @fn         SDRM_rijndaelEncrypt
+ * @brief      16 byte AES Encryption with round key
+ *
+ * @param      rk                                      [in]expanded round key
+ * @param      Nr                                      [in]numer of rounds
+ * @param      pt                                      [in]plain text
+ * @param      ct                                      [out]cipher text
+ *
+ * @return     void
+ */
+void SDRM_rijndaelEncrypt(const cc_u32 rk[/*4*(Nr + 1)*/], int Nr, const cc_u8 pt[16], cc_u8 ct[16]);
+
+/*
+ * @fn         SDRM_rijndaelDecrypt
+ * @brief      16 byte AES Decryption with round key
+ *
+ * @param      rk                                      [in]expanded round key
+ * @param      Nr                                      [in]numer of rounds
+ * @param      ct                                      [in]cipher text
+ * @param      pt                                      [out]plain text
+ *
+ * @return     void
+ */
+void SDRM_rijndaelDecrypt(const cc_u32 rk[/*4*(Nr + 1)*/], int Nr, const cc_u8 ct[16], cc_u8 pt[16]);
+
+/*
+ * @fn         SDRM_AES128_Encryption
+ * @brief      AES-128 Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES128_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey);
+
+/*
+ * @fn         SDRM_AES128_Decryption
+ * @brief      AES-128 Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES128_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey);
+
+/*
+ * @fn         SDRM_AES192_Encryption
+ * @brief      AES-192 Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES192_Encryption(cc_u8 *cipherText, cc_u8 *plainText,        cc_u8 *UserKey);
+
+/*
+ * @fn         SDRM_AES192_Decryption
+ * @brief      AES-192 Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES192_Decryption(cc_u8 *plainText, cc_u8 *cipherText,        cc_u8 *UserKey);
+
+/*
+ * @fn         SDRM_AES256_Encryption
+ * @brief      AES-256 Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES256_Encryption(cc_u8 *cipherText, cc_u8 *plainText,        cc_u8 *UserKey);
+
+/*
+ * @fn         SDRM_AES256_Decryption
+ * @brief      AES-256 Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES256_Decryption(cc_u8 *plainText, cc_u8 *cipherText,        cc_u8 *UserKey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_bignum.h b/ssflib/dep/cryptocore/include/base/cc_bignum.h
new file mode 100755 (executable)
index 0000000..57dc235
--- /dev/null
@@ -0,0 +1,697 @@
+/**
+ * \file       bignum.h
+ * @brief      big number library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/03
+ */
+
+
+#ifndef _CCBIGNUM_H
+#define _CCBIGNUM_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Parameters and Bit-wise Macros
+////////////////////////////////////////////////////////////////////////////
+/*!    @brief  byte-length of single cc_u32    */
+#define SDRM_SIZE_OF_DWORD                     4
+/*!    @brief  bit-length of single cc_u32     */
+#define SDRM_BitsInDWORD                       (8 * SDRM_SIZE_OF_DWORD)
+/*!    @brief  num_hex_simbols of single cc_u32        */
+#define SDRM_SIZE_BLOCK                                (2 * SDRM_SIZE_OF_DWORD)
+
+/*!    @brief  get k-th bit form cc_u32 array A        */
+#define SDRM_CheckBitUINT32(A, k)      (0x01 & ((A)[(k) >> 5] >> ((k) & 31)))
+
+/*!    @brief  get k-th byte from cc_u32 array A       */
+#define SDRM_CheckByteUINT32(A, k)     (cc_u8)(0xff & (A[(k) >> 2] >> (((k) & 3 ) << 3)))
+#define SDRM_isEven0(X)                                (((X)[0] & 0x01) == 0)
+#define SDRM_isOdd0(X)                         (((X)[0] & 0x01) == 1)
+
+/*!    @brief  increase 1 from Byte Array A, byte-length of B  */
+#define SDRM_INC_BA(A, B)                      do {                                                                                    \
+                                                                               for (i = 0; i < (B); i++) {                                     \
+                                                                                       if (++A[i] != 0) break;                                 \
+                                                                               }                                                                                       \
+                                                                       } while(0)                                                                              \
+
+////////////////////////////////////////////////////////////////////////////
+// MACROs for cc_u32 Evaluation
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_DIGIT_Mul(Dest, Src1, Src2)
+ * @brief      Double-width UINT32 Multiplication
+ * @param      Dest            [out]destination, 2-cc_u32-size array
+ * @param      Src1            [in]first element
+ * @param      Src2            [in]second element
+ *
+ * @return     void
+ */
+#ifndef _OP64_NOTSUPPORTED
+#define SDRM_DIGIT_Mul(Dest, Src1, Src2)       do {                                                                                                                                            \
+                                                                                               (Dest)[0] = (cc_u32) ((cc_u64)(Src1) * (Src2));                                                 \
+                                                                                               (Dest)[1] = (cc_u32)(((cc_u64)(Src1) * (Src2)) >> SDRM_BitsInDWORD);    \
+                                                                                       } while(0)
+#else
+void SDRM_DIGIT_Mul(cc_u32 *Dest, cc_u32 Src1, cc_u32 Src2);
+#endif
+
+/*
+ * @fn         SDRM_DIGIT_Div(Src1, Src2, Div)
+ * @brief      Doublue-width DWROD Division
+ *
+ * @param      Src1            [in]upper-digit of dividend
+ * @param      Src2            [in]lower-digit of dividend
+ * @param      Div                     [in]divisor
+ */
+#ifndef _OP64_NOTSUPPORTED
+#define SDRM_DIGIT_Div(Src1, Src2, Div)        (cc_u32)((((cc_u64)(Src1) << SDRM_BitsInDWORD) ^ (Src2)) / (Div))
+#else
+cc_u32 SDRM_DIGIT_Div(cc_u32 Src1, cc_u32 Src2, cc_u32 Div);
+#endif
+
+/*
+ * @fn         SDRM_DIGIT_Mod(Src1, Src2, Div)
+ * @brief      Doublue-width DWROD Modular
+ *
+ * @param      Src1            [in]upper-digit of dividend
+ * @param      Src2            [in]lower-digit of dividend
+ * @param      Div                     [in]divisor
+ */
+#ifndef _OP64_NOTSUPPORTED
+#define SDRM_DIGIT_Mod(Src1, Src2, Div)        (cc_u32)((((cc_u64)(Src1) << SDRM_BitsInDWORD) ^ (Src2)) % (Div))
+#else
+cc_u32 SDRM_DIGIT_Mod(cc_u32 Src1, cc_u32 Src2, cc_u32 Div);
+#endif
+
+/*
+ * @fn         SDRM_DWD_Copy(Dest, Src, Size)
+ * @brief      Copy Digit Array
+ *
+ * @param      Dest            [in]destination, cc_u32 array
+ * @param      Src                     [in]source, cc_u32 array
+ * @param      Size            [in]length of dSrc
+ */
+#define SDRM_DWD_Copy(Dest, Src, Size) do {                                                                                            \
+                                                                                       memcpy(Dest, Src, SDRM_SIZE_OF_DWORD * Size);   \
+                                                                               } while(0)
+
+////////////////////////////////////////////////////////////////////////////
+// MACROs for Big Number
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_BN_IS_ODD(a)
+ * @brief      check big number a is an odd number     
+ */
+#define SDRM_BN_IS_ODD(a)                      ((a)->pData[0] & 1)
+
+/*
+ * @fn         SDRM_BN_FREE(X)
+ * @brief      free allocated memory   
+ */
+#define SDRM_BN_FREE(X)                                do {if (X) free(X);} while(0)
+
+/*     
+ * @fn         SDRM_BN_OPTIMIZE_LENGTH(BN
+ * @brief      optimize SDRM_BIG_NUM's length member   
+ */
+#define SDRM_BN_OPTIMIZE_LENGTH(BN)    do {                                                                                                                    \
+                                                                               while((BN)->Length > 0)                                                                         \
+                                                                                       if((BN)->pData[(BN)->Length - 1])                                               \
+                                                                                               break;                                                                                          \
+                                                                                       else                                                                                                    \
+                                                                                               (BN)->Length--;                                                                         \
+                                                                       } while(0)
+/*
+ * @fn         SDRM_IS_BN_NEGATIVE(X)
+ * @brief      check big number's sign 
+ */
+#define SDRM_IS_BN_NEGATIVE(X)         ((X)->sign)
+
+/*!    @brief  calc cc_u32-length when byte array is converted to cc_u32 array */
+#define SDRM_B2DLEN(X)                         ((X) > 0 ? (((X) - 1) >> 2) + 1 : 0)
+
+/*!    @brief  count byte-length of big number */
+#define        SDRM_BN_GETBYTELEN(X, A)        do {                                                                                                                                            \
+                                                                               if (!((X)->Length)) (A) = 0;                                                                                    \
+                                                                               else {                                                                                                                                  \
+                                                                                       (A) = (X)->Length * 4;                                                                                          \
+                                                                                       while(SDRM_CheckByteUINT32((X)->pData, (A) - 1) == 0) {(A) -= 1;}       \
+                                                                               }                                                                                                                                               \
+                                                                       } while(0)
+
+/*!    @brief  count bit-length of big number  */
+#define        SDRM_BN_GETBITLEN(X, A) do {                                                                                                                                                    \
+                                                                               if (!((X)->Length)) (A) = 0;                                                                                    \
+                                                                               else {                                                                                                                                  \
+                                                                                       (A) = (X)->Length * SDRM_BitsInDWORD;                                                           \
+                                                                                       while(SDRM_CheckBitUINT32((X)->pData, (A) - 1) == 0) {(A) -= 1;}        \
+                                                                               }                                                                                                                                               \
+                                                                       } while(0)
+
+////////////////////////////////////////////////////////////////////////////
+// Global Variables
+////////////////////////////////////////////////////////////////////////////
+/*!    @brief  some special big numbers        */
+extern SDRM_BIG_NUM *BN_Zero, *BN_One;
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen);
+
+/*
+ * @fn         int     SDRM_BN2OS(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
+ * @brief      Convert Big Number to Octet String
+ *
+ * @param      BN_Src  [in]source integer
+ * @param      dDstLen [in]Byte-length of pbDst
+ * @param      pbDst   [out]output octet string
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
+ */
+int    SDRM_BN2OS(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst);
+
+/*
+ * @fn         int     SDRM_OS2BN(cc_u8* pbSrc, cc_u32 dSrcLen, SDRM_BIG_NUM *BN_Dst)
+ * @brief      Convert Octet String to Big Number
+ *
+ * @param      pbSrc   [in]source octet string
+ * @param      dSrcLen [in]Byte-length of pbSrc
+ * @param      BN_Dst  [out]output big number
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
+ */
+int    SDRM_OS2BN(cc_u8* pbSrc, cc_u32 dSrcLen, SDRM_BIG_NUM *BN_Dst);
+
+/*
+ * @fn         int     SDRM_I2OSP(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
+ * @brief      Converts a nonnonegative integer to an octet string of a specified length
+ *
+ * @param      BN_Src                                  [in]nonnegative integer to be converted
+ * @param      dDstLen                                 [in]intended length of the resulting octet string
+ * @param      pbDst                                   [out]corresponding octet string of length dDstLen
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ */
+int    SDRM_I2OSP(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst);
+
+/*
+ * @fn         int SDRM_BN_Clr(SDRM_BIG_NUM* BN_Src)
+ * @brief      Clear the SDRM_BIG_NUM structure
+ *
+ * @param      BN_Src          [in]source
+ *
+ * @return     CRYPTO_SUCCESS
+ */
+int SDRM_BN_Clr(SDRM_BIG_NUM* BN_Src);
+
+/*
+ * @fn         int SDRM_BN_Copy(SDRM_BIG_NUM* BN_Dest, SDRM_BIG_NUM* BN_Src)
+ * @brief      copy SDRM_BIG_NUM
+ *
+ * @param      BN_Dest         [out]destination
+ * @param      BN_Src          [in]source
+ *
+ * @return     CRYPTO_SUCCESS
+ */
+int SDRM_BN_Copy(SDRM_BIG_NUM* BN_Dest, SDRM_BIG_NUM* BN_Src);
+
+/*
+ * @fn         SDRM_BIG_NUM *SDRM_BN_Alloc(cc_u8* pbSrc, cc_u32 dSize)
+ * @brief      allocate big number from buffer
+ *
+ * @param      pbSrc           [in]start pointer of buffer
+ * @param      dSize           [in]buffer size of big number
+ *
+ * @return     pointer of SDRM_BIG_NUM structure
+ */
+SDRM_BIG_NUM *SDRM_BN_Alloc(cc_u8* pbSrc, cc_u32 dSize);
+
+/*
+ * @fn         SDRM_BIG_NUM *SDRM_BN_Init(cc_u32 dSize)
+ * @brief      Allocate a new big number object
+ *
+ * @param      dSize           [in]buffer size of big number
+ *
+ * @return     pointer of SDRM_BIG_NUM structure
+ * \n          NULL if memory allocation is failed
+ */
+SDRM_BIG_NUM *SDRM_BN_Init(cc_u32 dSize);
+
+/*
+ * @fn         int SDRM_BN_Cmp(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+ * @brief      Compare two Big Number
+ *
+ * @param      BN_Src1         [in]first element
+ * @param      BN_Src2         [in]second element
+ *
+ * @return     1 if BN_Src1 is larger than pdSrc2
+ * \n          0 if same
+ * \n          -1 if BN_Src2 is larger than pdSrc1
+ */
+int SDRM_BN_Cmp(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2);
+
+/*
+ * @fn         int SDRM_BN_Cmp_sign(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+ * @brief      Compare two Big Number considering sign
+ *
+ * @param      BN_Src1         [in]first element
+ * @param      BN_Src2         [in]second element
+ *
+ * @return     1 if BN_Src1 is larger than pdSrc2
+ * \n          0 if same
+ * \n          -1 if BN_Src2 is larger than pdSrc1
+ */
+int SDRM_BN_Cmp_sign(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2);
+
+/*
+ * @fn         int SDRM_BN_Rand(SDRM_BIG_NUM *BN_Dst, cc_u32 BitLen)
+ * @brief      Generate simple random number
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BitLen          [in]bit-length of generated random number
+ *
+ * @return     CRYPTO_SUCCESS if no error is occured
+ */
+int SDRM_BN_Rand(SDRM_BIG_NUM *BN_Dst, cc_u32 BitLen);
+
+/*
+ * @fn         int SDRM_BN_SHL(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
+ * @brief      Big Number Shift Left
+ *
+ * @param      BN_Dst                  [out]destination
+ * @param      BN_Src                  [in]source
+ * @param      NumOfShift              [in]shift amount
+ *
+ * @return     CRYPTO_SUCCESS  if no error occured
+ */
+int SDRM_BN_SHL(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift);
+
+/*
+ * @fn         int SDRM_BN_SHR(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
+ * @brief      Big Number Shift Right
+ *
+ * @param      BN_Dst                  [out]destination
+ * @param      BN_Src                  [in]source
+ * @param      NumOfShift              [in]shift amount
+ *
+ * @return     CRYPTO_SUCCESS  if no error occured
+ */
+int SDRM_BN_SHR(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift);
+
+/*
+ * @fn         int SDRM_BN_Add(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+ * @brief      Big Number Addition
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src1                                         [in]first element
+ * @param      BN_Src2                                         [in]second element
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Add(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2);
+
+/*
+ * @fn         int SDRM_BN_Sub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+ * @brief      Big Number Subtraction
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src1                                         [in]first element
+ * @param      BN_Src2                                         [in]second element
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Sub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2);
+
+/*
+ * @fn         int SDRM_BN_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+ * @brief      Big Number Multiplication
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src1                                         [in]first element
+ * @param      BN_Src2                                         [in]second element
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2);
+
+/*
+ * @fn         int SDRM_BN_Div(SDRM_BIG_NUM *BN_Quotient, SDRM_BIG_NUM *BN_Remainder, SDRM_BIG_NUM *BN_Dividend, SDRM_BIG_NUM *BN_Divisor)
+ * @brief      Big Number Division
+ *
+ * @param      BN_Quotient                                     [out]quotient
+ * @param      BN_Remainder                            [out]remainder
+ * @param      BN_Dividend                                     [in]dividend
+ * @param      BN_Divisor                                      [in]divisor
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Div(SDRM_BIG_NUM *BN_Quotient, SDRM_BIG_NUM *BN_Remainder, SDRM_BIG_NUM *BN_Dividend, SDRM_BIG_NUM *BN_Divisor);
+
+/*
+ * @fn         int SDRM_BN_ModAdd(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Addition
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src1                                         [in]first element of addition
+ * @param      BN_Src2                                         [in]second element of addition
+ * @param      BN_Modulus                                      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModAdd(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         int SDRM_BN_ModSub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Subtraction
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src1                                         [in]first element of subtraction
+ * @param      BN_Src2                                         [in]second element of subtraction
+ * @param      BN_Modulus                                      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModSub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         int SDRM_BN_ModRed(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Reduction
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src                                          [in]source
+ * @param      BN_Modulus                                      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModRed(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         int SDRM_BN_ModMul(SDRM_BIG_NUM *BN_Res, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Multiplication
+ *
+ * @param      BN_Res                                          [out]destination
+ * @param      BN_Src1                                         [in]first element of multiplication
+ * @param      BN_Src2                                         [in]second element of multipliation
+ * @param      BN_Modulus                                      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModMul(SDRM_BIG_NUM *BN_Res, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         int SDRM_BN_ModInv(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Inverse
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Src                                          [in]soure
+ * @param      BN_Modulus                                      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ * \n          CRYPTO_NEGATIVE_INPUT           if source is negative value
+ * \n          CRYPTO_INVERSE_NOT_EXIST        if inverse is not exists
+ */
+int SDRM_BN_ModInv(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         int SDRM_BN_ModExp(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Exponentiation
+ *
+ * @param      BN_Dst                                          [out]destination
+ * @param      BN_Base                                         [in]base
+ * @param      BN_Exponent                                     [in]exponent
+ * @param      BN_Modulus                                      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ */
+int SDRM_BN_ModExp(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         int SDRM_BN_ModExp2(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Big Number Modular Exponentiation2 - Karen's method
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Base         [in]base
+ * @param      BN_Exponent     [in]exponent
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_BN_ModExp2(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         void SDRM_PrintBN(const char* s, SDRM_BIG_NUM* bn)
+ * @brief      Show out a Big Number
+ *
+ * @param      level           [in]log level
+ * @param      s                       [in]title
+ * @param      bn                      [in]big number to show out
+ *
+ * @return     void
+ */
+void SDRM_PrintBN(const char* s, SDRM_BIG_NUM* bn);
+
+int SDRM_BN_num_bits_index(SDRM_BIG_NUM *BN_Src, cc_u32 bitIndex);
+int SDRM_UINT32_num_bits_index(cc_u32 *pdSrc, cc_u32 bitIndex);
+
+
+/*
+ * @fn         int SDRM_BN_num_bits(SDRM_BIG_NUM *BN_Src)
+ * @brief      Calc bit-length of Big Number
+ *
+ * @param      BN_Src  [in]source
+ *
+ * @return     bit-length
+ */
+int SDRM_BN_num_bits(SDRM_BIG_NUM *BN_Src);
+
+/*
+ * @fn         int     SDRM_UINT32_num_bits(cc_u32 *pdSrc)
+ * @brief      Calc bit-length of cc_u32
+ *
+ * @param      pdSrc   [in]source
+ *
+ * @return     bit-length
+ */
+int    SDRM_UINT32_num_bits(cc_u32 *pdSrc);
+
+/*
+ * @fn         int     SDRM_INT_num_bits(int Src)
+ * @brief      Calc bit-length of integer
+ *
+ * @param      Src     [in]source
+ *
+ * @return     bit-length
+ */
+int    SDRM_INT_num_bits(int Src);
+
+/*
+ * @fn         int SDRM_MONT_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_MONT *Mont)
+ * @brief      Montgomery Multiplication
+ *
+ * @param      BN_Dst          [out]destination, montgomery number
+ * @param      BN_Src1         [in]first element, montgomery number
+ * @param      BN_Src2         [in]second element, montgomery number
+ * @param      Mont            [in]montgomery parameters
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+int SDRM_MONT_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         SDRM_MONT_Zn2rzn(DST, SRC1, MONT)
+ * @brief      Convert normal number to Montgomery number
+ * @param      Dst                     [out]destination, montgomery number
+ * @param      SRC1            [in]source, normal number
+ * @param      MONT            [in]montgomery parameters
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+#define SDRM_MONT_Zn2rzn(DST, SRC1, MONT)      SDRM_MONT_Mul(DST, SRC1, (MONT)->R, MONT)
+
+/*
+ * @fn         int SDRM_MONT_Rzn2zn(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_MONT *Mont)
+ * @brief      Convert Montgomery number to normal number
+ *
+ * @param      BN_Dst          [out]destination, normal number
+ * @param      BN_Src1         [in]source, montgomery number
+ * @param      Mont            [in]montgomery parameters
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+int SDRM_MONT_Rzn2zn(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         SDRM_BIG_MONT *SDRM_MONT_Init(cc_u32 dSize)
+ * @brief      Allocate new momory for Montgomery parameter
+ *
+ * @param      dSize   [in]size of buffer of big number
+ *
+ * @return     Pointer to created structure
+ * \n          NULL if malloc failed
+ */
+SDRM_BIG_MONT *SDRM_MONT_Init(cc_u32 dSize);
+
+/*
+ * @fn         int SDRM_MONT_Set(SDRM_BIG_MONT *Mont, SDRM_BIG_NUM *BN_Modulus)
+ * @brief      Set Montgomery parameters
+ *
+ * @param      Mont            [out]montgomery parameter
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          BN_NOT_ENOUGHT_BUFFER if malloc is failed
+ * \n          CRYPTO_INVERSE_NOT_EXIST if inverse is not exists
+ */
+int SDRM_MONT_Set(SDRM_BIG_MONT *Mont, SDRM_BIG_NUM *BN_Modulus);
+
+/*
+ * @fn         void SDRM_MONT_Free(SDRM_BIG_MONT *Mont)
+ * @brief      Free allocated memory for montgomery paramter
+ *
+ * @param      Mont    [in]montgomery parameters
+ *
+ * @return     void
+ */
+void SDRM_MONT_Free(SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         int SDRM_BN_CheckRelativelyPrime(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+ * @brief      get gcd of two big number
+ *
+ * @param      BN_Src1                                         [in]first element
+ * @param      BN_Src2                                         [in]second element
+ *
+ * @return     CRYPTO_ISPRIME                          if two elements are relatively prime
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR    otherwise
+ */
+int SDRM_BN_CheckRelativelyPrime(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2);
+
+/*
+ * @fn         int SDRM_BN_MILLER_RABIN(SDRM_BIG_NUM* n, cc_u32 t)
+ * @brief      MILLER_RABIN Test
+ *
+ * @param      n                                       [in]value to test
+ * @param      t                                       [in]security parameter
+ *
+ * @return     CRYPTO_ISPRIME                  if n is (probably) prime
+ * \n          CRYPTO_INVALID_ARGUMENT if n is composite
+ */
+int SDRM_BN_MILLER_RABIN(SDRM_BIG_NUM* n, cc_u32 t);
+
+/*
+ * @fn         int     SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
+ * @brief      Convert Hex String to Big Number
+ *
+ * @param      pbSrc   [in]source hex string
+ * @param      BN_Dst  [out]output big number
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
+ */
+int    SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst);
+
+/*
+ * @fn         cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
+ * @brief      Convert Big Number to binary String
+ *
+ * @param      pbSrc   [in]source big number
+ * @param      BN_Dst  [out]output numberBits of uot string
+ *
+ * @return     (cc_u8 *) binary string
+ */
+cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
+
+/*
+ * @fn         int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t);
+ * @brief      Set word to Big Number
+ *
+ * @param      pbSrc   [in]source word
+ * @param      BN_Dst  [out]output Big Nubmer
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occuredg
+ */
+int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t);
+
+/*
+ * @fn         int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src);
+ * @brief      check big number is zero
+ *
+ * @param      pbSrc   [in]source big number
+ *
+ * @return     0 - false, 1 - true
+ */
+int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src);
+
+/*
+ * @fn         cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
+ * @brief      Convert Big Number to four String
+ *
+ * @param      pbSrc   [in]source big number
+ * @param      BN_Dst  [out]output numberBits of four string
+ *
+ * @return     (cc_u8 *) four string
+ */
+cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
+
+/*
+ * @fn         SDRM_BN_MassInit
+ * @brief      Allocate a series of big number object
+ *
+ * @param      dBufSize        [in]buffer size of each big number
+ * @param      count           [in]number BigNumbers
+ *
+ * @return     double pointer of SDRM_BIG_NUM structure
+ * \n          NULL if memory allocation is failed
+ */
+SDRM_BIG_NUM **SDRM_BN_MassInit(cc_u32 dBufSize, cc_u32 count);
+
+/*
+ * @fn         SDRM_BN_IntInit
+ * @brief      Allocate a big number object and assign an integer value
+ *
+ * @param      dSize           [in]buffer size of each big number
+ * @param      data            [in]integer value
+ *
+ * @return     double pointer of SDRM_BIG_NUM structure
+ * \n          NULL if memory allocation is failed
+ */
+SDRM_BIG_NUM *SDRM_BN_IntInit(cc_u32 dSize, cc_u32 data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //      _BIGNUM_H
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/base/cc_des.h b/ssflib/dep/cryptocore/include/base/cc_des.h
new file mode 100755 (executable)
index 0000000..9523ed8
--- /dev/null
@@ -0,0 +1,412 @@
+/**
+ * \file       des.h
+ * @brief      high-speed implementation of DES
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/06
+ */
+
+
+#ifndef _CCDES_H
+#define _CCDES_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Define Constants
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_DES_NUM_OF_ROUNDS 16
+
+////////////////////////////////////////////////////////////////////////////
+// Macros
+////////////////////////////////////////////////////////////////////////////
+/*!    @brief  circular left and right shifts for cc_u32       */
+#ifdef _MSC_VER
+       #define SDRM_rotl32(A, B)       _lrotl((A), (B))
+       #define SDRM_rotr32(A, B)       _lrotr((A), (B))
+#else
+       #define SDRM_rotl32(A, B) (((A) << (B)) + ((A) >> (32 - (B))))
+       #define SDRM_rotr32(A, B) (((A) >> (B)) + ((A) << (32 - (B))))
+#endif
+
+/*!    @brief  permutation operation                                           */
+#define SDRM_PERM_OP(a,b,t,n,m) {                              \
+       (t) = ((((a)>>(n))^(b))&(m));                           \
+       (b) ^= (t);                                                                     \
+       (a) ^= ((t)<<(n));                                                      \
+}
+
+/*!    @brief  initial permutation                                                     */
+#define SDRM_IP(l,r) {                                                 \
+       cc_u32 tt;                                                                      \
+       SDRM_PERM_OP(r,l,tt, 4,0x0f0f0f0f);                     \
+       SDRM_PERM_OP(l,r,tt,16,0x0000ffff);                     \
+       SDRM_PERM_OP(r,l,tt, 2,0x33333333);                     \
+       SDRM_PERM_OP(l,r,tt, 8,0x00ff00ff);                     \
+       SDRM_PERM_OP(r,l,tt, 1,0x55555555);                     \
+}
+
+/*!    @brief  inverse of initial permutation                          */
+#define SDRM_INV_IP(l,r) {                                             \
+       cc_u32 tt;                                                                      \
+       SDRM_PERM_OP(l,r,tt, 1,0x55555555);                     \
+       SDRM_PERM_OP(r,l,tt, 8,0x00ff00ff);                     \
+       SDRM_PERM_OP(l,r,tt, 2,0x33333333);                     \
+       SDRM_PERM_OP(r,l,tt,16,0x0000ffff);                     \
+       SDRM_PERM_OP(l,r,tt, 4,0x0f0f0f0f);                     \
+}
+
+/*!    @brief  encrypt one round                                                       */
+#define SDRM_D_ENCRYPT(L,R) {                                  \
+       u = R ^ RoundKey[i][0];                                         \
+       t = R ^ RoundKey[i][1];                                         \
+       t = SDRM_rotr32(t, 4);                                          \
+       L^=     SDRM_DES_SPtrans[0][(u >>  2U) & 0x3f]^ \
+               SDRM_DES_SPtrans[2][(u >> 10U) & 0x3f]^ \
+               SDRM_DES_SPtrans[4][(u >> 18U) & 0x3f]^ \
+               SDRM_DES_SPtrans[6][(u >> 26U) & 0x3f]^ \
+               SDRM_DES_SPtrans[1][(t >>  2U) & 0x3f]^ \
+               SDRM_DES_SPtrans[3][(t >> 10U) & 0x3f]^ \
+               SDRM_DES_SPtrans[5][(t >> 18U) & 0x3f]^ \
+               SDRM_DES_SPtrans[7][(t >> 26U) & 0x3f]; \
+}
+
+////////////////////////////////////////////////////////////////////////////
+// static values - specified in FIPS 46
+////////////////////////////////////////////////////////////////////////////
+static const cc_u8 SDRM_DES_KS_SHIFT[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+
+static const cc_u32 SDRM_DES_BitMask[] = {
+          0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+static const cc_u8 SDRM_DES_KS_PC1[] = {
+       56, 48, 40, 32, 24, 16,  8,
+        0, 57, 49, 41, 33, 25, 17,
+        9,  1, 58, 50, 42, 34, 26,
+       18, 10,  2, 59, 51, 43, 35,
+
+       62, 54, 46, 38, 30, 22, 14,
+        6, 61, 53, 45, 37, 29, 21,
+       13,  5, 60, 52, 44, 36, 28,
+       20, 12,  4, 27, 19, 11,  3
+};
+
+static const cc_u32 SDRM_des_skb[8][64]={
+       {
+               /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+               0x00000000L,0x00000010L,0x20000000L,0x20000010L,
+               0x00010000L,0x00010010L,0x20010000L,0x20010010L,
+               0x00000800L,0x00000810L,0x20000800L,0x20000810L,
+               0x00010800L,0x00010810L,0x20010800L,0x20010810L,
+               0x00000020L,0x00000030L,0x20000020L,0x20000030L,
+               0x00010020L,0x00010030L,0x20010020L,0x20010030L,
+               0x00000820L,0x00000830L,0x20000820L,0x20000830L,
+               0x00010820L,0x00010830L,0x20010820L,0x20010830L,
+               0x00080000L,0x00080010L,0x20080000L,0x20080010L,
+               0x00090000L,0x00090010L,0x20090000L,0x20090010L,
+               0x00080800L,0x00080810L,0x20080800L,0x20080810L,
+               0x00090800L,0x00090810L,0x20090800L,0x20090810L,
+               0x00080020L,0x00080030L,0x20080020L,0x20080030L,
+               0x00090020L,0x00090030L,0x20090020L,0x20090030L,
+               0x00080820L,0x00080830L,0x20080820L,0x20080830L,
+               0x00090820L,0x00090830L,0x20090820L,0x20090830L,
+       },
+       {
+               /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+               0x00000000L,0x02000000L,0x00002000L,0x02002000L,
+               0x00200000L,0x02200000L,0x00202000L,0x02202000L,
+               0x00000004L,0x02000004L,0x00002004L,0x02002004L,
+               0x00200004L,0x02200004L,0x00202004L,0x02202004L,
+               0x00000400L,0x02000400L,0x00002400L,0x02002400L,
+               0x00200400L,0x02200400L,0x00202400L,0x02202400L,
+               0x00000404L,0x02000404L,0x00002404L,0x02002404L,
+               0x00200404L,0x02200404L,0x00202404L,0x02202404L,
+               0x10000000L,0x12000000L,0x10002000L,0x12002000L,
+               0x10200000L,0x12200000L,0x10202000L,0x12202000L,
+               0x10000004L,0x12000004L,0x10002004L,0x12002004L,
+               0x10200004L,0x12200004L,0x10202004L,0x12202004L,
+               0x10000400L,0x12000400L,0x10002400L,0x12002400L,
+               0x10200400L,0x12200400L,0x10202400L,0x12202400L,
+               0x10000404L,0x12000404L,0x10002404L,0x12002404L,
+               0x10200404L,0x12200404L,0x10202404L,0x12202404L,
+       },
+       {
+               /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+               0x00000000L,0x00000001L,0x00040000L,0x00040001L,
+               0x01000000L,0x01000001L,0x01040000L,0x01040001L,
+               0x00000002L,0x00000003L,0x00040002L,0x00040003L,
+               0x01000002L,0x01000003L,0x01040002L,0x01040003L,
+               0x00000200L,0x00000201L,0x00040200L,0x00040201L,
+               0x01000200L,0x01000201L,0x01040200L,0x01040201L,
+               0x00000202L,0x00000203L,0x00040202L,0x00040203L,
+               0x01000202L,0x01000203L,0x01040202L,0x01040203L,
+               0x08000000L,0x08000001L,0x08040000L,0x08040001L,
+               0x09000000L,0x09000001L,0x09040000L,0x09040001L,
+               0x08000002L,0x08000003L,0x08040002L,0x08040003L,
+               0x09000002L,0x09000003L,0x09040002L,0x09040003L,
+               0x08000200L,0x08000201L,0x08040200L,0x08040201L,
+               0x09000200L,0x09000201L,0x09040200L,0x09040201L,
+               0x08000202L,0x08000203L,0x08040202L,0x08040203L,
+               0x09000202L,0x09000203L,0x09040202L,0x09040203L,
+       },
+       {
+               /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+               0x00000000L,0x00100000L,0x00000100L,0x00100100L,
+               0x00000008L,0x00100008L,0x00000108L,0x00100108L,
+               0x00001000L,0x00101000L,0x00001100L,0x00101100L,
+               0x00001008L,0x00101008L,0x00001108L,0x00101108L,
+               0x04000000L,0x04100000L,0x04000100L,0x04100100L,
+               0x04000008L,0x04100008L,0x04000108L,0x04100108L,
+               0x04001000L,0x04101000L,0x04001100L,0x04101100L,
+               0x04001008L,0x04101008L,0x04001108L,0x04101108L,
+               0x00020000L,0x00120000L,0x00020100L,0x00120100L,
+               0x00020008L,0x00120008L,0x00020108L,0x00120108L,
+               0x00021000L,0x00121000L,0x00021100L,0x00121100L,
+               0x00021008L,0x00121008L,0x00021108L,0x00121108L,
+               0x04020000L,0x04120000L,0x04020100L,0x04120100L,
+               0x04020008L,0x04120008L,0x04020108L,0x04120108L,
+               0x04021000L,0x04121000L,0x04021100L,0x04121100L,
+               0x04021008L,0x04121008L,0x04021108L,0x04121108L,
+       },
+       {
+               /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+               0x00000000L,0x10000000L,0x00010000L,0x10010000L,
+               0x00000004L,0x10000004L,0x00010004L,0x10010004L,
+               0x20000000L,0x30000000L,0x20010000L,0x30010000L,
+               0x20000004L,0x30000004L,0x20010004L,0x30010004L,
+               0x00100000L,0x10100000L,0x00110000L,0x10110000L,
+               0x00100004L,0x10100004L,0x00110004L,0x10110004L,
+               0x20100000L,0x30100000L,0x20110000L,0x30110000L,
+               0x20100004L,0x30100004L,0x20110004L,0x30110004L,
+               0x00001000L,0x10001000L,0x00011000L,0x10011000L,
+               0x00001004L,0x10001004L,0x00011004L,0x10011004L,
+               0x20001000L,0x30001000L,0x20011000L,0x30011000L,
+               0x20001004L,0x30001004L,0x20011004L,0x30011004L,
+               0x00101000L,0x10101000L,0x00111000L,0x10111000L,
+               0x00101004L,0x10101004L,0x00111004L,0x10111004L,
+               0x20101000L,0x30101000L,0x20111000L,0x30111000L,
+               0x20101004L,0x30101004L,0x20111004L,0x30111004L,
+       },
+       {
+               /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+               0x00000000L,0x08000000L,0x00000008L,0x08000008L,
+               0x00000400L,0x08000400L,0x00000408L,0x08000408L,
+               0x00020000L,0x08020000L,0x00020008L,0x08020008L,
+               0x00020400L,0x08020400L,0x00020408L,0x08020408L,
+               0x00000001L,0x08000001L,0x00000009L,0x08000009L,
+               0x00000401L,0x08000401L,0x00000409L,0x08000409L,
+               0x00020001L,0x08020001L,0x00020009L,0x08020009L,
+               0x00020401L,0x08020401L,0x00020409L,0x08020409L,
+               0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
+               0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
+               0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
+               0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
+               0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
+               0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
+               0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
+               0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
+       },
+       {
+               /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+               0x00000000L,0x00000100L,0x00080000L,0x00080100L,
+               0x01000000L,0x01000100L,0x01080000L,0x01080100L,
+               0x00000010L,0x00000110L,0x00080010L,0x00080110L,
+               0x01000010L,0x01000110L,0x01080010L,0x01080110L,
+               0x00200000L,0x00200100L,0x00280000L,0x00280100L,
+               0x01200000L,0x01200100L,0x01280000L,0x01280100L,
+               0x00200010L,0x00200110L,0x00280010L,0x00280110L,
+               0x01200010L,0x01200110L,0x01280010L,0x01280110L,
+               0x00000200L,0x00000300L,0x00080200L,0x00080300L,
+               0x01000200L,0x01000300L,0x01080200L,0x01080300L,
+               0x00000210L,0x00000310L,0x00080210L,0x00080310L,
+               0x01000210L,0x01000310L,0x01080210L,0x01080310L,
+               0x00200200L,0x00200300L,0x00280200L,0x00280300L,
+               0x01200200L,0x01200300L,0x01280200L,0x01280300L,
+               0x00200210L,0x00200310L,0x00280210L,0x00280310L,
+               0x01200210L,0x01200310L,0x01280210L,0x01280310L,
+       },
+       {
+               /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+               0x00000000L,0x04000000L,0x00040000L,0x04040000L,
+               0x00000002L,0x04000002L,0x00040002L,0x04040002L,
+               0x00002000L,0x04002000L,0x00042000L,0x04042000L,
+               0x00002002L,0x04002002L,0x00042002L,0x04042002L,
+               0x00000020L,0x04000020L,0x00040020L,0x04040020L,
+               0x00000022L,0x04000022L,0x00040022L,0x04040022L,
+               0x00002020L,0x04002020L,0x00042020L,0x04042020L,
+               0x00002022L,0x04002022L,0x00042022L,0x04042022L,
+               0x00000800L,0x04000800L,0x00040800L,0x04040800L,
+               0x00000802L,0x04000802L,0x00040802L,0x04040802L,
+               0x00002800L,0x04002800L,0x00042800L,0x04042800L,
+               0x00002802L,0x04002802L,0x00042802L,0x04042802L,
+               0x00000820L,0x04000820L,0x00040820L,0x04040820L,
+               0x00000822L,0x04000822L,0x00040822L,0x04040822L,
+               0x00002820L,0x04002820L,0x00042820L,0x04042820L,
+               0x00002822L,0x04002822L,0x00042822L,0x04042822L,
+       }
+};
+
+static const cc_u32 SDRM_DES_SPtrans[8][64]={
+       //  nibble 0
+       {
+               0x02080800, 0x00080000, 0x02000002, 0x02080802, 0x02000000, 0x00080802, 0x00080002, 0x02000002,
+               0x00080802, 0x02080800, 0x02080000, 0x00000802, 0x02000802, 0x02000000, 0x00000000, 0x00080002,
+               0x00080000, 0x00000002, 0x02000800, 0x00080800, 0x02080802, 0x02080000, 0x00000802, 0x02000800,
+               0x00000002, 0x00000800, 0x00080800, 0x02080002, 0x00000800, 0x02000802, 0x02080002, 0x00000000,
+               0x00000000, 0x02080802, 0x02000800, 0x00080002, 0x02080800, 0x00080000, 0x00000802, 0x02000800,
+               0x02080002, 0x00000800, 0x00080800, 0x02000002, 0x00080802, 0x00000002, 0x02000002, 0x02080000,
+               0x02080802, 0x00080800, 0x02080000, 0x02000802, 0x02000000, 0x00000802, 0x00080002, 0x00000000,
+               0x00080000, 0x02000000, 0x02000802, 0x02080800, 0x00000002, 0x02080002, 0x00000800, 0x00080802
+       },
+       //  nibble 1
+       {
+               0x40108010, 0x00000000, 0x00108000, 0x40100000, 0x40000010, 0x00008010, 0x40008000, 0x00108000,
+               0x00008000, 0x40100010, 0x00000010, 0x40008000, 0x00100010, 0x40108000, 0x40100000, 0x00000010,
+               0x00100000, 0x40008010, 0x40100010, 0x00008000, 0x00108010, 0x40000000, 0x00000000, 0x00100010,
+               0x40008010, 0x00108010, 0x40108000, 0x40000010, 0x40000000, 0x00100000, 0x00008010, 0x40108010,
+               0x00100010, 0x40108000, 0x40008000, 0x00108010, 0x40108010, 0x00100010, 0x40000010, 0x00000000,
+               0x40000000, 0x00008010, 0x00100000, 0x40100010, 0x00008000, 0x40000000, 0x00108010, 0x40008010,
+               0x40108000, 0x00008000, 0x00000000, 0x40000010, 0x00000010, 0x40108010, 0x00108000, 0x40100000,
+               0x40100010, 0x00100000, 0x00008010, 0x40008000, 0x40008010, 0x00000010, 0x40100000, 0x00108000
+       },
+       //  nibble 2
+       {
+               0x04000001, 0x04040100, 0x00000100, 0x04000101, 0x00040001, 0x04000000, 0x04000101, 0x00040100,
+               0x04000100, 0x00040000, 0x04040000, 0x00000001, 0x04040101, 0x00000101, 0x00000001, 0x04040001,
+               0x00000000, 0x00040001, 0x04040100, 0x00000100, 0x00000101, 0x04040101, 0x00040000, 0x04000001,
+               0x04040001, 0x04000100, 0x00040101, 0x04040000, 0x00040100, 0x00000000, 0x04000000, 0x00040101,
+               0x04040100, 0x00000100, 0x00000001, 0x00040000, 0x00000101, 0x00040001, 0x04040000, 0x04000101,
+               0x00000000, 0x04040100, 0x00040100, 0x04040001, 0x00040001, 0x04000000, 0x04040101, 0x00000001,
+               0x00040101, 0x04000001, 0x04000000, 0x04040101, 0x00040000, 0x04000100, 0x04000101, 0x00040100,
+               0x04000100, 0x00000000, 0x04040001, 0x00000101, 0x04000001, 0x00040101, 0x00000100, 0x04040000
+       },
+       //  nibble 3
+       {
+               0x00401008, 0x10001000, 0x00000008, 0x10401008, 0x00000000, 0x10400000, 0x10001008, 0x00400008,
+               0x10401000, 0x10000008, 0x10000000, 0x00001008, 0x10000008, 0x00401008, 0x00400000, 0x10000000,
+               0x10400008, 0x00401000, 0x00001000, 0x00000008, 0x00401000, 0x10001008, 0x10400000, 0x00001000,
+               0x00001008, 0x00000000, 0x00400008, 0x10401000, 0x10001000, 0x10400008, 0x10401008, 0x00400000,
+               0x10400008, 0x00001008, 0x00400000, 0x10000008, 0x00401000, 0x10001000, 0x00000008, 0x10400000,
+               0x10001008, 0x00000000, 0x00001000, 0x00400008, 0x00000000, 0x10400008, 0x10401000, 0x00001000,
+               0x10000000, 0x10401008, 0x00401008, 0x00400000, 0x10401008, 0x00000008, 0x10001000, 0x00401008,
+               0x00400008, 0x00401000, 0x10400000, 0x10001008, 0x00001008, 0x10000000, 0x10000008, 0x10401000
+       },
+       //  nibble 4
+       {
+               0x08000000, 0x00010000, 0x00000400, 0x08010420, 0x08010020, 0x08000400, 0x00010420, 0x08010000,
+               0x00010000, 0x00000020, 0x08000020, 0x00010400, 0x08000420, 0x08010020, 0x08010400, 0x00000000,
+               0x00010400, 0x08000000, 0x00010020, 0x00000420, 0x08000400, 0x00010420, 0x00000000, 0x08000020,
+               0x00000020, 0x08000420, 0x08010420, 0x00010020, 0x08010000, 0x00000400, 0x00000420, 0x08010400,
+               0x08010400, 0x08000420, 0x00010020, 0x08010000, 0x00010000, 0x00000020, 0x08000020, 0x08000400,
+               0x08000000, 0x00010400, 0x08010420, 0x00000000, 0x00010420, 0x08000000, 0x00000400, 0x00010020,
+               0x08000420, 0x00000400, 0x00000000, 0x08010420, 0x08010020, 0x08010400, 0x00000420, 0x00010000,
+               0x00010400, 0x08010020, 0x08000400, 0x00000420, 0x00000020, 0x00010420, 0x08010000, 0x08000020
+       },
+       //  nibble 5
+       {
+               0x80000040, 0x00200040, 0x00000000, 0x80202000, 0x00200040, 0x00002000, 0x80002040, 0x00200000,
+               0x00002040, 0x80202040, 0x00202000, 0x80000000, 0x80002000, 0x80000040, 0x80200000, 0x00202040,
+               0x00200000, 0x80002040, 0x80200040, 0x00000000, 0x00002000, 0x00000040, 0x80202000, 0x80200040,
+               0x80202040, 0x80200000, 0x80000000, 0x00002040, 0x00000040, 0x00202000, 0x00202040, 0x80002000,
+               0x00002040, 0x80000000, 0x80002000, 0x00202040, 0x80202000, 0x00200040, 0x00000000, 0x80002000,
+               0x80000000, 0x00002000, 0x80200040, 0x00200000, 0x00200040, 0x80202040, 0x00202000, 0x00000040,
+               0x80202040, 0x00202000, 0x00200000, 0x80002040, 0x80000040, 0x80200000, 0x00202040, 0x00000000,
+               0x00002000, 0x80000040, 0x80002040, 0x80202000, 0x80200000, 0x00002040, 0x00000040, 0x80200040
+       },
+
+       //  nibble 6
+       {
+               0x00004000, 0x00000200, 0x01000200, 0x01000004, 0x01004204, 0x00004004, 0x00004200, 0x00000000,
+               0x01000000, 0x01000204, 0x00000204, 0x01004000, 0x00000004, 0x01004200, 0x01004000, 0x00000204,
+               0x01000204, 0x00004000, 0x00004004, 0x01004204, 0x00000000, 0x01000200, 0x01000004, 0x00004200,
+               0x01004004, 0x00004204, 0x01004200, 0x00000004, 0x00004204, 0x01004004, 0x00000200, 0x01000000,
+               0x00004204, 0x01004000, 0x01004004, 0x00000204, 0x00004000, 0x00000200, 0x01000000, 0x01004004,
+               0x01000204, 0x00004204, 0x00004200, 0x00000000, 0x00000200, 0x01000004, 0x00000004, 0x01000200,
+               0x00000000, 0x01000204, 0x01000200, 0x00004200, 0x00000204, 0x00004000, 0x01004204, 0x01000000,
+               0x01004200, 0x00000004, 0x00004004, 0x01004204, 0x01000004, 0x01004200, 0x01004000, 0x00004004
+       },
+       //  nibble 7
+       {
+               0x20800080, 0x20820000, 0x00020080, 0x00000000, 0x20020000, 0x00800080, 0x20800000, 0x20820080,
+               0x00000080, 0x20000000, 0x00820000, 0x00020080, 0x00820080, 0x20020080, 0x20000080, 0x20800000,
+               0x00020000, 0x00820080, 0x00800080, 0x20020000, 0x20820080, 0x20000080, 0x00000000, 0x00820000,
+               0x20000000, 0x00800000, 0x20020080, 0x20800080, 0x00800000, 0x00020000, 0x20820000, 0x00000080,
+               0x00800000, 0x00020000, 0x20000080, 0x20820080, 0x00020080, 0x20000000, 0x00000000, 0x00820000,
+               0x20800080, 0x20020080, 0x20020000, 0x00800080, 0x20820000, 0x00000080, 0x00800080, 0x20020000,
+               0x20820080, 0x00800000, 0x20800000, 0x20000080, 0x00820000, 0x00020080, 0x20020080, 0x20800000,
+               0x00000080, 0x20820000, 0x00820080, 0x00000000, 0x20000000, 0x20800080, 0x00020000, 0x00820080
+       }
+};
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_DES_KeySched(cc_u8 *RoundKey, cc_u8 *UserKey, cc_u32 RKPos, cc_u32 RKStep)
+ * @brief      Expand the cipher key into the encryption key schedule
+ *
+ * @param      RoundKey                        [out]generated round key
+ * @param      UserKey                         [in]user key, 8 byte
+ * @param      RKPos                           [in]index of round key starts
+ * @param      RKStep                          [in]step for index
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_DES_KeySched(cc_u8 *RoundKey, cc_u8 *UserKey, cc_u32 RKPos, cc_u32 RKStep);
+
+/*
+ * @fn         int SDRM_DES_Encryption(cc_u32 RoundKey[][2], cc_u8 *msg, cc_u8 *out)
+ * @brief      DES processing for one block
+ *
+ * @param      RoundKey                        [in]expanded round key
+ * @param      msg                                     [in]8 byte plaintext
+ * @param      out                                     [out]8 byte ciphertext
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_DES_Encryption(cc_u32 RoundKey[][2], cc_u8 *msg, cc_u8 *out);
+
+/*
+ * @fn         int SDRM_DES64_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey)
+ * @brief      one block DES Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_DES64_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey);
+
+/*
+ * @fn         int SDRM_DES64_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey)
+ * @brief      one block DES Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_DES64_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_ecc.h b/ssflib/dep/cryptocore/include/base/cc_ecc.h
new file mode 100755 (executable)
index 0000000..6740661
--- /dev/null
@@ -0,0 +1,249 @@
+/**
+ * \file       ecc.h
+ * @brief      ecc library based on big number
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jiyoung Moon
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/05/03
+ * Note : optimized by Jiyoung Moon & Jisoon Park, August,2006.
+ */
+
+
+#ifndef _CCECC_H
+#define _CCECC_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+#include "cc_bignum.h"
+#include "cc_sha1.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Constants
+////////////////////////////////////////////////////////////////////////////
+#define        SDRM_MAX_DIMENSION_ECC  256
+#define SDRM_SIZE_OF_ECC_KEY   (SDRM_SIZE_OF_DWORD * SDRM_ECC_BN_BUFSIZE)
+
+////////////////////////////////////////////////////////////////////////////
+// Macros for ECC
+////////////////////////////////////////////////////////////////////////////
+#define SDRM_EC_FREE(X)                        if (X) {free(X);}
+
+#define SDRM_EC_SET_ZERO(A)            do {                                                                                                                                                                            \
+                                                                       memset((A), 0, sizeof(SDRM_EC_POINT) + SDRM_ECC_ALLOC_SIZE * 5);                                                \
+                                                                       (A)->IsInfinity = 0;                                                                                                                                    \
+                                                                       A->x  = SDRM_BN_Alloc((cc_u8*)A     + sizeof(SDRM_EC_POINT), SDRM_ECC_BN_BUFSIZE);              \
+                                                                       A->y  = SDRM_BN_Alloc((cc_u8*)A->x  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);              \
+                                                                       A->z  = SDRM_BN_Alloc((cc_u8*)A->y  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);              \
+                                                                       A->z2 = SDRM_BN_Alloc((cc_u8*)A->z  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);              \
+                                                                       A->z3 = SDRM_BN_Alloc((cc_u8*)A->z2 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);              \
+                                                               } while(0)
+
+#define SDRM_EC_CLR(A)                 SDRM_EC_SET_ZERO(A)
+
+#define SDRM_ECC_Clr(A)                do {                                                                                                    \
+                                                                       SDRM_BN_Clr((A)->ECC_p);                                                \
+                                                                       SDRM_BN_Clr((A)->ECC_A);                                                \
+                                                                       SDRM_BN_Clr((A)->ECC_b);                                                \
+                                                                       SDRM_BN_Clr((A)->ECC_n);                                                \
+                                                                       SDRM_BN_Clr((A)->PRIV_KEY);                                             \
+                                                                       EC_Clr((A)->ECC_G);                                                             \
+                                                                       EC_Clr((A)->PUBLIC_KEY);                                                \
+                                                               } while(0)
+
+#define SDRM_ECC_FREE(X)               do {                                                                                                                            \
+                                                                       if ((X)) {                                                                                                              \
+                                                                               SDRM_BN_FREE(X->ECC_a);                                                                         \
+                                                                               SDRM_EC_FREE(X->ECC_G);                                                                         \
+                                                                               SDRM_EC_FREE(X->PUBLIC_KEY);                                                            \
+                                                                               SDRM_EC_FREE(X);                                                                                        \
+                                                                       }                                                                                                                               \
+                                                               } while(0)
+
+#define SDRM_EC_COPY(A, B)             do {                                                                                                                            \
+                                                                       (A)->IsInfinity = (B)->IsInfinity;                                                              \
+                                                                       SDRM_BN_Copy((A)->x, (B)->x);                                                                   \
+                                                                       SDRM_BN_Copy((A)->y, (B)->y);                                                                   \
+                                                                       SDRM_BN_Copy((A)->z, (B)->z);                                                                   \
+                                                                       SDRM_BN_Copy((A)->z2, (B)->z2);                                                                 \
+                                                                       SDRM_BN_Copy((A)->z3, (B)->z3);                                                                 \
+                                                               } while(0)
+
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///// ECC º¸Á¶ÇÔ¼ö
+/*
+ * @fn         SDRM_ECC_Init   
+ * @brief      return SDRM_EC_POINT structure
+ *
+ * @return     address of allocate structure
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_EC_POINT *SDRM_ECC_Init(void);
+
+/*
+ * @fn         SDRM_CURVE_Init
+ * @brief      return SDRM_ECC_CTX structure
+ *
+ * @return     address of allocate structure
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_ECC_CTX *SDRM_CURVE_Init(void);
+
+///// ECC Point ¿¬»êÇÔ¼ö
+/*
+ * @fn         SDRM_CTX_EC_Chain
+ * @brief      Chain ÇÔ¼ö
+ *
+ * signed window method        :       size of window = 4
+ * chain for addition/subtraction of k Using sliding window method
+ * @param      chain                                           [out]destination
+ * @param      L_Src                                           [in]byte-length of chain
+ * @param      Len_Src                                         [in]number of doubling in chain
+ * @param      k                                                       [in]source
+ * @param      window_size                                     [in]size of window
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT         if given value is incorrect
+ */
+int SDRM_CTX_EC_Chain(signed char *chain, cc_u32 *L_Src, cc_u32 *Len_Src, SDRM_BIG_NUM *k, int window_size);
+
+/*
+ * @fn         SDRM_CTX_EC_kP
+ * @brief      get EC_Dst = kP by Montgomery Method
+ *
+ * @param      ctx                                                     [in]ecc context
+ * @param      EC_Dst                                          [out]destination
+ * @param      EC_Src                                          [in]first element(P)
+ * @param      k                                                       [in]second element(k)
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT         if the arguemnt represents a minus value
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_INFINITY_INPUT           if the argument is a infinity value
+ */
+int SDRM_CTX_EC_kP(SDRM_ECC_CTX *ctx, SDRM_EC_POINT* EC_Dst, SDRM_EC_POINT *EC_Src, SDRM_BIG_NUM *k);
+
+/*     
+ * @fn         SDRM_CTX_EC_2kP
+ * @brief      get EC_Dst = k1*C1 + k2*C2
+ *
+ * @param      ctx                                                     [in]ecc context
+ * @param      EC_Dst                                          [out]destination
+ * @param      k1                                                      [in]first element(k1)
+ * @param      EC_Src1                                         [in]second element(C1)
+ * @param      k2                                                      [in]third element(k2)
+ * @param      EC_Src2                                         [in]fourth element(C2)
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT         if the arguemnt represents a minus value
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_INFINITY_INPUT           if the argument is a infinity value
+ */
+int SDRM_CTX_EC_2kP(SDRM_ECC_CTX *ctx, SDRM_EC_POINT *EC_Dst, SDRM_BIG_NUM *k1, SDRM_EC_POINT *EC_Src1, SDRM_BIG_NUM *k2, SDRM_EC_POINT *EC_Src2);
+
+///// Functions of Converting Coordingate
+/*
+ * @fn         SDRM_Mont_Jm2Jc
+ * @brief      ÁÂÇ¥º¯È¯ 1
+ *                     Modified Jacobian  =>  Chundnovsky Jacobian 
+ *                     (A->y)  <= (A->y)/2
+ *                     (A->z2) <= (A->z)^2
+ *                     (A->z3) <= (A->z)^3
+ *
+ * @param      EC_Dst                  [out]destination
+ * @param      new_a                   [in]first element
+ * @param      new_b                   [in]second element
+ * @param      Mont                    [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_Mont_Jm2Jc(SDRM_EC_POINT *EC_Dst, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         SDRM_Mont_Jc2Jm
+ * @brief      ÁÂÇ¥º¯È¯ 2
+ *                     Chundnovsky Jacobian  =>  Modified Jacobian
+ *                     (A->y)  <= 2*(A->y)
+ *                     (A->z2) <= new_a*(A->z)^4
+ * @param      A                               [out]destination
+ * @param      new_a                   [in]first element
+ * @param      new_b                   [in]second element
+ * @param      Mont                    [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_Mont_Jc2Jm(SDRM_EC_POINT *A, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         SDRM_CTX_EC_Add_Jc
+ * @brief      Chundnovsky Jacobian coordinate
+ *                     using montgomery (A = B + C)
+ *
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      EC_Src2                                         [in]second element(C)
+ * @param      new_a                                           [in]ECC_A's montgomery value
+ * @param      new_b                                           [in]ECC_B's montgomery value
+ * @param      Mont                                            [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Add_Jc(SDRM_EC_POINT* EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_EC_POINT *EC_Src2, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         SDRM_CTX_EC_Double_Jc   
+ * @brief      Chundnovsky Jacobian coordinate
+ *                     montgomery (A = 2B)
+ *
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      new_a                                           [in]ECC_A's montgomery value
+ * @param      new_b                                           [in]ECC_B's montgomery value
+ * @param      Mont                                            [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Double_Jc(SDRM_EC_POINT *EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont);
+
+/*
+ * @fn         SDRM_CTX_EC_Double_Jm
+ * @brief      Modified Jacobian coordinate
+ *                     montgomery (A = 2B)
+ *
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      new_a                                           [in]ECC_A's montgomery value
+ * @param      new_b                                           [in]ECC_B's montgomery value
+ * @param      Mont                                            [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Double_Jm(SDRM_EC_POINT *EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ECC_H
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/base/cc_fast_math.h b/ssflib/dep/cryptocore/include/base/cc_fast_math.h
new file mode 100755 (executable)
index 0000000..12dd955
--- /dev/null
@@ -0,0 +1,290 @@
+/** 
+ * @file       fast_math.h
+ * @brief      Header file for fast_mathf.c
+ *
+ * [Optional] Detail description (major features, interface description, flow of control, and so on)
+ * @see        [Optional] Related information
+
+ * Copyright 2008 by Samsung Electronics, Inc.,
+ * 
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ * 
+ * \internal
+ * Author : Karen Ispiryan
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2008/08/28
+*/
+
+#ifndef CCFAST_MATH_H
+#define CCFAST_MATH_H
+
+#include "CC_Type.h"
+
+#ifndef _OP64_NOTSUPPORTED
+#      define ORD_32
+#else
+#      define ORD_16
+#endif //_OP64_NOTSUPPORTED
+
+/* when we have only 16 bit processor available */
+#ifdef ORD_16
+
+typedef cc_u16 BasicWord;
+typedef cc_u32 BasicDWord;
+
+#define DIV_BY_ORD_BYTES_COUNT(x)              (BasicWord)((x) >> 1)
+#define MUL_BY_ORD_BYTES_COUNT(x)              (BasicWord)((x) << 1)
+
+#define BASICWORD_BITS_COUNT   16
+#define BASICWORD_BYTES_COUNT  2
+#define MAXDIGIT       (BasicWord)(0xFFFF)
+
+#endif
+
+/* when we have 32 bit processor available and also have 64 bit data type */
+#ifdef ORD_32
+
+typedef cc_u32 BasicWord;
+typedef cc_u64 BasicDWord;
+
+#define DIV_BY_ORD_BYTES_COUNT(x)              (BasicWord)((x) >> 2)
+#define MUL_BY_ORD_BYTES_COUNT(x)              (BasicWord)((x) << 2)
+
+#define BASICWORD_BITS_COUNT   32
+#define BASICWORD_BYTES_COUNT  4
+#define MAXDIGIT       (BasicWord)(0xFFFFFFFF)
+
+#endif
+
+#define LOW_WORD(a)            (BasicWord) (a)
+#define HIGH_WORD(a)   (BasicWord)((a) >> BASICWORD_BITS_COUNT)
+
+/* In our implementation we are using assumption that DWord data type available for using. */
+/* If for some reasons it isn't so, then we just need to redefine rhe following two macros in appropriate way 
+ * and functions will work properly.
+ */
+#define _add_add_(aw1,aw2,aw3,rwl,rwh) {                                                                                                       \
+                                                                                       BasicDWord dw = (BasicDWord)(aw1)+(aw2)+(aw3);  \
+                                                                                       rwl = LOW_WORD(dw);                                                             \
+                                                                                       rwh = HIGH_WORD(dw);                                                    \
+                                                                               }
+
+#define _mul_add_add(wm1,wm2,aw1,aw2,rwl,rwh) {                                                                                                                                \
+                                                                                                       BasicDWord dw = (BasicDWord)(wm1)*(wm2)+(aw1)+(aw2);    \
+                                                                                                       rwl = LOW_WORD(dw);                                                                             \
+                                                                                                       rwh = HIGH_WORD(dw);                                                                    \
+                                                                                               }
+
+#define IN
+#define OUT
+
+/*===========================================================================================================*/
+
+/**
+  * @fn                        SDRM_ll_Cmp
+  * @brief             Compare two large unsigned integers
+  * 
+  * @param             pFirstOperand [in] the first operand
+  * @param             pSecondOperand [in] the second operand
+  *
+  * @return            0 if they are equal
+  *                            1 if first bigger then second
+  *                            -1 if the seond one is bigger then first
+  */
+int SDRM_ll_Cmp(const BasicWord *pFirstOperand, const BasicWord *pSecondOperand, unsigned uOperandLength);
+
+/**
+  * @fn                        SDRM_ll_Copy
+  * @brief             Just copy two large unsigned integers from one into another
+  */
+void SDRM_ll_Copy(BasicWord *pFirstOperand, const BasicWord *pSecondOperand, unsigned uOperandLength);
+
+/**
+  * @fn                        SDRM_ll_bit_RShift
+  * @brief             Shift large unsigned integer to the right by uBits
+  * 
+  * @param             pOperand [inout] pointer to the operand to be shifted
+  *
+  * @return            Nothing
+  * @warning   We have to be careful when using this function because it modifies uOperandLength+1 words 
+  *                            that is by 1 word bigger then operand original size.
+  *                            WWW....Operand...WWW|W <- it modifies the word immediately after the last one of passed operand.
+  */
+void SDRM_ll_bit_RShift(IN OUT BasicWord *pOperand, IN BasicWord uOperandLength, OUT BasicWord uBits);
+
+/**
+  * @fn                        SDRM_ll_bit_LShift
+  * @brief             Shift large unsigned integer to the left by uBits
+  * 
+  * @param             pOperand [inout] pointer to the operand to be shifted
+  *
+  * @return            Nothing
+  * @warning   We have to be careful when using this function because it modifies uOperandLength+1 words 
+  *                            that is by 1 word bigger then operand original size.
+  *                            It modifies the word immediately prior to the first one of passed operand -> W|WWW....Operand...WWW
+  */
+void SDRM_ll_bit_LShift(IN OUT BasicWord *pOperand, IN BasicWord uOperandLength, OUT BasicWord uBits);
+
+/**
+  * @fn                        SDRM_ll_getMSW
+  * @brief             Return index of most significant word.
+  * 
+  * @param             pOperand [in] pointer to the large integer.
+  *
+  * @return            The index of most significant word.
+  *                            -1 if passed integer actually is equal to 0.
+  */
+int SDRM_ll_getMSW(IN const BasicWord *pOperand, IN BasicWord uOperandLength);
+
+/**
+  * @fn                        SDRM_ll_Add
+  * @brief             Add two large unsigned integers that have the same size.
+  * 
+  * @param             pFirstOperand  [in] pointer to first large integer
+  * @param             pSecondOperand [in] pointer to second large integer
+  * @param             uOperandsLength [in] length of the operands in words
+  * @param             pResult [out] pointer to result of subtraction
+  *
+  * @return            carry if so.
+  */
+int SDRM_ll_Add(IN const BasicWord *pFirstOperand, 
+                               IN const BasicWord *pSecondOperand, 
+                               IN BasicWord uOperandsLength, 
+                               OUT BasicWord *pResult);
+
+/**
+  * @fn                        SDRM_ll_AddCarry
+  * @brief             Add carry to large unsigned integer
+  * 
+  * @param             oneWord  [in] value of carry
+  * @param             pOperand [inout] pointer to large integer
+  * @param             uOperandLength [in] length of the second operand in words
+  *
+  * @return            carry if so.
+  */
+int SDRM_ll_AddCarry(IN BasicWord oneWord, IN BasicWord *pOperand, IN BasicWord uOperandLength);
+
+/**
+  * @fn                        SDRM_ll_Sub
+  * @brief             Subtract two large unsigned integers that have the same size.
+  * 
+  * @param             pFirstOperand   [in] pointer to first large integer
+  * @param             pSecondOperand  [in] pointer to second large integer
+  * @param             uOperandsLength [in] length of the operands in words
+  * @param             pResult                 [out] pointer to result of subtraction
+  *
+  * @return            borrow if so.
+  */
+int SDRM_ll_Sub(IN const BasicWord *pFirstOperand, 
+                               IN const BasicWord *pSecondOperand, 
+                               IN BasicWord uOperandsLength, 
+                               OUT BasicWord *pResult);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_MulAdd(IN BasicWord *pFirstOperand, IN BasicWord uFirstOperandsLength, 
+                                       IN BasicWord *pSecondOperand, IN BasicWord uSecondOperandsLength, 
+                                       OUT BasicWord *pResult);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_Mul(IN BasicWord *pFirstOperand, IN BasicWord uFirstOperandsLength, 
+                                IN BasicWord *pSecondOperand, IN BasicWord uSecondOperandsLength, 
+                                OUT BasicWord *pResult);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_Square(IN BasicWord *pOperand, IN BasicWord uOperandLength, OUT BasicWord *pResult);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_mont_Rem(IN OUT BasicWord *pFirstOperand, 
+                                         IN BasicWord *pModule, 
+                                         IN BasicWord uModuleLength, 
+                                         IN BasicWord inv);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_mont_Square(IN BasicWord *pFirstOperand, 
+                                               IN BasicWord *pModule, 
+                                               IN BasicWord uModuleLength, 
+                                               IN BasicWord Inv, 
+                                               OUT BasicWord *pResult);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_mont_Mul(IN BasicWord *pFirstOperand, 
+                                        IN BasicWord *pSecondOperand, 
+                                        IN BasicWord *pModule, 
+                                        IN BasicWord uModuleLengthInBytes, 
+                                        IN BasicWord Inv, 
+                                        OUT BasicWord *pResult);
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_ExpMod( IN BasicWord *pBase, IN BasicWord uBaseLengthInBytes, 
+                                       IN BasicWord *pExponent, IN BasicWord uExponentLengthInBytes,
+                                       IN BasicWord *pModule, IN BasicWord uModuleLengthInBytes, 
+                                       OUT BasicWord *pResult);
+
+#endif /*FAST_MATH_H*/
diff --git a/ssflib/dep/cryptocore/include/base/cc_hash.h b/ssflib/dep/cryptocore/include/base/cc_hash.h
new file mode 100755 (executable)
index 0000000..446f33d
--- /dev/null
@@ -0,0 +1,337 @@
+/**
+ * \file       hash.h
+ * @brief      hash API function
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/08
+ */
+
+#ifndef _CCHASH_H
+#define _CCHASH_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CC_API.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_SHA1_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_init(CryptoCoreContainer *crt);
+
+/*
+ * @fn         SDRM_SHA1_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+
+/*
+ * @fn         SDRM_SHA1_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_final(CryptoCoreContainer *crt, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA1_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA224_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_init(CryptoCoreContainer *crt);
+
+
+/*
+ * @fn         SDRM_SHA224_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+
+/*
+ * @fn         SDRM_SHA224_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_final(CryptoCoreContainer *crt, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA224_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA256_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_init(CryptoCoreContainer *crt);
+
+
+/*
+ * @fn         SDRM_SHA256_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+
+/*
+ * @fn         SDRM_SHA256_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_final(CryptoCoreContainer *crt, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA256_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA384_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_init(CryptoCoreContainer *crt);
+
+/*
+ * @fn         SDRM_SHA384_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+
+/*
+ * @fn         SDRM_SHA384_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_final(CryptoCoreContainer *crt, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA384_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA512_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_init(CryptoCoreContainer *crt);
+
+/*
+ * @fn         SDRM_SHA512_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+
+/*
+ * @fn         SDRM_SHA512_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_final(CryptoCoreContainer *crt, cc_u8 *output);
+
+/*
+ * @fn         SDRM_SHA512_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+
+/*
+ * @fn         SDRM_MD5_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_init(CryptoCoreContainer *crt);
+
+/*
+ * @fn         SDRM_MD5_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen);
+
+/*     
+ * @fn         SDRM_MD5_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_final(CryptoCoreContainer *crt, cc_u8 *output);
+
+/*
+ * @fn         SDRM_MD5_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_md5.h b/ssflib/dep/cryptocore/include/base/cc_md5.h
new file mode 100755 (executable)
index 0000000..c8c5326
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Implementation of MD5
+ */
+
+#ifndef _CCMD5_H
+#define _CCMD5_H
+
+#include <stdio.h>
+#include <string.h>
+#include "CryptoCore.h"
+
+//prototypes
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SDRM_MD5_Init(SDRM_MD5Context *ctx);
+
+void SDRM_MD5_Update(SDRM_MD5Context *ctx, cc_u8* buffer, cc_u32 cc_u8Count);
+
+void SDRM_MD5_Final(SDRM_MD5Context *ctx, cc_u8* output );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _MD5_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_moo.h b/ssflib/dep/cryptocore/include/base/cc_moo.h
new file mode 100755 (executable)
index 0000000..80457a9
--- /dev/null
@@ -0,0 +1,206 @@
+/**
+ * \file       moo.h
+ * @brief      implementation of mode of operations
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/04
+ */
+
+
+#ifndef _CCMOO_H
+#define _CCMOO_H
+
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+#include "cc_aes.h"
+#include "cc_des.h"
+#include "cc_tdes.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// Macros for Mode of operation
+////////////////////////////////////////////////////////////////////////////
+#ifndef SDRM_CheckByteUINT32
+/*!    @brief  get k-th byte from cc_u32 array A       */
+#define SDRM_CheckByteUINT32(A, k)             (cc_u8)(0xff & (A[(k) >> 2] >> (((k) & 3 ) << 3)))
+#endif
+
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_ECB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key)
+ * @brief      Encrypt a block with ECB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_ECB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key);
+
+
+/*
+ * @fn         int SDRM_ECB_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key)
+ * @brief      Decrypt a block with ECB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]plain text block
+ * @param      in                                              [in]cipher text block
+ * @param      key                                             [in]user key
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_ECB_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key);
+
+
+/*
+ * @fn         int SDRM_CBC_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+ * @brief      Encrypt a block with CBC mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CBC_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV);
+
+
+/*
+ * @fn         int SDRM_CBC_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+ * @brief      Decrypt a block with CBC mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                     [out]plain text block
+ * @param      in                                      [in]cipher text block
+ * @param      key                                     [in]user key
+ * @param      IV                                      [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CBC_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV);
+
+
+/*     
+ * @fn         int SDRM_CFB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+ * @brief      Encrypt a block with CFB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                     [out]cipher text block
+ * @param      in                                      [in]plain text block
+ * @param      key                                     [in]user key
+ * @param      IV                                      [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CFB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV);
+
+
+/*
+ * @fn         int SDRM_CFB_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+ * @brief      Decrypt a block with CBC mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]plain text block
+ * @param      in                                              [in]cipher text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CFB_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV);
+
+
+/*
+ * @fn         int SDRM_OFB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+ * @brief      Encrypt a block with OFB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_OFB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV);
+
+
+/*
+ * @fn         SDRM_OFB_Dec(ALG, OUT, IN, KEY, IV)
+ * @brief      Decrypt a block with OFB mode
+ *
+ * \n  ALG                                             [in]algorithm
+ * \n  OUT                                             [out]plain text block
+ * \n  IN                                              [in]cipher text block
+ * \n  KEY                                             [in]user key
+ * \n  IV                                              [in]initial vector
+ */
+#define SDRM_OFB_Dec(ALG, OUT, IN, KEY, IV)    SDRM_OFB_Enc(ALG, OUT, IN, KEY, IV)
+
+/*
+ * @fn         int SDRM_CTR_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV, cc_u32 counter)
+ * @brief      Encrypt a block with CTR mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ * @param      counter                                 [in]counter
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CTR_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV, cc_u32 counter);
+
+
+/*
+ * @fn         SDRM_CTR_Dec(ALG, OUT, IN, KEY, IV, CTR)
+ * @brief      Decrypt a block with CTR mode
+ *
+ * \n  ALG                                             [in]algorithm
+ * \n  OUT                                             [out]plain text block
+ * \n  IN                                              [in]cipher text block
+ * \n  KEY                                             [in]user key
+ * \n  IV                                              [in]initial vector
+ * \n  CTR                                             [in]counter
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+#define SDRM_CTR_Dec(ALG, OUT, IN, KEY, IV, CTR)       SDRM_CTR_Enc(ALG, OUT, IN, KEY, IV, CTR)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _MOO_H
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/base/cc_pkcs1_v21.h b/ssflib/dep/cryptocore/include/base/cc_pkcs1_v21.h
new file mode 100755 (executable)
index 0000000..c77660e
--- /dev/null
@@ -0,0 +1,195 @@
+/**
+ * \file       pkcs1_v21.h
+ * @brief      PKCS#1 V1.5, V2.0(RSAES-OAEP), V2.1(RSASSA-PSS) Implemetation
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/20
+ */
+
+
+#ifndef _CCPKCS1_V21_H
+#define _CCPKCS1_V21_H
+
+//////////////////////////////////////////////////////////////////////////
+// Include Header Files
+//////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include "CryptoCore.h"
+#include "cc_bignum.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Define Constants
+//////////////////////////////////////////////////////////////////////////
+/*!    @brief  padding mode - enpadding        */
+#define SDRM_ENPADDING         11111
+/*!    @brief  padding mode - depadding        */
+#define SDRM_DEPADDING         11112
+
+/*!    @brief  DER message     */
+#define SDRM_DIGESTINFO_MD5_VALUE                      {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x40, 0x10}
+#define SDRM_DIGESTINFO_SHA1_VALUE                     {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}
+#define SDRM_DIGESTINFO_SHA224_VALUE           {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}
+#define SDRM_DIGESTINFO_SHA256_VALUE           {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}
+#define SDRM_DIGESTINFO_SHA384_VALUE           {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}
+#define SDRM_DIGESTINFO_SHA512_VALUE           {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}
+
+/*!    @brief  byte-length of DER message      */
+#define SDRM_DIGESTINFO_MD5_LEN                                18
+#define SDRM_DIGESTINFO_SHA1_LEN                       15
+#define SDRM_DIGESTINFO_SHA224_LEN                     19
+#define SDRM_DIGESTINFO_SHA256_LEN                     19
+#define SDRM_DIGESTINFO_SHA384_LEN                     19
+#define SDRM_DIGESTINFO_SHA512_LEN                     19
+
+#define SDRM_EMSA_PSS_SALT_LEN                         4
+
+//////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+* @brief               RSAES PKCS#1 v1.5 enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k);
+/*
+* @fn          int SDRM_Depad_Rsaes_pkcs15(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k);
+* @brief               RSAES PKCS#1 v1.5 depadding
+*
+* @param       m                                               [out]Depadded msg
+* @param       mLen                                    [out]byte-size of m
+* @param       EM                                              [in]Enpadded msg
+* @param       emLen                                   [in]byte-size of EM
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_INVALID_ARGUMENT if enpadded message is out of RSA padding scheme
+*/
+int SDRM_Depad_Rsaes_pkcs15(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k);
+/*
+* @fn          int SDRM_Enpad_Rsaes_oaep(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k, int HASH_Algorithm)
+* @brief               RSAES OAEP enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsaes_oaep(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k, int HASH_Algorithm);
+/*
+* @fn          int SDRM_Depad_Rsaes_oaep(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k, int HASH_Algorithm)
+* @brief               RSAES PKCS#1 v1.5 depadding
+*
+* @param       m                                               [out]Depadded msg
+* @param       mLen                                    [out]byte-size of m
+* @param       EM                                              [in]Enpadded msg
+* @param       emLen                                   [in]byte-size of EM
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_INVALID_ARGUMENT if enpadded message is out of RSA padding scheme
+*/
+int SDRM_Depad_Rsaes_oaep(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k, int HASH_Algorithm);
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+* @brief               RSAES PKCS#1 v1.5 enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsassa_pkcs15(cc_u8 *EM, cc_u32 emLen, cc_u8 *h, cc_u32 hLen, int HASH_Algorithm);
+
+/*
+* @fn          int SDRM_Depad_Rsassa_pkcs15(cc_u8 *EM, cc_u32 emLen, cc_u8 *h, cc_u32 hLen, int HASH_Algorithm);
+* @brief               RSAES PKCS#1 v1.5 enpadding
+*
+* @param       m                                               [out]Depadded msg
+* @param       mLen                                    [out]byte-size of m
+* @param       EM                                              [in]Enpadded msg
+* @param       emLen                                   [in]byte-size of EM
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Depad_Rsassa_pkcs15(cc_u8 *EM, cc_u32 emLen, cc_u8 *h, cc_u32 hLen, int HASH_Algorithm);
+
+/*
+ * @fn         int SDRM_Enpad_Rsassa_pss(cc_u8 *EM, cc_u32 nBits, cc_u8 *h, cc_u32 hLen, cc_u32 k, int HASH_Algorithm);
+ * @brief      RSASSA PSS
+ *
+* @param       EM                                              [out]Enpadded msg
+* @param       nBits                                   [in]bit length of enpadded msg.
+* @param       h                                               [in]hash of src message
+* @param       hLen                                    [in]hash message length.
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsassa_pss(cc_u8 *EM, cc_u32 nBits, cc_u8 *h, cc_u32 hLen, cc_u32 k, int HASH_Algorithm);
+/*
+* @fn          int SDRM_Depad_Rsassa_pss(cc_u8 *EM, cc_u32 nBits, cc_u8 *h, cc_u32 hLen, cc_u32 k, int HASH_Algorithm);
+* @brief       RSASSA PSS
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       nBits                                   [in]bit length of enpadded msg.
+* @param       h                                               [in]hash of src message
+* @param       hLen                                    [in]hash message length.
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Depad_Rsassa_pss(cc_u8 *EM, cc_u32 nBits, cc_u8 *h, cc_u32 hLen, cc_u32 k, int HASH_Algorithm);
+/*
+ * @fn         int SDRM_MGF1(int HASH_Algorithm, cc_u8* mask, cc_u8* pbSeed, cc_u32 SeedLen, cc_u32 dMaskLen)
+ * @brief      MGF1 Function (Mask Generation Function based on a hash function)
+ *
+ * @param      mask                                    [out]byte-length of generated mask
+ * @param      pbSeed                                  [in]seed for MGF
+ * @param      SeedLen                                 [in]byte-length of pbSeed
+ * @param      dMaskLen                                [in]byte-length of mask
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+//int SDRM_MGF1(int HASH_Algorithm, cc_u8* mask, cc_u8* pbSeed, cc_u32 SeedLen, cc_u32 dMaskLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_rc4.h b/ssflib/dep/cryptocore/include/base/cc_rc4.h
new file mode 100755 (executable)
index 0000000..98510ae
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * \file       rc4.h
+ * @brief      implementation of RC4 encryption scheme
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/01
+ */
+
+
+#ifndef _CCRC4_H
+#define _CCRC4_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_RC4_Setup(SDRM_RC4Context *ctx, cc_u8 *UserKey, cc_u32 keyLen)
+ * @brief      intialize s
+ *
+ * @param      ctx                                     [in]crypto context
+ * @param      UserKey                         [in]user key
+ * @param      keyLen                          [out]byte-length of UserKey
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_RC4_Setup(SDRM_RC4Context *ctx, cc_u8 *UserKey, cc_u32 keyLen);
+
+/*
+ * @fn         int SDRM_RC4_PRNG(SDRM_RC4Context *ctx, cc_u8 *in, cc_u32 inLen, cc_u8 *out)
+ * @brief      process stream data
+ *
+ * @param      ctx                                     [in]crypto context
+ * @param      in                                      [in]plaintext
+ * @param      inLen                           [in]byte-length of in
+ * @param      out                                     [out]cipher text
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_RC4_PRNG(SDRM_RC4Context *ctx, cc_u8 *in, cc_u32 inLen, cc_u8 *out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_sha1.h b/ssflib/dep/cryptocore/include/base/cc_sha1.h
new file mode 100755 (executable)
index 0000000..773bbce
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Implementation of SHA-1
+ */
+
+#ifndef _CCSHA1_H
+#define _CCSHA1_H
+
+#include <stdio.h>
+#include <string.h>
+#include "CryptoCore.h"
+
+//prototypes
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SDRM_SHA1_Init(SDRM_SHA1Context* ctx);
+
+void SDRM_SHA1_Update(SDRM_SHA1Context* ctx, const cc_u8* buffer, int ByteCount);
+
+void SDRM_SHA1_Final(SDRM_SHA1Context* ctx, cc_u8* output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SHA1_H
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/base/cc_sha2.h b/ssflib/dep/cryptocore/include/base/cc_sha2.h
new file mode 100755 (executable)
index 0000000..69eb1c6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Implementation of SHA-2
+ */
+
+#ifndef _CCSHA2_H
+#define _CCSHA2_H
+
+#include <stdio.h>
+#include <string.h>
+#include "CryptoCore.h"
+
+//prototypes
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SDRM_SHA224_Init(SDRM_SHA224Context* ctx);
+void SDRM_SHA224_Update(SDRM_SHA224Context* ctx, const cc_u8 *message, cc_u32 len);
+void SDRM_SHA224_Final(SDRM_SHA224Context* ctx, cc_u8 *digest);
+
+void SDRM_SHA256_Init(SDRM_SHA256Context* ctx);
+void SDRM_SHA256_Update(SDRM_SHA256Context* ctx, const cc_u8 *message, cc_u32 len);
+void SDRM_SHA256_Final(SDRM_SHA256Context* ctx, cc_u8 *digest);
+
+#ifndef _OP64_NOTSUPPORTED
+
+void SDRM_SHA384_Init(SDRM_SHA384Context* ctx);
+void SDRM_SHA384_Update(SDRM_SHA384Context* ctx, const cc_u8 *message, cc_u32 len);
+void SDRM_SHA384_Final(SDRM_SHA384Context* ctx, cc_u8 *digest);
+
+void SDRM_SHA512_Init(SDRM_SHA512Context* ctx);
+void SDRM_SHA512_Update(SDRM_SHA512Context* ctx, const cc_u8 *message, cc_u32 len);
+void SDRM_SHA512_Final(SDRM_SHA512Context* ctx, cc_u8 *digest);
+
+#endif //_OP64_NOTSUPPORTED
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SHA2_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/base/cc_snow2.h b/ssflib/dep/cryptocore/include/base/cc_snow2.h
new file mode 100755 (executable)
index 0000000..639acd6
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * \file       snow2.h
+ * @brief      implementation of SNOW 2.0 encryption scheme
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/02
+ */
+
+
+#ifndef _CCSNOW2_H
+#define _CCSNOW2_H
+
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_SNOW2_Setup(SDRM_SNOW2Context *ctx, cc_u8 *UserKey, cc_u32 keyLen, cc_u8 *IV)
+ * @brief      Setup FSM and s values
+ * @param      ctx                             [out]crypto context
+ * @param      UserKey                 [in]User Key, 128 or 256 bit
+ * @param      keyLen                  [in]byte-size of User Key, 16 or 32
+ * @param      IV                              [in]16 byte initial vector
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_SNOW2_Setup(SDRM_SNOW2Context *ctx, cc_u8 *UserKey, cc_u32 keyLen, cc_u8 *IV);
+
+/*
+ * @fn         int SDRM_SNOW2_getKeyStream64(SDRM_SNOW2Context *ctx, cc_u32 *keyStream64)
+ * @brief      get 64 byte key stream
+ * @param      ctx                             [out]crypto context
+ * @param      keyStream64             [in]generated key stream
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_SNOW2_getKeyStream64(SDRM_SNOW2Context *ctx, cc_u32 *keyStream64);
+
+/*
+ * @fn         int SDRM_SNOW2_getKeyStream(SDRM_SNOW2Context *ctx, cc_u32 *keyStream)
+ * @brief      get 4 byte key stream
+ * @param      ctx                             [out]crypto context
+ * @param      keyStream               [in]generated key stream
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_SNOW2_getKeyStream(SDRM_SNOW2Context *ctx, cc_u32 *keyStream);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //      _SNOW2_H
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/drm_macro.h b/ssflib/dep/cryptocore/include/drm_macro.h
new file mode 100755 (executable)
index 0000000..ab20527
--- /dev/null
@@ -0,0 +1,201 @@
+/**
+ * \file       drm_macro.h
+ * @brief      Common Macro Difinitions
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Changsup Ahn
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/02
+ */
+
+#ifndef _DRM_MACRO_H
+#define _DRM_MACRO_H
+
+////////////////////////////////////////////////////////////////////////////
+// Header File Include
+////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+
+////////////////////////////////////////////////////////////////////////////
+// Macros
+////////////////////////////////////////////////////////////////////////////
+/*!    @brief  get larger of two       */
+#define MAX2(A, B) ((A) > (B) ? (A) : (B))
+
+/*!    @brief  get largest of three    */
+#define MAX3(C, D, E) ((C) > MAX2((D), (E)) ? (C) : MAX2((D), (E)))
+
+/*!    @brief  print out by byte unit  */
+#undef PrintBYTE
+#define PrintBYTE(msg, Data, DataLen) {                                        \
+       int idx;                                                                                        \
+       printf("%10s =", msg);                                                          \
+       for( idx=0; idx<(int)DataLen; idx++) {                          \
+               if( (idx!=0) && ((idx%16)==0) ) printf("\n");   \
+               if((idx % 4) == 0)      printf(" 0x");                          \
+               printf("%.2x", Data[idx]);                                              \
+       }                                                                                                       \
+       printf("\n");                                                                           \
+}
+
+/*!    @brief  print out in hexa representation        */
+#undef PrintBYTE_HEX
+#define PrintBYTE_HEX(msg, Data, DataLen) {                            \
+       int idx;                                                                                        \
+       printf("%10s =", msg);                                                          \
+       for( idx=0; idx<(int)DataLen; idx++) {                          \
+               if( (idx!=0) && ((idx%8)==0) ) printf("\n");    \
+               printf("0x%.2x, ", Data[idx]);                                  \
+       }                                                                                                       \
+       printf("\n");                                                                           \
+}
+
+/*!    @brief  print out in hexa representation without length information     */
+#undef PrintBYTE_FILE_RAW                                                                      // raw data ÇüÅ·Π»ç¿ëÇÒ ¼ö ÀÖµµ·Ï Hex ÇüÅ·ΠÃâ·Â 
+#define PrintBYTE_FILE_RAW(pfile, Data, DataLen) {             \
+       int idx;                                                                                        \
+       for( idx=0; idx<(int)DataLen; idx++) {                          \
+               if( (idx==0) || ((idx%8)!=0) )                                  \
+                       fprintf(pfile, "0x%.2x, ", Data[idx]);          \
+               else                                                                                    \
+                       fprintf(pfile, " \n0x%.2x, ", Data[idx]);       \
+       }                                                                                                       \
+}
+
+/*!    @brief  print out message       */
+#undef PrintMSG
+#define PrintMSG(msg) {                                                                        \
+       fprintf(stdout, "\n************************************************\n");        \
+       fprintf(stdout, "*     %s\n", msg);                                     \
+       fprintf(stdout, "*\n");                                                         \
+}
+
+/*!    @brief  copy 16 byte block      */
+#undef BlockCopy
+#define BlockCopy(pbDst, pbSrc) {                                              \
+       memcpy(pbDst, pbSrc, 16);                                                       \
+}
+
+/*!    @brief  xor 16 byte block       */
+#undef BlockXor
+#define BlockXor(pbDst, phSrc1, phSrc2) {                              \
+       int idx;                                                                                        \
+       for(idx = 0; idx < 16; idx++)                                           \
+               (pbDst)[idx] = (phSrc1)[idx] ^ (phSrc2)[idx];   \
+}
+
+/*!    @brief  convert 32-bit unit to 4 byte   */
+#undef GET_UINT32
+#define GET_UINT32(n,b,i)                                                              \
+{                                                                                                              \
+    (n) = ((unsigned int)((b)[(i)    ]) << 24 )                        \
+        | ((unsigned int)((b)[(i) + 1]) << 16 )                        \
+        | ((unsigned int)((b)[(i) + 2]) <<  8 )                        \
+        | ((unsigned int)((b)[(i) + 3])       );               \
+}
+
+/*!    @brief  4 byte to 32-bit unit   */
+#undef PUT_UINT32
+#define PUT_UINT32(n,b,i)                                                              \
+{                                                                                                              \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );                              \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );                              \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );                              \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );                              \
+}
+
+/*!    @brief  convert 24-bit unit to 3 byte   */
+#undef GET_UINT24
+#define GET_UINT24(n,b,i)                                                              \
+{                                                                                                              \
+    (n) = ( (b)[(i)    ] << 16 )                                               \
+        | ( (b)[(i) + 1] << 8  )                                               \
+        | ( (b)[(i) + 2]       );                                              \
+}
+
+/*!    @brief  convert 3 byte to 24-bit unit   */
+#undef PUT_UINT24
+#define PUT_UINT24(n,b,i)                                                              \
+{                                                                                                              \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 16 );                              \
+    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );                              \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>    );                              \
+}
+
+/*!    @brief  convert 16-bit unit to 2 byte   */
+#undef GET_UINT16
+#define GET_UINT16(n,b,i)                                                              \
+{                                                                                                              \
+    (n) = ( (b)[(i)    ] << 8 )                                                        \
+        | ( (b)[(i) + 1]       );                                                      \
+}
+
+/*!    @brief  convert 2 byte to 16-bit unit   */
+#undef PUT_UINT16
+#define PUT_UINT16(n,b,i)                                                              \
+{                                                                                                              \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 8 );                               \
+    (b)[(i) + 1] = (unsigned char) ( (n)      );                               \
+}
+
+/*!    @brief  read 1 byte of s form o & increase o    */
+#undef READ_8
+#define READ_8(t,s,o) {                                                                        \
+       t = (unsigned char) s[o];                                                                       \
+       o+=1;                                                                                           \
+}
+
+/*!    @brief  read 2 byte of sfrom o & increase o     */
+#undef READ_16
+#define READ_16(t,s,o) {                                                               \
+       GET_UINT16(t,s,o);                                                                      \
+       o+=2;                                                                                           \
+}
+
+/*!    @brief  read 3 byte of s from o & increase o    */
+#undef READ_24
+#define READ_24(t,s,o) {                                                               \
+       GET_UINT24(t,s,o);                                                                      \
+       o+=3;                                                                                           \
+}
+
+/*!    @brief  read 4 byte of s from o & increase o    */
+#undef READ_32
+#define READ_32(t,s,o) {                                                               \
+       GET_UINT32(t,s,o);                                                                      \
+       o+=4;                                                                                           \
+}
+
+/*!    @brief  write 4 byte to s from o & increase o   */
+#undef WRITE_32
+#define WRITE_32(t,s,o) {                                                              \
+       PUT_UINT32(s,t,o);                                                                      \
+       o+=4;                                                                                           \
+}
+
+/*!    @brief  write 3 byte to s from o & increase o   */
+#undef WRITE_24
+#define WRITE_24(t,s,o) {                                                              \
+       PUT_UINT24(s,t,o);                                                                      \
+       o+=3;                                                                                           \
+}
+
+/*!    @brief  write 2 byte to s from o & increase o   */
+#undef WRITE_16
+#define WRITE_16(t,s,o) {                                                              \
+       PUT_UINT16(s,t,o);                                                                      \
+       o+=2;                                                                                           \
+}
+
+/*!    @brief  write 1 byte to s from o & increase o   */
+#undef WRITE_8
+#define WRITE_8(t,s,o) {                                                               \
+       t[o] = (unsigned char)s;                                                                        \
+       o+=1;                                                                                           \
+}
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_cmac.h b/ssflib/dep/cryptocore/include/middle/cc_cmac.h
new file mode 100755 (executable)
index 0000000..05409c1
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * \file       cmac.h
+ * @brief      funciton for c-mac code generation by AES-128
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/20
+ */
+
+
+#ifndef _CCCMAC_H
+#define _CCCMAC_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CC_API.h"
+#include "cc_moo.h"
+#include "cc_aes.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_CMAC_init(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen)
+ * @brief      Parameter setting for mac code generation
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CMAC_init(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen);
+
+/*
+ * @fn         int SDRM_CMAC_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen)
+ * @brief      process data blocks
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CMAC_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen);
+
+/*
+ * @fn         int SDRM_CMAC_final(CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen)
+ * @brief      process last data block
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CMAC_final(CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         int SDRM_CMAC_getMAC(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen)
+ * @brief      generate c-mac code
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ */
+int SDRM_CMAC_getMAC(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _CMAC_H
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/include/middle/cc_dh.h b/ssflib/dep/cryptocore/include/middle/cc_dh.h
new file mode 100755 (executable)
index 0000000..21631b0
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * \file       dh.h
+ * @brief      implementation of Diffie-Hellman Key Exchange Protocol
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2012/04/12
+ */
+
+#ifndef _DIFFIE_HELLMAN_H
+#define _DIFFIE_HELLMAN_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include "CC_API.h"
+
+#define DH_DEFAULT_GENERATOR   5                                       /**<    fixed generator value   */
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @fn         SDRM_GenerateDHParam(SDRM_DHContext* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned int* pGenerator)
+ * @brief      generate parameters for Diffie-Hellman protocol
+ *
+ * @param      [out] crt                               context
+ * @param      [out] pPrime                    prime number
+ * @param      [in]  nPrimeLen                 size of pPrime buffer
+ * @param      [out] pGenerator                generator value
+ * @return     int
+ */
+int SDRM_GenerateDHParam(CryptoCoreContainer* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned char* pGenerator);
+
+/**
+ * @fn         SDRM_SetDHParam(SDRM_DHContext* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned int nGenerator)
+ * @brief      set parameters for Diffie-Hellman protocol
+ *
+ * @param      [out] crt                               context
+ * @param      [in]  pPrime                    prime number
+ * @param      [in]  nPrimeLen                 size of pPrime buffer
+ * @param      [in]  pGenerator                generator value
+ * @param      [in]  nGeneratorLen             generator len
+ * @return     int
+ */
+int SDRM_SetDHParam(CryptoCoreContainer* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned char* pGenerator, unsigned int nGeneratorLen);
+
+/**
+ * @fn         SDRM_GenerateDHPrivate(CryptoCoreContainer* crt, unsigned char* pPub)
+ * @brief      generate private value and calculate public value
+ *
+ * @param      [in]  crt                               context
+ * @param      [out] pPriv                             private value
+ * @param      [out] pPub                              public value
+ * @return     int
+ */
+int SDRM_GenerateDHPrivate(CryptoCoreContainer* crt, unsigned char* pPriv, unsigned char* pPub);
+
+/**
+ * @fn         SDRM_GetDHSharedSecret(CryptoCoreContainer* crt, unsigned char* pPub, unsigned char* pSharedSecret)
+ * @brief      calculate shared secret
+ *
+ * @param      [in]  crt                               context
+ * @param      [in]  pPriv                             private value
+ * @param      [in]  pPub                              guest's public value
+ * @param      [out] pSharedSecret             public value
+ * @return     int
+ */
+int SDRM_GetDHSharedSecret(CryptoCoreContainer* crt, unsigned char* pPriv, unsigned char* pPub, unsigned char* pSharedSecret);
+
+/**
+ * @fn         SDRM_FreeDHContext(CryptoCoreContainer* crt)
+ * @brief      free context buffer
+ *
+ * @param      [in]  crt                               context
+ */
+void SDRM_FreeDHContext(SDRM_DHContext* ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DIFFIE_HELLMAN_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_dsa.h b/ssflib/dep/cryptocore/include/middle/cc_dsa.h
new file mode 100755 (executable)
index 0000000..8ba4fd9
--- /dev/null
@@ -0,0 +1,171 @@
+/**
+ * \file       dsa.h
+ * @brief      implementation of dsa signature/verifycation
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/23
+ */
+
+#ifndef _CCDSA_H
+#define _CCDSA_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include "CC_API.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_DSAContext *SDRM_DSA_InitCrt(void)
+ * @brief      generate DSA Context
+ *
+ * @return     pointer to the generated context
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_DSAContext *SDRM_DSA_InitCrt(void);
+
+/*
+ * @fn         int SDRM_DSA_SetParam(CryptoCoreContainer *crt, cc_u8 *DSA_P_Data,      cc_u32 DSA_P_Len, cc_u8 *DSA_Q_Data,    cc_u32 DSA_Q_Len, cc_u8 *DSA_G_Data,    cc_u32 DSA_G_Len)
+ * @brief      set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      DSA_P_Data                                      [in]octet string of p value
+ * @param      DSA_P_Len                                       [in]legnth of p_val
+ * @param      DSA_Q_Data                                      [in]octet string of q value
+ * @param      DSA_Q_Len                                       [in]legnth of q_val
+ * @param      DSA_G_Data                                      [in]octet string of al value
+ * @param      DSA_G_Len                                       [in]legnth of al_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_SetParam(
+       CryptoCoreContainer *crt, 
+       cc_u8 *DSA_P_Data,      cc_u32 DSA_P_Len, 
+       cc_u8 *DSA_Q_Data,      cc_u32 DSA_Q_Len, 
+       cc_u8 *DSA_G_Data,      cc_u32 DSA_G_Len);
+
+/*
+ * @fn         int SDRM_DSA_SetKeyPair(CryptoCoreContainer *crt, cc_u8 *DSA_Y_Data, cc_u32 DSA_Y_Len, cc_u8 *DSA_X_Data, cc_u32 DSA_X_Len)
+ * @brief      set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      DSA_Y_Data                                      [in]octet string of y value
+ * @param      DSA_Y_Len                                       [in]legnth of y_val
+ * @param      DSA_X_Data                                      [in]octet string of a value
+ * @param      DSA_X_Len                                       [in]legnth of a_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_SetKeyPair(
+       CryptoCoreContainer *crt, 
+       cc_u8 *DSA_Y_Data, cc_u32 DSA_Y_Len, 
+       cc_u8 *DSA_X_Data, cc_u32 DSA_X_Len);
+
+/*
+ * @fn         int SDRM_DSA_GenParam(CryptoCoreContainer *crt, cc_u32 T_Siz, cc_u8 *DSA_P_Data, cc_u32 *DSA_P_Len, cc_u8 *DSA_Q_Data, cc_u32 *DSA_Q_Len, cc_u8 *DSA_G_Data, cc_u32 *DSA_G_Len)
+ * @brief      generate and set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      T_Siz                                           [in]fix the length of p to 512 + 64t bit (0 <= T_Siz <= 8)
+ * @param      DSA_P_Data                                      [out]octet string of p value
+ * @param      DSA_P_Len                                       [out]legnth of p_val
+ * @param      DSA_Q_Data                                      [out]octet string of q value
+ * @param      DSA_Q_Len                                       [out]legnth of q_val
+ * @param      DSA_G_Data                                      [out]octet string of al value
+ * @param      DSA_G_Len                                       [out]legnth of al_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_GenParam(
+       CryptoCoreContainer *crt, 
+       cc_u32 T_Siz, cc_u8 *DSA_P_Data, cc_u32 *DSA_P_Len, 
+       cc_u8 *DSA_Q_Data, cc_u32 *DSA_Q_Len, 
+       cc_u8 *DSA_G_Data, cc_u32 *DSA_G_Len);
+
+/*
+ * @fn         int SDRM_DSA_GenKeypair(CryptoCoreContainer *crt, cc_u8 *DSA_Y_Data, cc_u32 *DSA_Y_Len, cc_u8 *DSA_X_Data, cc_u32 *DSA_X_Len)
+ * @brief      generate and set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      DSA_Y_Data                                      [out]octet string of y value
+ * @param      DSA_Y_Len                                       [out]legnth of y_val
+ * @param      DSA_X_Data                                      [out]octet string of a value
+ * @param      DSA_X_Len                                       [out]legnth of a_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_GenKeypair(
+       CryptoCoreContainer *crt, 
+       cc_u8 *DSA_Y_Data, cc_u32 *DSA_Y_Len, 
+       cc_u8 *DSA_X_Data, cc_u32 *DSA_X_Len);
+
+/*
+ * @fn         int SDRM_DSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      hash                            [in]hash value
+ * @param      hashLen                         [in]byte-length of hash
+ * @param      signature                       [out]generated signature
+ * @param      signLen                         [out]byte-length of signature
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_DSA_sign(
+       CryptoCoreContainer *crt,
+       cc_u8 *hash, cc_u32 hashLen,
+       cc_u8 *signature, cc_u32 *signLen);
+
+/*
+ * @fn         int SDRM_DSA_verify(CryptoCoreContainer *crt,cc_u8 *hash, cc_u32 hashLen,cc_u8 *signature, cc_u32 signLen,int *result)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      hash                                    [in]hash value
+ * @param      hashLen                                 [in]byte-length of hash
+ * @param      signature                               [in]signature
+ * @param      signLen                                 [in]byte-length of signature
+ * @param      result                                  [in]result of veryfing signature
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if the length of signature is invalid
+ */
+int SDRM_DSA_verify(
+       CryptoCoreContainer *crt,
+       cc_u8 *hash, cc_u32 hashLen,
+       cc_u8 *signature, cc_u32 signLen,
+       int *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DSA_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_ecdh.h b/ssflib/dep/cryptocore/include/middle/cc_ecdh.h
new file mode 100755 (executable)
index 0000000..8caa853
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * \file       ecdh.h
+ * @brief      implementation of EC Diffie-Hellman Key Exchange Protocol
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/27
+ */
+
+#ifndef _CCECDH_H
+#define _CCECDH_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include "CC_API.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_generateDH1stPhaseKey(CryptoCoreContainer *crt, cc_u8 *pchXk, cc_u8 *pchXv)
+ * @brief      generate Xk and its Xv
+ *
+ * @param      crt                                     [in]crypto context
+ * @param      pchXk                           [out]Generated Random Number
+ * @param      pchXv                           [out]DH 1st phase value
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_generateDH1stPhaseKey(CryptoCoreContainer *crt, cc_u8 *pchXk, cc_u8 *pchXv);
+
+/*
+ * @fn         int SDRM_generateDHKey(CryptoCoreContainer *crt, cc_u8* pchXk, cc_u8* pchYv, cc_u8* pchKauth)
+ * @brief      genenrate auth key with Xk and Yv
+ *
+ * @param      crt                                     [in]crypto context
+ * @param      pchXk                           [in]Generated Random Number
+ * @param      pchYv                           [in]DH 1st phase value
+ * @param      pchKauth                        [out]authentication key
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_generateDHKey(CryptoCoreContainer *crt, cc_u8* pchXk, cc_u8* pchYv, cc_u8* pchKauth);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _ECDH_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_ecdsa.h b/ssflib/dep/cryptocore/include/middle/cc_ecdsa.h
new file mode 100755 (executable)
index 0000000..c9fd27f
--- /dev/null
@@ -0,0 +1,144 @@
+/**
+ * \file       ecdsa.h
+ * @brief      implementation of public key signature algorithm
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/13
+ */
+
+#ifndef _CCECDSA_H
+#define _CCECDSA_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CC_API.h"
+#include "cc_ecc.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_ECDSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      hash                            [in]hash value
+ * @param      hashLen                         [in]byte-length of hash
+ * @param      signature                       [out]generated signature
+ * @param      signLen                         [out]byte-length of signature
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_ECDSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen);
+
+/*
+ * @fn         int SDRM_ECDSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      hash                                    [in]hash value
+ * @param      hashLen                                 [in]byte-length of hash
+ * @param      signature                               [in]signature
+ * @param      signLen                                 [in]byte-length of signature
+ * @param      result                                  [in]result of veryfing signature
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if the length of signature is invalid
+ */
+int SDRM_ECDSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result);
+
+/*
+ * @fn         SDRM_ECC_Set_CTX
+ * @brief      Set parameters for ECC
+ *
+ * @param      crt                                     [out]crypto env structure
+ * @param      Dimension                       [in]dimension
+ * @param      ECC_P_Data                      [in]represents p
+ * @param      ECC_P_Len                       [in]byte-length of p
+ * @param      ECC_A_Data                      [in]represents a
+ * @param      ECC_A_Len                       [in]byte-length of a
+ * @param      ECC_B_Data                      [in]represents b
+ * @param      ECC_B_Len                       [in]byte-length of b
+ * @param      ECC_G_X_Data            [in]represents x coordinate of g
+ * @param      ECC_G_X_Len                     [in]byte-length of x coordinate of g
+ * @param      ECC_G_Y_Data            [in]represents y coordinate of g
+ * @param      ECC_G_Y_Len                     [in]byte-length of y coordinate of g
+ * @param      ECC_R_Data                      [in]represents r
+ * @param      ECC_R_Len                       [in]byte-length of r
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if argument is null
+ */
+int SDRM_ECC_Set_CTX(
+       struct _CryptoCoreContainer *crt, cc_u16 Dimension, 
+       cc_u8* ECC_P_Data,   cc_u32 ECC_P_Len,
+       cc_u8* ECC_A_Data,   cc_u32 ECC_A_Len,
+       cc_u8* ECC_B_Data,   cc_u32 ECC_B_Len,
+       cc_u8* ECC_G_X_Data, cc_u32 ECC_G_X_Len,
+       cc_u8* ECC_G_Y_Data, cc_u32 ECC_G_Y_Len,
+       cc_u8* ECC_R_Data,   cc_u32 ECC_R_Len
+);
+
+/*
+ * @fn         SDRM_ECC_genKeypair
+ * @brief      Generate Private Key and Generate Key Pair for ECC Signature
+ *
+ * @param      crt                                     [out]crypto env structure
+ * @param      PrivateKey                      [in]represents x coordinate of public key
+ * @param      PrivateKeyLen           [in]byte-length of x coordinate of public key
+ * @param      PublicKey_X                     [in]represents x coordinate of public key
+ * @param      PublicKey_XLen          [in]byte-length of x coordinate of public key
+ * @param      PublicKey_Y                     [in]represents y coordinate of public key
+ * @param      PublicKey_YLen          [in]byte-length of y coordinate of public key
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if argument is null
+ */
+int SDRM_ECC_genKeypair(
+       CryptoCoreContainer *crt,
+       cc_u8 *PrivateKey,  cc_u32 *PrivateKeyLen, 
+       cc_u8 *PublicKey_X, cc_u32 *PublicKey_XLen,
+       cc_u8 *PublicKey_Y, cc_u32 *PublicKey_YLen
+);
+                                                                                               
+/*
+ * @fn         SDRM_ECC_setKeypair
+ * @brief      Set key data for ECC
+ *
+ * @param      crt                                     [out]crypto env structure
+ * @param      PRIV_Data                       [in]represents private key
+ * @param      PRIV_Len                        [in]byte-length of private key
+ * @param      PUB_X_Data                      [in]represents x coordinate of public key
+ * @param      PUB_X_Len                       [in]byte-length of x coordinate of public key
+ * @param      PUB_Y_Data                      [in]represents y coordinate of public key
+ * @param      PUB_Y_Len                       [in]byte-length of y coordinate of public key
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if argument is null
+ */
+int SDRM_ECC_setKeypair(
+       CryptoCoreContainer *crt,
+       cc_u8* PRIV_Data,  cc_u32 PRIV_Len,
+       cc_u8* PUB_X_Data, cc_u32 PUB_X_Len,
+       cc_u8* PUB_Y_Data, cc_u32 PUB_Y_Len
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_hmac.h b/ssflib/dep/cryptocore/include/middle/cc_hmac.h
new file mode 100755 (executable)
index 0000000..73e1df5
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * \file       hmac.h
+ * @brief      funciton for c-mac code generation by SHA1 and MD5
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/19
+ */
+
+
+#ifndef _CCHMAC_H
+#define _CCHMAC_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CC_API.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_HMAC_init
+ * @brief      Parameter setting for mac code generation
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_HMAC_init(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen);
+
+/*
+ * @fn         SDRM_HMAC_update
+ * @brief      process data blocks
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_HMAC_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen);
+
+/*
+ * @fn         SDRM_HMAC_final
+ * @brief      process last data block
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_HMAC_final(CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         SDRM_HMAC_getMAC
+ * @brief      generate h-mac code
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ */
+int SDRM_HMAC_getMAC(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _HMAC_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_rng.h b/ssflib/dep/cryptocore/include/middle/cc_rng.h
new file mode 100755 (executable)
index 0000000..9be75c7
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * \file       rng.h
+ * @brief      Random Number Generator Interface
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon, Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/07
+ */
+
+
+#ifndef _CCRNG_H
+#define _CCRNG_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <time.h>
+#include "CC_API.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_X931_seed
+ * @brief      Seed RNG System
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      seed                            [in]seed for RNG System
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ */
+int SDRM_X931_seed(CryptoCoreContainer *crt, cc_u8 *seed);
+
+/*
+ * @fn         SDRM_X931_get
+ * @brief      generate random number
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      bitLength                       [in]bit length for generated number
+ * @param      data                            [out]generated data
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ */
+int    SDRM_X931_get(CryptoCoreContainer *crt, cc_u32 bitLength, cc_u8 *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _RNG_H
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_rsa.h b/ssflib/dep/cryptocore/include/middle/cc_rsa.h
new file mode 100755 (executable)
index 0000000..6c37c69
--- /dev/null
@@ -0,0 +1,351 @@
+/**
+ * \file       rsa.h
+ * @brief      implementation of rsa encryption/decryption and signature/verifycation
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/20
+ */
+
+
+#ifndef _CCRSA_H
+#define _CCRSA_H
+
+//////////////////////////////////////////////////////////////////////////
+// Include Header Files
+//////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include "CC_API.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+//////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_RSA_InitCrt
+ * @brief      generate RSA Context
+ *
+ * @return     pointer to the generated context
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_RSAContext *SDRM_RSA_InitCrt(cc_u32 RSAKeyByteLen);
+
+/*
+ * @fn         SDRM_RSA_setNED
+ * @brief      set RSA parameters
+ *
+ * @param      crt                                     [out]rsa context
+ * @param      PaddingMethod           [in]padding method
+ * @param      RSA_N_Data                      [in]n value
+ * @param      RSA_N_Len                       [in]byte-length of n
+ * @param      RSA_E_Data                      [in]e value
+ * @param      RSA_E_Len                       [in]byte-length of e
+ * @param      RSA_D_Data                      [in]d value
+ * @param      RSA_D_Len                       [in]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if an argument is a null pointer
+ */
+int SDRM_RSA_setNED
+(
+       CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+       cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+       cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+       cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len
+);
+
+/*
+ * @fn         SDRM_RSA_setNEDPQ
+ * @brief      set RSA parameters
+ *
+ * @param      crt                                     [out]rsa context
+ * @param      PaddingMethod           [in]padding method
+ * @param      RSA_N_Data                      [in]n value
+ * @param      RSA_N_Len                       [in]byte-length of n
+ * @param      RSA_E_Data                      [in]e value
+ * @param      RSA_E_Len                       [in]byte-length of e
+ * @param      RSA_D_Data                      [in]d value
+ * @param      RSA_D_Len                       [in]byte-length of d
+ * @param      RSA_P_Data                      [in]p value
+ * @param      RSA_P_Len                       [in]byte-length of p
+ * @param      RSA_Q_Data                      [in]q value
+ * @param      RSA_Q_Len                       [in]byte-length of q
+ * @param      RSA_DmodP1_Data         [in]d mod (p-1) value
+ * @param      RSA_DmodP1_Len          [in]byte-length of d mod (p-1)
+ * @param      RSA_DmodQ1_Data         [in]d mod (q-1) value
+ * @param      RSA_DmodQ1_Len          [in]byte-length of d mod (q-1)
+ * @param      RSA_iQmodP_Data         [in]q^(-1) mod p value
+ * @param      RSA_iQmodP_Len          [in]byte-length of q^(-1) mod p
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if an argument is a null pointer
+ */
+int SDRM_RSA_setNEDPQ
+(
+       CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+       cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+       cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+       cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len,
+       cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+       cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+       cc_u8* RSA_DmodP1_Data,   cc_u32 RSA_DmodP1_Len,
+       cc_u8* RSA_DmodQ1_Data,   cc_u32 RSA_DmodQ1_Len,
+       cc_u8* RSA_iQmodP_Data,   cc_u32 RSA_iQmodP_Len
+);
+
+/*
+ * @fn         SDRM_RSA_GenerateKey
+ * @brief      generate and set RSA parameters
+ *
+ * @param      crt                                                     [out]rsa context
+ * @param      PaddingMethod                           [out]padding method
+ * @param      RSA_N_Data                                      [out]n value
+ * @param      RSA_N_Len                                       [out]byte-length of n
+ * @param      RSA_E_Data                                      [out]e value
+ * @param      RSA_E_Len                                       [out]byte-length of e
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateKey
+(
+       CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+       cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+       cc_u8* RSA_E_Data,   cc_u32 *RSA_E_Len,
+       cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len
+);
+
+/*!    \brief  generate and set RSA parameters
+ * \param      crt                                                     [in/out]rsa context
+ * \param      PaddingMethod                           [in]padding method
+ * \param      RSA_N_Data                                      [out]n value
+ * \param      RSA_N_Len                                       [out]byte-length of n
+ * \param      RSA_E_Data                                      [in]e value
+ * \param      RSA_E_Len                                       [in]byte-length of e
+ * \param      RSA_D_Data                                      [out]d value
+ * \param      RSA_D_Len                                       [out]byte-length of d
+  * \param     RSA_P_Data                                      [out]p value
+ * \param      RSA_P_Len                                       [out]byte-length of p
+ * \param      RSA_Q_Data                                      [out]q value
+ * \param      RSA_Q_Len                                       [out]byte-length of q
+ * \param      RSA_DP_Data                             [out]dmodp1 value
+ * \param      RSA_DP_Len                                      [out]byte-length of dmodp1
+  * \param     RSA_DQ_Data                             [out]dmodq1 value
+ * \param      RSA_DQ_Len                              [out]byte-length of dmodq1
+ * \param      RSA_QP_Data                             [out]iqmodp value
+ * \param      RSA_QP_Len                                      [out]byte-length of iqmodp
+ * \return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateKeyforCRT(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                cc_u8* RSA_E_Data,      cc_u32 RSA_E_Len,
+                                                cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,                 
+                                                cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len,
+                                                cc_u8* RSA_P_Data,   cc_u32 *RSA_P_Len,
+                                                cc_u8* RSA_Q_Data,   cc_u32 *RSA_Q_Len,
+                                                cc_u8* RSA_DP_Data,   cc_u32 *RSA_DP_Len,
+                                                cc_u8* RSA_DQ_Data,   cc_u32 *RSA_DQ_Len,
+                                                cc_u8* RSA_QP_Data,   cc_u32 *RSA_QP_Len
+);
+/*
+ * @fn         SDRM_RSA_GenerateND
+ * @brief      generate and set RSA parameters with specfied e
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_E_Data                                      [in]e value
+ * @param      RSA_E_Len                                       [in]byte-length of e
+ * @param      RSA_N_Data                                      [out]n value
+ * @param      RSA_N_Len                                       [out]byte-length of n
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateND
+(
+       CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+       cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+       cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+       cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len
+);
+
+/*     
+ * @fn         SDRM_RSA_GenerateDwithPQE
+ * @brief      generate D with specfied p, q, d mod (p-1), d mod (q-1) and e
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_E_Data                                      [in]e value
+ * @param      RSA_E_Len                                       [in]byte-length of e
+ * @param      RSA_P_Data                                      [in]n value
+ * @param      RSA_P_Len                                       [in]byte-length of n
+ * @param      RSA_Q_Data                                      [in]d value
+ * @param      RSA_Q_Len                                       [in]byte-length of d
+ * @param      RSA_D_P_Data                            [in]d mod (p-1) value
+ * @param      RSA_D_P_Len                                     [in]byte-length of d mod (p-1) 
+ * @param      RSA_D_Q_Data                            [in]d mod (q-1)  value
+ * @param      RSA_D_Q_Len                                     [in]byte-length of d mod (q-1) 
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateDwithPQE
+(
+       CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+       cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+       cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+       cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+       cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+       cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len
+);
+
+/*
+ * @fn         int SDRM_RSA_GenNEDPQ(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+ *                                              cc_u8* RSA_N_Data, cc_u32 *RSA_N_Len,
+ *                                              cc_u8* RSA_E_Data, cc_u32 *RSA_E_Len,
+ *                                              cc_u8* RSA_D_Data, cc_u32 *RSA_D_Len,
+ *                                              cc_u8* RSA_P_Data, cc_u32 *RSA_P_Len,
+ *                                              cc_u8* RSA_Q_Data, cc_u32 *RSA_Q_Len,
+ *                                              cc_u8* RSA_DmodP1_Data, cc_u32 *RSA_DmodP1_Len,
+ *                                              cc_u8* RSA_DmodQ1_Data, cc_u32 *RSA_DmodQ1_Len,
+ *                                              cc_u8* RSA_iQmodP_Data, cc_u32 *RSA_iQmodP_Len)
+ * @brief      generate and set RSA parameters for CRT
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_N_Data                                      [out]n value
+ * @param      RSA_N_Len                                       [out]byte-length of n
+ * @param      RSA_E_Data                                      [out]e value
+ * @param      RSA_E_Len                                       [out]byte-length of e
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ * @param      RSA_P_Len                                       [out]byte-length of p
+ * @param      RSA_Q_Data                                      [out]q value
+ * @param      RSA_Q_Len                                       [out]byte-length of q
+ * @param      RSA_DmodP1_Data                         [out]d mod (p-1) value
+ * @param      RSA_DmodP1_Len                          [out]byte-length of d mod (p-1)
+ * @param      RSA_DmodQ1_Data                         [out]d mod (q-1) value
+ * @param      RSA_DmodQ1_Len                          [out]byte-length of d mod (q-1)
+ * @param      RSA_iQmodP_Data                         [out]q^(-1) mod p value
+ * @param      RSA_iQmodP_Len                          [out]byte-length of q^(-1) mod p
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenNEDPQ(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                cc_u8* RSA_N_Data, cc_u32 *RSA_N_Len,
+                                                cc_u8* RSA_E_Data, cc_u32 *RSA_E_Len,
+                                                cc_u8* RSA_D_Data, cc_u32 *RSA_D_Len,
+                                                cc_u8* RSA_P_Data, cc_u32 *RSA_P_Len,
+                                                cc_u8* RSA_Q_Data, cc_u32 *RSA_Q_Len,
+                                                cc_u8* RSA_DmodP1_Data, cc_u32 *RSA_DmodP1_Len,
+                                                cc_u8* RSA_DmodQ1_Data, cc_u32 *RSA_DmodQ1_Len,
+                                                cc_u8* RSA_iQmodP_Data, cc_u32 *RSA_iQmodP_Len);
+
+/*
+ * @fn         SDRM_RSA_encrypt
+ * @brief      generate and set RSA parameters
+ *
+ * @param      crt                                                     [in]rsa context
+ * @param      in                                                      [in]message to encrypt
+ * @param      inLen                                           [in]byte-length of in
+ * @param      out                                                     [out]encrypted message
+ * @param      outLen                                          [out]byte-length of out
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_encrypt(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+
+/*
+ * @fn         SDRM_RSA_decrypt
+ * @brief      RSA Decryption
+ *
+ * @param      crt                                                     [in]rsa context
+ * @param      in                                                      [in]message to decrypt
+ * @param      inLen                                           [in]byte-length of in
+ * @param      out                                                     [out]decrypted message
+ * @param      outLen                                          [out]byte-length of out
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_decrypt(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+
+/*
+ * @fn         SDRM_RSA_decryptByCRT
+ * @brief      RSA Decryption using CRT
+ *
+ * @param      crt                                                     [in]rsa context
+ * @param      in                                                      [in]message to decrypt
+ * @param      inLen                                           [in]byte-length of in
+ * @param      out                                                     [out]decrypted message
+ * @param      outLen                                          [out]byte-length of out
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_decryptByCRT(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+
+/*
+ * @fn         SDRM_RSA_sign
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      hash                            [in]hash value
+ * @param      hashLen                         [in]byte-length of hash
+ * @param      signature                       [out]generated signature
+ * @param      signLen                         [out]byte-length of signature
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_RSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen);
+
+/*
+ * @fn         SDRM_RSA_verify
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      hash                                    [in]hash value
+ * @param      hashLen                                 [in]byte-length of hash
+ * @param      signature                               [in]signature
+ * @param      signLen                                 [in]byte-length of signature
+ * @param      result                                  [in]result of veryfing signature
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if the length of signature is invalid
+ */
+int SDRM_RSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_symmetric.h b/ssflib/dep/cryptocore/include/middle/cc_symmetric.h
new file mode 100755 (executable)
index 0000000..f49c7a1
--- /dev/null
@@ -0,0 +1,247 @@
+/**
+ * \file       symmetric.h
+ * @brief      API for symmetric encryption
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon, Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/07
+ */
+
+
+#ifndef _CCSYMMETRIC_H
+#define _CCSYMMETRIC_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CC_API.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         SDRM_AES_init
+ * @brief      intialize crypt context for aes
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_AES_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV);
+
+/*
+ * @fn         SDRM_AES_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      Text                                    [in]message block
+ * @param      TextLen                                 [in]byte-length of Text
+ * @param      output                                  [out]proecessed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_AES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         SDRM_AES_final
+ * @brief      process final block and padding
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      input                                   [in]message block
+ * @param      inputLen                                [in]byte-length of Text
+ * @param      output                                  [out]processed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_AES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         SDRM_RC4_init
+ * @brief      intialize crypt context for RC4
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method, not needed
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector, not needed
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_RC4_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV);
+
+/*
+ * @fn         SDRM_RC4_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      Text                                    [in]message block
+ * @param      TextLen                                 [in]byte-length of Text
+ * @param      output                                  [out]proecessed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_RC4_process(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+
+/*     
+ * @fn         SDRM_SNOW2_init
+ * @brief      intialize crypt context for SNOW2
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method, not needed
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_SNOW2_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV);
+
+/*
+ * @fn
+ * @brief      process message block
+ * @param      crt                                             [in]crypto env structure
+ * @param      in                                              [in]message block
+ * @param      inLen                                   [in]byte-length of Text
+ * @param      out                                             [out]processed message
+ * @param      outLen                                  [out]byte-length of output
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_SNOW2_process(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen);
+
+/*
+ * @fn         SDRM_DES_init
+ * @brief      intialize crypt context for des
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_DES_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV);
+
+/*
+ * @fn         SDRM_DES_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      in                                              [in]message block       
+ * @param      inLen                                   [in]byte-length of Text
+ * @param      out                                             [out]processed message
+ * @param      outLen                                  [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_DES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         SDRM_DES_final
+ * @brief      process final block and padding
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      input                                   [in]message block
+ * @param      inputLen                                [in]byte-length of Text
+ * @param      output                                  [out]processed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_DES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         SDRM_TDES_init
+ * @brief      intialize crypt context for triple des
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_TDES_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV);
+
+/*
+ * @fn         SDRM_TDES_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      Text                                    [in]message block
+ * @param      TextLen                                 [in]byte-length of Text
+ * @param      output                                  [out]proecessed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_TDES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen);
+
+/*
+ * @fn         SDRM_TDES_final
+ * @brief      process final block and padding
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      input                                   [in]message block
+ * @param      inputLen                                [in]byte-length of Text
+ * @param      output                                  [out]processed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_TDES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/include/middle/cc_tdes.h b/ssflib/dep/cryptocore/include/middle/cc_tdes.h
new file mode 100755 (executable)
index 0000000..386fae9
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * \file       tdes.h
+ * @brief      high-speed implementation of Triple DES-EDE
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/06
+ */
+
+
+#ifndef _CCTDES_H
+#define _CCTDES_H
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "CryptoCore.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Function Prototypes
+////////////////////////////////////////////////////////////////////////////
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * @fn         int SDRM_TDES_KeySched(cc_u8 *RoundKey, cc_u8 *UserKey, cc_u32 KeyLen, cc_u32 RKStep)
+ * @brief      Expand the cipher key into the encryption key schedule
+ *
+ * @param      RoundKey                        [out]generated round key
+ * @param      UserKey                         [in]user key, 16 or 24 byte
+ * @param      KeyLen                          [in]byte-length of UserKey
+ * @param      RKStep                          [in]operation mode
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_TDES_KeySched(cc_u8 *RoundKey, cc_u8 *UserKey, cc_u32 KeyLen, cc_u32 RKStep);
+
+/*
+ * @fn         int SDRM_TDES_Encryption(cc_u32 RoundKey[][2], cc_u8 *msg, cc_u8 *out)
+ * @brief      Triple DES processing for one block
+ *
+ * @param      RoundKey                        [in]expanded round key
+ * @param      msg                                     [in]8 byte plaintext
+ * @param      out                                     [out]8 byte ciphertext
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_TDES_Encryption(cc_u32 RoundKey[][2], cc_u8 *msg, cc_u8 *out);
+
+/*
+ * @fn         int SDRM_TDES64_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey)
+ * @brief      one block Triple DES Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_TDES64_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey);
+
+/*
+ * @fn         int SDRM_TDES64_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey)
+ * @brief      one block Triple DES Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_TDES64_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/CC_API.c b/ssflib/dep/cryptocore/source/CC_API.c
new file mode 100755 (executable)
index 0000000..9fa7d66
--- /dev/null
@@ -0,0 +1,448 @@
+/**
+ * \file       CC_API.c
+ * @brief      API of samsung Crypto Library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jae Heung Lee
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/10/24
+ * Note : modified for implementation, by Jisoon, Park, 06/11/06
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+#include "CryptoCore.h"
+#include "cc_rng.h"
+#include "cc_symmetric.h"
+#include "cc_hash.h"
+#include "cc_ecdsa.h"
+#include "cc_cmac.h"
+#include "cc_rsa.h"
+#include "cc_dsa.h"
+#include "cc_ecdh.h"
+#include "cc_hmac.h"
+#include "cc_dh.h"
+
+////////////////////////////////////////////////////////////////////////////
+// functions
+////////////////////////////////////////////////////////////////////////////
+void *CCMalloc(int siz)
+{
+       cc_u8 *pbBuf = (cc_u8*)malloc(siz);
+
+       if (pbBuf == NULL)
+       {
+               return NULL;
+       }
+       else
+       {
+               memset(pbBuf, 0, siz);
+               return (void*)pbBuf;
+       }
+}
+
+void CCFree(void *ptr)
+{
+       if (ptr != NULL)
+       {
+               free(ptr);
+       }
+}
+
+/*
+ * @fn         CryptoCoreContainer *create_CryptoCoreContainer(cc_u32 algorithm)
+ * @brief      memory allocation and initialize the crypt sturcture
+ *
+ * @param      algorithm       [in]algorithm want to use
+ *
+ * @return     address of created sturcture
+ */
+CryptoCoreContainer *create_CryptoCoreContainer(cc_u32 algorithm)
+{
+       CryptoCoreContainer *crt;
+       srand((unsigned int)time(NULL));
+
+       // allocate memory for crypt data structure (by using CCMalloc)
+       crt = (CryptoCoreContainer *)CCMalloc(sizeof(CryptoCoreContainer));
+       if (crt == NULL)
+       {
+               return NULL;
+       }
+
+       crt->ctx = (CryptoCoreCTX *)CCMalloc(sizeof(CryptoCoreCTX));
+       if (crt->ctx == NULL)
+       {
+               free(crt);
+               return NULL;
+       }
+       
+       crt->PRNG_seed                  = NULL;
+       crt->PRNG_get                   = NULL;
+       crt->MD_init                            = NULL;
+       crt->MD_update                  = NULL;
+       crt->MD_final                   = NULL;
+       crt->MD_getHASH                 = NULL;
+       crt->MAC_init                   = NULL;
+       crt->MAC_update                 = NULL;
+       crt->MAC_final                  = NULL;
+       crt->MAC_getMAC                 = NULL;
+       crt->SE_init                            = NULL;
+       crt->SE_process                 = NULL;
+       crt->SE_final                   = NULL;
+       crt->AE_encrypt                 = NULL;
+       crt->AE_decrypt                 = NULL;
+       crt->DS_sign                            = NULL;
+       crt->DS_verify                  = NULL;
+       crt->DSA_genParam               = NULL;
+       crt->DSA_setParam               = NULL;
+       crt->DSA_genKeypair             = NULL;
+       crt->DSA_setKeyPair             = NULL;
+       crt->RSA_genKeypair             = NULL;
+       crt->RSA_genKeypairWithE= NULL;
+    crt->RSA_genKeypairForCRT = NULL;
+       crt->RSA_genKeyDWithPQE = NULL;
+       crt->RSA_genKeypairWithEforCRT= NULL;
+       crt->RSA_setKeypair             = NULL;
+    crt->RSA_setKeypairForCRT = NULL;
+       crt->EC_setCurve                        = NULL;
+       crt->EC_genKeypair              = NULL;
+       crt->EC_setKeypair              = NULL;
+       crt->DH_GenerateParam   = NULL;
+       crt->DH_SetParam                        = NULL;
+       crt->DH_Gen1stPhaseKey  = NULL;
+       crt->DH_GenAuthKey              = NULL;
+       crt->ECDH_Gen1stPhaseKey= NULL;
+       crt->ECDH_GenAuthKey            = NULL;
+
+       // allocate memory for context data structure
+       // and set up the member functions according to the algorithm
+       crt->alg = algorithm;
+       switch(algorithm)
+       {
+               case ID_X931:
+                       crt->ctx->x931ctx                       = (SDRM_X931Context*)CCMalloc(sizeof(SDRM_X931Context));
+                       crt->PRNG_seed                          = SDRM_X931_seed;
+                       crt->PRNG_get                           = SDRM_X931_get;
+                       break;
+               case ID_MD5:
+                       crt->ctx->md5ctx                        = (SDRM_MD5Context*)CCMalloc(sizeof(SDRM_MD5Context));
+                       crt->MD_init                            = SDRM_MD5_init;
+                       crt->MD_update                          = SDRM_MD5_update;
+                       crt->MD_final                           = SDRM_MD5_final;
+                       crt->MD_getHASH                         = SDRM_MD5_hash;
+                       break;  
+               case ID_SHA1:
+                       crt->ctx->sha1ctx                       = (SDRM_SHA1Context*)CCMalloc(sizeof(SDRM_SHA1Context));
+                       crt->MD_init                            = SDRM_SHA1_init;
+                       crt->MD_update                          = SDRM_SHA1_update;
+                       crt->MD_final                           = SDRM_SHA1_final;
+                       crt->MD_getHASH                         = SDRM_SHA1_hash;
+                       break;
+               case ID_SHA224:
+                       crt->ctx->sha224ctx                     = (SDRM_SHA224Context*)CCMalloc(sizeof(SDRM_SHA224Context));
+                       crt->MD_init                            = SDRM_SHA224_init;
+                       crt->MD_update                          = SDRM_SHA224_update;
+                       crt->MD_final                           = SDRM_SHA224_final;
+                       crt->MD_getHASH                         = SDRM_SHA224_hash;
+                       break;
+               case ID_SHA256:
+                       crt->ctx->sha256ctx                     = (SDRM_SHA256Context*)CCMalloc(sizeof(SDRM_SHA256Context));
+                       crt->MD_init                            = SDRM_SHA256_init;
+                       crt->MD_update                          = SDRM_SHA256_update;
+                       crt->MD_final                           = SDRM_SHA256_final;
+                       crt->MD_getHASH                         = SDRM_SHA256_hash;
+                       break;
+#ifndef _OP64_NOTSUPPORTED
+               case ID_SHA384:
+                       crt->ctx->sha384ctx                     = (SDRM_SHA384Context*)CCMalloc(sizeof(SDRM_SHA384Context));
+                       crt->MD_init                            = SDRM_SHA384_init;
+                       crt->MD_update                          = SDRM_SHA384_update;
+                       crt->MD_final                           = SDRM_SHA384_final;
+                       crt->MD_getHASH                         = SDRM_SHA384_hash;
+                       break;
+               case ID_SHA512:
+                       crt->ctx->sha512ctx                     = (SDRM_SHA512Context*)CCMalloc(sizeof(SDRM_SHA512Context));
+                       crt->MD_init                            = SDRM_SHA512_init;
+                       crt->MD_update                          = SDRM_SHA512_update;
+                       crt->MD_final                           = SDRM_SHA512_final;
+                       crt->MD_getHASH                         = SDRM_SHA512_hash;
+                       break;
+#endif
+               case ID_CMAC:
+                       crt->ctx->cmacctx                       = (SDRM_CMACContext*)CCMalloc(sizeof(SDRM_CMACContext));
+                       crt->MAC_init                           = SDRM_CMAC_init;
+                       crt->MAC_update                         = SDRM_CMAC_update;
+                       crt->MAC_final                          = SDRM_CMAC_final;
+                       crt->MAC_getMAC                         = SDRM_CMAC_getMAC;
+                       break;
+               case ID_HMD5:
+               case ID_HSHA1:
+               case ID_HSHA224:
+               case ID_HSHA256:
+#ifndef _OP64_NOTSUPPORTED
+               case ID_HSHA384:
+               case ID_HSHA512:
+#endif //_OP64_NOTSUPPORTED
+                       crt->ctx->hmacctx                       = (SDRM_HMACContext*)CCMalloc(sizeof(SDRM_HMACContext));
+                       crt->MAC_init                           = SDRM_HMAC_init;
+                       crt->MAC_update                         = SDRM_HMAC_update;
+                       crt->MAC_final                          = SDRM_HMAC_final;
+                       crt->MAC_getMAC                         = SDRM_HMAC_getMAC;
+                       break;
+               case ID_DH :
+                       crt->ctx->dhctx                         = (SDRM_DHContext*)CCMalloc(sizeof(SDRM_DHContext));
+                       crt->DH_GenerateParam           = SDRM_GenerateDHParam;
+                       crt->DH_SetParam                        = SDRM_SetDHParam;
+                       crt->DH_Gen1stPhaseKey          = SDRM_GenerateDHPrivate;
+                       crt->DH_GenAuthKey                      = SDRM_GetDHSharedSecret;
+                       break;
+               case ID_ECDH : 
+                       crt->ctx->ecdhctx                       = (SDRM_ECDHContext*)SDRM_CURVE_Init();
+                       crt->EC_setCurve                        = SDRM_ECC_Set_CTX;
+                       crt->EC_genKeypair                      = SDRM_ECC_genKeypair;
+                       crt->EC_setKeypair                      = SDRM_ECC_setKeypair;
+                       crt->ECDH_Gen1stPhaseKey        = SDRM_generateDH1stPhaseKey;
+                       crt->ECDH_GenAuthKey            = SDRM_generateDHKey;
+                       break;
+               case ID_AES128:
+                       crt->ctx->aesctx                        = (SDRM_AESContext*)CCMalloc(sizeof(SDRM_AESContext));
+                       crt->SE_init                            = SDRM_AES_init;
+                       crt->SE_process                         = SDRM_AES_process;
+                       crt->SE_final                           = SDRM_AES_final;
+                       crt->SE_EncryptOneBlock         = SDRM_AES128_Encryption;
+                       crt->SE_DecryptOneBlock         = SDRM_AES128_Decryption;
+                       break;
+               case ID_AES192:
+                       crt->ctx->aesctx                        = (SDRM_AESContext*)CCMalloc(sizeof(SDRM_AESContext));
+                       crt->SE_init                            = SDRM_AES_init;
+                       crt->SE_process                         = SDRM_AES_process;
+                       crt->SE_final                           = SDRM_AES_final;
+                       crt->SE_EncryptOneBlock         = SDRM_AES192_Encryption;
+                       crt->SE_DecryptOneBlock         = SDRM_AES192_Decryption;
+                       break;
+               case ID_AES256:
+                       crt->ctx->aesctx                        = (SDRM_AESContext*)CCMalloc(sizeof(SDRM_AESContext));
+                       crt->SE_init                            = SDRM_AES_init;
+                       crt->SE_process                         = SDRM_AES_process;
+                       crt->SE_final                           = SDRM_AES_final;
+                       crt->SE_EncryptOneBlock         = SDRM_AES256_Encryption;
+                       crt->SE_DecryptOneBlock         = SDRM_AES256_Decryption;
+                       break;
+               case ID_DES:
+                       crt->ctx->desctx                        = (SDRM_DESContext*)CCMalloc(sizeof(SDRM_DESContext));
+                       crt->SE_init                            = SDRM_DES_init;
+                       crt->SE_process                         = SDRM_DES_process;
+                       crt->SE_final                           = SDRM_DES_final;
+                       crt->SE_EncryptOneBlock         = SDRM_DES64_Encryption;
+                       crt->SE_DecryptOneBlock         = SDRM_DES64_Decryption;
+                       break;
+               case ID_TDES:
+                       crt->ctx->tdesctx                       = (SDRM_TDESContext*)CCMalloc(sizeof(SDRM_TDESContext));
+                       crt->SE_init                            = SDRM_TDES_init;
+                       crt->SE_process                         = SDRM_TDES_process;
+                       crt->SE_final                           = SDRM_TDES_final;
+                       crt->SE_EncryptOneBlock         = SDRM_TDES64_Encryption;
+                       crt->SE_DecryptOneBlock         = SDRM_TDES64_Decryption;
+                       break;
+               case ID_RC4:
+                       crt->ctx->rc4ctx                        = (SDRM_RC4Context*)CCMalloc(sizeof(SDRM_RC4Context));
+                       crt->SE_init                            = SDRM_RC4_init;
+                       crt->SE_process                         = SDRM_RC4_process;
+                       break;
+               case ID_SNOW2:
+                       crt->ctx->snow2ctx                      = (SDRM_SNOW2Context*)CCMalloc(sizeof(SDRM_SNOW2Context));
+                       crt->SE_init                            = SDRM_SNOW2_init;
+                       crt->SE_process                         = SDRM_SNOW2_process;
+                       break;
+               case ID_RSA512:
+                       crt->ctx->rsactx                        = SDRM_RSA_InitCrt(64);
+                       crt->RSA_genKeypair                     = SDRM_RSA_GenerateKey;
+                       crt->RSA_genKeypairWithE        = SDRM_RSA_GenerateND;
+                       crt->RSA_genKeyDWithPQE         = SDRM_RSA_GenerateDwithPQE;
+                       crt->RSA_genKeypairWithEforCRT  = SDRM_RSA_GenerateKeyforCRT;
+                       crt->RSA_setKeypair                     = SDRM_RSA_setNED;
+                       crt->RSA_setKeypairForCRT       = SDRM_RSA_setNEDPQ;
+                       crt->AE_encrypt                         = SDRM_RSA_encrypt;
+                       crt->AE_decrypt                         = SDRM_RSA_decrypt;
+                       crt->AE_decryptByCRT            = SDRM_RSA_decryptByCRT;
+                       crt->DS_sign                            = SDRM_RSA_sign;
+                       crt->DS_verify                          = SDRM_RSA_verify;
+                       break;
+               case ID_RSA:
+               case ID_RSA1024:
+                       crt->ctx->rsactx                        = SDRM_RSA_InitCrt(128);
+                       crt->RSA_genKeypair                     = SDRM_RSA_GenerateKey;
+                       crt->RSA_genKeypairWithE        = SDRM_RSA_GenerateND;
+                       crt->RSA_genKeyDWithPQE         = SDRM_RSA_GenerateDwithPQE;
+                       crt->RSA_genKeypairWithEforCRT  = SDRM_RSA_GenerateKeyforCRT;
+                       crt->RSA_setKeypair                     = SDRM_RSA_setNED;
+                       crt->RSA_setKeypairForCRT       = SDRM_RSA_setNEDPQ;
+                       crt->AE_encrypt                         = SDRM_RSA_encrypt;
+                       crt->AE_decrypt                         = SDRM_RSA_decrypt;
+                       crt->AE_decryptByCRT            = SDRM_RSA_decryptByCRT;
+                       crt->DS_sign                            = SDRM_RSA_sign;
+                       crt->DS_verify                          = SDRM_RSA_verify;
+                       break;
+               case ID_RSA2048:
+                       crt->ctx->rsactx                        = SDRM_RSA_InitCrt(256);
+                       crt->RSA_genKeypair                     = SDRM_RSA_GenerateKey;
+                       crt->RSA_genKeypairWithE        = SDRM_RSA_GenerateND;
+                       crt->RSA_genKeyDWithPQE         = SDRM_RSA_GenerateDwithPQE;
+                       crt->RSA_genKeypairWithEforCRT  = SDRM_RSA_GenerateKeyforCRT;
+                       crt->RSA_setKeypair                     = SDRM_RSA_setNED;
+                       crt->RSA_setKeypairForCRT       = SDRM_RSA_setNEDPQ;
+                       crt->AE_encrypt                         = SDRM_RSA_encrypt;
+                       crt->AE_decrypt                         = SDRM_RSA_decrypt;
+                       crt->AE_decryptByCRT            = SDRM_RSA_decryptByCRT;
+                       crt->DS_sign                            = SDRM_RSA_sign;
+                       crt->DS_verify                          = SDRM_RSA_verify;
+                       break;
+               case ID_RSA3072:
+                       crt->ctx->rsactx                        = SDRM_RSA_InitCrt(384);
+                       crt->RSA_genKeypair                     = SDRM_RSA_GenerateKey;
+                       crt->RSA_genKeypairWithE        = SDRM_RSA_GenerateND;
+                       crt->RSA_genKeyDWithPQE         = SDRM_RSA_GenerateDwithPQE;
+                       crt->RSA_genKeypairWithEforCRT  = SDRM_RSA_GenerateKeyforCRT;
+                       crt->RSA_setKeypair                     = SDRM_RSA_setNED;
+                       crt->RSA_setKeypairForCRT       = SDRM_RSA_setNEDPQ;
+                       crt->AE_encrypt                         = SDRM_RSA_encrypt;
+                       crt->AE_decrypt                         = SDRM_RSA_decrypt;
+                       crt->AE_decryptByCRT            = SDRM_RSA_decryptByCRT;
+                       crt->DS_sign                            = SDRM_RSA_sign;
+                       crt->DS_verify                          = SDRM_RSA_verify;
+                       break;
+               case ID_DSA:
+                       crt->ctx->dsactx                        = (SDRM_DSAContext*)SDRM_DSA_InitCrt();
+                       crt->DSA_genParam                       = SDRM_DSA_GenParam;
+                       crt->DSA_setParam                       = SDRM_DSA_SetParam;
+                       crt->DSA_genKeypair                     = SDRM_DSA_GenKeypair;
+                       crt->DSA_setKeyPair                     = SDRM_DSA_SetKeyPair;
+                       crt->DS_sign                            = SDRM_DSA_sign;
+                       crt->DS_verify                          = SDRM_DSA_verify;
+                       break;
+               case ID_ECDSA:
+                       crt->ctx->ecdsactx                      = (SDRM_ECDSAContext*)SDRM_CURVE_Init();
+                       crt->EC_setCurve                        = SDRM_ECC_Set_CTX;
+                       crt->EC_genKeypair                      = SDRM_ECC_genKeypair;
+                       crt->EC_setKeypair                      = SDRM_ECC_setKeypair;
+                       crt->DS_sign                            = SDRM_ECDSA_sign;
+                       crt->DS_verify                          = SDRM_ECDSA_verify;
+                       break;
+               default:
+                       // free CryptoCoreContainer data structure
+                       free(crt->ctx);
+                       free(crt);
+                       crt = NULL;
+                       break;
+       }
+       return crt;
+}
+
+/*
+ * @fn         void destroy_CryptoCoreContainer(CryptoCoreContainer* crt)
+ *
+ * @brief      free allocated memory
+ * @param      crt             [in]crypt context
+ *
+ * @return     void
+ */
+void destroy_CryptoCoreContainer(CryptoCoreContainer* crt)
+{
+       if (crt == NULL)
+       {
+               return;
+       }
+
+       if (crt->ctx == NULL)
+       {
+               free(crt);
+               return;
+       }
+
+       // free context data structure
+       switch(crt->alg)
+       {
+               case ID_X931:
+                       CCFree(crt->ctx->x931ctx);
+                       break;
+               case ID_MD5:
+                       CCFree(crt->ctx->md5ctx);
+                       break;  
+               case ID_SHA1:
+                       CCFree(crt->ctx->sha1ctx);
+                       break;
+               case ID_SHA224:
+                       CCFree(crt->ctx->sha224ctx);
+                       break;
+               case ID_SHA256:
+                       CCFree(crt->ctx->sha256ctx);
+                       break;
+#ifndef _OP64_NOTSUPPORTED
+               case ID_SHA384:
+                       CCFree(crt->ctx->sha384ctx);
+                       break;
+               case ID_SHA512:
+                       CCFree(crt->ctx->sha512ctx);
+                       break;
+#endif
+               case ID_CMAC:
+                       CCFree(crt->ctx->cmacctx);
+                       break;
+               case ID_HMD5:
+               case ID_HSHA1:
+               case ID_HSHA224:
+               case ID_HSHA256:
+#ifndef _OP64_NOTSUPPORTED
+               case ID_HSHA384:
+               case ID_HSHA512:
+#endif //_OP64_NOTSUPPORTED
+                       CCFree(crt->ctx->hmacctx);
+                       break;
+               case ID_AES128:
+               case ID_AES192:
+               case ID_AES256:
+                       CCFree(crt->ctx->aesctx);
+                       break;
+               case ID_DES:
+                       CCFree(crt->ctx->desctx);
+                       break;
+               case ID_TDES:
+                       CCFree(crt->ctx->tdesctx);
+                       break;
+               case ID_RC4:
+                       CCFree(crt->ctx->rc4ctx);
+                       break;
+               case ID_SNOW2:
+                       CCFree(crt->ctx->snow2ctx);
+                       break;
+               case ID_RSA512:
+               case ID_RSA:
+               case ID_RSA1024:
+               case ID_RSA2048:
+                       CCFree(crt->ctx->rsactx);
+                       break;
+               case ID_DSA:
+                       CCFree(crt->ctx->dsactx);
+                       break;
+               case ID_ECDSA:
+                       CCFree(crt->ctx->ecdsactx);
+                       break;
+               case ID_ECDH:
+                       CCFree(crt->ctx->ecdhctx);
+                       break;
+               case ID_DH :
+                       SDRM_FreeDHContext(crt->ctx->dhctx);
+                       CCFree(crt->ctx->dhctx);
+                       break;
+       }
+
+       // free CryptoCoreContainer data structure
+       CCFree(crt->ctx);
+       CCFree(crt);
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/base/cc_ANSI_x931.c b/ssflib/dep/cryptocore/source/base/cc_ANSI_x931.c
new file mode 100755 (executable)
index 0000000..98c55d7
--- /dev/null
@@ -0,0 +1,110 @@
+/**
+ * \file       ANSI_x931.c
+ * @brief      Pseudorandom number generator based on a design described in ANSI X9.31
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Junbum Shin
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/23
+ * Edited : Use date data, and update seed, by Jisoon Park, 06/11/08
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include <time.h>
+#include "cc_aes.h"
+#include "cc_ANSI_x931.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Constants
+////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_RNG_X931
+ * @brief      generate random number with seed
+ *
+ * @param      Seed                            [in]seed for RNG System
+ * @param      bitLength                       [in]bit length of data to generate
+ * @param      data                            [out]generated data
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ */
+int    SDRM_RNG_X931(cc_u8 *Si_ANSI_X9_31, cc_u32 bitLength, cc_u8 *data)
+{
+       static cc_u8 K_ANSI_X9_31[SDRM_X931_SEED_SIZ] = {0xfd, 0x74, 0x3d, 0xe1, 0xdc, 0x08, 0xdc, 0x3d, 0x0f, 0xea, 0xf5, 0xa3, 0x6e, 0xb1, 0xc0, 0x7f};
+       int             res = CRYPTO_SUCCESS;
+       int             i, offset; 
+       int             byteLength, residue; 
+       int             numBlock, residueBlock;
+       cc_u8   *DT;
+       cc_u8   I[SDRM_X931_SEED_SIZ] = {0};
+       cc_u8   Ri_ANSI_X9_31[SDRM_X931_SEED_SIZ];
+       cc_u32  Date[SDRM_X931_SEED_SIZ / 4];
+       cc_u32  RoundKey[4*(10 + 1)];                   //AES Round Key
+
+       time_t nowTime;
+
+       time(&nowTime);
+       Date[0] = (cc_u32)nowTime;
+       Date[1] = rand();
+       Date[2] = rand();
+       Date[3] = rand();
+
+       DT = (cc_u8*)Date;                                              //DT : Time | Clock | RND | RND
+
+       SDRM_rijndaelKeySetupDec(RoundKey, K_ANSI_X9_31, 128);
+
+       byteLength = bitLength / 8 ; 
+       residue = bitLength - byteLength * 8; 
+
+       if (residue == 0)
+       {
+               memset(data, 0x0, byteLength); 
+       }
+       else
+       {
+               byteLength += 1; 
+               memset(data, 0x0, byteLength); 
+       }
+
+       numBlock = byteLength / SDRM_X931_SEED_SIZ; 
+       residueBlock = byteLength - numBlock * SDRM_X931_SEED_SIZ; 
+       offset = 0; 
+
+       for(i = 0; i < numBlock; i++)
+       {
+               SDRM_rijndaelDecrypt(RoundKey, 10, DT, I);
+               BlockXor(I, I, Si_ANSI_X9_31); 
+
+               SDRM_rijndaelDecrypt(RoundKey, 10, I, Ri_ANSI_X9_31);
+               BlockXor(I, I, Ri_ANSI_X9_31); 
+
+               SDRM_rijndaelDecrypt(RoundKey, 10, I, Si_ANSI_X9_31);
+               memcpy(data + offset, Ri_ANSI_X9_31, SDRM_X931_SEED_SIZ); 
+               offset += SDRM_X931_SEED_SIZ;           
+       }
+
+       if (residueBlock != 0)
+       {
+               SDRM_rijndaelDecrypt(RoundKey, 10, DT, I);
+               BlockXor(I, I, Si_ANSI_X9_31); 
+
+               SDRM_rijndaelDecrypt(RoundKey, 10, I, Ri_ANSI_X9_31);
+               BlockXor(I, I, Ri_ANSI_X9_31); 
+
+               SDRM_rijndaelDecrypt(RoundKey, 10, I, Si_ANSI_X9_31);
+               memcpy(data + offset, Ri_ANSI_X9_31, residueBlock); 
+       }
+
+       BlockXor(Si_ANSI_X9_31, I, Si_ANSI_X9_31);
+
+       return res;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/base/cc_aes.c b/ssflib/dep/cryptocore/source/base/cc_aes.c
new file mode 100755 (executable)
index 0000000..cbce0d7
--- /dev/null
@@ -0,0 +1,1389 @@
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_aes.h"
+
+#define FULL_UNROLL
+
+////////////////////////////////////////////////////////////////////////////
+// AES conversion matrix
+////////////////////////////////////////////////////////////////////////////
+static const cc_u32 SDRM_Te0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const cc_u32 SDRM_Te1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const cc_u32 SDRM_Te2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const cc_u32 SDRM_Te3[256] = {
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const cc_u32 SDRM_Te4[256] = {
+    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+static const cc_u32 SDRM_Td0[256] = {
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const cc_u32 SDRM_Td1[256] = {
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const cc_u32 SDRM_Td2[256] = {
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const cc_u32 SDRM_Td3[256] = {
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const cc_u32 SDRM_Td4[256] = {
+    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const cc_u32 SDRM_rcon[] = {
+       0x01000000, 0x02000000, 0x04000000, 0x08000000,
+       0x10000000, 0x20000000, 0x40000000, 0x80000000,
+       0x1B000000, 0x36000000, 
+       /* for 128-bit blocks, Rijndael never uses more than 10 _rcon values */
+};
+
+////////////////////////////////////////////////////////////////////////////
+// Macros for AES
+////////////////////////////////////////////////////////////////////////////
+#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+
+#ifdef _MSC_VER
+       #define GETUINT32(p) SWAP(*((cc_u32 *)(p)))
+       #define PUTUINT32(ct, st) { *((cc_u32 *)(ct)) = SWAP((st)); }
+#else
+       #define GETUINT32(pt) (((cc_u32)(pt)[0] << 24) ^ ((cc_u32)(pt)[1] << 16) ^ ((cc_u32)(pt)[2] <<  8) ^ ((cc_u32)(pt)[3]))
+       #define PUTUINT32(ct, st) { (ct)[0] = (cc_u8)((st) >> 24); (ct)[1] = (cc_u8)((st) >> 16); (ct)[2] = (cc_u8)((st) >>  8); (ct)[3] = (cc_u8)(st); }
+#endif
+
+/*
+ * @fn         SDRM_rijndaelKeySetupEnc
+ * @brief      Expand the cipher key into the encryption key schedule
+ *
+ * @param      rk                                      [out]expanded round key
+ * @param      cipherKey                       [in]user key
+ * @param      keyBits                         [in]bit-length of cipherKey
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_rijndaelKeySetupEnc(cc_u32 rk[/*4*(Nr + 1)*/], const cc_u8 cipherKey[], int keyBits)
+{
+       int             i = 0;
+       cc_u32  temp;
+
+       rk[0] = GETUINT32(cipherKey     );
+       rk[1] = GETUINT32(cipherKey +  4);
+       rk[2] = GETUINT32(cipherKey +  8);
+       rk[3] = GETUINT32(cipherKey + 12);
+       if (keyBits == 128)
+       {
+               for (;;)
+               {
+                       temp  = rk[3];
+                       rk[4] = rk[0] ^
+                               (SDRM_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                               (SDRM_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                               (SDRM_Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                               (SDRM_Te4[(temp >> 24)       ] & 0x000000ff) ^
+                               SDRM_rcon[i];
+                       rk[5] = rk[1] ^ rk[4];
+                       rk[6] = rk[2] ^ rk[5];
+                       rk[7] = rk[3] ^ rk[6];
+                       if (++i == 10)
+                       {
+                               return 10;
+                       }
+                       rk += 4;
+               }
+       }
+
+       rk[4] = GETUINT32(cipherKey + 16);
+       rk[5] = GETUINT32(cipherKey + 20);
+       if (keyBits == 192)
+       {
+               for (;;) {
+                       temp = rk[ 5];
+                       rk[ 6] = rk[ 0] ^
+                               (SDRM_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                               (SDRM_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                               (SDRM_Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                               (SDRM_Te4[(temp >> 24)       ] & 0x000000ff) ^
+                               SDRM_rcon[i];
+                       rk[ 7] = rk[ 1] ^ rk[ 6];
+                       rk[ 8] = rk[ 2] ^ rk[ 7];
+                       rk[ 9] = rk[ 3] ^ rk[ 8];
+                       if (++i == 8)
+                       {
+                               return 12;
+                       }
+                       rk[10] = rk[ 4] ^ rk[ 9];
+                       rk[11] = rk[ 5] ^ rk[10];
+                       rk += 6;
+               }
+       }
+       rk[6] = GETUINT32(cipherKey + 24);
+       rk[7] = GETUINT32(cipherKey + 28);
+       if (keyBits == 256)
+       {
+        for (;;)
+               {
+               temp = rk[ 7];
+               rk[ 8] = rk[ 0] ^
+                       (SDRM_Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+                       (SDRM_Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                       (SDRM_Te4[(temp      ) & 0xff] & 0x0000ff00) ^
+                       (SDRM_Te4[(temp >> 24)       ] & 0x000000ff) ^
+                       SDRM_rcon[i];
+               rk[ 9] = rk[ 1] ^ rk[ 8];
+               rk[10] = rk[ 2] ^ rk[ 9];
+               rk[11] = rk[ 3] ^ rk[10];
+                       if (++i == 7) {
+                               return 14;
+                       }
+               temp = rk[11];
+               rk[12] = rk[ 4] ^
+                       (SDRM_Te4[(temp >> 24)       ] & 0xff000000) ^
+                       (SDRM_Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+                       (SDRM_Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
+                       (SDRM_Te4[(temp      ) & 0xff] & 0x000000ff);
+               rk[13] = rk[ 5] ^ rk[12];
+               rk[14] = rk[ 6] ^ rk[13];
+               rk[15] = rk[ 7] ^ rk[14];
+
+                       rk += 8;
+        }
+       }
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_rijndaelKeySetupDec
+ * @brief      Expand the cipher key into the decryption key schedule
+ *
+ * @param      rk                                      [out]expanded round key
+ * @param      cipherKey                       [in]user key
+ * @param      keyBits                         [in]bit-length of cipherKey
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_rijndaelKeySetupDec(cc_u32 rk[/*4*(Nr + 1)*/], const cc_u8 cipherKey[], int keyBits)
+{
+       int             Nr, i, j;
+       cc_u32  temp;
+
+       /* expand the cipher key: */
+       Nr = SDRM_rijndaelKeySetupEnc(rk, cipherKey, keyBits);
+       /* invert the order of the round keys: */
+       for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4)
+       {
+               temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+               temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+               temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+               temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+       }
+
+       /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+       for (i = 1; i < Nr; i++)
+       {
+               rk += 4;
+               rk[0] =
+                       SDRM_Td0[SDRM_Te4[(rk[0] >> 24)       ] & 0xff] ^
+                       SDRM_Td1[SDRM_Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+                       SDRM_Td2[SDRM_Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
+                       SDRM_Td3[SDRM_Te4[(rk[0]      ) & 0xff] & 0xff];
+               rk[1] =
+                       SDRM_Td0[SDRM_Te4[(rk[1] >> 24)       ] & 0xff] ^
+                       SDRM_Td1[SDRM_Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+                       SDRM_Td2[SDRM_Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
+                       SDRM_Td3[SDRM_Te4[(rk[1]      ) & 0xff] & 0xff];
+               rk[2] =
+                       SDRM_Td0[SDRM_Te4[(rk[2] >> 24)       ] & 0xff] ^
+                       SDRM_Td1[SDRM_Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+                       SDRM_Td2[SDRM_Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
+                       SDRM_Td3[SDRM_Te4[(rk[2]      ) & 0xff] & 0xff];
+               rk[3] =
+                       SDRM_Td0[SDRM_Te4[(rk[3] >> 24)       ] & 0xff] ^
+                       SDRM_Td1[SDRM_Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+                       SDRM_Td2[SDRM_Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
+                       SDRM_Td3[SDRM_Te4[(rk[3]      ) & 0xff] & 0xff];
+       }
+       return Nr;
+}
+
+/*
+ * @fn         SDRM_rijndaelEncrypt
+ * @brief      16 byte AES Encryption with round key
+ *
+ * @param      rk                                      [in]expanded round key
+ * @param      Nr                                      [in]numer of rounds
+ * @param      pt                                      [in]plain text
+ * @param      ct                                      [out]cipher text
+ *
+ * @return     void
+ */
+void SDRM_rijndaelEncrypt(const cc_u32 rk[/*4*(Nr + 1)*/], int Nr, const cc_u8 pt[16], cc_u8 ct[16])
+{
+       cc_u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+    int r;
+#endif /* ?FULL_UNROLL */
+
+    /*
+        * map byte array block to cipher state
+        * and add initial round key:
+        */
+       s0 = GETUINT32(pt     ) ^ rk[0];
+       s1 = GETUINT32(pt +  4) ^ rk[1];
+       s2 = GETUINT32(pt +  8) ^ rk[2];
+       s3 = GETUINT32(pt + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+       t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[ 4];
+       t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[ 5];
+       t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[ 6];
+       t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[ 7];
+       /* round 2: */
+       s0 = SDRM_Te0[t0 >> 24] ^ SDRM_Te1[(t1 >> 16) & 0xff] ^ SDRM_Te2[(t2 >>  8) & 0xff] ^ SDRM_Te3[t3 & 0xff] ^ rk[ 8];
+       s1 = SDRM_Te0[t1 >> 24] ^ SDRM_Te1[(t2 >> 16) & 0xff] ^ SDRM_Te2[(t3 >>  8) & 0xff] ^ SDRM_Te3[t0 & 0xff] ^ rk[ 9];
+       s2 = SDRM_Te0[t2 >> 24] ^ SDRM_Te1[(t3 >> 16) & 0xff] ^ SDRM_Te2[(t0 >>  8) & 0xff] ^ SDRM_Te3[t1 & 0xff] ^ rk[10];
+       s3 = SDRM_Te0[t3 >> 24] ^ SDRM_Te1[(t0 >> 16) & 0xff] ^ SDRM_Te2[(t1 >>  8) & 0xff] ^ SDRM_Te3[t2 & 0xff] ^ rk[11];
+    /* round 3: */
+       t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[12];
+       t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[13];
+       t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[14];
+       t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[15];
+       /* round 4: */
+       s0 = SDRM_Te0[t0 >> 24] ^ SDRM_Te1[(t1 >> 16) & 0xff] ^ SDRM_Te2[(t2 >>  8) & 0xff] ^ SDRM_Te3[t3 & 0xff] ^ rk[16];
+       s1 = SDRM_Te0[t1 >> 24] ^ SDRM_Te1[(t2 >> 16) & 0xff] ^ SDRM_Te2[(t3 >>  8) & 0xff] ^ SDRM_Te3[t0 & 0xff] ^ rk[17];
+       s2 = SDRM_Te0[t2 >> 24] ^ SDRM_Te1[(t3 >> 16) & 0xff] ^ SDRM_Te2[(t0 >>  8) & 0xff] ^ SDRM_Te3[t1 & 0xff] ^ rk[18];
+       s3 = SDRM_Te0[t3 >> 24] ^ SDRM_Te1[(t0 >> 16) & 0xff] ^ SDRM_Te2[(t1 >>  8) & 0xff] ^ SDRM_Te3[t2 & 0xff] ^ rk[19];
+    /* round 5: */
+       t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[20];
+       t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[21];
+       t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[22];
+       t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[23];
+       /* round 6: */
+       s0 = SDRM_Te0[t0 >> 24] ^ SDRM_Te1[(t1 >> 16) & 0xff] ^ SDRM_Te2[(t2 >>  8) & 0xff] ^ SDRM_Te3[t3 & 0xff] ^ rk[24];
+       s1 = SDRM_Te0[t1 >> 24] ^ SDRM_Te1[(t2 >> 16) & 0xff] ^ SDRM_Te2[(t3 >>  8) & 0xff] ^ SDRM_Te3[t0 & 0xff] ^ rk[25];
+       s2 = SDRM_Te0[t2 >> 24] ^ SDRM_Te1[(t3 >> 16) & 0xff] ^ SDRM_Te2[(t0 >>  8) & 0xff] ^ SDRM_Te3[t1 & 0xff] ^ rk[26];
+       s3 = SDRM_Te0[t3 >> 24] ^ SDRM_Te1[(t0 >> 16) & 0xff] ^ SDRM_Te2[(t1 >>  8) & 0xff] ^ SDRM_Te3[t2 & 0xff] ^ rk[27];
+    /* round 7: */
+       t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[28];
+       t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[29];
+       t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[30];
+       t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[31];
+       /* round 8: */
+       s0 = SDRM_Te0[t0 >> 24] ^ SDRM_Te1[(t1 >> 16) & 0xff] ^ SDRM_Te2[(t2 >>  8) & 0xff] ^ SDRM_Te3[t3 & 0xff] ^ rk[32];
+       s1 = SDRM_Te0[t1 >> 24] ^ SDRM_Te1[(t2 >> 16) & 0xff] ^ SDRM_Te2[(t3 >>  8) & 0xff] ^ SDRM_Te3[t0 & 0xff] ^ rk[33];
+       s2 = SDRM_Te0[t2 >> 24] ^ SDRM_Te1[(t3 >> 16) & 0xff] ^ SDRM_Te2[(t0 >>  8) & 0xff] ^ SDRM_Te3[t1 & 0xff] ^ rk[34];
+       s3 = SDRM_Te0[t3 >> 24] ^ SDRM_Te1[(t0 >> 16) & 0xff] ^ SDRM_Te2[(t1 >>  8) & 0xff] ^ SDRM_Te3[t2 & 0xff] ^ rk[35];
+    /* round 9: */
+       t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[36];
+       t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[37];
+       t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[38];
+       t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[39];
+    if (Nr > 10)
+       {
+        /* round 10: */
+        s0 = SDRM_Te0[t0 >> 24] ^ SDRM_Te1[(t1 >> 16) & 0xff] ^ SDRM_Te2[(t2 >>  8) & 0xff] ^ SDRM_Te3[t3 & 0xff] ^ rk[40];
+        s1 = SDRM_Te0[t1 >> 24] ^ SDRM_Te1[(t2 >> 16) & 0xff] ^ SDRM_Te2[(t3 >>  8) & 0xff] ^ SDRM_Te3[t0 & 0xff] ^ rk[41];
+        s2 = SDRM_Te0[t2 >> 24] ^ SDRM_Te1[(t3 >> 16) & 0xff] ^ SDRM_Te2[(t0 >>  8) & 0xff] ^ SDRM_Te3[t1 & 0xff] ^ rk[42];
+        s3 = SDRM_Te0[t3 >> 24] ^ SDRM_Te1[(t0 >> 16) & 0xff] ^ SDRM_Te2[(t1 >>  8) & 0xff] ^ SDRM_Te3[t2 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[44];
+        t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[45];
+        t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[46];
+        t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[47];
+        if (Nr > 12) {
+            /* round 12: */
+            s0 = SDRM_Te0[t0 >> 24] ^ SDRM_Te1[(t1 >> 16) & 0xff] ^ SDRM_Te2[(t2 >>  8) & 0xff] ^ SDRM_Te3[t3 & 0xff] ^ rk[48];
+            s1 = SDRM_Te0[t1 >> 24] ^ SDRM_Te1[(t2 >> 16) & 0xff] ^ SDRM_Te2[(t3 >>  8) & 0xff] ^ SDRM_Te3[t0 & 0xff] ^ rk[49];
+            s2 = SDRM_Te0[t2 >> 24] ^ SDRM_Te1[(t3 >> 16) & 0xff] ^ SDRM_Te2[(t0 >>  8) & 0xff] ^ SDRM_Te3[t1 & 0xff] ^ rk[50];
+            s3 = SDRM_Te0[t3 >> 24] ^ SDRM_Te1[(t0 >> 16) & 0xff] ^ SDRM_Te2[(t1 >>  8) & 0xff] ^ SDRM_Te3[t2 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = SDRM_Te0[s0 >> 24] ^ SDRM_Te1[(s1 >> 16) & 0xff] ^ SDRM_Te2[(s2 >>  8) & 0xff] ^ SDRM_Te3[s3 & 0xff] ^ rk[52];
+            t1 = SDRM_Te0[s1 >> 24] ^ SDRM_Te1[(s2 >> 16) & 0xff] ^ SDRM_Te2[(s3 >>  8) & 0xff] ^ SDRM_Te3[s0 & 0xff] ^ rk[53];
+            t2 = SDRM_Te0[s2 >> 24] ^ SDRM_Te1[(s3 >> 16) & 0xff] ^ SDRM_Te2[(s0 >>  8) & 0xff] ^ SDRM_Te3[s1 & 0xff] ^ rk[54];
+            t3 = SDRM_Te0[s3 >> 24] ^ SDRM_Te1[(s0 >> 16) & 0xff] ^ SDRM_Te2[(s1 >>  8) & 0xff] ^ SDRM_Te3[s2 & 0xff] ^ rk[55];
+        }
+    }
+    rk += Nr << 2;
+#else  /* !FULL_UNROLL */
+    /*
+        * Nr - 1 full rounds:
+        */
+    r = Nr >> 1;
+    for (;;)
+       {
+        t0 =
+            SDRM_Te0[(s0 >> 24)       ] ^
+            SDRM_Te1[(s1 >> 16) & 0xff] ^
+            SDRM_Te2[(s2 >>  8) & 0xff] ^
+            SDRM_Te3[(s3      ) & 0xff] ^
+            rk[4];
+        t1 =
+            SDRM_Te0[(s1 >> 24)       ] ^
+            SDRM_Te1[(s2 >> 16) & 0xff] ^
+            SDRM_Te2[(s3 >>  8) & 0xff] ^
+            SDRM_Te3[(s0      ) & 0xff] ^
+            rk[5];
+        t2 =
+            SDRM_Te0[(s2 >> 24)       ] ^
+            SDRM_Te1[(s3 >> 16) & 0xff] ^
+            SDRM_Te2[(s0 >>  8) & 0xff] ^
+            SDRM_Te3[(s1      ) & 0xff] ^
+            rk[6];
+        t3 =
+            SDRM_Te0[(s3 >> 24)       ] ^
+            SDRM_Te1[(s0 >> 16) & 0xff] ^
+            SDRM_Te2[(s1 >>  8) & 0xff] ^
+            SDRM_Te3[(s2      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0)
+               {
+            break;
+        }
+
+        s0 =
+            SDRM_Te0[(t0 >> 24)       ] ^
+            SDRM_Te1[(t1 >> 16) & 0xff] ^
+            SDRM_Te2[(t2 >>  8) & 0xff] ^
+            SDRM_Te3[(t3      ) & 0xff] ^
+            rk[0];
+        s1 =
+            SDRM_Te0[(t1 >> 24)       ] ^
+            SDRM_Te1[(t2 >> 16) & 0xff] ^
+            SDRM_Te2[(t3 >>  8) & 0xff] ^
+            SDRM_Te3[(t0      ) & 0xff] ^
+            rk[1];
+        s2 =
+            SDRM_Te0[(t2 >> 24)       ] ^
+            SDRM_Te1[(t3 >> 16) & 0xff] ^
+            SDRM_Te2[(t0 >>  8) & 0xff] ^
+            SDRM_Te3[(t1      ) & 0xff] ^
+            rk[2];
+        s3 =
+            SDRM_Te0[(t3 >> 24)       ] ^
+            SDRM_Te1[(t0 >> 16) & 0xff] ^
+            SDRM_Te2[(t1 >>  8) & 0xff] ^
+            SDRM_Te3[(t2      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+        * apply last round and
+        * map cipher state to byte array block:
+        */
+       s0 =
+               (SDRM_Te4[(t0 >> 24)       ] & 0xff000000) ^
+               (SDRM_Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Te4[(t3      ) & 0xff] & 0x000000ff) ^
+               rk[0];
+       PUTUINT32(ct     , s0);
+       s1 =
+               (SDRM_Te4[(t1 >> 24)       ] & 0xff000000) ^
+               (SDRM_Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Te4[(t0      ) & 0xff] & 0x000000ff) ^
+               rk[1];
+       PUTUINT32(ct +  4, s1);
+       s2 =
+               (SDRM_Te4[(t2 >> 24)       ] & 0xff000000) ^
+               (SDRM_Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Te4[(t1      ) & 0xff] & 0x000000ff) ^
+               rk[2];
+       PUTUINT32(ct +  8, s2);
+       s3 =
+               (SDRM_Te4[(t3 >> 24)       ] & 0xff000000) ^
+               (SDRM_Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Te4[(t2      ) & 0xff] & 0x000000ff) ^
+               rk[3];
+       PUTUINT32(ct + 12, s3);
+}
+
+/*
+ * @fn         SDRM_rijndaelDecrypt
+ * @brief      16 byte AES Decryption with round key
+ *
+ * @param      rk                                      [in]expanded round key
+ * @param      Nr                                      [in]numer of rounds
+ * @param      ct                                      [in]cipher text
+ * @param      pt                                      [out]plain text
+ *
+ * @return     void
+ */
+void SDRM_rijndaelDecrypt(const cc_u32 rk[/*4*(Nr + 1)*/], int Nr, const cc_u8 ct[16], cc_u8 pt[16])
+{
+       cc_u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+    int r;
+#endif /* ?FULL_UNROLL */
+
+    /*
+        * map byte array block to cipher state
+        * and add initial round key:
+        */
+    s0 = GETUINT32(ct     ) ^ rk[0];
+    s1 = GETUINT32(ct +  4) ^ rk[1];
+    s2 = GETUINT32(ct +  8) ^ rk[2];
+    s3 = GETUINT32(ct + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[ 4];
+    t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[ 5];
+    t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[ 6];
+    t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = SDRM_Td0[t0 >> 24] ^ SDRM_Td1[(t3 >> 16) & 0xff] ^ SDRM_Td2[(t2 >>  8) & 0xff] ^ SDRM_Td3[t1 & 0xff] ^ rk[ 8];
+    s1 = SDRM_Td0[t1 >> 24] ^ SDRM_Td1[(t0 >> 16) & 0xff] ^ SDRM_Td2[(t3 >>  8) & 0xff] ^ SDRM_Td3[t2 & 0xff] ^ rk[ 9];
+    s2 = SDRM_Td0[t2 >> 24] ^ SDRM_Td1[(t1 >> 16) & 0xff] ^ SDRM_Td2[(t0 >>  8) & 0xff] ^ SDRM_Td3[t3 & 0xff] ^ rk[10];
+    s3 = SDRM_Td0[t3 >> 24] ^ SDRM_Td1[(t2 >> 16) & 0xff] ^ SDRM_Td2[(t1 >>  8) & 0xff] ^ SDRM_Td3[t0 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[12];
+    t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[13];
+    t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[14];
+    t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = SDRM_Td0[t0 >> 24] ^ SDRM_Td1[(t3 >> 16) & 0xff] ^ SDRM_Td2[(t2 >>  8) & 0xff] ^ SDRM_Td3[t1 & 0xff] ^ rk[16];
+    s1 = SDRM_Td0[t1 >> 24] ^ SDRM_Td1[(t0 >> 16) & 0xff] ^ SDRM_Td2[(t3 >>  8) & 0xff] ^ SDRM_Td3[t2 & 0xff] ^ rk[17];
+    s2 = SDRM_Td0[t2 >> 24] ^ SDRM_Td1[(t1 >> 16) & 0xff] ^ SDRM_Td2[(t0 >>  8) & 0xff] ^ SDRM_Td3[t3 & 0xff] ^ rk[18];
+    s3 = SDRM_Td0[t3 >> 24] ^ SDRM_Td1[(t2 >> 16) & 0xff] ^ SDRM_Td2[(t1 >>  8) & 0xff] ^ SDRM_Td3[t0 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[20];
+    t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[21];
+    t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[22];
+    t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = SDRM_Td0[t0 >> 24] ^ SDRM_Td1[(t3 >> 16) & 0xff] ^ SDRM_Td2[(t2 >>  8) & 0xff] ^ SDRM_Td3[t1 & 0xff] ^ rk[24];
+    s1 = SDRM_Td0[t1 >> 24] ^ SDRM_Td1[(t0 >> 16) & 0xff] ^ SDRM_Td2[(t3 >>  8) & 0xff] ^ SDRM_Td3[t2 & 0xff] ^ rk[25];
+    s2 = SDRM_Td0[t2 >> 24] ^ SDRM_Td1[(t1 >> 16) & 0xff] ^ SDRM_Td2[(t0 >>  8) & 0xff] ^ SDRM_Td3[t3 & 0xff] ^ rk[26];
+    s3 = SDRM_Td0[t3 >> 24] ^ SDRM_Td1[(t2 >> 16) & 0xff] ^ SDRM_Td2[(t1 >>  8) & 0xff] ^ SDRM_Td3[t0 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[28];
+    t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[29];
+    t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[30];
+    t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = SDRM_Td0[t0 >> 24] ^ SDRM_Td1[(t3 >> 16) & 0xff] ^ SDRM_Td2[(t2 >>  8) & 0xff] ^ SDRM_Td3[t1 & 0xff] ^ rk[32];
+    s1 = SDRM_Td0[t1 >> 24] ^ SDRM_Td1[(t0 >> 16) & 0xff] ^ SDRM_Td2[(t3 >>  8) & 0xff] ^ SDRM_Td3[t2 & 0xff] ^ rk[33];
+    s2 = SDRM_Td0[t2 >> 24] ^ SDRM_Td1[(t1 >> 16) & 0xff] ^ SDRM_Td2[(t0 >>  8) & 0xff] ^ SDRM_Td3[t3 & 0xff] ^ rk[34];
+    s3 = SDRM_Td0[t3 >> 24] ^ SDRM_Td1[(t2 >> 16) & 0xff] ^ SDRM_Td2[(t1 >>  8) & 0xff] ^ SDRM_Td3[t0 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[36];
+    t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[37];
+    t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[38];
+    t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[39];
+    if (Nr > 10)
+       {
+        /* round 10: */
+        s0 = SDRM_Td0[t0 >> 24] ^ SDRM_Td1[(t3 >> 16) & 0xff] ^ SDRM_Td2[(t2 >>  8) & 0xff] ^ SDRM_Td3[t1 & 0xff] ^ rk[40];
+        s1 = SDRM_Td0[t1 >> 24] ^ SDRM_Td1[(t0 >> 16) & 0xff] ^ SDRM_Td2[(t3 >>  8) & 0xff] ^ SDRM_Td3[t2 & 0xff] ^ rk[41];
+        s2 = SDRM_Td0[t2 >> 24] ^ SDRM_Td1[(t1 >> 16) & 0xff] ^ SDRM_Td2[(t0 >>  8) & 0xff] ^ SDRM_Td3[t3 & 0xff] ^ rk[42];
+        s3 = SDRM_Td0[t3 >> 24] ^ SDRM_Td1[(t2 >> 16) & 0xff] ^ SDRM_Td2[(t1 >>  8) & 0xff] ^ SDRM_Td3[t0 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[44];
+        t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[45];
+        t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[46];
+        t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[47];
+        if (Nr > 12) {
+            /* round 12: */
+            s0 = SDRM_Td0[t0 >> 24] ^ SDRM_Td1[(t3 >> 16) & 0xff] ^ SDRM_Td2[(t2 >>  8) & 0xff] ^ SDRM_Td3[t1 & 0xff] ^ rk[48];
+            s1 = SDRM_Td0[t1 >> 24] ^ SDRM_Td1[(t0 >> 16) & 0xff] ^ SDRM_Td2[(t3 >>  8) & 0xff] ^ SDRM_Td3[t2 & 0xff] ^ rk[49];
+            s2 = SDRM_Td0[t2 >> 24] ^ SDRM_Td1[(t1 >> 16) & 0xff] ^ SDRM_Td2[(t0 >>  8) & 0xff] ^ SDRM_Td3[t3 & 0xff] ^ rk[50];
+            s3 = SDRM_Td0[t3 >> 24] ^ SDRM_Td1[(t2 >> 16) & 0xff] ^ SDRM_Td2[(t1 >>  8) & 0xff] ^ SDRM_Td3[t0 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = SDRM_Td0[s0 >> 24] ^ SDRM_Td1[(s3 >> 16) & 0xff] ^ SDRM_Td2[(s2 >>  8) & 0xff] ^ SDRM_Td3[s1 & 0xff] ^ rk[52];
+            t1 = SDRM_Td0[s1 >> 24] ^ SDRM_Td1[(s0 >> 16) & 0xff] ^ SDRM_Td2[(s3 >>  8) & 0xff] ^ SDRM_Td3[s2 & 0xff] ^ rk[53];
+            t2 = SDRM_Td0[s2 >> 24] ^ SDRM_Td1[(s1 >> 16) & 0xff] ^ SDRM_Td2[(s0 >>  8) & 0xff] ^ SDRM_Td3[s3 & 0xff] ^ rk[54];
+            t3 = SDRM_Td0[s3 >> 24] ^ SDRM_Td1[(s2 >> 16) & 0xff] ^ SDRM_Td2[(s1 >>  8) & 0xff] ^ SDRM_Td3[s0 & 0xff] ^ rk[55];
+        }
+    }
+       rk += Nr << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = Nr >> 1;
+    for (;;)
+       {
+        t0 =
+            SDRM_Td0[(s0 >> 24)       ] ^
+            SDRM_Td1[(s3 >> 16) & 0xff] ^
+            SDRM_Td2[(s2 >>  8) & 0xff] ^
+            SDRM_Td3[(s1      ) & 0xff] ^
+            rk[4];
+        t1 =
+            SDRM_Td0[(s1 >> 24)       ] ^
+            SDRM_Td1[(s0 >> 16) & 0xff] ^
+            SDRM_Td2[(s3 >>  8) & 0xff] ^
+            SDRM_Td3[(s2      ) & 0xff] ^
+            rk[5];
+        t2 =
+            SDRM_Td0[(s2 >> 24)       ] ^
+            SDRM_Td1[(s1 >> 16) & 0xff] ^
+            SDRM_Td2[(s0 >>  8) & 0xff] ^
+            SDRM_Td3[(s3      ) & 0xff] ^
+            rk[6];
+        t3 =
+            SDRM_Td0[(s3 >> 24)       ] ^
+            SDRM_Td1[(s2 >> 16) & 0xff] ^
+            SDRM_Td2[(s1 >>  8) & 0xff] ^
+            SDRM_Td3[(s0      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0)
+               {
+            break;
+        }
+
+        s0 =
+            SDRM_Td0[(t0 >> 24)       ] ^
+            SDRM_Td1[(t3 >> 16) & 0xff] ^
+            SDRM_Td2[(t2 >>  8) & 0xff] ^
+            SDRM_Td3[(t1      ) & 0xff] ^
+            rk[0];
+        s1 =
+            SDRM_Td0[(t1 >> 24)       ] ^
+            SDRM_Td1[(t0 >> 16) & 0xff] ^
+            SDRM_Td2[(t3 >>  8) & 0xff] ^
+            SDRM_Td3[(t2      ) & 0xff] ^
+            rk[1];
+        s2 =
+            SDRM_Td0[(t2 >> 24)       ] ^
+            SDRM_Td1[(t1 >> 16) & 0xff] ^
+            SDRM_Td2[(t0 >>  8) & 0xff] ^
+            SDRM_Td3[(t3      ) & 0xff] ^
+            rk[2];
+        s3 =
+            SDRM_Td0[(t3 >> 24)       ] ^
+            SDRM_Td1[(t2 >> 16) & 0xff] ^
+            SDRM_Td2[(t1 >>  8) & 0xff] ^
+            SDRM_Td3[(t0      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+        * apply last round and
+        * map cipher state to byte array block:
+        */
+       s0 =
+               (SDRM_Td4[(t0 >> 24)       ] & 0xff000000) ^
+               (SDRM_Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Td4[(t1      ) & 0xff] & 0x000000ff) ^
+               rk[0];
+       PUTUINT32(pt     , s0);
+       s1 =
+               (SDRM_Td4[(t1 >> 24)       ] & 0xff000000) ^
+               (SDRM_Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Td4[(t2      ) & 0xff] & 0x000000ff) ^
+               rk[1];
+       PUTUINT32(pt +  4, s1);
+       s2 =
+               (SDRM_Td4[(t2 >> 24)       ] & 0xff000000) ^
+               (SDRM_Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Td4[(t3      ) & 0xff] & 0x000000ff) ^
+               rk[2];
+       PUTUINT32(pt +  8, s2);
+       s3 =
+               (SDRM_Td4[(t3 >> 24)       ] & 0xff000000) ^
+               (SDRM_Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+               (SDRM_Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+               (SDRM_Td4[(t0      ) & 0xff] & 0x000000ff) ^
+               rk[3];
+       PUTUINT32(pt + 12, s3);
+}
+
+/*
+ * @fn         SDRM_AES128_Encryption
+ * @brief      AES-128 Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES128_Encryption(cc_u8 *cipherText, cc_u8 *plainText,        cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[4*(10 + 1)];
+
+       SDRM_rijndaelKeySetupEnc(RoundKey, UserKey, 128);
+
+       SDRM_rijndaelEncrypt(RoundKey, 10, plainText, cipherText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_AES128_Decryption
+ * @brief      AES-128 Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES128_Decryption(cc_u8 *plainText, cc_u8 *cipherText,        cc_u8 *UserKey)
+{      
+       cc_u32 RoundKey[4*(10 + 1)];
+
+       SDRM_rijndaelKeySetupDec(RoundKey, UserKey, 128);
+
+       SDRM_rijndaelDecrypt(RoundKey, 10, cipherText, plainText);
+
+       return CRYPTO_SUCCESS; 
+}
+
+/*
+ * @fn         SDRM_AES192_Encryption
+ * @brief      AES-192 Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES192_Encryption(cc_u8 *cipherText, cc_u8 *plainText,        cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[4*(12 + 1)];
+
+       SDRM_rijndaelKeySetupEnc(RoundKey, UserKey, 192);
+
+       SDRM_rijndaelEncrypt(RoundKey, 12, plainText, cipherText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_AES192_Decryption
+ * @brief      AES-192 Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES192_Decryption(cc_u8 *plainText, cc_u8 *cipherText,        cc_u8 *UserKey)
+{      
+       cc_u32 RoundKey[4*(12 + 1)];
+
+       SDRM_rijndaelKeySetupDec(RoundKey, UserKey, 192);
+
+       SDRM_rijndaelDecrypt(RoundKey, 12, cipherText, plainText);
+
+       return CRYPTO_SUCCESS; 
+}
+
+/*
+ * @fn         SDRM_AES256_Encryption
+ * @brief      AES-256 Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES256_Encryption(cc_u8 *cipherText, cc_u8 *plainText,        cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[4*(14 + 1)];
+
+       SDRM_rijndaelKeySetupEnc(RoundKey, UserKey, 256);
+
+       SDRM_rijndaelEncrypt(RoundKey, 14, plainText, cipherText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_AES256_Decryption
+ * @brief      AES-256 Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_AES256_Decryption(cc_u8 *plainText, cc_u8 *cipherText,        cc_u8 *UserKey)
+{      
+       cc_u32 RoundKey[4*(14 + 1)];
+
+       SDRM_rijndaelKeySetupDec(RoundKey, UserKey, 256);
+
+       SDRM_rijndaelDecrypt(RoundKey, 14, cipherText, plainText);
+
+       return CRYPTO_SUCCESS; 
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/base/cc_bignum.c b/ssflib/dep/cryptocore/source/base/cc_bignum.c
new file mode 100755 (executable)
index 0000000..07016ab
--- /dev/null
@@ -0,0 +1,3202 @@
+/**
+ * \file       bignum.c
+ * @brief      big number library
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/03
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_bignum.h"
+#include "cc_fast_math.h"
+////////////////////////////////////////////////////////////////////////////
+// Global Variables
+////////////////////////////////////////////////////////////////////////////
+cc_u32                 DWD_Zero[2]     = {0, 0};
+cc_u32                 DWD_One[2]      = {1, 0};
+
+SDRM_BIG_NUM   _BN_Zero        = {0, 0, 2, DWD_Zero};
+SDRM_BIG_NUM   _BN_One         = {0, 1, 2, DWD_One};
+
+SDRM_BIG_NUM   *BN_Zero        = &_BN_Zero;
+SDRM_BIG_NUM   *BN_One         = &_BN_One;
+
+////////////////////////////////////////////////////////////////////////////
+// Local Functon Protypes
+////////////////////////////////////////////////////////////////////////////
+int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen);
+
+#ifdef _OP64_NOTSUPPORTED
+
+#define SDRM_HL(A)     (cc_u32)(((A) >> 16) & 0xffffu)
+#define SDRM_LL(A)     (cc_u32)((A) & 0xffffu)
+#define SDRM_LH(A)     (cc_u32)(((A) & 0xffffu) << 16)
+#define NOT(A)         (~(A))
+
+/*
+ * @fn         SDRM_DIGIT_Mul
+ * @brief      Double-width UINT32 Multiplication
+ *
+ * \n  Dest            [out]destination, 2-cc_u32-size array
+ * \n  Src1            [in]first element
+ * \n  Src2            [in]second element
+ *
+ * @return     void
+ */
+void SDRM_DIGIT_Mul(cc_u32 *Dest, cc_u32 Src1, cc_u32 Src2)
+{
+       cc_u32  Da, Db, R1, R0;
+
+       R1 = SDRM_HL(Src1) * SDRM_HL(Src2);
+       R0 = SDRM_LL(Src1) * SDRM_LL(Src2);
+
+       Da = SDRM_HL(Src1) * SDRM_LL(Src2);
+       Db = SDRM_LL(Src1) * SDRM_HL(Src2);
+
+       if ((Db += Da) < Da) {
+               R1 += ((cc_u32)1) << 16;
+       }
+       if ((R0 += SDRM_LH(Db)) < SDRM_LH(Db)) {
+               R1++;
+       }
+
+       Dest[0] = R0;
+       Dest[1] = R1 + SDRM_HL(Db);
+       
+       return;
+}
+
+/*
+ * @fn         SDRM_DIGIT_Div
+ * @brief      Doublue-width DWROD Division
+ *
+ * \n  Src1            [in]upper-digit of dividend
+ * \n  Src2            [in]lower-digit of dividend
+ * \n  Div                     [in]divisor
+ */
+cc_u32 SDRM_DIGIT_Div(cc_u32 Src1, cc_u32 Src2, cc_u32 Div)
+{
+       cc_u32  Dq, Dr, Dx, Dy, Dt;
+
+       //      Estimate high half of quotient
+       Dq = Src1 / (SDRM_HL(Div) + 1);
+
+       //      Subtract the product of estimate and divisor from the dividend
+       Dr = Src1 - (SDRM_HL(Div) * Dq);
+       Dx = SDRM_HL(Dr);
+       Dy = SDRM_LH(Dr) + SDRM_HL(Src2);
+       if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
+       {
+               Dx--;
+       }
+
+       //      Correct estimate
+       while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
+       {
+               if((Dr -= Div) > NOT(Div))
+               {
+                       Dx--;
+               }
+               Dq++;
+       }
+       Dt = SDRM_LH(Dq);
+
+       //      Estimate low half of quotient
+       Dq = Dr / (SDRM_HL(Div) + 1);
+
+       //      Subtract the product of estimate and divisor from the dividend
+       Dr -= SDRM_HL(Div) * Dq;
+       Dx = SDRM_HL(Dr);
+       Dy = SDRM_LH(Dr) + SDRM_LL(Src2);
+       if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy) {
+               Dx--;
+       }
+
+       //      Correct estimate
+       while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
+       {
+               if ((Dr -= Div) > NOT(Div))
+               {
+                       Dx--;
+               }
+               Dq++;
+       }
+
+       return (Dt + Dq);
+}
+
+/*
+ * @fn         SDRM_DIGIT_Mod
+ * @brief      Doublue-width DWROD Modular
+ *
+ * \n  Src1            [in]upper-digit of dividend
+ * \n  Src2            [in]lower-digit of dividend
+ * \n  Div                     [in]divisor
+ */
+cc_u32 SDRM_DIGIT_Mod(cc_u32 Src1, cc_u32 Src2, cc_u32 Div)
+{
+       cc_u32  Dq, Dr, Dx, Dy;
+
+       //      Estimate high half of quotient
+       Dq = Src1 / (SDRM_HL(Div) + 1);
+
+       //      Subtract the from dividend the product of estimate and divisor
+       Dr = Src1 - (SDRM_HL(Div) * Dq);
+       Dx = SDRM_HL(Dr);
+       Dy = SDRM_LH(Dr) + SDRM_HL(Src2);
+       if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
+       {
+               Dx--;
+       }
+
+       //      Correct estimate
+       while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
+       {
+               if ((Dr -= Div) > NOT(Div))
+               {
+                       Dx--;
+               }
+       }
+
+       //      Estimate low half of quotient
+       Dq = Dr / (SDRM_HL(Div) + 1);
+
+       //      Subtract the from dividend the product of estimate and divisor
+       Dr -= SDRM_HL(Div) * Dq;
+       Dx = SDRM_HL(Dr);
+       Dy = SDRM_LH(Dr) + SDRM_LL(Src2);
+       if ((Dr = Dy - (SDRM_LL(Div) * Dq)) > Dy)
+       {
+               Dx--;
+       }
+
+       //      Correct estimate
+       while ((Dx > 0) || ((Dx == 0) && (Dr >= Div)))
+       {
+               if ((Dr -= Div) > NOT(Div) )
+               {
+                       Dx--;
+               }
+       }
+
+       return Dr;
+}
+
+#endif //_OP64_NOTSUPPORTED
+
+/*
+ * @fn         SDRM_DWD_Cmp
+ * @brief      cc_u32 Array Comparison
+ *
+ * @param      pdSrc1          [in]first element
+ * @param      dSrcLen1        [in]legnth of pdSrc1
+ * @param      pdSrc2          [in]second element
+ * @param      dSrcLen2        [in]legnth of pdSrc2
+ *
+ * @return     1 if pdSrc1 is larger than pdSrc2
+ * \n          0 if same
+ * \n          -1 if pdSrc2 is larger than pdSrc1
+ */
+static int SDRM_DWD_Cmp(cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
+{
+       cc_u32  i;
+
+       //When the length is different
+       if (dSrcLen1 >= dSrcLen2)
+       {
+               for (i = dSrcLen1 - 1; i != dSrcLen2 - 1; i--)
+               {
+                       if (pdSrc1[i])
+                       {
+                               return +1;
+                       }
+               }
+       }
+       else
+       {
+               for (i = dSrcLen2 - 1; i != dSrcLen1 - 1; i--)
+               {
+                       if (pdSrc2[i])
+                       {
+                               return -1;
+                       }
+               }
+       }
+
+       //Compare common digits
+       for (; i != (cc_u32)-1; i--)
+       {
+               if (pdSrc1[i] == pdSrc2[i])
+               {
+                       continue;
+               }
+               else
+               {
+                       if (pdSrc1[i] > pdSrc2[i])
+                       {
+                               return +1;
+                       }
+                       else
+                       {
+                               return -1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * @fn         SDRM_DWD_SHL
+ * @brief      Shift left the digit array
+ *
+ * @param      pdDest          [out]destination
+ * @param      pdSrc           [in]source
+ * @param      dSrcLen         [in]legnth of pdSrc
+ * @param      dNumOfShift     [in]shift amount
+ *
+ * @return     carry
+ */
+static cc_u32 SDRM_DWD_SHL(cc_u32 *pdDest, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dNumOfShift)
+{
+       cc_u32  i = dSrcLen - 1;
+       cc_u32  dRet;
+
+       if (dSrcLen == 0)
+       {
+               *pdDest = 0;
+               return 0;
+       }
+
+       dRet = pdSrc[i] >> (SDRM_BitsInDWORD - dNumOfShift);
+
+       for (; i != 0; i--)
+       {
+               pdDest[i] = (pdSrc[i] << dNumOfShift) ^ (pdSrc[i - 1] >> (SDRM_BitsInDWORD - dNumOfShift));
+       }
+
+       pdDest[i] = pdSrc[i] << dNumOfShift;
+
+       return dRet;
+}
+
+/*
+ * @fn         SDRM_DWD_SHR
+ * @brief      Shift right the digit array
+ *
+ * @param      pdDest          [out]destination
+ * @param      pdSrc           [in]source
+ * @param      dSrcLen         [in]legnth of pdSrc
+ * @param      dNumOfShift     [in]shift amount
+ *
+ * @return     carry
+ */
+static cc_u32 SDRM_DWD_SHR(cc_u32 *pdDest, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dNumOfShift)
+{
+       cc_u32 i = 0;
+       cc_u32 dRet;
+
+       dRet = pdSrc[i] << (SDRM_BitsInDWORD - dNumOfShift);
+
+       for (; i < dSrcLen - 1; i++)
+       {
+               pdDest[i] = (pdSrc[i] >> dNumOfShift) ^ (pdSrc[i + 1] << (SDRM_BitsInDWORD - dNumOfShift));
+       }
+
+       pdDest[i] = pdSrc[i] >> dNumOfShift;
+
+       return dRet;
+}
+
+/*
+ * @fn         SDRM_DWD_Add
+ * @brief      Add two digit array
+ *
+ * @param      pdDest          [out]destination
+ * @param      pdSrc1          [in]first element
+ * @param      dSrcLen1        [in]legnth of pdSrc1
+ * @param      pdSrc2          [in]second element
+ * @param      dSrcLen2        [in]legnth of pdSrc2
+ *
+ * @return     carry
+ */
+static cc_u32 SDRM_DWD_Add(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
+{
+       cc_u32  i;
+       cc_u32  dCarry = 0, dTemp;
+
+       //add low digits
+       for (i = 0; i < dSrcLen2; i++)
+       {
+               if ((pdSrc2[i] == ((cc_u32)-1)) && (dCarry))
+               {
+                       pdDest[i] = pdSrc1[i];
+               }
+               else
+               {
+                       dTemp = pdSrc2[i] + dCarry;
+                       pdDest[i] = pdSrc1[i] + dTemp;
+                       dCarry = (pdDest[i] < dTemp ) ? 1 : 0;
+               }
+       }
+
+       //copy high digits
+       if (dSrcLen1 > i)
+       {
+               memcpy(pdDest + i, pdSrc1 + i, (dSrcLen1 - i) * SDRM_SIZE_OF_DWORD);
+       }
+
+       //process carry
+       if (!dCarry)
+       {
+               return 0;
+       }
+       else
+       {
+               for (i = dSrcLen2; i < dSrcLen1; i++)
+               {
+                       if (++pdDest[i])
+                       {
+                               return 0;
+                       }
+               }
+       }
+
+       return 1;
+}
+
+/*
+ * @fn         SDRM_DWD_Sub
+ * @brief      subtract digit array
+ *
+ * @param      pdDest          [out]destination
+ * @param      pdSrc1          [in]first element
+ * @param      dSrcLen1        [in]legnth of pdSrc1
+ * @param      pdSrc2          [in]second element
+ * @param      dSrcLen2        [in]legnth of pdSrc2
+ *
+ * @return     carry
+ */
+static cc_u32 SDRM_DWD_Sub(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
+{
+       cc_u32  i;
+       cc_u32  dCarry = 0, dTemp;
+
+       //subtract low digits
+       for (i = 0; i < dSrcLen2; i++)
+       {
+               if (pdSrc2[i] + dCarry == 0)
+               {
+                       pdDest[i] = pdSrc1[i];
+               }
+               else
+               {
+                       dTemp = pdSrc2[i] + dCarry;
+                       pdDest[i] = pdSrc1[i] - dTemp;
+                       dCarry = ((pdDest[i]) > ~(dTemp)) ? 1 : 0;
+               }
+       }
+
+       //copy high digits
+       if (dSrcLen1 > i)
+       {
+               memcpy(pdDest + i, pdSrc1 + i, (dSrcLen1 - i) * SDRM_SIZE_OF_DWORD);
+       }
+       //process carry
+       if (!dCarry)
+       {
+               return 0;
+       }
+       else
+       {
+               for (i = dSrcLen2  ; i < dSrcLen1; i++)
+               {
+                       if (pdDest[i]--)
+                       {
+                               return 0;
+                       }
+               }
+       }
+
+       return (~0);
+}
+
+/*
+ * @fn         SDRM_DWD_MulAdd
+ * @brief      Add multiple
+ *
+ * @param      pdDest          [out]destination
+ * @param      dDstLen         [in]legnth of pbDest
+ * @param      pdSrc           [in]source
+ * @param      dSrcLen         [in]legnth of pdSrc
+ * @param      dMultiplier     [in]multiplier
+ *
+ * @return     carry
+ */
+static cc_u32 SDRM_DWD_MulAdd(cc_u32 *pdDest, cc_u32 dDstLen, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dMultiplier)
+{
+       cc_u32 i;
+       cc_u32 dTemp = 0;
+       cc_u64 pdDigit2;
+
+       //Multiplication part
+       for (i = 0; i < dSrcLen; i++)
+       {
+               /* 
+               * Time code optimization. To be continue! 
+               */
+               pdDigit2 =((cc_u64)pdSrc[i] * dMultiplier) + pdDest[i] + dTemp;
+        pdDest[i] = (cc_u32)pdDigit2;
+        dTemp = pdDigit2 >> 32;
+
+               /*SDRM_DIGIT_Mul(pdDigit, dMultiplier, pdSrc[i]);
+               if ((dTemp += pdDigit[0]) < pdDigit[0])
+               {
+                       pdDigit[1]++;
+               }
+
+               if ((pdDest[i] += dTemp) < dTemp)
+               {
+                       pdDigit[1]++;
+               }
+
+               dTemp = pdDigit[1];*/
+       }
+
+       if (i == dDstLen)
+       {
+               return dTemp;
+       }
+
+       //process top digit
+       if ((pdDest[i] += dTemp) >= dTemp)
+       {
+               return 0;
+       }
+
+       for (i++; i < dDstLen; i++)
+       {
+               if ((++pdDest[i]) != 0)
+               {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+/*
+ * @fn         SDRM_DWD_MulSub
+ * @brief      Multiply and Subtract Digit Array
+ *
+ * @param      pdDest          [out]destination
+ * @param      dDstLen         [in]legnth of pbDest
+ * @param      pdSrc           [in]source
+ * @param      dSrcLen         [in]legnth of pdSrc
+ * @param      dMultiplier     [in]multiplier
+ *
+ * @return     carry
+ */
+static cc_u32 SDRM_DWD_MulSub(cc_u32 *pdDest, cc_u32 dDstLen, cc_u32 *pdSrc, cc_u32 dSrcLen, cc_u32 dMultiplier)
+{
+       cc_u32  i;
+       cc_u32  pdDigit[2], dTemp = 0;
+
+       //Multiplication part
+       for (i = 0; i < dSrcLen; i++)
+       {
+               SDRM_DIGIT_Mul(pdDigit, dMultiplier, pdSrc[i]);
+               dTemp += pdDigit[0];
+
+               if (dTemp < pdDigit[0])
+               {
+                       pdDigit[1]++;
+               }
+
+               if (pdDest[i] < dTemp)
+               {
+                       pdDigit[1]++;
+               }
+
+               pdDest[i] -= dTemp;
+               dTemp = pdDigit[1];
+       }
+
+       if (i == dDstLen)
+       {
+               return dTemp;
+       }
+
+       //process top digit
+       if (pdDest[i] >= dTemp)
+       {
+               pdDest[i] -= dTemp;
+
+               return 0;
+       }
+       else
+       {
+               pdDest[i] -= dTemp;
+       }
+
+       for (i++; i < dDstLen; i++)
+       {
+               if ((pdDest[i]--) != 0)
+               {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+/*
+ * @fn         SDRM_DWD_Mul
+ * @brief      Multiply tow Digit array
+ *
+ * @param      pdDest          [out]destination
+ * @param      pdSrc1          [in]first element
+ * @param      dSrcLen1        [in]legnth of pdSrc1
+ * @param      pdSrc2          [in]second element
+ * @param      dSrcLen2        [in]legnth of pdSrc2
+ *
+ * @return     void
+ */
+static void SDRM_DWD_Mul(cc_u32 *pdDest, cc_u32 *pdSrc1, cc_u32 dSrcLen1, cc_u32 *pdSrc2, cc_u32 dSrcLen2)
+{
+       cc_u32  i, j;
+       cc_u32  dTemp;
+       cc_u64 pdDigit2;
+
+       memset(pdDest, 0, (dSrcLen1 + dSrcLen2) * SDRM_SIZE_OF_DWORD);
+
+       for (j = 0; j < dSrcLen2; j++)
+       {
+               dTemp = 0;
+               for (i = 0; i < dSrcLen1; i++)
+               {
+
+                       pdDigit2 =((cc_u64)pdSrc1[i] * pdSrc2[j]) + pdDest[i + j] + dTemp;
+            pdDest[i + j] = (cc_u32)pdDigit2;
+            dTemp = pdDigit2 >> 32;
+
+
+                       /*SDRM_DIGIT_Mul(pdDigit, pdSrc1[i], pdSrc2[j]);
+                       if ((dTemp += pdDigit[0]) < pdDigit[0])
+                       {
+                               pdDigit[1]++;
+                       }
+
+                       if ((pdDest[i + j] += dTemp) < dTemp)
+                       {
+                               pdDigit[1]++;
+                       }
+
+                       dTemp = pdDigit[1];*/
+               }
+               pdDest[i + j] = dTemp;
+       }
+}
+
+/*
+ * @fn         SDRM_DWD_Div
+ * @brief      Multiply tow Digit array
+ *
+ * @param      pdDest          [out]quotient
+ * @param      pdRem           [out]remainder
+ * @param      pdSrc1          [in]divisor
+ * @param      dSrcLen1        [in]legnth of pdSrc1
+ * @param      pdSrc2          [in]dividend
+ * @param      dSrcLen2        [in]legnth of pdSrc2
+ *
+ * @return     0 if reaminder is zero
+ * \n          1 otherwise
+ */
+static cc_u32 SDRM_DWD_Div(cc_u32 *pdDest, cc_u32 *pdRem,
+                                                  cc_u32 *pdSrc1, cc_u32 dSrcLen1,
+                                                  cc_u32 *pdSrc2, cc_u32 dSrcLen2)
+{
+       cc_u32  i, q, c, dNum_of_Shift = 0;
+       cc_u32  *C = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * 2 * (MAX2(dSrcLen1, dSrcLen2) + 2));
+
+       if (!C)
+       {
+               return (cc_u32)CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_DWD_Copy(C, pdSrc1, dSrcLen1);
+       C[dSrcLen1] = 0;
+       c = dSrcLen1 + 1;
+
+       //Remove lowest '0's
+       for (i = dSrcLen2 * SDRM_BitsInDWORD-1; !SDRM_CheckBitUINT32(pdSrc2, i); i--, dNum_of_Shift++);
+                
+       if (dNum_of_Shift)
+       {
+               SDRM_DWD_SHL(C, C, c, dNum_of_Shift);
+               SDRM_DWD_SHL(pdSrc2, pdSrc2, dSrcLen2, dNum_of_Shift);
+       }
+
+       for (i = c-dSrcLen2 - 1; i != (cc_u32)-1; i--)
+       {
+               if (C[dSrcLen2 + i]==pdSrc2[dSrcLen2 - 1] )
+               {
+                       q = (cc_u32)-1;
+               }
+               else
+               {
+                       q = SDRM_DIGIT_Div(C[dSrcLen2 + i], C[dSrcLen2 + i - 1], pdSrc2[dSrcLen2 - 1]);
+               }
+
+               if (SDRM_DWD_MulSub(C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2, q) )
+               {
+                       q--;
+                       if (!SDRM_DWD_Add(C + i, C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2))
+                       {
+                               q--;
+                               SDRM_DWD_Add(C + i, C + i, dSrcLen2 + 1, pdSrc2, dSrcLen2);
+                       }
+               }
+               pdDest[i] = q;
+       }
+
+       //Recover lowest '0's
+       if (dNum_of_Shift)
+       {
+               SDRM_DWD_SHR(pdSrc2, pdSrc2, dSrcLen2, dNum_of_Shift);
+               SDRM_DWD_SHR(C, C, dSrcLen2, dNum_of_Shift);
+       }
+
+       if (pdRem)
+       {
+               SDRM_DWD_Copy(pdRem, C, dSrcLen2);
+       }
+
+       for (i = 0; i < c; i++)
+       {
+               if (C[i])
+               {
+                       free(C);
+
+                       return 1;
+               }
+       }
+       free(C);
+
+       return 0;
+}
+
+/*
+ * @fn         SDRM_DWD_Classical_REDC
+ * @brief      Classical Modular Reduction Algorithm
+ *
+ * @param      pdDest          [out]destination
+ * @param      DstLen          [in]length of pdDest
+ * @param      pdModulus       [in]modulus
+ * @param      ModLen          [in]legnth of pdModulus
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_DWD_Classical_REDC(cc_u32 *pdDest, cc_u32 DstLen, cc_u32 *pdModulus, cc_u32 ModLen)
+{
+       cc_u32  i;
+       cc_u32  MSB=0, TTTT=0, FLAG=0, D_Quotient, MSD_Modulus;
+
+       if (DstLen < ModLen)
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       if (pdDest[DstLen - 1] >= pdModulus[ModLen - 1])
+       {
+               FLAG++;
+               TTTT = pdDest[DstLen];
+               pdDest[DstLen++] = 0;
+       }
+
+       for (i = SDRM_BitsInDWORD - 1; i != (cc_u32)-1; i--)
+       {
+               if (pdModulus[ModLen - 1] & ((cc_u32)1 << i))
+               {
+                       break;
+               }
+
+               MSB++;
+       }
+
+       if (MSB)
+       {
+               SDRM_DWD_SHL(pdModulus, pdModulus, ModLen, MSB);
+               SDRM_DWD_SHL(pdDest, pdDest, DstLen, MSB);
+       }
+
+       //      Step 2 : main part
+       MSD_Modulus = pdModulus[ModLen - 1];
+       for (i = DstLen - ModLen - 1; i != (cc_u32)-1; i--)
+       {
+               //      Step 2-1 : Estimate D_Quotient
+               if (pdDest[ModLen + i] == MSD_Modulus)
+               {
+                       D_Quotient = (cc_u32)-1;
+               }
+               else
+               {
+                       D_Quotient = SDRM_DIGIT_Div(pdDest[ModLen + i], pdDest[ModLen + i - 1], MSD_Modulus);
+               }
+
+               //      Step 2-2 : Make pdDest <- pdDest-D_Quotient*pdModulus
+               if (SDRM_DWD_MulSub(pdDest + i, ModLen + 1, pdModulus, ModLen, D_Quotient) )
+               {
+                       if (SDRM_DWD_Add(pdDest + i, pdDest + i, ModLen + 1, pdModulus, ModLen) == 0)
+                       {
+                               SDRM_DWD_Add(pdDest + i, pdDest + i, ModLen + 1, pdModulus, ModLen);
+                       }
+               }
+       }
+
+       //      Step 4 : inverse part of Step 2
+       if (MSB)
+       {
+               SDRM_DWD_SHR(pdModulus, pdModulus, ModLen, MSB);
+               SDRM_DWD_SHR(pdDest, pdDest, ModLen, MSB);
+       }
+
+       //      Step 4.5 : inverse part of Step 1.5
+       if (FLAG)
+       {
+               DstLen--;
+               pdDest[DstLen] = TTTT;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DIGIT_Gcd
+ * @brief      get gcd of two digits
+ *
+ * @param      s1                                      [in]first element
+ * @param      s2                                      [in]second element
+ *
+ * @return     gcd
+ */
+cc_u32 SDRM_DIGIT_Gcd(cc_u32 s1, cc_u32 s2)
+ {
+       cc_u32 dTemp;
+
+       if (s1 < s2)
+       {
+               dTemp = s1;
+               s1 = s2;
+               s2 = dTemp;
+       }
+
+       while(s2)
+       {
+               dTemp = s1 % s2;
+               s1 = s2;
+               s2 = dTemp;
+       }
+
+       return s1;
+}
+
+/*
+ * @fn         SDRM_PrintBN
+ * @brief      Show out a Big Number
+ *
+ * @param      level           [in]log level
+ * @param      s                       [in]title
+ * @param      bn                      [in]big number to show out
+ *
+ * @return     void
+ */
+void SDRM_PrintBN(const char* s, SDRM_BIG_NUM* bn)
+{
+       cc_u32 i;
+       if(bn->sign == 0) {
+               printf("%15s %d :", s, (int)(bn->Length));
+       }
+       else {
+               printf("%15s-%d :", s, (int)(bn->Length));
+       }
+       for (i = 0; i < bn->Length ; i++)
+       {
+               printf("%08x ", (int)(bn->pData[bn->Length - i -1])); 
+       }
+
+       printf("\n"); 
+
+       return; 
+}
+
+/*     
+ * @fn         SDRM_BN2OS
+ * @brief      Convert Big Number to Octet String
+ *
+ * @param      BN_Src  [in]source integer
+ * @param      dDstLen [in]Byte-length of pbDst
+ * @param      pbDst   [out]output octet string
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
+ */
+int    SDRM_BN2OS(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
+{
+       cc_u32  i;
+
+       if ((BN_Src == NULL) || (pbDst == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Src);
+
+       if (BN_Src->sign)
+       {
+               pbDst[0] = '-';
+               dDstLen += 1;
+       }
+
+       if ((SDRM_SIZE_OF_DWORD * BN_Src->Length) <= dDstLen)
+       {
+               memset(pbDst, 0, dDstLen);
+
+               for (i = 0; (dDstLen != 0) && (i < BN_Src->Length); i++)
+               {
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]    ) & 0xff);
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>> 8) & 0xff);
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>16) & 0xff);
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>24) & 0xff);
+               }
+       }
+       else
+       {
+               i = (SDRM_SIZE_OF_DWORD * BN_Src->Length) - dDstLen;
+               if (i >= SDRM_SIZE_OF_DWORD)
+               {
+                       return CRYPTO_BUFFER_TOO_SMALL;
+               }
+               else if ( BN_Src->pData[BN_Src->Length - 1] >> (8 * (SDRM_SIZE_OF_DWORD - i)))
+               {
+                       return CRYPTO_BUFFER_TOO_SMALL;
+               }
+
+               for (i = 0;; i++)
+               {
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]    ) & 0xff);
+                       if (dDstLen == 0)
+                       {
+                               break;
+                       }
+
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>> 8) & 0xFF);
+                       if (dDstLen == 0)
+                       {
+                               break;
+                       }
+
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>16) & 0xFF);
+                       if (dDstLen == 0)
+                       {
+                               break;
+                       }
+
+                       pbDst[--dDstLen] = (cc_u8)((BN_Src->pData[i]>>24) & 0xFF);
+                       if (dDstLen == 0)
+                       {
+                               break;
+                       }
+               }
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_OS2BN
+ * @brief      Convert Octet String to Big Number
+ *
+ * @param      pbSrc   [in]source octet string
+ * @param      dSrcLen [in]Byte-length of pbSrc
+ * @param      BN_Dst  [out]output big number
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
+ */
+int    SDRM_OS2BN(cc_u8 *pbSrc, cc_u32 dSrcLen, SDRM_BIG_NUM *BN_Dst)
+{
+       cc_u32  i;
+       int             ret;
+
+       if ((pbSrc == NULL) || (BN_Dst == NULL))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       SDRM_BN_Clr(BN_Dst);
+
+       for (i = 0; i < dSrcLen; i++)
+       {
+               ret = SDRM_BN_SHL(BN_Dst, BN_Dst, 8);
+
+               if (ret != CRYPTO_SUCCESS)
+               {
+                       return ret;
+               }
+
+               BN_Dst->pData[0] ^= pbSrc[i];
+               if (BN_Dst->Length == 0) {
+                       BN_Dst->Length = 1;
+               }
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_I2OSP
+ * @brief      Converts a nonnonegative integer to an octet string of a specified length
+ *
+ * @param      BN_Src                                  [in]nonnegative integer to be converted
+ * @param      dDstLen                                 [in]intended length of the resulting octet string
+ * @param      pbDst                                   [out]corresponding octet string of length dDstLen
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ */
+int    SDRM_I2OSP(SDRM_BIG_NUM *BN_Src, cc_u32 dDstLen, cc_u8 *pbDst)
+{
+       int count;
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Src);
+
+       count = 0;
+       for (dDstLen--; (int)dDstLen >= 0; dDstLen--)
+       {
+               pbDst[count++] = SDRM_CheckByteUINT32(BN_Src->pData, dDstLen);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Clr
+ * @brief      Clear the SDRM_BIG_NUM structure
+ *
+ * @param      BN_Src          [in]source
+ *
+ * @return     CRYPTO_SUCCESS
+ */
+int SDRM_BN_Clr(SDRM_BIG_NUM* BN_Src)
+{
+       BN_Src->sign = 0;
+       BN_Src->Length = 0;
+
+       memset(BN_Src->pData, 0, BN_Src->Size * SDRM_SIZE_OF_DWORD);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Copy
+ * @brief      copy SDRM_BIG_NUM
+ *
+ * @param      BN_Dest         [out]destination
+ * @param      BN_Src          [in]source
+ *
+ * @return     CRYPTO_SUCCESS
+ */
+int SDRM_BN_Copy(SDRM_BIG_NUM* BN_Dest, SDRM_BIG_NUM* BN_Src)
+{
+       if (BN_Src->Length > BN_Dest->Size)
+       {
+               return CRYPTO_BUFFER_TOO_SMALL;
+       }
+
+       BN_Dest->sign = BN_Src->sign;
+       BN_Dest->Length = BN_Src->Length;
+
+       memcpy(BN_Dest->pData, BN_Src->pData, BN_Src->Length * SDRM_SIZE_OF_DWORD);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Alloc
+ * @brief      allocate big number from buffer
+ *
+ * @param      pbSrc           [in]start pointer of buffer
+ * @param      dSize           [in]buffer size of big number
+ *
+ * @return     pointer of SDRM_BIG_NUM structure
+ */
+SDRM_BIG_NUM *SDRM_BN_Alloc(cc_u8* pbSrc, cc_u32 dSize)
+{
+       SDRM_BIG_NUM    *BN_Dest = (SDRM_BIG_NUM*)(void*)pbSrc;
+
+       if (pbSrc == NULL)
+       {
+               return NULL;
+       }
+
+       memset(BN_Dest, 0, sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD);
+       BN_Dest->pData = (cc_u32*)(void*)(pbSrc + sizeof(SDRM_BIG_NUM));
+       BN_Dest->Size = dSize;
+       BN_Dest->Length = 0;
+
+       return BN_Dest;
+}
+
+/*
+ * @fn         SDRM_BN_Init
+ * @brief      Allocate a new big number object
+ *
+ * @param      dSize           [in]buffer size of big number
+ *
+ * @return     pointer of SDRM_BIG_NUM structure
+ * \n          NULL if memory allocation is failed
+ */
+SDRM_BIG_NUM *SDRM_BN_Init(cc_u32 dSize)
+{
+       cc_u32                  AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(AllocSize);
+       SDRM_BIG_NUM    *BN_Src = (SDRM_BIG_NUM*)(void*)pbBuf;
+       if (BN_Src == NULL)
+       {
+               return NULL;
+       }
+
+       memset(BN_Src, 0, AllocSize);
+       BN_Src->pData = (cc_u32*)(void*)(pbBuf + sizeof(SDRM_BIG_NUM));
+       BN_Src->Size = dSize;
+
+       return BN_Src;
+}
+
+/*
+ * @fn         SDRM_BN_Cmp
+ * @brief      Compare two Big Number
+ *
+ * @param      BN_Src1         [in]first element
+ * @param      BN_Src2         [in]second element
+ *
+ * @return     1 if BN_Src1 is larger than pdSrc2
+ * \n          0 if same
+ * \n          -1 if BN_Src2 is larger than pdSrc1
+ */
+int SDRM_BN_Cmp(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+{
+       if (BN_Src1->Length >= BN_Src2->Length)
+       {
+               return  SDRM_DWD_Cmp(BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
+       }
+       else
+       {
+               return -SDRM_DWD_Cmp(BN_Src2->pData, BN_Src2->Length, BN_Src1->pData, BN_Src1->Length);
+       }
+}
+
+/*
+ * @fn         SDRM_BN_Cmp_sign
+ * @brief      Compare two Big Number considering sign
+ *
+ * @param      BN_Src1         [in]first element
+ * @param      BN_Src2         [in]second element
+ *
+ * @return     1 if BN_Src1 is larger than pdSrc2
+ * \n          0 if same
+ * \n          -1 if BN_Src2 is larger than pdSrc1
+ */
+int SDRM_BN_Cmp_sign(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+{
+       if (BN_Src1->sign > BN_Src2->sign)
+       {
+               return -1;
+       }
+       else if (BN_Src1->sign < BN_Src2->sign)
+       {
+               return 1;
+       }
+
+       if ( BN_Src1->Length >= BN_Src2->Length )
+       {
+               return  SDRM_DWD_Cmp(BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
+       }
+       else
+       {
+               return -SDRM_DWD_Cmp(BN_Src2->pData, BN_Src2->Length, BN_Src1->pData, BN_Src1->Length);
+       }
+}
+
+/*
+ * @fn         SDRM_BN_Rand
+ * @brief      Generate simple random number
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BitLen          [in]bit-length of generated random number
+ *
+ * @return     CRYPTO_SUCCESS if no error is occured
+ */
+int SDRM_BN_Rand(SDRM_BIG_NUM *BN_Dst, cc_u32 BitLen)
+{
+       cc_u32  i, j;
+
+       SDRM_BN_Clr(BN_Dst);
+
+       for (i = 0; i < (BitLen / SDRM_BitsInDWORD); i++)
+       {
+               BN_Dst->pData[i] = rand() ^ (rand() << 11);
+       }
+
+       j = BitLen % SDRM_BitsInDWORD;
+       if (j)
+       {
+               BN_Dst->pData[i] = rand() ^ (rand() << 11);
+               BN_Dst->pData[i] &= (((cc_u32)1) << j) - 1;
+               i++;
+       }
+
+       BN_Dst->Length = ((BitLen - 1) / SDRM_BitsInDWORD) + 1;
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_SHL
+ * @brief      Big Number Shift Left
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src          [in]source
+ * @param      NumOfShift      [in]shift amount
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+int SDRM_BN_SHL(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
+{
+       cc_u32  t;
+
+       if (!BN_Src->Length)
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Zero);
+               return CRYPTO_SUCCESS;
+       }
+
+       BN_Dst->sign = BN_Src->sign;
+
+       t = NumOfShift % SDRM_BitsInDWORD;
+       if (t)
+       {
+               BN_Dst->Length = BN_Src->Length;
+               t = SDRM_DWD_SHL(BN_Dst->pData, BN_Src->pData, BN_Src->Length, t);
+               if (t)
+               {
+                       BN_Dst->pData[BN_Dst->Length++] = t;
+               }
+       }
+       else
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Src);
+       }
+
+       t = NumOfShift / SDRM_BitsInDWORD;
+       if (t)
+       {
+               BN_Dst->Length += t;
+
+               memmove((BN_Dst->pData) + t, BN_Dst->pData, (BN_Dst->Length - t) * SDRM_SIZE_OF_DWORD);
+
+               memset(BN_Dst->pData, 0, t * SDRM_SIZE_OF_DWORD);
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_SHR
+ * @brief      Big Number Shift Right
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src          [in]source
+ * @param      NumOfShift      [in]shift amount
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+int SDRM_BN_SHR(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, cc_u32 NumOfShift)
+{
+       cc_u32  t;
+
+       if (!BN_Src->Length)
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Src);
+               return CRYPTO_SUCCESS;
+       }
+       
+       t = NumOfShift / SDRM_BitsInDWORD;
+       if (t)
+       {
+               if (t >= BN_Src->Length)
+               {
+                       SDRM_BN_Copy(BN_Dst, BN_Zero);
+                       return CRYPTO_SUCCESS;
+               }
+
+               memcpy(BN_Dst->pData, (BN_Src->pData) + t, (BN_Src->Length - t) * SDRM_SIZE_OF_DWORD);
+
+               BN_Dst->Length = BN_Src->Length - t;
+               BN_Dst->sign = BN_Src->sign;
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+       }
+       else
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Src);
+       }
+
+       t = NumOfShift % SDRM_BitsInDWORD;
+       if (t)
+       {
+               SDRM_DWD_SHR(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, t);
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Add
+ * @brief      Big Number Addition
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src1         [in]first element
+ * @param      BN_Src2         [in]second element
+ *
+ * @return     CRYPTO_SUCCESS                          if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Add(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+{
+       cc_u32                  carry, dSize, dAllocSize;
+       SDRM_BIG_NUM    *temp, *temp_Src1, *temp_Src2;
+       cc_u8                   *pbBuf;
+       
+       dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       pbBuf = (cc_u8*)malloc(dAllocSize * 2);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       temp_Src1 = SDRM_BN_Alloc(pbBuf, dSize);
+       temp_Src2 = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
+
+       if (!BN_Src1->Length)
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Src2);
+               free(pbBuf);
+               
+               return CRYPTO_SUCCESS;
+       }
+
+       if (!BN_Src2->Length) {
+               SDRM_BN_Copy(BN_Dst, BN_Src1);
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS;
+       }
+
+       SDRM_BN_Copy(temp_Src1, BN_Src1);
+       SDRM_BN_Copy(temp_Src2, BN_Src2);
+
+       if (temp_Src1->sign ^ temp_Src2->sign)
+       {
+               if (temp_Src1->sign)
+               {
+                       temp = temp_Src1;
+                       temp_Src1 = temp_Src2;
+                       temp_Src2 = temp;
+               }
+
+               if (SDRM_BN_Cmp(temp_Src1, temp_Src2) < 0)
+               {
+                       SDRM_DWD_Sub(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
+                       BN_Dst->sign = 1;
+                       BN_Dst->Length = temp_Src2->Length;
+               }
+               else
+               {
+                       SDRM_DWD_Sub(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
+                       BN_Dst->sign = 0;
+                       BN_Dst->Length = temp_Src1->Length;
+               }
+
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS;
+       }
+
+       if (temp_Src1->sign)
+       {
+               BN_Dst->sign = 1;
+       }
+       else
+       {
+               BN_Dst->sign = 0;
+       }
+
+       if (temp_Src1->Length > temp_Src2->Length)
+       {
+               BN_Dst->Length = temp_Src1->Length;
+               carry = SDRM_DWD_Add(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
+               if (carry)
+               {
+                       BN_Dst->pData[BN_Dst->Length++] = carry;
+               }
+       }
+       else
+       {
+               BN_Dst->Length = temp_Src2->Length;
+               carry = SDRM_DWD_Add(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
+               if ( carry )
+               {
+                       BN_Dst->pData[BN_Dst->Length++] = carry;
+               }
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Sub
+ * @brief      Big Number Subtraction
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src1         [in]first element
+ * @param      BN_Src2         [in]second element
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Sub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+{
+       int                             i, add = 0, dSize, dAllocSize;
+       SDRM_BIG_NUM    *temp, *temp_Src1, *temp_Src2;
+       cc_u8                   *pbBuf;
+
+       dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+       pbBuf = (cc_u8*)malloc(dAllocSize * 2);
+
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       temp_Src1 = SDRM_BN_Alloc(pbBuf, dSize);
+       temp_Src2 = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
+
+       SDRM_BN_Copy(temp_Src1, BN_Src1);
+       SDRM_BN_Copy(temp_Src2, BN_Src2);
+
+       if (BN_Src1 == BN_Src2)
+       {
+               SDRM_BN_Clr(BN_Dst);
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS;
+       }
+
+       //to process sign
+       if (temp_Src1->sign)
+       {
+               if (temp_Src2->sign)
+               {
+                       temp = temp_Src1;
+                       temp_Src1 = temp_Src2;
+                       temp_Src2 = temp;
+               }
+               else
+               {
+                       add = 1;
+                       temp_Src2->sign = 1;
+               }
+       }
+       else
+       {
+               if (temp_Src2->sign)
+               {
+                       add = 1;
+                       temp_Src2->sign = 0;
+               }
+       }
+
+       if (add)
+       {
+               i = (temp_Src1->Length | temp_Src2->Length) +1;
+               if (i)
+               {
+                       SDRM_BN_Add(BN_Dst, temp_Src1, temp_Src2);
+               }
+               else
+               {
+                       SDRM_BN_Add(BN_Dst, temp_Src2, temp_Src1);
+               }
+
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS;
+       }
+
+       if (SDRM_BN_Cmp(temp_Src1, temp_Src2) < 0)
+       {
+               SDRM_DWD_Sub(BN_Dst->pData, temp_Src2->pData, temp_Src2->Length, temp_Src1->pData, temp_Src1->Length);
+               BN_Dst->sign = 1;
+               BN_Dst->Length = temp_Src2->Length;
+       }
+       else
+       {
+               SDRM_DWD_Sub(BN_Dst->pData, temp_Src1->pData, temp_Src1->Length, temp_Src2->pData, temp_Src2->Length);
+               BN_Dst->sign = 0;
+               BN_Dst->Length = temp_Src1->Length;
+       }
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Mul
+ * @brief      Big Number Multiplication
+ *
+ * @param      BN_Dst                  [out]destination
+ * @param      BN_Multiplicand [in]first element
+ * @param      BN_Multiplier   [in]second element
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Multiplicand, SDRM_BIG_NUM *BN_Multiplier)
+{
+       SDRM_BIG_NUM    *Dst;
+
+       if ((BN_Multiplicand->Length == 0) || (BN_Multiplier->Length == 0))
+       {
+               SDRM_BN_Clr(BN_Dst);
+               return CRYPTO_SUCCESS;
+       }
+
+       Dst = SDRM_BN_Init(BN_Dst->Size * 2);
+       if (Dst == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       Dst->Length = BN_Multiplicand->Length + BN_Multiplier->Length;
+
+       if (BN_Multiplicand->sign != BN_Multiplier->sign)
+       {
+               Dst->sign = 1;
+       }
+       else
+       {
+               Dst->sign = 0;
+       }
+
+       if (BN_Multiplicand->Length > BN_Multiplier->Length)
+       {
+               SDRM_DWD_Mul(Dst->pData, BN_Multiplicand->pData, BN_Multiplicand->Length, BN_Multiplier->pData, BN_Multiplier->Length);
+       }
+       else
+       {
+               SDRM_DWD_Mul(Dst->pData, BN_Multiplier->pData, BN_Multiplier->Length, BN_Multiplicand->pData, BN_Multiplicand->Length);
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(Dst);
+
+       SDRM_BN_Copy(BN_Dst, Dst);
+       SDRM_BN_FREE(Dst);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_Div
+ * @brief      Big Number Division
+ *
+ * @param      BN_Quotient             [out]quotient
+ * @param      BN_Remainder    [out]remainder
+ * @param      BN_Dividend             [in]dividend
+ * @param      BN_Divisor              [in]divisor
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_Div(SDRM_BIG_NUM *BN_Quotient, SDRM_BIG_NUM *BN_Remainder, SDRM_BIG_NUM *BN_Dividend, SDRM_BIG_NUM *BN_Divisor)
+{
+       cc_u32                  tmp, dSize, dAllocSize;
+       SDRM_BIG_NUM    *temp_Dividend, *temp_Divisor;
+       cc_u32                  *bnTmp;
+       cc_u8                   *pbBuf;
+
+       if (BN_Quotient != NULL)
+       {
+               dSize = MAX2(BN_Quotient->Size, BN_Dividend->Size);
+       }
+       else
+       {
+               dSize = BN_Dividend->Size;
+       }
+
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+       pbBuf = (cc_u8*)malloc(dAllocSize * 3 + 2 * SDRM_SIZE_OF_DWORD);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       temp_Dividend   = SDRM_BN_Alloc(pbBuf, dSize);
+       temp_Divisor    = SDRM_BN_Alloc(pbBuf + dAllocSize, dSize);
+       bnTmp = (cc_u32*)(void*)(pbBuf + dSize + dAllocSize);
+
+       SDRM_BN_Copy(temp_Dividend, BN_Dividend);
+       SDRM_BN_Copy(temp_Divisor, BN_Divisor);
+
+       if (SDRM_BN_Cmp(temp_Dividend, temp_Divisor) < 0)
+       {
+               if (BN_Remainder != NULL)
+               {
+                       SDRM_BN_Copy(BN_Remainder, temp_Dividend);
+                       //free(pbBuf);  
+                       //return CRYPTO_SUCCESS; modify by Chalyi Aleksandr: it is not correct
+               }
+
+               if (BN_Quotient != NULL)
+               {
+                       SDRM_BN_Clr(BN_Quotient);
+               }
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS;
+       }
+
+       if (BN_Quotient == NULL)
+       {
+               BN_Remainder->Length = temp_Divisor->Length;
+               tmp = SDRM_DWD_Div(bnTmp, BN_Remainder->pData, temp_Dividend->pData, temp_Dividend->Length, temp_Divisor->pData, temp_Divisor->Length);
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Remainder);
+               BN_Remainder->sign = BN_Dividend->sign;
+       }
+       else if (BN_Remainder == NULL)
+       {
+               BN_Quotient->Length = temp_Dividend->Length - temp_Divisor->Length + 1;
+               tmp = SDRM_DWD_Div(BN_Quotient->pData, bnTmp, temp_Dividend->pData, temp_Dividend->Length, temp_Divisor->pData, temp_Divisor->Length);
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Quotient);
+               BN_Quotient->sign= (BN_Dividend->sign^BN_Divisor->sign);
+       }
+       else
+       {
+               BN_Quotient->Length = temp_Dividend->Length - temp_Divisor->Length + 1;
+               BN_Remainder->Length = temp_Divisor->Length;
+               BN_Quotient->sign= (BN_Dividend->sign^BN_Divisor->sign);
+               BN_Remainder->sign = BN_Dividend->sign;
+
+               tmp = SDRM_DWD_Div(BN_Quotient->pData, BN_Remainder->pData, BN_Dividend->pData, BN_Dividend->Length, BN_Divisor->pData, BN_Divisor->Length);
+
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Quotient);
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Remainder);
+       }
+
+       free(pbBuf);
+
+       if (!(tmp == 0 || tmp == 1))
+       {
+               return CRYPTO_ERROR;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_ModAdd
+ * @brief      Big Number Modular Addition
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src1         [in]first element of addition
+ * @param      BN_Src2         [in]second element of addition
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModAdd(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
+{
+       SDRM_BIG_NUM    *BN_Src1_temp, *BN_Src2_temp;
+       cc_u8                   *pbBuf;
+       cc_u32                  tmp = 0, dSize, AllocSize;
+
+       dSize = MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size);
+       AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       pbBuf = (cc_u8*)malloc(AllocSize * 2);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_Src1_temp = SDRM_BN_Alloc(pbBuf, dSize);
+       BN_Src2_temp = SDRM_BN_Alloc(pbBuf + AllocSize, dSize);
+
+       SDRM_BN_Copy(BN_Src1_temp, BN_Src1);
+       SDRM_BN_Copy(BN_Src2_temp, BN_Src2);
+
+       if ((SDRM_BN_Cmp(BN_Src1, BN_Modulus)>=0))
+       {
+               SDRM_BN_ModRed(BN_Src1_temp, BN_Src1, BN_Modulus);
+       }
+
+       if ((SDRM_BN_Cmp(BN_Src2, BN_Modulus)>=0))
+       {
+               SDRM_BN_ModRed(BN_Src2_temp, BN_Src2, BN_Modulus);
+       }
+
+       if (BN_Src1_temp->Length >= BN_Src2_temp->Length)
+       {
+               BN_Dst->Length = BN_Src1_temp->Length;
+               BN_Dst->sign = BN_Src1_temp->sign;
+               tmp = SDRM_DWD_Add(BN_Dst->pData, BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
+       }
+       else
+       {
+               BN_Dst->Length = BN_Src2_temp->Length;
+               BN_Dst->sign = BN_Src2_temp->sign;
+               tmp = SDRM_DWD_Add(BN_Dst->pData, BN_Src2_temp->pData, BN_Src2_temp->Length,
+                                                                        BN_Src1_temp->pData, BN_Src1_temp->Length);
+       }
+
+       if (tmp)
+       {
+               BN_Dst->pData[BN_Dst->Length++] = tmp;
+       }
+
+       SDRM_BN_ModRed(BN_Dst, BN_Dst, BN_Modulus);
+
+       if (SDRM_DWD_Cmp(BN_Dst->pData, BN_Dst->Length, BN_Modulus->pData, BN_Modulus->Length) >= 0)
+       {
+               SDRM_DWD_Sub(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, BN_Modulus->pData, BN_Modulus->Length);
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_ModSub
+ * @brief      Big Number Modular Subtraction
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src1         [in]first element of subtraction
+ * @param      BN_Src2         [in]second element of subtraction
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModSub(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
+{
+       cc_u32                  tmp = 0, dSize, AllocSize;
+       SDRM_BIG_NUM    *BN_Src1_temp, *BN_Src2_temp;
+       cc_u8                   *pbBuf;
+
+       dSize = MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size);
+       AllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       pbBuf = (cc_u8*)malloc(AllocSize * 2);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_Src1_temp = SDRM_BN_Alloc(pbBuf, dSize);
+       BN_Src2_temp = SDRM_BN_Alloc(pbBuf + AllocSize, dSize);
+
+       SDRM_BN_Copy(BN_Src1_temp, BN_Src1);
+       SDRM_BN_Copy(BN_Src2_temp, BN_Src2);
+
+       if ((SDRM_BN_Cmp(BN_Src1, BN_Modulus) >= 0))
+       {
+               SDRM_BN_ModRed(BN_Src1_temp, BN_Src1, BN_Modulus);
+       }
+
+       if ((SDRM_BN_Cmp(BN_Src2, BN_Modulus) >= 0))
+       {
+               SDRM_BN_ModRed(BN_Src2_temp, BN_Src2, BN_Modulus);
+       }
+
+       if (SDRM_DWD_Cmp(BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length) >= 0)
+       {
+               BN_Dst->Length = BN_Src1_temp->Length;
+               BN_Dst->sign = BN_Src1_temp->sign;
+
+               tmp = SDRM_DWD_Sub(BN_Dst->pData, BN_Src1_temp->pData, BN_Src1_temp->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
+       }
+       else
+       {
+               BN_Dst->Length = BN_Modulus->Length;
+               BN_Dst->sign = BN_Modulus->sign;
+               SDRM_DWD_Add(BN_Dst->pData, BN_Modulus->pData, BN_Modulus->Length, BN_Src1_temp->pData, BN_Src1_temp->Length);
+               SDRM_DWD_Sub(BN_Dst->pData, BN_Dst->pData, BN_Dst->Length, BN_Src2_temp->pData, BN_Src2_temp->Length);
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+       free(pbBuf);
+
+       if (tmp != 0)
+       {
+               return CRYPTO_ERROR;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_ModRed
+ * @brief      Big Number Modular Reduction
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src          [in]source
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModRed(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
+{
+       int                     ret;
+       cc_u32          *Value = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * 2 * (sizeof(SDRM_BIG_NUM) + MAX2(BN_Src->Size, BN_Modulus->Size) + 2));
+
+       if (!Value)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       if (SDRM_BN_Cmp(BN_Src, BN_Modulus) < 0)
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Src);
+               free(Value);
+               return CRYPTO_SUCCESS;
+       }
+
+       memcpy(Value, BN_Src->pData, BN_Src->Length * SDRM_SIZE_OF_DWORD);
+
+       ret = SDRM_DWD_Classical_REDC(Value, BN_Src->Length,    BN_Modulus->pData, BN_Modulus->Length);
+
+       if (ret != CRYPTO_SUCCESS)
+       {
+               free(Value);
+               return ret;
+       }
+
+       memcpy(BN_Dst->pData, Value, BN_Modulus->Length * SDRM_SIZE_OF_DWORD);
+
+       BN_Dst->Length = BN_Modulus->Length;
+       BN_Dst->sign = BN_Modulus->sign;
+       SDRM_BN_OPTIMIZE_LENGTH(BN_Dst);
+
+       free(Value);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*     
+ * @fn         SDRM_BN_ModMul
+ * @brief      Big Number Modular Multiplication
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Src1         [in]first element of multiplication
+ * @param      BN_Src2         [in]second element of multipliation
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+int SDRM_BN_ModMul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_NUM *BN_Modulus)
+{
+       int             ret;
+       SDRM_BIG_NUM Dest;
+       cc_u32  *Value = (cc_u32*)malloc(SDRM_SIZE_OF_DWORD * (MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size) + 2));
+
+       if (!Value)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       memset(Value, 0x00, SDRM_SIZE_OF_DWORD * (MAX3(BN_Src1->Size, BN_Src2->Size, BN_Modulus->Size) + 2));
+
+       SDRM_DWD_Mul(Value, BN_Src1->pData, BN_Src1->Length, BN_Src2->pData, BN_Src2->Length);
+
+       ret = SDRM_DWD_Classical_REDC(Value, BN_Src1->Length + BN_Src2->Length, BN_Modulus->pData, BN_Modulus->Length);
+       if (ret != CRYPTO_SUCCESS)
+       {
+               free(Value);
+
+               return ret;
+       }
+
+       Dest.sign = (BN_Src1->sign == BN_Src2->sign)? 0 : 1;
+       Dest.Length = BN_Modulus->Length;
+       Dest.pData = Value;
+
+       SDRM_BN_OPTIMIZE_LENGTH(&Dest);
+
+       SDRM_BN_Copy(BN_Dst, &Dest);
+
+       free(Value);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_ModInv
+ * @brief      Big Number Modular Inverse
+ *
+ * @param      BN_Dest         [out]destination
+ * @param      BN_Src          [in]soure
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ * \n          CRYPTO_NEGATIVE_INPUT           if source is negative value
+ * \n          CRYPTO_INVERSE_NOT_EXIST        if inverse is not exists
+ */
+int SDRM_BN_ModInv(SDRM_BIG_NUM *BN_Dest, SDRM_BIG_NUM *BN_Src, SDRM_BIG_NUM *BN_Modulus)
+{
+       SDRM_BIG_NUM    *BN_G0, *BN_G1, *BN_V0, *BN_V1, *BN_Y, *BN_Temp1, *BN_Temp2;
+       cc_u8                   *pbBuf = NULL;
+       cc_u32                  dSize, dAllocSize;
+
+       dSize = MAX2(BN_Src->Size, BN_Modulus->Size);
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       pbBuf = (cc_u8*)malloc(dAllocSize * 7);
+
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_G0 =    SDRM_BN_Alloc(pbBuf, dSize);
+       BN_G1 =    SDRM_BN_Alloc((cc_u8*)BN_G0    + dAllocSize, dSize);
+       BN_V0 =    SDRM_BN_Alloc((cc_u8*)BN_G1    + dAllocSize, dSize);
+       BN_V1 =    SDRM_BN_Alloc((cc_u8*)BN_V0    + dAllocSize, dSize);
+       BN_Y =     SDRM_BN_Alloc((cc_u8*)BN_V1    + dAllocSize, dSize);
+       BN_Temp1 = SDRM_BN_Alloc((cc_u8*)BN_Y     + dAllocSize, dSize);
+       BN_Temp2 = SDRM_BN_Alloc((cc_u8*)BN_Temp1 + dAllocSize, dSize);
+
+       if (BN_Src->sign)
+       {
+               free(pbBuf);
+               return CRYPTO_NEGATIVE_INPUT;
+       }
+
+       //Extended Euclid Algorithm
+       SDRM_BN_Copy(BN_G0, BN_Modulus);
+       SDRM_BN_ModRed(BN_G1, BN_Src, BN_Modulus);
+
+       SDRM_BN_Copy(BN_V0, BN_Zero);
+       SDRM_BN_Copy(BN_V1, BN_One);
+
+       SDRM_BN_Clr(BN_Y);
+       SDRM_BN_Clr(BN_Dest);
+
+       while(SDRM_BN_Cmp(BN_G1, BN_Zero))
+       {
+               if (!SDRM_BN_Cmp(BN_G1, BN_One))
+               {
+                       SDRM_BN_Copy(BN_Dest, BN_V1);
+                       SDRM_BN_OPTIMIZE_LENGTH(BN_Dest);
+                       free(pbBuf);
+
+                       return CRYPTO_SUCCESS;
+               }
+
+               SDRM_BN_Clr(BN_Y);
+               SDRM_BN_Clr(BN_Temp1);
+               SDRM_DWD_Div(BN_Y->pData, BN_Temp1->pData, BN_G0->pData, BN_G0->Length, BN_G1->pData, BN_G1->Length);
+
+               BN_Y->Length = BN_G0->Length;
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Y);
+
+               BN_Temp1->Length = BN_G1->Length;
+               SDRM_BN_Copy(BN_G0, BN_Temp1);
+               SDRM_BN_OPTIMIZE_LENGTH(BN_G0);
+
+               SDRM_BN_Clr(BN_Temp1);
+               SDRM_DWD_Mul(BN_Temp1->pData, BN_Y->pData, BN_Y->Length, BN_V1->pData, BN_V1->Length);
+               BN_Temp1->Length = BN_Y->Length + BN_V1->Length;
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Temp1);
+
+               SDRM_BN_Clr(BN_Temp2);
+               if (SDRM_BN_Cmp(BN_V0, BN_Temp1) >= 0)
+               {
+                       SDRM_BN_Add(BN_Temp2, BN_V0, BN_Temp1);
+               }
+               else
+               {
+                       SDRM_BN_Add(BN_Temp2, BN_Temp1, BN_V0);
+               }
+
+               SDRM_BN_Copy(BN_V0, BN_Temp2);
+
+               if (!SDRM_BN_Cmp(BN_G0, BN_Zero))
+               {
+                       break;
+               }
+
+               if (!SDRM_BN_Cmp(BN_G0, BN_One))
+               {
+                       SDRM_BN_Sub(BN_Dest, BN_Modulus, BN_V0);
+                       SDRM_BN_OPTIMIZE_LENGTH(BN_Dest);
+                       free(pbBuf);
+
+                       return CRYPTO_SUCCESS;
+               }
+
+               SDRM_BN_Clr(BN_Y);
+               SDRM_BN_Clr(BN_Temp1);
+               SDRM_DWD_Div(BN_Y->pData, BN_Temp1->pData, BN_G1->pData, BN_G1->Length, BN_G0->pData, BN_G0->Length);
+
+               BN_Y->Length = BN_G1->Length;
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Y);
+
+               BN_Temp1->Length = BN_G0->Length;
+               SDRM_BN_Copy(BN_G1, BN_Temp1);
+               SDRM_BN_OPTIMIZE_LENGTH(BN_G1);
+
+               SDRM_BN_Clr(BN_Temp1);
+               SDRM_DWD_Mul(BN_Temp1->pData, BN_Y->pData, BN_Y->Length, BN_V0->pData, BN_V0->Length);
+               BN_Temp1->Length = BN_Y->Length + BN_V0->Length;
+               SDRM_BN_OPTIMIZE_LENGTH(BN_Temp1);
+
+               SDRM_BN_Clr(BN_Temp2);
+               if (SDRM_BN_Cmp(BN_V1, BN_Temp1) >= 0)
+               {
+                       SDRM_BN_Add(BN_Temp2, BN_V1, BN_Temp1);
+               }
+               else
+               {
+                       SDRM_BN_Add(BN_Temp2, BN_Temp1, BN_V1);
+               }
+
+               SDRM_BN_Copy(BN_V1, BN_Temp2);
+       }
+
+       SDRM_BN_Copy(BN_Dest, BN_Zero);
+       free(pbBuf);
+
+       return CRYPTO_INVERSE_NOT_EXIST;
+}
+
+/*
+ * @fn         SDRM_MONT_Rzn2zn
+ * @brief      Convert Montgomery number to noraml number
+ *
+ * @param      BN_Dst          [out]destination, normal number
+ * @param      BN_Src1         [in]source, montgomery number
+ * @param      Mont            [in]montgomery parameters
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+int SDRM_MONT_Rzn2zn(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_MONT *Mont)
+{
+       cc_u32                  Src1_Len, Mod_Len, ri, i;
+       cc_u32                  carry;
+       SDRM_BIG_NUM    *Src1 = NULL;
+       
+       if (!BN_Src1->Length)
+       {
+               BN_Dst->Length = 0;
+
+               return CRYPTO_SUCCESS;
+       }
+
+       Src1_Len = ri = Mont->ri / SDRM_BitsInDWORD;
+       Mod_Len = Mont->Mod->Length + 1;
+
+       Src1 = SDRM_BN_Init(BN_Src1->Size + Mod_Len);
+    if(Src1 == NULL)//fixed prevent cid=89093 by guoxing.xu 
+    {
+        return CRYPTO_ERROR;
+    }
+       SDRM_BN_Copy(Src1, BN_Src1);
+       
+       if (!Src1_Len || !Mod_Len)
+       {
+               BN_Dst->Length = 0;
+               BN_Dst->pData[0] = 0;
+               SDRM_BN_FREE(Src1);
+
+               return CRYPTO_SUCCESS;
+       }
+
+       Src1->sign = BN_Src1->sign ^ Mont->Mod->sign;
+
+       memset(Src1->pData + Src1->Length, 0, (Mod_Len + BN_Src1->Length - Src1->Length) * SDRM_SIZE_OF_DWORD);
+       
+       Src1->Length = Mod_Len + BN_Src1->Length;
+
+       for (i = 0; i < Mod_Len; i++)
+       {       
+               if ((carry = SDRM_DWD_MulAdd(Src1->pData + i, Src1->Length - i, Mont->Mod->pData, Mod_Len, (cc_u32)Src1->pData[i] * Mont->N0)))
+               {
+                       Src1->pData[Src1->Length++] = carry;                                                            //Added by Park Ji soon, 05-03-2006
+               }                                                                                                                                               // (cc_u32)A.pData[i]*modulus_p   <== u=a[i]*m' mod b
+                                                                                                                                                               //  A=A+ (A.pData[i]*modulus_p* modulus[i])*b^i;
+       }
+       SDRM_BN_OPTIMIZE_LENGTH(Src1);
+
+       SDRM_BN_SHR(BN_Dst, Src1, (Mod_Len) * 32);
+       //BN_Dst->Length = Src1->Length - ri;
+       BN_Dst->Length = Src1->Length - ri- 1;//Added by yhhwang
+
+       //if (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
+       while (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
+       {
+               SDRM_BN_Sub(BN_Dst, BN_Dst, Mont->Mod);
+       }
+
+       SDRM_BN_FREE(Src1);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_MONT_Mul
+ * @brief      Montgomery Multiplication
+ *
+ * @param      BN_Dst          [out]destination, montgomery number
+ * @param      BN_Src1         [in]first element, montgomery number
+ * @param      BN_Src2         [in]second element, montgomery number
+ * @param      Mont            [in]montgomery parameters
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ */
+int SDRM_MONT_Mul(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2, SDRM_BIG_MONT *Mont)
+{
+       int ret;
+
+       /* Begin - Add to test input range by Yong Ho Hwang (20120809) */
+       /*
+       if (SDRM_BN_Cmp(BN_Src1, Mont->Mod) >= 0)
+       {
+               ret = SDRM_BN_ModRed(BN_Src1, BN_Src1, Mont->Mod);
+               if (ret != CRYPTO_SUCCESS)
+               {
+                       return ret;
+               }
+       } else if ( BN_Src1->sign == 1)
+       {
+               printf("Minus Value\n");
+               ret = SDRM_BN_Add(BN_Src1, BN_Src1, Mont->Mod);
+               if (BN_Src1->sign == 1)
+               {
+                       printf("Value Fail.\n");
+                       return CRYPTO_ERROR;
+               }
+       }
+       
+       if (SDRM_BN_Cmp(BN_Src2, Mont->Mod) >= 0)
+       {
+               ret = SDRM_BN_ModRed(BN_Src2, BN_Src2, Mont->Mod);
+               if (ret != CRYPTO_SUCCESS)
+               {
+                       return ret;
+               }
+       } else if ( BN_Src2->sign == 1)
+       {
+               printf("Minus Value\n");
+               ret = SDRM_BN_Add(BN_Src2, BN_Src2, Mont->Mod);
+               if (BN_Src2->sign == 1)
+               {
+                       printf("Value Fail.\n");
+                       return CRYPTO_ERROR;
+               }
+       }
+       */
+       /* End - Add to test input range by Yong Ho Hwang (20120809) */
+
+       ret = SDRM_BN_Mul(BN_Dst, BN_Src1, BN_Src2);
+       if (ret != CRYPTO_SUCCESS)
+       {
+               return ret;
+       }
+
+       ret = SDRM_MONT_Rzn2zn(BN_Dst, BN_Dst, Mont);
+
+       /* Begin - Add to test input range by Yong Ho Hwang (20120809) */
+       /*
+       if (SDRM_BN_Cmp(BN_Dst, Mont->Mod) >= 0)
+       {
+               printf("Output is bigger than Mod\n");
+       } else if ( BN_Dst->sign == 1)
+       {
+               printf("Minus Value\n");
+       }
+       */
+       /* End - Add to test input range by Yong Ho Hwang (20120809) */
+
+       return ret;
+}
+
+/*
+ * @fn         SDRM_MONT_Set
+ * @brief      Set Montgomery parameters
+ *
+ * @param      Mont            [out]montgomery parameter
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          BN_NOT_ENOUGHT_BUFFER if malloc is failed
+ * \n          CRYPTO_INVERSE_NOT_EXIST if inverse is not exists
+ */
+int SDRM_MONT_Set(SDRM_BIG_MONT *Mont, SDRM_BIG_NUM *BN_Modulus)
+{
+       SDRM_BIG_NUM    *Ri, *R;
+       SDRM_BIG_NUM    *temp, *Rsquare;
+       cc_u8                   *pbBuf;
+       cc_u32                  buf[2], dSize, dAllocSize, r2Size;
+
+       if ((Mont == NULL) || (BN_Modulus == NULL))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (Mont->R == NULL)
+       {
+               Mont->R = SDRM_BN_Init(BN_Modulus->Size);
+       }
+    if (Mont->R == NULL)//fix prevent 89095 by guoxing.xu
+    {
+        return CRYPTO_MEMORY_ALLOC_FAIL; 
+    }
+       if (Mont->Mod == NULL)
+       {
+               Mont->Mod = SDRM_BN_Init(BN_Modulus->Size);
+       }
+       if (Mont->Mod == NULL)//fix prevent 89-95 by guoxing.xu
+    {
+        SDRM_BN_FREE(Mont->R);
+        return CRYPTO_MEMORY_ALLOC_FAIL; 
+    }
+       if (SDRM_BN_Cmp(Mont->Mod, BN_Modulus) == 0)
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       dSize = BN_Modulus->Size + 1;
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+       if (!(pbBuf = (cc_u8*)malloc(dAllocSize * 3)))
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       Ri =   SDRM_BN_Alloc( pbBuf,                             dSize);
+       R =    SDRM_BN_Alloc((cc_u8*)Ri + dAllocSize, dSize);
+       temp = SDRM_BN_Alloc((cc_u8*)R  + dAllocSize, dSize);
+
+//++ 2012.08.20 - modified by yhhwang to apply R=2^(160+32)
+/* == DELETED ==
+       SDRM_BN_Copy(Mont->Mod, BN_Modulus);
+
+       Mont->ri = (SDRM_BN_num_bits(BN_Modulus) + (SDRM_BitsInDWORD - 1)) / SDRM_BitsInDWORD * SDRM_BitsInDWORD;
+
+       SDRM_BN_SHL(R, BN_One, SDRM_BitsInDWORD);
+
+       buf[0] = BN_Modulus->pData[0];
+       buf[1] = 0;
+       temp->pData[0] = buf[0];
+       temp->Length = 1;
+       temp->sign = BN_Modulus->sign;
+
+       SDRM_BN_ModInv(Ri, R, temp);
+       if (Ri == NULL)
+       {
+               free(pbBuf);
+
+               return CRYPTO_INVERSE_NOT_EXIST;
+       }
+
+       SDRM_BN_SHL(Ri, Ri, SDRM_BitsInDWORD);
+       SDRM_BN_Sub(Ri, Ri, BN_One);
+       SDRM_BN_Div(Ri, NULL, Ri, temp);
+       SDRM_BN_Copy(Mont->Inv_Mod, Ri);
+       Mont->N0 = Ri->pData[0];
+
+       SDRM_BN_SHL(Mont->R, BN_One, 2 * (32 + Mont->ri));
+       SDRM_BN_ModRed(Mont->R, Mont->R, Mont->Mod);
+*/
+
+// == NEW CODE ==
+       SDRM_BN_Copy(Mont->Mod, BN_Modulus);
+       Mont->Mod->pData[Mont->Mod->Length] = 0;        
+       
+       Mont->ri = (SDRM_BN_num_bits(BN_Modulus) + (SDRM_BitsInDWORD - 1)) / SDRM_BitsInDWORD * SDRM_BitsInDWORD;
+
+       SDRM_BN_SHL(R, BN_One, SDRM_BitsInDWORD);
+       
+       // Compute -m^-1 mod b
+       buf[0] = BN_Modulus->pData[0];
+       buf[1] = 0;
+       temp->pData[0] = buf[0];
+       temp->Length = 1;
+       temp->sign = BN_Modulus->sign;
+       
+       SDRM_BN_ModInv(Ri, temp, R);
+       Ri->sign = 1;
+       SDRM_BN_Add(Ri, Ri, R);
+       Mont->N0 = Ri->pData[0];
+       
+       r2Size = 2 * (SDRM_BitsInDWORD + Mont->ri);
+       Rsquare = SDRM_BN_Init(r2Size / SDRM_BitsInDWORD + 1);
+       if (Rsquare == NULL)
+       {
+               free(pbBuf);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       // Compute R and R^2 mod M
+       SDRM_BN_SHL(Rsquare, BN_One, r2Size);
+       SDRM_BN_ModRed(Mont->R, Rsquare, BN_Modulus);
+//-- 2012.08.20 - modified by yhhwang
+
+       free(pbBuf);
+       free(Rsquare);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_MONT_Init
+ * @brief      Allocate new momory for Montgomery parameter
+ *
+ * @param      dSize   [in]size of buffer of big number
+ *
+ * @return     Pointer to created structure
+ * \n          NULL if malloc failed
+ */
+SDRM_BIG_MONT *SDRM_MONT_Init(cc_u32 dSize)
+{
+       SDRM_BIG_MONT   *Mont;
+       cc_u32                  AllocSiz = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       Mont = (SDRM_BIG_MONT *)malloc(sizeof(SDRM_BIG_MONT) + AllocSiz * 3);
+       if (Mont == NULL)
+       {
+               return NULL;
+       }
+
+       Mont->ri          = 0;
+       Mont->R           = SDRM_BN_Alloc((cc_u8*)Mont + sizeof(SDRM_BIG_MONT), dSize);
+       Mont->Mod         = SDRM_BN_Alloc((cc_u8*)Mont->R + AllocSiz,              dSize);
+       Mont->Inv_Mod = SDRM_BN_Alloc((cc_u8*)Mont->Mod + AllocSiz,                dSize);
+
+       return Mont;
+}
+
+/*
+ * @fn         SDRM_MONT_Free
+ * @brief      Free allocated memory for montgomery paramter
+ *
+ * @param      Mont    [in]montgomery parameters
+ *
+ * @return     void
+ */
+void SDRM_MONT_Free(SDRM_BIG_MONT *Mont)
+{
+       if (Mont != NULL) {
+               free(Mont);
+       }
+}
+
+int SDRM_BN_num_bits_index(SDRM_BIG_NUM *BN_Src, cc_u32 bitIndex)
+{
+       cc_u32  l;
+       int j;
+
+       if (BN_Src->Length == 0)
+       {
+               return 0;
+       }
+
+       int div = bitIndex / (sizeof(cc_u32) * 8);
+       int rem = bitIndex % (sizeof(cc_u32) * 8);
+
+       l = BN_Src->pData[div];
+       j = SDRM_UINT32_num_bits_index(&l, rem);
+       return j;
+}
+
+int SDRM_UINT32_num_bits_index(cc_u32 *pdSrc, cc_u32 bitIndex)
+{
+       cc_u32  i = 0;
+       cc_u32  temp;
+
+       temp = *pdSrc;
+
+       if (!temp)
+       {
+               return 0;
+       }
+
+       while(temp)
+       {
+               if(bitIndex == i) {
+                       break;
+               }
+               temp >>= 1;
+               i++;
+       }               
+       return temp & 0x00000001;
+}
+
+
+
+/*
+ * @fn         SDRM_BN_num_bits
+ * @brief      Calc bit-length of Big Number
+ *
+ * @param      BN_Src  [in]source
+ *
+ * @return     bit-length
+ */
+int SDRM_BN_num_bits(SDRM_BIG_NUM *BN_Src)
+{
+       cc_u32  l;
+       int             i, j;
+
+       if (BN_Src->Length == 0)
+       {
+               return 0;
+       }
+
+       l = BN_Src->pData[BN_Src->Length - 1];
+       i = (BN_Src->Length-1) * SDRM_BitsInDWORD;
+
+       j = SDRM_UINT32_num_bits(&l);
+               
+       return(i + j);
+}
+
+/*
+ * @fn         SDRM_UINT32_num_bits
+ * @brief      Calc bit-length of cc_u32
+ *
+ * @param      pdSrc   [in]source
+ *
+ * @return     bit-length
+ */
+int    SDRM_UINT32_num_bits(cc_u32 *pdSrc)
+{
+       int             i = 0;
+       cc_u32  temp;
+
+       temp = *pdSrc;
+
+       if (!temp)
+       {
+               return 0;
+       }
+
+       while(temp)
+       {
+               temp >>= 1;
+               i++;
+       }               
+       
+       return i;
+}
+
+/*
+ * @fn         SDRM_INT_num_bits
+ * @brief      Calc bit-length of integer
+ *
+ * @param      Src     [in]source
+ *
+ * @return     bit-length
+ */
+int    SDRM_INT_num_bits(int Src)
+{
+       int i = 0;
+
+       if (!Src)
+       {
+               return 0;
+       }
+
+       while(Src)
+       {
+               Src >>= 1;
+               i++;
+       }               
+       
+       return i;
+}
+
+/*
+ * @fn         SDRM_BN_ModExp
+ * @brief      Big Number Modular Exponentiation
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Base         [in]base
+ * @param      BN_Exponent     [in]exponent
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_BN_ModExp(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
+{
+       SDRM_BIG_NUM    *c_, *a_, *BN_Temp;
+       SDRM_BIG_MONT   *Mont;
+       int                             i, m;
+       cc_u8                   *pbBuf;
+       cc_u32                  dSize, dAllocSize;
+
+       dSize = MAX3(BN_Base->Size, BN_Exponent->Size, BN_Modulus->Size);
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       pbBuf = (cc_u8*)malloc(dAllocSize * 3);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       c_ = SDRM_BN_Alloc(pbBuf, dSize);
+       a_ = SDRM_BN_Alloc((cc_u8*)c_ + dAllocSize, dSize);
+       BN_Temp = SDRM_BN_Alloc((cc_u8*)a_ + dAllocSize, dSize);
+
+       if (SDRM_BN_Cmp(BN_Base, BN_Modulus) >= 0)
+       {
+               SDRM_BN_ModRed(BN_Temp, BN_Base, BN_Modulus);
+       }
+       else
+       {
+               BN_Temp = BN_Base;
+       }
+
+       if (SDRM_BN_Cmp(BN_Temp, BN_Zero) == 0)
+       {
+               SDRM_BN_Copy(BN_Dst, BN_Zero);
+
+               free(pbBuf);
+               return CRYPTO_SUCCESS;
+       }
+
+       Mont = SDRM_MONT_Init(dSize);
+       SDRM_MONT_Set(Mont, BN_Modulus);
+
+       SDRM_MONT_Zn2rzn(a_, BN_Temp, Mont);
+       SDRM_MONT_Zn2rzn(c_, BN_One, Mont);
+
+       m = SDRM_BN_num_bits(BN_Exponent);
+
+       for (i = m - 1; i >= 0; i--)
+       {
+               SDRM_MONT_Mul(c_, c_, c_, Mont);
+               
+               if (SDRM_CheckBitUINT32(BN_Exponent->pData, i) == 1)
+               {
+                       SDRM_MONT_Mul(c_, c_, a_, Mont);
+               }
+       }
+
+       SDRM_MONT_Rzn2zn(BN_Dst, c_, Mont);
+
+       SDRM_MONT_Free(Mont);
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_ModExp2
+ * @brief      Big Number Modular Exponentiation2 - Karen's method
+ *
+ * @param      BN_Dst          [out]destination
+ * @param      BN_Base         [in]base
+ * @param      BN_Exponent     [in]exponent
+ * @param      BN_Modulus      [in]modular m
+ *
+ * @return     CRYPTO_SUCCESS if no error occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_BN_ModExp2(SDRM_BIG_NUM *BN_Dst, SDRM_BIG_NUM *BN_Base, SDRM_BIG_NUM *BN_Exponent, SDRM_BIG_NUM *BN_Modulus)
+{
+       int retVal;
+       SDRM_BIG_NUM *BN_Temp;
+
+       if ((BN_Dst != BN_Base) && (BN_Dst != BN_Exponent) && (BN_Dst != BN_Modulus))
+       {
+               SDRM_BN_Clr(BN_Dst);
+       }
+
+       if (SDRM_BN_Cmp(BN_Base, BN_Modulus) >= 0)
+       {
+               BN_Temp = SDRM_BN_Init(MAX3(BN_Base->Size, BN_Exponent->Size, BN_Modulus->Size));
+               if (BN_Temp == NULL)
+               {
+                       return CRYPTO_MEMORY_ALLOC_FAIL;
+               }
+
+               if (BN_Temp == BN_Base)
+               {
+                       free(BN_Temp);
+                       return CRYPTO_ERROR;
+               }
+
+               SDRM_BN_ModRed(BN_Temp, BN_Base, BN_Modulus);
+       }
+       else
+       {
+               BN_Temp = BN_Base;
+       }
+
+       if (SDRM_BN_Cmp(BN_Temp, BN_Zero) == 0)
+       {
+               SDRM_BN_Clr(BN_Dst);
+
+               if (BN_Temp != BN_Base)
+               {
+                       free(BN_Temp);
+               }
+
+               return CRYPTO_SUCCESS;
+       }
+
+       retVal = SDRM_ll_ExpMod(BN_Temp->pData, BN_Temp->Length * 4, BN_Exponent->pData, BN_Exponent->Length * 4, BN_Modulus->pData, BN_Modulus->Length * 4, BN_Dst->pData);
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               if (BN_Temp != BN_Base)
+               {
+                       free(BN_Temp);
+               }
+
+               return retVal;
+       }
+
+       BN_Dst->Length = BN_Dst->Size;
+
+       while(BN_Dst->pData[BN_Dst->Length - 1] == 0)
+       {
+               BN_Dst->Length--;
+       }
+
+       if (BN_Temp != BN_Base)
+       {
+               free(BN_Temp);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_BN_CheckRelativelyPrime
+ * @brief      get gcd of two big number
+ *
+ * @param      BN_Src1                                         [in]first element
+ * @param      BN_Src2                                         [in]second element
+ *
+ * @return     CRYPTO_ISPRIME                          if two elements are relatively prime
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR    otherwise
+ */
+int SDRM_BN_CheckRelativelyPrime(SDRM_BIG_NUM *BN_Src1, SDRM_BIG_NUM *BN_Src2)
+{
+       SDRM_BIG_NUM    *Temp, *S1, *S2;
+       cc_u8                   *pbBuf;
+       cc_u32                  dSize, dAllocSize;
+
+       dSize = MAX2(BN_Src1->Size, BN_Src2->Size);
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       if (!(pbBuf = (cc_u8*)malloc(dAllocSize * 3)))
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       S1       = SDRM_BN_Alloc(pbBuf,                                 dSize);
+       S2       = SDRM_BN_Alloc((cc_u8*)S1 + dAllocSize, dSize);
+       Temp = SDRM_BN_Alloc((cc_u8*)S2 + dAllocSize, dSize);
+
+       if (SDRM_BN_Cmp(BN_Src1, BN_Src2) >= 0)
+       {
+               SDRM_BN_Copy(S1, BN_Src1);
+               SDRM_BN_Copy(S2, BN_Src2);
+       }
+       else
+       {
+               SDRM_BN_Copy(S1, BN_Src2);
+               SDRM_BN_Copy(S2, BN_Src1);
+       }
+
+       SDRM_BN_OPTIMIZE_LENGTH(S1);
+       SDRM_BN_OPTIMIZE_LENGTH(S2);
+
+       while(S2->Length)
+       {
+               SDRM_BN_ModRed(Temp, S1, S2);
+               SDRM_BN_Copy(S1, S2);
+               SDRM_BN_Copy(S2, Temp);
+       }
+
+       if (SDRM_BN_Cmp(S1, BN_One) == 0)
+       {
+               free(pbBuf);
+
+               return CRYPTO_ISPRIME;
+       }
+       
+       free(pbBuf);
+
+       return CRYPTO_ERROR;
+}
+
+//small primes for pre-testing
+static cc_u32 miniPrimes[] = {
+       0xC8E15F2A, 0x16FA4227, 0x87B81DA9, 0xDA38C071, 0xFDB17C23, 0xFE5E796B,
+       0xC7E4CBF5, 0x7EB0F0B1, 0xB72EFC93, 0xF46CEE57, 0x80B2C2BB, 0x34A77199,
+       0x447D1BD5, 0xEA4C7C31, 0xF046D45B, 0xFF55A7BF, 0x9B287041, 0x85663BEF,
+       0x7856625B, 0
+};
+
+/*
+ * @fn         SDRM_BN_MILLER_RABIN
+ * @brief      MILLER_RABIN Test
+ *
+ * @param      n                                       [in]value to test
+ * @param      t                                       [in]security parameter
+ *
+ * @return     CRYPTO_ISPRIME                  if n is (probably) prime
+ * \n          CRYPTO_INVALID_ARGUMENT if n is composite
+ */
+int SDRM_BN_MILLER_RABIN(SDRM_BIG_NUM* n, cc_u32 t)
+{
+       SDRM_BIG_NUM    *r, *a, *y, *n1;
+       cc_u32                  i, j, tmp, srcLen, s = 1;
+       cc_u8                   *pbBuf;
+       cc_u32                  dSize, dAllocSize;
+       
+       dSize = n->Size;
+       dAllocSize = sizeof(SDRM_BIG_NUM) + dSize * SDRM_SIZE_OF_DWORD;
+
+       if (n->Length == 0)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if ((n->pData[0] & 0x01) == 0)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       for (i = 0; miniPrimes[i] != 0; i++)
+       {
+               tmp = 0;
+               for (j = n->Length - 1; j != (cc_u32)-1; j--)
+               {
+                       tmp = SDRM_DIGIT_Mod(tmp, n->pData[j], miniPrimes[i]);
+               }
+
+               if(SDRM_DIGIT_Gcd(miniPrimes[i], tmp) != 1)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+       }
+       
+       while(SDRM_CheckBitUINT32(n->pData, s) == 0) {
+               s++;
+       }
+
+       pbBuf = (cc_u8*)malloc(dAllocSize * 4);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       r  = SDRM_BN_Alloc( pbBuf,                               dSize);
+       a  = SDRM_BN_Alloc((cc_u8*)r + dAllocSize, dSize);
+       y  = SDRM_BN_Alloc((cc_u8*)a + dAllocSize, dSize);
+       n1 = SDRM_BN_Alloc((cc_u8*)y + dAllocSize, dSize);
+
+       SDRM_BN_Sub(n1, n, BN_One);
+       SDRM_BN_SHR(r, n1, s);
+
+       srcLen = SDRM_BN_num_bits(n);
+
+       for (i = 1; i <= t; i++)
+       {
+               SDRM_BN_Rand(a, srcLen);
+               a->pData[n->Length - 1] %= n->pData[n->Length - 1];
+
+               SDRM_BN_ModExp(y, a, r, n);
+               if ((SDRM_BN_Cmp(y, BN_One) == 0) || (SDRM_BN_Cmp(y, n1) == 0))
+               {
+                       continue;
+               }
+
+               for (j = 1; (j < s) && SDRM_BN_Cmp(y, n1) != 0; j++)
+               {
+                       SDRM_BN_ModMul(y, y, y, n);
+
+                       if (SDRM_BN_Cmp(y, BN_One) == 0) 
+                       {
+                               free(pbBuf);
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+               }
+
+               if (SDRM_BN_Cmp(y, n1) != 0)
+               {
+                       free(pbBuf);
+
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+
+       }
+       free(pbBuf);
+
+       return CRYPTO_ISPRIME;
+}
+
+/*
+ * @fn         int     SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
+ * @brief      Convert Hex String to Big Number
+ *
+ * @param      pbSrc   [in]source hex string
+ * @param      BN_Dst  [out]output big number
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if arrary is too small
+ */
+int    SDRM_HEX2BN(cc_u8* pbSrc, SDRM_BIG_NUM *BN_Dst)
+{
+       cc_u32 i, n, k, j;
+       cc_u8 * bufferHex = NULL;
+
+       if (!BN_Dst)
+       {
+               BN_Dst = SDRM_BN_Init(BN_Dst->Length * SDRM_SIZE_OF_DWORD * 8);
+               if(BN_Dst == NULL)
+               {
+                       return CRYPTO_MEMORY_ALLOC_FAIL;
+               }
+       }
+       if(pbSrc[0] == '-')
+       {
+               BN_Dst->sign = 1;
+               pbSrc[0] = '0';
+       }
+
+       BN_Dst->Length = 0;
+       n = strlen((const char*)pbSrc);
+       
+       BN_Dst->Length = n / SDRM_SIZE_BLOCK;
+       //normalize length
+       if( n % SDRM_SIZE_BLOCK != 0 ) {
+               BN_Dst->Length+=1;
+       }
+#if 0 //fix prevent problem by guoxing.xu 20140826. move to before 
+       if (!BN_Dst)
+       {
+               BN_Dst = SDRM_BN_Init(BN_Dst->Length * SDRM_SIZE_OF_DWORD * 8);
+       }
+#endif
+       for(i = 0; i < BN_Dst->Length ; i++)
+       {
+               BN_Dst->pData[i] = 0;
+       }
+
+       //full string: bufferHex mod Length = 0
+       bufferHex = (cc_u8 *)malloc( sizeof(cc_u8) * (BN_Dst->Length * SDRM_SIZE_BLOCK));
+
+       //init byffer by 0 
+       for(i = 0; i < BN_Dst->Length * SDRM_SIZE_BLOCK; i++)
+       {
+               bufferHex[i] = '0';
+       }
+       
+
+       k = n - 1;
+       for(i = (BN_Dst->Length * SDRM_SIZE_BLOCK) - 1; (int)k >= 0; i--, k--)
+       {
+               bufferHex[i] = pbSrc[k];
+       }
+       
+       for(i = 0; i < BN_Dst->Length; i++)
+       {
+               for(j = (BN_Dst->Length * SDRM_SIZE_BLOCK) - (i * SDRM_SIZE_BLOCK) - SDRM_SIZE_BLOCK; j < (BN_Dst->Length * SDRM_SIZE_BLOCK) - (i * SDRM_SIZE_BLOCK) ; j++)
+               {  
+                       switch(bufferHex[j])
+                       {
+                               case '0':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x0;
+                                       break;
+                               case '1':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x1;
+                                       break;
+                               case '2':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x2;
+                                       break;
+                               case '3':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x3;
+                                       break;
+                               case '4':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x4;
+                                       break;
+                               case '5':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x5;
+                                       break;
+                               case '6':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x6;
+                                       break;
+                               case '7':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x7;
+                                       break;
+                               case '8':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x8;
+                                       break;
+                               case '9':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0x9;
+                                       break;
+                               case 'a':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xa;
+                                       break;
+                               case 'A':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xa;
+                                       break;
+                               case 'b':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xb;
+                                       break;
+                               case 'B':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xb;
+                                       break;
+                               case 'c':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xc;
+                                       break;
+                               case 'C':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xc;
+                                       break;
+                               case 'd':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xd;
+                                       break;
+                               case 'D':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xd;
+                                       break;
+                               case 'e':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xe;
+                                       break;
+                               case 'E':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xe;
+                                       break;
+                               case 'f':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xf;
+                                       break;
+                               case 'F':
+                                       BN_Dst->pData[i] = BN_Dst->pData[i] << 4;
+                                       BN_Dst->pData[i] |= 0xf;
+                                       break;
+                               default:
+                                       return CRYPTO_INVALID_ARGUMENT;
+                       }
+               }
+       }
+       
+       //clear time buffer
+       free(bufferHex); 
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
+ * @brief      Convert Big Number to binary String
+ *
+ * @param      pbSrc   [in]source big number
+ * @param      BN_Dst  [out]output numberBits of uot string
+ *
+ * @return     (cc_u8 *) binary string
+ */
+cc_u8 * SDRM_BN2STRBIN(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src)
+{
+       cc_u32 i,j,k;
+       cc_u32 mask = 0x80000000;
+       cc_u32 temp, check;
+       cc_u8 *tempC, *tempR;
+       (*numberBits) = sizeof(cc_u8) * BN_Src->Length * SDRM_SIZE_OF_DWORD * 8 + 1;
+       tempC = (cc_u8*)malloc(*numberBits);
+       tempR = (cc_u8*)malloc(*numberBits);
+       tempC[(*numberBits) - 1] = '\0';
+       for(i = BN_Src->Length - 1; (int)i >= 0 ; i--)
+       {
+               temp = BN_Src->pData[i];
+               for(j = 0; j < (SDRM_SIZE_OF_DWORD * 8); j++)
+               {
+                       if((temp & mask) > 0) {
+                               tempC[(((BN_Src->Length - 1) - i) * (SDRM_SIZE_OF_DWORD * 8)) + j] = '1';
+                       }
+                       else {
+                               tempC[(((BN_Src->Length - 1) - i) * (SDRM_SIZE_OF_DWORD * 8)) + j] = '0';
+                       }
+
+                       temp = temp << 1;       
+               }
+       }
+
+       //next block for normalize length string (eg 0111 = 111)
+       check = 0; k = 0;
+       for(i = 0; i < (*numberBits); i++)
+       {
+               if(tempC[i] == '0' && check == 0) {
+                       continue;
+               }
+               else {
+                       check = 1;
+               }
+
+               tempR[k] = tempC[i];
+               k++;
+               
+       }
+       tempR[k] = '\0';
+       (*numberBits) = k - 1;
+
+       free(tempC);
+
+       return tempR;
+}
+
+/*
+ * @fn         int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t);
+ * @brief      Set word to Big Number
+ *
+ * @param      pbSrc   [in]source word
+ * @param      BN_Dst  [out]output Big Nubmer
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occuredg
+ */
+int SDRM_BN_SetWord(SDRM_BIG_NUM *BN_Dst, cc_u32 t)
+{
+       if((int)t >= 0)
+       {
+               BN_Dst->Length = 1;
+               BN_Dst->sign = 0;
+               BN_Dst->pData[0] = t;
+       }
+       else
+       {
+               BN_Dst->Length = 1;
+               BN_Dst->sign = 1;
+               BN_Dst->pData[0] = t * (-1);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src);
+ * @brief      check big number is zero
+ *
+ * @param      pbSrc   [in]source big number
+ *
+ * @return     0 - false, 1 - true
+ */
+int SDRM_BN_isZero(SDRM_BIG_NUM *BN_Src)
+{
+       return ((BN_Src)->Length == 0)?1:0;
+}
+
+/*
+ * @fn         cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src);
+ * @brief      Convert Big Number to four String
+ *
+ * @param      pbSrc   [in]source big number
+ * @param      BN_Dst  [out]output numberBits of four string
+ *
+ * @return     (cc_u8 *) four string
+ */
+cc_u8 * SDRM_BN2STRFOUR(cc_u32 *numberBits, SDRM_BIG_NUM *BN_Src)
+{
+       SDRM_BIG_NUM *d, *tempREM, *num;
+       cc_u32 i;
+       cc_u32 sLength = (2 * SDRM_SIZE_OF_DWORD) * BN_Src->Length;
+       cc_u8 * strDestTemp = (cc_u8*)malloc(sLength * 10);
+       cc_u8 * strDest;
+       cc_u8 tempChar[10];
+       (*numberBits) = 0;
+
+       d = SDRM_BN_Init(BN_Src->Size);
+    if( d == NULL)// fix prevent cid =89093 by guoxing.xu
+    {
+        return NULL;
+    }
+       tempREM = SDRM_BN_Init(BN_Src->Size);
+       num = SDRM_BN_Init(BN_Src->Size);
+    if( num == NULL)//fix prevent cid = 89093 by guoxing.xu
+    {
+        SDRM_BN_FREE(d);
+        return NULL;
+    }
+       SDRM_BN_Copy(num, BN_Src);
+       SDRM_BN_SetWord(d, 4);
+       
+       
+
+       while (!SDRM_BN_isZero(num))
+       {
+               SDRM_BN_Div(num, tempREM, num, d);      
+               //itoa(tempREM->pData[0], (char *)tempChar, 10);        
+               //sprintf((char*)tempChar, "%d", tempREM->pData[0]);
+               snprintf((char*)tempChar, sizeof(tempChar), "%d", tempREM->pData[0]);// fix prevnet 60199 by guoxing.xu
+               strDestTemp[(*numberBits)] = tempChar[0];
+               (*numberBits)++;
+
+       }
+       
+       if((*numberBits) != 0)
+       {
+               strDest = (cc_u8*)malloc((*numberBits) + 1);
+               for(i = 0; i < (*numberBits); i++) {
+                       strDest[i] = strDestTemp[((*numberBits) - 1) - i];
+               }
+               strDest[(*numberBits)] = '\0';
+       }
+       else
+       {
+               (*numberBits) = 1;
+               strDest = (cc_u8*)malloc((*numberBits) + 1);
+               strDest[0] = '0';
+               strDest[(*numberBits)] = '\0';
+       }
+
+       free(strDestTemp);
+       SDRM_BN_FREE(d);
+       SDRM_BN_FREE(tempREM);
+       SDRM_BN_FREE(num);
+
+       return strDest;
+}
+
+/*
+ * @fn         SDRM_BN_MassInit
+ * @brief      Allocate a series of big number object
+ *
+ * @param      dBufSize        [in]buffer size of each big number
+ * @param      count           [in]number BigNumbers
+ *
+ * @return     double pointer of SDRM_BIG_NUM structure
+ * \n          NULL if memory allocation is failed
+ */
+SDRM_BIG_NUM **SDRM_BN_MassInit(cc_u32 dBufSize, cc_u32 count)
+{
+       cc_u32 i;
+       cc_u32 bnsiz = sizeof(SDRM_BIG_NUM) + dBufSize * SDRM_SIZE_OF_DWORD;
+       cc_u8* ptr;
+    void * tmp;
+       
+       SDRM_BIG_NUM** BN_Buf = (SDRM_BIG_NUM**)malloc((sizeof(SDRM_BIG_NUM*) + bnsiz) * count);
+
+       if (BN_Buf == NULL)
+       {
+               return NULL;
+       }
+
+       memset(BN_Buf, 0x00, (sizeof(SDRM_BIG_NUM*) + bnsiz) * count);
+
+       ptr = (cc_u8*)BN_Buf + sizeof(SDRM_BIG_NUM*) * count;
+       for(i = 0; i < count; i++)
+       {
+           //add by guoxing.xu to avoid warning. 2/15/2014
+           tmp = ptr;
+        BN_Buf[i] = (SDRM_BIG_NUM*)tmp;
+               //BN_Buf[i] = (SDRM_BIG_NUM*)ptr;
+               BN_Buf[i]->Size = dBufSize;
+        tmp = (ptr + sizeof(SDRM_BIG_NUM));
+        BN_Buf[i]->pData =  (cc_u32*)tmp;
+               //BN_Buf[i]->pData = (cc_u32*)(ptr + sizeof(SDRM_BIG_NUM));
+               ptr += bnsiz;
+       }
+
+       return BN_Buf;
+}
+
+/*
+ * @fn         SDRM_BN_IntInit
+ * @brief      Allocate a big number object and assign an integer value
+ *
+ * @param      dSize           [in]buffer size of each big number
+ * @param      data            [in]integer value
+ *
+ * @return     double pointer of SDRM_BIG_NUM structure
+ * \n          NULL if memory allocation is failed
+ */
+SDRM_BIG_NUM *SDRM_BN_IntInit(cc_u32 dSize, cc_u32 data)
+{
+       SDRM_BIG_NUM* BN_Buf = SDRM_BN_Init(dSize);
+       if (BN_Buf == NULL)
+       {
+               return NULL;
+       }
+
+       BN_Buf->pData[0] = data;
+       BN_Buf->Length = 1;
+
+       return BN_Buf;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/base/cc_des.c b/ssflib/dep/cryptocore/source/base/cc_des.c
new file mode 100755 (executable)
index 0000000..b7834b2
--- /dev/null
@@ -0,0 +1,168 @@
+/**
+ * \file       des.c
+ * @brief      high-speed implementation of DES
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/06
+ */
+
+//////////////////////////////////////////////////////////////////////////
+// Include Header Files
+//////////////////////////////////////////////////////////////////////////
+#include "cc_des.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_DES_KeySched
+ * @brief      Expand the cipher key into the encryption key schedule
+ *
+ * @param      RoundKey                        [out]generated round key
+ * @param      UserKey                         [in]user key, 8 byte
+ * @param      RKPos                           [in]index of round key starts
+ * @param      RKStep                          [in]step for index
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_DES_KeySched(cc_u8 *RoundKey, cc_u8 *UserKey, cc_u32 RKPos, cc_u32 RKStep)
+{
+       cc_u32  round, i, s, t, t2;
+       cc_u32  roundkey[16][2];
+       cc_u32  c = 0, d = 0;
+
+       //process Permuted Choice 1
+       for (i = 0; i < 28; i++)
+       {
+               t = SDRM_DES_KS_PC1[i];
+               c |= (UserKey[t >> 3] & SDRM_DES_BitMask[t & 0x07]) ? (1 << i) : 0;
+       }
+
+       for (i = 28; i < 56; i++)
+       {
+               t = SDRM_DES_KS_PC1[i];
+               d |= (UserKey[t >> 3] & SDRM_DES_BitMask[t & 0x07]) ? (1 << (i - 28)) : 0;
+       }
+
+       //get round key
+       for (round = 0; round < SDRM_DES_NUM_OF_ROUNDS; round++)
+       {
+               //shift left operation
+               c = (c >> SDRM_DES_KS_SHIFT[round]) | (c << (28 - SDRM_DES_KS_SHIFT[round]));
+               d = (d >> SDRM_DES_KS_SHIFT[round]) | (d << (28 - SDRM_DES_KS_SHIFT[round]));
+
+               s =     SDRM_des_skb[0][((c)      ) & 0x3f] | 
+                       SDRM_des_skb[1][((c >>  6L) & 0x03) | ((c >>  7L) & 0x3c)] |
+                       SDRM_des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
+                       SDRM_des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06)  | ((c>>22L)&0x38)];
+               t =     SDRM_des_skb[4][((d)      ) & 0x3f] |
+                       SDRM_des_skb[5][((d >>  7L) & 0x03) | ((d >>  8L) & 0x3c)] |
+                       SDRM_des_skb[6][ (d >> 15L) & 0x3f] |
+                       SDRM_des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
+
+               t2 = (t << 16L) | (s & 0x0000ffffL);
+               roundkey[RKPos][0] = SDRM_rotr32(t2, 30);
+
+               t2 = ((s >> 16L) | (t & 0xffff0000L));
+               roundkey[RKPos][1] = SDRM_rotr32(t2, 26);
+
+               RKPos += RKStep;
+       }
+
+       memcpy(RoundKey, roundkey, 128);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DES_Encryption
+ * @brief      DES processing for one block
+ *
+ * @param      RoundKey                        [in]expanded round key
+ * @param      msg                                     [in]8 byte plaintext
+ * @param      out                                     [out]8 byte ciphertext
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_DES_Encryption(cc_u32 RoundKey[][2], cc_u8 *msg, cc_u8 *out)
+{
+       cc_u32  l, r, i, t, u;
+
+       r = *(cc_u32*)(void*)(msg);
+       l = *(cc_u32*)(void*)(msg + 4);
+
+       SDRM_IP(r,l);
+
+       r = SDRM_rotr32(r, 29);
+       l = SDRM_rotr32(l, 29);
+
+       for (i = 0; i < SDRM_DES_NUM_OF_ROUNDS; i++)
+       {
+               if (i & 0x01)
+               {
+                       SDRM_D_ENCRYPT(r, l);
+               }
+               else
+               {
+                       SDRM_D_ENCRYPT(l, r);
+               }
+       }
+
+       r = SDRM_rotr32(r, 3);
+       l = SDRM_rotr32(l, 3);
+
+       SDRM_INV_IP(r, l);
+
+       memcpy(out        , &l, 4);
+       memcpy(out + 4, &r, 4);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DES64_Encryption
+ * @brief      one block DES Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_DES64_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[16][2];
+
+       SDRM_DES_KeySched((cc_u8*)RoundKey, UserKey, 0, 1);
+
+       SDRM_DES_Encryption(RoundKey, plainText, cipherText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DES64_Decryption
+ * @brief      one block DES Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_DES64_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[16][2];
+
+       SDRM_DES_KeySched((cc_u8*)RoundKey, UserKey, 15, (cc_u32)-1);
+
+       SDRM_DES_Encryption(RoundKey, cipherText, plainText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/base/cc_ecc.c b/ssflib/dep/cryptocore/source/base/cc_ecc.c
new file mode 100755 (executable)
index 0000000..d8251be
--- /dev/null
@@ -0,0 +1,1280 @@
+/**
+ * \file       ecc.c
+ * @brief      ecc library based on big number
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jiyoung Moon
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/05/03
+ * Note : optimized by Jiyoung Moon & Jisoon Park, August,2006.
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_ecc.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_ECC_Init
+ * @brief      return SDRM_EC_POINT structure
+ *
+ * @return     address of allocate structure
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_EC_POINT *SDRM_ECC_Init()
+{
+       SDRM_EC_POINT   *temp;
+
+       temp = (SDRM_EC_POINT *)malloc(sizeof(SDRM_EC_POINT) + SDRM_ECC_ALLOC_SIZE * 5);
+       if (!temp)
+       {
+               return NULL;
+       }
+
+       temp->IsInfinity = 0;
+       temp->x  = SDRM_BN_Alloc((cc_u8*)temp     + sizeof(SDRM_EC_POINT), SDRM_ECC_BN_BUFSIZE);
+       temp->y  = SDRM_BN_Alloc((cc_u8*)temp->x  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       temp->z  = SDRM_BN_Alloc((cc_u8*)temp->y  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       temp->z2 = SDRM_BN_Alloc((cc_u8*)temp->z  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       temp->z3 = SDRM_BN_Alloc((cc_u8*)temp->z2 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+
+       return temp;
+}
+
+/*
+ * @fn         SDRM_CURVE_Init
+ * @brief      return SDRM_ECC_CTX structure
+ *
+ * @return     address of allocate structure
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_ECC_CTX *SDRM_CURVE_Init()
+{
+       SDRM_ECC_CTX    *temp;
+       SDRM_EC_POINT   *ptr;
+       cc_u8                   *pbBlk;
+
+       temp = (SDRM_ECC_CTX *)malloc(sizeof(SDRM_ECC_CTX) + SDRM_ECC_ALLOC_SIZE * 15 + 2 * sizeof(SDRM_EC_POINT));
+       if (!temp) {
+               return NULL;
+       }
+
+       pbBlk = (cc_u8*)temp + sizeof(SDRM_ECC_CTX);
+
+       temp->ECC_a             = SDRM_BN_Alloc(pbBlk,                                                                    SDRM_ECC_BN_BUFSIZE);
+       temp->ECC_b             = SDRM_BN_Alloc((cc_u8*)temp->ECC_a + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       temp->ECC_p             = SDRM_BN_Alloc((cc_u8*)temp->ECC_b + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       temp->ECC_n             = SDRM_BN_Alloc((cc_u8*)temp->ECC_p + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       temp->PRIV_KEY  = SDRM_BN_Alloc((cc_u8*)temp->ECC_n + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       temp->uDimension = 0;
+
+       ptr = (SDRM_EC_POINT*)(void*)((cc_u8*)temp + sizeof(SDRM_ECC_CTX) + SDRM_ECC_ALLOC_SIZE * 5);
+       ptr->IsInfinity = 0;
+       ptr->x  = SDRM_BN_Alloc((cc_u8*)ptr     + sizeof(SDRM_EC_POINT), SDRM_ECC_BN_BUFSIZE);
+       ptr->y  = SDRM_BN_Alloc((cc_u8*)ptr->x  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       ptr->z  = SDRM_BN_Alloc((cc_u8*)ptr->y  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       ptr->z2 = SDRM_BN_Alloc((cc_u8*)ptr->z  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       ptr->z3 = SDRM_BN_Alloc((cc_u8*)ptr->z2 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+
+       temp->ECC_G = ptr;
+
+       ptr = (SDRM_EC_POINT*)(void*)((cc_u8*)ptr + sizeof(SDRM_EC_POINT) + SDRM_ECC_ALLOC_SIZE * 5);
+       ptr->IsInfinity = 0;
+       ptr->x  = SDRM_BN_Alloc((cc_u8*)ptr     + sizeof(SDRM_EC_POINT), SDRM_ECC_BN_BUFSIZE);
+       ptr->y  = SDRM_BN_Alloc((cc_u8*)ptr->x  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       ptr->z  = SDRM_BN_Alloc((cc_u8*)ptr->y  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       ptr->z2 = SDRM_BN_Alloc((cc_u8*)ptr->z  + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       ptr->z3 = SDRM_BN_Alloc((cc_u8*)ptr->z2 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+
+       temp->PUBLIC_KEY = ptr;
+
+       return temp;
+}
+
+////////////////////////////////////////////////////////////////////////////
+// ECC   Լ
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_CHECK_EC_POINT_ZERO
+ * @brief      check if the point points zero
+ *
+ * @param      r                       [in]point
+ *
+ * @return     1                       if the point is pointing zero
+ * \n          0                       otherwise
+ */
+int SDRM_CHECK_EC_POINT_ZERO(SDRM_EC_POINT* r)
+{
+       if ((r->x->Length == 0) | (r->y->Length == 0))
+       {
+               //      return = 1              if input is zero
+               return 1; 
+       }
+       else
+       {
+               return 0; 
+       }
+}
+
+/*
+ * @fn         SDRM_Mont_Jm2Jc
+ * @brief      ǥȯ 1 : Modified Jacobian  =>  Chundnovsky Jacobian 
+ *                     (A->y)  <= (A->y)/2
+ *                     (A->z2) <= (A->z)^2
+ *                     (A->z3) <= (A->z)^3
+ *
+ * @param      EC_Dst                  [out]destination
+ * @param      new_a                   [in]first element
+ * @param      new_b                   [in]second element
+ * @param      Mont                    [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_Mont_Jm2Jc(SDRM_EC_POINT *EC_Dst, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont)
+{
+       if (SDRM_BN_IS_ODD(EC_Dst->y))
+       {
+               if (SDRM_BN_Add(EC_Dst->y, EC_Dst->y, Mont->Mod) != CRYPTO_SUCCESS)
+               {
+                       return CRYPTO_ERROR;
+               }
+       }
+       
+       if (SDRM_BN_SHR(EC_Dst->y, EC_Dst->y, 1) != CRYPTO_SUCCESS)
+       {
+               return CRYPTO_ERROR;
+       }
+       
+       SDRM_MONT_Mul(EC_Dst->z2, EC_Dst->z, EC_Dst->z, Mont);
+       SDRM_MONT_Mul(EC_Dst->z3, EC_Dst->z, EC_Dst->z2, Mont);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_Mont_Jc2Jm
+ * @brief      ǥȯ 2 : Chundnovsky Jacobian  =>  Modified Jacobian
+ *                     (A->y)  <= 2*(A->y)
+ *                     (A->z2) <= new_a*(A->z)^4
+ *
+ * @param      A                               [out]destination
+ * @param      new_a                   [in]first element
+ * @param      new_b                   [in]second element
+ * @param      Mont                    [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ * \n          CRYPTO_ERROR    if evaluation is failed
+ */
+int SDRM_Mont_Jc2Jm(SDRM_EC_POINT *A, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont)
+{
+       if (SDRM_BN_SHL(A->y, A->y, 1) != CRYPTO_SUCCESS)
+       {
+               return CRYPTO_ERROR;
+       }
+       
+       if (SDRM_BN_Cmp(A->y, Mont->Mod)>=0)
+       {
+               SDRM_BN_Sub(A->y, A->y, Mont->Mod);
+       }
+       
+       SDRM_MONT_Mul(A->z2, A->z, A->z, Mont);
+       SDRM_MONT_Mul(A->z2, A->z2, A->z2, Mont);
+       SDRM_MONT_Mul(A->z2, new_a, A->z2, Mont);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_CTX_EC_Add
+ * @brief      Affine Coordinate (A = B + C)
+ *
+ * @param      ctx                                                     [in]ECC context
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      EC_Src2                                         [in]second element(C)
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Add(SDRM_ECC_CTX *ctx, SDRM_EC_POINT* EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_EC_POINT *EC_Src2)
+{
+       SDRM_BIG_NUM    *t1, *t2, *t3, *lambda, *lambda_sqr; 
+       SDRM_BIG_NUM    *x3, *y3;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 7);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       if (SDRM_CHECK_EC_POINT_ZERO(EC_Src1))
+       {
+               SDRM_EC_COPY(EC_Dst, EC_Src2); 
+               free(pbBuf);
+               return CRYPTO_SUCCESS; 
+       }
+       else if (SDRM_CHECK_EC_POINT_ZERO(EC_Src2))
+       {
+               SDRM_EC_COPY(EC_Dst, EC_Src1); 
+               free(pbBuf);
+               return CRYPTO_SUCCESS; 
+       }
+
+       t1         = SDRM_BN_Alloc(pbBuf,                                                                       SDRM_ECC_BN_BUFSIZE);
+       t2         = SDRM_BN_Alloc((cc_u8*)t1            + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       t3         = SDRM_BN_Alloc((cc_u8*)t2            + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       lambda     = SDRM_BN_Alloc((cc_u8*)t3            + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       lambda_sqr = SDRM_BN_Alloc((cc_u8*)lambda        + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       x3         = SDRM_BN_Alloc((cc_u8*)lambda_sqr + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       y3         = SDRM_BN_Alloc((cc_u8*)x3            + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       if (SDRM_BN_Cmp(EC_Src1->x, EC_Src2->x) == 0)                                   /* xǥ ٸ */
+       {
+               if (SDRM_BN_Cmp(EC_Src1->y, EC_Src2->y) != 0)                           /* y ǥ ٸٸ */
+               {       // (B = -C)
+                       SDRM_EC_SET_ZERO(EC_Dst);
+                       free(pbBuf);
+
+                       return CRYPTO_SUCCESS;
+               }
+               else                                                                                                            /* y ǥ ٸ */
+               {       // (B = C)
+                       SDRM_BN_ModAdd(t1, EC_Src1->y, EC_Src1->y, ctx->ECC_p); /* t1 = 2 * y1 */
+                       SDRM_BN_ModInv(t1, t1, ctx->ECC_p);                                             /* t1 = 1/(2 * y1) */
+
+                       SDRM_BN_ModMul(t2, EC_Src1->x, EC_Src1->x, ctx->ECC_p);         /* t2 = x1^2 */
+                       SDRM_BN_ModAdd(t3, t2, t2, ctx->ECC_p);                                 /* t3 = t2 + t2 */                      
+                       SDRM_BN_ModAdd(t3, t3, t2, ctx->ECC_p);                                 /* t2 = t3 + t2 = 3 * x1^2*/                    
+                       SDRM_BN_ModAdd(t3, t3, ctx->ECC_a, ctx->ECC_p);                 /* t3 = 3 * x1^2 + a */
+
+                       SDRM_BN_ModMul(lambda, t3, t1, ctx->ECC_p);                             /* lambda = (3 * x1^2 + a) / (2 * y1) */
+               }
+       }
+       else /* x ǥ ٸٸ */
+       {
+               SDRM_BN_ModSub(t1, EC_Src2->x, EC_Src1->x, ctx->ECC_p);         /* t1 = x2 - x1 */
+               SDRM_BN_ModSub(t2, EC_Src2->y, EC_Src1->y, ctx->ECC_p);         /* t2 = y2 - y1 */
+
+               SDRM_BN_ModInv(t1, t1, ctx->ECC_p);                                                     /* t1 = t1^(-1) = 1/(x2-x1) */
+               SDRM_BN_ModMul(lambda, t1, t2, ctx->ECC_p);                                     /* lambda = (y2-y1)/(x2-x1) */
+       }
+
+       SDRM_BN_ModMul(lambda_sqr, lambda, lambda, ctx->ECC_p);                 /* lambda^2 */
+       SDRM_BN_ModSub(t1, lambda_sqr, EC_Src1->x, ctx->ECC_p);                 /* x3 = lambda^2 - x1 */
+       SDRM_BN_ModSub(x3, t1, EC_Src2->x, ctx->ECC_p);                                 /* x3 = lambda^2 - x1 - x2 */
+
+       SDRM_BN_ModSub(t1, EC_Src1->x, x3, ctx->ECC_p);                                 /* t1 = x1 - x3 */
+       SDRM_BN_ModMul(t2, t1, lambda, ctx->ECC_p);                                             /* t2 = (x1 - x3) * lambda */
+       SDRM_BN_ModSub(y3, t2, EC_Src1->y, ctx->ECC_p);                                 /* y3 = (x1 - x3) * lambda - y1 */
+
+       SDRM_BN_Copy(EC_Dst->x, x3); 
+       SDRM_BN_Copy(EC_Dst->y, y3); 
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS; 
+}
+
+/*
+ * @fn         SDRM_CTX_EC_Add_Jc
+ * @brief      Chundnovsky Jacobian coordinate
+ *                     using montgomery (A = B + C)
+ *
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      EC_Src2                                         [in]second element(C)
+ * @param      new_a                                           [in]ECC_A's montgomery value
+ * @param      new_b                                           [in]ECC_B's montgomery value
+ * @param      Mont                                            [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Add_Jc(SDRM_EC_POINT *EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_EC_POINT *EC_Src2, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont)
+{
+       SDRM_BIG_NUM    *u1, *u2, *s1, *s2, *h, *r, *tmp1, *tmp2;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 8);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+       
+       if (EC_Src1->IsInfinity || SDRM_CHECK_EC_POINT_ZERO(EC_Src1))
+       {
+               SDRM_EC_COPY(EC_Dst, EC_Src2); 
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS; 
+       }
+       else if (EC_Src2->IsInfinity || SDRM_CHECK_EC_POINT_ZERO(EC_Src2))
+       {
+               SDRM_EC_COPY(EC_Dst, EC_Src1); 
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS; 
+       }
+
+       u1   = SDRM_BN_Alloc(pbBuf                                                        , SDRM_ECC_BN_BUFSIZE);
+       u2   = SDRM_BN_Alloc((cc_u8*)u1 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       s1   = SDRM_BN_Alloc((cc_u8*)u2 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       s2   = SDRM_BN_Alloc((cc_u8*)s1 + SDRM_ECC_ALLOC_SIZE,   SDRM_ECC_BN_BUFSIZE);
+       h    = SDRM_BN_Alloc((cc_u8*)s2  + SDRM_ECC_ALLOC_SIZE,  SDRM_ECC_BN_BUFSIZE);
+       r    = SDRM_BN_Alloc((cc_u8*)h + SDRM_ECC_ALLOC_SIZE,    SDRM_ECC_BN_BUFSIZE);
+       tmp1 = SDRM_BN_Alloc((cc_u8*)r + SDRM_ECC_ALLOC_SIZE,    SDRM_ECC_BN_BUFSIZE);
+       tmp2 = SDRM_BN_Alloc((cc_u8*)tmp1 + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       // u1
+       SDRM_MONT_Mul(u1, EC_Src1->x, EC_Src2->z2, Mont);
+       // u2
+       SDRM_MONT_Mul(u2, EC_Src2->x, EC_Src1->z2, Mont);
+       // s1
+       SDRM_MONT_Mul(s1, EC_Src1->y, EC_Src2->z3, Mont);
+       // s2
+       SDRM_MONT_Mul(s2, EC_Src2->y, EC_Src1->z3, Mont);
+
+       SDRM_BN_Sub(h, u2, u1);
+       if (h->sign)
+       {
+               SDRM_BN_Add(h, h, Mont->Mod);
+       }
+
+       // r
+       SDRM_BN_Sub(r, s2, s1);
+       if (r->sign)
+       {
+               SDRM_BN_Add(r, r, Mont->Mod);
+       }
+
+       // exception cases check
+       if (h->Length == 0)
+       {
+               if (r->Length == 0)
+               {
+                       // If (h == 0) & (r == 0), CTX_EC_Double_Jc 
+                       // because B, C are same point.
+                       free(pbBuf);
+
+                       return SDRM_CTX_EC_Double_Jc(EC_Dst, EC_Src1, new_a, new_b, Mont);
+               }
+               else
+               {
+                       // If (h == 0) & (r != 0), A = Infinity point
+                       EC_Dst->IsInfinity = 1;
+                       free(pbBuf);
+
+                       return CRYPTO_INFINITY_INPUT;
+               }
+       }
+
+       // EC_Dst->x
+       SDRM_MONT_Mul(EC_Dst->x, r, r, Mont);
+       SDRM_MONT_Mul(EC_Dst->y, h, h, Mont);                           // A->y : h^2, temp
+       SDRM_MONT_Mul(tmp1, EC_Dst->y, h, Mont);                        // tmp1 : h^3, temp
+       SDRM_MONT_Mul(EC_Dst->y, u1, EC_Dst->y, Mont);          // A->y : u1*h^2
+
+       SDRM_BN_SHL(tmp2, EC_Dst->y, 1);
+       if (SDRM_BN_Cmp(tmp2, Mont->Mod) >= 0)
+       {
+               SDRM_BN_Sub(tmp2, tmp2, Mont->Mod);
+       }
+
+       SDRM_BN_ModSub(EC_Dst->x, EC_Dst->x, tmp2, Mont->Mod);
+       SDRM_BN_ModSub(EC_Dst->x, EC_Dst->x, tmp1, Mont->Mod);
+
+       // EC_Dst->y
+       SDRM_BN_ModSub(EC_Dst->y, EC_Dst->y, EC_Dst->x, Mont->Mod);
+       SDRM_MONT_Mul(EC_Dst->y, r, EC_Dst->y, Mont);
+       SDRM_MONT_Mul(tmp1, s1, tmp1, Mont);
+       SDRM_BN_ModSub(EC_Dst->y, EC_Dst->y, tmp1, Mont->Mod);
+
+       // EC_Dst->z
+       SDRM_MONT_Mul(EC_Dst->z, EC_Src1->z, EC_Src2->z, Mont);
+       SDRM_MONT_Mul(EC_Dst->z, EC_Dst->z, h, Mont);
+
+       // ȿ  Ʒ -> ʿ  ܺο 
+#if 0
+       // EC_Dst->z2
+       SDRM_MONT_Mul(EC_Dst->z2, EC_Dst->z, EC_Dst->z, Mont);
+       // EC_Dst->z3
+       SDRM_MONT_Mul(EC_Dst->z3, EC_Dst->z, EC_Dst->z2, Mont);
+#endif
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CTX_EC_Double_Jc
+ * @brief      Chundnovsky Jacobian coordinate
+ *                     montgomery (A = 2B)
+ *
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      new_a                                           [in]ECC_A's montgomery value
+ * @param      new_b                                           [in]ECC_B's montgomery value
+ * @param      Mont                                            [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Double_Jc(SDRM_EC_POINT *EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont)
+{
+       SDRM_BIG_NUM    *s, *k, *tmp1, *tmp2;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 4);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       // If B = infinite point || (B->y) = 0, A = infinite point.
+       if (EC_Src1->IsInfinity || SDRM_CHECK_EC_POINT_ZERO(EC_Src1))
+       {
+               EC_Dst->IsInfinity = 1; 
+               free(pbBuf);
+               return CRYPTO_SUCCESS; 
+       }
+
+       s    = SDRM_BN_Alloc(pbBuf                                                        , SDRM_ECC_BN_BUFSIZE);
+       k    = SDRM_BN_Alloc((cc_u8*)s + SDRM_ECC_ALLOC_SIZE,    SDRM_ECC_BN_BUFSIZE);
+       tmp1 = SDRM_BN_Alloc((cc_u8*)k + SDRM_ECC_ALLOC_SIZE,    SDRM_ECC_BN_BUFSIZE);
+       tmp2 = SDRM_BN_Alloc((cc_u8*)tmp1 + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       
+       // s
+       SDRM_MONT_Mul(s, EC_Src1->y, EC_Src1->y, Mont);                 // s = (B->y)^2
+       SDRM_MONT_Mul(tmp1, s, s, Mont);                                                        // tmp1 = (B->y)^4
+       SDRM_MONT_Mul(s, EC_Src1->x, s, Mont);
+       SDRM_BN_SHL(s, s, 2);
+       SDRM_BN_ModRed(s, s, Mont->Mod);
+
+       // k
+       SDRM_MONT_Mul(k, EC_Src1->x, EC_Src1->x, Mont);
+       SDRM_BN_SHL(tmp2, k, 1);
+       SDRM_BN_ModAdd(tmp2, tmp2, k, Mont->Mod);
+       SDRM_MONT_Mul(k, EC_Src1->z, EC_Src1->z3, Mont);
+       SDRM_MONT_Mul(k, new_a, k, Mont);
+       SDRM_BN_ModAdd(k, tmp2, k, Mont->Mod);
+
+       // t & EC_Dst->x
+       SDRM_BN_SHL(tmp2, s, 1);
+
+       if (SDRM_BN_Cmp(tmp2, Mont->Mod)>=0)
+       {
+               SDRM_BN_Sub(tmp2, tmp2, Mont->Mod);
+       }
+
+       SDRM_MONT_Mul(EC_Dst->x, k, k, Mont);
+       SDRM_BN_ModSub(EC_Dst->x, EC_Dst->x, tmp2, Mont->Mod);
+
+       // EC_Dst->z
+       SDRM_MONT_Mul(EC_Dst->z, EC_Src1->y, EC_Src1->z, Mont);
+       SDRM_BN_SHL(EC_Dst->z, EC_Dst->z, 1);
+
+       if (SDRM_BN_Cmp(EC_Dst->z, Mont->Mod)>=0)
+       {
+               SDRM_BN_Sub(EC_Dst->z, EC_Dst->z, Mont->Mod);
+       }
+
+       // EC_Dst->y
+       SDRM_BN_SHL(EC_Dst->y, tmp1, 3);
+       while(SDRM_BN_Cmp(EC_Dst->y, Mont->Mod) >= 0)
+       {
+               SDRM_BN_Sub(EC_Dst->y, EC_Dst->y, Mont->Mod);
+       }
+
+       SDRM_BN_ModSub(tmp1, s, EC_Dst->x, Mont->Mod);                  // tmp1 = s-t (s ٲ)
+       SDRM_MONT_Mul(tmp1, k, tmp1, Mont);                                             // k(s-t)
+       SDRM_BN_ModSub(EC_Dst->y, tmp1, EC_Dst->y, Mont->Mod);
+       if (EC_Dst->y->sign)
+       {
+               SDRM_BN_Add(EC_Dst->y, EC_Dst->y, Mont->Mod);
+       }
+
+       // EC_Dst->z2
+       SDRM_MONT_Mul(EC_Dst->z2, EC_Dst->z, EC_Dst->z, Mont);
+       
+       // EC_Dst->z3
+       SDRM_MONT_Mul(EC_Dst->z3, EC_Dst->z, EC_Dst->z2, Mont);
+
+       // Memory Free
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_CTX_EC_Double_Jm
+ * @brief      Modified Jacobian coordinate
+ *                     montgomery (A = 2B)
+ *
+ * @param      EC_Dst                                          [out]destination(A)
+ * @param      EC_Src1                                         [in]first element(B)
+ * @param      new_a                                           [in]ECC_A's montgomery value
+ * @param      new_b                                           [in]ECC_B's montgomery value
+ * @param      Mont                                            [in]montgomery context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_ERROR                            if evaluation is failed
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CTX_EC_Double_Jm(SDRM_EC_POINT *EC_Dst, SDRM_EC_POINT *EC_Src1, SDRM_BIG_NUM *new_a, SDRM_BIG_NUM *new_b, SDRM_BIG_MONT *Mont)
+{
+       SDRM_BIG_NUM    *a, *b, *c, *tmp1;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 4);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       // If B is the infinite point or (B->y) is zero, A is the infinite point.
+       if (EC_Src1->IsInfinity || SDRM_CHECK_EC_POINT_ZERO(EC_Src1))
+       {
+               EC_Dst->IsInfinity = 1; 
+               free(pbBuf);
+
+               return CRYPTO_SUCCESS; 
+       }
+
+       a    = SDRM_BN_Alloc(pbBuf, SDRM_ECC_BN_BUFSIZE);
+       b    = SDRM_BN_Alloc((cc_u8*)a + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       c    = SDRM_BN_Alloc((cc_u8*)b + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       tmp1 = SDRM_BN_Alloc((cc_u8*)c + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       // a
+       SDRM_MONT_Mul(a, EC_Src1->x, EC_Src1->x, Mont);
+       SDRM_BN_SHL(tmp1, a, 1);
+       SDRM_BN_Add(a, tmp1, a);
+       SDRM_BN_Add(a, a, EC_Src1->z2);
+       while(SDRM_BN_Cmp(a, Mont->Mod) >= 0)
+       {
+               SDRM_BN_Sub(a, a, Mont->Mod);
+       }
+
+       // b & c
+       SDRM_MONT_Mul(b, EC_Src1->y, EC_Src1->y, Mont);         // b = (y1)^2
+       SDRM_MONT_Mul(c, b, b, Mont);                                                   // c = (y1)^4
+       SDRM_MONT_Mul(b, EC_Src1->x, b, Mont);
+       SDRM_BN_SHL(b, b, 1);
+       if (SDRM_BN_Cmp(b, Mont->Mod)>=0)
+       {
+               SDRM_BN_Sub(b, b, Mont->Mod);
+       }
+
+       // EC_Dst->x
+       SDRM_MONT_Mul(EC_Dst->x, a, a, Mont);
+       SDRM_BN_ModSub(EC_Dst->x, EC_Dst->x, b, Mont->Mod);
+
+       // EC_Dst->z
+       SDRM_MONT_Mul(EC_Dst->z, EC_Src1->y, EC_Src1->z, Mont);
+
+       // EC_Dst->y
+       SDRM_BN_SHL(EC_Dst->y, EC_Dst->x, 1);
+
+       if (SDRM_BN_Cmp(EC_Dst->y, Mont->Mod)>=0)
+       {
+               SDRM_BN_Sub(EC_Dst->y, EC_Dst->y, Mont->Mod);
+       }
+
+       SDRM_BN_Sub(EC_Dst->y, b, EC_Dst->y);
+       
+       if (EC_Dst->y->sign)
+       {
+               SDRM_BN_Add(EC_Dst->y, EC_Dst->y, Mont->Mod);
+       }
+
+       SDRM_MONT_Mul(EC_Dst->y, a, EC_Dst->y, Mont);
+       SDRM_BN_ModSub(EC_Dst->y, EC_Dst->y, c, Mont->Mod);
+
+       // EC_Dst->z2
+       SDRM_MONT_Mul(EC_Dst->z2, c, EC_Dst->z2, Mont);
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CTX_EC_Chain
+ * @brief      Chain Լ
+ *                     signed wondow method    :       size of window = 4
+ *                     chain for addition/subtraction of k Using sliding window method
+ *
+ * @param      chain                                           [out]destination
+ * @param      L_Src                                           [in]byte-length of chain
+ * @param      Len_Src                                         [in]number of doubling in chain
+ * @param      k                                                       [in]source
+ * @param      window_size                                     [in]size of window
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT         if given value is incorrect
+ */
+int SDRM_CTX_EC_Chain(signed char *chain, cc_u32 *L_Src, cc_u32 *Len_Src, SDRM_BIG_NUM *k, int window_size)
+{
+       int             i, j = 0, AddorSub, last = 0, doublings = 0;
+       int             bits_k = 0, subtract=0, pos = 0, temp_1 = 0;    
+       cc_u32  temp = 0;
+       cc_u32  numDoubling = 0;                                        // number of doubling(= lshift)
+
+       // k ȿ check
+       if (k->sign)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       bits_k=(SDRM_BN_num_bits(k)-1);
+
+       // sliding window method ('06)
+       while(bits_k>=0)
+       {
+               if ((bits_k + 1) < window_size) {
+                       window_size = bits_k + 1;
+               }
+
+               if ((subtract == 0) || (subtract == 10))
+               {
+                       AddorSub = 0;
+               }
+               else
+               {
+                       AddorSub = 1;
+               }
+
+               for(i = bits_k; i >= bits_k - window_size + 1; i--)
+               {
+                       temp <<= 1;
+                       temp += AddorSub ^ SDRM_CheckBitUINT32(k->pData, i);
+               }
+
+               bits_k -= window_size;
+               
+               if ((SDRM_CheckBitUINT32(k->pData, bits_k) == (cc_u32)1 - AddorSub) && (bits_k >= 0))
+               {
+                       temp++;
+                       AddorSub = 1 - AddorSub;
+               }
+
+               if ((bits_k == -1) && (AddorSub == 1)) {
+                       temp++;
+               }
+
+               if (bits_k>=0)
+               {
+                       if (SDRM_CheckBitUINT32(k->pData, bits_k)==1)
+                       {
+                               if ((subtract == 0) || (subtract == 10))
+                               {
+                                       subtract = 1;
+                               }
+                               else
+                               {
+                                       subtract = 11;
+                               }
+
+                               for(temp_1 = 0 ; SDRM_CheckBitUINT32(k->pData, bits_k)==1; bits_k--)
+                               {
+                                       if (bits_k >=0)
+                                       {
+                                               temp_1++;
+                                       }
+                               }
+                       }
+                       else
+                       {
+                               if ((subtract == 0) || (subtract == 10))
+                               {
+                                       subtract = 0;
+                               }
+                               else
+                               {
+                                       subtract = 10;
+                               }
+
+                               for(temp_1 = 0 ; SDRM_CheckBitUINT32(k->pData, bits_k)==0; bits_k--)
+                               {
+                                       if (bits_k >=0)
+                                       {
+                                               temp_1++;
+                                       }
+                               }
+                       }
+
+                       if (bits_k < 0)
+                       {
+                               last = 1;
+                       }
+               }
+               else
+               {
+                       if ((subtract == 0) || (subtract == 10))
+                       {
+                               subtract = 0;
+                       }
+                       else
+                       {
+                               subtract = 10;
+                       }
+               }
+               
+               j = temp >> window_size;
+
+               if (temp != 0)
+               {
+                       for(doublings = 0; !(temp&0x1); doublings++)
+                       {
+                               temp >>= 1;
+                       }
+                       doublings += temp_1;
+               }
+               else
+               {
+                       doublings = temp_1;
+               }
+
+               if (pos > 0)
+               {
+                       for(i = temp ; i > j ; i>>=1)
+                       {
+                               chain[++pos] = 0;                               
+                               numDoubling++;                  
+                       }
+               }
+
+               if ((subtract==10) || (subtract == 11))
+               {
+                       chain[++pos] = (char)((~temp + 1) & 0xff);
+               }
+               else
+               {
+                       chain[++pos] = (char)((temp) & 0xff);
+               }
+
+               for( ; doublings > 0; doublings--)
+               {
+                       chain[++pos] = 0;                               
+                       numDoubling++;
+               }
+
+               if (last == 1)
+               {
+                       if (AddorSub == 1) 
+                       {
+                               chain[++pos] = -1;
+                       }
+               }
+                               
+               temp = 0;
+               temp_1 = 0;
+       }
+
+       *L_Src = pos;
+       *Len_Src = numDoubling;
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CTX_EC_kP
+ * @brief      get EC_Dst = kP by Montgomery Method
+ *
+ * @param      ctx                                                     [in]ecc context
+ * @param      EC_Dst                                          [out]destination
+ * @param      EC_Src                                          [in]first element(P)
+ * @param      k                                                       [in]second element(k)
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT         if the arguemnt represents a minus value
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_INFINITY_INPUT           if the argument is a infinity value
+ */
+int SDRM_CTX_EC_kP(SDRM_ECC_CTX *ctx, SDRM_EC_POINT* EC_Dst, SDRM_EC_POINT *EC_Src, SDRM_BIG_NUM *k)
+{
+       int                             res, i;
+       int                             window_size = 4;                                        // window size
+       int                             w_p = (1 << (window_size-1)) + 1;       // pre-computation number
+//     int                             add = 0, subtract = 0;                          // add : num_(addition + subtract)
+                                                                                                               // subtract :  0 - before = 0 & after = 0
+                                                                                                               //                        10 - before = 1 & after = 0   
+                                                                                                               //                         1 - before = 0 & after = 1   
+                                                                                                               //                        11 - before = 1 & after = 1   
+                                                                                                               //      => 0 : no subtract / 1 : subtract
+       SDRM_EC_POINT   *Pw[9] = {0};                                           // number of precomputation data : 9 = w_p = 2^(window_size-1) + 1
+       SDRM_BIG_MONT   *Mont;
+       SDRM_BIG_NUM    *new_a, *new_b;
+       SDRM_BIG_NUM    *t1, *t2;               
+       signed char             chain[2 * SDRM_MAX_DIMENSION_ECC];              // DIMENSION_ECC :  ecdsa.h define
+       cc_u32                  length;                                                         // addition & subtrction chain length of k1 & k2
+       cc_u32                  lenD;                                                           // number of doubling of addition & subtrction chain of k1 & k2 
+
+       cc_u8                   *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 4);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+       
+       // k P ȿ check
+       if (k->sign)
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (EC_Src->x->sign|EC_Src->y->sign)
+       {
+               free(pbBuf);    
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       Mont = SDRM_MONT_Init(ctx->ECC_p->Size);
+       if (Mont == NULL) 
+       {
+               free(pbBuf);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_MONT_Set(Mont, ctx->ECC_p);
+
+       new_a = SDRM_BN_Alloc(pbBuf,                                                      SDRM_ECC_BN_BUFSIZE);
+       new_b = SDRM_BN_Alloc((cc_u8*)new_a + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       t1    = SDRM_BN_Alloc((cc_u8*)new_b + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       t2    = SDRM_BN_Alloc((cc_u8*)t1           + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       if (SDRM_MONT_Zn2rzn(new_a, ctx->ECC_a, Mont) != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+               return CRYPTO_ERROR;
+       }
+
+       if (SDRM_MONT_Zn2rzn(new_b, ctx->ECC_b, Mont) != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+               return CRYPTO_ERROR;
+       }
+
+
+       //chain 
+       res = SDRM_CTX_EC_Chain(chain, &length, &lenD, k, window_size);
+       if (res != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+
+               return CRYPTO_ERROR;
+       }
+       
+       // pre-computation Data         :               Chunvosky algorithm
+               // Pw[1] = EC_Src
+               // Pw[2] = 3 * EC_Src
+               // Pw[3] = 5 * EC_Src
+               // Pw[4] = 7 * EC_Src
+               // ..................
+       for(i = 0; i < 9; i++)
+       {
+               Pw[i] = SDRM_ECC_Init();
+               if (Pw[i] == NULL)
+               {
+                       free(pbBuf);
+                       SDRM_MONT_Free(Mont);
+                       while (i > 0)
+                       {
+                               free(Pw[--i]);
+                       }
+                       return CRYPTO_MEMORY_ALLOC_FAIL;
+               }
+       }
+
+       SDRM_EC_COPY(Pw[1], EC_Src);
+
+       SDRM_MONT_Zn2rzn(Pw[1]->x, Pw[1]->x, Mont);
+       SDRM_MONT_Zn2rzn(Pw[1]->y, Pw[1]->y, Mont);
+       SDRM_MONT_Zn2rzn(Pw[1]->z, BN_One, Mont);
+
+       SDRM_BN_Copy(Pw[1]->z2, Pw[1]->z);
+       SDRM_BN_Copy(Pw[1]->z3, Pw[1]->z);
+
+       SDRM_EC_SET_ZERO(Pw[0]);
+       SDRM_CTX_EC_Double_Jc(Pw[0], Pw[1], new_a, new_b, Mont);
+
+       for (i = 2; i < w_p; i++)
+       {
+               SDRM_EC_SET_ZERO(Pw[i]);
+               SDRM_CTX_EC_Add_Jc(Pw[i], Pw[i-1], Pw[0], new_a, new_b, Mont);
+
+               SDRM_MONT_Mul(Pw[i]->z2, Pw[i]->z, Pw[i]->z, Mont);
+               SDRM_MONT_Mul(Pw[i]->z3, Pw[i]->z2, Pw[i]->z, Mont);
+       }
+
+       EC_Dst->IsInfinity = 1;
+
+       for(i = 0; i != (int)length; i++)
+       {
+               if (chain[i + 1]==0)
+               {
+                       // EC_Dst = 2 * EC_Dst
+                       SDRM_CTX_EC_Double_Jm(EC_Dst, EC_Dst, new_a, new_b, Mont);
+                       lenD--;
+               }
+               else
+               {
+                       SDRM_Mont_Jm2Jc(EC_Dst, new_a, new_b, Mont);
+                       if (chain[i + 1]>0)
+                       {
+                               // EC_Dst = EC_Dst + Pw[(chain[i + 1]+1)/2]
+                               SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[(chain[i + 1]+1)/2], new_a, new_b, Mont);
+                       }
+                       else
+                       {
+                               // EC_Dst = EC_Dst - Pw[(chain[i + 1]]+1)/2]
+                               SDRM_EC_COPY(Pw[0], Pw[(-chain[i + 1]+1)/2]);
+                               SDRM_BN_Sub(Pw[0]->y, ctx->ECC_p, Pw[0]->y);
+                               SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[0], new_a, new_b, Mont);  
+                       }
+                       SDRM_Mont_Jc2Jm(EC_Dst, new_a, new_b, Mont);
+               }
+       }
+       
+       // montgomery reduction of EC_Dst
+       SDRM_MONT_Rzn2zn(EC_Dst->x, EC_Dst->x, Mont);
+       SDRM_MONT_Rzn2zn(EC_Dst->y, EC_Dst->y, Mont);
+       SDRM_MONT_Rzn2zn(EC_Dst->z, EC_Dst->z, Mont);
+       
+       if (EC_Dst->z->Length == 0)
+       {
+               for(i = 0; i < 9; i++)
+               {
+                       free(Pw[i]);
+               }
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+
+               EC_Dst->IsInfinity = 1;
+
+               return CRYPTO_INFINITY_INPUT;
+       }
+       // Convert coordinate :  "Modified Jacobian" => "Affine"
+       //  (EC_Dst->x) <= (EC_Dst->x) * { ((EC_Dst->z)^2)^-1 }
+       //  (EC_Dst->y) <= (EC_Dst->y) * { (2*((EC_Dst->z)^3))^-1 }
+
+       SDRM_BN_ModMul(t1, EC_Dst->z, EC_Dst->z, ctx->ECC_p);
+       SDRM_BN_ModInv(t2, t1, ctx->ECC_p);
+       SDRM_BN_ModMul(EC_Dst->x, EC_Dst->x, t2, ctx->ECC_p);
+
+       SDRM_BN_ModMul(t1, t1, EC_Dst->z, ctx->ECC_p);
+       SDRM_BN_SHL(t1, t1, 1);
+       SDRM_BN_ModInv(t2, t1, ctx->ECC_p);
+       SDRM_BN_ModMul(EC_Dst->y, EC_Dst->y, t2, ctx->ECC_p);
+       
+       // Memory Free
+       for(i = 0; i < 9; i++)
+       {
+               free(Pw[i]);
+       }
+
+       free(pbBuf);
+       SDRM_MONT_Free(Mont);
+
+       return CRYPTO_SUCCESS; 
+}
+
+/*
+ * @fn         SDRM_CTX_EC_2kP
+ * @brief      get EC_Dst = k1*C1 + k2*C2
+ *
+ * @param      ctx                                                     [in]ecc context
+ * @param      EC_Dst                                          [out]destination
+ * @param      k1                                                      [in]first element(k1)
+ * @param      EC_Src1                                         [in]second element(C1)
+ * @param      k2                                                      [in]third element(k2)
+ * @param      EC_Src2                                         [in]fourth element(C2)
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT         if the arguemnt represents a minus value
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_INFINITY_INPUT           if the argument is a infinity value
+ */
+int SDRM_CTX_EC_2kP(SDRM_ECC_CTX *ctx, SDRM_EC_POINT *EC_Dst, SDRM_BIG_NUM *k1, SDRM_EC_POINT *EC_Src1, SDRM_BIG_NUM *k2, SDRM_EC_POINT *EC_Src2)
+{
+       signed char             chain[2][2 * SDRM_MAX_DIMENSION_ECC];           // addition/subtrction chain of k1  k2
+       cc_u32                  length[2];                                                              // addition/subtrction chain length of k1  k2
+       cc_u32                  lenD[2];                                                                // # of doubling of addition/subtrction chain of k1  k2 
+       cc_u32                  idx[2];
+       int                             window_size = 4;                                                // window size
+       int                             w2 = (1 << (window_size - 1)) + 1;              // 2^(window_size-1)+1 : the precomputation point number
+       int                             i, j, res;
+       SDRM_EC_POINT   *Pw[2][9];                                                              // precomputation data
+       SDRM_BIG_MONT   *Mont=NULL;
+       SDRM_BIG_NUM    *new_a, *new_b;
+       SDRM_BIG_NUM    *t1, *t2;                                                               // Used in coordinate change from "Modified Jacobian" to "Affine"
+
+       cc_u8 *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 4);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       // k1 & k2 & C1 & C2 ȿ check
+       if (k1->sign | k2->sign)
+       {
+               free(pbBuf);
+
+               return CRYPTO_ERROR;
+       }
+
+       if (EC_Src1->x->sign | EC_Src1->y->sign | EC_Src2->x->sign | EC_Src2->y->sign)
+       {
+               free(pbBuf);
+
+               return CRYPTO_ERROR;
+       }
+
+       Mont = SDRM_MONT_Init(ctx->ECC_p->Size);
+       SDRM_MONT_Set(Mont, ctx->ECC_p);
+
+       new_a = SDRM_BN_Alloc(pbBuf,                                                      SDRM_ECC_BN_BUFSIZE);
+       new_b = SDRM_BN_Alloc((cc_u8*)new_a + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       t1    = SDRM_BN_Alloc((cc_u8*)new_b + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       t2    = SDRM_BN_Alloc((cc_u8*)t1           + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       
+       if (SDRM_MONT_Zn2rzn(new_a, ctx->ECC_a, Mont) != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+               return CRYPTO_ERROR;
+       }
+
+       if (SDRM_MONT_Zn2rzn(new_b, ctx->ECC_b, Mont) != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+               return CRYPTO_ERROR;
+       }
+
+       // chain 
+       res = SDRM_CTX_EC_Chain(chain[0], &length[0], &lenD[0], k1, window_size);
+       if (res != CRYPTO_SUCCESS)
+       {
+               free(pbBuf); 
+               SDRM_MONT_Free(Mont);
+               return res;
+       }
+
+       res = SDRM_CTX_EC_Chain(chain[1], &length[1], &lenD[1], k2, window_size);
+       if (res != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+               return res;
+       }
+
+       // Precomputation data
+       for(i = 0; i < 2; i++)
+       {
+//             Pw[i] = (SDRM_EC_POINT **)malloc(sizeof(SDRM_EC_POINT *) * w2);
+//             if (!Pw[i]) return CRYPTO_MEMORY_ALLOC_FAIL;
+               for(j = 0; j < 9; j++)
+               {
+                       Pw[i][j] =  SDRM_ECC_Init();
+               }
+       }
+       
+       SDRM_EC_COPY(Pw[0][1], EC_Src1);
+       SDRM_EC_COPY(Pw[1][1], EC_Src2);
+
+       for (i=0;i<2;i++)
+       {
+               SDRM_MONT_Zn2rzn(Pw[i][1]->x, Pw[i][1]->x, Mont);
+               SDRM_MONT_Zn2rzn(Pw[i][1]->y, Pw[i][1]->y, Mont);
+               SDRM_MONT_Zn2rzn(Pw[i][1]->z, BN_One, Mont);
+               SDRM_BN_Copy(Pw[i][1]->z2, Pw[i][1]->z);
+               SDRM_BN_Copy(Pw[i][1]->z3, Pw[i][1]->z);
+               SDRM_CTX_EC_Double_Jc(Pw[i][0], Pw[i][1], new_a, new_b, Mont);
+               
+               for (j=2;j<w2;j++)
+               {
+                       SDRM_CTX_EC_Add_Jc(Pw[i][j], Pw[i][j-1], Pw[i][0], new_a, new_b, Mont);
+                       SDRM_MONT_Mul(Pw[i][j]->z2, Pw[i][j]->z, Pw[i][j]->z, Mont);
+                       SDRM_MONT_Mul(Pw[i][j]->z3, Pw[i][j]->z2, Pw[i][j]->z, Mont);
+               }
+       }
+       
+       EC_Dst->IsInfinity = 1;
+       idx[0] = idx[1] = 1;
+
+       // 켱 doubling   ū  
+       if (lenD[0] != lenD[1])
+       {
+               i = ((lenD[0] > lenD[1]) ? 0 : 1);
+               for (;lenD[0] != lenD[1]; idx[i]++)
+               {
+                       if (chain[i][idx[i]] == 0)
+                       {
+                               // EC_Dst = 2EC_Dst
+                               SDRM_CTX_EC_Double_Jm(EC_Dst, EC_Dst, new_a, new_b, Mont);
+                               lenD[i]--;
+                       }
+                       else
+                       {
+                               SDRM_Mont_Jm2Jc(EC_Dst, new_a, new_b, Mont);
+
+                               if (chain[i][idx[i]]>0)
+                               {
+                                       // EC_Dst = EC_Dst + Pw[i][(chain[i][idx[i]]+1)/2]
+                                       SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[i][(chain[i][idx[i]]+1)/2], new_a, new_b, Mont);
+                               }
+                               else
+                               {
+                                       // EC_Dst = EC_Dst - Pw[i][(chain[i][idx[i]]+1)/2]
+                                       SDRM_EC_COPY(Pw[i][0], Pw[i][(-chain[i][idx[i]]+1)/2]);
+                                       SDRM_BN_Sub(Pw[i][0]->y, ctx->ECC_p, Pw[i][0]->y);
+                                       SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[i][0], new_a, new_b, Mont);       
+                               }
+                               SDRM_Mont_Jc2Jm(EC_Dst, new_a, new_b, Mont);
+                       }
+               }
+       }
+
+       while ((idx[0] <= length[0]) && (idx[1] <= length[1]))
+       {
+               if ((chain[0][idx[0]] == 0) && (chain[1][idx[1]] == 0))
+               {
+                       // EC_Dst = 2EC_Dst
+                       SDRM_CTX_EC_Double_Jm(EC_Dst, EC_Dst, new_a, new_b, Mont);
+                       idx[0]++;
+                       idx[1]++;
+                       continue;
+               }
+
+               SDRM_Mont_Jm2Jc(EC_Dst, new_a, new_b, Mont);
+
+               if (chain[0][idx[0]]!=0)
+               {
+                       if (chain[0][idx[0]]>0)
+                       {
+                               // EC_Dst = EC_Dst + Pw[0][(chain[0][idx[0]]+1)/2]
+                               SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[0][(chain[0][idx[0]] + 1) / 2], new_a, new_b, Mont);
+                       }
+                       else
+                       {
+                               // EC_Dst = EC_Dst - Pw[0][(chain[0][idx[0]]+1)/2]
+                               SDRM_EC_COPY(Pw[0][0], Pw[0][(-chain[0][idx[0]] + 1) / 2]);
+                               SDRM_BN_Sub(Pw[0][0]->y, ctx->ECC_p, Pw[0][0]->y);
+                               SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[0][0], new_a, new_b, Mont);
+                       }
+
+                       idx[0]++;
+
+                       if (chain[1][idx[1]] != 0)
+                       {
+                               // make z^2, z^3 for next computation
+                               SDRM_MONT_Mul(EC_Dst->z2, EC_Dst->z, EC_Dst->z, Mont);
+                               SDRM_MONT_Mul(EC_Dst->z3, EC_Dst->z2, EC_Dst->z, Mont);
+                       }
+               }
+
+               if (chain[1][idx[1]]!=0)
+               {
+                       if (chain[1][idx[1]]>0)
+                       {
+                               // EC_Dst = EC_Dst + Pw[1][(chain[1][idx[1]]+1)/2]
+                               SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[1][(chain[1][idx[1]]+1)/2], new_a, new_b, Mont);
+                       }
+                       else
+                       {
+                               // EC_Dst = EC_Dst - Pw[1][(chain[1][idx[1]]+1)/2]
+                               SDRM_EC_COPY(Pw[1][0], Pw[1][(-chain[1][idx[1]]+1)/2]);
+                               SDRM_BN_Sub(Pw[1][0]->y, ctx->ECC_p, Pw[1][0]->y);
+                               SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[1][0], new_a, new_b, Mont);
+                       }
+                       idx[1]++;
+               }
+               SDRM_Mont_Jc2Jm(EC_Dst, new_a, new_b, Mont);
+       }
+
+       if ((idx[0]==length[0]) || (idx[1]==length[1]))
+       {
+               i = ((idx[0]==length[0]) ? 0 : 1);
+
+               SDRM_Mont_Jm2Jc(EC_Dst, new_a, new_b, Mont);
+
+               if (chain[i][idx[i]]>0)
+               {
+                       // EC_Dst = EC_Dst + Pw[i][(chain[i][idx[i]]+1)/2]
+                       SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[i][(chain[i][idx[i]] + 1) / 2], new_a, new_b, Mont);
+               }
+               else
+               {
+                       // EC_Dst = EC_Dst - Pw[i][(chain[i][idx[i]]+1)/2]
+                       SDRM_EC_COPY(Pw[i][0], Pw[i][(-chain[i][idx[i]] + 1) / 2]);
+                       SDRM_BN_Sub(Pw[i][0]->y, ctx->ECC_p, Pw[i][0]->y);
+                       SDRM_CTX_EC_Add_Jc(EC_Dst, EC_Dst, Pw[i][0], new_a, new_b, Mont);
+               }
+               SDRM_Mont_Jc2Jm(EC_Dst, new_a, new_b, Mont);
+       }
+
+
+       // montgomery reduction of EC_Dst
+       SDRM_MONT_Rzn2zn(EC_Dst->x, EC_Dst->x, Mont);
+       SDRM_MONT_Rzn2zn(EC_Dst->y, EC_Dst->y, Mont);
+       SDRM_MONT_Rzn2zn(EC_Dst->z, EC_Dst->z, Mont);
+       
+       if (EC_Dst->z->Length == 0)
+       {
+               for(i = 0; i < 2; i++)
+               {
+                       for(j = 0; j < 9; j++)
+                       {
+                               free(Pw[i][j]);
+                       }
+               }
+
+               free(pbBuf);
+               SDRM_MONT_Free(Mont);
+
+               EC_Dst->IsInfinity = 1;
+
+               return CRYPTO_INFINITY_INPUT;
+       }
+
+       // ǥȯ : Modified Jacobian     =>      Affine
+       //  (EC_Dst->x) <= (EC_Dst->x) * { ((EC_Dst->z)^2)^-1 }
+       //  (EC_Dst->y) <= (EC_Dst->y) * { (2*((EC_Dst->z)^3))^-1 }
+       SDRM_BN_ModMul(t1, EC_Dst->z, EC_Dst->z, ctx->ECC_p);
+       SDRM_BN_ModInv(t2, t1, ctx->ECC_p);
+       SDRM_BN_ModMul(EC_Dst->x, EC_Dst->x, t2, ctx->ECC_p);
+
+       SDRM_BN_ModMul(t2, t1, EC_Dst->z, ctx->ECC_p);
+       SDRM_BN_SHL(t2, t2, 1);
+       SDRM_BN_ModInv(t1, t2, ctx->ECC_p);
+       SDRM_BN_ModMul(EC_Dst->y, EC_Dst->y, t1, ctx->ECC_p);
+
+       for(i = 0; i < 2; i++)
+       {
+               for(j = 0; j < 9; j++)
+               {
+                       free(Pw[i][j]);
+               }
+       }
+
+       free(pbBuf);
+       SDRM_MONT_Free(Mont);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/base/cc_fast_math.c b/ssflib/dep/cryptocore/source/base/cc_fast_math.c
new file mode 100755 (executable)
index 0000000..2718a8b
--- /dev/null
@@ -0,0 +1,914 @@
+/** 
+ * @file       fast_mathf.c
+ * @brief      This file contains optimized implementations for severall basic arithmetical functions.
+ *
+ * [Optional] Detail description (major features, interface description, flow of control, and so on)
+ * @see        [Optional] Related information
+
+ * Copyright 2008 by Samsung Electronics, Inc.,
+ * 
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ * 
+ * \internal
+ * Author : Karen Ispiryan
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2008/08/28
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "CryptoCore.h"
+#include "CC_Constants.h"
+#include "cc_bignum.h"
+
+#include "cc_fast_math.h"
+
+/**
+  * @fn                        SDRM_ll_Cmp
+  * @brief             Compare two large unsigned integers
+  * 
+  * @param             pFirstOperand [in] the first operand
+  * @param             pSecondOperand [in] the second operand
+  *
+  * @return            0 if they are equal
+  *                            1 if first bigger then second
+  *                            -1 if the seond one is bigger then first
+  */
+int SDRM_ll_Cmp(const BasicWord *pFirstOperand, const BasicWord *pSecondOperand, unsigned uOperandLength)
+{
+       pFirstOperand += uOperandLength;
+       pSecondOperand += uOperandLength;
+
+       while (uOperandLength--) {
+               if (*--pFirstOperand != *--pSecondOperand)
+               {
+                       if (*pFirstOperand < *pSecondOperand)
+                       {
+                               return -1;
+                       }
+                       else
+                       {
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+/**
+  * @fn                        SDRM_ll_Copy
+  * @brief             Just copy two large unsigned integers from one into another
+  */
+void SDRM_ll_Copy(BasicWord *pFirstOperand, const BasicWord *pSecondOperand, unsigned uOperandLength)
+{
+       while (uOperandLength--)
+       {
+               *pFirstOperand++ = *pSecondOperand++;
+       }
+}
+
+/**
+  * @fn                        SDRM_ll_bit_RShift
+  * @brief             Shift large unsigned integer to the right by uBits
+  * 
+  * @param             pOperand [inout] pointer to the operand to be shifted
+  *
+  * @return            Nothing
+  * @warning   We have to be careful when using this function because it modifies uOperandLength+1 words 
+  *                            that is by 1 word bigger then operand original size.
+  *                            WWW....Operand...WWW|W <- it modifies the word immediately after the last one of passed operand.
+  */
+void SDRM_ll_bit_RShift(IN OUT BasicWord *pOperand, IN BasicWord uOperandLength, OUT BasicWord uBits)
+{
+       BasicWord uLastIndex = (BasicWord)(uOperandLength - 1);
+       register BasicWord t;
+
+       while (uLastIndex--)
+       {
+               t = *pOperand >> uBits;
+               *pOperand = t | (*(pOperand + 1) << (BASICWORD_BITS_COUNT - uBits));
+               pOperand++;
+       }
+       *pOperand >>= uBits;
+}
+
+/**
+  * @fn                        SDRM_ll_bit_LShift
+  * @brief             Shift large unsigned integer to the left by uBits
+  * 
+  * @param             pOperand [inout] pointer to the operand to be shifted
+  *
+  * @return            Nothing
+  * @warning   We have to be careful when using this function because it modifies uOperandLength+1 words 
+  *                            that is by 1 word bigger then operand original size.
+  *                            It modifies the word immediately prior to the first one of passed operand -> W|WWW....Operand...WWW
+  */
+void SDRM_ll_bit_LShift(IN OUT BasicWord *pOperand, IN BasicWord uOperandLength, OUT BasicWord uBits)
+{
+       BasicWord uLastIndex = (BasicWord)(uOperandLength - 1);
+       BasicWord t;
+
+       pOperand += uOperandLength-1;
+       while (uLastIndex--)
+       {
+               t = *pOperand << uBits;
+               *pOperand = t | (*(pOperand - 1) >> (BASICWORD_BITS_COUNT - uBits));
+               pOperand--;             
+       }
+       *pOperand <<= uBits;
+}
+
+/**
+  * @fn                        SDRM_ll_getMSW
+  * @brief             Return index of most significant word.
+  * 
+  * @param             pOperand [in] pointer to the large integer.
+  *
+  * @return            The index of most significant word.
+  *                            -1 if passed integer actually is equal to 0.
+  */
+int SDRM_ll_getMSW(IN const BasicWord *pOperand, IN BasicWord uOperandLength)
+{
+       int nEl;
+       for(nEl = uOperandLength - 1; nEl >= 0; nEl--)
+       {
+               if (0 != pOperand[nEl])
+               {
+                       break;
+               }
+       }
+       return nEl;
+}
+
+/**
+  * @fn                        SDRM_ll_getMSB
+  * @brief             Find the leftmost non-zero bit in passed unsigned integer.
+  * 
+  * @param             oneWord [in] value of unsigned integer
+  *
+  * @return            Position of leftmost non-zero bit.
+  * @warning   Actually this function returns the position of leftmost non-zero bit started from the end of the integer.
+  *                            For example if we considering the unsigned integer with value 0x80000000 then SDRM_ll_getMSB will return 0 as a result.
+  *                            Or in the case if integer has value equal t 1, then SDRM_ll_getMSB will return BASICWORD_BITS_COUNT as a result.
+  */
+int SDRM_ll_getMSB(IN BasicWord oneWord)
+{
+       register BasicWord mask = (1 << (BASICWORD_BITS_COUNT-1));
+       int nPos = 0;
+
+       if ( !oneWord ) {
+               return BASICWORD_BITS_COUNT;
+       }
+
+       while (!(oneWord & mask))
+       {
+               nPos++;
+               mask >>= 1;
+       }
+
+       return nPos;
+}
+
+/**
+  * @fn                        SDRM_ll_bit_getBitValue
+  * @brief             Return one bit value in the large integer number.
+  * 
+  * @param             pOperand [in] pointer to large integer
+  * @param             nBit     [in] bit position in the large integer.
+  *
+  * @return            0 or 1 depends on actual bit value.
+  */
+int SDRM_ll_bit_getBitValue(IN BasicWord *pOperand, IN BasicWord nBit)
+{
+       BasicWord uOrdNum = nBit / BASICWORD_BITS_COUNT;
+       BasicWord uBitNum = nBit % BASICWORD_BITS_COUNT;
+
+       return (pOperand[uOrdNum] >> uBitNum) & 0x1;
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_bit_getBitsValue(IN const BasicWord *pOperand, IN BasicWord uStartBit, IN BasicWord uBitsCount)
+{
+       int nValueLen, i;
+       BasicWord uValue = 0;
+       BasicWord uStartOrdNum = uStartBit / BASICWORD_BITS_COUNT;      /* number of ords */
+       BasicWord uStartBitNum = uStartBit % BASICWORD_BITS_COUNT;      /* number of bits in remainder BasicWord */
+
+       if((nValueLen = (int)(uStartBitNum + 1 - uBitsCount)) >= 0)
+       {
+               for(i = uStartBitNum; i >= nValueLen; i--)
+               {
+                       uValue = (BasicWord)(((pOperand[uStartOrdNum] >> i) & 1) | (uValue << 1));
+               }
+       }
+       else
+       {
+               nValueLen = uBitsCount - uStartBitNum - 1;
+               for(i = uStartBitNum; i >= 0; i--)
+               {
+                       uValue = (BasicWord)(((pOperand[uStartOrdNum] >> i) & 1) | (uValue << 1));
+               }
+
+               uStartOrdNum--;
+               nValueLen = BASICWORD_BITS_COUNT - nValueLen;
+               for(i = BASICWORD_BITS_COUNT - 1; i >= nValueLen; i--)
+               {
+                       uValue = (BasicWord)(((pOperand[uStartOrdNum] >> i) & 1) | (uValue << 1));
+               }
+       }
+
+       do
+       {
+               if(0 != (uValue & 1))
+               {
+                       break;
+               }
+               uValue >>= 1;
+       }
+       while(1);
+
+       uValue = uValue >> 1;   /* get rid of least significant bit */
+
+       return uValue;
+}
+
+/**
+  * @fn                        SDRM_ll_Add
+  * @brief             Add two large unsigned integers that have the same size.
+  * 
+  * @param             pFirstOperand  [in] pointer to first large integer
+  * @param             pSecondOperand [in] pointer to second large integer
+  * @param             uOperandsLength [in] length of the operands in words
+  * @param             pResult [out] pointer to result of subtraction
+  *
+  * @return            carry if so.
+  */
+int SDRM_ll_Add(IN const BasicWord *pFirstOperand, 
+                               IN const BasicWord *pSecondOperand, 
+                               IN BasicWord uOperandsLength, 
+                               OUT BasicWord *pResult)
+{
+       unsigned i = 1;
+       register BasicWord rh;
+       register BasicWord fo, so, rl;
+
+       fo = *pFirstOperand++;
+       so = *pSecondOperand++;
+       _add_add_(fo,so,0,rl,rh)
+       *pResult++ = rl;
+       for (; i < uOperandsLength; i++)
+       {
+               fo = *pFirstOperand++;
+               so = *pSecondOperand++;
+               _add_add_(fo,so,rh,rl,rh)
+               *pResult++ = rl;
+       }
+
+       return rh;
+}
+
+/**
+  * @fn                        SDRM_ll_AddCarry
+  * @brief             Add carry to large unsigned integer
+  * 
+  * @param             oneWord  [in] value of carry
+  * @param             pOperand [inout] pointer to large integer
+  * @param             uOperandLength [in] length of the second operand in words
+  *
+  * @return            carry if so.
+  */
+int SDRM_ll_AddCarry(IN BasicWord oneWord, IN BasicWord *pOperand, IN BasicWord uOperandLength)
+{
+       BasicWord       i = 1;
+       register BasicWord ow = oneWord;
+
+       if ((pOperand[0] += ow) >= ow)
+       {
+               return 0;
+       }
+
+       while(i < uOperandLength)
+       {
+               if(++pOperand[i++] != 0)
+               {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+/**
+  * @fn                        SDRM_ll_Sub
+  * @brief             Subtract two large unsigned integers that have the same size.
+  * 
+  * @param             pFirstOperand   [in] pointer to first large integer
+  * @param             pSecondOperand  [in] pointer to second large integer
+  * @param             uOperandsLength [in] length of the operands in words
+  * @param             pResult                 [out] pointer to result of subtraction
+  *
+  * @return            borrow if so.
+  */
+int SDRM_ll_Sub(IN const BasicWord *pFirstOperand, 
+                               IN const BasicWord *pSecondOperand, 
+                               IN BasicWord uOperandsLength, 
+                               OUT BasicWord *pResult)
+{
+       register BasicWord temp, borrow = 0;
+
+       while (uOperandsLength--)
+       {
+               temp = *pFirstOperand - *pSecondOperand - borrow;
+               borrow = (borrow && (*pFirstOperand == *pSecondOperand)) || (*pFirstOperand < *pSecondOperand);
+               *pResult++ = temp;
+               pFirstOperand++;
+               pSecondOperand++;
+       }
+       return (borrow);
+}
+
+/**
+  * @fn                        SDRM_ll_Mul1
+  * @brief             Multiply large integer by one word.
+  *                            Result = oneWord*SecondOperand.
+  * 
+  * @param             oneWord                                 [in] value of first multiplayer.
+  * @param             pSecondOperand                  [in] pointer to large integer
+  * @param             uSecondOperandsLength   [in] length of the second operand in words
+  * @param             pResult                                 [out] pointer to result of multiplication
+  *
+  * @warning   Routine doesn't store the last word of multiplication result, 
+  *                            so we have to be carefull and take care about it after calling this function.
+  */
+BasicWord SDRM_ll_Mul1(IN BasicWord oneWord, 
+                                          IN BasicWord *pSecondOperand, BasicWord uSecondOperandsLength, 
+                                          IN OUT BasicWord *pResult)
+{
+       register BasicWord ow = oneWord;
+       register BasicWord rh, op2, r;
+
+       op2 = *pSecondOperand++;
+       r = *pResult;
+       _mul_add_add(op2, ow, 0, 0, r, rh)
+       *pResult++ = r;
+       while ( --uSecondOperandsLength )
+       {
+               op2 = *pSecondOperand++;
+               r = *pResult;
+               _mul_add_add(op2, ow, 0, rh, r, rh)
+               *pResult++ = r;
+       }
+
+       return rh;
+}
+
+/**
+  * @fn                        SDRM_ll_Mul1
+  * @brief             Multiply large integer by one word and add result to the another large integer.
+  *                            Result += oneWord*SecondOperand.
+  * 
+  * @param             oneWord  [in] value of first multiplayer.
+  * @param             pSecondOperand [in] pointer to large integer
+  * @param             uSecondOperandsLength [in] length of the second operand in words
+  * @param             pResult [inout] pointer to result of multiplication
+  *
+  * @warning   Routine doesn't store the last word of multiplication result, 
+  *                            so we have to be carefull and take care about it after calling this function.
+  */
+BasicWord SDRM_ll_MulAdd1(IN BasicWord oneWord, 
+                                                 IN BasicWord *pSecondOperand, BasicWord uSecondOperandsLength, 
+                                                 IN OUT BasicWord *pResult)
+{
+       register BasicWord ow = oneWord;
+       register BasicWord rh, op2, r;
+
+       op2 = *pSecondOperand++;
+       r = *pResult;
+       _mul_add_add(op2, ow, r, 0, r, rh)
+       *pResult++ = r;
+       while (--uSecondOperandsLength)
+       {
+               op2 = *pSecondOperand++;
+               r = *pResult;
+               _mul_add_add(op2, ow, r, rh, r, rh)
+               *pResult++ = r;
+       }
+
+       return rh;
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_MulAdd(IN BasicWord *pFirstOperand, IN BasicWord uFirstOperandsLength, 
+                                       IN BasicWord *pSecondOperand, IN BasicWord uSecondOperandsLength, 
+                                       OUT BasicWord *pResult)
+{
+       while (uFirstOperandsLength--)
+       {
+               *(pResult+uSecondOperandsLength) = SDRM_ll_MulAdd1(*pFirstOperand++, pSecondOperand, uSecondOperandsLength, pResult);
+               pResult++;
+       }
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_Mul(IN BasicWord *pFirstOperand, IN BasicWord uFirstOperandsLength, 
+                                IN BasicWord *pSecondOperand, IN BasicWord uSecondOperandsLength, 
+                                OUT BasicWord *pResult)
+{
+       *(pResult+uSecondOperandsLength) = SDRM_ll_Mul1(*pFirstOperand++, pSecondOperand, uSecondOperandsLength, pResult);
+       while (--uFirstOperandsLength)
+       {
+               *(pResult+uSecondOperandsLength) = SDRM_ll_MulAdd1(*pFirstOperand++, pSecondOperand, uSecondOperandsLength, pResult);
+               pResult++;
+       }
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_Square(IN BasicWord *pOperand, IN BasicWord uOperandLength, OUT BasicWord *pResult)
+{
+       BasicWord i;
+       BasicWord j;
+       BasicWord t;
+       BasicWord len;
+
+       /* Compute the product of diagonal elements */
+       for(i = 0; i < uOperandLength; i++)
+       {
+               BasicWord rl, rh, op;
+               op = pOperand[i];
+               _mul_add_add(op,op,0,0,rl,rh)
+               pResult[i * 2] = rl;
+               pResult[i * 2 + 1] = rh;
+       }
+
+       /* Divide the result by 2 */
+       SDRM_ll_bit_RShift(pResult, (BasicWord)(uOperandLength << 1), 1);
+
+       /* Add the half of the rest part of squaring to the half of diagonal */
+       i = 0;
+       j = 0;
+       len = uOperandLength;
+       while (--len)
+       {
+               t = SDRM_ll_MulAdd1(pOperand[i], pOperand+i+1, (BasicWord)len, pResult + j + 1);
+               SDRM_ll_AddCarry(t, pResult+len+j+1, len+1);
+               j+=2;
+               i++;
+       }
+
+       /* Multiply the result by 2 */
+       SDRM_ll_bit_LShift(pResult, (BasicWord)(uOperandLength << 1), 1);
+
+       /* Restore the least significant bit */
+       if((pOperand[0] & 0x1L) != 0)
+       {
+               pResult[0] |= 0x1L;
+       }
+}
+
+/**
+  * @fn                        SDRM_ll_Rem
+  * @brief             Compute reminder of division.
+  * 
+  * @warning   This is a temporary solution. It has been created mostly for testing purposes. 
+  */
+int SDRM_ll_Rem(IN BasicWord *pOperand, IN BasicWord uOperandLengthInBytes, 
+                               IN BasicWord *pModule, IN BasicWord uModuleLengthInBytes, 
+                               OUT BasicWord *pResult)
+{
+       BasicWord nWordX = DIV_BY_ORD_BYTES_COUNT(uOperandLengthInBytes);
+       BasicWord nWordP;
+       BasicWord *pTempResult;
+
+       nWordX = SDRM_ll_getMSW(pOperand, nWordX) + 1;
+       nWordP = SDRM_ll_getMSW(pModule, nWordX) + 1;
+       
+       // Krishna
+       pTempResult =  (BasicWord*) calloc(nWordX+1,BASICWORD_BYTES_COUNT);
+       if (!pTempResult)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_ll_Copy(pTempResult, pOperand, nWordX);
+
+       SDRM_DWD_Classical_REDC(pTempResult, nWordX, pModule, nWordP);
+       
+       SDRM_ll_Copy(pResult, pTempResult, nWordP);
+
+       free(pTempResult);
+
+       return 0;
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_mont_Inverse(OUT BasicWord *out, IN BasicWord oneWord)
+{
+       /*
+               t = m^(-1) mod b
+               m^(-1) = t*(2-m*t) mod (b^2)
+
+               So we are just using some simple iteration t <- t*(2-m*t) and check the condition that t*m == 1 mod b.
+       */
+       BasicWord t = oneWord;
+       BasicWord r = t*t;
+
+       while (r != 1)
+       {
+               t = t*(2 - r);
+               r = oneWord*t;
+
+               if (!(r) && !(t))
+               {
+                       return -1;
+               }
+       }
+
+       *out = (BasicWord)(-t);
+
+       return 0;
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+void SDRM_ll_mont_Rem(IN OUT BasicWord *pFirstOperand, 
+                                         IN BasicWord *pModule, 
+                                         IN BasicWord uModuleLength, 
+                                         IN BasicWord inv)
+{
+       BasicWord lp;              /* leftmost non-zero element */
+       BasicWord temp, temp_longs;
+       BasicWord carry = 0;
+
+       temp_longs = uModuleLength;
+       lp = SDRM_ll_getMSW(pModule, uModuleLength) + 1;
+       do
+       {
+               temp = inv * pFirstOperand[0];
+               temp = SDRM_ll_MulAdd1(temp, pModule, lp, pFirstOperand);
+               carry += SDRM_ll_AddCarry(temp, pFirstOperand+uModuleLength, temp_longs);
+               pFirstOperand++;
+       }
+       while(--temp_longs);
+
+       while(carry)
+       {
+               if(SDRM_ll_Sub(pFirstOperand, pModule, uModuleLength, pFirstOperand)) {
+                       carry--;
+               }
+       }
+
+       while(SDRM_ll_Cmp(pFirstOperand, pModule, uModuleLength) >= 0)
+       {
+               SDRM_ll_Sub(pFirstOperand, pModule, uModuleLength, pFirstOperand);
+       }
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_mont_Square(IN BasicWord *pFirstOperand, 
+                                               IN BasicWord *pModule, 
+                                               IN BasicWord uModuleLength, 
+                                               IN BasicWord Inv, 
+                                               OUT BasicWord *pResult)
+{
+       pResult[uModuleLength * 2] = 0;
+
+       /* Compute square */
+       SDRM_ll_Square(pFirstOperand, uModuleLength, pResult);
+       /* Compute the modulo by the Montgomery */
+       SDRM_ll_mont_Rem(pResult, pModule, uModuleLength, Inv);
+
+       /* Note: The next step for making toolkit faster is to redesign Montgomery functions and remove all memory allocation 
+          and copying from there. That means that exponentiation routine should be redesigne as well. */
+       memcpy(pFirstOperand, pResult + uModuleLength, MUL_BY_ORD_BYTES_COUNT(uModuleLength));
+       return CRYPTO_SUCCESS;
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+int SDRM_ll_mont_Mul(IN BasicWord *pFirstOperand, 
+                                        IN BasicWord *pSecondOperand, 
+                                        IN BasicWord *pModule, 
+                                        IN BasicWord uModuleLengthInBytes, 
+                                        IN BasicWord Inv, 
+                                        OUT BasicWord *pResult)
+{
+       BasicWord P_longs;             /* number of longs in P, X and Y */
+       BasicWord lx, ly;              /* leftmost non-zero elements */
+       BasicWord *XY;                 /* pointer to product result */
+
+       P_longs = DIV_BY_ORD_BYTES_COUNT(uModuleLengthInBytes);
+       XY = (BasicWord*)calloc(2 * P_longs + 1, BASICWORD_BYTES_COUNT);
+       if(!XY)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       /* Find leftmost non-zero elements */
+       lx = SDRM_ll_getMSW(pFirstOperand, P_longs) + 1;
+       ly = SDRM_ll_getMSW(pSecondOperand, P_longs) + 1;
+       /* Compute the product of FirstOperand and SecondOperand */
+       SDRM_ll_MulAdd(pFirstOperand, lx, pSecondOperand, ly, XY);
+       /* Compute the modulo by the Montgomery */
+       SDRM_ll_mont_Rem(XY, pModule, P_longs, Inv);
+
+       /* Note: The next step for making toolkit faster is to redesign Montgomery functions and remove all memory allocation 
+          and copying from there. That means that exponentiation routine should be redesigne as well. */
+       memcpy(pResult, XY + P_longs, uModuleLengthInBytes);
+       free(XY);
+       return CRYPTO_SUCCESS;
+}
+
+/**
+  * @fn                        [Mandatory] Function name
+  * @brief             [Mandatory] Description of major features and algorithms
+  * 
+  * @param             [Optional] description of parameters ([one among in, out, inout])
+  *
+  * @return            [Optional] description of return value
+  * @warning   [Optional] constraints or notices
+  * @see               [Optional] related information
+  */
+
+#define _win_pval(i) (BasicWord*)(temp_1 + (i) * uOrdsP)
+int SDRM_ll_ExpMod( IN BasicWord *pBase, IN BasicWord uBaseLengthInBytes, 
+                                       IN BasicWord *pExponent, IN BasicWord uExponentLengthInBytes,
+                                       IN BasicWord *pModule, IN BasicWord uModuleLengthInBytes, 
+                                       OUT BasicWord *pResult)
+{
+       int nStatus = CRYPTO_SUCCESS;
+       BasicWord *temp_1, inv;
+       BasicWord *m_temp, *m_sq;
+       int n_mem, win_len;
+       BasicWord uOrdsY, uOrdsP;
+       int i, j, k, eb = 0;
+       BasicWord nIndex;
+       int ly;
+       /* The values of num_squar array given below represents the lengths of particular window values in bits */
+       /* We have to take into account that we store only odd values. */
+       /* window values  -> 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, etc... */
+       /* num_squar      -> 1, 2, 3, 3, 4,  4,  4,  4,  5,  5, etc... */
+       int num_squar[32] = {1, 2, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+                                                6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,};
+
+       uOrdsY = DIV_BY_ORD_BYTES_COUNT(uExponentLengthInBytes);
+       uOrdsP = DIV_BY_ORD_BYTES_COUNT(uModuleLengthInBytes);
+       /* Find the leftmost non-zero element of modulo */
+       if(-1 == SDRM_ll_getMSW(pModule, uOrdsP)) {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+       /* Find the leftmost non-zero element of exponent */
+       ly = SDRM_ll_getMSW(pExponent, uOrdsY);
+
+       /* if exponent equal to 0 result is 1 */
+       if(-1 == ly)
+       {
+               memset(pResult, 0, uModuleLengthInBytes);
+               pResult[0] = 1;
+               return CRYPTO_SUCCESS;
+       }
+
+       /* Find the leftmost non-zero bit in this element */
+       eb = SDRM_ll_getMSB(pExponent[ly]);
+
+       /* Choose window length */
+       k = BASICWORD_BITS_COUNT * (ly + 1) - eb - 1;
+       if(k < 512)
+       {
+               win_len = 4;
+       }
+       else if((k >= 512) && (k < 1024))
+       {
+               win_len = 5;
+       }
+       else
+       { /* for any k >= 1024 */
+               win_len = 6;
+       }
+
+       /* Obtain number of precomputed elements */
+       n_mem = (1 << (win_len - 1)) + 1;
+       /* Allocate storage for precomputetd values */
+       temp_1 = (BasicWord*)calloc((n_mem + 1) * uOrdsP, BASICWORD_BYTES_COUNT);
+       if (!temp_1)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       /* Allocate temporary storages */
+       m_temp = (BasicWord*)calloc(2 * uOrdsP + 1, BASICWORD_BYTES_COUNT);
+       if (!m_temp)
+       {
+               free(temp_1);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+       m_sq = (BasicWord*)malloc(2 * uModuleLengthInBytes + BASICWORD_BYTES_COUNT);
+       if (!m_sq)
+       {
+               free(temp_1);
+               free(m_temp);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       do
+       {
+               /* Convert Base to Montgomery form */
+               inv = *pModule;
+               if (SDRM_ll_mont_Inverse(&inv, inv) != 0)
+               {
+                       nStatus = CRYPTO_INVERSE_NOT_EXIST;
+                       break;
+               }
+               /* Move n up "mlen" words into a */
+               /* Actually we obtain X*R where R is Montgomery reduction coefficient */
+               memcpy(m_temp + uOrdsP, pBase, uBaseLengthInBytes);
+
+               /* Do the division - dump the quotient in the high-order words */
+               if((nStatus = SDRM_ll_Rem(m_temp, (BasicWord)(uBaseLengthInBytes + uModuleLengthInBytes), pModule, uModuleLengthInBytes, temp_1)) != CRYPTO_SUCCESS)
+               {
+                       break;
+               }
+
+               /* After this operation we will obtain X*R mod P */
+               memcpy(m_temp, temp_1, uModuleLengthInBytes);
+
+               /* Initialization */
+               /* Compute X^2*R mod P */
+               SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+               memcpy(_win_pval(n_mem), m_temp, uModuleLengthInBytes);
+
+               /* We have to calculate X^3, X^5 and so on ... */
+               /* For making that we just use previously calculated value of X^2 and use it as multiplayer consecutively. */
+               /* element (0) <- X*R mod P */
+               /* element (1) <- X^3*R = element (0) * X^2*R mod P */
+               /* element (2) <- X^5*R = element (1) * X^2*R mod P */
+               /* element (3) <- X^7*R = element (2) * X^2*R mod P */
+               /* element (4) <- ... */
+               for(i = 1; i < n_mem; i++)
+               {
+                       SDRM_ll_mont_Mul(_win_pval(i - 1), _win_pval(n_mem), pModule, uModuleLengthInBytes, inv, _win_pval(i));
+               }
+               
+               /* OK, now let compute R mod P */
+               memset(m_temp, 0, 2 * uModuleLengthInBytes + 1);
+               m_temp[uOrdsP] = 1;
+               if((nStatus = SDRM_ll_Rem(m_temp, (BasicWord)(uModuleLengthInBytes + BASICWORD_BYTES_COUNT), pModule, uModuleLengthInBytes, m_temp)) != CRYPTO_SUCCESS) {
+                       break;
+               }
+
+               /* Compute the exponent */
+               for(i = k; i >= win_len-1; )
+               {
+                       /* Note: I don't like this solution, but it was easy and from that point of view was suitable for short development cycle. 
+                          During further refactoring exponent bits processing should be changed in a way that makes possible to perform
+                          all computations inside of the one cycle. See some additional related comments right after the body of this cycle.*/
+
+                       /* Find next suitable bits for computations */
+                       nIndex = (BasicWord)SDRM_ll_bit_getBitsValue(pExponent, (BasicWord)i, (BasicWord)win_len);
+
+                       /* Square the intermediate result */
+                       for(j = 0; j < num_squar[nIndex]; j++)
+                       {
+                               SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+                       }
+
+                       /* Multiply with the precomputed data */
+                       SDRM_ll_mont_Mul(m_temp, _win_pval(nIndex), pModule, uModuleLengthInBytes, inv, m_temp);
+
+                       /* Square (win_len - num_squar) times */
+                       for(j = 0 ; j < win_len - num_squar[nIndex]; j++)
+                       {
+                               SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+                       }
+
+                       i -= win_len;
+
+                       /* perform squering till first nonzero bit */
+                       while((i >= win_len - 1) && !SDRM_ll_bit_getBitValue(pExponent, (BasicWord)i))
+                       {
+                               SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+                               i--;
+                       }
+               }
+
+               /* Note: Actually it would be batter to perform remeined last bits processing inside of the exponent computation main cycle.
+                  So the next refactoring step is to modify this routine and make things in that way. */
+
+               /* if we still have some bit(s) ... */
+               /* perform squering till first nonzero bit */
+               while((i >= 0) && !SDRM_ll_bit_getBitValue(pExponent, (BasicWord)i))
+               {
+                       SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+                       i--;
+               }
+
+               /* if we still have some nonzero bit(s) ... */
+               if(i >= 0)
+               {
+                       nIndex = (BasicWord)SDRM_ll_bit_getBitsValue(pExponent, (BasicWord)i, (BasicWord)(i + 1));
+                       for(j = 0; j < num_squar[nIndex]; j++)
+                       {
+                               SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+                       }
+
+                       /* Multiply with precomputed data*/
+                       SDRM_ll_mont_Mul(m_temp, _win_pval(nIndex), pModule, uModuleLengthInBytes, inv, m_temp);
+
+                       /* Square (win_len - num_squar) times */
+                       for(j = 0 ; j <= i - num_squar[nIndex]; j++)
+                       {
+                               SDRM_ll_mont_Square(m_temp, pModule, uOrdsP, inv, m_sq);
+                       }
+               }
+
+               /* Convert the result out of Montgomery form */
+               SDRM_ll_mont_Rem(m_temp,  pModule, uOrdsP, inv);
+               memcpy(pResult, m_temp + uOrdsP, uModuleLengthInBytes);
+               /* This is the tricky place :) Actually we have (X*R+R) mod P. */
+               /* So we just need to remove that additional R */
+               pResult[0]--;
+
+               break;  /* always break this loop */
+       }
+       while(0);
+
+       free(temp_1);
+       free(m_temp);
+       free(m_sq);
+
+       return nStatus;
+}
diff --git a/ssflib/dep/cryptocore/source/base/cc_hash.c b/ssflib/dep/cryptocore/source/base/cc_hash.c
new file mode 100755 (executable)
index 0000000..0ee058c
--- /dev/null
@@ -0,0 +1,578 @@
+/**
+ * \file       hash.c
+ * @brief      hash API function
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/08
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_hash.h"
+#include "cc_sha1.h"
+#include "cc_sha2.h"
+#include "cc_md5.h"
+
+////////////////////////////////////////////////////////////////////////////
+// functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_SHA1_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_init(CryptoCoreContainer *crt)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA1_Init(crt->ctx->sha1ctx);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA1_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]cc_u8-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA1_Update(crt->ctx->sha1ctx, msg, msglen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA1_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_final(CryptoCoreContainer *crt, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA1_Final(crt->ctx->sha1ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA1_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA1_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA1_Init(crt->ctx->sha1ctx);
+       SDRM_SHA1_Update(crt->ctx->sha1ctx, msg, msglen);
+       SDRM_SHA1_Final(crt->ctx->sha1ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA224_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_init(CryptoCoreContainer *crt)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA224_Init(crt->ctx->sha224ctx);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA224_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA224_Update(crt->ctx->sha224ctx, msg, msglen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA224_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_final(CryptoCoreContainer *crt, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (output == NULL)) {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA224_Final(crt->ctx->sha224ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA224_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA224_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA224_Init(crt->ctx->sha224ctx);
+       SDRM_SHA224_Update(crt->ctx->sha224ctx, msg, msglen);
+       SDRM_SHA224_Final(crt->ctx->sha224ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA256_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_init(CryptoCoreContainer *crt)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA256_Init(crt->ctx->sha256ctx);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA256_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA256_Update(crt->ctx->sha256ctx, msg, msglen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA256_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_final(CryptoCoreContainer *crt, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (output == NULL)) {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA256_Final(crt->ctx->sha256ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA256_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA256_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA256_Init(crt->ctx->sha256ctx);
+       SDRM_SHA256_Update(crt->ctx->sha256ctx, msg, msglen);
+       SDRM_SHA256_Final(crt->ctx->sha256ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+#ifndef _OP64_NOTSUPPORTED
+
+/*
+ * @fn         SDRM_SHA384_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_init(CryptoCoreContainer *crt)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA384_Init(crt->ctx->sha384ctx);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*             
+ * @fn         SDRM_SHA384_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA384_Update(crt->ctx->sha384ctx, msg, msglen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA384_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_final(CryptoCoreContainer *crt, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA384_Final(crt->ctx->sha384ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA384_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA384_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA384_Init(crt->ctx->sha384ctx);
+       SDRM_SHA384_Update(crt->ctx->sha384ctx, msg, msglen);
+       SDRM_SHA384_Final(crt->ctx->sha384ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA512_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_init(CryptoCoreContainer *crt)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA512_Init(crt->ctx->sha512ctx);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA512_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA512_Update(crt->ctx->sha512ctx, msg, msglen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA512_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_final(CryptoCoreContainer *crt, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA512_Final(crt->ctx->sha512ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SHA512_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_SHA512_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_SHA512_Init(crt->ctx->sha512ctx);
+       SDRM_SHA512_Update(crt->ctx->sha512ctx, msg, msglen);
+       SDRM_SHA512_Final(crt->ctx->sha512ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+#endif //_OP64_NOTSUPPORTED
+
+/*
+ * @fn         SDRM_MD5_init
+ * @brief      initialize CryptoCoreContainer context
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_init(CryptoCoreContainer *crt)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_MD5_Init(crt->ctx->md5ctx);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_MD5_update
+ * @brief      process a message block
+ *
+ * @param      crt                                     [out]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_MD5_Update(crt->ctx->md5ctx, msg, msglen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_MD5_final
+ * @brief      get hashed message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_final(CryptoCoreContainer *crt, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_MD5_Final(crt->ctx->md5ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_MD5_hash
+ * @brief      get hashed message from message
+ *
+ * @param      crt                                     [in]CryptoCoreContainer context
+ * @param      msg                                     [in]message
+ * @param      msglen                          [in]byte-length of msg
+ * @param      output                          [out]hashed message
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_MD5_hash(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msglen, cc_u8 *output)
+{
+       if ((crt == NULL) || (crt->ctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_MD5_Init(crt->ctx->md5ctx);
+       SDRM_MD5_Update(crt->ctx->md5ctx, msg, msglen);
+       SDRM_MD5_Final(crt->ctx->md5ctx, output);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/base/cc_md5.c b/ssflib/dep/cryptocore/source/base/cc_md5.c
new file mode 100755 (executable)
index 0000000..e11e034
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * MD5 implementation
+ */
+
+#include "cc_md5.h"
+
+//Constants for MD5Transform routine.
+static cc_u8 S[4][4] = {
+       {7, 12, 17, 22},
+       {5,  9, 14, 20},
+       {4, 11, 16, 23},
+       {6, 10, 15, 21}
+};
+
+static void SDRM_MD5Transform(cc_u32 [4], const unsigned char*);
+static void SDRM_Encode (unsigned char *, cc_u32 *, cc_u32);
+static void SDRM_Decode (cc_u32 *, const unsigned char *, cc_u32);
+
+static unsigned char PADDING[64] = {0x80, 0,};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+//#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+//#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+//#define H(x, y, z) ((x) ^ (y) ^ (z))
+//#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) F(z, x, y)
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) {                                     \
+ (a) += F ((b), (c), (d)) + (x) + (cc_u32)(ac);                \
+ (a) = ROTATE_LEFT ((a), (s));                                         \
+ (a) += (b);                                                                           \
+}
+#define GG(a, b, c, d, x, s, ac) {                                     \
+ (a) += G ((b), (c), (d)) + (x) + (cc_u32)(ac);                \
+ (a) = ROTATE_LEFT ((a), (s));                                         \
+ (a) += (b);                                                                           \
+}
+#define HH(a, b, c, d, x, s, ac) {                                     \
+ (a) += H ((b), (c), (d)) + (x) + (cc_u32)(ac);                \
+ (a) = ROTATE_LEFT ((a), (s));                                         \
+ (a) += (b);                                                                           \
+}
+#define II(a, b, c, d, x, s, ac) {                                     \
+ (a) += I ((b), (c), (d)) + (x) + (cc_u32)(ac);                \
+ (a) = ROTATE_LEFT ((a), (s));                                         \
+ (a) += (b);                                                                           \
+}
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void SDRM_MD5_Init(SDRM_MD5Context *ctx)
+{
+       ctx->count[0] = 0;
+       ctx->count[1] = 0;
+
+       // Load magic initialization constants.
+       ctx->state[0] = 0x67452301;
+       ctx->state[1] = 0xefcdab89;
+       ctx->state[2] = 0x98badcfe;
+       ctx->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+void SDRM_MD5_Update(SDRM_MD5Context *ctx, cc_u8* input, cc_u32 inputLen)
+{
+       cc_u32 i, idx, partLen;
+
+       /* Compute number of bytes mod 64 */
+       idx = (cc_u32)((ctx->count[0] >> 3) & 0x3F);
+
+       /* Update number of bits */
+       if ((ctx->count[0] += ((cc_u32)inputLen << 3)) < ((cc_u32)inputLen << 3))
+       {
+               ctx->count[1]++;
+       }
+       
+       ctx->count[1] += ((cc_u32)inputLen >> 29);
+
+       partLen = 64 - idx;
+
+       // Transform as many times as possible.
+       if (inputLen >= partLen)
+       {
+               memcpy(&ctx->buffer[idx], input, partLen);
+               SDRM_MD5Transform(ctx->state, ctx->buffer);
+
+               for (i = partLen; i + 63 < inputLen; i += 64) 
+               {
+                       SDRM_MD5Transform(ctx->state, &input[i]);
+               }
+
+               idx = 0;
+       }
+       else
+       {
+               i = 0;
+       }
+
+       /* Buffer remaining input */
+       memcpy(&ctx->buffer[idx], &input[i], inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+void SDRM_MD5_Final(SDRM_MD5Context *ctx, cc_u8* digest)
+{
+       unsigned char bits[8];
+       cc_u32 idx, padLen;
+
+       /* Save number of bits */
+       SDRM_Encode(bits, ctx->count, 8);
+
+       // Pad out to 56 mod 64.
+       idx = (cc_u32)((ctx->count[0] >> 3) & 0x3f);
+       padLen = (idx < 56) ? (56 - idx) : (120 - idx);
+       SDRM_MD5_Update (ctx, PADDING, padLen);
+
+       /* Append length (before padding) */
+       SDRM_MD5_Update (ctx, bits, 8);
+
+       /* Store state in digest */
+       SDRM_Encode (digest, ctx->state, 16);
+
+       // Zeroize sensitive information.
+       memset(ctx, 0, sizeof(*ctx));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void SDRM_MD5Transform (cc_u32 state[4], const unsigned char* block)
+{
+       cc_u32 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+       SDRM_Decode (x, block, 64);
+
+       /* Round 1 */
+       FF (a, b, c, d, x[ 0], S[0][0], 0xd76aa478); /* 1 */
+       FF (d, a, b, c, x[ 1], S[0][1], 0xe8c7b756); /* 2 */
+       FF (c, d, a, b, x[ 2], S[0][2], 0x242070db); /* 3 */
+       FF (b, c, d, a, x[ 3], S[0][3], 0xc1bdceee); /* 4 */
+       FF (a, b, c, d, x[ 4], S[0][0], 0xf57c0faf); /* 5 */
+       FF (d, a, b, c, x[ 5], S[0][1], 0x4787c62a); /* 6 */
+       FF (c, d, a, b, x[ 6], S[0][2], 0xa8304613); /* 7 */
+       FF (b, c, d, a, x[ 7], S[0][3], 0xfd469501); /* 8 */
+       FF (a, b, c, d, x[ 8], S[0][0], 0x698098d8); /* 9 */
+       FF (d, a, b, c, x[ 9], S[0][1], 0x8b44f7af); /* 10 */
+       FF (c, d, a, b, x[10], S[0][2], 0xffff5bb1); /* 11 */
+       FF (b, c, d, a, x[11], S[0][3], 0x895cd7be); /* 12 */
+       FF (a, b, c, d, x[12], S[0][0], 0x6b901122); /* 13 */
+       FF (d, a, b, c, x[13], S[0][1], 0xfd987193); /* 14 */
+       FF (c, d, a, b, x[14], S[0][2], 0xa679438e); /* 15 */
+       FF (b, c, d, a, x[15], S[0][3], 0x49b40821); /* 16 */
+
+       /* Round 2 */
+       GG (a, b, c, d, x[ 1], S[1][0], 0xf61e2562); /* 17 */
+       GG (d, a, b, c, x[ 6], S[1][1], 0xc040b340); /* 18 */
+       GG (c, d, a, b, x[11], S[1][2], 0x265e5a51); /* 19 */
+       GG (b, c, d, a, x[ 0], S[1][3], 0xe9b6c7aa); /* 20 */
+       GG (a, b, c, d, x[ 5], S[1][0], 0xd62f105d); /* 21 */
+       GG (d, a, b, c, x[10], S[1][1], 0x02441453); /* 22 */
+       GG (c, d, a, b, x[15], S[1][2], 0xd8a1e681); /* 23 */
+       GG (b, c, d, a, x[ 4], S[1][3], 0xe7d3fbc8); /* 24 */
+       GG (a, b, c, d, x[ 9], S[1][0], 0x21e1cde6); /* 25 */
+       GG (d, a, b, c, x[14], S[1][1], 0xc33707d6); /* 26 */
+       GG (c, d, a, b, x[ 3], S[1][2], 0xf4d50d87); /* 27 */
+       GG (b, c, d, a, x[ 8], S[1][3], 0x455a14ed); /* 28 */
+       GG (a, b, c, d, x[13], S[1][0], 0xa9e3e905); /* 29 */
+       GG (d, a, b, c, x[ 2], S[1][1], 0xfcefa3f8); /* 30 */
+       GG (c, d, a, b, x[ 7], S[1][2], 0x676f02d9); /* 31 */
+       GG (b, c, d, a, x[12], S[1][3], 0x8d2a4c8a); /* 32 */
+
+       /* Round 3 */
+       HH (a, b, c, d, x[ 5], S[2][0], 0xfffa3942); /* 33 */
+       HH (d, a, b, c, x[ 8], S[2][1], 0x8771f681); /* 34 */
+       HH (c, d, a, b, x[11], S[2][2], 0x6d9d6122); /* 35 */
+       HH (b, c, d, a, x[14], S[2][3], 0xfde5380c); /* 36 */
+       HH (a, b, c, d, x[ 1], S[2][0], 0xa4beea44); /* 37 */
+       HH (d, a, b, c, x[ 4], S[2][1], 0x4bdecfa9); /* 38 */
+       HH (c, d, a, b, x[ 7], S[2][2], 0xf6bb4b60); /* 39 */
+       HH (b, c, d, a, x[10], S[2][3], 0xbebfbc70); /* 40 */
+       HH (a, b, c, d, x[13], S[2][0], 0x289b7ec6); /* 41 */
+       HH (d, a, b, c, x[ 0], S[2][1], 0xeaa127fa); /* 42 */
+       HH (c, d, a, b, x[ 3], S[2][2], 0xd4ef3085); /* 43 */
+       HH (b, c, d, a, x[ 6], S[2][3], 0x04881d05); /* 44 */
+       HH (a, b, c, d, x[ 9], S[2][0], 0xd9d4d039); /* 45 */
+       HH (d, a, b, c, x[12], S[2][1], 0xe6db99e5); /* 46 */
+       HH (c, d, a, b, x[15], S[2][2], 0x1fa27cf8); /* 47 */
+       HH (b, c, d, a, x[ 2], S[2][3], 0xc4ac5665); /* 48 */
+
+       /* Round 4 */
+       II (a, b, c, d, x[ 0], S[3][0], 0xf4292244); /* 49 */
+       II (d, a, b, c, x[ 7], S[3][1], 0x432aff97); /* 50 */
+       II (c, d, a, b, x[14], S[3][2], 0xab9423a7); /* 51 */
+       II (b, c, d, a, x[ 5], S[3][3], 0xfc93a039); /* 52 */
+       II (a, b, c, d, x[12], S[3][0], 0x655b59c3); /* 53 */
+       II (d, a, b, c, x[ 3], S[3][1], 0x8f0ccc92); /* 54 */
+       II (c, d, a, b, x[10], S[3][2], 0xffeff47d); /* 55 */
+       II (b, c, d, a, x[ 1], S[3][3], 0x85845dd1); /* 56 */
+       II (a, b, c, d, x[ 8], S[3][0], 0x6fa87e4f); /* 57 */
+       II (d, a, b, c, x[15], S[3][1], 0xfe2ce6e0); /* 58 */
+       II (c, d, a, b, x[ 6], S[3][2], 0xa3014314); /* 59 */
+       II (b, c, d, a, x[13], S[3][3], 0x4e0811a1); /* 60 */
+       II (a, b, c, d, x[ 4], S[3][0], 0xf7537e82); /* 61 */
+       II (d, a, b, c, x[11], S[3][1], 0xbd3af235); /* 62 */
+       II (c, d, a, b, x[ 2], S[3][2], 0x2ad7d2bb); /* 63 */
+       II (b, c, d, a, x[ 9], S[3][3], 0xeb86d391); /* 64 */
+
+       state[0] += a;
+       state[1] += b;
+       state[2] += c;
+       state[3] += d;
+
+       //Zeroize sensitive information.
+       memset (x, 0, sizeof (x));
+}
+
+/* Encodes input (cc_u4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void SDRM_Encode (unsigned char *output, cc_u32 *input, cc_u32 len)
+{
+       cc_u32 i, j;
+
+       for (i = 0, j = 0; j < len; i++, j += 4)
+       {
+               output[j  ] = (unsigned char)((input[i]      ) & 0xff);
+               output[j+1] = (unsigned char)((input[i] >>  8) & 0xff);
+               output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+               output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+       }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+  a multiple of 4.
+ */
+static void SDRM_Decode (cc_u32 *output, const unsigned char *input, cc_u32 len)
+{
+       cc_u32 i, j;
+
+       for (i = 0, j = 0; j < len; i++, j += 4)
+       {
+               output[i] = (
+               (((cc_u32)input[j]    )      ) | 
+               (((cc_u32)input[j + 1]) <<  8) |
+               (((cc_u32)input[j + 2]) << 16) |
+               (((cc_u32)input[j + 3]) << 24));
+       }
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/base/cc_moo.c b/ssflib/dep/cryptocore/source/base/cc_moo.c
new file mode 100755 (executable)
index 0000000..95c465c
--- /dev/null
@@ -0,0 +1,487 @@
+/**
+ * \file       moo.c
+ * @brief      implementation of mode of operations
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/08/04
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_moo.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_ECB_Enc
+ * @brief      Encrypt a block with ECB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_ECB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key)
+{
+       switch(Algorithm)
+       {
+               case ID_AES128 :
+                       SDRM_rijndaelEncrypt((cc_u32*)(void*)key, 10, in, out);
+                       return CRYPTO_SUCCESS;
+               case ID_AES192 :
+                       SDRM_rijndaelEncrypt((cc_u32*)(void*)key, 12, in, out);
+                       return CRYPTO_SUCCESS;
+               case ID_AES256 :
+                       SDRM_rijndaelEncrypt((cc_u32*)(void*)key, 14, in, out);
+                       return CRYPTO_SUCCESS;
+               case ID_DES :
+                       return SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, in, out);
+               case ID_TDES :
+                       return SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, in, out);
+               default :
+                       break;
+       }
+
+       return CRYPTO_INVALID_ARGUMENT;
+}
+
+/*
+ * @fn         SDRM_ECB_Dec
+ * @brief      Decrypt a block with ECB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]plain text block
+ * @param      in                                              [in]cipher text block
+ * @param      key                                             [in]user key
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_ECB_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key)
+{
+       switch(Algorithm)
+       {
+               case ID_AES128 :
+                       SDRM_rijndaelDecrypt((const cc_u32*)(void*)key, 10, in, out);
+                       return CRYPTO_SUCCESS;
+               case ID_AES192 :
+                       SDRM_rijndaelDecrypt((const cc_u32*)(void*)key, 12, in, out);
+                       return CRYPTO_SUCCESS;
+               case ID_AES256 :
+                       SDRM_rijndaelDecrypt((const cc_u32*)(void*)key, 14, in, out);
+                       return CRYPTO_SUCCESS;
+               case ID_DES :
+                       return SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, in, out);
+               case ID_TDES :
+                       return SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, in, out);
+               default :
+                       break;
+       }
+
+       return CRYPTO_INVALID_ARGUMENT;
+}
+
+/*
+ * @fn         SDRM_CBC_Enc
+ * @brief      Encrypt a block with CBC mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CBC_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+{
+       int i;
+
+       switch(Algorithm) 
+       {
+               case ID_AES128 : 
+                       for (i = 0; i < 16; i++)
+                       {
+                               IV[i] ^= in[i];
+                       }
+
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 10, IV, out);
+
+                       memcpy(IV, out, 16);
+
+                       break;
+               case ID_AES192 : 
+                       for (i = 0; i < 16; i++)
+                       {
+                               IV[i] ^= in[i];
+                       }
+
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 12, IV, out);
+
+                       memcpy(IV, out, 16);
+
+                       break;
+               case ID_AES256 : 
+                       for (i = 0; i < 16; i++)
+                       {
+                               IV[i] ^= in[i];
+                       }
+
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 14, IV, out);
+
+                       memcpy(IV, out, 16);
+
+                       break;
+               case ID_DES :
+                       for (i = 0; i < 8; i++)
+                       {
+                               IV[i] ^= in[i];
+                       }
+
+                       SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+
+                       memcpy(IV, out, 8);
+
+                       break;
+               case ID_TDES :
+                       for (i = 0; i < 8; i++)
+                       {
+                               IV[i] ^= in[i];
+                       }
+
+                       SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+
+                       memcpy(IV, out, 8);
+
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CBC_Dec
+ * @brief      Decrypt a block with CBC mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]plain text block
+ * @param      in                                              [in]cipher text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CBC_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV){
+       int i, BlockLen;
+       cc_u8 buf[16];
+
+       switch(Algorithm)
+       {
+               case ID_AES128 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelDecrypt((const cc_u32*)(void*)key, 10, in, out);
+                       break;
+               case ID_AES192 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelDecrypt((const cc_u32*)(void*)key, 12, in, out);
+                       break;
+               case ID_AES256 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelDecrypt((const cc_u32*)(void*)key, 14, in, out);
+                       break;
+               case ID_DES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, in, out);
+                       break;
+               case ID_TDES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, in, out);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       for (i = 0; i < BlockLen; i++)
+       {
+               out[i] ^= IV[i];
+       }
+
+       memcpy(IV, buf, BlockLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CFB_Enc
+ * @brief      Encrypt a block with CFB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CFB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+{
+       int i, BlockLen;
+       cc_u8 buf[16];
+
+       switch(Algorithm)
+       {
+               case ID_AES128 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 10, IV, out);
+                       break;
+               case ID_AES192 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 12, IV, out);
+                       break;
+               case ID_AES256 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 14, IV, out);
+                       break;
+               case ID_DES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               case ID_TDES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+       
+       for (i = 0; i < BlockLen; i++)
+       {
+               out[i] ^= buf[i];
+       }
+
+       memcpy(IV, out, BlockLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CFB_Dec
+ * @brief      Decrypt a block with CFB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]plain text block
+ * @param      in                                              [in]cipher text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CFB_Dec(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+{
+       int i, BlockLen;
+       cc_u8 buf[16];
+
+       switch(Algorithm)
+       {
+               case ID_AES128 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 10, IV, out);
+                       break;
+               case ID_AES192 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 12, IV, out);
+                       break;
+               case ID_AES256 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 14, IV, out);
+                       break;
+               case ID_DES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               case ID_TDES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+       
+       for (i = 0; i < BlockLen; i++)
+       {
+               out[i] ^= buf[i];
+       }
+
+       memcpy(IV, buf, BlockLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_OFB_Enc
+ * @brief      Encrypt a block with OFB mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_OFB_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV)
+{
+       int i, BlockLen;
+       cc_u8 buf[16];
+
+       switch(Algorithm)
+       {
+               case ID_AES128 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 10, IV, out);
+                       break;
+               case ID_AES192 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 12, IV, out);
+                       break;
+               case ID_AES256 : 
+                       BlockLen = 16;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 14, IV, out);
+                       break;
+               case ID_DES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               case ID_TDES :
+                       BlockLen = 8;
+                       memcpy(buf, in, BlockLen);
+                       SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       memcpy(IV, out, BlockLen);
+
+       for (i = 0; i < BlockLen; i++)
+       {
+               out[i] ^= buf[i];
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*     
+ * @fn         SDRM_CTR_Enc
+ * @brief      Encrypt a block with CTR mode
+ *
+ * @param      Algorithm                               [in]algorithm
+ * @param      out                                             [out]cipher text block
+ * @param      in                                              [in]plain text block
+ * @param      key                                             [in]user key
+ * @param      IV                                              [in]initial vector
+ * @param      counter                                 [in]
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_INVALID_ARGUMENT if parameter is invalid
+ */
+int SDRM_CTR_Enc(int Algorithm, cc_u8 *out, cc_u8 *in, cc_u8 *key, cc_u8 *IV, cc_u32 counter)
+{
+       int i, BlockLen;
+       cc_u8 buf[16];
+
+       switch(Algorithm)
+       {
+               case ID_AES128 : 
+                       BlockLen = 16;
+                       IV[12] = (cc_u8)(0xff & (counter >> 24));
+                       IV[13] = (cc_u8)(0xff & (counter >> 16));
+                       IV[14] = (cc_u8)(0xff & (counter >> 8 ));
+                       IV[15] = (cc_u8)(0xff & (counter      ));
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 10, IV, out);
+                       break;
+               case ID_AES192 : 
+                       BlockLen = 16;
+                       IV[12] = (cc_u8)(0xff & (counter >> 24));
+                       IV[13] = (cc_u8)(0xff & (counter >> 16));
+                       IV[14] = (cc_u8)(0xff & (counter >> 8 ));
+                       IV[15] = (cc_u8)(0xff & (counter      ));
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 12, IV, out);
+                       break;
+               case ID_AES256 : 
+                       BlockLen = 16;
+                       IV[12] = (cc_u8)(0xff & (counter >> 24));
+                       IV[13] = (cc_u8)(0xff & (counter >> 16));
+                       IV[14] = (cc_u8)(0xff & (counter >> 8 ));
+                       IV[15] = (cc_u8)(0xff & (counter      ));
+                       memcpy(buf, in, BlockLen);
+                       SDRM_rijndaelEncrypt((const cc_u32*)(void*)key, 14, IV, out);
+                       break;
+               case ID_DES :
+                       BlockLen = 8;
+                       IV[4] = (cc_u8)(0xff & (counter >> 24));
+                       IV[5] = (cc_u8)(0xff & (counter >> 16));
+                       IV[6] = (cc_u8)(0xff & (counter >> 8 ));
+                       IV[7] = (cc_u8)(0xff & (counter      ));
+                       memcpy(buf, in, BlockLen);
+                       SDRM_DES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               case ID_TDES :
+                       BlockLen = 8;
+                       IV[4] = (cc_u8)(0xff & (counter >> 24));
+                       IV[5] = (cc_u8)(0xff & (counter >> 16));
+                       IV[6] = (cc_u8)(0xff & (counter >> 8 ));
+                       IV[7] = (cc_u8)(0xff & (counter      ));
+                       memcpy(buf, in, BlockLen);
+                       SDRM_TDES_Encryption((cc_u32(*)[2])(void*)key, IV, out);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       for (i = 0; i < BlockLen; i++)
+       {
+               out[i] ^= buf[i];
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/base/cc_pkcs1_v21.c b/ssflib/dep/cryptocore/source/base/cc_pkcs1_v21.c
new file mode 100755 (executable)
index 0000000..53f5845
--- /dev/null
@@ -0,0 +1,1068 @@
+/**
+ * \file       pkcs1_v21.c
+ * @brief      PKCS#1 V1.5, V2.0(RSAES-OAEP), V2.1(RSASSA-PSS) Implemetation
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/20
+ * Note : Edited for Big-Endian Machine support, 2008/12/16
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_pkcs1_v21.h"
+#include "cc_md5.h"
+#include "cc_sha1.h"
+#include "cc_sha2.h"
+#include "cc_ANSI_x931.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Functions
+//////////////////////////////////////////////////////////////////////////
+static int SDRM_MGF1(int HASH_Algorithm, cc_u8* mask, cc_u8* pbSeed, cc_u32 SeedLen, cc_u32 dMaskLen);
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+* @brief               RSAES PKCS#1 v1.5 enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+{
+       cc_u8 Si_ANSI_X9_31[SDRM_X931_SEED_SIZ];
+       cc_u32 i;
+
+       if (mLen > k - 11)
+       {
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+               EM[0] = 0x00;
+               EM[1] = 0x02;
+               
+               for (i = 0; i < 16; i++)
+               {
+                       Si_ANSI_X9_31[i] = ((rand()  << 16) + rand()) & 0xff;
+               }
+
+       srand(time(NULL));
+
+       SDRM_RNG_X931(Si_ANSI_X9_31, (k - mLen - 3) * 8, &EM[2]);
+
+       EM[k - mLen - 1] = 0x00;
+
+       for (i = 2; i < (k - mLen - 1); i++)
+       {
+               if (EM[i] == 0)
+               {
+                       EM[i--] = (cc_u8)(((rand()  << 16) + rand()) & 0xff);
+                       continue;
+               }
+       }
+
+       memcpy(EM + k - mLen, m, mLen);
+
+       memset(Si_ANSI_X9_31, 0x00, 16);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+* @brief               RSAES PKCS#1 v1.5 depadding
+*
+* @param       m                                               [out]Depadded msg
+* @param       mLen                                    [out]byte-size of m
+* @param       EM                                              [in]Enpadded msg
+* @param       emLen                                   [in]byte-size of EM
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_INVALID_ARGUMENT if enpadded message is out of RSA padding scheme
+*/
+int SDRM_Depad_Rsaes_pkcs15(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k)
+{
+       cc_u32 i;
+
+       if ((emLen == k) && (EM[0] == 0))
+       {
+               EM = EM + 1;
+               emLen = emLen - 1;
+       }
+
+       if ((emLen != k - 1) || (EM[0] != 0x02))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       EM = EM + 1;
+       emLen = emLen - 1;
+
+       for (i = 0; i < emLen; i++)
+       {
+               if (EM[i] == 0)
+               {
+                       break;
+               }
+       }
+
+       //i : length of PS
+       if ((i == emLen) || (i < 8))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       EM = EM + i + 1;
+       emLen = emLen - i - 1;
+
+       memmove(m, EM, emLen);
+
+       if (mLen != NULL)
+       {
+               *mLen = emLen;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_oaep(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k, int HASH_Algorithm)
+* @brief               RSAES OAEP enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsaes_oaep(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k, int HASH_Algorithm)
+{
+       cc_u8 Si_ANSI_X9_31[SDRM_X931_SEED_SIZ];
+       cc_u8 *DB, *seed, *dbMask, *maskedDB, *seedMask, *maskedSeed;
+       cc_u32 i, dbLen;
+       cc_u32 hLen = 0;
+
+       SDRM_MD5Context         md5_ctx;                                        //Hash env var
+       SDRM_SHA1Context        sha1_ctx;                                       //Hash env var
+       SDRM_SHA224Context      sha224_ctx;                                     //Hash env var
+       SDRM_SHA256Context      sha256_ctx;                                     //Hash env var
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      sha384_ctx;                                     //Hash env var
+       SDRM_SHA512Context      sha512_ctx;                                     //Hash env var
+#endif //_OP64_NOTSUPPORTED
+
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               hLen = SDRM_MD5_BLOCK_SIZ;
+               break;
+       case 0:
+       case ID_SHA1:
+               hLen = SDRM_SHA1_BLOCK_SIZ;
+               break;
+       case ID_SHA224 :
+               hLen = SDRM_SHA224_BLOCK_SIZ;
+               break;
+       case ID_SHA256:
+               hLen = SDRM_SHA256_BLOCK_SIZ;
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               hLen = SDRM_SHA384_BLOCK_SIZ;
+               break;
+       case ID_SHA512:
+               hLen = SDRM_SHA512_BLOCK_SIZ;
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       dbLen = k - hLen - 1;
+
+       //Memory allocation
+       DB = (cc_u8*)malloc(k * 2);
+       if (DB == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       maskedSeed = EM + 1;
+       maskedDB = maskedSeed + hLen;
+
+       dbMask = DB + dbLen;
+       seed = dbMask + dbLen;
+       seedMask = seed + hLen;
+
+       //Check message length
+       if (mLen > k - 2 * hLen - 2)
+       {
+               free(DB);
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+       //Get hash of 'L'
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               SDRM_MD5_Init(&md5_ctx);                                                                        //Init hash function
+               SDRM_MD5_Final(&md5_ctx, DB);                                                           //'L' is an empty string, so get output immediately
+               break;
+       case 0:
+       case ID_SHA1:
+               SDRM_SHA1_Init(&sha1_ctx);                                                                      //Init hash function
+               SDRM_SHA1_Final(&sha1_ctx, DB);                                                         //'L' is an empty string, so get output immediately
+               break;
+       case ID_SHA224 :
+               SDRM_SHA224_Init(&sha224_ctx);                                                          //Init hash function
+               SDRM_SHA224_Final(&sha224_ctx, DB);                                                     //'L' is an empty string, so get output immediately
+               break;
+       case ID_SHA256:
+               SDRM_SHA256_Init(&sha256_ctx);                                                          //Init hash function
+               SDRM_SHA256_Final(&sha256_ctx, DB);                                                     //'L' is an empty string, so get output immediately
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               SDRM_SHA384_Init(&sha384_ctx);                                                          //Init hash function
+               SDRM_SHA384_Final(&sha384_ctx, DB);                                                     //'L' is an empty string, so get output immediately
+               break;
+       case ID_SHA512:
+               SDRM_SHA512_Init(&sha512_ctx);                                                          //Init hash function
+               SDRM_SHA512_Final(&sha512_ctx, DB);                                                     //'L' is an empty string, so get output immediately
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+        free(DB);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       //DB = lHash||PS||M
+       memset(DB + hLen, 0x00, k - mLen - 2 * hLen - 2);
+       DB[dbLen - mLen - 1] = 0x01;
+       memcpy(DB + dbLen - mLen, m, mLen);
+
+       //Generate random seed
+       for (i = 0; i < 16; i++)
+       {
+               Si_ANSI_X9_31[i] = ((rand()  << 16) + rand()) & 0xff;
+       }
+
+       SDRM_RNG_X931(Si_ANSI_X9_31, hLen * 8, seed);
+
+       //dbMask = MGF(Seed, dbLen), maskedDB = DB ^ dbMask
+       SDRM_MGF1(HASH_Algorithm, dbMask, seed, hLen, dbLen);
+
+       for (i = 0; i < dbLen; i++)
+       {
+               maskedDB[i] = DB[i] ^ dbMask[i];
+       }
+
+       //seedMask = MGF(maskedDB, SDRM_SHA1_BLOCK_SIZ), maskedSeed = Seed ^ seedMask
+       SDRM_MGF1(HASH_Algorithm, seedMask, maskedDB, dbLen, hLen);
+
+       for (i = 0; i < hLen; i++)
+       {
+               maskedSeed[i] = seed[i] ^ seedMask[i];
+       }
+
+       //EM = 0x00||maskedSeed||maskedDB
+       EM[0] = 0x00;
+
+       memset(Si_ANSI_X9_31, 0x00, 16);
+       memset(DB, 0x00, k * 2);
+       free(DB);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+* @fn          int SDRM_Depad_Rsaes_oaep(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k, int HASH_Algorithm)
+* @brief               RSAES PKCS#1 v1.5 depadding
+*
+* @param       m                                               [out]Depadded msg
+* @param       mLen                                    [out]byte-size of m
+* @param       EM                                              [in]Enpadded msg
+* @param       emLen                                   [in]byte-size of EM
+* @param       k                                               [in]byte-size of n(RSA modulus)
+* @param       HASH_Algorithm                  [in]hash algorithm id
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_INVALID_ARGUMENT if enpadded message is out of RSA padding scheme
+*/
+int SDRM_Depad_Rsaes_oaep(cc_u8 *m, cc_u32* mLen, cc_u8 *EM, cc_u32 emLen, cc_u32 k, int HASH_Algorithm)
+{
+       cc_u8 *DB, *seed, *dbMask, *maskedDB, *seedMask, *maskedSeed;
+       cc_u8 hash[SDRM_SHA512_DATA_SIZE];
+       cc_u32 i, dbLen;
+       cc_u32 hLen = 0;
+
+       SDRM_MD5Context         md5_ctx;                                        //Hash env var
+       SDRM_SHA1Context        sha1_ctx;                                       //Hash env var
+       SDRM_SHA224Context      sha224_ctx;                                     //Hash env var
+       SDRM_SHA256Context      sha256_ctx;                             //Hash env var
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      sha384_ctx;                             //Hash env var
+       SDRM_SHA512Context      sha512_ctx;                             //Hash env var
+#endif //_OP64_NOTSUPPORTED
+
+       if ((emLen == k) && (EM[0] == 0))
+       {
+               EM = EM + 1;
+               emLen = emLen - 1;
+       }
+
+       if (emLen != k - 1)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+       /*
+       EM = EM + 1;
+       emLen = emLen - 1;
+       */
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               hLen = SDRM_MD5_BLOCK_SIZ;
+               break;
+       case 0:
+       case ID_SHA1:
+               hLen = SDRM_SHA1_BLOCK_SIZ;
+               break;
+       case ID_SHA224:
+               hLen = SDRM_SHA224_BLOCK_SIZ;
+               break;
+       case ID_SHA256:
+               hLen = SDRM_SHA256_BLOCK_SIZ;
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               hLen = SDRM_SHA384_BLOCK_SIZ;
+               break;
+       case ID_SHA512:
+               hLen = SDRM_SHA512_BLOCK_SIZ;
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       dbLen = k - hLen - 1;
+
+       //Memory allocation
+       DB = (cc_u8*)malloc(k * 2);
+       if (DB == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       maskedSeed = EM;
+       maskedDB = maskedSeed + hLen;
+
+       dbMask = DB + dbLen;
+       seed = dbMask + dbLen;
+       seedMask = seed + hLen;
+
+       //seedMask = MGF(maskedDB, SDRM_SHA1_BLOCK_SIZ), Seed = maskedSeed ^ seedMask
+       SDRM_MGF1(HASH_Algorithm, seedMask, maskedDB, dbLen, hLen);
+       for (i = 0; i < hLen; i++)
+       {
+               seed[i] = maskedSeed[i] ^ seedMask[i];
+       }
+
+       //dbMask = MGF(Seed, dbLen), DB = maskedDB ^ dbMask
+       SDRM_MGF1(HASH_Algorithm, dbMask, seed, hLen, dbLen);
+       for (i = 0; i < dbLen; i++)
+       {
+               DB[i] = maskedDB[i] ^ dbMask[i];
+       }
+
+       //Get hash of 'L'
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               SDRM_MD5_Init(&md5_ctx);                                                                        //Init hash function
+               SDRM_MD5_Final(&md5_ctx, hash);                                                         //'L' is an empty string, so get output immediately
+               break;
+       case 0:
+       case ID_SHA1:
+               SDRM_SHA1_Init(&sha1_ctx);                                                                      //Init hash function
+               SDRM_SHA1_Final(&sha1_ctx, hash);                                                       //'L' is an empty string, so get output immediately
+               break;
+       case ID_SHA224 :
+               SDRM_SHA224_Init(&sha224_ctx);                                                          //Init hash function
+               SDRM_SHA224_Final(&sha224_ctx, hash);                                           //'L' is an empty string, so get output immediately
+               break;
+       case ID_SHA256:
+               SDRM_SHA256_Init(&sha256_ctx);                                                          //Init hash function
+               SDRM_SHA256_Final(&sha256_ctx, hash);                                           //'L' is an empty string, so get output immediately
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               SDRM_SHA384_Init(&sha384_ctx);                                                          //Init hash function
+               SDRM_SHA384_Final(&sha384_ctx, hash);                                           //'L' is an empty string, so get output immediately
+               break;
+       case ID_SHA512:
+               SDRM_SHA512_Init(&sha512_ctx);                                                          //Init hash function
+               SDRM_SHA512_Final(&sha512_ctx, hash);                                           //'L' is an empty string, so get output immediately
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+        free(DB);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       //Compare hash value
+       for (i = 0; i < hLen; i++)
+       {
+               if (hash[i] != DB[i])
+               {
+                       free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+       }
+
+       //ignore 0x00s after hash(PS)
+       for (; i < dbLen; i++)
+       {
+               if (DB[i] != 0x00)
+               {
+                       break;
+               }
+       }
+
+       if ((i == dbLen) || (DB[i] != 0x01))
+       {
+               free(DB);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       memmove(m, DB + i + 1, dbLen - i - 1);
+
+       if (mLen != NULL)
+       {
+               *mLen = dbLen - i - 1;
+       }
+
+       memset(DB, 0x00, k * 2);
+       free(DB);
+
+       return CRYPTO_SUCCESS;
+}
+
+cc_u8 SDRM_DER_MD5[SDRM_DIGESTINFO_MD5_LEN] = SDRM_DIGESTINFO_MD5_VALUE;
+cc_u8 SDRM_DER_SHA1[SDRM_DIGESTINFO_SHA1_LEN] = SDRM_DIGESTINFO_SHA1_VALUE;
+cc_u8 SDRM_DER_SHA224[SDRM_DIGESTINFO_SHA224_LEN] = SDRM_DIGESTINFO_SHA224_VALUE;
+cc_u8 SDRM_DER_SHA256[SDRM_DIGESTINFO_SHA256_LEN] = SDRM_DIGESTINFO_SHA256_VALUE;
+cc_u8 SDRM_DER_SHA384[SDRM_DIGESTINFO_SHA384_LEN] = SDRM_DIGESTINFO_SHA384_VALUE;
+cc_u8 SDRM_DER_SHA512[SDRM_DIGESTINFO_SHA512_LEN] = SDRM_DIGESTINFO_SHA512_VALUE;
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+* @brief               RSAES PKCS#1 v1.5 enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_EMSA_PKCS1_v1_5_Encode(cc_u8 *EM, cc_u32 emLen, cc_u8 *h, cc_u32 hLen, int HASH_Algorithm)
+{
+       cc_u32 tLen;
+       cc_u32 DigestInfoLen = 0;
+       cc_u8 DER[32];
+
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               if (hLen != SDRM_MD5_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               DigestInfoLen = SDRM_DIGESTINFO_MD5_LEN;
+               memcpy(DER, SDRM_DER_MD5, SDRM_DIGESTINFO_MD5_LEN);
+               tLen = DigestInfoLen + SDRM_MD5_BLOCK_SIZ;
+               break;
+       case 0:
+       case ID_SHA1:
+               if (hLen != SDRM_SHA1_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               DigestInfoLen = SDRM_DIGESTINFO_SHA1_LEN;
+               memcpy(DER, SDRM_DER_SHA1, SDRM_DIGESTINFO_SHA1_LEN);
+               tLen = DigestInfoLen + SDRM_SHA1_BLOCK_SIZ;
+               break;
+       case ID_SHA224:
+               if (hLen != SDRM_SHA224_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               DigestInfoLen = SDRM_DIGESTINFO_SHA224_LEN;
+               memcpy(DER, SDRM_DER_SHA224, SDRM_DIGESTINFO_SHA224_LEN);
+               tLen = DigestInfoLen + SDRM_SHA224_BLOCK_SIZ;
+               break;
+       case ID_SHA256:
+               if (hLen != SDRM_SHA256_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               DigestInfoLen = SDRM_DIGESTINFO_SHA256_LEN;
+               memcpy(DER, SDRM_DER_SHA256, SDRM_DIGESTINFO_SHA256_LEN);
+               tLen = DigestInfoLen + SDRM_SHA256_BLOCK_SIZ;
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               if (hLen != SDRM_SHA384_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               DigestInfoLen = SDRM_DIGESTINFO_SHA384_LEN;
+               memcpy(DER, SDRM_DER_SHA384, SDRM_DIGESTINFO_SHA384_LEN);
+               tLen = DigestInfoLen + SDRM_SHA384_BLOCK_SIZ;
+               break;
+       case ID_SHA512:
+               if (hLen != SDRM_SHA512_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               DigestInfoLen = SDRM_DIGESTINFO_SHA512_LEN;
+               memcpy(DER, SDRM_DER_SHA512, SDRM_DIGESTINFO_SHA512_LEN);
+               tLen = DigestInfoLen + SDRM_SHA512_BLOCK_SIZ;
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (emLen < tLen + 11)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       EM[0] = 0x00;
+       EM[1] = 0x01;
+       memset(EM + 2, 0xff, emLen - tLen - 3);
+       EM[emLen - tLen - 1] = 0x00;
+
+       memcpy(EM + emLen - tLen, DER, DigestInfoLen);
+       memcpy(EM + emLen - hLen, h, hLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+* @fn          int SDRM_Enpad_Rsaes_pkcs15(cc_u8 *EM, cc_u8 *m, cc_u32 mLen, cc_u32 k)
+* @brief               RSAES PKCS#1 v1.5 enpadding
+*
+* @param       EM                                              [out]Enpadded msg
+* @param       m                                               [in]Message to pad
+* @param       mLen                                    [in]byte-size of m
+* @param       k                                               [in]byte-size of n(RSA modulus)
+*
+* @return      CRYPTO_SUCCESS                  if no error is occured
+* \n           CRYPTO_MSG_TOO_LONG             if message is longer then key
+*/
+int SDRM_Enpad_Rsassa_pkcs15(cc_u8 *EM, cc_u32 emLen, cc_u8 *h, cc_u32 hLen, int HASH_Algorithm)
+{
+       return SDRM_EMSA_PKCS1_v1_5_Encode(EM, emLen, h, hLen, HASH_Algorithm);
+}
+
+int SDRM_Depad_Rsassa_pkcs15(cc_u8 *EM, cc_u32 emLen, cc_u8 *h, cc_u32 hLen, int HASH_Algorithm)
+{
+       int ret;
+       cc_u8* EM_;
+       cc_u32 em_Len;
+
+       if (EM[0] == 0x00)
+       {
+               EM = EM + 1;
+               emLen = emLen - 1;
+       }
+
+       if (EM[0] != 0x01)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       em_Len = emLen + 1;
+       EM_ = (cc_u8*)malloc(em_Len);
+       if (EM_ == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       ret = SDRM_EMSA_PKCS1_v1_5_Encode(EM_, em_Len, h, hLen, HASH_Algorithm);
+       if (ret != CRYPTO_SUCCESS)
+       {
+               free(EM_);
+               return ret;
+       }
+
+       if (memcmp(EM_ + 1, EM, emLen) == 0)
+       {
+               ret = CRYPTO_VALID_SIGN;
+       }
+       else
+       {
+               ret = CRYPTO_INVALID_SIGN;
+       }
+
+       memset(EM_, 0x00, em_Len);
+       free(EM_);
+
+       return ret;
+
+}
+
+int SDRM_Enpad_Rsassa_pss(cc_u8 *EM, cc_u32 nBits, cc_u8 *h, cc_u32 hLen, cc_u32 k, int HASH_Algorithm)
+{
+       cc_u8 Si_ANSI_X9_31[SDRM_X931_SEED_SIZ];
+       cc_u8 salt[64];
+       cc_u8 eight_zeros[8] = { 0 };
+       cc_u32 sLen = hLen;
+       cc_u32 msBits = (nBits - 1) & 0x07;
+       cc_u32 emLen = k;
+       cc_u32 dbLen;
+       cc_u32 i;
+
+       SDRM_MD5Context         md5_ctx;                                        //Hash env var
+       SDRM_SHA1Context        sha1_ctx;                                       //Hash env var
+       SDRM_SHA224Context      sha224_ctx;                                     //Hash env var
+       SDRM_SHA256Context      sha256_ctx;                             //Hash env var
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      sha384_ctx;                             //Hash env var
+       SDRM_SHA512Context      sha512_ctx;                             //Hash env var
+#endif //_OP64_NOTSUPPORTED
+
+       if (msBits == 0)
+       {
+               EM[0] = 0;
+               EM = EM + 1;
+               emLen = emLen - 1;
+       }
+
+       if (emLen < hLen + sLen + 2)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       dbLen = emLen - hLen - 1;
+
+       for (i = 0; i < 16; i++)
+       {
+               Si_ANSI_X9_31[i] = ((rand()  << 16) + rand()) & 0xff;
+       }
+
+       SDRM_RNG_X931(Si_ANSI_X9_31, sLen * 8, salt);
+
+       //Get Hash of M'
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               if (hLen != SDRM_MD5_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_MD5_Init(&md5_ctx);                                                                        //Init hash function
+               SDRM_MD5_Update(&md5_ctx, eight_zeros, 8);                                      //Input data
+               SDRM_MD5_Update(&md5_ctx, h, hLen);
+               SDRM_MD5_Update(&md5_ctx, salt, sLen);
+               SDRM_MD5_Final(&md5_ctx, EM + dbLen);                                           //Get Output
+               break;
+       case 0:
+       case ID_SHA1:
+               if (hLen != SDRM_SHA1_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA1_Init(&sha1_ctx);                                                                      //Init hash function
+               SDRM_SHA1_Update(&sha1_ctx, eight_zeros, 8);                            //Input data
+               SDRM_SHA1_Update(&sha1_ctx, h, hLen);
+               SDRM_SHA1_Update(&sha1_ctx, salt, sLen);
+               SDRM_SHA1_Final(&sha1_ctx, EM + dbLen);                                         //Get Output
+               break;
+       case ID_SHA224:
+               if (hLen != SDRM_SHA224_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA224_Init(&sha224_ctx);                                                          //Init hash function
+               SDRM_SHA224_Update(&sha224_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA224_Update(&sha224_ctx, h, hLen);
+               SDRM_SHA224_Update(&sha224_ctx, salt, sLen);
+               SDRM_SHA224_Final(&sha224_ctx, EM + dbLen);                                     //Get Output
+               break;
+       case ID_SHA256:
+               if (hLen != SDRM_SHA256_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA256_Init(&sha256_ctx);                                                          //Init hash function
+               SDRM_SHA256_Update(&sha256_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA256_Update(&sha256_ctx, h, hLen);
+               SDRM_SHA256_Update(&sha256_ctx, salt, sLen);
+               SDRM_SHA256_Final(&sha256_ctx, EM + dbLen);                                     //Get Output
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               if (hLen != SDRM_SHA384_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA384_Init(&sha384_ctx);                                                          //Init hash function
+               SDRM_SHA384_Update(&sha384_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA384_Update(&sha384_ctx, h, hLen);
+               SDRM_SHA384_Update(&sha384_ctx, salt, sLen);
+               SDRM_SHA384_Final(&sha384_ctx, EM + dbLen);                                     //Get Output
+               break;
+       case ID_SHA512:
+               if (hLen != SDRM_SHA512_BLOCK_SIZ)
+               {
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA512_Init(&sha512_ctx);                                                          //Init hash function
+               SDRM_SHA512_Update(&sha512_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA512_Update(&sha512_ctx, h, hLen);
+               SDRM_SHA512_Update(&sha512_ctx, salt, sLen);
+               SDRM_SHA512_Final(&sha512_ctx, EM + dbLen);                                     //Get Output
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       SDRM_MGF1(HASH_Algorithm, EM, EM + dbLen, hLen, dbLen);
+       EM[emLen - sLen - hLen - 2] ^= 0x01;
+
+
+       //memset(EM, 0x00, emLen - sLen - hLen - 2);
+       for (i = 0; i < sLen; i++)
+       {
+               EM[emLen - sLen - hLen - 1 + i] ^= salt[i];
+       }
+
+       if (msBits != 0)
+       {
+               EM[0] &= (0xff >> (8 - msBits));
+       }
+
+       EM[emLen - 1] = 0xbc;
+
+       memset(Si_ANSI_X9_31, 0, 16);
+       memset(salt, 0, 64);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+int SDRM_Depad_Rsassa_pss(cc_u8 *EM, cc_u32 nBits, cc_u8 *h, cc_u32 hLen, cc_u32 k, int HASH_Algorithm)
+{
+       cc_u8* DB;
+       cc_u8 eight_zeros[8] = { 0 };
+       cc_u32 msBits = (nBits - 1) & 0x07;
+       cc_u32 emLen = k;
+       cc_u32 sLen;
+       cc_u32 dbLen;
+       cc_u32 i;
+       cc_u8 hash[64] = {0};
+
+       SDRM_MD5Context         md5_ctx;                                        //Hash env var
+       SDRM_SHA1Context        sha1_ctx;                                       //Hash env var
+       SDRM_SHA224Context      sha224_ctx;                                     //Hash env var
+       SDRM_SHA256Context      sha256_ctx;                                     //Hash env var
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      sha384_ctx;                                     //Hash env var
+       SDRM_SHA512Context      sha512_ctx;                                     //Hash env var
+#endif //_OP64_NOTSUPPORTED
+
+       if (EM[0] & (0xff << msBits))
+       {
+               return CRYPTO_INVALID_SIGN;
+       }
+
+       if (msBits == 0)
+       {
+               EM = EM + 1;
+               emLen = emLen - 1;
+       }
+
+       if (EM[emLen - 1] != 0xbc)
+       {
+               return CRYPTO_INVALID_SIGN;
+       }
+
+       dbLen = emLen - hLen - 1;
+       DB = (cc_u8*)malloc(dbLen);
+       if (DB == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_MGF1(HASH_Algorithm, DB, EM + dbLen, hLen, dbLen);
+
+       for (i = 0; i < dbLen; i++)
+       {
+               DB[i] = DB[i] ^ EM[i];
+       }
+
+       if (msBits)
+       {
+               DB[0] &= (0xff >> (8 - msBits));
+       }
+
+       for (i = 0; i < dbLen; i++)
+       {
+               if (DB[i] != 0)
+               {
+                       break;
+               }
+       }
+
+       if ((i == dbLen) || (DB[i] != 0x01))
+       {
+               free(DB);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       sLen = dbLen - i - 1;
+
+       //Get Hash of M'
+       switch (HASH_Algorithm)
+       {
+       case ID_MD5:
+               if (hLen != SDRM_MD5_BLOCK_SIZ)
+               {
+            free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_MD5_Init(&md5_ctx);                                                                        //Init hash function
+               SDRM_MD5_Update(&md5_ctx, eight_zeros, 8);                                      //Input data
+               SDRM_MD5_Update(&md5_ctx, h, hLen);
+               SDRM_MD5_Update(&md5_ctx, DB + i + 1, sLen);
+               SDRM_MD5_Final(&md5_ctx, hash);                                                         //Get Output
+               break;
+       case 0:
+       case ID_SHA1:
+               if (hLen != SDRM_SHA1_BLOCK_SIZ)
+               {
+            free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA1_Init(&sha1_ctx);                                                                      //Init hash function
+               SDRM_SHA1_Update(&sha1_ctx, eight_zeros, 8);                            //Input data
+               SDRM_SHA1_Update(&sha1_ctx, h, hLen);
+               SDRM_SHA1_Update(&sha1_ctx, DB + i + 1, sLen);
+               SDRM_SHA1_Final(&sha1_ctx, hash);                                                       //Get Output
+               break;
+       case ID_SHA224:
+               if (hLen != SDRM_SHA224_BLOCK_SIZ)
+               {
+            free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA224_Init(&sha224_ctx);                                                          //Init hash function
+               SDRM_SHA224_Update(&sha224_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA224_Update(&sha224_ctx, h, hLen);
+               SDRM_SHA224_Update(&sha224_ctx, DB + i + 1, sLen);
+               SDRM_SHA224_Final(&sha224_ctx, hash);                                           //Get Output
+               break;
+       case ID_SHA256:
+               if (hLen != SDRM_SHA256_BLOCK_SIZ)
+               {
+            free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA256_Init(&sha256_ctx);                                                          //Init hash function
+               SDRM_SHA256_Update(&sha256_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA256_Update(&sha256_ctx, h, hLen);
+               SDRM_SHA256_Update(&sha256_ctx, DB + i + 1, sLen);
+               SDRM_SHA256_Final(&sha256_ctx, hash);                                           //Get Output
+               break;
+#ifndef _OP64_NOTSUPPORTED
+       case ID_SHA384:
+               if (hLen != SDRM_SHA384_BLOCK_SIZ)
+               {
+            free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA384_Init(&sha384_ctx);                                                          //Init hash function
+               SDRM_SHA384_Update(&sha384_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA384_Update(&sha384_ctx, h, hLen);
+               SDRM_SHA384_Update(&sha384_ctx, DB + i + 1, sLen);
+               SDRM_SHA384_Final(&sha384_ctx, hash);                                           //Get Output
+               break;
+       case ID_SHA512:
+               if (hLen != SDRM_SHA512_BLOCK_SIZ)
+               {
+            free(DB);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+               SDRM_SHA512_Init(&sha512_ctx);                                                          //Init hash function
+               SDRM_SHA512_Update(&sha512_ctx, eight_zeros, 8);                        //Input data
+               SDRM_SHA512_Update(&sha512_ctx, h, hLen);
+               SDRM_SHA512_Update(&sha512_ctx, DB + i + 1, sLen);
+               SDRM_SHA512_Final(&sha512_ctx, hash);                                           //Get Output
+               break;
+#endif //_OP64_NOTSUPPORTED
+       default:
+               free(DB);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       memset(DB, 0x00, dbLen);
+       free(DB);
+
+       if (memcmp(hash, EM + dbLen, hLen) == 0)
+       {
+               return CRYPTO_VALID_SIGN;
+       }
+       else
+       {
+               return CRYPTO_INVALID_SIGN;
+       }
+}
+
+/*
+ * @fn         int SDRM_MGF1(int HASH_Algorithm, cc_u8* mask, cc_u8* pbSeed, cc_u32 SeedLen, cc_u32 dMaskLen)
+ * @brief      SDRM_MGF1 Function (Mask Generation Function based on a hash function)
+ *
+ * @param      mask                                    [out]byte-length of generated mask
+ * @param      pbSeed                                  [in]seed for MGF
+ * @param      SeedLen                                 [in]byte-length of pbSeed
+ * @param      dMaskLen                                [in]byte-length of mask
+ *
+ * @return     CRYPTO_SUCCESS                  if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if malloc is failed
+ */
+static int SDRM_MGF1(int HASH_Algorithm, cc_u8* mask, cc_u8* pbSeed, cc_u32 SeedLen, cc_u32 dMaskLen)
+{
+       cc_u8                    *T, *Seed, *pbBuf;
+       cc_u32                   counter;
+       cc_u8                    hash[64];                                              //SHA-1 output size is 160 bit
+       cc_u8                    hashlen;
+       SDRM_MD5Context md5_ctx;                                                //Hash env var
+       SDRM_SHA1Context sha1_ctx;                                              //Hash env var
+       SDRM_SHA224Context sha224_ctx;                                  //Hash env var
+       SDRM_SHA256Context sha256_ctx;                                  //Hash env var
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context sha384_ctx;                                  //Hash env var
+       SDRM_SHA512Context sha512_ctx;                                  //Hash env var
+#endif //_OP64_NOTSUPPORTED
+
+       switch(HASH_Algorithm)
+       {
+               case ID_MD5 :
+                       hashlen = SDRM_MD5_BLOCK_SIZ;
+                       break;
+               case 0 :
+               case ID_SHA1 :
+                       hashlen = SDRM_SHA1_BLOCK_SIZ;
+                       break;
+               case ID_SHA224 :
+                       hashlen = SDRM_SHA224_BLOCK_SIZ;
+                       break;
+               case ID_SHA256 :
+                       hashlen = SDRM_SHA256_BLOCK_SIZ;
+                       break;
+#ifndef _OP64_NOTSUPPORTED
+               case ID_SHA384 :
+                       hashlen = SDRM_SHA384_BLOCK_SIZ;
+                       break;
+               case ID_SHA512 :
+                       hashlen = SDRM_SHA512_BLOCK_SIZ;
+                       break;
+#endif //_OP64_NOTSUPPORTED
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       pbBuf = (cc_u8*)malloc(dMaskLen + hashlen + SeedLen + 4);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       T = pbBuf;
+       Seed = T + dMaskLen + hashlen;
+
+       memset(mask, 0, dMaskLen);
+       memcpy(Seed, pbSeed, SeedLen);
+
+       for (counter = 0; counter < (dMaskLen - 1) / hashlen + 1; counter++)
+       {
+               Seed[SeedLen    ] = (cc_u8)(counter >> 24);
+               Seed[SeedLen + 1] = (cc_u8)(counter >> 16);
+               Seed[SeedLen + 2] = (cc_u8)(counter >> 8 );
+               Seed[SeedLen + 3] = (cc_u8)(counter      );
+
+               //Hash(Seed||counter)
+               switch(HASH_Algorithm)
+               {
+                       case ID_MD5 :
+                               SDRM_MD5_Init(&md5_ctx);                                                //Init hash function
+                               SDRM_MD5_Update(&md5_ctx, Seed, SeedLen + 4);   //Input data
+                               SDRM_MD5_Final(&md5_ctx, hash);                                 //Get Output
+                               break;
+                       case 0 :
+                       case ID_SHA1 :
+                               SDRM_SHA1_Init(&sha1_ctx);                                              //Init hash function
+                               SDRM_SHA1_Update(&sha1_ctx, Seed, SeedLen + 4); //Input data
+                               SDRM_SHA1_Final(&sha1_ctx, hash);                               //Get Output
+                               break;
+                       case ID_SHA224 :
+                               SDRM_SHA224_Init(&sha224_ctx);                                          //Init hash function
+                               SDRM_SHA224_Update(&sha224_ctx, Seed, SeedLen + 4);     //Input data
+                               SDRM_SHA224_Final(&sha224_ctx, hash);                           //Get Output
+                               break;
+                       case ID_SHA256 :
+                               SDRM_SHA256_Init(&sha256_ctx);                                          //Init hash function
+                               SDRM_SHA256_Update(&sha256_ctx, Seed, SeedLen + 4);     //Input data
+                               SDRM_SHA256_Final(&sha256_ctx, hash);                           //Get Output
+                               break;
+#ifndef _OP64_NOTSUPPORTED     
+                       case ID_SHA384 :
+                               SDRM_SHA384_Init(&sha384_ctx);                                          //Init hash function
+                               SDRM_SHA384_Update(&sha384_ctx, Seed, SeedLen + 4);     //Input data
+                               SDRM_SHA384_Final(&sha384_ctx, hash);                           //Get Output
+                               break;
+                       case ID_SHA512 :
+                               SDRM_SHA512_Init(&sha512_ctx);                                          //Init hash function
+                               SDRM_SHA512_Update(&sha512_ctx, Seed, SeedLen + 4);     //Input data
+                               SDRM_SHA512_Final(&sha512_ctx, hash);                           //Get Output
+                               break;
+#endif //_OP64_NOTSUPPORTED
+                       default :
+                               free(pbBuf);
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               memcpy(T + counter * hashlen, hash, hashlen);
+       }
+
+       memcpy(mask, T, dMaskLen);
+       memset(pbBuf, 0x00, dMaskLen + hashlen + SeedLen + 4);
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/base/cc_rc4.c b/ssflib/dep/cryptocore/source/base/cc_rc4.c
new file mode 100755 (executable)
index 0000000..6db4ea7
--- /dev/null
@@ -0,0 +1,161 @@
+/**
+ * \file       rc4.c
+ * @brief      implementation of RC4 encryption scheme
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/01
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_rc4.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// initial vector of s
+////////////////////////////////////////////////////////////////////////////
+static cc_u32 RC4_S_VALUE_LITTLE[] = {
+       0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
+       0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
+       0x23222120, 0x27262524, 0x2b2a2928, 0x2f2e2d2c,
+       0x33323130, 0x37363534, 0x3b3a3938, 0x3f3e3d3c,
+       0x43424140, 0x47464544, 0x4b4a4948, 0x4f4e4d4c,
+       0x53525150, 0x57565554, 0x5b5a5958, 0x5f5e5d5c,
+       0x63626160, 0x67666564, 0x6b6a6968, 0x6f6e6d6c,
+       0x73727170, 0x77767574, 0x7b7a7978, 0x7f7e7d7c,
+       0x83828180, 0x87868584, 0x8b8a8988, 0x8f8e8d8c,
+       0x93929190, 0x97969594, 0x9b9a9998, 0x9f9e9d9c,
+       0xa3a2a1a0, 0xa7a6a5a4, 0xabaaa9a8, 0xafaeadac,
+       0xb3b2b1b0, 0xb7b6b5b4, 0xbbbab9b8, 0xbfbebdbc,
+       0xc3c2c1c0, 0xc7c6c5c4, 0xcbcac9c8, 0xcfcecdcc,
+       0xd3d2d1d0, 0xd7d6d5d4, 0xdbdad9d8, 0xdfdedddc,
+       0xe3e2e1e0, 0xe7e6e5e4, 0xebeae9e8, 0xefeeedec,
+       0xf3f2f1f0, 0xf7f6f5f4, 0xfbfaf9f8, 0xfffefdfc,
+};
+
+static cc_u32 RC4_S_VALUE_BIG[] = {
+       0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f,
+       0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f,
+       0x20212223, 0x24252627, 0x28292a2b, 0x2c2d2e2f,
+       0x30313233, 0x34353637, 0x38393a3b, 0x3c3d3e3f,
+       0x40414243, 0x44454647, 0x48494a4b, 0x4c4d4e4f,
+       0x50515253, 0x54555657, 0x58595a5b, 0x5c5d5e5f,
+       0x60616263, 0x64656667, 0x68696a6b, 0x6c6d6e6f,
+       0x70717273, 0x74757677, 0x78797a7b, 0x7c7d7e7f,
+       0x80818283, 0x84858687, 0x88898a8b, 0x8c8d8e8f,
+       0x90919293, 0x94959697, 0x98999a9b, 0x9c9d9e9f,
+       0xa0a1a2a3, 0xa4a5a6a7, 0xa8a9aaab, 0xacadaeaf,
+       0xb0b1b2b3, 0xb4b5b6b7, 0xb8b9babb, 0xbcbdbebf,
+       0xc0c1c2c3, 0xc4c5c6c7, 0xc8c9cacb, 0xcccdcecf,
+       0xd0d1d2d3, 0xd4d5d6d7, 0xd8d9dadb, 0xdcdddedf,
+       0xe0e1e2e3, 0xe4e5e6e7, 0xe8e9eaeb, 0xecedeeef,
+       0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff
+};
+
+/*
+ * @fn         SDRM_RC4_Setup
+ * @brief      intialize s
+ *
+ * @param      ctx                                     [in]crypto context
+ * @param      UserKey                         [in]user key
+ * @param      keyLen                          [out]byte-length of UserKey
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_RC4_Setup(SDRM_RC4Context *ctx, cc_u8 *UserKey, cc_u32 keyLen)
+{
+       cc_u32  i, j, loc = keyLen;
+       cc_u8   temp;
+
+       //initialization
+       i = 0xff;
+       if (((cc_u8*)&i)[0] == 0xff)
+       {
+//             LOG4DRM_INFO(&CryptoLogCTX), "is Little Endian machine\n");
+               memcpy(ctx->s, RC4_S_VALUE_LITTLE, 256);
+       }
+       else
+       {
+//             LOG4DRM_INFO(&CryptoLogCTX), "is Big Endian machine\n");
+               memcpy(ctx->s, RC4_S_VALUE_BIG, 256);
+       }
+       
+       memcpy(ctx->key, UserKey, keyLen);
+
+       ctx->keyLen = keyLen;
+       ctx->i = 0;
+       ctx->j = 0;
+
+       //scrambling
+       if ((keyLen == 16) || (keyLen == 32))
+       {
+               loc--;
+               for (i = 0, j = 0; i < 256; ++i)
+               {
+                       j= (j + ctx->key[i & loc] + ctx->s[i]) & 0xff;
+                       temp = ctx->s[i];
+                       ctx->s[i] = ctx->s[j];
+                       ctx->s[j] = temp;
+               }
+       }
+       else
+       {
+               for (i = 0, j = 0; i < 256; ++i)
+               {
+                       j = (j + ctx->key[i % ctx->keyLen] + ctx->s[i]) & 0xff;
+                       temp = ctx->s[i];
+                       ctx->s[i] = ctx->s[j];
+                       ctx->s[j] = temp;
+               }
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_RC4_PRNG
+ * @brief      process stream data
+ *
+ * @param      ctx                                     [in]crypto context
+ * @param      in                                      [in]plaintext
+ * @param      inLen                           [in]byte-length of in
+ * @param      out                                     [out]cipher text
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_RC4_PRNG(SDRM_RC4Context *ctx, cc_u8 *in, cc_u32 inLen, cc_u8 *out)
+{
+       cc_u32  i, j, k;
+       cc_u8   temp;
+       
+       i = ctx->i;
+       j = ctx->j;
+
+       for (k = 0; k < inLen; k++)
+       {
+               i++;
+               i &= 0xff;
+               j += ctx->s[i];
+               j &= 0xff;
+
+               temp = ctx->s[i];
+               ctx->s[i] = ctx->s[j];
+               ctx->s[j] = temp;
+
+               temp = ctx->s[i] + ctx->s[j];
+
+               out[k] = in[k]^(ctx->s[temp]);
+       }
+
+       ctx->i = i;
+       ctx->j = j;
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/base/cc_sha1.c b/ssflib/dep/cryptocore/source/base/cc_sha1.c
new file mode 100755 (executable)
index 0000000..be9dd2a
--- /dev/null
@@ -0,0 +1,477 @@
+/* For torrentcheck.c, main() commented out */
+/* sha1.c : Implementation of the Secure Hash Algorithm */
+
+/* SHA: NIST's Secure Hash Algorithm */
+
+/*     This version written November 2000 by David Ireland of 
+       DI Management Services Pty Limited <code@di-mgt.com.au>
+
+       Adapted from code in the Python Cryptography Toolkit, 
+       version 1.0.0 by A.M. Kuchling 1995.
+*/
+
+/* AM Kuchling's posting:- 
+   Based on SHA code originally posted to sci.crypt by Peter Gutmann
+   in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
+   Modified to test for endianness on creation of SHA objects by AMK.
+   Also, the original specification of SHA was found to have a weakness
+   by NSA/NIST.  This code implements the fixed version of SHA.
+*/
+
+/* Here's the first paragraph of Peter Gutmann's posting:
+   
+The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
+SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
+what's changed in the new version.  The fix is a simple change which involves
+adding a single rotate in the initial expansion function.  It is unknown
+whether this is an optimal solution to the problem which was discovered in the
+SHA or whether it's simply a bandaid which fixes the problem with a minimum of
+effort (for example the reengineering of a great many Capstone chips).
+*/
+
+/* JS Park's posting:
+       Modification for naming confilct.
+        - Attach prefix 'SDRM_SHA1_' for all function and constants.
+        - Change name of data context to 'SDRM_SHA1Context'
+       endianTest code is modified to avoid gcc warning.
+       Primitive data types are used, instead of user-defined data types.
+       Prototypes are moved to header file.
+       Not using functions are commented out.
+ */
+
+
+void SDRM_endianTest(int *endianness);
+
+/* sha.c */
+
+#include "cc_sha1.h"
+
+static void SDRM_SHAtoByte(unsigned char *output, unsigned int *input, unsigned int len);
+
+/* The SHS block size and message digest sizes, in bytes */
+
+#define SDRM_SHA1_DATASIZE    64
+#define SDRM_SHA1_DIGESTSIZE  20
+
+
+/* The SHS f()-functions.  The f1 and f3 functions can be optimized to
+   save one boolean operation each - thanks to Rich Schroeppel,
+   rcs@cs.arizona.edu for discovering this */
+
+/*#define SDRM_SHA1_f1(x,y,z) ((x & y) | (~x & z))                          // Rounds  0-19 */
+#define SDRM_SHA1_f1(x,y,z)   ((z) ^ ((x) & ((y) ^ (z))))                               /* Rounds  0-19 */
+#define SDRM_SHA1_f2(x,y,z)   ((x) ^ (y) ^ (z))                                                 /* Rounds 20-39 */
+/*#define SDRM_SHA1_f3(x,y,z) ((x & y) | (x & z) | (y & z))             // Rounds 40-59 */
+#define SDRM_SHA1_f3(x,y,z)   (((x) & (y)) | ((z) & ((x) | (y))))                       /* Rounds 40-59 */
+#define SDRM_SHA1_f4(x,y,z)   ((x) ^ (y) ^ (z))                                                 /* Rounds 60-79 */
+
+/* The SHS Mysterious Constants */
+
+#define SDRM_SHA1_K1  0x5A827999L                                 /* Rounds  0-19 */
+#define SDRM_SHA1_K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
+#define SDRM_SHA1_K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
+#define SDRM_SHA1_K4  0xCA62C1D6L                                 /* Rounds 60-79 */
+
+/* SHS initial values */
+
+#define SDRM_SHA1_h0init  0x67452301L
+#define SDRM_SHA1_h1init  0xEFCDAB89L
+#define SDRM_SHA1_h2init  0x98BADCFEL
+#define SDRM_SHA1_h3init  0x10325476L
+#define SDRM_SHA1_h4init  0xC3D2E1F0L
+
+/* Note that it may be necessary to add parentheses to these macros if they
+   are to be called with expressions as arguments */
+/* 32-bit rotate left - kludged with shifts */
+
+#define SDRM_SHA1_ROTL(n, X)  (((X) << (n)) | ((X) >> (32 - (n))))
+
+/* The initial expanding function.  The hash function is defined over an
+   80-UINT2 expanded input array W, where the first 16 are copies of the input
+   data, and the remaining 64 are defined by
+
+        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+   This implementation generates these values on the fly in a circular
+   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+   optimization.
+
+   The updated SHS changes the expanding function by adding a rotate of 1
+   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+   for this information */
+
+#define SDRM_SHA1_expand(W, i) (W[(i) & 15] = SDRM_SHA1_ROTL(1, (W[(i) & 15] ^ W[((i) - 14) & 15] ^ \
+                                                 W[((i) - 8) & 15] ^ W[((i) - 3) & 15])))
+
+
+/* The prototype SHS sub-round.  The fundamental sub-round is:
+
+        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+        b' = a;
+        c' = ROTL( 30, b );
+        d' = c;
+        e' = d;
+
+   but this is implemented by unrolling the loop 5 times and renaming the
+   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+   This code is then replicated 20 times for each of the 4 functions, using
+   the next 20 values from the W[] array each time */
+
+#define SDRM_SHA1_subRound(a, b, c, d, e, f, k, data) \
+    (e += SDRM_SHA1_ROTL(5, a) + f(b, c, d) + (k) + (data), b = SDRM_SHA1_ROTL(30, b))
+
+/* Initialize the SHS values */
+
+void SDRM_SHA1_Init(SDRM_SHA1Context  *shsInfo)
+{
+    SDRM_endianTest(&shsInfo->Endianness);
+    /* Set the h-vars to their initial values */
+    shsInfo->digest[ 0 ] = SDRM_SHA1_h0init;
+    shsInfo->digest[ 1 ] = SDRM_SHA1_h1init;
+    shsInfo->digest[ 2 ] = SDRM_SHA1_h2init;
+    shsInfo->digest[ 3 ] = SDRM_SHA1_h3init;
+    shsInfo->digest[ 4 ] = SDRM_SHA1_h4init;
+
+    /* Initialise bit count */
+    shsInfo->countLo = shsInfo->countHi = 0;
+}
+
+
+/* Perform the SHS transformation.  Note that this code, like MD5, seems to
+   break some optimizing compilers due to the complexity of the expressions
+   and the size of the basic block.  It may be necessary to split it into
+   sections, e.g. based on the four subrounds
+
+   Note that this corrupts the shsInfo->data area */
+
+static void SDRM_SHSTransform(unsigned int *digest, unsigned int *data )
+    {
+    unsigned int A, B, C, D, E;     /* Local vars */
+    unsigned int eData[ 16 ];       /* Expanded data */
+
+    /* Set up first buffer and local data buffer */
+    A = digest[ 0 ];
+    B = digest[ 1 ];
+    C = digest[ 2 ];
+    D = digest[ 3 ];
+    E = digest[ 4 ];
+    memcpy( (unsigned char*)eData, (unsigned char*)data, SDRM_SHA1_DATASIZE );
+
+    /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  0 ] );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  1 ] );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  2 ] );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  3 ] );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  4 ] );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  5 ] );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  6 ] );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  7 ] );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  8 ] );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[  9 ] );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[ 10 ] );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[ 11 ] );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[ 12 ] );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[ 13 ] );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[ 14 ] );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f1, SDRM_SHA1_K1, eData[ 15 ] );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f1, SDRM_SHA1_K1, SDRM_SHA1_expand( eData, 16 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f1, SDRM_SHA1_K1, SDRM_SHA1_expand( eData, 17 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f1, SDRM_SHA1_K1, SDRM_SHA1_expand( eData, 18 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f1, SDRM_SHA1_K1, SDRM_SHA1_expand( eData, 19 ) );
+
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 20 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 21 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 22 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 23 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 24 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 25 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 26 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 27 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 28 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 29 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 30 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 31 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 32 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 33 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 34 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 35 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 36 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 37 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 38 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f2, SDRM_SHA1_K2, SDRM_SHA1_expand( eData, 39 ) );
+
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 40 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 41 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 42 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 43 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 44 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 45 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 46 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 47 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 48 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 49 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 50 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 51 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 52 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 53 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 54 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 55 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 56 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 57 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 58 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f3, SDRM_SHA1_K3, SDRM_SHA1_expand( eData, 59 ) );
+
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 60 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 61 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 62 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 63 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 64 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 65 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 66 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 67 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 68 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 69 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 70 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 71 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 72 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 73 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 74 ) );
+    SDRM_SHA1_subRound( A, B, C, D, E, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 75 ) );
+    SDRM_SHA1_subRound( E, A, B, C, D, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 76 ) );
+    SDRM_SHA1_subRound( D, E, A, B, C, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 77 ) );
+    SDRM_SHA1_subRound( C, D, E, A, B, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 78 ) );
+    SDRM_SHA1_subRound( B, C, D, E, A, SDRM_SHA1_f4, SDRM_SHA1_K4, SDRM_SHA1_expand( eData, 79 ) );
+
+    /* Build message digest */
+    digest[ 0 ] += A;
+    digest[ 1 ] += B;
+    digest[ 2 ] += C;
+    digest[ 3 ] += D;
+    digest[ 4 ] += E;
+    }
+
+/* When run on a little-endian CPU we need to perform byte reversal on an
+   array of long words. */
+
+static void SDRM_longReverse(unsigned int *buffer, int byteCount, int Endianness)
+{
+    unsigned int value;
+
+       if (Endianness == !(0)) {
+               return;
+       }
+    byteCount /= sizeof( unsigned int );
+    while(byteCount--)
+    {
+        value = *buffer;
+        value = ((value & 0xFF00FF00L) >> 8) | \
+                ((value & 0x00FF00FFL ) << 8);
+         *buffer++ = (value << 16) | (value >> 16);
+       }
+}
+
+/* Update SHS for a block of data */
+
+void SDRM_SHA1_Update(SDRM_SHA1Context  *shsInfo, const unsigned char *buffer, int count)
+{
+    unsigned int       tmp;
+    int                dataCount;
+
+    /* Update bitcount */
+    tmp = shsInfo->countLo;
+       if ((shsInfo->countLo = tmp + ((unsigned int)count << 3)) < tmp) {
+               shsInfo->countHi++;        /* Carry from low to high */
+       }
+
+    shsInfo->countHi += count >> 29;
+
+    /* Get count of bytes already in data */
+    dataCount = (int)(tmp >> 3) & 0x3F;
+
+    /* Handle any leading odd-sized chunks */
+    if (dataCount)
+    {
+        unsigned char *p = (unsigned char*) shsInfo->data + dataCount;
+
+        dataCount = SDRM_SHA1_DATASIZE - dataCount;
+        if(count < dataCount)
+        {
+            memcpy(p, buffer, count);
+            return;
+        }
+        memcpy(p, buffer, dataCount);
+        SDRM_longReverse(shsInfo->data, SDRM_SHA1_DATASIZE, shsInfo->Endianness);
+        SDRM_SHSTransform(shsInfo->digest, shsInfo->data);
+        buffer += dataCount;
+        count -= dataCount;
+    }
+
+    /* Process data in SHS_DATASIZE chunks */
+    while(count >= SDRM_SHA1_DATASIZE)
+    {
+        memcpy((unsigned char*)shsInfo->data, buffer, SDRM_SHA1_DATASIZE);
+        SDRM_longReverse(shsInfo->data, SDRM_SHA1_DATASIZE, shsInfo->Endianness);
+        SDRM_SHSTransform(shsInfo->digest, shsInfo->data);
+        buffer += SDRM_SHA1_DATASIZE;
+        count -= SDRM_SHA1_DATASIZE;
+    }
+
+    /* Handle any remaining bytes of data. */
+    memcpy( (unsigned char*)shsInfo->data, buffer, count);
+    }
+
+/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
+   1 0* (64-bit count of bits processed, MSB-first) */
+
+void SDRM_SHA1_Final(SDRM_SHA1Context  *shsInfo, unsigned char *output)
+{
+    int count;
+    unsigned char *dataPtr;
+
+    /* Compute number of bytes mod 64 */
+    count = (int) shsInfo->countLo;
+    count = (count >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    dataPtr = (unsigned char*) shsInfo->data + count;
+    *dataPtr++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = SDRM_SHA1_DATASIZE - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if( count < 8 )
+    {
+        /* Two lots of padding:  Pad the first block to 64 bytes */
+        memset(dataPtr, 0, count);
+        SDRM_longReverse(shsInfo->data, SDRM_SHA1_DATASIZE, shsInfo->Endianness);
+        SDRM_SHSTransform(shsInfo->digest, shsInfo->data);
+
+        /* Now fill the next block with 56 bytes */
+        memset((unsigned char*)shsInfo->data, 0, SDRM_SHA1_DATASIZE - 8);
+    }
+    else
+        /* Pad block to 56 bytes */
+       {
+        memset(dataPtr, 0, count - 8);
+       }
+
+    /* Append length in bits and transform */
+    shsInfo->data[14] = shsInfo->countHi;
+    shsInfo->data[15] = shsInfo->countLo;
+
+    SDRM_longReverse(shsInfo->data, SDRM_SHA1_DATASIZE - 8, shsInfo->Endianness);
+    SDRM_SHSTransform(shsInfo->digest, shsInfo->data);
+
+       /* Output to an array of bytes */
+       SDRM_SHAtoByte(output, shsInfo->digest, SDRM_SHA1_DIGESTSIZE);
+
+       /* Zeroise sensitive stuff */
+       memset((unsigned char*)shsInfo, 0, sizeof(SDRM_SHA1Context));
+}
+
+static void SDRM_SHAtoByte(unsigned char *output, unsigned int *input, unsigned int len)
+{      /* Output SHA digest in byte array */
+       unsigned int i, j;
+
+       for(i = 0, j = 0; j < len; i++, j += 4) 
+       {
+        output[j+3] = (unsigned char)( input[i]        & 0xff);
+        output[j+2] = (unsigned char)((input[i] >> 8 ) & 0xff);
+        output[j+1] = (unsigned char)((input[i] >> 16) & 0xff);
+        output[j  ] = (unsigned char)((input[i] >> 24) & 0xff);
+       }
+}
+
+
+//unsigned char digest[20];
+//unsigned char message[3] = {'a', 'b', 'c' };
+//unsigned char *mess56 = 
+//     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+
+/* Correct solutions from FIPS PUB 180-1 */
+//char *dig1 = "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D";
+//char *dig2 = "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1";
+//char *dig3 = "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F";
+
+/* Output should look like:-
+ a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d
+ A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D <= correct
+ 84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1
+ 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 <= correct
+ 34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f
+ 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F <= correct
+*/
+
+//main()
+//{
+//     SHA_CTX sha;
+//     int i;
+//     BYTE big[1000];
+//
+//     SHAInit(&sha);
+//     SHAUpdate(&sha, message, 3);
+//     SHAFinal(digest, &sha);
+//
+//     for (i = 0; i < 20; i++)
+//     {
+//             if ((i % 4) == 0) printf(" ");
+//             printf("%02x", digest[i]);
+//     }
+//     printf("\n");
+//     printf(" %s <= correct\n", dig1);
+//
+//     SHAInit(&sha);
+//     SHAUpdate(&sha, mess56, 56);
+//     SHAFinal(digest, &sha);
+//
+//     for (i = 0; i < 20; i++)
+//     {
+//             if ((i % 4) == 0) printf(" ");
+//             printf("%02x", digest[i]);
+//     }
+//     printf("\n");
+//     printf(" %s <= correct\n", dig2);
+//
+//     /* Fill up big array */
+//     for (i = 0; i < 1000; i++)
+//             big[i] = 'a';
+//
+//     SHAInit(&sha);
+//     /* Digest 1 million x 'a' */
+//     for (i = 0; i < 1000; i++)
+//             SHAUpdate(&sha, big, 1000);
+//     SHAFinal(digest, &sha);
+//
+//     for (i = 0; i < 20; i++)
+//     {
+//             if ((i % 4) == 0) printf(" ");
+//             printf("%02x", digest[i]);
+//     }
+//     printf("\n");
+//     printf(" %s <= correct\n", dig3);
+//
+//     return 0;
+//}
+
+/* endian.c */
+
+void SDRM_endianTest(int *endian_ness)
+{
+    static short test = 1;
+
+    if ( *((char *) &test) != 1)
+    {
+               /* printf("Big endian = no change\n"); */
+               *endian_ness = !(0);
+    }
+    else
+    {
+               /* printf("Little endian = swap\n"); */
+               *endian_ness = 0;
+    }
+}
+
+/***************************** End of File *****************************/
+
diff --git a/ssflib/dep/cryptocore/source/base/cc_sha2.c b/ssflib/dep/cryptocore/source/base/cc_sha2.c
new file mode 100755 (executable)
index 0000000..75ad2a9
--- /dev/null
@@ -0,0 +1,660 @@
+/*
+ * FIPS 180-2 SHA-224/256/384/512 implementation
+ * Last update: 02/02/2007
+ * Issue date:  04/30/2005
+ *
+ * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* JS Park's posting:
+       Modification for naming confilct.
+       Attach prefix 'SDRM_' for all function and constants.
+       Change name of data context to 'SDRM_SHAxxxContext' (xxx is bit length of digest)
+*/
+
+#include <string.h>
+
+#include "cc_sha2.h"
+
+#define SDRM_SHA2_SHFR(x, n)   ((x) >> (n))
+#define SDRM_SHA2_ROTR(x, n)   (((x) >> (n)) | ((x) << ((sizeof(x) << 3) - (n))))
+#define SDRM_SHA2_ROTL(x, n)   (((x) << (n)) | ((x) >> ((sizeof(x) << 3) - (n))))
+#define SDRM_SHA2_CH(x, y, z)  (((x) & (y)) ^ (~(x) & (z)))
+#define SDRM_SHA2_MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#define SDRM_SHA2_SHA256_F1(x) (SDRM_SHA2_ROTR(x,  2) ^ SDRM_SHA2_ROTR(x, 13) ^ SDRM_SHA2_ROTR(x, 22))
+#define SDRM_SHA2_SHA256_F2(x) (SDRM_SHA2_ROTR(x,  6) ^ SDRM_SHA2_ROTR(x, 11) ^ SDRM_SHA2_ROTR(x, 25))
+#define SDRM_SHA2_SHA256_F3(x) (SDRM_SHA2_ROTR(x,  7) ^ SDRM_SHA2_ROTR(x, 18) ^ SDRM_SHA2_SHFR(x,  3))
+#define SDRM_SHA2_SHA256_F4(x) (SDRM_SHA2_ROTR(x, 17) ^ SDRM_SHA2_ROTR(x, 19) ^ SDRM_SHA2_SHFR(x, 10))
+
+#define SDRM_SHA2_SHA512_F1(x) (SDRM_SHA2_ROTR(x, 28) ^ SDRM_SHA2_ROTR(x, 34) ^ SDRM_SHA2_ROTR(x, 39))
+#define SDRM_SHA2_SHA512_F2(x) (SDRM_SHA2_ROTR(x, 14) ^ SDRM_SHA2_ROTR(x, 18) ^ SDRM_SHA2_ROTR(x, 41))
+#define SDRM_SHA2_SHA512_F3(x) (SDRM_SHA2_ROTR(x,  1) ^ SDRM_SHA2_ROTR(x,  8) ^ SDRM_SHA2_SHFR(x,  7))
+#define SDRM_SHA2_SHA512_F4(x) (SDRM_SHA2_ROTR(x, 19) ^ SDRM_SHA2_ROTR(x, 61) ^ SDRM_SHA2_SHFR(x,  6))
+
+#define SDRM_SHA2_UNPACK32(x, str)                             \
+do {                                                                                   \
+       *((str) + 3) = (cc_u8) ((x)       );                    \
+       *((str) + 2) = (cc_u8) ((x) >>  8);                     \
+       *((str) + 1) = (cc_u8) ((x) >> 16);                     \
+       *((str) + 0) = (cc_u8) ((x) >> 24);                     \
+} while(0)
+
+#define SDRM_SHA2_PACK32(str, x)                               \
+do {                                                                                   \
+       *(x) =    ((cc_u32) *((str) + 3)          )             \
+                       | ((cc_u32) *((str) + 2) <<  8)         \
+                       | ((cc_u32) *((str) + 1) << 16)         \
+                       | ((cc_u32) *((str) + 0) << 24);        \
+} while(0)
+
+#define SDRM_SHA2_UNPACK64(x, str)                             \
+do {                                                                                   \
+       *((str) + 7) = (cc_u8) ((x)       );                    \
+       *((str) + 6) = (cc_u8) ((x) >>  8);                     \
+       *((str) + 5) = (cc_u8) ((x) >> 16);                     \
+       *((str) + 4) = (cc_u8) ((x) >> 24);                     \
+       *((str) + 3) = (cc_u8) ((x) >> 32);                     \
+       *((str) + 2) = (cc_u8) ((x) >> 40);                     \
+       *((str) + 1) = (cc_u8) ((x) >> 48);                     \
+       *((str) + 0) = (cc_u8) ((x) >> 56);                     \
+} while(0)
+
+#define SDRM_SHA2_PACK64(str, x)                               \
+do {                                                                                   \
+       *(x) =  ((cc_u64) *((str) + 7)    )                     \
+                       | ((cc_u64) *((str) + 6) <<  8)         \
+                       | ((cc_u64) *((str) + 5) << 16)         \
+                       | ((cc_u64) *((str) + 4) << 24)         \
+                       | ((cc_u64) *((str) + 3) << 32)         \
+                       | ((cc_u64) *((str) + 2) << 40)         \
+                       | ((cc_u64) *((str) + 1) << 48)         \
+                       | ((cc_u64) *((str) + 0) << 56);        \
+} while(0)
+
+/* Macros used for loops unrolling */
+
+#define SDRM_SHA2_SHA256_SCR(i)                                                                \
+{                                                                                                                      \
+       w[i] =  SDRM_SHA2_SHA256_F4(w[(i) -  2]) + w[(i) -  7]          \
+                       + SDRM_SHA2_SHA256_F3(w[(i) - 15]) + w[(i) - 16];       \
+}
+
+#define SDRM_SHA2_SHA512_SCR(i)                                                                \
+{                                                                                                                      \
+       w[i] =  SDRM_SHA2_SHA512_F4(w[(i) -  2]) + w[(i) -  7]          \
+                       + SDRM_SHA2_SHA512_F3(w[(i) - 15]) + w[(i) - 16];       \
+}
+
+#define SDRM_SHA2_SHA256_EXP(a, b, c, d, e, f, g, h, j)                                                        \
+{                                                                                                                                                              \
+       t1 = wv[h] + SDRM_SHA2_SHA256_F2(wv[e]) + SDRM_SHA2_CH(wv[e], wv[f], wv[g])     \
+               + sha256_k[j] + w[j];                                                                                                   \
+       t2 = SDRM_SHA2_SHA256_F1(wv[a]) + SDRM_SHA2_MAJ(wv[a], wv[b], wv[c]);           \
+       wv[d] += t1;                                                                                                                            \
+       wv[h] = t1 + t2;                                                                                                                        \
+}
+
+#define SDRM_SHA2_SHA512_EXP(a, b, c, d, e, f, g ,h, j)                                                        \
+{                                                                                                                                                              \
+       t1 = wv[h] + SDRM_SHA2_SHA512_F2(wv[e]) + SDRM_SHA2_CH(wv[e], wv[f], wv[g]) \
+               + sha512_k[j] + w[j];                                                                                                   \
+       t2 = SDRM_SHA2_SHA512_F1(wv[a]) + SDRM_SHA2_MAJ(wv[a], wv[b], wv[c]);           \
+       wv[d] += t1;                                                                                                                            \
+       wv[h] = t1 + t2;                                                                                                                        \
+}
+
+cc_u32 sha224_h0[8] =
+            {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
+
+cc_u32 sha256_h0[8] =
+                       {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+                        0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+
+cc_u32 sha256_k[64] =
+                       {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+                        0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+                        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+                        0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+                        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+                        0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+                        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+                        0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+                        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+                        0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+                        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+                        0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+                        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+                        0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+                        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+                        0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
+
+#ifndef _OP64_NOTSUPPORTED
+
+#ifdef _WIN32
+cc_u64 sha384_h0[8] =
+                       {0xcbbb9d5dc1059ed8, 0x629a292a367cd507,
+                        0x9159015a3070dd17, 0x152fecd8f70e5939,
+                        0x67332667ffc00b31, 0x8eb44a8768581511,
+                        0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4};
+
+cc_u64 sha512_h0[8] =
+                       {0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
+                        0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+                        0x510e527fade682d1, 0x9b05688c2b3e6c1f,
+                        0x1f83d9abfb41bd6b, 0x5be0cd19137e2179};
+
+cc_u64 sha512_k[80] =
+                       {0x428a2f98d728ae22, 0x7137449123ef65cd,
+                        0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
+                        0x3956c25bf348b538, 0x59f111f1b605d019,
+                        0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
+                        0xd807aa98a3030242, 0x12835b0145706fbe,
+                        0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
+                        0x72be5d74f27b896f, 0x80deb1fe3b1696b1,
+                        0x9bdc06a725c71235, 0xc19bf174cf692694,
+                        0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
+                        0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
+                        0x2de92c6f592b0275, 0x4a7484aa6ea6e483,
+                        0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
+                        0x983e5152ee66dfab, 0xa831c66d2db43210,
+                        0xb00327c898fb213f, 0xbf597fc7beef0ee4,
+                        0xc6e00bf33da88fc2, 0xd5a79147930aa725,
+                        0x06ca6351e003826f, 0x142929670a0e6e70,
+                        0x27b70a8546d22ffc, 0x2e1b21385c26c926,
+                        0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
+                        0x650a73548baf63de, 0x766a0abb3c77b2a8,
+                        0x81c2c92e47edaee6, 0x92722c851482353b,
+                        0xa2bfe8a14cf10364, 0xa81a664bbc423001,
+                        0xc24b8b70d0f89791, 0xc76c51a30654be30,
+                        0xd192e819d6ef5218, 0xd69906245565a910,
+                        0xf40e35855771202a, 0x106aa07032bbd1b8,
+                        0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
+                        0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
+                        0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
+                        0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
+                        0x748f82ee5defb2fc, 0x78a5636f43172f60,
+                        0x84c87814a1f0ab72, 0x8cc702081a6439ec,
+                        0x90befffa23631e28, 0xa4506cebde82bde9,
+                        0xbef9a3f7b2c67915, 0xc67178f2e372532b,
+                        0xca273eceea26619c, 0xd186b8c721c0c207,
+                        0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
+                        0x06f067aa72176fba, 0x0a637dc5a2c898a6,
+                        0x113f9804bef90dae, 0x1b710b35131c471b,
+                        0x28db77f523047d84, 0x32caab7b40c72493,
+                        0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
+                        0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
+                        0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
+#else
+cc_u64 sha384_h0[8] =
+                       {0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
+                        0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
+                        0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+                        0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL};
+
+cc_u64 sha512_h0[8] =
+                       {0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
+                        0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+                        0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+                        0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL};
+
+cc_u64 sha512_k[80] =
+                       {0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+                        0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+                        0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+                        0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+                        0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+                        0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+                        0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+                        0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+                        0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+                        0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+                        0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+                        0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+                        0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+                        0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+                        0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+                        0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+                        0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+                        0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+                        0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+                        0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+                        0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+                        0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+                        0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+                        0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+                        0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+                        0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+                        0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+                        0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+                        0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+                        0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+                        0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+                        0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+                        0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+                        0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+                        0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+                        0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+                        0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+                        0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+                        0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+                        0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
+#endif //_WIN32
+#endif //_OP64_NOTSUPPORTED
+
+/* SHA-256 functions */
+
+void SDRM_SHA256_Transf(SDRM_SHA256Context* ctx, const cc_u8 *message, cc_u32 block_nb)
+{
+       cc_u32 w[64];
+       cc_u32 wv[8];
+       cc_u32 t1, t2;
+       const cc_u8 *sub_block;
+       int i;
+
+       int j;
+
+       for (i = 0; i < (int) block_nb; i++)
+       {
+               sub_block = message + (i << 6);
+
+               for (j = 0; j < 16; j++)
+               {
+                       SDRM_SHA2_PACK32(&sub_block[j << 2], &w[j]);
+               }
+
+               for (j = 16; j < 64; j++)
+               {
+                       SDRM_SHA2_SHA256_SCR(j);
+               }
+
+               for (j = 0; j < 8; j++)
+               {
+                       wv[j] = ctx->h[j];
+               }
+
+               for (j = 0; j < 64; j++)
+               {
+                       t1 = wv[7] + SDRM_SHA2_SHA256_F2(wv[4]) + SDRM_SHA2_CH(wv[4], wv[5], wv[6]) + sha256_k[j] + w[j];
+                       t2 = SDRM_SHA2_SHA256_F1(wv[0]) + SDRM_SHA2_MAJ(wv[0], wv[1], wv[2]);
+                       wv[7] = wv[6];
+                       wv[6] = wv[5];
+                       wv[5] = wv[4];
+                       wv[4] = wv[3] + t1;
+                       wv[3] = wv[2];
+                       wv[2] = wv[1];
+                       wv[1] = wv[0];
+                       wv[0] = t1 + t2;
+               }
+
+               for (j = 0; j < 8; j++)
+               {
+                       ctx->h[j] += wv[j];
+               }
+       }
+}
+
+void SDRM_SHA256_Init(SDRM_SHA256Context* ctx)
+{
+       int i;
+       for (i = 0; i < 8; i++)
+       {
+               ctx->h[i] = sha256_h0[i];
+       }
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void SDRM_SHA256_Update(SDRM_SHA256Context* ctx, const cc_u8 *message, cc_u32 len)
+{
+       cc_u32 block_nb;
+       cc_u32 new_len, rem_len, tmp_len;
+       const cc_u8 *shifted_message;
+
+       tmp_len = SDRM_SHA256_DATA_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SDRM_SHA256_DATA_SIZE)
+       {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SDRM_SHA256_DATA_SIZE;
+
+       shifted_message = message + rem_len;
+
+       SDRM_SHA256_Transf(ctx, ctx->block, 1);
+       SDRM_SHA256_Transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SDRM_SHA256_DATA_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 6], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void SDRM_SHA256_Final(SDRM_SHA256Context* ctx, cc_u8 *digest)
+{
+       cc_u32 block_nb;
+       cc_u32 pm_len;
+       cc_u32 len_b;
+
+       int i;
+
+       block_nb = (1 + ((SDRM_SHA256_DATA_SIZE - 9) < (ctx->len % SDRM_SHA256_DATA_SIZE)));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 6;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SDRM_SHA2_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       SDRM_SHA256_Transf(ctx, ctx->block, block_nb);
+
+       for (i = 0 ; i < 8; i++)
+       {
+               SDRM_SHA2_UNPACK32(ctx->h[i], &digest[i << 2]);
+       }
+}
+
+#ifndef _OP64_NOTSUPPORTED
+
+/* SHA-512 functions */
+
+void SDRM_SHA512_Transf(SDRM_SHA512Context* ctx, const cc_u8 *message, cc_u32 block_nb)
+{
+       cc_u64 w[80];
+       cc_u64 wv[8];
+       cc_u64 t1, t2;
+       const cc_u8 *sub_block;
+       int i, j;
+
+       for (i = 0; i < (int) block_nb; i++)
+       {
+               sub_block = message + (i << 7);
+
+               for (j = 0; j < 16; j++)
+               {
+                       SDRM_SHA2_PACK64(&sub_block[j << 3], &w[j]);
+               }
+
+               for (j = 16; j < 80; j++)
+               {
+                       SDRM_SHA2_SHA512_SCR(j);
+               }
+
+               for (j = 0; j < 8; j++)
+               {
+                       wv[j] = ctx->h[j];
+               }
+
+               for (j = 0; j < 80; j++)
+               {
+                       t1 = wv[7] + SDRM_SHA2_SHA512_F2(wv[4]) + SDRM_SHA2_CH(wv[4], wv[5], wv[6])
+                               + sha512_k[j] + w[j];
+                       t2 = SDRM_SHA2_SHA512_F1(wv[0]) + SDRM_SHA2_MAJ(wv[0], wv[1], wv[2]);
+                       wv[7] = wv[6];
+                       wv[6] = wv[5];
+                       wv[5] = wv[4];
+                       wv[4] = wv[3] + t1;
+                       wv[3] = wv[2];
+                       wv[2] = wv[1];
+                       wv[1] = wv[0];
+                       wv[0] = t1 + t2;
+               }
+
+               for (j = 0; j < 8; j++)
+               {
+                       ctx->h[j] += wv[j];
+               }
+       }
+}
+
+void SDRM_SHA512_Init(SDRM_SHA512Context* ctx)
+{
+       int i;
+       for (i = 0; i < 8; i++)
+       {
+               ctx->h[i] = sha512_h0[i];
+       }
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void SDRM_SHA512_Update(SDRM_SHA512Context* ctx, const cc_u8 *message, cc_u32 len)
+{
+       cc_u32 block_nb;
+       cc_u32 new_len, rem_len, tmp_len;
+       const cc_u8 *shifted_message;
+
+       tmp_len = SDRM_SHA512_DATA_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SDRM_SHA512_DATA_SIZE)
+       {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SDRM_SHA512_DATA_SIZE;
+
+       shifted_message = message + rem_len;
+
+       SDRM_SHA512_Transf(ctx, ctx->block, 1);
+       SDRM_SHA512_Transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SDRM_SHA512_DATA_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 7], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 7;
+}
+
+void SDRM_SHA512_Final(SDRM_SHA512Context* ctx, cc_u8 *digest)
+{
+       cc_u32 block_nb;
+       cc_u32 pm_len;
+       cc_u32 len_b;
+
+       int i;
+
+       block_nb = 1 + ((SDRM_SHA512_DATA_SIZE - 17) < (ctx->len % SDRM_SHA512_DATA_SIZE));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 7;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SDRM_SHA2_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       SDRM_SHA512_Transf(ctx, ctx->block, block_nb);
+
+       for (i = 0 ; i < 8; i++)
+       {
+               SDRM_SHA2_UNPACK64(ctx->h[i], &digest[i << 3]);
+       }
+}
+
+/* SHA-384 functions */
+
+void SDRM_SHA384_Init(SDRM_SHA384Context* ctx)
+{
+       int i;
+       for (i = 0; i < 8; i++)
+       {
+               ctx->h[i] = sha384_h0[i];
+       }
+
+       ctx->len = 0;
+       ctx->tot_len = 0;
+}
+
+void SDRM_SHA384_Update(SDRM_SHA384Context* ctx, const cc_u8 *message, cc_u32 len)
+{
+       cc_u32 block_nb;
+       cc_u32 new_len, rem_len, tmp_len;
+       const cc_u8 *shifted_message;
+
+       tmp_len = SDRM_SHA384_DATA_SIZE - ctx->len;
+       rem_len = len < tmp_len ? len : tmp_len;
+
+       memcpy(&ctx->block[ctx->len], message, rem_len);
+
+       if (ctx->len + len < SDRM_SHA384_DATA_SIZE)
+       {
+               ctx->len += len;
+               return;
+       }
+
+       new_len = len - rem_len;
+       block_nb = new_len / SDRM_SHA384_DATA_SIZE;
+
+       shifted_message = message + rem_len;
+
+       SDRM_SHA512_Transf(ctx, ctx->block, 1);
+       SDRM_SHA512_Transf(ctx, shifted_message, block_nb);
+
+       rem_len = new_len % SDRM_SHA384_DATA_SIZE;
+
+       memcpy(ctx->block, &shifted_message[block_nb << 7], rem_len);
+
+       ctx->len = rem_len;
+       ctx->tot_len += (block_nb + 1) << 7;
+}
+
+void SDRM_SHA384_Final(SDRM_SHA384Context* ctx, cc_u8 *digest)
+{
+       cc_u32 block_nb;
+       cc_u32 pm_len;
+       cc_u32 len_b;
+
+       int i;
+
+       block_nb = (1 + ((SDRM_SHA384_DATA_SIZE - 17) < (ctx->len % SDRM_SHA384_DATA_SIZE)));
+
+       len_b = (ctx->tot_len + ctx->len) << 3;
+       pm_len = block_nb << 7;
+
+       memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+       ctx->block[ctx->len] = 0x80;
+       SDRM_SHA2_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+       SDRM_SHA512_Transf(ctx, ctx->block, block_nb);
+
+       for (i = 0 ; i < 6; i++)
+       {
+               SDRM_SHA2_UNPACK64(ctx->h[i], &digest[i << 3]);
+       }
+}
+
+#endif //_OP64_NOTSUPPORTED
+
+/* SHA-224 functions */
+
+void SDRM_SHA224_Init(SDRM_SHA224Context *ctx)
+{
+    int i;
+    for (i = 0; i < 8; i++) {
+        ctx->h[i] = sha224_h0[i];
+    }
+
+    ctx->len = 0;
+    ctx->tot_len = 0;
+}
+
+void SDRM_SHA224_Update(SDRM_SHA224Context *ctx, const unsigned char *message,
+                   unsigned int len)
+{
+    unsigned int block_nb;
+    unsigned int new_len, rem_len, tmp_len;
+    const unsigned char *shifted_message;
+
+    tmp_len = SDRM_SHA224_DATA_SIZE - ctx->len;
+    rem_len = len < tmp_len ? len : tmp_len;
+
+    memcpy(&ctx->block[ctx->len], message, rem_len);
+
+    if (ctx->len + len < SDRM_SHA224_DATA_SIZE) {
+        ctx->len += len;
+        return;
+    }
+
+    new_len = len - rem_len;
+    block_nb = new_len / SDRM_SHA224_DATA_SIZE;
+
+    shifted_message = message + rem_len;
+
+    SDRM_SHA256_Transf(ctx, ctx->block, 1);
+    SDRM_SHA256_Transf(ctx, shifted_message, block_nb);
+
+    rem_len = new_len % SDRM_SHA224_DATA_SIZE;
+
+    memcpy(ctx->block, &shifted_message[block_nb << 6],
+           rem_len);
+
+    ctx->len = rem_len;
+    ctx->tot_len += (block_nb + 1) << 6;
+}
+
+void SDRM_SHA224_Final(SDRM_SHA224Context *ctx, unsigned char *digest)
+{
+    unsigned int block_nb;
+    unsigned int pm_len;
+    unsigned int len_b;
+
+    int i;
+
+    block_nb = (1 + ((SDRM_SHA224_DATA_SIZE - 9)
+                     < (ctx->len % SDRM_SHA224_DATA_SIZE)));
+
+    len_b = (ctx->tot_len + ctx->len) << 3;
+    pm_len = block_nb << 6;
+
+    memset(ctx->block + ctx->len, 0, pm_len - ctx->len);
+    ctx->block[ctx->len] = 0x80;
+    SDRM_SHA2_UNPACK32(len_b, ctx->block + pm_len - 4);
+
+    SDRM_SHA256_Transf(ctx, ctx->block, block_nb);
+
+    for (i = 0 ; i < 7; i++) {
+        SDRM_SHA2_UNPACK32(ctx->h[i], &digest[i << 2]);
+    }
+}
diff --git a/ssflib/dep/cryptocore/source/base/cc_snow2.c b/ssflib/dep/cryptocore/source/base/cc_snow2.c
new file mode 100755 (executable)
index 0000000..700863d
--- /dev/null
@@ -0,0 +1,404 @@
+/**
+ * \file       snow2.c
+ * @brief      implementation of SNOW 2.0 encryption scheme
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/02
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_snow2.h"
+
+////////////////////////////////////////////////////////////////////////////
+// pre-computated values
+////////////////////////////////////////////////////////////////////////////
+static cc_u32 SNOW2_MUL_a[256]= {
+       0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835, 0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679, 
+       0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD, 0xD320B2D4, 0x32BF7DC7, 0xB8B785F2, 0x59284AE1, 
+       0x0AE71199, 0xEB78DE8A, 0x617026BF, 0x80EFE9AC, 0xDC607FD5, 0x3DFFB0C6, 0xB7F748F3, 0x566887E0, 
+       0x0F40CD01, 0xEEDF0212, 0x64D7FA27, 0x85483534, 0xD9C7A34D, 0x38586C5E, 0xB250946B, 0x53CF5B78, 
+       0x1467229B, 0xF5F8ED88, 0x7FF015BD, 0x9E6FDAAE, 0xC2E04CD7, 0x237F83C4, 0xA9777BF1, 0x48E8B4E2, 
+       0x11C0FE03, 0xF05F3110, 0x7A57C925, 0x9BC80636, 0xC747904F, 0x26D85F5C, 0xACD0A769, 0x4D4F687A, 
+       0x1E803302, 0xFF1FFC11, 0x75170424, 0x9488CB37, 0xC8075D4E, 0x2998925D, 0xA3906A68, 0x420FA57B, 
+       0x1B27EF9A, 0xFAB82089, 0x70B0D8BC, 0x912F17AF, 0xCDA081D6, 0x2C3F4EC5, 0xA637B6F0, 0x47A879E3, 
+       0x28CE449F, 0xC9518B8C, 0x435973B9, 0xA2C6BCAA, 0xFE492AD3, 0x1FD6E5C0, 0x95DE1DF5, 0x7441D2E6, 
+       0x2D699807, 0xCCF65714, 0x46FEAF21, 0xA7616032, 0xFBEEF64B, 0x1A713958, 0x9079C16D, 0x71E60E7E, 
+       0x22295506, 0xC3B69A15, 0x49BE6220, 0xA821AD33, 0xF4AE3B4A, 0x1531F459, 0x9F390C6C, 0x7EA6C37F, 
+       0x278E899E, 0xC611468D, 0x4C19BEB8, 0xAD8671AB, 0xF109E7D2, 0x109628C1, 0x9A9ED0F4, 0x7B011FE7, 
+       0x3CA96604, 0xDD36A917, 0x573E5122, 0xB6A19E31, 0xEA2E0848, 0x0BB1C75B, 0x81B93F6E, 0x6026F07D, 
+       0x390EBA9C, 0xD891758F, 0x52998DBA, 0xB30642A9, 0xEF89D4D0, 0x0E161BC3, 0x841EE3F6, 0x65812CE5, 
+       0x364E779D, 0xD7D1B88E, 0x5DD940BB, 0xBC468FA8, 0xE0C919D1, 0x0156D6C2, 0x8B5E2EF7, 0x6AC1E1E4, 
+       0x33E9AB05, 0xD2766416, 0x587E9C23, 0xB9E15330, 0xE56EC549, 0x04F10A5A, 0x8EF9F26F, 0x6F663D7C, 
+       0x50358897, 0xB1AA4784, 0x3BA2BFB1, 0xDA3D70A2, 0x86B2E6DB, 0x672D29C8, 0xED25D1FD, 0x0CBA1EEE, 
+       0x5592540F, 0xB40D9B1C, 0x3E056329, 0xDF9AAC3A, 0x83153A43, 0x628AF550, 0xE8820D65, 0x091DC276, 
+       0x5AD2990E, 0xBB4D561D, 0x3145AE28, 0xD0DA613B, 0x8C55F742, 0x6DCA3851, 0xE7C2C064, 0x065D0F77, 
+       0x5F754596, 0xBEEA8A85, 0x34E272B0, 0xD57DBDA3, 0x89F22BDA, 0x686DE4C9, 0xE2651CFC, 0x03FAD3EF, 
+       0x4452AA0C, 0xA5CD651F, 0x2FC59D2A, 0xCE5A5239, 0x92D5C440, 0x734A0B53, 0xF942F366, 0x18DD3C75, 
+       0x41F57694, 0xA06AB987, 0x2A6241B2, 0xCBFD8EA1, 0x977218D8, 0x76EDD7CB, 0xFCE52FFE, 0x1D7AE0ED, 
+       0x4EB5BB95, 0xAF2A7486, 0x25228CB3, 0xC4BD43A0, 0x9832D5D9, 0x79AD1ACA, 0xF3A5E2FF, 0x123A2DEC, 
+       0x4B12670D, 0xAA8DA81E, 0x2085502B, 0xC11A9F38, 0x9D950941, 0x7C0AC652, 0xF6023E67, 0x179DF174, 
+       0x78FBCC08, 0x9964031B, 0x136CFB2E, 0xF2F3343D, 0xAE7CA244, 0x4FE36D57, 0xC5EB9562, 0x24745A71, 
+       0x7D5C1090, 0x9CC3DF83, 0x16CB27B6, 0xF754E8A5, 0xABDB7EDC, 0x4A44B1CF, 0xC04C49FA, 0x21D386E9, 
+       0x721CDD91, 0x93831282, 0x198BEAB7, 0xF81425A4, 0xA49BB3DD, 0x45047CCE, 0xCF0C84FB, 0x2E934BE8, 
+       0x77BB0109, 0x9624CE1A, 0x1C2C362F, 0xFDB3F93C, 0xA13C6F45, 0x40A3A056, 0xCAAB5863, 0x2B349770, 
+       0x6C9CEE93, 0x8D032180, 0x070BD9B5, 0xE69416A6, 0xBA1B80DF, 0x5B844FCC, 0xD18CB7F9, 0x301378EA, 
+       0x693B320B, 0x88A4FD18, 0x02AC052D, 0xE333CA3E, 0xBFBC5C47, 0x5E239354, 0xD42B6B61, 0x35B4A472, 
+       0x667BFF0A, 0x87E43019, 0x0DECC82C, 0xEC73073F, 0xB0FC9146, 0x51635E55, 0xDB6BA660, 0x3AF46973, 
+       0x63DC2392, 0x8243EC81, 0x084B14B4, 0xE9D4DBA7, 0xB55B4DDE, 0x54C482CD, 0xDECC7AF8, 0x3F53B5EB
+};
+
+static cc_u32 SNOW2_MUL_ainverse[256]= {
+    0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE, 0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998, 
+       0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32, 0xA04452AA, 0xB84B1267, 0x905AD299, 0x88559254, 
+       0x29F05F31, 0x31FF1FFC, 0x19EEDF02, 0x01E19FCF, 0x49CCF657, 0x51C3B69A, 0x79D27664, 0x61DD36A9, 
+       0xE988A4FD, 0xF187E430, 0xD99624CE, 0xC1996403, 0x89B40D9B, 0x91BB4D56, 0xB9AA8DA8, 0xA1A5CD65, 
+       0x5249BE62, 0x4A46FEAF, 0x62573E51, 0x7A587E9C, 0x32751704, 0x2A7A57C9, 0x026B9737, 0x1A64D7FA, 
+       0x923145AE, 0x8A3E0563, 0xA22FC59D, 0xBA208550, 0xF20DECC8, 0xEA02AC05, 0xC2136CFB, 0xDA1C2C36, 
+       0x7BB9E153, 0x63B6A19E, 0x4BA76160, 0x53A821AD, 0x1B854835, 0x038A08F8, 0x2B9BC806, 0x339488CB, 
+       0xBBC11A9F, 0xA3CE5A52, 0x8BDF9AAC, 0x93D0DA61, 0xDBFDB3F9, 0xC3F2F334, 0xEBE333CA, 0xF3EC7307, 
+       0xA492D5C4, 0xBC9D9509, 0x948C55F7, 0x8C83153A, 0xC4AE7CA2, 0xDCA13C6F, 0xF4B0FC91, 0xECBFBC5C, 
+       0x64EA2E08, 0x7CE56EC5, 0x54F4AE3B, 0x4CFBEEF6, 0x04D6876E, 0x1CD9C7A3, 0x34C8075D, 0x2CC74790, 
+       0x8D628AF5, 0x956DCA38, 0xBD7C0AC6, 0xA5734A0B, 0xED5E2393, 0xF551635E, 0xDD40A3A0, 0xC54FE36D, 
+       0x4D1A7139, 0x551531F4, 0x7D04F10A, 0x650BB1C7, 0x2D26D85F, 0x35299892, 0x1D38586C, 0x053718A1, 
+       0xF6DB6BA6, 0xEED42B6B, 0xC6C5EB95, 0xDECAAB58, 0x96E7C2C0, 0x8EE8820D, 0xA6F942F3, 0xBEF6023E, 
+       0x36A3906A, 0x2EACD0A7, 0x06BD1059, 0x1EB25094, 0x569F390C, 0x4E9079C1, 0x6681B93F, 0x7E8EF9F2, 
+       0xDF2B3497, 0xC724745A, 0xEF35B4A4, 0xF73AF469, 0xBF179DF1, 0xA718DD3C, 0x8F091DC2, 0x97065D0F, 
+       0x1F53CF5B, 0x075C8F96, 0x2F4D4F68, 0x37420FA5, 0x7F6F663D, 0x676026F0, 0x4F71E60E, 0x577EA6C3, 
+       0xE18D0321, 0xF98243EC, 0xD1938312, 0xC99CC3DF, 0x81B1AA47, 0x99BEEA8A, 0xB1AF2A74, 0xA9A06AB9, 
+       0x21F5F8ED, 0x39FAB820, 0x11EB78DE, 0x09E43813, 0x41C9518B, 0x59C61146, 0x71D7D1B8, 0x69D89175, 
+       0xC87D5C10, 0xD0721CDD, 0xF863DC23, 0xE06C9CEE, 0xA841F576, 0xB04EB5BB, 0x985F7545, 0x80503588, 
+       0x0805A7DC, 0x100AE711, 0x381B27EF, 0x20146722, 0x68390EBA, 0x70364E77, 0x58278E89, 0x4028CE44, 
+       0xB3C4BD43, 0xABCBFD8E, 0x83DA3D70, 0x9BD57DBD, 0xD3F81425, 0xCBF754E8, 0xE3E69416, 0xFBE9D4DB, 
+       0x73BC468F, 0x6BB30642, 0x43A2C6BC, 0x5BAD8671, 0x1380EFE9, 0x0B8FAF24, 0x239E6FDA, 0x3B912F17, 
+       0x9A34E272, 0x823BA2BF, 0xAA2A6241, 0xB225228C, 0xFA084B14, 0xE2070BD9, 0xCA16CB27, 0xD2198BEA, 
+       0x5A4C19BE, 0x42435973, 0x6A52998D, 0x725DD940, 0x3A70B0D8, 0x227FF015, 0x0A6E30EB, 0x12617026, 
+       0x451FD6E5, 0x5D109628, 0x750156D6, 0x6D0E161B, 0x25237F83, 0x3D2C3F4E, 0x153DFFB0, 0x0D32BF7D, 
+       0x85672D29, 0x9D686DE4, 0xB579AD1A, 0xAD76EDD7, 0xE55B844F, 0xFD54C482, 0xD545047C, 0xCD4A44B1, 
+       0x6CEF89D4, 0x74E0C919, 0x5CF109E7, 0x44FE492A, 0x0CD320B2, 0x14DC607F, 0x3CCDA081, 0x24C2E04C, 
+       0xAC977218, 0xB49832D5, 0x9C89F22B, 0x8486B2E6, 0xCCABDB7E, 0xD4A49BB3, 0xFCB55B4D, 0xE4BA1B80, 
+       0x17566887, 0x0F59284A, 0x2748E8B4, 0x3F47A879, 0x776AC1E1, 0x6F65812C, 0x477441D2, 0x5F7B011F, 
+       0xD72E934B, 0xCF21D386, 0xE7301378, 0xFF3F53B5, 0xB7123A2D, 0xAF1D7AE0, 0x870CBA1E, 0x9F03FAD3, 
+       0x3EA637B6, 0x26A9777B, 0x0EB8B785, 0x16B7F748, 0x5E9A9ED0, 0x4695DE1D, 0x6E841EE3, 0x768B5E2E, 
+       0xFEDECC7A, 0xE6D18CB7, 0xCEC04C49, 0xD6CF0C84, 0x9EE2651C, 0x86ED25D1, 0xAEFCE52F, 0xB6F3A5E2
+};
+
+static cc_u32 SNOW2_T0[256]= {
+       0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 
+       0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 
+       0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 
+       0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 
+       0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 
+       0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 
+       0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 
+       0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 
+       0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 
+       0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 
+       0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 
+       0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 
+       0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 
+       0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 
+       0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 
+       0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 
+       0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 
+       0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 
+       0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 
+       0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 
+       0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, 
+       0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 
+       0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 
+       0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 
+       0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 
+       0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 
+       0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, 
+       0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 
+       0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 
+       0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 
+       0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 
+       0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
+};
+
+static cc_u32 SNOW2_T1[256]= {
+       0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 
+       0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 
+       0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 
+       0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, 
+       0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 
+       0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 
+       0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, 
+       0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 
+       0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, 
+       0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 
+       0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 
+       0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 
+       0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 
+       0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, 
+       0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 
+       0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 
+       0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 
+       0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 
+       0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, 
+       0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 
+       0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, 
+       0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 
+       0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 
+       0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, 
+       0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 
+       0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 
+       0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, 
+       0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 
+       0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, 
+       0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 
+       0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 
+       0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a
+};
+
+static cc_u32 SNOW2_T2[256]= {
+       0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 
+       0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 
+       0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 
+       0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, 
+       0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 
+       0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 
+       0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, 
+       0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 
+       0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, 
+       0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 
+       0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 
+       0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 
+       0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 
+       0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, 
+       0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 
+       0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 
+       0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 
+       0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 
+       0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, 
+       0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 
+       0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, 
+       0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 
+       0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 
+       0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, 
+       0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 
+       0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 
+       0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, 
+       0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 
+       0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, 
+       0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 
+       0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 
+       0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16
+};
+
+static cc_u32 SNOW2_T3[256]= {
+       0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 
+       0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 
+       0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 
+       0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, 
+       0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 
+       0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 
+       0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0xa0f0505, 0x2fb59a9a, 
+       0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 
+       0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, 
+       0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 
+       0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 
+       0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 
+       0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 
+       0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, 
+       0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 
+       0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 
+       0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 
+       0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 
+       0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, 
+       0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 
+       0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, 
+       0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 
+       0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 
+       0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, 
+       0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 
+       0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 
+       0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, 
+       0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 
+       0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, 
+       0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 
+       0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 
+       0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616
+};
+
+////////////////////////////////////////////////////////////////////////////
+// Macros
+////////////////////////////////////////////////////////////////////////////
+#define a_MUL(w)       (((w) << 8) ^ SNOW2_MUL_a[(w) >> 24])
+#define ainv_MUL(w)    (((w) >> 8) ^ SNOW2_MUL_ainverse[(w) & 0xff])
+
+#define BYTE0(w)       ( (w)            & 0xff)
+#define BYTE1(w)       (((w) >>  8) & 0xff)
+#define BYTE2(w)       (((w) >> 16) & 0xff)
+#define BYTE3(w)       (((w) >> 24) & 0xff)
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_SNOW2_Setup
+ * @brief      Setup FSM and s values
+ *
+ * @param      ctx                             [out]crypto context
+ * @param      UserKey                 [in]User Key, 128 or 256 bit
+ * @param      keyLen                  [in]byte-size of User Key, 16 or 32
+ * @param      IV                              [in]16 byte initial vector
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_SNOW2_Setup(SDRM_SNOW2Context *ctx, cc_u8 *UserKey, cc_u32 keyLen, cc_u8 *IV)
+{
+       cc_u32 IV0, IV1, IV2, IV3;
+       cc_u32 *s = ctx->s;
+       cc_u32 r1, r2, i;
+       cc_u32 Ft, R1_next;
+
+       //test endian
+       i = 0xff;
+       ctx->endian = (*((cc_u8*)&i) == 0xff) ? CRYPTO_LITTLE_ENDIAN : CRYPTO_BIG_ENDIAN;
+
+       //Initialize IV
+       GET_UINT32(IV3, IV,  0)
+       GET_UINT32(IV2, IV,  4)
+       GET_UINT32(IV1, IV,  8)
+       GET_UINT32(IV0, IV, 12)
+
+       //Load Key
+       if (keyLen == 16) {
+               GET_UINT32(s[15], UserKey,  0)
+               GET_UINT32(s[14], UserKey,  4)
+               GET_UINT32(s[13], UserKey,  8)
+               GET_UINT32(s[12], UserKey, 12)
+               s[11] = ~s[15];
+               s[10] = ~s[14];
+               s[ 9] = ~s[13];
+               s[ 8] = ~s[12];
+               s[ 7] =  s[15];
+               s[ 6] =  s[14];
+               s[ 5] =  s[13];
+               s[ 4] =  s[12];
+               s[ 3] = ~s[15];
+               s[ 2] = ~s[14];
+               s[ 1] = ~s[13];
+               s[ 0] = ~s[12];
+       }
+       else {
+               GET_UINT32(s[15], UserKey,  0)
+               GET_UINT32(s[14], UserKey,  4)
+               GET_UINT32(s[13], UserKey,  8)
+               GET_UINT32(s[12], UserKey, 12)
+               GET_UINT32(s[11], UserKey, 16)
+               GET_UINT32(s[10], UserKey, 20)
+               GET_UINT32(s[ 9], UserKey, 24)
+               GET_UINT32(s[ 8], UserKey, 28)
+               s[ 7] = ~s[15];
+               s[ 6] = ~s[14];
+               s[ 5] = ~s[13];
+               s[ 4] = ~s[12];
+               s[ 3] = ~s[11];
+               s[ 2] = ~s[10];
+               s[ 1] = ~s[ 9];
+               s[ 0] = ~s[ 8];
+       }
+
+       s[15] ^= IV0;
+       s[12] ^= IV1;
+       s[10] ^= IV2;
+       s[ 9] ^= IV3;
+
+       r1 = 0;
+       r2 = 0;
+
+       // clock 32 times without producing any output
+       for (i = 0; i < 16; i++)
+       {
+               Ft = (r1 + s[(i - 1) & 0x0f]) ^ r2;
+               s[i] = a_MUL(s[i]) ^ s[(i + 2) & 0x0f] ^ ainv_MUL(s[(i + 11) & 0x0f]) ^ Ft;
+               R1_next = r2 + s[(i + 5) & 0x0f];
+               r2 = SNOW2_T0[BYTE0(r1)] ^ SNOW2_T1[BYTE1(r1)] ^ SNOW2_T2[BYTE2(r1)] ^ SNOW2_T3[BYTE3(r1)];
+               r1 = R1_next;
+       }
+
+       for (i = 0; i < 16; i++)
+       {
+               Ft = (r1 + s[(i - 1) & 0x0f]) ^ r2;
+               s[i] = a_MUL(s[i]) ^ s[(i + 2) & 0x0f] ^ ainv_MUL(s[(i + 11) & 0x0f]) ^ Ft;
+               R1_next = r2 + s[(i + 5) & 0x0f];
+               r2 = SNOW2_T0[BYTE0(r1)] ^ SNOW2_T1[BYTE1(r1)] ^ SNOW2_T2[BYTE2(r1)] ^ SNOW2_T3[BYTE3(r1)];
+               r1 = R1_next;
+       }
+
+       ctx->r1 = r1;
+       ctx->r2 = r2;
+
+       ctx->t = 0;
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SNOW2_getKeyStream64
+ * @brief      get 64 byte key stream
+ *
+ * @param      ctx                             [out]crypto context
+ * @param      keyStream64             [in]generated key stream
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_SNOW2_getKeyStream64(SDRM_SNOW2Context *ctx, cc_u32 *keyStream64)
+{
+       cc_u32 R1_next, i;
+       cc_u32 *s = ctx->s;
+       cc_u32 t = ctx->t;
+
+       for (i = t; i < t + 16; i++)
+       {
+               s[i & 0x0f] = a_MUL(s[i & 0x0f]) ^ s[(i + 2) & 0x0f] ^ ainv_MUL(s[(i + 11) & 0x0f]);
+               R1_next = ctx->r2 + s[(i + 5) & 0x0f];
+               ctx->r2 = SNOW2_T0[BYTE0(ctx->r1)] ^ SNOW2_T1[BYTE1(ctx->r1)] ^ SNOW2_T2[BYTE2(ctx->r1)] ^ SNOW2_T3[BYTE3(ctx->r1)];
+               ctx->r1 = R1_next;
+               
+               keyStream64[i] = (ctx->r1 + s[i & 0x0f]) ^ ctx->r2 ^ s[(i + 1) & 0x0f];
+       }
+
+       ctx->t = t & 0x0f;
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_SNOW2_getKeyStream
+ * @brief      get 4 byte key stream
+ *
+ * @param      ctx                             [out]crypto context
+ * @param      keyStream               [in]generated key stream
+ *
+ * @return     CRYPTO_SUCCESS  if no error is occured
+ */
+int SDRM_SNOW2_getKeyStream(SDRM_SNOW2Context *ctx, cc_u32 *keyStream)
+{
+       cc_u32 R1_next;
+       cc_u32 *s = ctx->s;
+       cc_u32 t = ctx->t;
+
+       s[t & 0x0f] = a_MUL(s[t & 0x0f]) ^ s[(t + 2) & 0x0f] ^ ainv_MUL(s[(t + 11) & 0x0f]);
+       R1_next = ctx->r2 + s[(t + 5) & 0x0f];
+       ctx->r2 = SNOW2_T0[BYTE0(ctx->r1)] ^ SNOW2_T1[BYTE1(ctx->r1)] ^ SNOW2_T2[BYTE2(ctx->r1)] ^ SNOW2_T3[BYTE3(ctx->r1)];
+       ctx->r1 = R1_next;
+       
+       *keyStream = (ctx->r1 + s[t & 0x0f]) ^ ctx->r2 ^ s[(t + 1) & 0x0f];
+
+       ctx->t = (t + 1) & 0x0f;
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/middle/cc_cmac.c b/ssflib/dep/cryptocore/source/middle/cc_cmac.c
new file mode 100755 (executable)
index 0000000..cda9d3c
--- /dev/null
@@ -0,0 +1,260 @@
+/**
+ * \file       cmac.c
+ * @brief      funciton for c-mac code generation by AES-128
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/20
+ */
+
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_cmac.h"
+
+
+////////////////////////////////////////////////////////////////////////////
+// Constants
+////////////////////////////////////////////////////////////////////////////
+/*!    @brief  max block columns       */
+#define CMAC_MAXBC                             (256/32)
+
+/*!    @brief  max key columns         */
+#define CMAC_MAXKC                             (256/32)
+
+/*!    @brief  max rounds                      */
+#define CMAC_MAXROUNDS                 14
+
+/*!    @brief  constant - defined in OMAC1a(One-Key CBC MAC1, submitted by Iwata and Kurosawa) */
+static cc_u8 R_b[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
+
+
+/*
+ * @fn         int SDRM_CMAC_init(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen)
+ *
+ * @brief      Parameter setting for mac code generation
+ * @param      crt                                                     [out]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CMAC_init(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen)
+{
+       cc_u8   *K1, *K2, temp[16] = {0};
+       cc_u8   ZERO[16] = {0};
+       int             i;
+       cc_u32  *RoundKey;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->cmacctx == NULL) || (Key == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (KeyLen != 16)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       memset(crt->ctx->cmacctx->IV, 0, SDRM_AES_BLOCK_SIZ);
+
+       crt->ctx->cmacctx->BlockLen = 0;
+
+       RoundKey = (cc_u32*)(void*)(crt->ctx->cmacctx->RoundKey);
+       K1 = crt->ctx->cmacctx->K1;
+       K2 = crt->ctx->cmacctx->K2;
+
+       SDRM_rijndaelKeySetupEnc(RoundKey, Key, 128);
+
+       SDRM_rijndaelEncrypt(RoundKey, 10, ZERO, temp);
+
+       if((temp[0] >> 7) == 0x00)                                                      // L << 1
+       {
+               for (i = 0; i < 15; i++)
+               {
+                       K1[i] = (temp[i] << 1) | (temp[i+1] >> 7); 
+               }
+               K1[15] = temp[i] << 1; 
+       }
+       else if ((temp[0] >> 7) == 0x01)
+       {
+               for (i = 0; i < 15; i++)
+               {
+                       K1[i] = (temp[i] << 1) | (temp[i+1] >> 7); 
+               }
+               K1[15] = temp[i] << 1; 
+               BlockXor(K1, K1, R_b);
+       }
+
+       if((K1[0] >> 7) == 0x00)                                                        // K1 << 1
+       {
+               for (i = 0; i < 15; i++)
+               {
+                       K2[i] = (K1[i] << 1) | (K1[i+1] >> 7); 
+               }
+               K2[15] = K1[i] << 1; 
+       }
+       else if ((K1[0] >> 7) == 0x01)
+       {
+               for (i = 0; i < 15; i++)
+               {
+                       K2[i] = (K1[i] << 1) | (K1[i+1] >> 7); 
+               }
+               K2[15] = K1[i] << 1; 
+               BlockXor(K2, K2, R_b);
+       }
+
+//     LOG4DRM_BUFFER(&CryptoLogCTX), LOG_DEBUG, "K1", K1, 16); 
+//     LOG4DRM_BUFFER(&CryptoLogCTX), LOG_DEBUG, "K2", K2, 16); 
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         int SDRM_CMAC_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen)
+ * @brief      process data blocks
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CMAC_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen)
+{
+       int             Loop;
+       cc_u8   *ptr;
+
+       if (msgLen == 0)
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->cmacctx == NULL) || (msg == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (msgLen + crt->ctx->cmacctx->BlockLen <= SDRM_AES_BLOCK_SIZ)
+       {
+               memcpy(crt->ctx->cmacctx->Block + crt->ctx->cmacctx->BlockLen, msg, msgLen);
+               crt->ctx->cmacctx->BlockLen += msgLen;
+               return CRYPTO_SUCCESS;
+       }
+
+       memcpy(crt->ctx->cmacctx->Block + crt->ctx->cmacctx->BlockLen, msg, SDRM_AES_BLOCK_SIZ - crt->ctx->cmacctx->BlockLen);
+       SDRM_CBC_Enc(ID_AES128, crt->ctx->cmacctx->IV, crt->ctx->cmacctx->Block, crt->ctx->cmacctx->RoundKey, crt->ctx->cmacctx->IV);
+
+       Loop = (msgLen + crt->ctx->cmacctx->BlockLen - 1) / SDRM_AES_BLOCK_SIZ - 1;
+       ptr = msg + SDRM_AES_BLOCK_SIZ - crt->ctx->cmacctx->BlockLen;
+       crt->ctx->cmacctx->BlockLen = (cc_u32)(msg + msgLen - ptr) - Loop * SDRM_AES_BLOCK_SIZ;
+
+       while (Loop > 0)
+       {
+               SDRM_CBC_Enc(ID_AES128, crt->ctx->cmacctx->IV, ptr, crt->ctx->cmacctx->RoundKey, crt->ctx->cmacctx->IV);
+               Loop--;
+               ptr += SDRM_AES_BLOCK_SIZ;
+       }
+
+//     LOG4DRM_BUFFER(&CryptoLogCTX), LOG_DEBUG, "Block", crt->ctx->cmacctx->IV, 16); 
+
+       memcpy(crt->ctx->cmacctx->Block, ptr, crt->ctx->cmacctx->BlockLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         int SDRM_CMAC_final(CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen)
+ * @brief      process last data block
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_CMAC_final(CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen)
+{
+       cc_u8 *K1, *K2;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->cmacctx == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       K1 = crt->ctx->cmacctx->K1;
+       K2 = crt->ctx->cmacctx->K2;
+
+       if (crt->ctx->cmacctx->BlockLen == SDRM_AES_BLOCK_SIZ)
+       {
+               BlockXor(crt->ctx->cmacctx->Block, crt->ctx->cmacctx->Block, K1);
+       }
+       else
+       {
+               crt->ctx->cmacctx->IV[crt->ctx->cmacctx->BlockLen] ^= 0x80;
+               BlockXor(crt->ctx->cmacctx->IV, crt->ctx->cmacctx->IV, K2);                                                     // input = input XOR K2
+               memset(crt->ctx->cmacctx->Block + crt->ctx->cmacctx->BlockLen, 0, SDRM_AES_BLOCK_SIZ - crt->ctx->cmacctx->BlockLen);
+       }
+
+       SDRM_CBC_Enc(ID_AES128, output, crt->ctx->cmacctx->Block, crt->ctx->cmacctx->RoundKey, crt->ctx->cmacctx->IV);
+
+       if (outputLen != NULL)
+       {
+               *outputLen = 16;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         int SDRM_CMAC_getMAC(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen)
+ * @brief      generate c-mac code
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ */
+int SDRM_CMAC_getMAC(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int result;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->cmacctx == NULL) || (Key == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       result = SDRM_CMAC_init(crt, Key, KeyLen);
+       if (result != CRYPTO_SUCCESS)
+       {
+               return result;
+       }
+
+       result = SDRM_CMAC_update(crt, msg, msgLen);
+       if (result != CRYPTO_SUCCESS)
+       {
+                       return result;
+       }
+
+       return SDRM_CMAC_final(crt, output, outputLen);
+}
+
+/***************************** End of File *****************************/      
diff --git a/ssflib/dep/cryptocore/source/middle/cc_dh.c b/ssflib/dep/cryptocore/source/middle/cc_dh.c
new file mode 100755 (executable)
index 0000000..3bfffbc
--- /dev/null
@@ -0,0 +1,333 @@
+/**
+ * \file       ecdh.c
+ * @brief      implementation of EC Diffie-Hellman Key Exchange Protocol
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/27
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_ANSI_x931.h"
+#include "cc_bignum.h"
+#include "cc_fast_math.h"
+#include "cc_dh.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/**
+ * @fn         SDRM_GenerateDHParam(CryptoCoreContainer* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned int* pGenerator)
+ * @brief      generate parameters for Diffie-Hellman protocol
+ *
+ * @param      [out] crt                               context
+ * @param      [out] pPrime                    prime number
+ * @param      [in]  nPrimeLen                 size of pPrime buffer
+ * @param      [out] pGenerator                generator value
+ *
+ * @return     int
+ */
+int SDRM_GenerateDHParam(CryptoCoreContainer* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned char* pGenerator)
+{
+       SDRM_DHContext* ctx;
+       cc_u32 Seed[4];
+       int i, sp, t1;
+       SDRM_BIG_NUM *p = NULL;
+       SDRM_BIG_NUM *g = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dhctx == NULL) || (pPrime == NULL) || (pGenerator == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->dhctx;
+
+       p = SDRM_BN_Init(nPrimeLen / 2 + 1);
+       if (p == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       g = SDRM_BN_Init(nPrimeLen / 2 + 1);
+       if (g == NULL)
+       {
+               free(p);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand() << 16) ^ rand();
+       }
+
+       t1 = (nPrimeLen * 8 - 1) % 32;
+
+       //set security parameter for miller-rabin probabilistic primality test
+       if (nPrimeLen >= 128)
+       {
+               sp = 3;
+       }
+       else if (nPrimeLen >= 64)
+       {
+               sp = 5;
+       }
+       else if (nPrimeLen >= 15)
+       {
+               sp = 15;
+       }
+       else
+       {
+               sp = 30;
+       }
+
+       //generate p
+       p->Length = (nPrimeLen + 3) / 4;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, nPrimeLen * 8, (cc_u8*)p->pData);
+               p->pData[0] |= 1L;
+               p->pData[p->Length - 1] &= ~((-1L) << t1);
+               p->pData[p->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(p, sp) != CRYPTO_ISPRIME);
+
+       SDRM_I2OSP(p, nPrimeLen, pPrime);
+
+       memset(pGenerator, 0x00, nPrimeLen - 1);
+       pGenerator[nPrimeLen - 1] = DH_DEFAULT_GENERATOR;
+
+       SDRM_OS2BN(pGenerator, nPrimeLen, g);
+
+       if (ctx->p != NULL)
+       {
+               free(ctx->p);
+       }
+       ctx->p = p;
+
+       if (ctx->g != NULL)
+       {
+               free(ctx->g);
+       }
+       ctx->g = g;
+
+       ctx->PrimeLen = nPrimeLen;
+
+       return CRYPTO_SUCCESS;
+}
+
+/**
+ * @fn         SDRM_SetDHParam(CryptoCoreContainer* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned int pGenerator)
+ * @brief      set parameters for Diffie-Hellman protocol
+ *
+ * @param      [out] crt                               context
+ * @param      [in]  pPrime                    prime number
+ * @param      [in]  nPrimeLen                 size of pPrime buffer
+ * @param      [in]  pGenerator                generator value
+ *
+ * @return     int
+ */
+int SDRM_SetDHParam(CryptoCoreContainer* crt, unsigned char* pPrime, unsigned int nPrimeLen, unsigned char* pGenerator, unsigned int nGeneratorLen)
+{
+       SDRM_DHContext* ctx;
+       SDRM_BIG_NUM* p = NULL;
+       SDRM_BIG_NUM* g = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dhctx == NULL) || (pPrime == NULL) || (pGenerator == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->dhctx;
+
+       p = SDRM_BN_Init(nPrimeLen / 2 + 1);
+       if (p == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       g = SDRM_BN_Init(nPrimeLen / 2 + 1);
+       if (g == NULL)
+       {
+               free(p);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_OS2BN(pPrime, nPrimeLen, p);
+       SDRM_OS2BN(pGenerator, nGeneratorLen, g);
+
+       ctx->PrimeLen = nPrimeLen;
+       ctx->p = p;
+       ctx->g = g;
+
+       return CRYPTO_SUCCESS;
+}
+
+/**
+ * @fn         SDRM_GenerateDHPrivate(CryptoCoreContainer* crt, unsigned char* pPub)
+ * @brief      generate private value and calculate public value
+ *
+ * @param      [in]  crt                               context
+ * @param      [out] pPriv                             private value
+ * @param      [out] pPub                              public value
+ *
+ * @return     int
+ */
+int SDRM_GenerateDHPrivate(CryptoCoreContainer* crt, unsigned char* pPriv, unsigned char* pPub)
+{
+       SDRM_DHContext* ctx;
+       cc_u32 Seed[4] = {0,};
+       int retVal;
+       SDRM_BIG_NUM* priv = NULL;
+       SDRM_BIG_NUM* pub = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dhctx == NULL) || (pPriv == NULL) || (pPub == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->dhctx;
+
+       priv = SDRM_BN_Init(ctx->PrimeLen / 2 + 1);
+       if (priv == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       pub = SDRM_BN_Init(ctx->PrimeLen / 2 + 1);
+       if (pub == NULL)
+       {
+               free(priv);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       //generate priv
+       priv->Length = (ctx->PrimeLen + 3) / 4;
+       SDRM_RNG_X931((cc_u8 *)Seed, ctx->PrimeLen * 8, (cc_u8*)priv->pData);
+       SDRM_BN_ModRed(priv, priv, ctx->p);
+
+#ifndef _OP64_NOTSUPPORTED
+       retVal = SDRM_BN_ModExp2(pub, ctx->g, priv, ctx->p);
+#else
+       retVal = SDRM_BN_ModExp(pub, ctx->g, priv, ctx->p);
+#endif //_OP64_NOTSUPPORTED
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(priv);
+               free(pub);
+
+               return retVal;
+       }
+
+       SDRM_I2OSP(priv, ctx->PrimeLen, pPriv);
+       SDRM_I2OSP(pub, ctx->PrimeLen, pPub);
+
+       free(priv);
+       free(pub);
+
+       return CRYPTO_SUCCESS;
+}
+
+/**
+ * @fn         SDRM_GetDHSharedSecret(CryptoCoreContainer* crt, unsigned char* pPriv, unsigned char* pPub, unsigned char* pSharedSecret)
+ * @brief      calculate shared secret
+ *
+ * @param      [in]  crt                               context
+ * @param      [in]  Priv                              private value
+ * @param      [in]  pPub                              guest's public value
+ * @param      [out] pSharedSecret             public value
+ *
+ * @return     int
+ */
+int SDRM_GetDHSharedSecret(CryptoCoreContainer* crt, unsigned char* pPriv, unsigned char* pPub, unsigned char* pSharedSecret)
+{
+       SDRM_DHContext* ctx;
+       SDRM_BIG_NUM* priv = NULL;
+       SDRM_BIG_NUM* pub = NULL;
+       SDRM_BIG_NUM* SharedSecret = NULL;
+       int retVal;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dhctx == NULL) || (pPriv == NULL) || (pPub == NULL) || (pSharedSecret == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->dhctx;
+
+       priv = SDRM_BN_Init(ctx->PrimeLen / 2 + 1);
+       if (priv == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       pub = SDRM_BN_Init(ctx->PrimeLen / 2 + 1);
+       if (pub == NULL)
+       {
+               free(priv);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SharedSecret = SDRM_BN_Init(ctx->PrimeLen / 2 + 1);
+       if (SharedSecret == NULL)
+       {
+               free(priv);
+               free(pub);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_OS2BN(pPriv, ctx->PrimeLen, priv);
+       SDRM_OS2BN(pPub, ctx->PrimeLen, pub);
+
+#ifndef _OP64_NOTSUPPORTED
+       retVal = SDRM_BN_ModExp2(SharedSecret, pub, priv, ctx->p);
+#else
+       retVal = SDRM_BN_ModExp(SharedSecret, pub, priv, ctx->p);
+#endif //_OP64_NOTSUPPORTED
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(priv);
+               free(pub);
+               free(SharedSecret);
+
+               return retVal;
+       }
+
+       SDRM_I2OSP(SharedSecret, ctx->PrimeLen, pSharedSecret);
+
+       free(priv);
+       free(pub);
+       free(SharedSecret);
+
+       return CRYPTO_SUCCESS;
+}
+
+/**
+ * @fn         SDRM_FreeDHContext(CryptoCoreContainer* crt)
+ * @brief      free context buffer
+ *
+ * @param      [in]  crt                               context
+ */
+void SDRM_FreeDHContext(SDRM_DHContext* ctx)
+{
+       if (ctx != NULL)
+       {
+               if (ctx->p != NULL)
+               {
+                       free(ctx->p);
+               }
+
+               if (ctx->g != NULL)
+               {
+                       free(ctx->g);
+               }
+
+               memset(ctx, 0x00, sizeof(SDRM_DHContext));
+       }
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/middle/cc_dsa.c b/ssflib/dep/cryptocore/source/middle/cc_dsa.c
new file mode 100755 (executable)
index 0000000..c933f85
--- /dev/null
@@ -0,0 +1,608 @@
+/**
+ * \file       dsa.c
+ * @brief      implementation of dsa signature/verifycation
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/23
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_dsa.h"
+#include "cc_bignum.h"
+#include "cc_sha1.h"
+#include "cc_ANSI_x931.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_Add_DW2BA
+ * @brief      Add a UINT32 value to a Byte Array
+ *                     function works correctly only when dLen >= 4
+ *
+ * @param      BA                                              [i/o]byte array
+ * @param      dLen                                    [in]byte-length of BA
+ * @param      val                                             [in]value to add
+ *
+ * @return     void
+ */
+void SDRM_Add_DW2BA(cc_u8* BA, cc_u32 dLen, cc_u32 val)
+{
+       cc_u32 i, DIGIT = 0;
+
+       if (dLen >= 4)
+       {
+               DIGIT = BA[dLen - 4] ^ (BA[dLen - 3] << 8) ^ (BA[dLen - 2] << 16) ^ (BA[dLen - 1] << 24);
+               DIGIT += val;
+               BA[dLen - 4] = (cc_u8)(DIGIT      ) & 0xff;
+               BA[dLen - 3] = (cc_u8)(DIGIT >> 8 ) & 0xff;
+               BA[dLen - 2] = (cc_u8)(DIGIT >> 16) & 0xff;
+               BA[dLen - 1] = (cc_u8)(DIGIT >> 24) & 0xff;
+
+               if (DIGIT < val)
+               {
+                       for (i = dLen - 5; i != (cc_u32)-1; i--)
+                       {
+                               if (++BA[i] != 0) 
+                               {
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       return;
+}
+
+/*
+ * @fn         SDRM_DSA_InitCrt
+ * @brief      generate DSA Context
+ *
+ * @return     pointer to the generated context
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_DSAContext *SDRM_DSA_InitCrt()
+{
+       SDRM_DSAContext *ctx;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(sizeof(SDRM_DSAContext) + SDRM_DSA_ALLOC_SIZE * 5);
+
+       if (pbBuf == NULL)
+       {
+               return NULL;
+       }
+
+       ctx             = (SDRM_DSAContext*)(void*)pbBuf;
+       ctx->p  = SDRM_BN_Alloc((cc_u8*)ctx        + sizeof(SDRM_DSAContext),   SDRM_DSA_BN_BUFSIZE);
+       ctx->q  = SDRM_BN_Alloc((cc_u8*)ctx->p  + SDRM_DSA_ALLOC_SIZE,          SDRM_DSA_BN_BUFSIZE);
+       ctx->al = SDRM_BN_Alloc((cc_u8*)ctx->q  + SDRM_DSA_ALLOC_SIZE,          SDRM_DSA_BN_BUFSIZE);
+       ctx->y  = SDRM_BN_Alloc((cc_u8*)ctx->al + SDRM_DSA_ALLOC_SIZE,          SDRM_DSA_BN_BUFSIZE);
+       ctx->a  = SDRM_BN_Alloc((cc_u8*)ctx->y  + SDRM_DSA_ALLOC_SIZE,          SDRM_DSA_BN_BUFSIZE);
+
+       return ctx;
+}
+
+/*
+ * @fn         int SDRM_DSA_SetParam(CryptoCoreContainer *crt,
+                                cc_u8 *DSA_P_Data,     cc_u32 DSA_P_Len,
+                                cc_u8 *DSA_Q_Data,     cc_u32 DSA_Q_Len,
+                                cc_u8 *DSA_G_Data,     cc_u32 DSA_G_Len)
+ * @brief      set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      DSA_P_Data                                      [in]octet string of p value
+ * @param      DSA_P_Len                                       [in]legnth of p_val
+ * @param      DSA_Q_Data                                      [in]octet string of q value
+ * @param      DSA_Q_Len                                       [in]legnth of q_val
+ * @param      DSA_G_Data                                      [in]octet string of al value
+ * @param      DSA_G_Len                                       [in]legnth of al_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_SetParam(CryptoCoreContainer *crt,
+                                cc_u8 *DSA_P_Data,     cc_u32 DSA_P_Len,
+                                cc_u8 *DSA_Q_Data,     cc_u32 DSA_Q_Len,
+                                cc_u8 *DSA_G_Data,     cc_u32 DSA_G_Len)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dsactx == NULL) || (DSA_P_Data == NULL) || (DSA_Q_Data == NULL) || (DSA_G_Data == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_OS2BN(DSA_P_Data, DSA_P_Len, crt->ctx->dsactx->p);
+       SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->dsactx->p);
+
+       SDRM_OS2BN(DSA_Q_Data, DSA_Q_Len, crt->ctx->dsactx->q);
+       SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->dsactx->q);
+
+       SDRM_OS2BN(DSA_G_Data, DSA_G_Len, crt->ctx->dsactx->al);
+       SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->dsactx->al);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         int SDRM_DSA_SetKeyPair(CryptoCoreContainer *crt,
+                                  cc_u8 *DSA_Y_Data,   cc_u32 DSA_Y_Len,
+                                  cc_u8 *DSA_X_Data,   cc_u32 DSA_X_Len)
+ * @brief      set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      DSA_Y_Data                                      [in]octet string of y value
+ * @param      DSA_Y_Len                                       [in]legnth of y_val
+ * @param      DSA_X_Data                                      [in]octet string of a value
+ * @param      DSA_X_Len                                       [in]legnth of a_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_SetKeyPair(CryptoCoreContainer *crt,
+                                  cc_u8 *DSA_Y_Data,   cc_u32 DSA_Y_Len,
+                                  cc_u8 *DSA_X_Data,   cc_u32 DSA_X_Len)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (DSA_Y_Data != NULL)
+       {
+               SDRM_OS2BN(DSA_Y_Data, DSA_Y_Len, crt->ctx->dsactx->y);
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->dsactx->y);
+       }
+
+       if (DSA_X_Data != NULL)
+       {
+               SDRM_OS2BN(DSA_X_Data, DSA_X_Len, crt->ctx->dsactx->a);
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->dsactx->a);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_DSA_GenParam(CryptoCoreContainer *crt, cc_u32 T_Siz,
+                                cc_u8 *DSA_P_Data, cc_u32 *DSA_P_Len,
+                                cc_u8 *DSA_Q_Data, cc_u32 *DSA_Q_Len,
+                                cc_u8 *DSA_G_Data, cc_u32 *DSA_G_Len)
+ * @brief      generate and set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      T_Siz                                           [in]fix the length of p to 512 + 64t bit (0 <= T_Siz <= 8)
+ * @param      DSA_P_Data                                      [out]octet string of p value
+ * @param      DSA_P_Len                                       [out]legnth of p_val
+ * @param      DSA_Q_Data                                      [out]octet string of q value
+ * @param      DSA_Q_Len                                       [out]legnth of q_val
+ * @param      DSA_G_Data                                      [out]octet string of al value
+ * @param      DSA_G_Len                                       [out]legnth of al_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_GenParam(CryptoCoreContainer *crt, cc_u32 T_Siz,
+                                cc_u8 *DSA_P_Data, cc_u32 *DSA_P_Len,
+                                cc_u8 *DSA_Q_Data, cc_u32 *DSA_Q_Len,
+                                cc_u8 *DSA_G_Data, cc_u32 *DSA_G_Len)
+{
+       cc_u32                   i, k, L, n/*, g*/;
+       cc_u8                    pbTemp[260], pbSeed[64];
+       SDRM_SHA1Context ctx;
+       SDRM_BIG_NUM     /**BN_A, */*BN_G, *BN_P, *BN_Q, *BN_AL, *BN_Temp;
+       cc_u8                    *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (T_Siz > 8)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       L = 512 + 64 * T_Siz;
+       n = (L - 1) / 160;
+//     g = (L - 1) % 160;
+
+
+       pbBuf = (cc_u8*)malloc(SDRM_DSA_ALLOC_SIZE * 2);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+       
+       BN_G    = SDRM_BN_Alloc((cc_u8*)pbBuf,                           SDRM_DSA_BN_BUFSIZE);
+       BN_Temp = SDRM_BN_Alloc((cc_u8*)BN_G + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+
+       BN_P  = crt->ctx->dsactx->p;
+       BN_Q  = crt->ctx->dsactx->q;
+       BN_AL = crt->ctx->dsactx->al;
+//     BN_A  = crt->ctx->dsactx->a;
+
+       //generate p and q
+       while(1)
+       {
+               do
+               {
+                       //choose a random seed s of bitlength g >= 160
+                       for (i = 0; i < SDRM_SHA1_BLOCK_SIZ; i++)
+                       {
+                               pbSeed[i] = (rand() << 16) ^ rand();
+                       }
+                       pbSeed[0] |= 0x80;
+                       pbSeed[SDRM_SHA1_BLOCK_SIZ - 1] |= 0x01;
+
+                       //U = H(s) xor H((s + 1) mod g)
+                       SDRM_SHA1_Init(&ctx);
+                       SDRM_SHA1_Update(&ctx, pbSeed, SDRM_SHA1_BLOCK_SIZ);
+                       SDRM_SHA1_Final(&ctx, pbTemp);
+
+                       SDRM_INC_BA(pbSeed, SDRM_SHA1_BLOCK_SIZ);
+
+                       SDRM_SHA1_Init(&ctx);
+                       SDRM_SHA1_Update(&ctx, pbSeed, SDRM_SHA1_BLOCK_SIZ);
+                       SDRM_SHA1_Final(&ctx, pbTemp + SDRM_SHA1_BLOCK_SIZ);
+
+                       for (i = 0; i < SDRM_SHA1_BLOCK_SIZ / sizeof(cc_u32); i++)
+                       {
+                               ((cc_u32*)(void*)pbTemp)[i] ^= ((cc_u32*)(void*)pbTemp)[i + SDRM_SHA1_BLOCK_SIZ / sizeof(cc_u32)];
+                       }
+
+                       pbTemp[0] |= 0x80;
+                       pbTemp[SDRM_SHA1_BLOCK_SIZ - 1] |= 0x01;
+
+                       SDRM_OS2BN(pbTemp, SDRM_SHA1_BLOCK_SIZ, BN_Q);
+               }
+               while(SDRM_BN_MILLER_RABIN(BN_Q, 18) != CRYPTO_SUCCESS);
+
+               SDRM_INC_BA(pbSeed, SDRM_SHA1_BLOCK_SIZ);
+
+               for (i = 0; i < 4096; i++)
+               {
+                       for (k = 0; k <= n; k++)
+                       {
+                               SDRM_SHA1_Init(&ctx);
+                               SDRM_SHA1_Update(&ctx, pbSeed, SDRM_SHA1_BLOCK_SIZ);
+                               SDRM_SHA1_Final(&ctx, pbTemp + (n - k) * SDRM_SHA1_BLOCK_SIZ);
+                               SDRM_Add_DW2BA(pbSeed, SDRM_SHA1_BLOCK_SIZ, n + 2);
+                       }
+
+                       pbTemp[(n + 1) * SDRM_SHA1_BLOCK_SIZ - L / 8] |= 0x80;
+                       SDRM_OS2BN(pbTemp + (n + 1) * SDRM_SHA1_BLOCK_SIZ - L / 8, L / 8, BN_P);
+
+                       SDRM_BN_SHL(BN_Q, BN_Q, 1);
+                       SDRM_BN_ModRed(BN_Temp, BN_P, BN_Q);
+                       SDRM_BN_SHR(BN_Q, BN_Q, 1);
+                       SDRM_BN_Sub(BN_P, BN_P, BN_Temp);
+                       SDRM_BN_Add(BN_P, BN_P, BN_One);
+
+                       if (SDRM_CheckBitUINT32(BN_P->pData, L - 1))
+                       {
+                               if (SDRM_BN_MILLER_RABIN(BN_P, 5) == CRYPTO_ISPRIME)
+                               {
+                                       goto SUCCESS;
+                               }
+                               else
+                               {
+                                       break;
+                               }
+                       }
+               }
+       }
+
+SUCCESS :
+       //select a generator al(alpha) of the unique cyclic group of order q in Zp
+       SDRM_BN_Clr(BN_Temp);
+       //temp = (p-1)/q
+       SDRM_BN_Sub(BN_Temp, BN_P, BN_One);
+       SDRM_BN_Div(BN_Temp, NULL, BN_Temp, BN_Q);
+
+       do {
+               //select an element g excluded in Zp*
+               do {
+                       SDRM_RNG_X931(pbSeed, L, (cc_u8*)BN_G->pData);
+                       BN_G->Length = L / 32 + 1;
+                       SDRM_BN_OPTIMIZE_LENGTH(BN_G);
+               }
+               while(SDRM_BN_Cmp(BN_G, BN_P) >= 0);
+
+               //al(alpha) = g^temp mod p
+               SDRM_BN_ModExp(BN_AL, BN_G, BN_Temp, BN_P);
+       }
+       while (SDRM_BN_Cmp(BN_AL, BN_One) == 0);
+
+       //write output
+       if (DSA_P_Data != NULL)
+       {
+               SDRM_I2OSP(BN_P, L / 8, DSA_P_Data);
+       }
+
+       if (DSA_P_Len != NULL)
+       {
+               *DSA_P_Len = L / 8;
+       }
+
+       if (DSA_Q_Data != NULL)
+       {
+               SDRM_I2OSP(BN_Q, 20, DSA_Q_Data);
+       }
+
+       if (DSA_Q_Len != NULL)
+       {
+               *DSA_Q_Len = 20;
+       }
+
+       if (DSA_G_Data != NULL)
+       {
+               SDRM_I2OSP(BN_AL, BN_AL->Length * 4, DSA_G_Data);
+       }
+
+       if (DSA_G_Len != NULL)
+       {
+               *DSA_G_Len = BN_AL->Length * 4;
+       }
+       
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_DSA_GenKeypair(CryptoCoreContainer *crt,
+                                           cc_u8 *DSA_Y_Data, cc_u32 *DSA_Y_Len,
+                                           cc_u8 *DSA_X_Data, cc_u32 *DSA_X_Len)
+ * @brief      generate and set DSA parameters
+ *
+ * @param      crt                                                     [out]dsa context
+ * @param      DSA_Y_Data                                      [out]octet string of y value
+ * @param      DSA_Y_Len                                       [out]legnth of y_val
+ * @param      DSA_X_Data                                      [out]octet string of a value
+ * @param      DSA_X_Len                                       [out]legnth of a_val
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if input parameter pointer is null
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_ERROR                            if conversion is failed
+ */
+int SDRM_DSA_GenKeypair(CryptoCoreContainer *crt,
+                                           cc_u8 *DSA_Y_Data, cc_u32 *DSA_Y_Len,
+                                           cc_u8 *DSA_X_Data, cc_u32 *DSA_X_Len)
+{
+       SDRM_BIG_NUM *BN_A;
+       cc_u32           Seed[4], i;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       BN_A = crt->ctx->dsactx->a;
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand() << 16) ^ rand();
+       }
+
+       //Select a random integer a such that 1 <= a <= q-1
+       do {
+               SDRM_RNG_X931((cc_u8*)Seed, 160, (cc_u8*)BN_A->pData);
+               BN_A->Length = 6;                                       //6 = 160 / 32 + 1
+               SDRM_BN_OPTIMIZE_LENGTH(BN_A);
+       }
+       while(SDRM_BN_Cmp(BN_A, crt->ctx->dsactx->q) >= 0);
+
+       //y = al ^ a mod p
+       SDRM_BN_ModExp(crt->ctx->dsactx->y, crt->ctx->dsactx->al, BN_A, crt->ctx->dsactx->p);
+
+
+       //write output
+       if (DSA_Y_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->dsactx->y, crt->ctx->dsactx->y->Length * 4, DSA_Y_Data);
+       }
+
+       if (DSA_Y_Len != NULL)
+       {
+               *DSA_Y_Len = crt->ctx->dsactx->y->Length * 4;
+       }
+
+       if (DSA_X_Data != NULL)
+       {
+               SDRM_I2OSP(BN_A, BN_A->Length * 4, DSA_X_Data);
+       }
+
+       if (DSA_X_Len != NULL)
+       {
+               *DSA_X_Len = BN_A->Length * 4;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_DSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      hash                            [in]hash value
+ * @param      hashLen                         [in]byte-length of hash
+ * @param      signature                       [out]generated signature
+ * @param      signLen                         [out]byte-length of signature
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_DSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+{
+       cc_u8            pbSeed[16] = {0};
+       SDRM_BIG_NUM *BN_P, *BN_Q, *BN_AL, *BN_A;
+       SDRM_BIG_NUM *BN_r, *BN_s, *BN_k, *BN_hash, *BN_ar, *temp1, *temp2;
+
+       cc_u8*  pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dsactx == NULL) || (crt->ctx->dsactx->a == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_DSA_ALLOC_SIZE * 7);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_r    = SDRM_BN_Alloc( pbBuf,                          SDRM_DSA_BN_BUFSIZE);
+       BN_s    = SDRM_BN_Alloc((cc_u8*)BN_r    + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       BN_k    = SDRM_BN_Alloc((cc_u8*)BN_s    + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       BN_hash = SDRM_BN_Alloc((cc_u8*)BN_k    + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       BN_ar   = SDRM_BN_Alloc((cc_u8*)BN_hash + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       temp1   = SDRM_BN_Alloc((cc_u8*)BN_ar   + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       temp2   = SDRM_BN_Alloc((cc_u8*)temp1   + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+
+       BN_P  = crt->ctx->dsactx->p;
+       BN_Q  = crt->ctx->dsactx->q;
+       BN_AL = crt->ctx->dsactx->al;
+       BN_A  = crt->ctx->dsactx->a;
+
+       //select a random secret integer k, 0 < k < q
+       do {
+               SDRM_RNG_X931(pbSeed, 160, (cc_u8*)BN_k->pData);
+               BN_k->Length = 6;                                       //6 = 160 / 32 + 1
+               SDRM_BN_OPTIMIZE_LENGTH(BN_k);
+       }
+       while(SDRM_BN_Cmp(BN_k, BN_Q) > 0);
+
+       SDRM_BN_ModExp(temp1, BN_AL, BN_k, BN_P);
+       //r = (al ^ k mod p) mod q
+       SDRM_BN_ModRed(BN_r, temp1, BN_Q);
+
+       SDRM_BN_ModInv(temp1, BN_k, BN_Q);
+
+       SDRM_OS2BN((cc_u8*)hash, hashLen, BN_hash);
+
+       SDRM_BN_Mul(BN_ar, BN_A, BN_r);
+       SDRM_BN_Add(temp2, BN_hash, BN_ar);
+
+       SDRM_BN_ModRed(temp2, temp2, BN_Q);
+
+       SDRM_BN_ModMul(BN_s, temp1, temp2, BN_Q);
+
+       SDRM_I2OSP(BN_r, 20, signature);
+       SDRM_I2OSP(BN_s, 20, signature + 20);
+
+       if (signLen != NULL)
+       {
+               *signLen = 40;
+       }
+
+       free(pbBuf);
+       
+       return CRYPTO_SUCCESS;
+ }
+
+/*
+ * @fn         int SDRM_DSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      hash                                    [in]hash value
+ * @param      hashLen                                 [in]byte-length of hash
+ * @param      signature                               [in]signature
+ * @param      signLen                                 [in]byte-length of signature
+ * @param      result                                  [in]result of veryfing signature
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if the length of signature is invalid
+ */
+int SDRM_DSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result)
+{
+       SDRM_BIG_NUM *w, *u1, *u2, *v, *BNH_m, *BN_r, *BN_s;
+       SDRM_BIG_NUM *temp1, *temp2, *temp3;
+
+       cc_u8            *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->dsactx == NULL) || (crt->ctx->dsactx->y == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_DSA_ALLOC_SIZE * 10);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       w         =     SDRM_BN_Alloc( pbBuf,                                 SDRM_DSA_BN_BUFSIZE);
+       u1        = SDRM_BN_Alloc((cc_u8*)w     + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       u2        = SDRM_BN_Alloc((cc_u8*)u1    + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       v         =     SDRM_BN_Alloc((cc_u8*)u2    + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       BNH_m = SDRM_BN_Alloc((cc_u8*)v     + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       BN_r  = SDRM_BN_Alloc((cc_u8*)BNH_m + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       BN_s  = SDRM_BN_Alloc((cc_u8*)BN_r  + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       temp1 = SDRM_BN_Alloc((cc_u8*)BN_s  + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       temp2 = SDRM_BN_Alloc((cc_u8*)temp1 + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+       temp3 = SDRM_BN_Alloc((cc_u8*)temp2 + SDRM_DSA_ALLOC_SIZE, SDRM_DSA_BN_BUFSIZE);
+
+
+       if ((SDRM_BN_Cmp(BN_r, crt->ctx->dsactx->q) >= 0) || (SDRM_BN_Cmp(BN_s, crt->ctx->dsactx->q) >= 0))                     //r < q and s < q
+       {
+               free(pbBuf);
+               return CRYPTO_ERROR;
+       }
+
+       if (signLen != 40)
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+
+       SDRM_OS2BN((cc_u8*)signature,     20, BN_r);
+       SDRM_OS2BN((cc_u8*)signature + 20, 20, BN_s);
+
+
+       SDRM_BN_ModInv(w, BN_s, crt->ctx->dsactx->q);                                                   //w = s^-1 mod q
+       SDRM_OS2BN((cc_u8*)hash, 20, BNH_m);
+
+       SDRM_BN_ModMul(u1, w, BNH_m, crt->ctx->dsactx->q);                                              //u1 = w x h(m) mod q
+       SDRM_BN_ModMul(u2, BN_r, w, crt->ctx->dsactx->q);                                               //u2 = rw mod q
+
+       SDRM_BN_ModExp(temp1, crt->ctx->dsactx->al, u1, crt->ctx->dsactx->p);   //temp1 = alpha^u1 mod p
+       SDRM_BN_ModExp(temp2, crt->ctx->dsactx->y,  u2, crt->ctx->dsactx->p);   //temp2 = y^u2 mod p
+
+       SDRM_BN_ModMul(temp3, temp1, temp2, crt->ctx->dsactx->p);                               //temp3 = (alpha^u1 x y^u2 mod p) mod p
+
+       SDRM_BN_ModRed(v, temp3, crt->ctx->dsactx->q);                                                  //v = (alpha^u1 x y^u2 mod p) mod q
+
+//     SDRM_PrintBN("v    : ", v);
+//     SDRM_PrintBN("Hash : ", BNH_m);
+
+       if (SDRM_BN_Cmp(v, BN_r) == 0)
+       {
+               *result = CRYPTO_VALID_SIGN;
+       }
+       else
+       {
+               *result = CRYPTO_INVALID_SIGN;
+       }
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/middle/cc_ecdh.c b/ssflib/dep/cryptocore/source/middle/cc_ecdh.c
new file mode 100755 (executable)
index 0000000..5882576
--- /dev/null
@@ -0,0 +1,204 @@
+/**
+ * \file       ecdh.c
+ * @brief      implementation of EC Diffie-Hellman Key Exchange Protocol
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/27
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_ecdh.h"
+#include "cc_ANSI_x931.h"
+#include "cc_ecc.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_generateDH1stPhaseKey
+ * @brief      generate Xk and its Xv
+ *
+ * @param      crt                                     [in]crypto context
+ * @param      pchXk                           [out]Generated Random Number
+ * @param      pchXv                           [out]DH 1st phase value
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_generateDH1stPhaseKey(CryptoCoreContainer *crt, cc_u8 *pchXk, cc_u8 *pchXv)
+{
+       cc_u8 Si_ANSI_X9_31[SDRM_X931_SEED_SIZ];
+
+       SDRM_BIG_NUM    *BN_Xk, *BN_Temp;
+       SDRM_EC_POINT   *kP;
+       SDRM_ECC_CTX    *ctx;
+       int i;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdhctx == NULL) || (pchXk == NULL) || (pchXv == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->ecdhctx;
+
+       for (i = 0; i < SDRM_X931_SEED_SIZ; i++)
+       {
+               Si_ANSI_X9_31[i] = ((rand() << 16) + rand()) & 0xff;
+       }
+
+
+       BN_Temp = SDRM_BN_Init(crt->ctx->ecdsactx->uDimension >> 3);
+       if (BN_Temp == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_Xk = SDRM_BN_Init(crt->ctx->ecdsactx->uDimension >> 3);
+       if (BN_Xk == NULL)
+       {
+               free(BN_Temp);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_BN_Sub(BN_Temp, ctx->ECC_n, BN_One);
+       do {
+               SDRM_RNG_X931(Si_ANSI_X9_31, crt->ctx->ecdsactx->uDimension, pchXk);
+               SDRM_OS2BN(pchXk, crt->ctx->ecdsactx->uDimension >> 3,  BN_Xk);
+       }
+       while ((SDRM_BN_Cmp(BN_Xk, BN_One) < 0) || (SDRM_BN_Cmp(BN_Xk, BN_Temp) > 0));
+
+       kP = SDRM_ECC_Init();
+       if (kP == NULL)
+       {
+               free(BN_Temp);
+               free(BN_Xk);
+
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       if (SDRM_CTX_EC_kP(ctx, kP, ctx->ECC_G, BN_Xk) == CRYPTO_MEMORY_ALLOC_FAIL)
+       {
+               free(BN_Temp);
+               free(BN_Xk);
+               free(kP);
+
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_BN2OS(kP->x, crt->ctx->ecdsactx->uDimension >> 3, pchXv); 
+       SDRM_BN2OS(kP->y, crt->ctx->ecdsactx->uDimension >> 3, pchXv + (crt->ctx->ecdsactx->uDimension >> 3));
+
+       free(BN_Temp);
+       free(BN_Xk);
+       free(kP);
+       
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_generateDHKey
+ * @brief      genenrate auth key with Xk and Yv
+ *
+ * @param      crt                                     [in]crypto context
+ * @param      pchXk                           [in]Generated Random Number
+ * @param      pchYv                           [in]DH 1st phase value
+ * @param      pchKauth                        [out]authentication key
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_generateDHKey(CryptoCoreContainer *crt, cc_u8* pchXk, cc_u8* pchYv, cc_u8* pchKauth)
+{
+       SDRM_BIG_NUM    *BN_Xk;
+       SDRM_EC_POINT   *kP, *EC_Yv;
+       SDRM_ECC_CTX    *ctx;
+       int retVal;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdhctx == NULL) || (pchXk == NULL) || (pchYv == NULL) || (pchKauth == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->ecdhctx;
+
+       BN_Xk = SDRM_BN_Init(crt->ctx->ecdsactx->uDimension >> 3);
+       if (BN_Xk == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       retVal = SDRM_OS2BN(pchXk, crt->ctx->ecdsactx->uDimension >> 3, BN_Xk);
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(BN_Xk);
+               return retVal;
+       }
+
+       kP = SDRM_ECC_Init();
+       if (kP == NULL)
+       {
+               free(BN_Xk);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       EC_Yv = SDRM_ECC_Init();
+       if (EC_Yv == NULL)
+       {
+               free(BN_Xk);
+               free(kP);
+
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       SDRM_EC_CLR(EC_Yv);
+       retVal = SDRM_OS2BN(pchYv, crt->ctx->ecdsactx->uDimension >> 3, EC_Yv->x);
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(BN_Xk);
+               free(kP);
+               free(EC_Yv);
+
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       retVal = SDRM_OS2BN(pchYv + (crt->ctx->ecdsactx->uDimension >> 3), crt->ctx->ecdsactx->uDimension >> 3, EC_Yv->y);
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(BN_Xk);
+               free(kP);
+               free(EC_Yv);
+
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+               
+       if (SDRM_CTX_EC_kP(ctx, kP, EC_Yv, BN_Xk) == CRYPTO_MEMORY_ALLOC_FAIL)
+       {
+               free(BN_Xk);
+               free(kP);
+               free(EC_Yv);
+
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       retVal = SDRM_BN2OS(kP->x, crt->ctx->ecdsactx->uDimension >> 3, pchKauth); 
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(BN_Xk);
+               free(kP);
+               free(EC_Yv);
+
+               return retVal;
+       }
+
+       free(BN_Xk);
+       free(kP);
+       free(EC_Yv);
+               
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/middle/cc_ecdsa.c b/ssflib/dep/cryptocore/source/middle/cc_ecdsa.c
new file mode 100755 (executable)
index 0000000..7a7918c
--- /dev/null
@@ -0,0 +1,666 @@
+/**
+ * \file       ecdsa.c
+ * @brief      implementation of public key signature algorithm
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/13
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#ifdef _WIN32_WCE
+#include <winbase.h>
+#endif
+#include <time.h>
+#include "cc_ecdsa.h"
+#include "cc_ANSI_x931.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_CTX_ECDSA_KEY_GEN
+ * @brief      generate signature
+ *
+ * @param      ctx                                                     [out]ecc context
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_NULL_POINTER                     if any argument is a null pointer
+ */
+int SDRM_CTX_ECDSA_KEY_GEN(SDRM_ECC_CTX *ctx)
+{
+       int                             i, retVal;
+       cc_u32                  Seed[4];
+       SDRM_BIG_NUM    *BN_d, *BN_temp;
+       SDRM_EC_POINT   *kP;
+       
+       cc_u8                   *pbBuf = NULL;
+
+       if (ctx == NULL)
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+       
+       pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 2);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_d    = SDRM_BN_Alloc( pbBuf                                                  , SDRM_ECC_BN_BUFSIZE);
+       BN_temp = SDRM_BN_Alloc((cc_u8*)BN_d + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       kP = SDRM_ECC_Init();
+       if (kP == NULL)
+       {
+               free(pbBuf);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand() << 16) ^ rand();
+       }
+
+       SDRM_BN_Sub(BN_temp, ctx->ECC_n, BN_One);
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, ctx->uDimension, (cc_u8*)BN_d->pData);
+               BN_d->Length =  ctx->uDimension / 32;
+       }
+       while ((SDRM_BN_Cmp(BN_d, BN_One) < 0) || (SDRM_BN_Cmp(BN_d, BN_temp) > 0));
+
+       SDRM_BN_OPTIMIZE_LENGTH(BN_d);
+
+       SDRM_EC_SET_ZERO(kP);
+       retVal = SDRM_CTX_EC_kP(ctx, kP, ctx->ECC_G, BN_d);
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               free(kP);
+
+               return retVal;
+       }
+
+       SDRM_BN_Copy(ctx->PRIV_KEY, BN_d);
+       SDRM_EC_COPY(ctx->PUBLIC_KEY, kP);
+
+       free(pbBuf);
+       free(kP);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_CTX_ECDSA_SIG_GEN
+ * @brief      generate signature
+ *
+ * @param      ctx                                                     [in]ecc context
+ * @param      sig                                                     [out]generated signature
+ * @param      hash                                            [in]hashed message
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_NULL_POINTER                     if any argument is a null pointer
+ */
+int SDRM_CTX_ECDSA_SIG_GEN(SDRM_ECC_CTX *ctx, cc_u8 *sig, cc_u8 *hash, unsigned int hashLen)
+{
+       int                             i, res = -1; 
+       cc_u32                  Seed[20];
+       SDRM_BIG_NUM    *BN_Tmp1, *BN_Tmp2, *BN_Tmp3;
+       SDRM_BIG_NUM    *BN_k, *BN_r, *BN_s, *BN_hash; 
+       SDRM_EC_POINT   *kP;
+
+       cc_u8                   *pbBuf = NULL;
+
+       if ((ctx== NULL) || (sig == NULL) || (hash == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 7);
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_Tmp1 = SDRM_BN_Alloc( pbBuf,                                                           SDRM_ECC_BN_BUFSIZE);
+       BN_Tmp2 = SDRM_BN_Alloc((cc_u8*)BN_Tmp1 + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_Tmp3 = SDRM_BN_Alloc((cc_u8*)BN_Tmp2 + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_k    = SDRM_BN_Alloc((cc_u8*)BN_Tmp3 + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_r    = SDRM_BN_Alloc((cc_u8*)BN_k    + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_s    = SDRM_BN_Alloc((cc_u8*)BN_r    + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_hash = SDRM_BN_Alloc((cc_u8*)BN_s    + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+
+       kP = SDRM_ECC_Init();
+       if (kP == NULL)
+       {
+               free(pbBuf);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand()  << 16) ^ rand();
+       }
+
+       while(1)
+       {
+               while(1)
+               {
+                       //      1. [1, r-1] »çÀÌÀÇ ³­¼ö k ¼±ÅÃ
+                       SDRM_BN_Sub(BN_Tmp1, ctx->ECC_n, BN_One);
+                       do {
+                               SDRM_RNG_X931((cc_u8 *)Seed, ctx->uDimension, (cc_u8*)BN_k->pData);
+                               BN_k->Length = ctx->uDimension / 32;
+                       }
+                       while((SDRM_BN_Cmp(BN_k, BN_One) < 0) || (SDRM_BN_Cmp(BN_k, BN_Tmp1) > 0));
+
+                       //      2. kP = (x1, y1), r = x1 mod n(&ctx.ECC_n) °è»ê. r = 0 À̸é k ´Ù½Ã ¼±Åà
+                       SDRM_EC_SET_ZERO(kP);
+                       res = SDRM_CTX_EC_kP(ctx, kP, ctx->ECC_G, BN_k);
+                       if (res != CRYPTO_SUCCESS)
+                       {
+                               free(pbBuf);
+                               free(kP);
+
+                               return res;
+                       }
+
+                       //SDRM_PrintBN("kP->x", kP->x); 
+                       SDRM_BN_ModRed(BN_r, kP->x, ctx->ECC_n);        
+                       if (BN_r->Length > 0)           // r = 0 À̸é k ´Ù½Ã ¼±ÅÃ
+                       {
+                               break;
+                       }
+               }
+
+       //      3. k^{-1} mod n °è»ê.
+               SDRM_BN_ModInv(BN_Tmp1, BN_k, ctx->ECC_n);
+
+               //SDRM_PrintBN("BN_k", BN_k); 
+               //SDRM_PrintBN("ctx->ECC_n", ctx->ECC_n); 
+               //SDRM_PrintBN("BN_Tmp1 = k^{-1} mod n", BN_Tmp1); 
+
+       //      4. s = k^{-1}(hash + dr) mod n °è»ê (d = private key). s = 0 À̸é 1¹øÀ¸·Î. 
+               // BN_Tmp2 = dr
+               SDRM_OS2BN(hash, hashLen, BN_hash); 
+
+               SDRM_BN_ModMul(BN_Tmp2, ctx->PRIV_KEY, BN_r, ctx->ECC_n);
+               SDRM_BN_ModAdd(BN_Tmp3, BN_hash, BN_Tmp2, ctx->ECC_n);
+               SDRM_BN_ModMul(BN_s, BN_Tmp1, BN_Tmp3, ctx->ECC_n);
+               if (BN_s->Length > 0)
+               {
+                       break;
+               }
+       }
+
+//     (r, s) ¼­¸íÀ¸·Î Ãâ·Â.
+       //SDRM_PrintBN("BN_r", BN_r);
+       //SDRM_PrintBN("BN_s", BN_s);
+
+       SDRM_BN2OS(BN_r, ctx->uDimension / 8, sig);
+       SDRM_BN2OS(BN_s, ctx->uDimension / 8, sig + ctx->uDimension / 8);
+
+       free(kP);
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS; 
+}
+
+/*
+ * @fn         SDRM_CTX_ECDSA_SIG_VERIFY
+ * @brief      verify ecdsa signature
+ *
+ * @param      ctx                                                     [in]ecc context
+ * @param      sig                                                     [out]generated signature
+ * @param      signLen                                         [out]byte-length of signature
+ * @param      hash                                            [in]hash value
+ * @param      hashLen                                         [in]byte-length of hash
+ *
+ * @return     CRYPTO_VALID_SIGN                       if given signature is valid
+ * \n          CRYPTO_INVALID_SIGN                     if given signature is invalid
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ * \n          CRYPTO_INVALID_ARGUMENT         if any argument is out of range
+ * \n          CRYPTO_INFINITY_INPUT           if given argument represents an infinity value
+ */
+int SDRM_CTX_ECDSA_SIG_VERIFY(SDRM_ECC_CTX *ctx, cc_u8 *sig, int signLen, cc_u8 *hash, int hashLen)
+{
+       int                             res;
+       SDRM_BIG_NUM    *BN_tmp, *BN_u1, *BN_u2, *BN_w, *BN_hash, *pBN_r, *pBN_s;
+       SDRM_EC_POINT   *EC_temp1, *EC_temp2; 
+
+       cc_u8 *pbBuf = (cc_u8*)malloc(SDRM_ECC_ALLOC_SIZE * 7);
+       
+       if (!pbBuf)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+       
+       BN_tmp  = SDRM_BN_Alloc( pbBuf,                                                          SDRM_ECC_BN_BUFSIZE);
+       BN_u1   = SDRM_BN_Alloc((cc_u8*)BN_tmp + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_u2   = SDRM_BN_Alloc((cc_u8*)BN_u1  + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_w    = SDRM_BN_Alloc((cc_u8*)BN_u2  + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       BN_hash = SDRM_BN_Alloc((cc_u8*)BN_w   + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       pBN_r   = SDRM_BN_Alloc((cc_u8*)BN_hash+ SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       pBN_s   = SDRM_BN_Alloc((cc_u8*)pBN_r  + SDRM_ECC_ALLOC_SIZE, SDRM_ECC_BN_BUFSIZE);
+       
+       EC_temp1 = SDRM_ECC_Init();
+       if (EC_temp1 == NULL)
+       {
+               free(pbBuf);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       EC_temp2 = SDRM_ECC_Init();
+       if (EC_temp2 == NULL)
+       {
+               free(pbBuf);
+               free(EC_temp1);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       if ((cc_u32)signLen != (ctx->uDimension / 4))
+       {
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       SDRM_OS2BN(sig, ctx->uDimension / 8, pBN_r);    
+       SDRM_OS2BN(sig + ctx->uDimension / 8, ctx->uDimension / 8, pBN_s);      
+       //SDRM_PrintBN("BN_r", pBN_r);
+       //SDRM_PrintBN("BN_s", pBN_s);
+
+       //      1. r°ú sÀÇ ¹üÀ§ Á¶»ç 
+       SDRM_BN_Sub(BN_tmp, ctx->ECC_n, BN_One);
+       if ((SDRM_BN_Cmp(pBN_r, BN_One) < 0) || (SDRM_BN_Cmp(pBN_r, BN_tmp) > 0))
+       {
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if ((SDRM_BN_Cmp(pBN_s, BN_One) < 0) || (SDRM_BN_Cmp(pBN_s, BN_tmp) > 0))
+       {
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+       
+       //      2. w = s^(-1) mod n, BN_hash °è»ê 
+       SDRM_OS2BN(hash, hashLen, BN_hash); 
+       res = SDRM_BN_ModInv(BN_w, pBN_s, ctx->ECC_n);
+//SDRM_PrintBN("BN_w", BN_w);
+
+       if (res != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+
+               return res;
+       }
+
+       //      3. u1 = BN_hash *w mod n, u2 = rw mod n
+       SDRM_BN_ModMul(BN_u1, BN_hash, BN_w, ctx->ECC_n);                       
+       SDRM_BN_ModMul(BN_u2, pBN_r,   BN_w, ctx->ECC_n);
+//SDRM_PrintBN("BN_u1", BN_u1);
+//SDRM_PrintBN("BN_u2", BN_u2);
+
+       //      4. (x0, y0) = u1P + u2Q, V = x0 mod n
+       res = SDRM_CTX_EC_2kP(ctx, EC_temp1, BN_u1, ctx->ECC_G, BN_u2, ctx->PUBLIC_KEY);
+       if (res != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+
+               return res;
+       }
+       else if(EC_temp1->IsInfinity == 1)
+       {
+               res = CRYPTO_INFINITY_INPUT;
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+
+               return res;
+       }
+       
+//     SDRM_PrintBN("EC_temp1->x", EC_temp1->x);
+//     SDRM_PrintBN("ctx->ECC_n", ctx->ECC_n);
+       SDRM_BN_ModRed(BN_tmp, EC_temp1->x, ctx->ECC_n);        
+
+//     SDRM_PrintBN("BN_tmp", BN_tmp);
+//     SDRM_PrintBN("pBN_r", pBN_r);
+       // 5. V = rÀΠ°æ¿ì ¼­¸í ok
+       res = SDRM_BN_Cmp_sign(BN_tmp, pBN_r);
+       if (res != 0)
+       {
+               res = CRYPTO_INVALID_SIGN;
+               free(pbBuf);
+               free(EC_temp1);
+               free(EC_temp2);
+
+               return res; 
+       }
+
+       //Success
+       free(pbBuf);
+       free(EC_temp1);
+       free(EC_temp2);
+
+       return CRYPTO_VALID_SIGN; 
+}
+
+/*
+ * @fn         SDRM_ECDSA_sign
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      hash                            [in]hash value
+ * @param      hashLen                         [in]byte-length of hash
+ * @param      signature                       [out]generated signature
+ * @param      signLen                         [out]byte-length of signature
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_ECDSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdsactx == NULL) || (hash == NULL) || (signature == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (signLen)
+       {
+               *signLen = crt->ctx->ecdsactx->uDimension / 4;
+       }
+
+       return SDRM_CTX_ECDSA_SIG_GEN(crt->ctx->ecdsactx, signature, hash, hashLen);
+}
+
+/*
+ * @fn         SDRM_ECDSA_verify
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      hash                                    [in]hash value
+ * @param      hashLen                                 [in]byte-length of hash
+ * @param      signature                               [in]signature
+ * @param      signLen                                 [in]byte-length of signature
+ * @param      result                                  [in]result of veryfing signature
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if the length of signature is invalid
+ */
+int SDRM_ECDSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result)
+{
+       int retVal;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdsactx == NULL) || (hash == NULL) || (signature == NULL) || (result == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (signLen != (crt->ctx->ecdsactx->uDimension / 4))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       retVal = SDRM_CTX_ECDSA_SIG_VERIFY(crt->ctx->ecdsactx, signature, signLen, hash, hashLen);
+
+       if (retVal == CRYPTO_VALID_SIGN)
+       {
+               *result = CRYPTO_VALID_SIGN;
+       }
+       else
+       {
+               *result = CRYPTO_INVALID_SIGN;
+       }
+
+       return retVal;
+}
+
+/*
+ * @fn         SDRM_ECC_Set_CTX
+ * @brief      Set parameters for ECC
+ *
+ * @param      crt                                     [out]crypto env structure
+ * @param      Dimension                       [in]dimension
+ * @param      ECC_P_Data                      [in]represents p
+ * @param      ECC_P_Len                       [in]byte-length of p
+ * @param      ECC_A_Data                      [in]represents a
+ * @param      ECC_A_Len                       [in]byte-length of a
+ * @param      ECC_B_Data                      [in]represents b
+ * @param      ECC_B_Len                       [in]byte-length of b
+ * @param      ECC_G_X_Data            [in]represents x coordinate of g
+ * @param      ECC_G_X_Len                     [in]byte-length of x coordinate of g
+ * @param      ECC_G_Y_Data            [in]represents y coordinate of g
+ * @param      ECC_G_Y_Len                     [in]byte-length of y coordinate of g
+ * @param      ECC_R_Data                      [in]represents r
+ * @param      ECC_R_Len                       [in]byte-length of r
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if argument is null
+ */
+int SDRM_ECC_Set_CTX(CryptoCoreContainer *crt, cc_u16 Dimension, 
+                                        cc_u8* ECC_P_Data,   cc_u32 ECC_P_Len,
+                                        cc_u8* ECC_A_Data,   cc_u32 ECC_A_Len,
+                                        cc_u8* ECC_B_Data,   cc_u32 ECC_B_Len,
+                                        cc_u8* ECC_G_X_Data, cc_u32 ECC_G_X_Len,
+                                        cc_u8* ECC_G_Y_Data, cc_u32 ECC_G_Y_Len,
+                                        cc_u8* ECC_R_Data,   cc_u32 ECC_R_Len)
+{
+       int                             retVal;
+       cc_u8                   zero[] = {0x00};
+       SDRM_ECC_CTX    *ECC_ctx;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if ((ECC_P_Data == NULL) || (ECC_A_Data == NULL) || (ECC_B_Data == NULL) || (ECC_G_X_Data == NULL) || (ECC_G_Y_Data == NULL) || (ECC_R_Data == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ECC_ctx = crt->ctx->ecdhctx;
+
+       ECC_ctx->uDimension = Dimension;
+
+       retVal = SDRM_OS2BN(ECC_P_Data, ECC_P_Len, ECC_ctx->ECC_p); 
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(ECC_ctx);
+               return retVal;
+       }
+
+       retVal = SDRM_OS2BN(ECC_A_Data, ECC_A_Len, ECC_ctx->ECC_a); 
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(ECC_ctx);
+               return retVal;
+       }
+
+       retVal = SDRM_OS2BN(ECC_B_Data, ECC_B_Len, ECC_ctx->ECC_b); 
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(ECC_ctx);
+               return retVal;
+       }
+
+       retVal = SDRM_OS2BN(ECC_R_Data, ECC_R_Len, ECC_ctx->ECC_n); 
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(ECC_ctx);
+               return retVal;
+       }
+       
+       ECC_ctx->ECC_G->IsInfinity = 0;
+       retVal = SDRM_OS2BN(ECC_G_X_Data, ECC_G_X_Len, ECC_ctx->ECC_G->x); 
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(ECC_ctx);
+               return retVal;
+       }
+       retVal = SDRM_OS2BN(ECC_G_Y_Data, ECC_G_Y_Len, ECC_ctx->ECC_G->y);      
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(ECC_ctx);
+               return retVal;
+       }
+
+       SDRM_OS2BN(zero, 0, ECC_ctx->ECC_G->z);
+       SDRM_OS2BN(zero, 0, ECC_ctx->ECC_G->z2);
+       SDRM_OS2BN(zero, 0, ECC_ctx->ECC_G->z3);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_ECC_genKeypair
+ * @brief      Generate Private Key and Generate Key Pair for ECC Signature
+ *
+ * @param      crt                                     [out]crypto env structure
+ * @param      PrivateKey                      [in]represents x coordinate of public key
+ * @param      PrivateKeyLen           [in]byte-length of x coordinate of public key
+ * @param      PublicKey_X                     [in]represents x coordinate of public key
+ * @param      PublicKey_XLen          [in]byte-length of x coordinate of public key
+ * @param      PublicKey_Y                     [in]represents y coordinate of public key
+ * @param      PublicKey_YLen          [in]byte-length of y coordinate of public key
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if argument is null
+ */
+int SDRM_ECC_genKeypair (CryptoCoreContainer *crt,
+                                                cc_u8 *PrivateKey,  cc_u32 *PrivateKeyLen, 
+                                                cc_u8 *PublicKey_X, cc_u32 *PublicKey_XLen,
+                                                cc_u8 *PublicKey_Y, cc_u32 *PublicKey_YLen)
+{
+       int retVal;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       retVal = SDRM_CTX_ECDSA_KEY_GEN(crt->ctx->ecdsactx);
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               return retVal;
+       }
+
+       if (PrivateKey != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->ecdsactx->PRIV_KEY, crt->ctx->ecdsactx->uDimension / 8, PrivateKey);
+       }
+
+       if (PrivateKeyLen != NULL)
+       {
+               *PrivateKeyLen = crt->ctx->ecdsactx->uDimension / 8;
+       }
+
+       if (PublicKey_X != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->ecdsactx->PUBLIC_KEY->x, crt->ctx->ecdsactx->uDimension / 8, PublicKey_X);
+       }
+
+       if (PublicKey_XLen != NULL)
+       {
+               *PublicKey_XLen = crt->ctx->ecdsactx->uDimension / 8;
+       }
+
+       if (PublicKey_Y != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->ecdsactx->PUBLIC_KEY->y, crt->ctx->ecdsactx->uDimension / 8, PublicKey_Y);
+       }
+
+       if (PublicKey_YLen != NULL)
+       {
+               *PublicKey_YLen = crt->ctx->ecdsactx->uDimension / 8;
+       }
+
+       return CRYPTO_SUCCESS;
+
+}
+
+/*
+ * @fn         SDRM_ECC_setKeypair
+ * @brief      Set key data for ECC
+ *
+ * @param      crt                                     [out]crypto env structure
+ * @param      PRIV_Data                       [in]represents private key
+ * @param      PRIV_Len                        [in]byte-length of private key
+ * @param      PUB_X_Data                      [in]represents x coordinate of public key
+ * @param      PUB_X_Len                       [in]byte-length of x coordinate of public key
+ * @param      PUB_Y_Data                      [in]represents y coordinate of public key
+ * @param      PUB_Y_Len                       [in]byte-length of y coordinate of public key
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if argument is null
+ */
+int SDRM_ECC_setKeypair(CryptoCoreContainer *crt,
+                                           cc_u8* PRIV_Data,  cc_u32 PRIV_Len,
+                                           cc_u8* PUB_X_Data, cc_u32 PUB_X_Len,
+                                           cc_u8* PUB_Y_Data, cc_u32 PUB_Y_Len)
+{
+       int                             retVal;
+       cc_u8                   zero[] = {0x00};
+       SDRM_ECC_CTX    *ECC_ctx;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->ecdsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ECC_ctx = crt->ctx->ecdsactx;
+
+       ECC_ctx->PUBLIC_KEY->IsInfinity = 0;
+
+       if (PRIV_Data != NULL)
+       {
+               retVal = SDRM_OS2BN(PRIV_Data, PRIV_Len, ECC_ctx->PRIV_KEY);
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       if (PUB_X_Data != NULL && PUB_Y_Data != NULL)
+       {
+               retVal = SDRM_OS2BN(PUB_X_Data, PUB_X_Len, ECC_ctx->PUBLIC_KEY->x); 
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+
+               retVal = SDRM_OS2BN(PUB_Y_Data, PUB_Y_Len, ECC_ctx->PUBLIC_KEY->y);
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       SDRM_OS2BN(zero, 0, ECC_ctx->PUBLIC_KEY->z);
+       SDRM_OS2BN(zero, 0, ECC_ctx->PUBLIC_KEY->z2);
+       SDRM_OS2BN(zero, 0, ECC_ctx->PUBLIC_KEY->z3);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/middle/cc_hmac.c b/ssflib/dep/cryptocore/source/middle/cc_hmac.c
new file mode 100755 (executable)
index 0000000..6051eaf
--- /dev/null
@@ -0,0 +1,574 @@
+/**
+ * \file       hmac.c
+ * @brief      funciton for c-mac code generation by SHA1 and MD5
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/19
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_hmac.h"
+#include "cc_sha1.h"
+#include "cc_sha2.h"
+#include "cc_md5.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+int SDRM_getK0(cc_u8* k0, cc_u8* Key, cc_u32 KeyLen, cc_u32 Algorithm, cc_u32 B);
+
+/*
+ * @fn         SDRM_HMAC_init
+ * @brief      Parameter setting for mac code generation
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_HMAC_init(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen)
+{
+       SDRM_HMACContext *ctx;
+       cc_u8                    *ipad;
+       cc_u32                   i;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->hmacctx == NULL) || (Key == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->hmacctx;
+       ctx->algorithm = crt->alg;
+
+       switch(ctx->algorithm)
+       {
+               case ID_HMD5 :
+                       ctx->B = SDRM_MD5_DATA_SIZE;
+                       break;
+
+               case ID_HSHA1 :
+                       ctx->B = SDRM_SHA1_DATA_SIZE;
+                       break;
+
+               case ID_HSHA224 :
+                       ctx->B = SDRM_SHA224_DATA_SIZE;
+                       break;
+
+               case ID_HSHA256 :
+                       ctx->B = SDRM_SHA256_DATA_SIZE;
+                       break;
+
+#ifndef _OP64_NOTSUPPORTED
+               case ID_HSHA384 :
+                       ctx->B = SDRM_SHA384_DATA_SIZE;
+                       break;
+
+               case ID_HSHA512 :
+                       ctx->B = SDRM_SHA512_DATA_SIZE;
+                       break;
+#endif //_OP64_NOTSUPPORTED
+
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       ipad = (cc_u8*)malloc(ctx->B);
+       if (ipad == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       ctx->k0 = (cc_u8*)malloc(ctx->B);
+       if (ctx->k0 == NULL)
+       {
+               free(ipad);
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       //make k0
+       SDRM_getK0(ctx->k0, Key, KeyLen, ctx->algorithm, ctx->B);
+
+       //ipad = k0 xor ipad
+       for (i = 0; i < ctx->B; i++)
+       {
+               ipad[i] = ctx->k0[i] ^ 0x36;
+       }
+
+       if (i != ctx->B)
+       {
+               for (; i < ctx->B; i++)
+               {
+                       ipad[i] = ctx->k0[i] ^ 0x36;
+               }
+       }
+
+       ctx->md5_ctx = NULL;
+       ctx->sha1_ctx = NULL;
+       ctx->sha224_ctx = NULL;
+       ctx->sha256_ctx = NULL;
+#ifndef _OP64_NOTSUPPORTED
+       ctx->sha384_ctx = NULL;
+       ctx->sha512_ctx = NULL;
+#endif //_OP64_NOTSUPPORTED
+
+       switch(ctx->algorithm)
+       {
+               case ID_HMD5 :
+                       ctx->md5_ctx = (SDRM_MD5Context*)malloc(sizeof(SDRM_MD5Context));
+
+                       if (ctx->md5_ctx == NULL)
+                       {
+                               if (ipad != NULL)
+                               {
+                                       free(ipad);
+                               }
+                               return CRYPTO_MEMORY_ALLOC_FAIL;
+                       }
+
+                       SDRM_MD5_Init(ctx->md5_ctx);
+                       SDRM_MD5_Update(ctx->md5_ctx, ipad, ctx->B);
+                       break;
+
+               case ID_HSHA1 :
+                       ctx->sha1_ctx = (SDRM_SHA1Context*)malloc(sizeof(SDRM_SHA1Context));
+
+                       if (ctx->sha1_ctx == NULL)
+                       {
+                               if (ipad != NULL)
+                               {
+                                       free(ipad);
+                               }
+                               return CRYPTO_MEMORY_ALLOC_FAIL;
+                       }
+
+                       SDRM_SHA1_Init(ctx->sha1_ctx);
+                       SDRM_SHA1_Update(ctx->sha1_ctx, ipad, ctx->B);
+                       break;
+
+               case ID_HSHA224 :
+                       ctx->sha224_ctx = (SDRM_SHA224Context*)malloc(sizeof(SDRM_SHA224Context));
+
+                       if (ctx->sha224_ctx == NULL)
+                       {
+                               if (ipad != NULL)
+                               {
+                                       free(ipad);
+                               }
+                               return CRYPTO_MEMORY_ALLOC_FAIL;
+                       }
+
+                       SDRM_SHA224_Init(ctx->sha224_ctx);
+                       SDRM_SHA224_Update(ctx->sha224_ctx, ipad, ctx->B);
+                       break;
+
+               case ID_HSHA256 :
+                       ctx->sha256_ctx = (SDRM_SHA256Context*)malloc(sizeof(SDRM_SHA256Context));
+
+                       if (ctx->sha256_ctx == NULL)
+                       {
+                               if (ipad != NULL)
+                               {
+                                       free(ipad);
+                               }
+                               return CRYPTO_MEMORY_ALLOC_FAIL;
+                       }
+
+                       SDRM_SHA256_Init(ctx->sha256_ctx);
+                       SDRM_SHA256_Update(ctx->sha256_ctx, ipad, ctx->B);
+                       break;
+
+#ifndef _OP64_NOTSUPPORTED
+               case ID_HSHA384 :
+                       ctx->sha384_ctx = (SDRM_SHA384Context*)malloc(sizeof(SDRM_SHA384Context));
+
+                       if (ctx->sha384_ctx == NULL)
+                       {
+                               if (ipad != NULL)
+                               {
+                                       free(ipad);
+                               }
+                               return CRYPTO_MEMORY_ALLOC_FAIL;
+                       }
+
+                       SDRM_SHA384_Init(ctx->sha384_ctx);
+                       SDRM_SHA384_Update(ctx->sha384_ctx, ipad, ctx->B);
+                       break;
+
+               case ID_HSHA512 :
+                       ctx->sha512_ctx = (SDRM_SHA512Context*)malloc(sizeof(SDRM_SHA512Context));
+
+                       if (ctx->sha512_ctx == NULL)
+                       {
+                               if (ipad != NULL)
+                               {
+                                       free(ipad);
+                               }
+                               return CRYPTO_MEMORY_ALLOC_FAIL;
+                       }
+
+                       SDRM_SHA512_Init(ctx->sha512_ctx);
+                       SDRM_SHA512_Update(ctx->sha512_ctx, ipad, ctx->B);
+                       break;
+#endif //_OP64_NOTSUPPORTED
+
+               default :
+                       free(ipad);
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       free(ipad);
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_HMAC_update
+ * @brief      process data blocks
+ *
+ * @param      crt                                                     [out]crypto parameter
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_HMAC_update(CryptoCoreContainer *crt, cc_u8 *msg, cc_u32 msgLen)
+{
+       if (msgLen == 0)
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->hmacctx == NULL) || (msg == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       switch(crt->ctx->hmacctx->algorithm)
+       {
+               case ID_HMD5 :
+                       SDRM_MD5_Update(crt->ctx->hmacctx->md5_ctx, msg, msgLen);
+                       break;
+               case ID_HSHA1 :
+                       SDRM_SHA1_Update(crt->ctx->hmacctx->sha1_ctx, msg, msgLen);
+                       break;
+               case ID_HSHA224 :
+                       SDRM_SHA224_Update(crt->ctx->hmacctx->sha224_ctx, msg, msgLen);
+                       break;
+               case ID_HSHA256 :
+                       SDRM_SHA256_Update(crt->ctx->hmacctx->sha256_ctx, msg, msgLen);
+                       break;
+
+#ifndef _OP64_NOTSUPPORTED
+               case ID_HSHA384 :
+                       SDRM_SHA384_Update(crt->ctx->hmacctx->sha384_ctx, msg, msgLen);
+                       break;
+               case ID_HSHA512 :
+                       SDRM_SHA512_Update(crt->ctx->hmacctx->sha512_ctx, msg, msgLen);
+                       break;
+#endif //OP64_NOTSUPPORTED
+
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_HMAC_final
+ * @brief      process last data block
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if Parameter is NULL
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_HMAC_final(CryptoCoreContainer *crt, cc_u8 *output, cc_u32 *outputLen)
+{
+       SDRM_HMACContext        *ctx;
+       SDRM_MD5Context         MD5ctx;
+       SDRM_SHA1Context        SHA1ctx;
+       SDRM_SHA224Context      SHA224ctx;
+       SDRM_SHA256Context      SHA256ctx;
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context      SHA384ctx;
+       SDRM_SHA512Context      SHA512ctx;
+#endif //_OP64_NOTSUPPORTED
+       cc_u8                           Step6_Result[64];
+       cc_u32                          HashLen, i;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->hmacctx == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       ctx = crt->ctx->hmacctx;
+
+       //k0 = k0 xor opad
+       for (i = 0; i < ctx->B; i++)
+       {
+               ctx->k0[i] ^= 0x5c;
+       }
+
+       if (i != ctx->B)
+       {
+               for (; i < ctx->B; i++)
+               {
+                       ctx->k0[i] ^= 0x5c;
+               }
+       }
+
+       //Step6 : get H((k0 xor ipad) | text) & Step 9 : make hash
+       switch(ctx->algorithm)
+       {
+               case ID_HMD5 :
+                       SDRM_MD5_Final(ctx->md5_ctx, Step6_Result);
+                       free(ctx->md5_ctx);
+
+                       HashLen = SDRM_MD5_BLOCK_SIZ;
+
+                       SDRM_MD5_Init(&MD5ctx);
+                       SDRM_MD5_Update(&MD5ctx, ctx->k0, ctx->B);
+                       SDRM_MD5_Update(&MD5ctx, Step6_Result, HashLen);
+                       SDRM_MD5_Final(&MD5ctx, output);
+
+                       break;
+
+               case ID_HSHA1 :
+                       SDRM_SHA1_Final(ctx->sha1_ctx, Step6_Result);
+                       free(ctx->sha1_ctx);
+
+                       HashLen = SDRM_SHA1_BLOCK_SIZ;
+
+                       SDRM_SHA1_Init(&SHA1ctx);
+                       SDRM_SHA1_Update(&SHA1ctx, ctx->k0, ctx->B);
+                       SDRM_SHA1_Update(&SHA1ctx, Step6_Result, HashLen);
+                       SDRM_SHA1_Final(&SHA1ctx, output);
+
+                       break;
+
+               case ID_HSHA224 :
+                       SDRM_SHA224_Final(ctx->sha224_ctx, Step6_Result);
+                       free(ctx->sha224_ctx);
+
+                       HashLen = SDRM_SHA224_BLOCK_SIZ;
+
+                       SDRM_SHA224_Init(&SHA224ctx);
+                       SDRM_SHA224_Update(&SHA224ctx, ctx->k0, ctx->B);
+                       SDRM_SHA224_Update(&SHA224ctx, Step6_Result, HashLen);
+                       SDRM_SHA224_Final(&SHA224ctx, output);
+
+                       break;
+
+               case ID_HSHA256 :
+                       SDRM_SHA256_Final(ctx->sha256_ctx, Step6_Result);
+                       free(ctx->sha256_ctx);
+
+                       HashLen = SDRM_SHA256_BLOCK_SIZ;
+
+                       SDRM_SHA256_Init(&SHA256ctx);
+                       SDRM_SHA256_Update(&SHA256ctx, ctx->k0, ctx->B);
+                       SDRM_SHA256_Update(&SHA256ctx, Step6_Result, HashLen);
+                       SDRM_SHA256_Final(&SHA256ctx, output);
+
+                       break;
+
+#ifndef _OP64_NOTSUPPORTED
+               case ID_HSHA384 :
+                       SDRM_SHA384_Final(ctx->sha384_ctx, Step6_Result);
+                       free(ctx->sha384_ctx);
+
+                       HashLen = SDRM_SHA384_BLOCK_SIZ;
+
+                       SDRM_SHA384_Init(&SHA384ctx);
+                       SDRM_SHA384_Update(&SHA384ctx, ctx->k0, ctx->B);
+                       SDRM_SHA384_Update(&SHA384ctx, Step6_Result, HashLen);
+                       SDRM_SHA384_Final(&SHA384ctx, output);
+
+                       break;
+
+               case ID_HSHA512 :
+                       SDRM_SHA512_Final(ctx->sha512_ctx, Step6_Result);
+                       free(ctx->sha512_ctx);
+
+                       HashLen = SDRM_SHA512_BLOCK_SIZ;
+
+                       SDRM_SHA512_Init(&SHA512ctx);
+                       SDRM_SHA512_Update(&SHA512ctx, ctx->k0, ctx->B);
+                       SDRM_SHA512_Update(&SHA512ctx, Step6_Result, HashLen);
+                       SDRM_SHA512_Final(&SHA512ctx, output);
+
+                       break;
+#endif
+
+               default :
+               if (ctx->k0) {
+                       free(ctx->k0);
+               }
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (outputLen != NULL)
+       {
+               *outputLen = HashLen;
+       }
+
+       if (ctx->k0)
+       {
+               free(ctx->k0);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_HMAC_getMAC
+ * @brief      generate h-mac code
+ *
+ * @param      crt                                                     [in]crypto parameter
+ * @param      Key                                                     [in]user key
+ * @param      KeyLen                                          [in]byte-length of Key
+ * @param      msg                                                     [in]data block
+ * @param      msgLen                                          [in]byte-length of Text
+ * @param      output                                          [out]generated MAC
+ * @param      outputLen                                       [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ */
+int SDRM_HMAC_getMAC(CryptoCoreContainer *crt, cc_u8 *Key, cc_u32 KeyLen, cc_u8 *msg, cc_u32 msgLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int result;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->hmacctx == NULL) || (Key == NULL) || (output == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       result = SDRM_HMAC_init(crt, Key, KeyLen);
+       if (result != CRYPTO_SUCCESS)
+       {
+               return result;
+       }
+
+       result = SDRM_HMAC_update(crt, msg, msgLen);
+       if (result != CRYPTO_SUCCESS)
+       {
+               return result;
+       }
+
+       return SDRM_HMAC_final(crt, output, outputLen);
+}
+
+int SDRM_getK0(cc_u8* k0, cc_u8* Key, cc_u32 KeyLen, cc_u32 Algorithm, cc_u32 B)
+{
+       SDRM_MD5Context  MD5ctx;
+       SDRM_SHA1Context SHA1ctx;
+       SDRM_SHA224Context SHA224ctx;
+       SDRM_SHA256Context SHA256ctx;
+#ifndef _OP64_NOTSUPPORTED
+       SDRM_SHA384Context SHA384ctx;
+       SDRM_SHA512Context SHA512ctx;
+#endif //_OP64_NOTSUPPORTED
+
+       int L;
+
+       if (KeyLen == B)
+       {
+               //if the length of K = B : set K0 = K
+               memcpy(k0, Key, B);
+       }
+       else if (KeyLen > B)
+       {
+               //if the length of K > B : get hask(K) and append (B - L) zeros
+
+               //get hash(K)
+
+               switch(Algorithm)
+               {
+                       case ID_HMD5 :
+                               SDRM_MD5_Init(&MD5ctx);
+                               SDRM_MD5_Update(&MD5ctx, Key, KeyLen);
+                               SDRM_MD5_Final(&MD5ctx, k0);
+
+                               L = SDRM_MD5_BLOCK_SIZ;
+
+                               break;
+
+                       case ID_HSHA1 :
+                               SDRM_SHA1_Init(&SHA1ctx);
+                               SDRM_SHA1_Update(&SHA1ctx, Key, KeyLen);
+                               SDRM_SHA1_Final(&SHA1ctx, k0);
+                               
+                               L = SDRM_SHA1_BLOCK_SIZ;
+
+                               break;
+
+                       case ID_HSHA224 :
+                               SDRM_SHA224_Init(&SHA224ctx);
+                               SDRM_SHA224_Update(&SHA224ctx, Key, KeyLen);
+                               SDRM_SHA224_Final(&SHA224ctx, k0);
+                               
+                               L = SDRM_SHA224_BLOCK_SIZ;
+
+                               break;
+
+                       case ID_HSHA256 :
+                               SDRM_SHA256_Init(&SHA256ctx);
+                               SDRM_SHA256_Update(&SHA256ctx, Key, KeyLen);
+                               SDRM_SHA256_Final(&SHA256ctx, k0);
+                               
+                               L = SDRM_SHA256_BLOCK_SIZ;
+
+                               break;
+
+#ifndef _OP64_NOTSUPPORTED
+                       case ID_HSHA384 :
+                               SDRM_SHA384_Init(&SHA384ctx);
+                               SDRM_SHA384_Update(&SHA384ctx, Key, KeyLen);
+                               SDRM_SHA384_Final(&SHA384ctx, k0);
+                               
+                               L = SDRM_SHA384_BLOCK_SIZ;
+
+                               break;
+
+                       case ID_HSHA512 :
+                               SDRM_SHA512_Init(&SHA512ctx);
+                               SDRM_SHA512_Update(&SHA512ctx, Key, KeyLen);
+                               SDRM_SHA512_Final(&SHA512ctx, k0);
+                               
+                               L = SDRM_SHA512_BLOCK_SIZ;
+
+                               break;
+#endif
+
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               //append zeros
+               memset(k0 + L, 0x00, B - L);
+       }
+       else {
+               //if the length of K < B : append zerots to the end of K
+               memcpy(k0, Key, KeyLen);
+               memset(k0 + KeyLen, 0x00, B - KeyLen);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/middle/cc_rng.c b/ssflib/dep/cryptocore/source/middle/cc_rng.c
new file mode 100755 (executable)
index 0000000..614aa61
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * \file       rng.c
+ * @brief      Random Number Generator Interface
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon, Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/07
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_ANSI_x931.h"
+#include "cc_rng.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_X931_seed
+ * @brief      Seed RNG System
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      seed                            [in]seed for RNG System
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ */
+int SDRM_X931_seed(CryptoCoreContainer *crt, cc_u8 *seed)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->x931ctx == NULL) || (seed == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       memcpy(crt->ctx->x931ctx->Seed, seed, SDRM_X931_SEED_SIZ);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_X931_get
+ * @brief      generate random number
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      bitLength                       [in]bit length for generated number
+ * @param      data                            [out]generated data
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ */
+int    SDRM_X931_get(CryptoCoreContainer *crt, cc_u32 bitLength, cc_u8 *data)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->x931ctx == NULL) || (data == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+#ifdef _WIN32_WCE
+       srand(GetTickCount());
+#else
+       srand((unsigned int)time(NULL));
+#endif
+
+       return SDRM_RNG_X931(crt->ctx->x931ctx->Seed, bitLength, data);
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/cryptocore/source/middle/cc_rsa.c b/ssflib/dep/cryptocore/source/middle/cc_rsa.c
new file mode 100755 (executable)
index 0000000..43d6f10
--- /dev/null
@@ -0,0 +1,1924 @@
+/**
+ * \file       rsa.c
+ * @brief      implementation of rsa encryption/decryption and signature/verifycation
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/20
+ * Note : Modified for support RSA-2048(Jisoon Park, 2007/03/14)
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_rsa.h"
+#include "cc_pkcs1_v21.h"
+#include "cc_ANSI_x931.h"
+#include "cc_bignum.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Functions
+//////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_RSAContext *SDRM_RSA_InitCrt(cc_u32 KeyByteLen)
+ *
+ * @brief      generate RSA Context
+ *
+ * @return     pointer to the generated context
+ * \n          NULL    if memory allocation is failed
+ */
+SDRM_RSAContext *SDRM_RSA_InitCrt(cc_u32 KeyByteLen)
+{
+       SDRM_RSAContext *ctx;
+       cc_u32                  RSA_KeyByteLen = KeyByteLen;
+       cc_u8                   *pbBuf = (cc_u8*)malloc(sizeof(SDRM_RSAContext) + SDRM_RSA_ALLOC_SIZE * 8);
+
+       if (pbBuf == NULL)
+       {
+               return NULL;
+       }
+
+       ctx                     = (SDRM_RSAContext*)(void*)pbBuf;
+       ctx->n          = SDRM_BN_Alloc((cc_u8*)ctx                             + sizeof(SDRM_RSAContext),      SDRM_RSA_BN_BUFSIZE);
+       ctx->e          = SDRM_BN_Alloc((cc_u8*)ctx->n                  + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+       ctx->d          = SDRM_BN_Alloc((cc_u8*)ctx->e                  + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+       ctx->p          = SDRM_BN_Alloc((cc_u8*)ctx->d                  + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+       ctx->q          = SDRM_BN_Alloc((cc_u8*)ctx->p                  + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+       ctx->dmodp1     = SDRM_BN_Alloc((cc_u8*)ctx->q                  + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+       ctx->dmodq1     = SDRM_BN_Alloc((cc_u8*)ctx->dmodp1             + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+       ctx->iqmodp     = SDRM_BN_Alloc((cc_u8*)ctx->dmodq1             + SDRM_RSA_ALLOC_SIZE,          SDRM_RSA_BN_BUFSIZE);
+
+       ctx->crt_operation = (unsigned int)-1;
+       ctx->k  = RSA_KeyByteLen;
+
+       return ctx;
+}
+
+/*
+ * @fn         int SDRM_RSA_setNED(CryptoCoreContainer *crt, cc_u32 PaddingMethod, cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len, cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len, cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len)
+ * @brief      set RSA parameters
+ *
+ * @param      crt                                     [out]rsa context
+ * @param      PaddingMethod           [in]padding method
+ * @param      RSA_N_Data                      [in]n value
+ * @param      RSA_N_Len                       [in]byte-length of n
+ * @param      RSA_E_Data                      [in]e value
+ * @param      RSA_E_Len                       [in]byte-length of e
+ * @param      RSA_D_Data                      [in]d value
+ * @param      RSA_D_Len                       [in]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if an argument is a null pointer
+ */
+int SDRM_RSA_setNED(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                   cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+                                   cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+                                   cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL) || (RSA_N_Data == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       SDRM_OS2BN(RSA_N_Data, RSA_N_Len, crt->ctx->rsactx->n);
+       SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->n);
+
+       if (RSA_E_Data != NULL)
+       {
+               SDRM_OS2BN(RSA_E_Data, RSA_E_Len, crt->ctx->rsactx->e);
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->e);
+       }
+
+       if (RSA_D_Data != NULL)
+       {
+               SDRM_OS2BN(RSA_D_Data, RSA_D_Len, crt->ctx->rsactx->d);
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->d);
+       }
+
+       crt->ctx->rsactx->pm = PaddingMethod;
+       crt->ctx->rsactx->crt_operation = 0;
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_setNEDPQ(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+ *                                 cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+ *                                 cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+ *                                 cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len,
+ *                                 cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+ *                                 cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+ *                                 cc_u8* RSA_DmodP1_Data,   cc_u32 RSA_DmodP1_Len,
+ *                                 cc_u8* RSA_DmodQ1_Data,   cc_u32 RSA_DmodQ1_Len,
+ *                                 cc_u8* RSA_iQmodP_Data,   cc_u32 RSA_iQmodP_Len)
+ *
+ * @brief      set RSA parameters
+ *
+ * @param      crt                                     [out]rsa context
+ * @param      PaddingMethod           [in]padding method
+ * @param      RSA_N_Data                      [in]n value
+ * @param      RSA_N_Len                       [in]byte-length of n
+ * @param      RSA_E_Data                      [in]e value
+ * @param      RSA_E_Len                       [in]byte-length of e
+ * @param      RSA_D_Data                      [in]d value
+ * @param      RSA_D_Len                       [in]byte-length of d
+ * @param      RSA_P_Data                      [in]p value
+ * @param      RSA_P_Len                       [in]byte-length of p
+ * @param      RSA_Q_Data                      [in]q value
+ * @param      RSA_Q_Len                       [in]byte-length of q
+ * @param      RSA_DmodP1_Data         [in]d mod (p-1) value
+ * @param      RSA_DmodP1_Len          [in]byte-length of d mod (p-1)
+ * @param      RSA_DmodQ1_Data         [in]d mod (q-1) value
+ * @param      RSA_DmodQ1_Len          [in]byte-length of d mod (q-1)
+ * @param      RSA_iQmodP_Data         [in]q^(-1) mod p value
+ * @param      RSA_iQmodP_Len          [in]byte-length of q^(-1) mod p
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ * \n          CRYPTO_NULL_POINTER     if an argument is a null pointer
+ */
+int SDRM_RSA_setNEDPQ(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                   cc_u8* RSA_N_Data,   cc_u32 RSA_N_Len,
+                                   cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+                                   cc_u8* RSA_D_Data,   cc_u32 RSA_D_Len,
+                                   cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+                                   cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+                                   cc_u8* RSA_DmodP1_Data,   cc_u32 RSA_DmodP1_Len,
+                                   cc_u8* RSA_DmodQ1_Data,   cc_u32 RSA_DmodQ1_Len,
+                                   cc_u8* RSA_iQmodP_Data,   cc_u32 RSA_iQmodP_Len)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       crt->ctx->rsactx->crt_operation = 0;
+       if ((RSA_P_Data != NULL) && (RSA_Q_Data != NULL) && (RSA_DmodP1_Data != NULL) && (RSA_DmodQ1_Data != NULL) && (RSA_iQmodP_Data != NULL))
+       {
+               crt->ctx->rsactx->crt_operation = 1;
+       }
+       else if (RSA_N_Data == NULL)
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (RSA_N_Data != NULL)
+       {
+               if( !SDRM_OS2BN(RSA_N_Data, RSA_N_Len, crt->ctx->rsactx->n) ) {
+                   SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->n);
+               }
+       }
+
+       if (RSA_E_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_E_Data, RSA_E_Len, crt->ctx->rsactx->e) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->e);
+           }
+       }
+
+       if (RSA_D_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_D_Data, RSA_D_Len, crt->ctx->rsactx->d) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->d);
+           }
+       }
+
+       if (RSA_P_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_P_Data, RSA_P_Len, crt->ctx->rsactx->p) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->p);
+           }
+       }
+
+       if (RSA_Q_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_Q_Data, RSA_Q_Len, crt->ctx->rsactx->q) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->q);
+           }
+       }
+
+       if (RSA_DmodP1_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_DmodP1_Data, RSA_DmodP1_Len, crt->ctx->rsactx->dmodp1) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->dmodp1);
+           }
+       }
+
+       if (RSA_DmodQ1_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_DmodQ1_Data, RSA_DmodQ1_Len, crt->ctx->rsactx->dmodq1) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->dmodq1);
+           }
+       }
+
+       if (RSA_iQmodP_Data != NULL)
+       {
+           if( !SDRM_OS2BN(RSA_iQmodP_Data, RSA_iQmodP_Len, crt->ctx->rsactx->iqmodp) ) {
+               SDRM_BN_OPTIMIZE_LENGTH(crt->ctx->rsactx->iqmodp);
+           }
+       }
+
+       crt->ctx->rsactx->pm = PaddingMethod;
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         int SDRM_RSA_GenerateKey(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+ *                                              cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+ *                                              cc_u8* RSA_E_Data,   cc_u32 *RSA_E_Len,
+ *                                              cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len)
+ * @brief      generate and set RSA parameters
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_N_Data                                      [out]n value
+ * @param      RSA_N_Len                                       [out]byte-length of n
+ * @param      RSA_E_Data                                      [out]e value
+ * @param      RSA_E_Len                                       [out]byte-length of e
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateKey(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+                                                cc_u8* RSA_E_Data,   cc_u32 *RSA_E_Len,
+                                                cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len)
+{
+       cc_u32           Seed[4];
+       SDRM_BIG_NUM *p, *q, *pi, *e, *temp1, *temp2;
+       cc_u32           RSA_KeyByteLen = 0;
+       int                      i, sp, t1;
+       cc_u8 *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       t1 = (RSA_KeyByteLen * 4 - 1) % 32;
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 5);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       p         = SDRM_BN_Alloc((cc_u8*)pbBuf,                                                  SDRM_RSA_BN_BUFSIZE);
+       q         = SDRM_BN_Alloc((cc_u8*)p        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       pi        = SDRM_BN_Alloc((cc_u8*)q        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp1 = SDRM_BN_Alloc((cc_u8*)pi           + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp2 = SDRM_BN_Alloc((cc_u8*)temp1 + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       e = crt->ctx->rsactx->e;
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand()  << 16) ^rand();
+       }
+
+       //set security parameter for miller-rabin probabilistic primality test
+       if (RSA_KeyByteLen >= 256)
+       {
+               sp = 3;
+       }
+       else if (RSA_KeyByteLen >= 128)
+       {
+               sp = 5;
+       }
+       else if (RSA_KeyByteLen >= 30)
+       {
+               sp = 15;
+       }
+       else
+       {
+               sp = 30;
+       }
+
+GEN_RND:
+       //Generate p
+       p->Length = (RSA_KeyByteLen + 7) / 8;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)p->pData);
+               p->pData[0] |= 1L;
+               p->pData[p->Length - 1] &= ~((-1L) << t1);
+               p->pData[p->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(p, sp) != CRYPTO_ISPRIME);
+
+       //Generate q
+       q->Length = (RSA_KeyByteLen + 7) / 8;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)q->pData);
+               q->pData[0] |= 1L;
+               q->pData[q->Length - 1] &= ~((-1L) << t1);
+               q->pData[q->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(q, sp) != CRYPTO_ISPRIME);
+
+//     SDRM_PrintBN("p", p);
+//     SDRM_PrintBN("q", q);
+
+       //temp1 = (p - 1), temp2 = (q - 1)
+       SDRM_BN_Sub(temp1, p, BN_One);
+       SDRM_BN_Sub(temp2, q, BN_One);
+
+       //evaluate n and pi
+       //n = p * q, pi = (p - 1) * (q - 1)
+       SDRM_BN_Mul(crt->ctx->rsactx->n, p, q);
+       SDRM_BN_Mul(pi, temp1, temp2);
+
+       //generate e
+       e->Length = (RSA_KeyByteLen + 3) / 4;
+       do {
+               do {
+                       SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 8 - 8, (cc_u8*)e->pData);
+                       e->pData[0] |= 0x01;
+               }
+               while(SDRM_BN_CheckRelativelyPrime(e, pi) != CRYPTO_ISPRIME);
+       }
+       while (SDRM_BN_Cmp(e, pi) >= 0);
+
+       if (SDRM_BN_ModInv(crt->ctx->rsactx->d, e, pi) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+
+       crt->ctx->rsactx->pm = PaddingMethod;
+
+       if (RSA_N_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->n, RSA_KeyByteLen, RSA_N_Data);
+       }
+
+       if (RSA_N_Len != NULL)
+       {
+               *RSA_N_Len = RSA_KeyByteLen;
+       }
+
+       if (RSA_E_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->e, RSA_KeyByteLen, RSA_E_Data);
+       }
+
+       if (RSA_E_Len != NULL)
+       {
+               *RSA_E_Len = RSA_KeyByteLen;
+       }
+
+       if (RSA_D_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->d, RSA_KeyByteLen, RSA_D_Data);
+       }
+
+       if (RSA_D_Len != NULL)
+       {
+               *RSA_D_Len = RSA_KeyByteLen;
+       }
+       
+       free(pbBuf);
+       
+       crt->ctx->rsactx->crt_operation = 0;
+
+       return CRYPTO_SUCCESS;
+}
+
+int SDRM_RSA_GenerateKeyforCRT(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                       cc_u8* RSA_E_Data,       cc_u32 RSA_E_Len,
+                                                        cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+                                                        cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len,
+                                                        cc_u8* RSA_P_Data,   cc_u32 *RSA_P_Len,
+                                                        cc_u8* RSA_Q_Data,   cc_u32 *RSA_Q_Len,
+                                                        cc_u8* RSA_DP_Data,   cc_u32 *RSA_DP_Len,
+                                                        cc_u8* RSA_DQ_Data,   cc_u32 *RSA_DQ_Len,
+                                                        cc_u8* RSA_QP_Data,   cc_u32 *RSA_QP_Len)
+{
+       cc_u32           Seed[4];
+       SDRM_BIG_NUM *p, *q, *h, *e, *p1, *q1;
+       cc_u32           RSA_KeyByteLen = 0;
+       int                      i, sp, t1;
+       cc_u8 *pbBuf = NULL;
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL)) {
+               return CRYPTO_NULL_POINTER;
+       }
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       t1 = (RSA_KeyByteLen * 4 - 1) % 32;
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 5);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+       p         = SDRM_BN_Alloc((cc_u8*)pbBuf,                                                  SDRM_RSA_BN_BUFSIZE);
+       q         = SDRM_BN_Alloc((cc_u8*)p        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       h         = SDRM_BN_Alloc((cc_u8*)q    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       p1 = SDRM_BN_Alloc((cc_u8*)h       + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       q1 = SDRM_BN_Alloc((cc_u8*)p1 + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       e = crt->ctx->rsactx->e;
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand() << 16) ^ rand();
+       }
+       if (RSA_KeyByteLen >= 256)
+       {
+               sp = 3;
+       }
+       else if (RSA_KeyByteLen >= 128)
+       {
+               sp = 5;
+       }
+       else if (RSA_KeyByteLen >= 30)
+       {
+               sp = 15;
+       }
+       else
+       {
+               sp = 30;
+       }
+GEN_RND:
+       p->Length = (RSA_KeyByteLen + 7) / 8;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)p->pData);
+               p->pData[0] |= 1L;
+               p->pData[p->Length - 1] &= ~((-1L) << t1);
+               p->pData[p->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(p, sp) != CRYPTO_ISPRIME);
+       q->Length = (RSA_KeyByteLen + 7) / 8;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)q->pData);
+               q->pData[0] |= 1L;
+               q->pData[q->Length - 1] &= ~((-1L) << t1);
+               q->pData[q->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(q, sp) != CRYPTO_ISPRIME);
+       SDRM_BN_Sub(p1, p, BN_One);
+       SDRM_BN_Sub(q1, q, BN_One);
+       SDRM_BN_Mul(h, p1, q1);
+       SDRM_OS2BN(RSA_E_Data, RSA_E_Len, e);
+       if ((SDRM_BN_CheckRelativelyPrime(e, h) != CRYPTO_ISPRIME) || (SDRM_BN_Cmp(e, h) >= 0))
+       {
+               goto GEN_RND;
+       }
+       SDRM_BN_Mul(crt->ctx->rsactx->n, p, q);
+       if (SDRM_BN_ModInv(crt->ctx->rsactx->d, e, h) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+       if (SDRM_BN_ModRed(crt->ctx->rsactx->dmodp1, crt->ctx->rsactx->d, p1) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+       if (SDRM_BN_ModRed(crt->ctx->rsactx->dmodq1, crt->ctx->rsactx->d, q1) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+       if (SDRM_BN_ModInv(crt->ctx->rsactx->iqmodp, q, p) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+       crt->ctx->rsactx->pm = PaddingMethod;
+       if (RSA_N_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->n, RSA_KeyByteLen, RSA_N_Data);
+       }
+       if (RSA_N_Len != NULL)
+       {
+               *RSA_N_Len = RSA_KeyByteLen;
+       }
+       if (RSA_D_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->d, RSA_KeyByteLen, RSA_D_Data);
+       }
+       if (RSA_D_Len != NULL)
+       {
+               *RSA_D_Len = RSA_KeyByteLen;
+       }
+       if (RSA_P_Data != NULL)
+       {
+               SDRM_I2OSP(p, RSA_KeyByteLen/2, RSA_P_Data);
+       }
+       if (RSA_P_Len != NULL)
+       {
+               *RSA_P_Len = RSA_KeyByteLen/2;
+       }
+       if (RSA_Q_Data != NULL)
+       {
+               SDRM_I2OSP(q, RSA_KeyByteLen/2, RSA_Q_Data);
+       }
+       if (RSA_Q_Len != NULL)
+       {
+               *RSA_Q_Len = RSA_KeyByteLen/2;
+       }
+       if (RSA_DP_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->dmodp1, RSA_KeyByteLen/2, RSA_DP_Data);
+       }
+       if (RSA_DP_Len != NULL)
+       {
+               *RSA_DP_Len = RSA_KeyByteLen/2;
+       }
+       if (RSA_DQ_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->dmodq1, RSA_KeyByteLen/2, RSA_DQ_Data);
+       }
+       if (RSA_DQ_Len != NULL)
+       {
+               *RSA_DQ_Len = RSA_KeyByteLen/2;
+       }
+       if (RSA_QP_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->iqmodp, RSA_KeyByteLen/2, RSA_QP_Data);
+       }
+       if (RSA_QP_Len != NULL)
+       {
+               *RSA_QP_Len = RSA_KeyByteLen/2;
+       }
+       free(pbBuf);
+       crt->ctx->rsactx->crt_operation = 0;
+       return CRYPTO_SUCCESS;
+}
+/*
+ * @fn         int SDRM_RSA_GenerateND(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+ *                                              cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+ *                                              cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+ *                                              cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len)
+ * @brief      generate and set RSA parameters with specfied e
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_E_Data                                      [in]e value
+ * @param      RSA_E_Len                                       [in]byte-length of e
+ * @param      RSA_N_Data                                      [out]n value
+ * @param      RSA_N_Len                                       [out]byte-length of n
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateND(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+                                                cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+                                                cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len)
+{
+       cc_u32           Seed[4];
+       SDRM_BIG_NUM *p, *q, *pi, *e, *temp1, *temp2;
+       cc_u32           RSA_KeyByteLen = 0;
+       int                      i, sp, t1;
+       cc_u8 *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL)) {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       t1 = (RSA_KeyByteLen * 4 - 1) % 32;
+               
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 5);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       p         = SDRM_BN_Alloc((cc_u8*)pbBuf,                                                  SDRM_RSA_BN_BUFSIZE);
+       q         = SDRM_BN_Alloc((cc_u8*)p        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       pi        = SDRM_BN_Alloc((cc_u8*)q        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp1 = SDRM_BN_Alloc((cc_u8*)pi           + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp2 = SDRM_BN_Alloc((cc_u8*)temp1 + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       e = crt->ctx->rsactx->e;
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand()  << 16) ^ rand();
+       }
+
+       //set security parameter for miller-rabin probabilistic primality test
+       if (RSA_KeyByteLen >= 256)
+       {
+               sp = 3;
+       }
+       else if (RSA_KeyByteLen >= 128)
+       {
+               sp = 5;
+       }
+       else if (RSA_KeyByteLen >= 30)
+       {
+               sp = 15;
+       }
+       else
+       {
+               sp = 30;
+       }
+
+GEN_RND:
+       //Generate p
+       p->Length = (RSA_KeyByteLen + 7) / 8;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)p->pData);
+               p->pData[0] |= 1L;
+               p->pData[p->Length - 1] &= ~((-1L) << t1);
+               p->pData[p->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(p, sp) != CRYPTO_ISPRIME);
+
+       //Generate q
+       q->Length = (RSA_KeyByteLen + 7) / 8;
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)q->pData);
+               q->pData[0] |= 1L;
+               q->pData[q->Length - 1] &= ~((-1L) << t1);
+               q->pData[q->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(q, sp) != CRYPTO_ISPRIME);
+
+       //temp1 = (p - 1), temp2 = (q - 1)
+       SDRM_BN_Sub(temp1, p, BN_One);
+       SDRM_BN_Sub(temp2, q, BN_One);
+
+       //evaluate n and pi
+       //n = p * q, pi = (p - 1) * (q - 1)
+       SDRM_BN_Mul(crt->ctx->rsactx->n, p, q);
+       SDRM_BN_Mul(pi, temp1, temp2);
+
+       //check N for e
+       SDRM_OS2BN(RSA_E_Data, RSA_E_Len, e);
+       if ((SDRM_BN_CheckRelativelyPrime(e, pi) != CRYPTO_ISPRIME) || (SDRM_BN_Cmp(e, pi) >= 0))
+       {
+               goto GEN_RND;
+       }
+
+       if (SDRM_BN_ModInv(crt->ctx->rsactx->d, e, pi) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+
+       crt->ctx->rsactx->pm = PaddingMethod;
+
+       if (RSA_N_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->n, RSA_KeyByteLen, RSA_N_Data);
+       }
+
+       if (RSA_N_Len != NULL)
+       {
+               *RSA_N_Len = RSA_KeyByteLen;
+       }
+
+       if (RSA_D_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->d, RSA_KeyByteLen, RSA_D_Data);
+       }
+
+       if (RSA_D_Len != NULL)
+       {
+               *RSA_D_Len = RSA_KeyByteLen;
+       }
+       
+       free(pbBuf);
+       
+       crt->ctx->rsactx->crt_operation = 0;
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_GenerateDwithPQE(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+ *                                              cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+ *                                              cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+ *                                              cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+ *                                              cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+ *                                              cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len)
+ * @brief      generate D with specfied p, q, d mod (p-1), d mod (q-1) and e
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_E_Data                                      [in]e value
+ * @param      RSA_E_Len                                       [in]byte-length of e
+ * @param      RSA_P_Data                                      [in]n value
+ * @param      RSA_P_Len                                       [in]byte-length of n
+ * @param      RSA_Q_Data                                      [in]d value
+ * @param      RSA_Q_Len                                       [in]byte-length of d
+ * @param      RSA_D_P_Data                            [in]d mod (p-1) value
+ * @param      RSA_D_P_Len                                     [in]byte-length of d mod (p-1) 
+ * @param      RSA_D_Q_Data                            [in]d mod (q-1)  value
+ * @param      RSA_D_Q_Len                                     [in]byte-length of d mod (q-1) 
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_GenerateDwithPQE(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                cc_u8* RSA_E_Data,   cc_u32 RSA_E_Len,
+                                                cc_u8* RSA_P_Data,   cc_u32 RSA_P_Len,
+                                                cc_u8* RSA_Q_Data,   cc_u32 RSA_Q_Len,
+                                                cc_u8* RSA_N_Data,   cc_u32 *RSA_N_Len,
+                                                cc_u8* RSA_D_Data,   cc_u32 *RSA_D_Len)
+{
+       SDRM_BIG_NUM *p, *q, *pi, *e, *temp1, *temp2;
+       cc_u32           RSA_KeyByteLen = 0;
+       int                      sp;
+       cc_u8 *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+               
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 5);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       p         = SDRM_BN_Alloc((cc_u8*)pbBuf,                                                  SDRM_RSA_BN_BUFSIZE);
+       q         = SDRM_BN_Alloc((cc_u8*)p        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       pi        = SDRM_BN_Alloc((cc_u8*)q        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp1 = SDRM_BN_Alloc((cc_u8*)pi           + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp2 = SDRM_BN_Alloc((cc_u8*)temp1 + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       e = crt->ctx->rsactx->e;
+
+       //set security parameter for miller-rabin probabilistic primality test
+       if (RSA_KeyByteLen >= 256)
+       {
+               sp = 3;
+       }
+       else if (RSA_KeyByteLen >= 128)
+       {
+               sp = 5;
+       }
+       else if (RSA_KeyByteLen >= 30)
+       {
+               sp = 15;
+       }
+       else
+       {
+               sp = 30;
+       }
+
+       SDRM_OS2BN((cc_u8*)RSA_P_Data, RSA_P_Len, p);   
+       if (SDRM_BN_MILLER_RABIN(p, sp) != CRYPTO_ISPRIME)
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       SDRM_OS2BN((cc_u8*)RSA_Q_Data, RSA_Q_Len, q);   
+       if (SDRM_BN_MILLER_RABIN(q, sp) != CRYPTO_ISPRIME)
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       //temp1 = (p - 1), temp2 = (q - 1)
+       SDRM_BN_Sub(temp1, p, BN_One);
+       SDRM_BN_Sub(temp2, q, BN_One);
+
+       //evaluate n and pi
+       //n = p * q, pi = (p - 1) * (q - 1)
+       SDRM_BN_Mul(crt->ctx->rsactx->n, p, q);
+       SDRM_BN_Mul(pi, temp1, temp2);
+
+       //check N for e
+       SDRM_OS2BN(RSA_E_Data, RSA_E_Len, e);
+       if ((SDRM_BN_CheckRelativelyPrime(e, pi) != CRYPTO_ISPRIME) || (SDRM_BN_Cmp(e, pi) >= 0))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (SDRM_BN_ModInv(crt->ctx->rsactx->d, e, pi) != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       crt->ctx->rsactx->pm = PaddingMethod;
+
+       if (RSA_N_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->n, RSA_KeyByteLen, RSA_N_Data);
+       }
+
+       if (RSA_N_Len != NULL)
+       {
+               *RSA_N_Len = RSA_KeyByteLen;
+       }
+
+       if (RSA_D_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->d, RSA_KeyByteLen, RSA_D_Data);
+       }
+
+       if (RSA_D_Len != NULL)
+       {
+               *RSA_D_Len = RSA_KeyByteLen;
+       }
+       
+       free(pbBuf);
+       
+       crt->ctx->rsactx->crt_operation = 0;
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_GenerateKeyForCRT(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+ *                                              cc_u8* RSA_N_Data, cc_u32 *RSA_N_Len,
+ *                                              cc_u8* RSA_E_Data, cc_u32 *RSA_E_Len,
+ *                                              cc_u8* RSA_D_Data, cc_u32 *RSA_D_Len,
+ *                                              cc_u8* RSA_P_Data, cc_u32 *RSA_P_Len,
+ *                                              cc_u8* RSA_Q_Data, cc_u32 *RSA_Q_Len,
+ *                                              cc_u8* RSA_DmodP1_Data, cc_u32 *RSA_DmodP1_Len,
+ *                                              cc_u8* RSA_DmodQ1_Data, cc_u32 *RSA_DmodQ1_Len,
+ *                                              cc_u8* RSA_iQmodP_Data, cc_u32 *RSA_iQmodP_Len)
+ * @brief      generate and set RSA parameters for CRT
+ *
+ * @param      crt                                                     [in/out]rsa context
+ * @param      PaddingMethod                           [in]padding method
+ * @param      RSA_N_Data                                      [out]n value
+ * @param      RSA_N_Len                                       [out]byte-length of n
+ * @param      RSA_E_Data                                      [out]e value
+ * @param      RSA_E_Len                                       [out]byte-length of e
+ * @param      RSA_D_Data                                      [out]d value
+ * @param      RSA_D_Len                                       [out]byte-length of d
+ * @param      RSA_P_Len                                       [out]byte-length of p
+ * @param      RSA_Q_Data                                      [out]q value
+ * @param      RSA_Q_Len                                       [out]byte-length of q
+ * @param      RSA_DmodP1_Data                         [out]d mod (p-1) value
+ * @param      RSA_DmodP1_Len                          [out]byte-length of d mod (p-1)
+ * @param      RSA_DmodQ1_Data                         [out]d mod (q-1) value
+ * @param      RSA_DmodQ1_Len                          [out]byte-length of d mod (q-1)
+ * @param      RSA_iQmodP_Data                         [out]q^(-1) mod p value
+ * @param      RSA_iQmodP_Len                          [out]byte-length of q^(-1) mod p
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+
+
+int SDRM_RSA_GenNEDPQ(CryptoCoreContainer *crt, cc_u32 PaddingMethod,
+                                                cc_u8* RSA_N_Data, cc_u32 *RSA_N_Len,
+                                                cc_u8* RSA_E_Data, cc_u32 *RSA_E_Len,
+                                                cc_u8* RSA_D_Data, cc_u32 *RSA_D_Len,
+                                                cc_u8* RSA_P_Data, cc_u32 *RSA_P_Len,
+                                                cc_u8* RSA_Q_Data, cc_u32 *RSA_Q_Len,
+                                                cc_u8* RSA_DmodP1_Data, cc_u32 *RSA_DmodP1_Len,
+                                                cc_u8* RSA_DmodQ1_Data, cc_u32 *RSA_DmodQ1_Len,
+                                                cc_u8* RSA_iQmodP_Data, cc_u32 *RSA_iQmodP_Len)
+{
+       cc_u32           Seed[4];
+       SDRM_BIG_NUM *p, *q, *pi, *e, *temp1, *temp2;
+       cc_u32           RSA_KeyByteLen = 0;
+       int                      i, sp, t1;
+       cc_u8 *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       t1 = (RSA_KeyByteLen * 4 - 1) % 32;
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 3);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       pi        = SDRM_BN_Alloc((cc_u8*)pbBuf,                                           SDRM_RSA_BN_BUFSIZE);
+       temp1 = SDRM_BN_Alloc((cc_u8*)pi        + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp2 = SDRM_BN_Alloc((cc_u8*)temp1 + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       e = crt->ctx->rsactx->e;
+       p = crt->ctx->rsactx->p;
+       q = crt->ctx->rsactx->q;
+
+       for (i = 0; i < 4; i++)
+       {
+               Seed[i] = (rand()  << 16) ^ rand();
+       }
+
+       //set security parameter for miller-rabin probabilistic primality test
+       if (RSA_KeyByteLen >= 256)
+       {
+               sp = 3;
+       }
+       else if (RSA_KeyByteLen >= 128)
+       {
+               sp = 5;
+       }
+       else if (RSA_KeyByteLen >= 30)
+       {
+               sp = 15;
+       }
+       else
+       {
+               sp = 30;
+       }
+
+GEN_RND:
+       
+       //Generate p
+       p->Length = (RSA_KeyByteLen + 7) / 8;
+       
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)p->pData);
+               p->pData[0] |= 1L;
+               p->pData[p->Length - 1] &= ~((-1L) << t1);
+               p->pData[p->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(p, sp) != CRYPTO_ISPRIME);
+
+       //Generate q
+       q->Length = (RSA_KeyByteLen + 7) / 8;
+       
+       do {
+               SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 4, (cc_u8*)q->pData);
+               q->pData[0] |= 1L;
+               q->pData[q->Length - 1] &= ~((-1L) << t1);
+               q->pData[q->Length - 1] |= (1L << t1);
+       }
+       while(SDRM_BN_MILLER_RABIN(q, sp) != CRYPTO_ISPRIME);
+
+//     SDRM_PrintBN("p", p);
+//     SDRM_PrintBN("q", q);
+               
+
+       //temp1 = (p - 1), temp2 = (q - 1)
+       SDRM_BN_Sub(temp1, p, BN_One);
+       SDRM_BN_Sub(temp2, q, BN_One);
+
+       //evaluate n and pi
+       //n = p * q, pi = (p - 1) * (q - 1)
+       SDRM_BN_Mul(crt->ctx->rsactx->n, p, q);
+       SDRM_BN_Mul(pi, temp1, temp2);
+
+       //generate e
+       e->Length = (RSA_KeyByteLen + 3) / 4;
+       do {
+               do {
+                       SDRM_RNG_X931((cc_u8 *)Seed, RSA_KeyByteLen * 8 - 8, (cc_u8*)e->pData);
+                       e->pData[0] |= 0x01;
+               }
+               while(SDRM_BN_CheckRelativelyPrime(e, pi) != CRYPTO_ISPRIME);
+       }
+       while (SDRM_BN_Cmp(e, pi) >= 0);
+
+       if (SDRM_BN_ModInv(crt->ctx->rsactx->d, e, pi) != CRYPTO_SUCCESS)
+       {
+               goto GEN_RND;
+       }
+
+       //calc dmodp1 = d mod (p - 1)
+       SDRM_BN_ModRed(crt->ctx->rsactx->dmodp1, crt->ctx->rsactx->d, temp1);
+
+       //calc dmodq1 = d mod (q - 1)
+       SDRM_BN_ModRed(crt->ctx->rsactx->dmodq1, crt->ctx->rsactx->d, temp2);
+
+       //calc iqmodp = inv_q mod p
+       SDRM_BN_ModInv(crt->ctx->rsactx->iqmodp, q, p);
+
+       crt->ctx->rsactx->pm = PaddingMethod;
+
+       if (RSA_N_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->n, RSA_KeyByteLen, RSA_N_Data);
+       }
+
+       if (RSA_N_Len != NULL)
+       {
+               *RSA_N_Len = RSA_KeyByteLen;
+       }
+
+       if (RSA_E_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->e, RSA_KeyByteLen, RSA_E_Data);
+       }
+
+       if (RSA_E_Len != NULL)
+       {
+               *RSA_E_Len = RSA_KeyByteLen;
+       }
+
+       if (RSA_D_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->d, RSA_KeyByteLen, RSA_D_Data);
+       }
+
+       if (RSA_D_Len != NULL)
+       {
+               *RSA_D_Len = RSA_KeyByteLen;
+       }
+       
+       if (RSA_P_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->p, RSA_KeyByteLen / 2, RSA_P_Data);
+       }
+
+       if (RSA_P_Len != NULL)
+       {
+               *RSA_P_Len = RSA_KeyByteLen / 2;
+       }
+
+       if (RSA_Q_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->q, RSA_KeyByteLen / 2, RSA_Q_Data);
+       }
+
+       if (RSA_Q_Len != NULL)
+       {
+               *RSA_Q_Len = RSA_KeyByteLen / 2;
+       }
+
+       if (RSA_DmodP1_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->dmodp1, RSA_KeyByteLen / 2, RSA_DmodP1_Data);
+       }
+
+       if (RSA_DmodP1_Len != NULL)
+       {
+               *RSA_DmodP1_Len = RSA_KeyByteLen / 2;
+       }
+
+       if (RSA_DmodQ1_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->dmodq1, RSA_KeyByteLen / 2, RSA_DmodQ1_Data);
+       }
+
+       if (RSA_DmodQ1_Len != NULL)
+       {
+               *RSA_DmodQ1_Len = RSA_KeyByteLen / 2;
+       }
+
+       if (RSA_iQmodP_Data != NULL)
+       {
+               SDRM_I2OSP(crt->ctx->rsactx->iqmodp, RSA_KeyByteLen / 2, RSA_iQmodP_Data);
+       }
+
+       if (RSA_iQmodP_Len != NULL)
+       {
+               *RSA_iQmodP_Len = RSA_KeyByteLen / 2;
+       }
+
+       free(pbBuf);
+       
+       crt->ctx->rsactx->crt_operation = 1;
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_encrypt(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+ * @brief      RSA Encryption
+ *
+ * @param      crt                                                     [in]rsa context
+ * @param      in                                                      [in]message to encrypt
+ * @param      inLen                                           [in]byte-length of in
+ * @param      out                                                     [out]encrypted message
+ * @param      outLen                                          [out]byte-length of out
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_encrypt(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+{
+       SDRM_BIG_NUM *BN_pMsg, *BN_Cipher;
+       int                      retVal = CRYPTO_ERROR;
+       cc_u32           RSA_KeyByteLen = 0;
+       cc_u8            *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL) || (in == NULL) || (out == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       if (inLen > RSA_KeyByteLen)
+       {
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_pMsg = SDRM_BN_Alloc((cc_u8*)pbBuf + RSA_KeyByteLen, SDRM_RSA_BN_BUFSIZE);
+       BN_Cipher = SDRM_BN_Alloc((cc_u8*)BN_pMsg + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       //Padding the message
+       switch(SDRM_LOW_HALF(crt->ctx->rsactx->pm))
+       {
+               case ID_RSAES_PKCS15 :
+                       retVal = SDRM_Enpad_Rsaes_pkcs15(pbBuf, in, inLen, RSA_KeyByteLen);
+                       break;
+               case ID_RSAES_OAEP :
+                       retVal = SDRM_Enpad_Rsaes_oaep(pbBuf, in, inLen, RSA_KeyByteLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+                       break;
+               case ID_NO_PADDING :
+            if( inLen != RSA_KeyByteLen) // add by guoxing.xu 20140919
+            {
+                free(pbBuf);
+                return CRYPTO_INVALID_ARGUMENT;
+            }
+                       memset(pbBuf, 0x00, RSA_KeyByteLen - inLen);
+                       memcpy(pbBuf + RSA_KeyByteLen - inLen, in, inLen);
+            retVal= CRYPTO_SUCCESS;// add by guoxing.xu 20140919
+                       break;
+               default :
+                       free(pbBuf);
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+//     SDRM_PrintBN("ENPADDED Text  : ", BN_pMsg);
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       SDRM_OS2BN(pbBuf, RSA_KeyByteLen, BN_pMsg);
+
+       //RSA Encryption by modular exponent
+#ifndef _OP64_NOTSUPPORTED
+       retVal = SDRM_BN_ModExp2(BN_Cipher, BN_pMsg, crt->ctx->rsactx->e, crt->ctx->rsactx->n);
+#else
+       retVal = SDRM_BN_ModExp(BN_Cipher, BN_pMsg, crt->ctx->rsactx->e, crt->ctx->rsactx->n);
+#endif //_OP64_NOTSUPPORTED
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       SDRM_I2OSP(BN_Cipher, RSA_KeyByteLen, out);
+
+       if (outLen != NULL)
+       {
+               *outLen = RSA_KeyByteLen;
+       }
+
+       memset(pbBuf, 0x00, SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_decrypt(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+ * @brief      RSA Decryption
+ *
+ * @param      crt                                                     [in]rsa context
+ * @param      in                                                      [in]message to decrypt
+ * @param      inLen                                           [in]byte-length of in
+ * @param      out                                                     [out]decrypted message
+ * @param      outLen                                          [out]byte-length of out
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_decrypt(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+{
+       SDRM_BIG_NUM    *BN_dMsg, *BN_Src;
+       int                             retVal;
+    cc_u32          plainLen;
+       cc_u32                  RSA_KeyByteLen = 0;
+       cc_u8                   *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL) || (in == NULL) || (out == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       if (inLen > RSA_KeyByteLen)
+       {
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_dMsg   = SDRM_BN_Alloc((cc_u8*)pbBuf + RSA_KeyByteLen, SDRM_RSA_BN_BUFSIZE);
+       BN_Src    = SDRM_BN_Alloc((cc_u8*)BN_dMsg + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       SDRM_OS2BN(in, inLen, BN_Src);
+       
+       //RSA Decryption by modular exponent
+#ifndef _OP64_NOTSUPPORTED
+       retVal = SDRM_BN_ModExp2(BN_dMsg, BN_Src, crt->ctx->rsactx->d, crt->ctx->rsactx->n);
+#else
+       retVal = SDRM_BN_ModExp(BN_dMsg, BN_Src, crt->ctx->rsactx->d, crt->ctx->rsactx->n);
+#endif //_OP64_NOTSUPPORTED
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       SDRM_I2OSP(BN_dMsg, RSA_KeyByteLen, pbBuf);
+
+       //Remove Padding from message
+       switch(SDRM_LOW_HALF(crt->ctx->rsactx->pm))
+       {
+               case ID_RSAES_PKCS15 :
+                       retVal = SDRM_Depad_Rsaes_pkcs15(out, &plainLen, pbBuf, RSA_KeyByteLen, RSA_KeyByteLen);
+                       break;
+               case ID_RSAES_OAEP :
+                       retVal = SDRM_Depad_Rsaes_oaep(out, &plainLen, pbBuf, RSA_KeyByteLen, RSA_KeyByteLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+                       break;
+               case ID_NO_PADDING :
+                       memcpy(out, pbBuf, RSA_KeyByteLen);
+                       plainLen = RSA_KeyByteLen;
+                       retVal = CRYPTO_SUCCESS;
+                       break;
+               default :
+                       free(pbBuf);
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       if (outLen != NULL)
+       {
+               *outLen = plainLen;
+       }
+
+       memset(pbBuf, 0x00, SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_decryptByCRT(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+ * @brief      RSA Decryption using CRT
+ *
+ * @param      crt                                                     [in]rsa context
+ * @param      in                                                      [in]message to decrypt
+ * @param      inLen                                           [in]byte-length of in
+ * @param      out                                                     [out]decrypted message
+ * @param      outLen                                          [out]byte-length of out
+ *
+ * @return     CRYPTO_SUCCESS                          if no error is occured
+ * \n          CRYPTO_NULL_POINTER                     if an argument is a null pointer
+ * \n          CRYPTO_MEMORY_ALLOC_FAIL        if memory allocation is failed
+ */
+int SDRM_RSA_decryptByCRT(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+{
+       SDRM_BIG_NUM    *BN_dMsg, *BN_Src;
+       int                             retVal;
+    cc_u32          plainLen;
+       cc_u32                  RSA_KeyByteLen = 0;
+       SDRM_BIG_NUM *pi, *temp1, *temp2, *m1, *m2, *h;
+       cc_u8                   *pbBuf = NULL;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL) || (in == NULL) || (out == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (crt->ctx->rsactx->crt_operation != 1)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       if (inLen > RSA_KeyByteLen)
+       {
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 8 + RSA_KeyByteLen);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_dMsg         = SDRM_BN_Alloc((cc_u8*)pbBuf + RSA_KeyByteLen,                    SDRM_RSA_BN_BUFSIZE);
+       BN_Src          = SDRM_BN_Alloc((cc_u8*)BN_dMsg         + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       pi                      = SDRM_BN_Alloc((cc_u8*)BN_Src          + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp1           = SDRM_BN_Alloc((cc_u8*)pi                      + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       temp2           = SDRM_BN_Alloc((cc_u8*)temp1           + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       m1                      = SDRM_BN_Alloc((cc_u8*)temp2           + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       m2                      = SDRM_BN_Alloc((cc_u8*)m1                      + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       h                       = SDRM_BN_Alloc((cc_u8*)m2                      + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       SDRM_OS2BN(in, inLen, BN_Src);
+       
+       //RSA Decryption by CRT
+       /*
+               dp = d mod (p - 1)
+               dq = d mod (q - 1)
+               qInv = (1/q) mod p  where p > q
+       => 
+               m1 = c^dp mod p
+               m2 = c^dq mod q
+               h = qInv(m1 - m2) mod p if (m1 >= m2) or h = qInv(m1 + p - m2) mod p if (m1 < m2)
+               m = m2 + hq
+       */
+
+       // Prepare variables
+       // 1. dP = d mod (p - 1)
+       //      dP is already set when SDRM_RSA_setNEDPQ
+
+       // 2. dQ = d mod (q - 1)
+       //      dQ is already set when SDRM_RSA_setNEDPQ
+
+       // 3. qInv = (1/q) mod p  where p > q
+       //      qInv is already set when SDRM_RSA_setNEDPQ
+
+       // Computation
+       // 4. m1 = c^dP mod p
+       if(SDRM_BN_ModExp2(m1, BN_Src, crt->ctx->rsactx->dmodp1, crt->ctx->rsactx->p))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       // 5. m2 = c^dQ mod q
+       if(SDRM_BN_ModExp2(m2, BN_Src, crt->ctx->rsactx->dmodq1, crt->ctx->rsactx->q))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       // 6. h = qInv(m1 - m2) mod p if (m1 >= m2) or h = qInv(m1 + p - m2) mod p if (m1 < m2)
+       if(SDRM_BN_Cmp(m1, m2) < 0)
+       {
+               if(SDRM_BN_Add(m1, m1, crt->ctx->rsactx->p))
+               {
+                       free(pbBuf);
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+       }
+
+       if(SDRM_BN_Sub(m1, m1, m2))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if(SDRM_BN_ModMul(h, crt->ctx->rsactx->iqmodp, m1, crt->ctx->rsactx->p))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+       
+       // 7. m = m2 + hq
+       if(SDRM_BN_Mul(h, h, crt->ctx->rsactx->q))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+               
+       if(SDRM_BN_Add(BN_dMsg, m2, h))
+       {
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+//     SDRM_PrintBN("OAEP Text  : ", BN_dMsg);
+
+       SDRM_I2OSP(BN_dMsg, RSA_KeyByteLen, pbBuf);
+
+       //Remove Padding from message
+       switch (SDRM_LOW_HALF(crt->ctx->rsactx->pm))
+       {
+       case ID_RSAES_PKCS15:
+               retVal = SDRM_Depad_Rsaes_pkcs15(out, &plainLen, pbBuf, RSA_KeyByteLen, RSA_KeyByteLen);
+               break;
+       case ID_RSAES_OAEP:
+               retVal = SDRM_Depad_Rsaes_oaep(out, &plainLen, pbBuf, RSA_KeyByteLen, RSA_KeyByteLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+               break;
+       case ID_NO_PADDING:
+               memcpy(out, pbBuf, RSA_KeyByteLen);
+               plainLen = RSA_KeyByteLen;
+               retVal = CRYPTO_SUCCESS;
+               break;
+       default:
+               free(pbBuf);
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       if (outLen != NULL)
+       {
+               *outLen = plainLen;
+       }
+
+       memset(pbBuf, 0x00, SDRM_RSA_ALLOC_SIZE * 8 + RSA_KeyByteLen);
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_RSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                     [in]crypto env structure
+ * @param      hash                            [in]hash value
+ * @param      hashLen                         [in]byte-length of hash
+ * @param      signature                       [out]generated signature
+ * @param      signLen                         [out]byte-length of signature
+ *
+ * @return     CRYPTO_SUCCESS          if success
+ * \n          CRYPTO_NULL_POINTER     if given argument is a null pointer
+ */
+int SDRM_RSA_sign(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 *signLen)
+{
+       SDRM_BIG_NUM    *BN_pMsg, *BN_Sign;
+       int                             retVal;
+       cc_u32                  RSA_KeyByteLen = 0;
+       cc_u8                   *pbBuf = NULL;
+       cc_u32                  nBits;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL) || (hash == NULL) || (signature == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       if (hashLen > RSA_KeyByteLen)
+       {
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_pMsg = SDRM_BN_Alloc((cc_u8*)pbBuf + RSA_KeyByteLen, SDRM_RSA_BN_BUFSIZE);
+       BN_Sign = SDRM_BN_Alloc((cc_u8*)BN_pMsg + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       //Msg Padding
+       switch(SDRM_LOW_HALF(crt->ctx->rsactx->pm))
+       {
+               case ID_RSASSA_PKCS15 :
+                       retVal = SDRM_Enpad_Rsassa_pkcs15(pbBuf, RSA_KeyByteLen, hash, hashLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+                       break;
+               case ID_RSASSA_PSS :
+                       SDRM_BN_GETBITLEN(crt->ctx->rsactx->n, nBits);
+                       retVal = SDRM_Enpad_Rsassa_pss(pbBuf, nBits, hash, hashLen, RSA_KeyByteLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+                       break;
+               case ID_NO_PADDING :
+                       memset(pbBuf, 0x00, RSA_KeyByteLen - hashLen);
+                       //memcpy(pbBuf + hashLen, hash, RSA_KeyByteLen);
+                       memcpy(pbBuf + RSA_KeyByteLen - hashLen, hash, hashLen);// fixed by guoxing.xu 20140919
+                       retVal = CRYPTO_SUCCESS;
+                       break;
+               default :
+                       free(pbBuf);
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+//     SDRM_PrintBN("ENPADDED Msg   : ", BN_pMsg);
+
+       SDRM_OS2BN(pbBuf, RSA_KeyByteLen, BN_pMsg);
+
+       //RSA Signature by modular exponent
+#ifndef _OP64_NOTSUPPORTED
+       retVal = SDRM_BN_ModExp2(BN_Sign, BN_pMsg, crt->ctx->rsactx->d, crt->ctx->rsactx->n);
+#else
+       retVal = SDRM_BN_ModExp(BN_Sign, BN_pMsg, crt->ctx->rsactx->d, crt->ctx->rsactx->n);
+#endif //_OP64_NOTSUPPORTED
+
+       if (retVal != CRYPTO_SUCCESS) 
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       SDRM_I2OSP(BN_Sign, RSA_KeyByteLen, signature);
+
+       if (signLen != NULL)
+       {
+               *signLen = RSA_KeyByteLen;
+       }
+
+       memset(pbBuf, 0x00, SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       free(pbBuf);
+
+       return retVal;
+}
+
+/*
+ * @fn         int SDRM_RSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result)
+ * @brief      generate signature for given value
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      hash                                    [in]hash value
+ * @param      hashLen                                 [in]byte-length of hash
+ * @param      signature                               [in]signature
+ * @param      signLen                                 [in]byte-length of signature
+ * @param      result                                  [in]result of verifying signature
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if the length of signature is invalid
+ */
+int SDRM_RSA_verify(CryptoCoreContainer *crt, cc_u8 *hash, cc_u32 hashLen, cc_u8 *signature, cc_u32 signLen, int *result)
+{
+       SDRM_BIG_NUM    *BN_dMsg, *BN_Sign;
+       int                             retVal;
+       cc_u32                  RSA_KeyByteLen = 0;
+       cc_u8                   *pbBuf = NULL;
+       cc_u32                  nBits;
+       cc_u32 i;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rsactx == NULL) || (hash == NULL) || (signature == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       RSA_KeyByteLen = crt->ctx->rsactx->k;
+       if (hashLen > RSA_KeyByteLen)
+       {
+               return CRYPTO_MSG_TOO_LONG;
+       }
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_dMsg = SDRM_BN_Alloc((cc_u8*)pbBuf + RSA_KeyByteLen, SDRM_RSA_BN_BUFSIZE);
+       BN_Sign = SDRM_BN_Alloc((cc_u8*)BN_dMsg + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       SDRM_OS2BN(signature, signLen, BN_Sign);
+//     SDRM_PrintBN("Generated Sign : ", BN_Sign);
+       
+       //RSA Verification by modular exponent
+#ifndef _OP64_NOTSUPPORTED
+       retVal = SDRM_BN_ModExp2(BN_dMsg, BN_Sign, crt->ctx->rsactx->e, crt->ctx->rsactx->n);
+#else
+       retVal = SDRM_BN_ModExp(BN_dMsg, BN_Sign, crt->ctx->rsactx->e, crt->ctx->rsactx->n);
+#endif //_OP64_NOTSUPPORTED
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               free(pbBuf);
+               return retVal;
+       }
+
+       SDRM_I2OSP(BN_dMsg, RSA_KeyByteLen, pbBuf);
+
+       //Msg Depadding
+       switch(SDRM_LOW_HALF(crt->ctx->rsactx->pm))
+       {
+               case ID_RSASSA_PKCS15 :
+                       *result = SDRM_Depad_Rsassa_pkcs15(pbBuf, RSA_KeyByteLen, hash, hashLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+                       break;
+               case ID_RSASSA_PSS :
+                       SDRM_BN_GETBITLEN(crt->ctx->rsactx->n, nBits);
+                       *result = SDRM_Depad_Rsassa_pss(pbBuf, nBits, hash, hashLen, RSA_KeyByteLen, SDRM_HIGH_HALF(crt->ctx->rsactx->pm));
+                       break;
+               case ID_NO_PADDING :
+                       for (i = 0; i < (RSA_KeyByteLen - hashLen); i++)
+                       {
+                               if (pbBuf[i] != 0)
+                               {
+                                       *result = CRYPTO_INVALID_SIGN;
+                               }
+                       }
+
+                       if ((i == (RSA_KeyByteLen - hashLen)) && (memcmp(pbBuf + i, hash, hashLen) == 0))
+                       {
+                               *result = CRYPTO_VALID_SIGN;
+                       }
+                       else
+                       {
+                               *result = CRYPTO_INVALID_SIGN;
+                       }
+
+               default :
+                       break;
+       }
+
+       memset(pbBuf, 0x00, SDRM_RSA_ALLOC_SIZE * 2 + RSA_KeyByteLen);
+       SDRM_BN_FREE(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
+int SDRM_Extended_GCD(SDRM_BIG_NUM* BN_v, SDRM_BIG_NUM* BN_a, SDRM_BIG_NUM* BN_b, SDRM_BIG_NUM* BN_x, SDRM_BIG_NUM* BN_y)
+{
+       SDRM_BIG_NUM* BN_g;
+       SDRM_BIG_NUM* BN_u;
+       SDRM_BIG_NUM* BN_A;
+       SDRM_BIG_NUM* BN_B;
+       SDRM_BIG_NUM* BN_C;
+       SDRM_BIG_NUM* BN_D;
+       SDRM_BIG_NUM* BN_tmp;
+       SDRM_BIG_NUM* BN_xx;
+       SDRM_BIG_NUM* BN_yy;
+       cc_u8* pbBuf = NULL;
+       cc_u32 RSA_KeyByteLen = 128;
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 9);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_g    = SDRM_BN_Alloc((cc_u8*)pbBuf,                                             SDRM_RSA_BN_BUFSIZE);
+       BN_u    = SDRM_BN_Alloc((cc_u8*)BN_g    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_A    = SDRM_BN_Alloc((cc_u8*)BN_u    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_B    = SDRM_BN_Alloc((cc_u8*)BN_A    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_C    = SDRM_BN_Alloc((cc_u8*)BN_B    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_D    = SDRM_BN_Alloc((cc_u8*)BN_C    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_tmp  = SDRM_BN_Alloc((cc_u8*)BN_D    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_xx   = SDRM_BN_Alloc((cc_u8*)BN_tmp  + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_yy   = SDRM_BN_Alloc((cc_u8*)BN_xx   + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       SDRM_BN_Copy(BN_g, BN_One);
+       SDRM_BN_Copy(BN_xx, BN_x);
+       SDRM_BN_Copy(BN_yy, BN_y);
+
+       while(!SDRM_BN_IS_ODD(BN_xx) && !SDRM_BN_IS_ODD(BN_yy))
+       {
+               SDRM_BN_SHR(BN_xx, BN_xx, 1);
+               SDRM_BN_SHR(BN_yy, BN_yy, 1);
+               SDRM_BN_SHL(BN_g, BN_g, 1);
+       }
+
+       SDRM_BN_Copy(BN_u, BN_xx);
+       SDRM_BN_Copy(BN_v, BN_yy);
+
+       SDRM_BN_Copy(BN_A, BN_One);
+       SDRM_BN_Copy(BN_B, BN_Zero);
+       SDRM_BN_Copy(BN_C, BN_Zero);
+       SDRM_BN_Copy(BN_D, BN_One);
+
+       while(1)
+       {
+               while(!SDRM_BN_IS_ODD(BN_u))
+               {
+                       SDRM_BN_SHR(BN_u, BN_u, 1);
+                       if (!SDRM_BN_IS_ODD(BN_A) && !SDRM_BN_IS_ODD(BN_B))
+                       {
+                               SDRM_BN_SHR(BN_A, BN_A, 1);
+                               SDRM_BN_SHR(BN_B, BN_B, 1);
+                       }
+                       else
+                       {
+                               SDRM_BN_Add(BN_A, BN_A, BN_yy);
+                               SDRM_BN_SHR(BN_A, BN_A, 1);
+
+                               SDRM_BN_Sub(BN_tmp, BN_B, BN_xx);
+                               SDRM_BN_SHR(BN_B, BN_tmp, 1);
+                       }
+               }
+
+               while(!SDRM_BN_IS_ODD(BN_v))
+               {
+                       SDRM_BN_SHR(BN_v, BN_v, 1);
+                       if (!SDRM_BN_IS_ODD(BN_C) && !SDRM_BN_IS_ODD(BN_D))
+                       {
+                               SDRM_BN_SHR(BN_C, BN_C, 1);
+                               SDRM_BN_SHR(BN_D, BN_D, 1);
+                       }
+                       else
+                       {
+                               SDRM_BN_Add(BN_C, BN_C, BN_yy);
+                               SDRM_BN_SHR(BN_C, BN_C, 1);
+
+                               SDRM_BN_Sub(BN_tmp, BN_D, BN_xx);
+                               SDRM_BN_SHR(BN_D, BN_tmp, 1);
+                       }
+               }
+
+               if (SDRM_BN_Cmp(BN_u, BN_v) >= 0)
+               {
+                       SDRM_BN_Sub(BN_tmp, BN_u, BN_v);
+                       SDRM_BN_Copy(BN_u, BN_tmp);
+
+                       SDRM_BN_Sub(BN_tmp, BN_A, BN_C);
+                       SDRM_BN_Copy(BN_A, BN_tmp);
+
+                       SDRM_BN_Sub(BN_tmp, BN_B, BN_D);
+                       SDRM_BN_Copy(BN_B, BN_tmp);
+               }
+               else
+               {
+                       SDRM_BN_Sub(BN_tmp, BN_v, BN_u);
+                       SDRM_BN_Copy(BN_v, BN_tmp);
+
+                       SDRM_BN_Sub(BN_tmp, BN_C, BN_A);
+                       SDRM_BN_Copy(BN_C, BN_tmp);
+
+                       SDRM_BN_Sub(BN_tmp, BN_D, BN_B);
+                       SDRM_BN_Copy(BN_D, BN_tmp);
+               }
+
+               if (SDRM_BN_Cmp(BN_u, BN_Zero) == 0)
+               {
+                       SDRM_BN_Copy(BN_a, BN_C);
+                       SDRM_BN_Copy(BN_b, BN_D);
+                       SDRM_BN_Mul(BN_tmp, BN_g, BN_v);
+                       SDRM_BN_Copy(BN_v, BN_tmp);
+                       
+                       break;
+               }
+       }
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+int SDRM_CheckRSAKey(SDRM_BIG_NUM* BN_n, SDRM_BIG_NUM* BN_e, SDRM_BIG_NUM* BN_d)
+{
+       SDRM_BIG_NUM* BN_m;
+       SDRM_BIG_NUM* BN_c;
+       SDRM_BIG_NUM* BN_m1;
+       cc_u8* pbBuf = NULL;
+       cc_u32 RSA_KeyByteLen = 128;
+
+       int retVal;
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 3);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_m    = SDRM_BN_Alloc((cc_u8*)pbBuf,                                             SDRM_RSA_BN_BUFSIZE);
+       BN_c    = SDRM_BN_Alloc((cc_u8*)BN_m    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_m1   = SDRM_BN_Alloc((cc_u8*)BN_c    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       SDRM_BN_Rand(BN_m, 1020);
+
+       SDRM_BN_ModExp(BN_c, BN_m, BN_e, BN_n);
+       SDRM_BN_ModExp(BN_m1, BN_c, BN_d, BN_n);
+
+       if (SDRM_BN_Cmp(BN_m, BN_m1) == 0)
+       {
+               retVal = CRYPTO_SUCCESS;
+       }
+       else
+       {
+               retVal = CRYPTO_ERROR;
+       }
+
+       free(pbBuf);
+
+       return retVal;
+}
+
+int SDRM_RSA_ConvertCRT2PrivateExp(cc_u8 *p320byteCRTParam, cc_u8 *PrivateExp)
+{
+       SDRM_BIG_NUM* BN_g;
+       SDRM_BIG_NUM* BN_v;
+       SDRM_BIG_NUM* BN_diff;
+       SDRM_BIG_NUM* BN_k;
+       SDRM_BIG_NUM* BN_r;
+       SDRM_BIG_NUM* BN_l;
+       SDRM_BIG_NUM* BN_u;
+       SDRM_BIG_NUM* BN_n;
+       SDRM_BIG_NUM* BN_e;
+       SDRM_BIG_NUM* BN_d;
+       SDRM_BIG_NUM* BN_p;
+       SDRM_BIG_NUM* BN_q;
+       SDRM_BIG_NUM* BN_dp;
+       SDRM_BIG_NUM* BN_dq;
+
+       cc_u8* pbBuf = NULL;
+       cc_u32 RSA_KeyByteLen = 128;
+
+       pbBuf = (cc_u8*)malloc(SDRM_RSA_ALLOC_SIZE * 14);
+       if (pbBuf == NULL)
+       {
+               return CRYPTO_MEMORY_ALLOC_FAIL;
+       }
+
+       BN_g    = SDRM_BN_Alloc((cc_u8*)pbBuf,                                             SDRM_RSA_BN_BUFSIZE);
+       BN_v    = SDRM_BN_Alloc((cc_u8*)BN_g    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_diff = SDRM_BN_Alloc((cc_u8*)BN_v    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_k    = SDRM_BN_Alloc((cc_u8*)BN_diff + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_r    = SDRM_BN_Alloc((cc_u8*)BN_k    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_l    = SDRM_BN_Alloc((cc_u8*)BN_r    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_u    = SDRM_BN_Alloc((cc_u8*)BN_l    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_n    = SDRM_BN_Alloc((cc_u8*)BN_u    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_e    = SDRM_BN_Alloc((cc_u8*)BN_n    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_d    = SDRM_BN_Alloc((cc_u8*)BN_e    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_p    = SDRM_BN_Alloc((cc_u8*)BN_d    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_q    = SDRM_BN_Alloc((cc_u8*)BN_p    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_dp   = SDRM_BN_Alloc((cc_u8*)BN_q    + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+       BN_dq   = SDRM_BN_Alloc((cc_u8*)BN_dp   + SDRM_RSA_ALLOC_SIZE, SDRM_RSA_BN_BUFSIZE);
+
+       SDRM_OS2BN(p320byteCRTParam,       64, BN_p);
+       SDRM_OS2BN(p320byteCRTParam + 64,  64, BN_q);
+       SDRM_OS2BN(p320byteCRTParam + 128, 64, BN_dp);
+       SDRM_OS2BN(p320byteCRTParam + 192, 64, BN_dq);
+
+       SDRM_BN_Mul(BN_n, BN_p, BN_q);
+
+       if (SDRM_BN_Cmp(BN_dp, BN_dq) < 0)
+       {
+               SDRM_BIG_NUM* tmp;
+               tmp = BN_p;
+               BN_p = BN_q;
+               BN_q = tmp;
+
+               tmp = BN_dp;
+               BN_dp = BN_dq;
+               BN_dq = tmp;
+       }
+
+       SDRM_BN_Sub(BN_p, BN_p, BN_One);
+       SDRM_BN_Sub(BN_q, BN_q, BN_One);
+
+       SDRM_Extended_GCD(BN_g, BN_u, BN_v, BN_p, BN_q);
+       SDRM_BN_Sub(BN_diff, BN_dp, BN_dq);
+       SDRM_BN_Div(BN_k, NULL, BN_diff, BN_g);
+
+       SDRM_BN_Mul(BN_r, BN_k, BN_u);
+       SDRM_BN_Mul(BN_k, BN_r, BN_p);
+       SDRM_BN_Sub(BN_d, BN_dp, BN_k);
+
+       SDRM_BN_Mul(BN_k, BN_p, BN_q);
+       SDRM_BN_Div(BN_l, NULL, BN_k, BN_g);
+
+       SDRM_BN_ModRed(BN_r, BN_d, BN_l);
+
+       if ((SDRM_BN_Cmp(BN_r, BN_Zero) != 0) && SDRM_IS_BN_NEGATIVE(BN_r))
+       {
+               SDRM_BN_Add(BN_d, BN_l, BN_r);
+       }
+       else
+       {
+               SDRM_BN_Copy(BN_d, BN_r);
+       }
+
+       SDRM_BN_ModInv(BN_e, BN_d, BN_l);
+       SDRM_BN_ModInv(BN_d, BN_e, BN_k);
+
+       if ((SDRM_BN_Cmp(BN_d, BN_Zero) != 0) && !SDRM_IS_BN_NEGATIVE(BN_d))
+       {
+               SDRM_BN_ModRed(BN_r, BN_d, BN_p);
+               SDRM_PrintBN("n", BN_n);
+               SDRM_PrintBN("e", BN_e);
+               SDRM_PrintBN("d", BN_d);
+
+               if (SDRM_BN_Cmp(BN_r, BN_dp) == 0)
+               {
+                       if (SDRM_CheckRSAKey(BN_n, BN_e, BN_d) == CRYPTO_SUCCESS)
+                       {
+                               SDRM_BN2OS(BN_d, 128, PrivateExp);
+                       }
+               }
+       }
+
+       free(pbBuf);
+
+       return CRYPTO_SUCCESS;
+}
+
+
diff --git a/ssflib/dep/cryptocore/source/middle/cc_symmetric.c b/ssflib/dep/cryptocore/source/middle/cc_symmetric.c
new file mode 100755 (executable)
index 0000000..b70f441
--- /dev/null
@@ -0,0 +1,1703 @@
+/**
+ * \file       symmetric.c
+ * @brief      API for symmetric encryption
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon, Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/11/07
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Include Header Files
+////////////////////////////////////////////////////////////////////////////
+#include "cc_symmetric.h"
+#include "cc_moo.h"
+#include "cc_rc4.h"
+#include "cc_snow2.h"
+#include <stdio.h>
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_getEncRoundKey
+ * @brief      get scheduled key for encryption
+ *
+ * @param      Algorithm                               [in]cipher algorithm
+ * @param      UserKey                                 [in]user key
+ * @param      RoundKey                                [out]round key
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_getEncRoundKey(int Algorithm, cc_u8* UserKey, cc_u8* RoundKey)
+{
+       if ((UserKey == NULL) || (RoundKey == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       switch (Algorithm)
+       {
+               case ID_AES128 : 
+                       SDRM_rijndaelKeySetupEnc((cc_u32*)(void*)RoundKey, UserKey, 128);
+                       return CRYPTO_SUCCESS;
+               case ID_AES192 : 
+                       SDRM_rijndaelKeySetupEnc((cc_u32*)(void*)RoundKey, UserKey, 192);
+                       return CRYPTO_SUCCESS;
+               case ID_AES256 : 
+                       SDRM_rijndaelKeySetupEnc((cc_u32*)(void*)RoundKey, UserKey, 256);
+                       return CRYPTO_SUCCESS;
+               case ID_DES : 
+                       SDRM_DES_KeySched(RoundKey, UserKey, 0, 1);
+                       return CRYPTO_SUCCESS;
+               case ID_TDES_EDE2 : 
+                       SDRM_TDES_KeySched(RoundKey, UserKey, 16, 1);
+                       return CRYPTO_SUCCESS;
+               case ID_TDES_EDE3 : 
+                       SDRM_TDES_KeySched(RoundKey, UserKey, 24, 1);
+                       return CRYPTO_SUCCESS;
+               default :
+                       break;
+       }
+
+       return CRYPTO_INVALID_ARGUMENT;
+}
+
+/*
+ * @fn         SDRM_getDecRoundKey
+ * @brief      get scheduled key for decryption
+ *
+ * @param      Algorithm                               [in]cipher algorithm
+ * @param      UserKey                                 [in]user key
+ * @param      RoundKey                                [out]round key
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_getDecRoundKey(int Algorithm, cc_u8* UserKey, cc_u8* RoundKey)
+{
+       if ((UserKey == NULL) || (RoundKey == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       switch (Algorithm)
+       {
+               case ID_AES128 : 
+                       SDRM_rijndaelKeySetupDec((cc_u32*)(void*)RoundKey, UserKey, 128);
+                       return CRYPTO_SUCCESS;
+               case ID_AES192 : 
+                       SDRM_rijndaelKeySetupDec((cc_u32*)(void*)RoundKey, UserKey, 192);
+                       return CRYPTO_SUCCESS;
+               case ID_AES256 : 
+                       SDRM_rijndaelKeySetupDec((cc_u32*)(void*)RoundKey, UserKey, 256);
+                       return CRYPTO_SUCCESS;
+               case ID_DES : 
+                       SDRM_DES_KeySched(RoundKey, UserKey, 15, (cc_u32)-1);
+                       return CRYPTO_SUCCESS;
+               case ID_TDES_EDE2 : 
+                       SDRM_TDES_KeySched(RoundKey, UserKey, 16, (cc_u32)-1);
+                       return CRYPTO_SUCCESS;
+               case ID_TDES_EDE3 : 
+                       SDRM_TDES_KeySched(RoundKey, UserKey, 24, (cc_u32)-1);
+                       return CRYPTO_SUCCESS;
+               default :
+                       break;
+       }
+
+       return CRYPTO_INVALID_ARGUMENT;
+}
+
+/*
+ * @fn         SDRM_AES_init
+ * @brief      intialize crypt context for aes
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_AES_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->aesctx == NULL) || (key == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (!(((mode >= 1111) && (mode <= 1115)) || ((mode >= 1121) && (mode <= 1125))))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (!((crt->alg == ID_AES128) && (keysize == 16)) &&
+               !((crt->alg == ID_AES192) && (keysize == 24)) &&
+               !((crt->alg == ID_AES256) && (keysize == 32)))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if ((crt->alg != ID_AES128) && (crt->alg != ID_AES192) && (crt->alg != ID_AES256))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if ((PADDING != 0) && (PADDING != ID_PKCS5) && (PADDING != ID_SSL_PADDING) && (PADDING != ID_ZERO_PADDING) && (PADDING != ID_NO_PADDING))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       crt->ctx->aesctx->moo = mode;
+
+       crt->ctx->aesctx->padding = PADDING;
+
+       if (mode != ID_DEC_ECB && mode != ID_DEC_CBC)
+       {
+               SDRM_getEncRoundKey(crt->alg, key, crt->ctx->aesctx->RoundKey);
+       }
+       else
+       {
+               SDRM_getDecRoundKey(crt->alg, key, crt->ctx->aesctx->RoundKey);
+       }
+       
+       if (IV)
+       {
+               memcpy(crt->ctx->aesctx->IV, IV, SDRM_AES_BLOCK_SIZ);
+       }
+       else
+       {
+               memset(crt->ctx->aesctx->IV, 0x00, SDRM_AES_BLOCK_SIZ);
+       }
+
+       crt->ctx->aesctx->BlockLen = 0;
+
+       GET_UINT32(crt->ctx->aesctx->CTR_Count, crt->ctx->aesctx->IV + 12, 0);
+
+       return CRYPTO_SUCCESS;
+
+}
+
+/*
+ * @fn         SDRM_AES_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      Text                                    [in]message block
+ * @param      TextLen                                 [in]byte-length of Text
+ * @param      output                                  [out]proecessed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_AES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int i, Temp;
+       int retVal, BlockLen;
+       cc_u8 *Block;
+       cc_u32 tempLen = 0;
+
+       if (outputLen != NULL)
+       {
+               *outputLen = 0;
+       }
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->aesctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       Block = crt->ctx->aesctx->Block;
+       BlockLen = crt->ctx->aesctx->BlockLen;
+
+       if ((TextLen + BlockLen) < SDRM_AES_BLOCK_SIZ)
+       {
+               memcpy(Block + BlockLen, Text, TextLen);
+               crt->ctx->aesctx->BlockLen += TextLen;
+               return CRYPTO_SUCCESS;
+       }
+
+       if (BlockLen)
+       {
+               memcpy(Block + BlockLen, Text, SDRM_AES_BLOCK_SIZ - BlockLen);
+
+               switch(crt->ctx->aesctx->moo)
+               {
+                       case ID_ENC_ECB :
+                               retVal = SDRM_ECB_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CBC :
+                               retVal = SDRM_CBC_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CFB :
+                               retVal = SDRM_CFB_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_OFB :
+                               retVal = SDRM_OFB_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CTR :
+                               retVal = SDRM_CTR_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV, crt->ctx->aesctx->CTR_Count++);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_ECB : 
+                               retVal = SDRM_ECB_Dec(crt->alg, output, Block, crt->ctx->aesctx->RoundKey);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CBC :
+                               retVal = SDRM_CBC_Dec(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CFB :
+                               retVal = SDRM_CFB_Dec(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_OFB :
+                               retVal = SDRM_OFB_Dec(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CTR : 
+                               retVal = SDRM_CTR_Dec(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV, crt->ctx->aesctx->CTR_Count++);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       Temp = TextLen - SDRM_AES_BLOCK_SIZ + 1;
+       for (i = (SDRM_AES_BLOCK_SIZ - BlockLen) & 0x0f; i < Temp; i += SDRM_AES_BLOCK_SIZ)
+       {
+               switch(crt->ctx->aesctx->moo)
+               {
+                       case ID_ENC_ECB : 
+                               retVal = SDRM_ECB_Enc(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CBC :
+                               retVal = SDRM_CBC_Enc(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CFB :
+                               retVal = SDRM_CFB_Enc(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_OFB :
+                               retVal = SDRM_OFB_Enc(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CTR : 
+                               retVal = SDRM_CTR_Enc(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV, crt->ctx->aesctx->CTR_Count++);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_ECB : 
+                               retVal = SDRM_ECB_Dec(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CBC :
+                               retVal = SDRM_CBC_Dec(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CFB :
+                               retVal = SDRM_CFB_Dec(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_OFB :
+                               retVal = SDRM_OFB_Dec(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CTR : 
+                               retVal = SDRM_CTR_Dec(crt->alg, output + tempLen, Text + i, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV, crt->ctx->aesctx->CTR_Count++);
+                               tempLen += SDRM_AES_BLOCK_SIZ;
+                               break;
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       crt->ctx->aesctx->BlockLen = (SDRM_AES_BLOCK_SIZ + TextLen - i) & 0x0f;
+       memcpy(Block, Text + TextLen - crt->ctx->aesctx->BlockLen, crt->ctx->aesctx->BlockLen);
+
+       if (outputLen != 0)
+       {
+               *outputLen = tempLen;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_AES_final
+ * @brief      process final block and padding
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      input                                   [in]message block
+ * @param      inputLen                                [in]byte-length of Text
+ * @param      output                                  [out]processed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_AES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int retVal = CRYPTO_SUCCESS;
+       cc_u8 *Block, PADDING[16];
+       cc_u32 BlockLen;
+       cc_u8 t;
+       int i = 0;
+
+
+
+       if (outputLen != NULL)
+       {
+               *outputLen = 0;
+       }
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->aesctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       Block = crt->ctx->aesctx->Block;
+       BlockLen = crt->ctx->aesctx->BlockLen;
+       i = 0;
+       printf("Block [%d]: %d\n", i, Block[0]);
+
+       if (crt->ctx->aesctx->moo >= ID_DEC_ECB)
+       {
+               goto DECRYPTION;
+       }
+
+//ENCRYPTION:
+       if (inputLen != 0)
+       {
+               unsigned int temp;
+               retVal = SDRM_AES_process(crt, input, inputLen, output, &temp);
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+
+               retVal = SDRM_AES_final(crt, NULL, 0, output + temp, outputLen);
+               
+               if (outputLen)
+               {
+                       *outputLen += temp;
+               }
+
+               return retVal;
+       }
+
+       if (outputLen != NULL)
+       {
+               *outputLen = SDRM_AES_BLOCK_SIZ;
+       }
+
+       //padding
+       switch(crt->ctx->aesctx->padding)
+       {
+               case 0 :
+               case ID_PKCS5 :
+                       memset(Block + BlockLen, SDRM_AES_BLOCK_SIZ - BlockLen, SDRM_AES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_SSL_PADDING :
+                       memset(Block + BlockLen, SDRM_AES_BLOCK_SIZ - BlockLen - 1, SDRM_AES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_ZERO_PADDING :
+                       memset(Block + BlockLen, 0x00, SDRM_AES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_NO_PADDING :
+                       if (BlockLen == 0)
+                       {
+                               if (outputLen)
+                               {
+                                       *outputLen = 0;
+                               }
+                               return CRYPTO_SUCCESS;
+                       }
+                       break;
+               default :
+               {
+
+                       return CRYPTO_INVALID_ARGUMENT;
+               }
+       }
+
+       //encryption
+       switch(crt->ctx->aesctx->moo)
+       {
+               case ID_ENC_ECB : 
+                       retVal = SDRM_ECB_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey);
+                       break;
+               case ID_ENC_CBC :
+                       retVal = SDRM_CBC_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                       break;
+               case ID_ENC_CFB :
+                       retVal = SDRM_CFB_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                       break;
+               case ID_ENC_OFB :
+                       retVal = SDRM_OFB_Enc(crt->alg, output, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                       break;
+               case ID_ENC_CTR : 
+                       retVal = SDRM_CTR_Enc(crt->alg, Block, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV, crt->ctx->aesctx->CTR_Count++);
+            if(crt->ctx->aesctx->padding != ID_NO_PADDING)// add by xugx to support padding 
+            {
+                BlockLen = SDRM_AES_BLOCK_SIZ;
+            }
+            memcpy(output, Block, BlockLen);
+                       if(outputLen != NULL)
+                       {
+                               *outputLen = BlockLen;
+                       }
+                       break;
+               default :
+                       {
+                               retVal = CRYPTO_INVALID_ARGUMENT;
+                       }
+                       break;
+       }
+
+       return retVal;
+
+DECRYPTION:
+       if (outputLen != NULL)
+       {
+               *outputLen = 0;
+       }
+
+       if ((inputLen == 0) && (crt->ctx->aesctx->padding == ID_NO_PADDING) && (crt->ctx->aesctx->moo != ID_DEC_CTR))
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       if (((BlockLen + inputLen) != SDRM_AES_BLOCK_SIZ) && (crt->ctx->aesctx->moo != ID_DEC_CTR))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (inputLen != 0)
+       {
+               memcpy(Block + BlockLen, input, inputLen);
+       }
+
+       switch(crt->ctx->aesctx->moo)
+       {
+               case ID_DEC_ECB : 
+                       retVal = SDRM_ECB_Dec(crt->alg, Block, Block, crt->ctx->aesctx->RoundKey);
+                       break;
+               case ID_DEC_CBC :
+                       retVal = SDRM_CBC_Dec(crt->alg, Block, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                       break;
+               case ID_DEC_CFB :
+                       retVal = SDRM_CFB_Dec(crt->alg, Block, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                       break;
+               case ID_DEC_OFB :
+                       retVal = SDRM_OFB_Dec(crt->alg, Block, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV);
+                       break;
+               case ID_DEC_CTR : 
+                       retVal = SDRM_CTR_Dec(crt->alg, Block, Block, crt->ctx->aesctx->RoundKey, crt->ctx->aesctx->IV, crt->ctx->aesctx->CTR_Count++);
+                       break;
+               default :
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+       }
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               return retVal;
+       }
+
+       //de-padding
+
+       t = Block[SDRM_AES_BLOCK_SIZ - 1];
+
+       switch(crt->ctx->aesctx->padding)
+       {
+               case 0 :
+               case ID_PKCS5 :
+               {       i = 0;
+                       //for (; i < 16; i++)
+                               printf("Block [%d]: %d\n", i, Block[i]);
+
+                       if ((t > SDRM_AES_BLOCK_SIZ) || (t < 1))
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+                       memset(PADDING, t, t);
+                       break;
+               }
+               case ID_SSL_PADDING :
+                       ++t;
+                       if ((t > SDRM_AES_BLOCK_SIZ) || (t < 1))
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+                       memset(PADDING, t - 1, t);
+                       break;
+               case ID_ZERO_PADDING :
+                       {
+                               cc_u32 tmpLen;
+                               tmpLen = SDRM_AES_BLOCK_SIZ;
+                               while((tmpLen != 0x00) && (Block[tmpLen - 1] == 0x00))
+                               {
+                                       tmpLen--;
+                               }
+
+                               memcpy(output, Block, tmpLen);
+
+                               if (outputLen != NULL)
+                               {
+                                       *outputLen = tmpLen;
+                               }
+                       }
+                       return CRYPTO_SUCCESS;
+               case ID_NO_PADDING :
+                       {
+                               cc_u32 tmpLen;
+                               tmpLen = SDRM_AES_BLOCK_SIZ;
+
+                               if (crt->ctx->aesctx->moo == ID_DEC_CTR)
+                               {
+                                       tmpLen = BlockLen + inputLen;
+                               }
+                               else
+                               {
+                                       tmpLen = SDRM_AES_BLOCK_SIZ;
+                               }
+
+                               memcpy(output, Block, tmpLen);
+
+                               if (outputLen != NULL)
+                               {
+                                       *outputLen = tmpLen;
+                               }
+                       }
+                       return CRYPTO_SUCCESS;
+               default :
+                       if (outputLen != NULL)
+                       {
+                               *outputLen = 0;
+
+                       return CRYPTO_INVALID_ARGUMENT;
+                       }
+       }
+
+       if (memcmp(PADDING, Block + SDRM_AES_BLOCK_SIZ - t, t) != 0)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       memcpy(output, Block, SDRM_AES_BLOCK_SIZ -t);
+
+       if (outputLen != NULL)
+       {
+               *outputLen = SDRM_AES_BLOCK_SIZ - t;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_RC4_init
+ * @brief      intialize crypt context for RC4
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method, not needed
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector, not needed
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_RC4_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rc4ctx == NULL) || (key == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (keysize > 32)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       SDRM_RC4_Setup(crt->ctx->rc4ctx, key, keysize);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_RC4_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      in                                              [in]message block
+ * @param      inLen                                   [in]byte-length of Text
+ * @param      out                                             [out]processed message
+ * @param      outLen                                  [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_RC4_process(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->rc4ctx == NULL) || (in == NULL) || (out == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+
+       SDRM_RC4_PRNG(crt->ctx->rc4ctx, in, inLen, out);
+
+       if (outLen != NULL)
+       {
+               *outLen = inLen;
+       }
+       
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_SNOW2_init
+ * @brief      intialize crypt context for SNOW2
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method, not needed
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_SNOW2_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->snow2ctx == NULL) || (key == NULL) || (IV == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if ((keysize != 16) && (keysize != 32))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       SDRM_SNOW2_Setup(crt->ctx->snow2ctx, key, keysize, IV);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_SNOW2_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      in                                              [in]message block       
+ * @param      inLen                                   [in]byte-length of Text
+ * @param      out                                             [out]processed message
+ * @param      outLen                                  [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_SNOW2_process(CryptoCoreContainer *crt, cc_u8 *in, cc_u32 inLen, cc_u8 *out, cc_u32 *outLen)
+{
+       cc_u32 i, j, BlockLen, rpt, loc;
+       cc_u32 keyStream64[16], keyStream;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->snow2ctx == NULL) || (in == NULL) || (out == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if ((inLen & 0x03) != 0)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       BlockLen = inLen / 64;
+
+       if (crt->ctx->snow2ctx->endian == CRYPTO_LITTLE_ENDIAN)
+       {                               //little endian machine
+               for (i = 0; i < BlockLen; i++)
+               {
+                       SDRM_SNOW2_getKeyStream64(crt->ctx->snow2ctx, keyStream64);
+
+                       for (j = 0; j < 16; j++)
+                       {
+                               loc = i * 64 + j * 4;
+                               out[loc    ] = (cc_u8)(in[loc    ] ^ ((keyStream64[j] >> 24) & 0xff));
+                               out[loc + 1] = (cc_u8)(in[loc + 1] ^ ((keyStream64[j] >> 16) & 0xff));
+                               out[loc + 2] = (cc_u8)(in[loc + 2] ^ ((keyStream64[j] >>  8) & 0xff));
+                               out[loc + 3] = (cc_u8)(in[loc + 3] ^ ((keyStream64[j]      ) & 0xff));
+                       }
+               }
+       } 
+       else
+       {                               //big endian machine
+               for (i = 0; i < BlockLen; i++)
+               {
+                       SDRM_SNOW2_getKeyStream64(crt->ctx->snow2ctx, keyStream64);
+                       
+                       for (j = 0; j < 16; j++)
+                       {
+                               ((cc_u32*)(void*)out)[j] = ((cc_u32*)(void*)in)[j] ^ keyStream64[j];
+                       }
+               }
+       }
+
+       in += BlockLen * 64;
+       out += BlockLen * 64;
+
+       rpt = (inLen - (BlockLen * 64)) / 4;
+
+       if (crt->ctx->snow2ctx->endian == CRYPTO_LITTLE_ENDIAN)
+       {                               //little endian machine
+               for (i = 0; i < rpt; i++)
+               {
+                       SDRM_SNOW2_getKeyStream(crt->ctx->snow2ctx, &keyStream);
+                       loc = i * 4;
+                       out[loc    ] = (cc_u8)(in[loc    ] ^ ((keyStream >> 24) & 0xff));
+                       out[loc + 1] = (cc_u8)(in[loc + 1] ^ ((keyStream >> 16) & 0xff));
+                       out[loc + 2] = (cc_u8)(in[loc + 2] ^ ((keyStream >>  8) & 0xff));
+                       out[loc + 3] = (cc_u8)(in[loc + 3] ^ ((keyStream          ) & 0xff));
+               }
+       }
+       else
+       {                               //big endian machine
+               for (i = 0; i < rpt; i++)
+               {
+                       SDRM_SNOW2_getKeyStream(crt->ctx->snow2ctx, &keyStream);
+                       ((cc_u32*)(void*)out)[i] = ((cc_u32*)(void*)in)[i] ^ keyStream;
+               }
+       }
+
+       if (outLen != NULL)
+       {
+               *outLen = inLen;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DES_init
+ * @brief      intialize crypt context for des
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_DES_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->desctx == NULL) || (key == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if ((keysize != 8) || !(((mode >= 1111) && (mode <= 1115)) || ((mode >= 1121) && (mode <= 1125))))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       crt->ctx->desctx->moo = mode;
+
+       if ((PADDING != 0) && (PADDING != ID_PKCS5) && (PADDING != ID_SSL_PADDING) && (PADDING != ID_ZERO_PADDING) && (PADDING != ID_NO_PADDING))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       crt->ctx->desctx->padding = PADDING;
+
+
+       if (mode != ID_DEC_ECB && mode != ID_DEC_CBC)
+       {
+               SDRM_getEncRoundKey(ID_DES, key, (cc_u8*)(crt->ctx->desctx->RoundKey));
+       }
+       else
+       {
+               SDRM_getDecRoundKey(ID_DES, key, (cc_u8*)(crt->ctx->desctx->RoundKey));
+       }
+       
+       crt->ctx->desctx->BlockLen = 0;
+       crt->ctx->desctx->CTR_Count = 0;
+
+       memcpy(crt->ctx->desctx->UserKey, key, SDRM_DES_BLOCK_SIZ);
+
+       if (IV)
+       {
+               memcpy(crt->ctx->desctx->IV, IV, SDRM_DES_BLOCK_SIZ);
+       }
+       else
+       {
+               memset(crt->ctx->desctx->IV, 0x00, SDRM_DES_BLOCK_SIZ);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DES_process
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      Text                                    [in]message block
+ * @param      TextLen                                 [in]byte-length of Text
+ * @param      output                                  [out]proecessed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_DES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int             i, Temp;
+       int             retVal, BlockLen;
+       cc_u8   *Block;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->desctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       Block = crt->ctx->desctx->Block;
+       BlockLen = crt->ctx->desctx->BlockLen;
+
+       *outputLen = 0;
+
+       if ((TextLen + BlockLen) < SDRM_DES_BLOCK_SIZ)
+       {
+               memcpy(Block + BlockLen, Text, TextLen);
+               crt->ctx->desctx->BlockLen += TextLen;
+               return CRYPTO_SUCCESS;
+       }
+
+       if (BlockLen)
+       {
+               memcpy(Block + BlockLen, Text, SDRM_DES_BLOCK_SIZ - BlockLen);
+
+               switch(crt->ctx->desctx->moo)
+               {
+                       case ID_ENC_ECB :
+                               retVal = SDRM_ECB_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CBC :
+                               retVal = SDRM_CBC_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CFB :
+                               retVal = SDRM_CFB_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_OFB :
+                               retVal = SDRM_OFB_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CTR :
+                               retVal = SDRM_CTR_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV, crt->ctx->desctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_ECB : 
+                               retVal = SDRM_ECB_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CBC :
+                               retVal = SDRM_CBC_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CFB :
+                               retVal = SDRM_CFB_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_OFB :
+                               retVal = SDRM_OFB_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CTR : 
+                               retVal = SDRM_CTR_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV, crt->ctx->desctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       Temp = TextLen + BlockLen - SDRM_DES_BLOCK_SIZ + 1;
+       for (i = (SDRM_DES_BLOCK_SIZ - BlockLen) & 0x07; i < Temp; i += SDRM_DES_BLOCK_SIZ)
+       {
+               switch(crt->ctx->desctx->moo)
+               {
+                       case ID_ENC_ECB : 
+                               retVal = SDRM_ECB_Enc(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CBC :
+                               retVal = SDRM_CBC_Enc(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CFB :
+                               retVal = SDRM_CFB_Enc(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_OFB :
+                               retVal = SDRM_OFB_Enc(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CTR : 
+                               retVal = SDRM_CTR_Enc(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV, crt->ctx->desctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_ECB : 
+                               retVal = SDRM_ECB_Dec(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CBC :
+                               retVal = SDRM_CBC_Dec(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CFB :
+                               retVal = SDRM_CFB_Dec(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_OFB :
+                               retVal = SDRM_OFB_Dec(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CTR : 
+                               retVal = SDRM_CTR_Dec(ID_DES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV, crt->ctx->desctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       crt->ctx->desctx->BlockLen = (SDRM_DES_BLOCK_SIZ + TextLen - i) & 0x07;
+       memcpy(Block, Text + TextLen - crt->ctx->desctx->BlockLen, crt->ctx->desctx->BlockLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_DES_final
+ * @brief      process final block and padding
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      input                                   [in]message block
+ * @param      inputLen                                [in]byte-length of Text
+ * @param      output                                  [out]processed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_DES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int             retVal = CRYPTO_SUCCESS;
+       cc_u8   *Block, PADDING[16];
+       cc_u32  BlockLen, t;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->desctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       Block = crt->ctx->desctx->Block;
+       BlockLen = crt->ctx->desctx->BlockLen;
+
+       if (crt->ctx->desctx->moo >= ID_DEC_ECB)
+       {
+               goto DECRYPTION;
+       }
+
+//ENCRYPTION:
+       if (inputLen != 0)
+       {
+               retVal = SDRM_DES_process(crt, input, inputLen, output, outputLen);
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+
+               retVal = SDRM_DES_final(crt, NULL, 0, output + *outputLen, &t);
+               *outputLen += t;
+
+               return retVal;
+       }
+
+       if (outputLen != NULL)
+       {
+               *outputLen = SDRM_DES_BLOCK_SIZ;
+       }
+
+       //padding
+       switch(crt->ctx->desctx->padding)
+       {
+               case 0 :
+               case ID_PKCS5 :
+                       memset(Block + BlockLen, SDRM_DES_BLOCK_SIZ - BlockLen, SDRM_DES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_SSL_PADDING :
+                       memset(Block + BlockLen, SDRM_DES_BLOCK_SIZ - BlockLen - 1, SDRM_DES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_ZERO_PADDING :
+                       memset(Block + BlockLen, 0x00, SDRM_DES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_NO_PADDING :
+                       if (BlockLen == 0)
+                       {
+                               if (outputLen)
+                               {
+                                       *outputLen = 0;
+                               }
+                               return CRYPTO_SUCCESS;
+                       }
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+
+       //encryption
+       switch(crt->ctx->desctx->moo)
+       {
+               case ID_ENC_ECB : 
+                       retVal = SDRM_ECB_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey);
+                       break;
+               case ID_ENC_CBC :
+                       retVal = SDRM_CBC_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                       break;
+               case ID_ENC_CFB :
+                       retVal = SDRM_CFB_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                       break;
+               case ID_ENC_OFB :
+                       retVal = SDRM_OFB_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                       break;
+               case ID_ENC_CTR : 
+                       retVal = SDRM_CTR_Enc(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV, crt->ctx->desctx->CTR_Count++);
+                       break;
+               default :
+                       retVal = CRYPTO_INVALID_ARGUMENT;
+                       break;
+       }
+
+       return retVal;
+
+DECRYPTION:
+       if (outputLen != NULL)
+       {
+               *outputLen = 0;
+       }
+
+       if ((inputLen == 0) && (crt->ctx->desctx->padding == ID_NO_PADDING))
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       if ((BlockLen + inputLen) != SDRM_DES_BLOCK_SIZ)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (inputLen != 0)
+       {
+               memcpy(Block + BlockLen, input, inputLen);
+       }
+
+       switch(crt->ctx->desctx->moo)
+       {
+               case ID_DEC_ECB : 
+                       retVal = SDRM_ECB_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey);
+                       break;
+               case ID_DEC_CBC :
+                       retVal = SDRM_CBC_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                       break;
+               case ID_DEC_CFB :
+                       retVal = SDRM_CFB_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                       break;
+               case ID_DEC_OFB :
+                       retVal = SDRM_OFB_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV);
+                       break;
+               case ID_DEC_CTR : 
+                       retVal = SDRM_CTR_Dec(ID_DES, output, Block, (cc_u8*)crt->ctx->desctx->RoundKey, crt->ctx->desctx->IV, crt->ctx->desctx->CTR_Count++);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               return retVal;
+       }
+
+       //de-padding
+       t = output[SDRM_DES_BLOCK_SIZ - 1];
+
+       switch(crt->ctx->desctx->padding)
+       {
+               case 0 :
+               case ID_PKCS5 :
+                       if ((t > SDRM_DES_BLOCK_SIZ) || (t < 1))
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+                       memset(PADDING, t, t);
+                       break;
+               case ID_SSL_PADDING :
+                       ++t;
+                       if ((t > SDRM_DES_BLOCK_SIZ) || (t < 1))
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+                       memset(PADDING, t - 1, t);
+                       break;
+               case ID_ZERO_PADDING :
+                       {
+                               cc_u32 tmpLen;
+                               tmpLen = SDRM_DES_BLOCK_SIZ;
+                               while((tmpLen != 0x00) && (output[tmpLen - 1] == 0x00))
+                               {
+                                       tmpLen--;
+                               }
+
+                               if (outputLen != NULL)
+                               {
+                                       *outputLen = tmpLen;
+                               }
+                       }
+                       return CRYPTO_SUCCESS;
+               case ID_NO_PADDING :
+                       if (outputLen != NULL)
+                       {
+                               *outputLen = SDRM_DES_BLOCK_SIZ;
+                       }
+                       return CRYPTO_SUCCESS;
+               default :
+                       if (outputLen != NULL)
+                       {
+                               *outputLen = 0;
+                       }
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (memcmp(PADDING, output + SDRM_DES_BLOCK_SIZ - t, t) != 0)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (outputLen != NULL)
+       {
+               *outputLen = SDRM_DES_BLOCK_SIZ - t;
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_TDES_init
+ * @brief      intialize crypt context for triple des
+ *
+ * @param      crt                                             [out]crypto env structure
+ * @param      mode                                    [in]encryption|decryption and mode of operation
+ * @param      PADDING                                 [in]padding method
+ * @param      key                                             [in]user key
+ * @param      keysize                                 [in]byte-length of key
+ * @param      IV                                              [in]initial vector
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_TDES_init(CryptoCoreContainer *crt, cc_u32 mode, cc_u32 PADDING, cc_u8 *key, cc_u32 keysize, cc_u8 *IV)
+{
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->tdesctx == NULL) || (key == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       if (((keysize != 16) && (keysize != 24)) || !(((mode >= 1111) && (mode <= 1115)) || ((mode >= 1121) && (mode <= 1125))))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       crt->ctx->tdesctx->moo = mode;
+
+       if ((PADDING != 0) && (PADDING != ID_PKCS5) && (PADDING != ID_SSL_PADDING) && (PADDING != ID_ZERO_PADDING) && (PADDING != ID_NO_PADDING))
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       crt->ctx->tdesctx->padding = PADDING;
+
+       if ((mode != ID_DEC_ECB) && (mode != ID_DEC_CBC))
+       {
+               if (keysize == 16)
+               {
+                       SDRM_getEncRoundKey(ID_TDES_EDE2, key, (cc_u8*)(crt->ctx->tdesctx->RoundKey));
+               }
+               else
+               {
+                       SDRM_getEncRoundKey(ID_TDES_EDE3, key, (cc_u8*)(crt->ctx->tdesctx->RoundKey));
+               }
+       }
+       else
+       {
+               if (keysize == 16)
+               {
+                       SDRM_getDecRoundKey(ID_TDES_EDE2, key, (cc_u8*)(crt->ctx->tdesctx->RoundKey));
+               }
+               else
+               {
+                       SDRM_getDecRoundKey(ID_TDES_EDE3, key, (cc_u8*)(crt->ctx->tdesctx->RoundKey));
+               }
+       }
+       
+       crt->ctx->tdesctx->BlockLen = 0;
+       crt->ctx->tdesctx->CTR_Count = 0;
+
+       memcpy(crt->ctx->tdesctx->UserKey, key, SDRM_DES_BLOCK_SIZ);
+
+       if (IV)
+       {
+               memcpy(crt->ctx->tdesctx->IV, IV, SDRM_DES_BLOCK_SIZ);
+       }
+       else
+       {
+               memset(crt->ctx->tdesctx->IV, 0x00, SDRM_DES_BLOCK_SIZ);
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         int SDRM_TDES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen)
+ * @brief      process message block
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      Text                                    [in]message block
+ * @param      TextLen                                 [in]byte-length of Text
+ * @param      output                                  [out]proecessed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_TDES_process(CryptoCoreContainer *crt, cc_u8 *Text, cc_u32 TextLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int             i, Temp;
+       int             retVal, BlockLen;
+       cc_u8   *Block;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->tdesctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       Block = crt->ctx->tdesctx->Block;
+       BlockLen = crt->ctx->tdesctx->BlockLen;
+
+       *outputLen = 0;
+
+       if ((TextLen + BlockLen) < SDRM_DES_BLOCK_SIZ)
+       {
+               memcpy(Block + BlockLen, Text, TextLen);
+               crt->ctx->tdesctx->BlockLen += TextLen;
+               return CRYPTO_SUCCESS;
+       }
+
+       if (BlockLen)
+       {
+               memcpy(Block + BlockLen, Text, SDRM_DES_BLOCK_SIZ - BlockLen);
+
+               switch(crt->ctx->tdesctx->moo)
+               {
+                       case ID_ENC_ECB :
+                               retVal = SDRM_ECB_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CBC :
+                               retVal = SDRM_CBC_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CFB :
+                               retVal = SDRM_CFB_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_OFB :
+                               retVal = SDRM_OFB_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CTR :
+                               retVal = SDRM_CTR_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV, crt->ctx->tdesctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_ECB : 
+                               retVal = SDRM_ECB_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CBC :
+                               retVal = SDRM_CBC_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CFB :
+                               retVal = SDRM_CFB_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_OFB :
+                               retVal = SDRM_OFB_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CTR : 
+                               retVal = SDRM_CTR_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV, crt->ctx->tdesctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       Temp = TextLen + BlockLen - SDRM_DES_BLOCK_SIZ + 1;
+       for (i = (SDRM_DES_BLOCK_SIZ - BlockLen) & 0x07; i < Temp; i += SDRM_DES_BLOCK_SIZ)
+       {
+               switch(crt->ctx->tdesctx->moo)
+               {
+                       case ID_ENC_ECB : 
+                               retVal = SDRM_ECB_Enc(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CBC :
+                               retVal = SDRM_CBC_Enc(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CFB :
+                               retVal = SDRM_CFB_Enc(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_OFB :
+                               retVal = SDRM_OFB_Enc(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_ENC_CTR : 
+                               retVal = SDRM_CTR_Enc(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV, crt->ctx->tdesctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_ECB : 
+                               retVal = SDRM_ECB_Dec(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CBC :
+                               retVal = SDRM_CBC_Dec(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CFB :
+                               retVal = SDRM_CFB_Dec(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_OFB :
+                               retVal = SDRM_OFB_Dec(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       case ID_DEC_CTR : 
+                               retVal = SDRM_CTR_Dec(ID_TDES, output + *outputLen, Text + i, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV, crt->ctx->tdesctx->CTR_Count++);
+                               *outputLen += SDRM_DES_BLOCK_SIZ;
+                               break;
+                       default :
+                               return CRYPTO_INVALID_ARGUMENT;
+               }
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+       }
+
+       crt->ctx->tdesctx->BlockLen = (SDRM_DES_BLOCK_SIZ + TextLen - i) & 0x07;
+       memcpy(Block, Text + TextLen - crt->ctx->tdesctx->BlockLen, crt->ctx->tdesctx->BlockLen);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         int SDRM_TDES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen)
+ * @brief      process final block and padding
+ *
+ * @param      crt                                             [in]crypto env structure
+ * @param      input                                   [in]message block
+ * @param      inputLen                                [in]byte-length of Text
+ * @param      output                                  [out]processed message
+ * @param      outputLen                               [out]byte-length of output
+ *
+ * @return     CRYPTO_SUCCESS                  if success
+ * \n          CRYPTO_NULL_POINTER             if given argument is a null pointer
+ * \n          CRYPTO_INVALID_ARGUMENT if given argument is invalid
+ */
+int SDRM_TDES_final(CryptoCoreContainer *crt, cc_u8 *input, cc_u32 inputLen, cc_u8 *output, cc_u32 *outputLen)
+{
+       int             retVal = CRYPTO_SUCCESS;
+       cc_u8   *Block, PADDING[16];
+       cc_u32  BlockLen, t;
+
+       if ((crt == NULL) || (crt->ctx == NULL) || (crt->ctx->tdesctx == NULL))
+       {
+               return CRYPTO_NULL_POINTER;
+       }
+
+       Block = crt->ctx->tdesctx->Block;
+       BlockLen = crt->ctx->tdesctx->BlockLen;
+
+
+       if (crt->ctx->tdesctx->moo >= ID_DEC_ECB)
+       {
+               goto DECRYPTION;
+       }
+
+//ENCRYPTION:
+       if (inputLen != 0)
+       {
+               retVal = SDRM_TDES_process(crt, input, inputLen, output, outputLen);
+
+               if (retVal != CRYPTO_SUCCESS)
+               {
+                       return retVal;
+               }
+
+               retVal = SDRM_TDES_final(crt, NULL, 0, output + *outputLen, &t);
+               *outputLen += t;
+
+               return retVal;
+       }
+
+       if (outputLen != NULL)
+       {
+               *outputLen = SDRM_DES_BLOCK_SIZ;
+       }
+
+       //padding
+       switch(crt->ctx->tdesctx->padding)
+       {
+               case 0 :
+               case ID_PKCS5 :
+                       memset(Block + BlockLen, SDRM_DES_BLOCK_SIZ - BlockLen, SDRM_DES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_SSL_PADDING :
+                       memset(Block + BlockLen, SDRM_DES_BLOCK_SIZ - BlockLen - 1, SDRM_DES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_ZERO_PADDING :
+                       memset(Block + BlockLen, 0x00, SDRM_DES_BLOCK_SIZ - BlockLen);
+                       break;
+               case ID_NO_PADDING :
+                       if (BlockLen == 0)
+                       {
+                               if (outputLen)
+                               {
+                                       *outputLen = 0;
+                               }
+                               return CRYPTO_SUCCESS;
+                       }
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       //encryption
+       switch(crt->ctx->tdesctx->moo)
+       {
+               case ID_ENC_ECB : 
+                       retVal = SDRM_ECB_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey);
+                       break;
+               case ID_ENC_CBC :
+                       retVal = SDRM_CBC_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                       break;
+               case ID_ENC_CFB :
+                       retVal = SDRM_CFB_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                       break;
+               case ID_ENC_OFB :
+                       retVal = SDRM_OFB_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                       break;
+               case ID_ENC_CTR : 
+                       retVal = SDRM_CTR_Enc(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV, crt->ctx->tdesctx->CTR_Count++);
+                       break;
+               default :
+                       retVal = CRYPTO_INVALID_ARGUMENT;
+                       break;
+       }
+
+       return retVal;
+
+DECRYPTION:
+       if (outputLen != NULL)
+       {
+               *outputLen = 0;
+       }
+
+       if ((inputLen == 0) && (crt->ctx->tdesctx->padding == ID_NO_PADDING))
+       {
+               return CRYPTO_SUCCESS;
+       }
+
+       if ((BlockLen + inputLen) != SDRM_DES_BLOCK_SIZ)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (inputLen != 0)
+       {
+               memcpy(Block + BlockLen, input, inputLen);
+       }
+
+       switch(crt->ctx->tdesctx->moo)
+       {
+               case ID_DEC_ECB : 
+                       retVal = SDRM_ECB_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey);
+                       break;
+               case ID_DEC_CBC :
+                       retVal = SDRM_CBC_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                       break;
+               case ID_DEC_CFB :
+                       retVal = SDRM_CFB_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                       break;
+               case ID_DEC_OFB :
+                       retVal = SDRM_OFB_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV);
+                       break;
+               case ID_DEC_CTR : 
+                       retVal = SDRM_CTR_Dec(ID_TDES, output, Block, (cc_u8*)crt->ctx->tdesctx->RoundKey, crt->ctx->tdesctx->IV, crt->ctx->tdesctx->CTR_Count++);
+                       break;
+               default :
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (retVal != CRYPTO_SUCCESS)
+       {
+               return retVal;
+       }
+
+       //de-padding
+       t = output[SDRM_DES_BLOCK_SIZ - 1];
+
+       switch(crt->ctx->tdesctx->padding)
+       {
+               case 0 :
+               case ID_PKCS5 :
+                       if ((t > SDRM_DES_BLOCK_SIZ) || (t < 1))
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+                       memset(PADDING, t, t);
+                       break;
+               case ID_SSL_PADDING :
+                       ++t;
+                       if ((t > SDRM_DES_BLOCK_SIZ) || (t < 1))
+                       {
+                               return CRYPTO_INVALID_ARGUMENT;
+                       }
+                       memset(PADDING, t - 1, t);
+                       break;
+               case ID_ZERO_PADDING :
+                       {
+                               cc_u32 tmpLen;
+                               tmpLen = SDRM_TDES_BLOCK_SIZ;
+                               while((tmpLen != 0x00) && (output[tmpLen - 1] == 0x00))
+                               {
+                                       tmpLen--;
+                               }
+
+                               if (outputLen != NULL)
+                               {
+                                       *outputLen = tmpLen;
+                               }
+                       }
+                       return CRYPTO_SUCCESS;
+               case ID_NO_PADDING :
+                       if (outputLen != NULL)
+                       {
+                               *outputLen = SDRM_TDES_BLOCK_SIZ;
+                       }
+                       return CRYPTO_SUCCESS;
+               default :
+                       if (outputLen != NULL)
+                       {
+                               *outputLen = 0;
+                       }
+                       return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (memcmp(PADDING, output + SDRM_TDES_BLOCK_SIZ - t, t) != 0)
+       {
+               return CRYPTO_INVALID_ARGUMENT;
+       }
+
+       if (outputLen != NULL)
+       {
+               *outputLen = SDRM_DES_BLOCK_SIZ - t;
+       }
+
+       return CRYPTO_SUCCESS;
+
+}
+
+/***************************** End of File *****************************/
diff --git a/ssflib/dep/cryptocore/source/middle/cc_tdes.c b/ssflib/dep/cryptocore/source/middle/cc_tdes.c
new file mode 100755 (executable)
index 0000000..269a122
--- /dev/null
@@ -0,0 +1,131 @@
+/**
+ * \file       tdes.c
+ * @brief      high-speed implementation of Triple DES-EDE
+ *
+ * - Copyright : Samsung Electronics CO.LTD.,
+ *
+ * \internal
+ * Author : Jisoon Park
+ * Dept : DRM Lab, Digital Media Laboratory
+ * Creation date : 2006/12/06
+ */
+
+//////////////////////////////////////////////////////////////////////////
+// Include Header Files
+//////////////////////////////////////////////////////////////////////////
+#include "cc_tdes.h"
+#include "cc_des.h"
+
+////////////////////////////////////////////////////////////////////////////
+// Functions
+////////////////////////////////////////////////////////////////////////////
+/*
+ * @fn         SDRM_TDES_KeySched
+ * @brief      Expand the cipher key into the encryption key schedule
+ *
+ * @param      RoundKey                        [out]generated round key
+ * @param      UserKey                         [in]user key, 16 or 24 byte
+ * @param      KeyLen                          [in]byte-length of UserKey
+ * @param      RKStep                          [in]operation mode
+ *
+ * @return     the number of rounds for the given cipher key size
+ */
+int SDRM_TDES_KeySched(cc_u8 *RoundKey, cc_u8 *UserKey, cc_u32 KeyLen, cc_u32 RKStep)
+{
+
+       if (RKStep == 1)
+       {
+               SDRM_DES_KeySched(RoundKey, UserKey, 0, 1);
+               SDRM_DES_KeySched(RoundKey + 128, UserKey + 8, 15, (cc_u32)-1);
+
+               if (KeyLen == 16)
+               {                                                                                       //2-key des
+                       memcpy(RoundKey + 256, RoundKey, 128);
+               }
+               else
+               {                                                                                       //3-key des
+                       SDRM_DES_KeySched(RoundKey + 256, UserKey + 16, 0, 1);
+               }
+       }
+       else {
+               SDRM_DES_KeySched(RoundKey + 256, UserKey, 15, (cc_u32)-1);
+               SDRM_DES_KeySched(RoundKey + 128, UserKey + 8, 0, 1);
+
+               if (KeyLen == 16)
+               {                                                                                       //2-key des
+                       memcpy(RoundKey, RoundKey + 256, 128);
+               }
+               else
+               {                                                                                       //3-key des
+                       SDRM_DES_KeySched(RoundKey, UserKey + 16, 15, (cc_u32)-1);
+               }
+       }
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_TDES_Encryption
+ * @brief      Triple DES processing for one block
+ *
+ * @param      RoundKey                        [in]expanded round key
+ * @param      msg                                     [in]8 byte plaintext
+ * @param      out                                     [out]8 byte ciphertext
+ *
+ * @return     CRYPTO_SUCCESS          if no error is occured
+ */
+int SDRM_TDES_Encryption(cc_u32 RoundKey[][2], cc_u8 *msg, cc_u8 *out)
+{
+       cc_u8 buf[8];
+
+       SDRM_DES_Encryption(RoundKey     , msg, buf);
+       SDRM_DES_Encryption(RoundKey + 16, buf, buf);
+       SDRM_DES_Encryption(RoundKey + 32, buf, out);
+
+       return CRYPTO_SUCCESS;
+}
+
+
+/*
+ * @fn         SDRM_TDES64_Encryption
+ * @brief      one block Triple DES Encryption
+ *
+ * @param      cipherText      [out]encrypted text
+ * @param      plainText       [in]plain text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_TDES64_Encryption(cc_u8 *cipherText, cc_u8 *plainText, cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[48][2];
+
+       SDRM_TDES_KeySched((cc_u8*)RoundKey, UserKey, 16, 1);
+
+       SDRM_TDES_Encryption(RoundKey, plainText, cipherText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/*
+ * @fn         SDRM_TDES64_Decryption
+ * @brief      one block Triple DES Decryption
+ *
+ * @param      plainText       [out]decrypted text
+ * @param      cipherText      [in]cipher text
+ * @param      UserKey         [in]user key
+ *
+ * @return     CRYPTO_SUCCESS if success
+ */
+int SDRM_TDES64_Decryption(cc_u8 *plainText, cc_u8 *cipherText, cc_u8 *UserKey)
+{
+       cc_u32 RoundKey[48][2];
+
+       SDRM_TDES_KeySched((cc_u8*)RoundKey, UserKey, 16, (cc_u32)-1);
+
+       SDRM_TDES_Encryption(RoundKey, cipherText, plainText);
+
+       return CRYPTO_SUCCESS;
+}
+
+/***************************** End of File *****************************/
\ No newline at end of file
diff --git a/ssflib/dep/swdss/include/file_op.h b/ssflib/dep/swdss/include/file_op.h
new file mode 100755 (executable)
index 0000000..d878006
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#ifndef _SECRUITY_FILE_OP_H_
+#define _SECRUITY_FILE_OP_H_
+
+#include "ss_types.h"
+#include "slog.h"
+#include <stdio.h>
+
+#define CURRENT_DIR "."
+#define PARENT_DIR ".."
+
+class file_op {
+public:
+
+       /**
+        * @brief write file 
+        *
+        * write buffer into file.
+        * @param[in] filename File full path.
+        * @param[in] buffer Point to data buffer.
+        * @param[in] size Size of data buffer.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       static int write_file(const char* filename, unsigned char* buffer,
+           unsigned int size);
+
+       /**
+        * @brief read file 
+        *
+        * Read file into buffer.
+        * @param[in] filename File full path.
+        * @param[in] buffer Point to data buffer.
+        * @param[in] size Size of data buffer.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       static int read_file(const char* filename, unsigned char** buffer,
+           unsigned int& size);
+
+       /**
+        * @brief remove file 
+        *
+        * Read file into buffer.
+        * @param[in] filename File full path.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       static int remove_file(const char* filename);
+
+       /**
+        * @brief   Validates data file path.
+        * @param[in] filename File full path.
+        * @return  non-zero value in the case of failure
+        */
+       static int is_valid_filename(const char* filename);
+
+       /**
+        *
+        * @brief  Creates folder inside of the given folder.
+        * @param[in] folder Folder path.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       static int create_folder(const char* folder);
+
+       /**
+        * @brief Remove folder
+        *
+        * Remove folder recursively.
+        * @param[in] folder Folder path.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       static int remove_folder(const char* folder);
+
+       /**
+        * @brief Check if folder exist
+        *
+        *  Check whether specific folder exist.
+        * @param[in] folder Folder path.
+        * @retval ture if exists.
+        * @retval false if not exist.
+        */
+
+       static bool is_folder_exists(const char* folder);
+
+       static bool is_file_exists(const char* file);
+
+       /**
+        * @brief Get base path
+        *
+        * Get base path of specific file.
+        * @param[in] filename Full file path.
+        * @return base path
+        */
+       static void get_base_path(const char* filename, char* base_path);
+
+};
+
+#endif
+
diff --git a/ssflib/dep/swdss/include/secure_file.h b/ssflib/dep/swdss/include/secure_file.h
new file mode 100755 (executable)
index 0000000..a7d4e76
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#ifndef _SWD_SECURE_FILE_H_
+#define _SWD_SECURE_FILE_H_
+
+#include "ss_temp_store.h"
+#include "ss_types.h"
+
+// this is hash material size, the real hash size is equal to SHA1 size 20 bytes
+static const CBT_UINT32 HASH_SIZE = 40;
+// header size may be bigger then 16 bytes, but non-less
+static const CBT_UINT32 HEADER_SIZE = 16;
+// this is key material size, the real key size is equal to AES 128 size 16 bytes
+static const CBT_UINT32 KEY_MAT_SIZE = 64;
+// encrypted key with size info buffer size
+static const CBT_UINT32 RSA_KEY_SIZE = 256;
+static const CBT_UINT32 ENCRYPTED_KEY_SIZE = RSA_KEY_SIZE + 4;
+
+/**
+ * @brief Secure file structure
+ *
+ */
+typedef struct secure_file_content {
+       secure_file_content() {
+               m_pFileHeader = NULL;
+               m_pHashMaterial = NULL;
+               m_pKeyMaterial = NULL;
+               m_pEncryptedKey = NULL;
+               m_pFileContent = NULL;
+               m_pOutputContent = NULL;
+               m_bHeaderAllocated = false;
+               m_bHashAllocated = false;
+               m_bKeyAllocated = false;
+               m_bEncryptedKeyAllocated = false;
+               m_bFileContentAllocated = false;
+               m_uFileHeaderSize = 0;
+               m_uHashMaterialSize = 0;
+               m_uKeyMaterialSize = 0;
+               m_uEncryptedKeySize = 0;
+               m_uFileContentSize = 0;
+               m_pOutputContentSize = 0;
+       }
+
+       bool m_bHeaderAllocated;
+       CBT_OCTET* m_pFileHeader;
+       CBT_UINT32 m_uFileHeaderSize;
+
+       bool m_bHashAllocated;
+       CBT_OCTET* m_pHashMaterial;
+       CBT_UINT32 m_uHashMaterialSize;
+
+       bool m_bKeyAllocated;
+       CBT_OCTET* m_pKeyMaterial;
+       CBT_UINT32 m_uKeyMaterialSize;
+
+       bool m_bEncryptedKeyAllocated;
+       CBT_OCTET* m_pEncryptedKey;
+       CBT_OCTET m_EncryptedKeyBuffer[ENCRYPTED_KEY_SIZE];
+       CBT_UINT32 m_uEncryptedKeySize;
+
+       bool m_bFileContentAllocated;
+       CBT_OCTET* m_pFileContent;
+       CBT_UINT32 m_uFileContentSize;
+
+       CBT_OCTET* m_pOutputContent;
+       CBT_UINT32 m_pOutputContentSize;
+} secure_file_content;
+
+/**
+ * @brief Secure file implementation
+ *
+ */
+typedef struct {
+       CBT_OCTET* rsa_n_data;
+       CBT_UINT32 rsa_n_len;
+       CBT_OCTET* rsa_e_data;
+       CBT_UINT32 rsa_e_len;
+       CBT_OCTET* rsa_d_data;
+       CBT_UINT32 rsa_d_len;
+} ss_rsa_key;
+
+/**
+ * @brief Secure file implementation calss
+ * 
+ * Implementation class of Interface  ss_secure_file, provide all secure storage operations.
+ * @author ryan
+ * @date 2013.07
+ * @version 1.0
+ */
+class secure_file {
+public:
+
+       secure_file() :
+                       m_cred(), m_options(0), m_file_content(), m_rsa_key(),
+                           m_use_crypted_key(false), m_cache(NULL), m_write_data(NULL),
+                           m_write_data_size(0), m_is_partial_write(false), m_read_data(NULL),
+                           m_read_data_size(0), m_file_path_ready(false) {
+       }
+       ;
+       ~secure_file();
+
+       /**
+        * @brief Ininitialize
+        *
+        * Initialize.
+        * @param[in] buffer Point to data buffer.
+        * @param[in] buf_size Size of data in bytes.
+        * @param[in] offset Start address for partial writing.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       int initialize(const ss_credential_s * cred, const char* data_name,
+           unsigned int options);
+
+       /**
+        * @brief Write data into secure storage
+        *
+        * Write data into secure storage
+        * @param[in] buffer Point to data buffer.
+        * @param[in] buf_size Size of data in bytes.
+        * @param[in] offset Start address for partial writing.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       int write(unsigned char* buffer, unsigned int buf_size, unsigned int offset);
+
+       /**
+        * @brief Read data from secure storage.
+        *
+        * Read data from secure storage into provided buffer.
+        * @param[out] ret_buf Point to data buffer read from secure storage.
+        * @param[in] read_size Up to "read_size"  bytes will be read.
+        * @param[in] offset Start address for partial reading.
+        * @return If success, real size in bytes of read data will be retured, if fails, -1 will be returned.
+        */
+       int read(unsigned char** ret_buf, unsigned int* read_size,
+           unsigned int offset);
+
+       /**
+        * @brief Write data into secure storage.
+        *
+        * Write data from provided buffer into secure storage, 
+        * and encrypt data encryption key with provided RSA public key and attach it to secure storage file.
+        * @param[in] buffer Point to data buffer.
+        * @param[in] buf_size Size of data in bytes.
+        * @param[in] offset Start address for partial writing.
+        * @param[in] rsa_n_data RSA public exponent.
+        * @param[in] rsa_n_len RSA public exponent size in bytes.
+        * @param[in] rsa_e_data RSA public key.
+        * @param[in] rsa_e_len RSA public key size in bytes.
+        * @param[in] async Indicate writing data in synchronous/ asynchronous mode,if set to ture, in sysnchronous mode.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       int write_ex(unsigned char* buffer, unsigned int buf_size,
+           unsigned int offset, const unsigned char* rsa_n_data,
+           unsigned long rsa_n_len, const unsigned char* rsa_e_data,
+           unsigned long rsa_e_len);
+
+       /**
+        * @brief Read data from secure storage.
+        *
+        * Read data from secure storage into provided buffer, content key will be recovered by provided RSA private key.
+        * @param[out] ret_buf Point to data buffer read from secure storage.
+        * @param[in] read_size Up to "read_size"  bytes will be read.
+        * @param[in] offset Start address for partial reading.
+        * @param[in] rsa_n_data RSA public exponent.
+        * @param[in] rsa_n_len RSA public exponent size in bytes.
+        * @param[in] rsa_d_data RSA private key.
+        * @param[in] rsa_d_len RSA private key size in bytes. 
+        * @return If success, real size in bytes of read data will be retured, if fails, -1 will be returned.
+        */
+       int read_ex(unsigned char** ret_buf, unsigned int* read_size,
+           unsigned int offset, const unsigned char* rsa_n_data,
+           unsigned long rsa_n_len, const unsigned char* rsa_d_data,
+           unsigned long rsa_d_len);
+
+       /**
+        * @brief Validate secure storage file structure.
+        *
+        * Validate the secure storage file structure. 
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       int validate();
+
+       /**
+        * @brief Delete fiel from secure storage.
+        *
+        * Delete fiel from secure storage.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       int remove();
+
+       /**
+        * @brief Remove all data from secure storage.
+        *
+        * Remove all data belongs to the credential from secure storage permanently, this should be used with caution.
+        * @retval 0 if success.
+        * @retval -1 if fail.
+        */
+       int clear_storage();
+
+private:
+
+       int finalize();
+
+       uint32_t transform_name_to_id(const char* data_name);
+
+       uint64_t transform_id_to_name(uint64_t uDataFileID);
+
+       int derive_file_path();
+
+       int gen_key_material();
+
+       void compute_file_hash(CBT_OCTET* pHash);
+
+       int prepare_data(unsigned char** ret_buf, unsigned int * ret_size,
+           unsigned char* buffer, unsigned int buf_size, unsigned int offset);
+
+       int prepare_file_content(unsigned char* buffer, unsigned int buf_size);
+
+       int parse_file_content(unsigned char* buffer, unsigned int buf_size);
+
+       int serialize_data(unsigned char** buffer, unsigned int& ret_size);
+
+       int write_temp_store(unsigned char* data, unsigned int size);
+
+       int read_temp_store(unsigned char** buffer, unsigned int& ret_size);
+
+       int write_persistent_store(unsigned char* data, unsigned int size);
+
+       int read_persistent_store(unsigned char** buffer, unsigned int& ret_size);
+
+       int remove_persistent_store(bool is_dir);
+
+       int check_file_content();
+
+       int decrypt_data();
+
+#ifdef _SECOS_SIM_
+       void get_data_name(char* data_name, bool is_dir);
+#endif
+
+private:
+
+       // credential
+       ss_credential_s m_cred;
+
+       // data name
+       char m_data_name[SS_MAX_DATA_NAME_LEN];
+
+       // options
+       unsigned int m_options;
+
+       // full path
+       char m_full_path[SS_FULL_DATA_NAME_LEN];
+
+       // file content
+       secure_file_content m_file_content;
+
+       // rsa key
+       ss_rsa_key m_rsa_key;
+
+       bool m_use_crypted_key;
+
+       // cache manager
+       ss_temp_store* m_cache;
+
+       // ready_data for support partial write
+       unsigned char* m_write_data;
+
+       unsigned int m_write_data_size;
+
+       bool m_is_partial_write;
+
+       unsigned char* m_read_data;
+
+       unsigned int m_read_data_size;
+
+       bool m_file_path_ready;
+
+};
+
+#endif
+
diff --git a/ssflib/dep/swdss/include/slog.h b/ssflib/dep/swdss/include/slog.h
new file mode 100755 (executable)
index 0000000..b9dc449
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+#ifndef _SWD_LOG_H_
+#define _SWD_LOG_H_
+
+#define LOG_TAG "SWDSS_LIB"
+
+#include <stdio.h>
+#define THE_PRINTF(fmt, ARG...) printf(fmt"\n", ##ARG)
+#define SLOGV(FMT, ARG ...)     THE_PRINTF("[VBOSE][%s]"FMT, LOG_TAG, ##ARG)
+#define SLOGD(FMT, ARG ...)     THE_PRINTF("[DEBUG][%s]"FMT, LOG_TAG, ##ARG)
+#define SLOGI(FMT, ARG ...)     THE_PRINTF("[INFO] [%s]"FMT, LOG_TAG, ##ARG)
+#define SLOGW(FMT, ARG ...)     THE_PRINTF("[WARN] [%s]"FMT, LOG_TAG, ##ARG)
+#define SLOGE(FMT, ARG ...)     THE_PRINTF("[ERROR][%s]"FMT, LOG_TAG, ##ARG)
+#define SLOGF(FMT, ARG ...)     THE_PRINTF("[FATAL][%s]"FMT, LOG_TAG, ##ARG)
+
+#endif
+
diff --git a/ssflib/dep/swdss/include/ss_api.h b/ssflib/dep/swdss/include/ss_api.h
new file mode 100755 (executable)
index 0000000..ae69f68
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#ifndef _SWDSS_SS_API_H_
+#define _SWDSS_SS_API_H_
+
+#include "ss_types.h"
+#include <string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief init secure storage
+ *
+ * set credential members
+ * @param[in] strategy 
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_init(int strategy);   // check swdss_ta_service is ready
+
+/**
+ * @brief Set credential
+ *
+ * set credential members
+ * @param[in] cred Point to credential to be set.
+ * @param[in] uuid UUID of credential.
+ * @param[in] module_name Module name.
+ * @param[in] major_ver major version info.
+ * @param[in] minor_ver minor version info.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_set_credential(ss_credential_s * cred, const char* uuid,
+    const char* module_name, unsigned long major_ver, unsigned long minor_ver);
+
+/**
+ * @brief Store data into Secure Storage.
+ *
+ * Store data from provided buffer into Secure Storage.
+ * @param[in] buffer Point to data buffer. The buffer should be freed by API caller.
+ * @param[in] data_size Size of data in bytes.
+ * @param[in] data_name Data name associated with data.
+ * @param[in] offset Start address for partial writing on an existent data, if offset == 0 and data does not exist,new data entry is created,
+ *                              the parameter takes effect only when option SS_OPT_PARTIAL_RW is set
+ * @param[in] cred Application credential.
+ * @param[in] options Data access options.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_write(unsigned char* buffer, unsigned int data_size, unsigned int offset,
+    const char* data_name, const ss_credential_s * cred, unsigned int options);
+
+/**
+ * @brief Read data from secure storage.
+ *
+ * Read data from secure storage into provided buffer.
+ * @param[out] ret_buf Point to data buffer read from secure storage,buffer is allocated inside the API,use ss_free_buffer to free.
+ * @param[out] data_size size of data read from secure storage, when SS_OPT_PARTIAL_RW is set, this is firstly used as an in parameter to indicate required read size.  
+ * @param[in] base_path Path that data will be stored, if set to NULL, default path will be used.
+ * @param[in] data_name Data name associated with data.
+ * @param[in] offset Start address for partial reading, only takes effect when SS_OPT_PARTIAL_RW is set.
+ * @param[in] cred Application credential.
+ * @param[in] options Data access options.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_read(unsigned char** ret_buf, unsigned int* data_size,
+    unsigned int offset, const char* data_name, const ss_credential_s * cred,
+    unsigned int options);
+
+/**
+ * @brief Write data into secure storage.
+ *
+ * Write data from provided buffer into secure storage, 
+ * and encrypt data encryption key with provided RSA public key and attach it to secure storage file.
+ * @param[in] buffer Point to data buffer.The buffer should be freed by API caller.
+ * @param[in] data_size Size of data in bytes.
+ * @param[in] data_name Data name associated with data.
+ * @param[in] offset Start address for partial writing on an existent data, if offset == 0 and data does not exist,new data entry is created,
+ *                              the parameter takes effect only when option SS_OPT_PARTIAL_RW is set
+ * @param[in] cred Application credential.
+ * @param[in] options Data access options.
+ * @param[in] rsa_n_data RSA public exponent.
+ * @param[in] rsa_n_len RSA public exponent size in bytes.
+ * @param[in] rsa_e_data RSA public key.
+ * @param[in] rsa_e_len RSA public key size in bytes.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_write_ex(unsigned char* buffer, unsigned int data_size,
+    unsigned int offset, const char* data_name, const ss_credential_s* cred,
+    unsigned int options, const unsigned char* rsa_n_data,
+    unsigned long rsa_n_len, const unsigned char* rsa_e_data,
+    unsigned long rsa_e_len);
+
+/**
+ * @brief Read data from secure storage.
+ *
+ * Read data from secure storage into provided buffer, content key will be recovered by provided RSA private key.
+ * @param[out] ret_buf Point to data buffer read from secure storage,the buffer is allocated inside the API, calo ss_free_buffer to free.
+ * @param[out] data_size size of data read from secure storage, when SS_OPT_PARTIAL_RW is set, this is firstly used as an in parameter to indicate required read size. 
+ * @param[in] base_path Path that data will be stored, if set to NULL, default path will be used.
+ * @param[in] data_name Data name associated with data.
+ * @param[in] offset Start address for partial reading, only takes effect when SS_OPT_PARTIAL_RW is set.
+ * @param[in] cred Application credential.
+ * @param[in] options Data access options.
+ * @param[in] rsa_n_data RSA public exponent.
+ * @param[in] rsa_n_len RSA public exponent size in bytes.
+ * @param[in] rsa_d_data RSA private key.
+ * @param[in] rsa_d_len RSA private key size in bytes. 
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_read_ex(unsigned char** ret_buf, unsigned int* data_size,
+    unsigned int offset, const char* data_name, const ss_credential_s* cred,
+    unsigned int options, const unsigned char* rsa_n_data,
+    unsigned long rsa_n_len, const unsigned char* rsa_d_data,
+    unsigned long rsa_d_len);
+
+/**
+ * @brief Validate secure storage file structure.
+ *
+ * Validate the secure storage file structure. 
+ * @param [in] data_name Data name associated with data.
+ * @param [in] cred Application credential.
+ * @param [in] options Data access options.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_validate(const char* data_name, const ss_credential_s* cred,
+    unsigned int options);
+
+/**
+ * @brief Delete fiel from secure storage.
+ *
+ * Delete fiel from secure storage.
+ * @param[in] base_path Path that data will be stored, if set to NULL, default path will be used.
+ * @param[in] data_name Data name associated with data.
+ * @param[in] cred Application credential.
+ * @param[in] options Data access options.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_delete(const char* data_name, const ss_credential_s* cred,
+    unsigned int options);
+
+/**
+ * @brief Remove all data from secure storage.
+ *
+ * Remove all data belongs to the credential from secure storage permanently, this should be used with caution.
+ * @param[in] base_path Path that data will be stored, if set to NULL, default path will be used.
+ * @param[in] cred Application credential.
+ * @param[in] options Data access options.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_clear_storage(const ss_credential_s* cred, unsigned int options);
+
+/**
+ * @brief free buffer allocated by secure storage API.
+ *
+ * Free buffer which is allocated by secure storage API ss_read/ss_read_ex
+ * @param buffer Point to buffer to be freed.
+ * @return ref to ss_ret_val_e enum.
+ */
+int ss_free_buffer(unsigned char* buffer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/ssflib/dep/swdss/include/ss_crypto.h b/ssflib/dep/swdss/include/ss_crypto.h
new file mode 100755 (executable)
index 0000000..ff7715d
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/**
+ * @file crypto.h
+ * @brief Crypto class header.
+ * @author ryan woo
+ * @version 1.0
+ * @date 2013.7.23
+ *
+ */
+
+#ifndef _SS_TA_CRYPTO_H_
+#define _SS_TA_CRYPTO_H_
+
+#include "CC_API.h"
+#include "ss_types.h"
+
+// rand gen
+
+static const CBT_UINT32 lcg_A = 1103515245; /* Initial value of A */
+static const CBT_UINT32 lcg_C = 12345; /* Initial value of C */
+
+void seed_rand(CBT_UINT32 seed);
+CBT_UINT32 gen_rand(void);
+
+void gen_rand_vec(CBT_OCTET* vec, CBT_UINT32 size);
+
+/**
+ * @class      CCryptoEngine
+ * @brief      Crypto Basic class
+ *
+ * Copyright 2011 by Samsung Electronics, Inc.,
+ * 
+ * This software is the confidential and proprietary information
+ * of Samsung Electronics, Inc. ("Confidential Information").  You
+ * shall not disclose such Confidential Information and shall use
+ * it only in accordance with the terms of the license agreement
+ * you entered into with Samsung.
+ */
+class CCryptoEngine {
+public:
+       const static int Hash_Size = 20; /**<Basic Hash size    */
+       const static int Key_Size = 16; /**<Cipher Key size     */
+       const static int EBlock_Size = 16; /**<Cipher Block size        */
+
+public:
+       /**
+        * @fn static int Encrypt(uint8_t* dest, uint8_t* src, unsigned long data_len, const uint8_t* key, unsigned long key_type)
+        * @brief    Encrypt provided data
+        */
+       static int Encrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
+           const uint8_t* key, unsigned long key_type);
+
+       /**
+        * @fn          static int HWEncrypt(uint8_t* dest, uint8_t* src, unsigned long data_len, const uint8_t* key, unsigned long key_type)
+        * @brief    Encrypt provided data by using HW based encryption engine
+        */
+       static int HWEncrypt(unsigned char* dest, unsigned long* dest_len,
+           unsigned char* src, unsigned long data_len, const unsigned char* key,
+           unsigned long key_type, unsigned long mode);
+
+       /**
+        * @fn          static int Decrypt(uint8_t* dest, uint8_t* src, unsigned long data_len, const uint8_t* key, unsigned long key_type)
+        * @brief    Decrypt provided data
+        */
+       static int Decrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
+           const uint8_t* key, unsigned long key_type);
+
+       /**
+        * @fn          static int HWDecrypt(uint8_t* dest, uint8_t* src, unsigned long data_len, const uint8_t* key, unsigned long key_type)
+        * @brief    Decrypt provided data
+        */
+       static int HWDecrypt(uint8_t* dest, unsigned long* dest_len, uint8_t* src,
+           unsigned long data_len, const uint8_t* key, unsigned long key_type,
+           unsigned long mode);
+
+       /**
+        * @fn          static int Hash(char* dest, const char* src, unsigned long data_len)
+        * @brief    Compute hash value over provided data
+        */
+       static int Hash(uint8_t* dest, const uint8_t* src, unsigned long data_len);
+
+       /**
+        * @fn          static int Random(char* dest, unsigned long data_len)
+        * @brief    Generating random number
+        */
+       static int Random(uint8_t* dest, unsigned long data_len);
+
+       /**
+        * @fn          static int RSAEncrypt(uint8_t* dest, unsigned long* dest_len, const uint8_t* src, unsigned long data_len,
+        const uint8_t* RSA_N_Data,   unsigned long RSA_N_Len,
+        const uint8_t* RSA_E_Data,   unsigned long RSA_E_Len);
+        * @brief    Encrypting data by using RSA pub key
+        */
+       static int RSAEncrypt(uint8_t* dest, unsigned long* dest_len,
+           const uint8_t* src, unsigned long src_len, const uint8_t* RSA_N_Data,
+           unsigned long RSA_N_Len, const uint8_t* RSA_E_Data,
+           unsigned long RSA_E_Len);
+
+       /**
+        * @fn  static int RSADecrypt(uint8_t* dest, unsigned long* 
+        *                       dest_len, const uint8_t* src, unsigned
+        *                       long data_len, const uint8_t*
+        *                       RSA_N_Data,   unsigned long RSA_N_Len,
+        *                       const uint8_t* RSA_E_Data,   unsigned
+        *                       long RSA_E_Len);
+        * @brief    Encrypting data by using RSA pub key
+        */
+       static int RSADecrypt(uint8_t* dest, unsigned long* dest_len,
+           const uint8_t* src, unsigned long src_len, const uint8_t* RSA_N_Data,
+           unsigned long RSA_N_Len, const uint8_t* RSA_D_Data,
+           unsigned long RSA_D_Len);
+};
+
+#endif
+
diff --git a/ssflib/dep/swdss/include/ss_misc.h b/ssflib/dep/swdss/include/ss_misc.h
new file mode 100755 (executable)
index 0000000..909838a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#ifndef _SS_MISC_H_
+#define _SS_MISC_H_
+
+#include <unistd.h>
+#include "ss_types.h"
+
+void byte_to_hex(uint8_t* dest, const uint8_t* src, unsigned long src_len);
+void hex_to_byte(uint8_t* dest, const uint8_t* src, unsigned long src_len);
+
+int is_hex(const char* text, char sep);
+
+#endif
+
diff --git a/ssflib/dep/swdss/include/ss_temp_store.h b/ssflib/dep/swdss/include/ss_temp_store.h
new file mode 100755 (executable)
index 0000000..a157a1e
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#ifndef _SWD_SS_TMP_STORE_H_
+#define _SWD_SS_TMP_STORE_H_
+
+#include <stdlib.h>
+#include "ss_types.h"
+#include <string.h>
+#include "ss_types.h"
+#include <pthread.h>
+#include "OsaLinuxUser.h"
+
+class auto_lock {
+public:
+
+       auto_lock() {
+               pthread_mutex_lock(&m_mutex);
+       }
+
+       ~auto_lock() {
+               pthread_mutex_unlock(&m_mutex);
+       }
+
+private:
+
+       static pthread_mutex_t m_mutex;
+};
+
+typedef struct temp_ss_node {
+       char node_id[SS_NODE_ID_LEN];
+       unsigned char* data;
+       unsigned int data_size;
+       temp_ss_node* prev;
+       temp_ss_node* next;
+} temp_ss_node;
+
+class ss_temp_store {
+public:
+       static ss_temp_store* get_instance();
+
+       int read(char* data_name, unsigned char** data, unsigned int& data_size);
+
+       int write(char* data_name, unsigned char* data, unsigned int data_size);
+
+       int remove(char* data_name);
+
+       int batch_remove(char* dir);
+
+private:
+
+       temp_ss_node* find_node(char* data_name);
+       temp_ss_node* del_node(temp_ss_node* node);
+
+       ss_temp_store() {
+               m_head.prev = NULL;
+               m_head.next = NULL;
+               m_head.data = NULL;
+               m_head.data_size = 0;
+       }
+
+private:
+
+       static ss_temp_store* m_instance;
+       temp_ss_node m_head;
+};
+
+#endif
diff --git a/ssflib/dep/swdss/include/ss_types.h b/ssflib/dep/swdss/include/ss_types.h
new file mode 100755 (executable)
index 0000000..02f1791
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#ifndef _SWD_SS_COMMON_H_
+#define _SWD_SS_COMMON_H_
+
+#define SS_MAX_UUID_LEN 64
+#define SS_MAX_MODULE_NAME_LEN 32
+#define SS_MAX_DATA_NAME_LEN 128
+#define SS_MAX_DATA_SIZE  1024*100
+
+#define SS_WSM_MEMPOOL_SIZE 3*1024*1024
+#define SS_CACHE_CAPACITY 2*1024*1024
+#define SWD_SS_SVC_START_CMD 0
+
+#define SS_FULL_DATA_NAME_LEN 256
+#define SS_NODE_ID_LEN SS_FULL_DATA_NAME_LEN
+
+typedef enum {
+       PRE_LOAD = 1, DELAY_WRITE = 2
+} ss_strategy_e;
+
+/**
+ * @brief secure storage return value.
+ *
+ */
+typedef enum {
+       SS_RET_SUCCESS = 0, /**< Return value in the case of success */
+       SS_RET_FAIL = 1, /**< Return value in the case of failure if no special detailed failure info available*/
+       SS_RET_INVALID_PARAM = 2, /**< Return value in the case if function input params are invalid */
+       SS_RET_INVALID_CREDENTIAL = 3, /**< Return value in the case if invalid credentials passed */
+       SS_RET_INVALID_DATA_NAME = 4, /**< Return value in the case if invalid data name passed */
+       SS_RET_CANT_FIND_REQUESTED_DATA = 5, /**< Return value in the case if requested data doesn't exist */
+       SS_RET_DUPLICATE_CREDENTIAL = 6, /**< Return value in the case if credentials duplication (used in internal functions only) */
+       SS_RET_OFFSET_ERR = 7, /**< Return value in the case if offset value is error*/
+       SS_RET_DATA_SIZE_IS_TOO_BIG = 8, /**< Return value in the case if provided data size is too big */
+       SS_RET_INVALID_OPTIONS = 9, /**< Return value in the case if invalid attributes passed */
+       SS_RET_MALLOC_FAILED = 10, /**< Return value in the case if memory allocation error occur */
+       SS_RET_INVALID_FILE = 11, /**< Return value in the case if file is corrupted or has invalid structure */
+       SS_RET_INTERNAL_ERROR = 12, /**< Return value in the case if any unexpected internal error occur */
+       SS_RET_COMM_ERR = 13, /**< Return value in the case if internal communication error */
+       SS_RET_INVALID_RSA_PARAM = 14, /**< Return value in the case if RSA key params are invalid */
+} ss_ret_val_e;
+
+/**
+ * @brief Secure storage options.
+ *
+ */
+typedef enum {
+       SS_OPT_DEFAULT = 0, /**<Default options,equals to  SS_OPT_UNIQUE|SS_OPT_PERMANENT*/
+       SS_OPT_UNIQUE = 1, /**<Bind particular secure file to particular device.*/
+       SS_OPT_COMMON = 2, /**<Create or load secure file which can be loaded on any other device or system.*/
+       SS_OPT_PERMANENT = 8, /**<Data will be stored in file system.*/
+       SS_OPT_TEMPORARY = 16, /**<Data will be stored in memory only.*/
+       SS_OPT_PARTIAL_RW = 32, /**<Enable partial reading and partial writing.*/
+} ss_options_e;
+
+/**
+ * @brief Credential structure.
+ *
+ * Every application should have a credential when using secure storage.
+ */
+typedef struct credential {
+       char uuid[SS_MAX_UUID_LEN]; /**< UUID.*/
+       char module_name[SS_MAX_MODULE_NAME_LEN]; /**< module name.*/
+
+       struct version_info {
+               unsigned long major;
+               unsigned long minor;
+       } version; /**< module version.*/
+
+} ss_credential_s;
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+typedef uint8_t CBT_OCTET;
+typedef uint8_t* CBT_OCTET_PTR;
+typedef uint32_t CBT_UINT32;
+typedef uint32_t* CBT_UINT32_PTR;
+typedef void* CBT_DATA_PTR;
+typedef CBT_UINT32 CBT_BOOL;
+typedef unsigned short uint16_t;
+
+#endif
+
diff --git a/ssflib/dep/swdss/source/file_op.cpp b/ssflib/dep/swdss/source/file_op.cpp
new file mode 100755 (executable)
index 0000000..290fb50
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#include "file_op.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <pthread.h>
+
+pthread_mutex_t delLock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t createLock = PTHREAD_MUTEX_INITIALIZER;
+
+using namespace std;
+
+int file_op::write_file(const char* filename, unsigned char* buffer,
+    unsigned int size) {
+       SLOGI("entering file_op::write_file");
+       if (NULL == buffer) {
+               return SS_RET_INVALID_PARAM;
+       }
+
+       FILE* file;
+
+       if (is_valid_filename(filename)) {
+               SLOGD("[%s][%d] NOT valid file : [ %s ]", __FUNCTION__, __LINE__, filename);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       // create folder if not exist.
+       char base_path[255] = {0};
+       get_base_path(filename, base_path);
+       SLOGI("base_path %s.", base_path);
+       if (!is_folder_exists(base_path)) {
+               if (0 != create_folder(base_path)) {
+                       return SS_RET_FAIL;
+               }
+       }
+
+       /* open file */
+       file = fopen(filename, "wb");
+       if (NULL == file) {
+               SLOGD("[%s][%d] fopen(..) == NULL , Can't open [ %s ] file. ", __FUNCTION__,
+                   __LINE__, filename);
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+
+       if (size != fwrite(buffer, 1, size, file)) {
+               SLOGD("[%s][%d]!!!DIFFERENT!!!", __FUNCTION__, __LINE__);
+               fclose(file);
+               return SS_RET_FAIL;
+       }
+
+       fflush(file);
+
+       //sync(fileno(file));   // sync blocked
+
+       fclose(file);
+
+       return SS_RET_SUCCESS;
+}
+
+int file_op::read_file(const char* filename, unsigned char** buffer,
+    unsigned int& size) {
+       SLOGI("Entering file_op::read_file...");
+       FILE* file;
+       long fLen;
+       *buffer = NULL;
+       size = 0;
+
+       if (is_valid_filename(filename)) {
+               SLOGD("[%s][%d] NOT valid file : [ %s ]", __FUNCTION__, __LINE__, filename);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       /* open file */
+       file = fopen(filename, "rb");
+       if (NULL == file) {
+               SLOGD("[%s][%d] fopen(..) == NULL , Can't open [ %s ] file. ", __FUNCTION__,
+                   __LINE__, filename);
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+
+       /* computing file size */
+       if(fseek(file, 0, SEEK_END) != 0){
+        fclose(file);
+        return SS_RET_FAIL;
+    }
+    fLen = ftell(file);
+       if (fLen > 0) {
+               size = fLen;
+       }
+    if(        fseek(file, 0, SEEK_SET) != 0){
+        fclose(file);
+        return SS_RET_FAIL;
+    }
+
+       /* allocating data buffer with enough size */
+       *buffer = new uint8_t[size];
+       if (!(*buffer)) {
+               SLOGD("[%s][%d] Can't malloc pBuffer to 'fread'. ", __FUNCTION__, __LINE__);
+               fclose(file);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       /* reading data from file */
+       if (size != fread(*buffer, size, 1, file)) {
+               SLOGD("[%s][%d] Read size is not equal to required size %d.", __FUNCTION__,
+                   __LINE__, size);
+       }
+
+       /* closing file */
+       fclose(file);
+
+       SLOGI("[%s][%d] File read successfully", __FUNCTION__, __LINE__);
+       return SS_RET_SUCCESS;
+}
+
+int file_op::remove_file(const char* filename) {
+       SLOGI("[%s][%d] Entering file_op::remove_file", __FUNCTION__, __LINE__);
+    pthread_mutex_lock(&delLock);    
+       bool ret = is_file_exists(filename);
+       if (ret) {
+               ret = remove(filename);
+               if (0 != ret) {
+                       SLOGD("[%s][%d] remove , nRet : %d , file [ %s ] not removed",
+                           __FUNCTION__, __LINE__, ret, filename);
+                       pthread_mutex_unlock(&delLock);
+                       return SS_RET_FAIL;
+               }
+       } else {
+               SLOGD("[%s][%d] access not ok , nRet : %d , There's NO file [ %s ] ",
+                   __FUNCTION__, __LINE__, ret, filename);
+               pthread_mutex_unlock(&delLock);
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+    pthread_mutex_unlock(&delLock);    
+       SLOGI("[%s][%d] Succeed to remove file...", __FUNCTION__, __LINE__);
+
+       return SS_RET_SUCCESS;
+}
+
+int file_op::is_valid_filename(const char* filename) {
+       // path shall not contain any "strange" characters
+       const char* validated_path = strpbrk(filename, "&;`'\"|*?~<>^()[]{}$\n \r");
+       if (validated_path != NULL) {
+               SLOGD(
+                   "[%s][%d] There are some forbidden charactors in path.(&;`'\"|*?~<>^()[]{}$\n \r) ",
+                   __FUNCTION__, __LINE__);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+int file_op::create_folder(const char* folder) {
+       SLOGI("[%s][%d] START", __FUNCTION__, __LINE__);
+
+       char base_p[256] = {0};
+       get_base_path(folder, base_p);
+       if (!is_folder_exists(base_p)) {
+               if (0 != create_folder(base_p)) {
+                       SLOGE("Failed to create folder %s.", base_p);
+                       return SS_RET_FAIL;
+               }
+       }
+
+       uint32_t result = SS_RET_SUCCESS;
+       struct stat st;
+       memset(&st, 0, sizeof(st));
+    pthread_mutex_lock(&createLock);
+       int res = stat(folder, &st);
+
+       if (res == -1) {
+               res = mkdir(folder, S_IRWXU);
+               if (0 != res) {
+                       result = SS_RET_FAIL;
+                       SLOGE("Failed to create folder %s.", folder);
+               }
+               //sync();
+       } else if (!(S_ISDIR(st.st_mode))) {
+               result = SS_RET_FAIL;
+       }
+    pthread_mutex_unlock(&createLock);
+
+       SLOGI("[%s][%d] END", __FUNCTION__, __LINE__);
+
+       return result;
+}
+
+int file_op::remove_folder(const char* folder) {
+       SLOGI("[%s][%d] START", __FUNCTION__, __LINE__);
+
+       rmdir(folder);
+
+       SLOGI("[%s][%d] END", __FUNCTION__, __LINE__);
+       return SS_RET_SUCCESS;
+}
+
+bool file_op::is_folder_exists(const char* folder) {
+       return is_file_exists(folder);
+}
+
+bool file_op::is_file_exists(const char* file) {
+       struct stat st;
+       memset(&st, 0, sizeof(st));
+       int res = stat(file, &st);
+       return (res != -1);
+}
+
+void file_op::get_base_path(const char* filename, char* base_path) {
+       char tmp[256] = {0};
+       memcpy(tmp, filename, strlen(filename));
+
+       for (int i = strlen(filename) - 1; i >= 0; --i) {
+               tmp[i] = 0;
+
+               if ('/' == filename[i]) {
+                       memcpy(base_path, tmp, strlen(tmp));
+                       break;
+               }
+       }
+}
+
diff --git a/ssflib/dep/swdss/source/secure_file.cpp b/ssflib/dep/swdss/source/secure_file.cpp
new file mode 100755 (executable)
index 0000000..51059b3
--- /dev/null
@@ -0,0 +1,1743 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#include "ss_crypto.h"
+#include "secure_file.h"
+#include <ctype.h>
+#include "ss_misc.h"
+#include "OsaLinuxUser.h"
+
+#ifdef _SECOS_SIM_
+#include "file_op.h"
+//#define SWD_SS_ROOT "/opt/usr/apps/tz_simulator/data/swdss/"
+#define SWD_SS_ROOT "/tmp/tastore2/"
+
+#endif
+
+// this is RNG SEED for mask
+static const CBT_UINT32 RNG_SEED = 0xa3e59cf2;
+// this is RNG SEED for mask
+static const CBT_UINT32 RNG_KEY_SEED = 0x3ae19f52;
+
+// Salts and IDs used i PBKDF2
+static const CBT_UINT32 SALT_SIZE = 20;
+//static CBT_UINT32 gUSaltID1 = 0;
+static const CBT_OCTET USALT1[SALT_SIZE] = {0xa2, 0x40, 0x51, 0x4f, 0x5d, 0x6c,
+    0xc5, 0x4f, 0xb0, 0x3f, 0x53, 0x33, 0xe9, 0x8a, 0xc0, 0xae, 0, 0, 0, 1};
+//static CBT_UINT32 gUSaltID2 = 0;
+static const CBT_OCTET USALT2[SALT_SIZE] = {0x0f, 0xb3, 0x9c, 0x0e, 0x65, 0x49,
+    0x91, 0x68, 0xa8, 0xe4, 0xd3, 0xa4, 0xdd, 0xe6, 0x3a, 0x0d, 0, 0, 0, 1};
+
+//static CBT_UINT32 gCSaltID1 = 0;
+static const CBT_OCTET CSALT1[SALT_SIZE] = {0x51, 0xa2, 0x40, 0x5d, 0x6c, 0x4f,
+    0xc5, 0xb0, 0x3f, 0x53, 0x4f, 0x33, 0xe9, 0xae, 0x8a, 0xc0, 0, 0, 0, 1};
+//static CBT_UINT32 gCSaltID2 = 0;
+static const CBT_OCTET CSALT2[SALT_SIZE] = {0x91, 0xb3, 0x9c, 0xa4, 0x0e, 0x0f,
+    0x49, 0x68, 0xa8, 0xe4, 0xd3, 0x0d, 0x65, 0xdd, 0xe6, 0x3a, 0, 0, 0, 1};
+
+const unsigned char g_Prekey[] = {0xa1, 0x21, 0x51, 0x71, 0xf1, 0x01, 0xd1,
+    0x31, 0x41, 0x01, 0x01, 0x91, 0x91, 0xb1, 0xe1, 0x11};
+
+// PBKDF2 iterations count
+static const CBT_UINT32 PHASE1_ITER = 200;
+static const CBT_UINT32 PHASE2_ITER = 250;
+
+#ifndef _SECOS_SIM_
+/*!
+ *  \brief  Determine file structure index
+ *  \param  pFileHeader [in]  pointer to file header
+ *  \return Structure index
+ */
+static CBT_UINT32 FileStructureType(CBT_OCTET* pFileHeader) {
+       return (pFileHeader[6] ^ pFileHeader[7]) % 6;
+}
+#endif
+
+static int PBKDF2(const CBT_OCTET* pKeyMaterial, CBT_UINT32 uKeyMaterialSize,
+    const CBT_OCTET* pSalt, unsigned long c, CBT_OCTET* pKey,
+    CryptoAlgorithm alg) {
+
+       CBT_OCTET pU[32] = {0};
+       CBT_OCTET pT[32] = {0};
+       cc_u32 uTSize = 0;
+
+       memcpy(pU, pSalt, SALT_SIZE);
+
+       // preparing crypto conteiner for HMAC-SHA1
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(alg);
+
+       // main cycle
+       for (unsigned long i = 0; i < c; i++) {
+               crt->MAC_getMAC(crt, const_cast<CBT_OCTET*>(pKeyMaterial), uKeyMaterialSize,
+                   pU, CCryptoEngine::Hash_Size, pT, &uTSize);
+               memcpy(pU, pT, uTSize);
+       }
+
+       destroy_CryptoCoreContainer(crt);
+
+       memcpy(pKey, pT, CCryptoEngine::Key_Size);
+
+       return 0;
+}
+
+static int MDeriveCommonKey1(const CBT_OCTET* pKeyMaterial,
+    CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
+       // deriving key
+       PBKDF2(pKeyMaterial, uKeyMaterialSize, CSALT1, PHASE1_ITER, pKey, ID_HSHA1);
+
+       return 0;
+}
+
+static int MDeriveCommonKey2(const CBT_OCTET* pKeyMaterial,
+    CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
+       // deriving key
+       PBKDF2(pKeyMaterial, uKeyMaterialSize, CSALT2, PHASE2_ITER, pKey, ID_HSHA1);
+
+       return 0;
+}
+
+static int MDeriveUniqueKey1(const CBT_OCTET* pKeyMaterial,
+    CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
+       // deriving key
+       PBKDF2(pKeyMaterial, uKeyMaterialSize, USALT1, PHASE1_ITER, pKey, ID_HSHA1);
+
+       return 0;
+}
+
+static int MDeriveUniqueKey2(const CBT_OCTET* pKeyMaterial,
+    CBT_UINT32 uKeyMaterialSize, CBT_OCTET* pKey) {
+       unsigned long nSize = 0;
+       CBT_OCTET* pBuffer = (CBT_OCTET*)NULL;
+       CBT_OCTET key[16] = {0, };
+
+       if (uKeyMaterialSize > KEY_MAT_SIZE) {
+               SLOGE("uKeyMaterialSize %d is too big.\n", uKeyMaterialSize);
+               return SS_RET_INTERNAL_ERROR;
+       }
+
+       pBuffer = new CBT_OCTET[uKeyMaterialSize + 16];
+       if (!pBuffer) {
+               SLOGE("Alloc memory failed.\n");
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       memset(pBuffer, 0, uKeyMaterialSize + 16);
+
+#if defined(_SECOS_SIM_)
+#define UCI_HW_SECRET_KEY 0
+#define ID_UCI_ENC_ECB 0
+#endif
+
+       int iRet = CCryptoEngine::HWEncrypt(pBuffer, &nSize, (CBT_OCTET*)pKeyMaterial,
+           uKeyMaterialSize, key,
+           UCI_HW_SECRET_KEY,
+           ID_UCI_ENC_ECB);
+       if (iRet) {
+               SLOGE("Failed to do HWEncrypt, ret_code %d.\n", iRet);
+               delete[] pBuffer;
+               return SS_RET_INTERNAL_ERROR;
+       }
+
+       memset(pBuffer + CCryptoEngine::Key_Size, 0, 16); //hack
+
+       // deriving key
+       PBKDF2(pBuffer, nSize, USALT2, PHASE2_ITER, pKey, ID_HSHA1);
+
+       delete[] pBuffer;
+
+       return 0;
+}
+
+static int GenKey(const CBT_OCTET* pKeyMaterial, CBT_OCTET* pKey,
+    CBT_UINT32 options) {
+       int iRet = 0;
+       CBT_OCTET pBufKey[CCryptoEngine::Key_Size];
+
+       // performing first transformation
+       if (options & SS_OPT_COMMON) {
+               iRet = MDeriveCommonKey1(pKeyMaterial, KEY_MAT_SIZE, pBufKey);
+       } else {
+               iRet = MDeriveUniqueKey1(pKeyMaterial, KEY_MAT_SIZE, pBufKey);
+       }
+
+       if (iRet) {
+               SLOGE("Failed to derive key 1st phase.\n");
+               return SS_RET_INTERNAL_ERROR;
+       }
+
+       // performing second transformation
+       if (options & SS_OPT_COMMON) {
+               iRet = MDeriveCommonKey2(pBufKey, CCryptoEngine::Key_Size, pKey);
+       } else {
+               iRet = MDeriveUniqueKey2(pBufKey, CCryptoEngine::Key_Size, pKey);
+       }
+
+       if (iRet) {
+               SLOGE("Failed to derive key 2nd phase.\n");
+               return SS_RET_INTERNAL_ERROR;
+       }
+
+       return iRet;
+}
+
+int Encrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
+    uint8_t* key_material, uint32_t options) {
+       int iRet = 0;
+       CBT_OCTET pKey[CCryptoEngine::Key_Size];
+
+       // generating random key data
+       CCryptoEngine::Random(key_material, KEY_MAT_SIZE);
+
+       iRet = GenKey(key_material, pKey, options);
+       if (iRet) {
+               SLOGE("Failed to do MGenKey.\n");
+               return 0;
+       }
+
+       return CCryptoEngine::Encrypt(dest, src, data_len, pKey, 0);
+}
+
+int EncryptEx(uint8_t* dest, uint8_t* src, unsigned long data_len,
+    uint8_t* key_material, uint8_t* enc_key, uint32_t options) {
+       CBT_OCTET pKey[CCryptoEngine::Key_Size];
+
+       int iRet = 0;
+       //int i;
+       int ret;
+       // generating random key data
+       CCryptoEngine::Random(key_material, KEY_MAT_SIZE);
+
+       iRet = GenKey(key_material, pKey, options);
+       if (iRet) {
+               SLOGE("Failed to do MGenKey.\n");
+               return 0;
+       }
+
+       unsigned int cipherTextLen, t;
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
+
+       if (crt == NULL) {
+               return 0;
+       }
+       crt->SE_init(crt, ID_ENC_ECB, ID_NO_PADDING, const_cast<uint8_t*>(g_Prekey),
+           CCryptoEngine::Key_Size, (cc_u8*)NULL);
+       crt->SE_process(crt, pKey, CCryptoEngine::Key_Size, enc_key,
+           static_cast<cc_u32*>(&cipherTextLen));
+       crt->SE_final(crt, (cc_u8*)NULL, 0, (pKey + cipherTextLen),
+           static_cast<cc_u32*>(&t));
+       cipherTextLen += t;
+       destroy_CryptoCoreContainer(crt);
+
+       ret = CCryptoEngine::Encrypt(dest, src, data_len, pKey, 0);
+
+       return ret;
+}
+
+int Decrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
+    const uint8_t* key_material, uint32_t options) {
+       int iRet = 0;
+       CBT_OCTET pKey[CCryptoEngine::Key_Size];
+
+       if (key_material == 0) {
+               SLOGE("Key material is NULL.\n");
+               return 0;
+       }
+
+       iRet = GenKey(key_material, pKey, options);
+       if (iRet) {
+               SLOGE("Failed to do MGenKey.\n");
+               return 0;
+       }
+
+       return CCryptoEngine::Decrypt(dest, src, data_len, pKey, 0);
+}
+
+int DecryptEx(uint8_t* dest, uint8_t* src, unsigned long data_len,
+    const uint8_t* enc_key/*, uint32_t keysize,  uint8_t* rsa_n_data, uint32_t rsa_n_len, uint8_t* rsa_d_data, uint32_t rsa_d_len*/) {
+       int ret;
+       //int i;
+       //unsigned long uDecryptedKeySize;
+       uint8_t decryptedKeyBuffer[ENCRYPTED_KEY_SIZE];
+
+       unsigned int plainTextLen, t;
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
+       if (crt == NULL) {
+               return 0;
+       }
+
+       crt->SE_init(crt, ID_DEC_ECB, ID_NO_PADDING, const_cast<uint8_t*>(g_Prekey),
+           16, (cc_u8*)NULL);
+       crt->SE_process(crt, const_cast<uint8_t*>(enc_key), CCryptoEngine::Key_Size,
+           decryptedKeyBuffer, static_cast<cc_u32*>(&plainTextLen));
+       crt->SE_final(crt, NULL, 0, (uint8_t*)(decryptedKeyBuffer + plainTextLen),
+           static_cast<cc_u32*>(&t));
+       destroy_CryptoCoreContainer(crt);
+       plainTextLen += t;
+
+       ret = CCryptoEngine::Decrypt(dest, src, data_len, decryptedKeyBuffer, 0);
+
+       return ret;
+}
+
+int is_valid_credential(const ss_credential_s& cred) {
+       // In its canonical form, a UUID consists of 32 hexadecimal digits, displayed in 5 groups separated by hyphens, 
+       // in the form 8-4-4-4-12 for a total of 36 characters(32 digits and 4 '-'). For example:
+       // 550e8400-e29b-41d4-a716-446655440000 
+       // Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the version number as well 
+       // as two reserved bits. All other bits are set using a random or pseudorandom data source. 
+       // Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal digits x and hexadecimal 
+       // digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+       char tmp_uuid[SS_MAX_UUID_LEN + 1] = {0};
+       char tmp_mn[SS_MAX_MODULE_NAME_LEN + 1] = {0};
+       strncpy(tmp_uuid, cred.uuid, SS_MAX_UUID_LEN);
+       strncpy(tmp_mn, cred.module_name, SS_MAX_MODULE_NAME_LEN);
+
+       // we have to check only UUID format
+       // checking size
+       if (strlen(tmp_uuid) != 36) {
+               return SS_RET_INVALID_CREDENTIAL;
+       }
+       // checking delimiters
+       if (tmp_uuid[8] != '-' || tmp_uuid[13] != '-' || tmp_uuid[18] != '-'
+           || tmp_uuid[23] != '-') {
+               return SS_RET_INVALID_CREDENTIAL;
+       }
+
+       // checking specific values
+       //if (tmp_uuid[14] != '4' || (tmp_uuid[19] != '8' && tmp_uuid[19] != '9' && tmp_uuid[19] != 'a' && tmp_uuid[19] != 'b'))
+       //{
+       //    return SS_RET_INVALID_CREDENTIAL;
+       //}
+       // checking that string contains only hexidecimal values
+       if (-1 == is_hex(tmp_uuid, '-')) {
+               return SS_RET_INVALID_CREDENTIAL;
+       }
+
+       // Module name shall not contain any spaces
+       for (uint32_t i = 0; i < strlen(tmp_mn); ++i) {
+               if (isspace(tmp_mn[i])) {
+                       return SS_RET_INVALID_CREDENTIAL;
+               }
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+static int is_valid_options(unsigned int options) {
+       if (((options & SS_OPT_COMMON) && (options & SS_OPT_UNIQUE))
+           || ((options & SS_OPT_TEMPORARY) && (options & SS_OPT_PERMANENT))) {
+               return SS_RET_INVALID_OPTIONS;
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+static int is_valid_data_name(const char* data_name) {
+       for (int i = 0; data_name[i] != 0; ++i) {
+               if ((!isalnum(data_name[i])) && ('-' != data_name[i])
+                   && ('_' != data_name[i]) && ('.' != data_name[i])) {
+                       return SS_RET_INVALID_DATA_NAME;
+               }
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+int cred_options_check(const ss_credential_s* cred, unsigned int options) {
+       if (SS_RET_SUCCESS != is_valid_credential(*cred)) {
+               SLOGE("[%s] invalid credential.\n", __FUNCTION__);
+               return SS_RET_INVALID_CREDENTIAL;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_options(options)) {
+               SLOGE("[%s] invalid options.\n", __FUNCTION__);
+               return SS_RET_INVALID_OPTIONS;
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+int secure_file::initialize(const ss_credential_s * cred, const char* data_name,
+    unsigned int options) {
+       int iRet = cred_options_check(cred, options);
+       if (SS_RET_SUCCESS != iRet) {
+               return iRet;
+       }
+
+       m_cred = *cred;
+
+       m_data_name[0] = '\0';
+       if (NULL != data_name) {
+               int data_name_len = strlen(data_name);
+               memcpy(m_data_name, data_name, data_name_len);
+               m_data_name[data_name_len] = '\0';
+       }
+
+       m_options = options;
+
+       m_use_crypted_key = false;
+
+       m_cache = ss_temp_store::get_instance();
+       if (NULL == m_cache) {
+               SLOGF("[%s][%d](ERROR) Failed to alloc cache_manager. ", __FUNCTION__,
+                   __LINE__);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+uint32_t secure_file::transform_name_to_id(const char* data_name) {
+       uint32_t uuidFile = 0;
+
+       for (unsigned int i = 0; i < strlen(data_name); i++) {
+               uuidFile = uuidFile * 33 + data_name[i];
+       }
+
+       return uuidFile;
+}
+
+uint64_t secure_file::transform_id_to_name(uint64_t uDataFileID) {
+       uint64_t uDataFileName;
+       CBT_UINT32 uDataFileName1, uDataFileName2;
+       // the main idea of this function is to transfor initial file id into different number which 
+       // hexidecimal representation will be the real file name.
+       // first part
+       seed_rand(uDataFileID & 0xffffffff);
+       uDataFileName1 = gen_rand();
+       uDataFileName1 = (uDataFileName1 << 15) | (uDataFileName1 >> (32 - 15));
+       seed_rand(RNG_SEED);
+       uDataFileName1 ^= gen_rand();
+       // second part
+       seed_rand((uDataFileID >> 32) & 0xffffffff);
+       uDataFileName2 = gen_rand();
+       uDataFileName2 = (uDataFileName2 << 10) | (uDataFileName2 >> (32 - 10));
+       seed_rand(RNG_SEED);
+       uDataFileName2 ^= gen_rand();
+       // hexidecimal representation of return value will be the real file name.
+       uDataFileName = uDataFileName1 | (((uint64_t)uDataFileName2) << 32);
+
+       SLOGI("[%s][%d] uDataFileName : %llu", __FUNCTION__, __LINE__, uDataFileName);
+       return uDataFileName;
+}
+
+int secure_file::finalize() {
+       if (m_file_content.m_bHeaderAllocated) {
+               delete[] m_file_content.m_pFileHeader;
+               m_file_content.m_pFileHeader = NULL;
+               m_file_content.m_bHeaderAllocated = false;
+       }
+
+       if (m_file_content.m_bHashAllocated) {
+               delete[] m_file_content.m_pHashMaterial;
+               m_file_content.m_bHashAllocated = NULL;
+               m_file_content.m_bHashAllocated = false;
+       }
+
+       if (m_file_content.m_bKeyAllocated) {
+               delete[] m_file_content.m_pKeyMaterial;
+               m_file_content.m_pKeyMaterial = NULL;
+               m_file_content.m_bKeyAllocated = false;
+       }
+
+       if (m_file_content.m_bFileContentAllocated) {
+               delete[] m_file_content.m_pFileContent;
+               m_file_content.m_pFileContent = NULL;
+               m_file_content.m_bFileContentAllocated = false;
+       }
+
+       if (m_file_content.m_pOutputContent) {
+               delete[] m_file_content.m_pOutputContent;
+               m_file_content.m_pOutputContent = NULL;
+       }
+
+       if (m_is_partial_write) {
+               if (NULL != m_write_data) {
+                       OsaFree(m_write_data);
+               }
+       }
+
+       if (m_read_data) {
+               OsaFree(m_read_data);
+       }
+
+       // finalize shm mgr
+
+       return SS_RET_SUCCESS;
+}
+
+int secure_file::derive_file_path() {
+#ifdef _SECOS_SIM_
+       if (true == m_file_path_ready) {
+               return SS_RET_SUCCESS;
+       }
+
+       memcpy(m_full_path, m_cred.uuid, SS_MAX_UUID_LEN);
+       strcat(m_full_path, "/");
+       strcat(m_full_path, m_data_name);
+       m_file_path_ready = true;
+       return SS_RET_SUCCESS;
+#else
+
+       //std::string sfolder;
+       char sUUID_and_Name[SS_MAX_UUID_LEN + SS_MAX_MODULE_NAME_LEN + 2] = {0};
+       char sTemp[SS_MAX_UUID_LEN + SS_MAX_MODULE_NAME_LEN
+       + 2 * CCryptoEngine::Hash_Size + 2] = {0};
+
+       CBT_OCTET pHash[2 * CCryptoEngine::Hash_Size];
+       CBT_OCTET pFolderName[2 * CCryptoEngine::Hash_Size];
+
+       // combining UUID and Name
+       char tmp_uuid[SS_MAX_UUID_LEN + 1] = {0};
+       char tmp_mn[SS_MAX_MODULE_NAME_LEN + 1] = {0};
+       strncpy(tmp_uuid, m_cred.uuid, SS_MAX_UUID_LEN);
+       strncpy(tmp_mn, m_cred.module_name, SS_MAX_MODULE_NAME_LEN);
+
+       memcpy(sUUID_and_Name, tmp_uuid, strlen(tmp_uuid));
+       memcpy(sUUID_and_Name + strlen(tmp_uuid), tmp_mn, strlen(tmp_mn));
+
+       // compute hash value of sUUID_and_Name
+       CCryptoEngine::Hash(pHash,
+                       (CBT_OCTET*)sUUID_and_Name,
+                       strlen(sUUID_and_Name));
+
+       // obtain first part of our string
+       byte_to_hex(pFolderName, pHash, CCryptoEngine::Hash_Size);
+       memcpy(sTemp, pFolderName, 2 * CCryptoEngine::Hash_Size);
+       //sTemp.assign((char*)pFolderName, 2*CCryptoEngine::Hash_Size);
+
+       // concatenate with UUID and Name
+       //sTemp += sUUID_and_Name;
+       memcpy(sTemp + 2 * CCryptoEngine::Hash_Size,
+                       sUUID_and_Name,
+                       strlen(sUUID_and_Name));
+
+       // compute hash of obtained string
+       CCryptoEngine::Hash(pHash, (CBT_OCTET*)sTemp, strlen(sTemp));
+
+       // we will use first 4 bytes of hash value
+       // convert them into hex format
+       //byte_to_hex(pFolderName, pHash, 4);
+
+       // set folder name
+       //sfolder.assign((char*)pFolderName, 8);
+       //sfolder += "/";
+
+       //m_full_path = sfolder;
+       memset(m_full_path, 0, SS_FULL_DATA_NAME_LEN);
+       memcpy(m_full_path, pHash, 4);
+
+       unsigned char dir[9] = {0};
+       byte_to_hex(dir, pHash, 4);
+       SLOGI("Dir is %s.", (char*)dir);
+
+       //m_full_path[8] = '/';
+
+       if (0 != strlen(m_data_name)) {
+               // computing file name
+               uint64_t data_id = transform_id_to_name(transform_name_to_id(m_data_name));
+               memcpy(&m_full_path[4], &data_id, sizeof(uint64_t));
+
+               unsigned char filename[17] = {0};
+               byte_to_hex(filename, (unsigned char*)&m_full_path[4], 8);
+               SLOGI("filename is %s.", (char*)filename);
+       }
+
+       m_file_path_ready = true;
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+void secure_file::compute_file_hash(CBT_OCTET* pHash) {
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_SHA1);
+       crt->MD_init(crt);
+       crt->MD_update(crt,
+           static_cast<cc_u8*>((void*)const_cast<uint8_t*>(m_file_content
+               .m_pFileContent)), m_file_content.m_uFileContentSize);
+       crt->MD_update(crt,
+           static_cast<cc_u8*>((void*)const_cast<uint8_t*>(m_file_content
+               .m_pKeyMaterial)), m_file_content.m_uKeyMaterialSize);
+       crt->MD_final(crt, (uint8_t*)pHash);
+       destroy_CryptoCoreContainer(crt);
+}
+
+int secure_file::prepare_file_content(unsigned char* buffer,
+    unsigned int buf_size) {
+#ifdef _SECOS_SIM_
+       return 0;
+#else
+
+       // first of all we have to encrypt file data
+       // allocating enough memory for encrypted content
+       m_file_content.m_pFileContent = new CBT_OCTET[buf_size + 32];
+
+       // allocating anough memory for key material
+       m_file_content.m_pKeyMaterial = new CBT_OCTET[KEY_MAT_SIZE];
+       m_file_content.m_uKeyMaterialSize = KEY_MAT_SIZE;
+       if (!m_file_content.m_pKeyMaterial) {
+               SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_file_content.m_pKeyMaterial' to conatin pKey",
+                               __FUNCTION__,
+                               __LINE__);
+               return SS_RET_MALLOC_FAILED;
+       }
+       m_file_content.m_bKeyAllocated = true;
+
+       if (!m_file_content.m_pFileContent) {
+               SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_file_content.m_pFileContent' used in Encypt(m_FileContent.m_pFileContent, ..)",
+                               __FUNCTION__,
+                               __LINE__);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       m_file_content.m_bFileContentAllocated = true;
+
+       if (m_use_crypted_key) {
+               int ret;
+
+               long unsigned uEncryptedKeySize;
+               CBT_OCTET keybuf[CCryptoEngine::Key_Size];
+               m_file_content.m_uFileContentSize = EncryptEx(m_file_content.m_pFileContent,
+                               const_cast<CBT_OCTET*>(buffer),
+                               buf_size,
+                               m_file_content.m_pKeyMaterial,
+                               keybuf,
+                               m_options);
+
+               if (0 == m_file_content.m_uFileContentSize) {
+                       SLOGD("[%s][%d](ERROR) TZ Can't ENcrypt data WITH EncryptedKey mode. // (0 == m_file_content.m_pOutputContentSize)",
+                                       __FUNCTION__,
+                                       __LINE__);
+                       SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
+                       return SS_RET_INTERNAL_ERROR;
+               }
+
+               ret = CCryptoEngine::RSAEncrypt(m_file_content.m_EncryptedKeyBuffer + 4,
+                               &uEncryptedKeySize,
+                               keybuf,
+                               CCryptoEngine::Key_Size,
+                               m_rsa_key.rsa_n_data,
+                               m_rsa_key.rsa_n_len,
+                               m_rsa_key.rsa_e_data,
+                               m_rsa_key.rsa_e_len);
+
+               // the first 4 bytes of buffer containes encrypted data size
+               m_file_content.m_EncryptedKeyBuffer[0] = uEncryptedKeySize & 0xff;
+               m_file_content.m_EncryptedKeyBuffer[1] = (uEncryptedKeySize >> 8) & 0xff;
+               m_file_content.m_EncryptedKeyBuffer[2] = (uEncryptedKeySize >> 16) & 0xff;
+               m_file_content.m_EncryptedKeyBuffer[3] = (uEncryptedKeySize >> 24) & 0xff;
+
+               if (CRYPTO_SUCCESS != ret) {
+                       SLOGD("%s RSA Encryption failure %i\n", __FUNCTION__, ret);
+                       return SS_RET_FAIL;
+               } else {
+                       SLOGD("%s Content key size is = %ld\n", __FUNCTION__, uEncryptedKeySize);
+               }
+
+       } else {
+               m_file_content.m_uFileContentSize = Encrypt(m_file_content.m_pFileContent,
+                               const_cast<CBT_OCTET*>(buffer),
+                               buf_size,
+                               m_file_content.m_pKeyMaterial,
+                               m_options);
+
+               if (0 == m_file_content.m_uFileContentSize) {
+                       SLOGD("[%s][%d](ERROR) TZ Can't ENcrypt data WITHOUT EncryptedKey mode. // (0 == m_file_content.m_pOutputContentSize)",
+                                       __FUNCTION__,
+                                       __LINE__);
+                       SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
+                       return SS_RET_INTERNAL_ERROR;
+               }
+       }
+
+       // time to compute hash
+       // allocating anough memory for hash
+       m_file_content.m_pHashMaterial = new CBT_OCTET[HASH_SIZE];
+       m_file_content.m_uHashMaterialSize = HASH_SIZE;
+
+       if (!m_file_content.m_pHashMaterial) {
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       m_file_content.m_bHashAllocated = true;
+
+       // filling it with random data
+       CCryptoEngine::Random(m_file_content.m_pHashMaterial, HASH_SIZE);
+
+       // computing hash
+       compute_file_hash(m_file_content.m_pHashMaterial);
+
+       // time to make header
+       // allocating anough memory for header
+       m_file_content.m_pFileHeader = new CBT_OCTET[HEADER_SIZE];
+       m_file_content.m_uFileHeaderSize = HEADER_SIZE;
+       if (!m_file_content.m_pFileHeader) {
+               SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_file_content.m_pFileHeader' to initialize Header information",
+                               __FUNCTION__,
+                               __LINE__);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       m_file_content.m_bHeaderAllocated = true;
+
+       // filling it with random data
+       CCryptoEngine::Random(m_file_content.m_pFileHeader, HEADER_SIZE);
+
+       m_file_content.m_pFileHeader[0] = 0xa5;
+       m_file_content.m_pFileHeader[1] = 0x5a;
+       m_file_content.m_pFileHeader[2] = 2;
+       m_file_content.m_pFileHeader[3] = 0;
+       m_file_content.m_pFileHeader[4] = 1;
+
+       if (m_use_crypted_key) {
+               m_file_content.m_pFileHeader[5] = 1; //encrypted key attached to file
+       } else {
+               m_file_content.m_pFileHeader[5] = 0;
+       }
+
+       SLOGI("[%s] m_file_content.m_pFileHeader[5] = %i",
+                       __FUNCTION__,
+                       m_file_content.m_pFileHeader[5]);
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+int secure_file::parse_file_content(unsigned char* buffer,
+    unsigned int buf_size) {
+#ifdef _SECOS_SIM_
+       return 0;
+#else
+
+       // header shall be at least 16 bytes.
+       if (NULL == buffer) {
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE)", __FUNCTION__, __LINE__);
+               return SS_RET_INVALID_FILE;
+       }
+       // the first 2 bytes shall have fixed values
+       if (buffer[0] != 0xa5 || buffer[1] != 0x5a) {
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) *pBuffer : %c // %x",
+                               __FUNCTION__,
+                               __LINE__,
+                               *buffer,
+                               *buffer);
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+1) : %c // %x",
+                               __FUNCTION__,
+                               __LINE__,
+                               *(buffer + 1),
+                               *(buffer + 1));
+               return SS_RET_INVALID_FILE;
+       }
+
+       // the next 4 bytes containes SS version and file structure version
+       if ((buffer[2] != 2) || (buffer[3] != 0)) {
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+2) : %c // %x",
+                               __FUNCTION__,
+                               __LINE__,
+                               *(buffer + 2),
+                               *(buffer + 2));
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+3) : %c // %x",
+                               __FUNCTION__,
+                               __LINE__,
+                               *(buffer + 3),
+                               *(buffer + 3));
+               return SS_RET_INVALID_FILE;
+       }
+
+       if ((buffer[4] != 1) || ((buffer[5] != 0) && (buffer[5] != 1))) {
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+4) : %c // %x",
+                               __FUNCTION__,
+                               __LINE__,
+                               *(buffer + 4),
+                               *(buffer + 4));
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) *(pBuffer+5) : %c // %x",
+                               __FUNCTION__,
+                               __LINE__,
+                               *(buffer + 5),
+                               *(buffer + 5));
+               return SS_RET_INVALID_FILE;
+       }
+
+       // temporary pointer to file content
+       CBT_OCTET* ptr = const_cast<CBT_OCTET*>(buffer);
+
+       // header, key material and hash sizes are fixed
+       m_file_content.m_uFileHeaderSize = HEADER_SIZE;
+       m_file_content.m_uHashMaterialSize = HASH_SIZE;
+       m_file_content.m_uKeyMaterialSize = KEY_MAT_SIZE;
+
+       if (buffer[5] == 0) {
+               SLOGI("[%s][%d] File dosn't containe encrypted key material!",
+                               __FUNCTION__,
+                               __LINE__);
+               m_file_content.m_uEncryptedKeySize = 0;
+               m_file_content.m_uFileContentSize = buf_size
+               - (HEADER_SIZE + HASH_SIZE + KEY_MAT_SIZE);
+       } else if (buffer[5] == 1) {
+               SLOGI("[%s][%d] File containes encrypted key material!",
+                               __FUNCTION__,
+                               __LINE__);
+               m_file_content.m_uEncryptedKeySize = ENCRYPTED_KEY_SIZE;
+               m_file_content.m_uFileContentSize = buf_size
+               - (HEADER_SIZE + HASH_SIZE + KEY_MAT_SIZE + ENCRYPTED_KEY_SIZE);
+       }
+
+       SLOGI("[%s][%d] m_file_content.m_uFileContentSize = %i!",
+                       __FUNCTION__,
+                       __LINE__,
+                       m_file_content.m_uFileContentSize);
+       SLOGI("[%s][%d] m_file_content.m_uEncryptedKeySize = %i!",
+                       __FUNCTION__,
+                       __LINE__,
+                       m_file_content.m_uEncryptedKeySize);
+
+       switch (FileStructureType(ptr)) {
+               case 0: {
+                       // [header][hash][data][key]
+                       m_file_content.m_pFileHeader = ptr;
+                       ptr += HEADER_SIZE;
+                       m_file_content.m_pHashMaterial = ptr;
+                       ptr += HASH_SIZE;
+                       m_file_content.m_pFileContent = ptr;
+                       ptr += m_file_content.m_uFileContentSize;
+                       m_file_content.m_pKeyMaterial = ptr;
+                       ptr += KEY_MAT_SIZE;
+                       break;
+               }
+               case 1: {
+                       // [header][hash][key][data]
+                       m_file_content.m_pFileHeader = ptr;
+                       ptr += HEADER_SIZE;
+                       m_file_content.m_pHashMaterial = ptr;
+                       ptr += HASH_SIZE;
+                       m_file_content.m_pKeyMaterial = ptr;
+                       ptr += KEY_MAT_SIZE;
+                       m_file_content.m_pFileContent = ptr;
+                       ptr += m_file_content.m_uFileContentSize;
+                       break;
+               }
+               case 2: {
+                       // [header][data][key][hash]
+                       m_file_content.m_pFileHeader = ptr;
+                       ptr += HEADER_SIZE;
+                       m_file_content.m_pFileContent = ptr;
+                       ptr += m_file_content.m_uFileContentSize;
+                       m_file_content.m_pKeyMaterial = ptr;
+                       ptr += KEY_MAT_SIZE;
+                       m_file_content.m_pHashMaterial = ptr;
+                       ptr += HASH_SIZE;
+                       break;
+               }
+               case 3: {
+                       // [header][key][data][hash]
+                       m_file_content.m_pFileHeader = ptr;
+                       ptr += HEADER_SIZE;
+                       m_file_content.m_pKeyMaterial = ptr;
+                       ptr += KEY_MAT_SIZE;
+                       m_file_content.m_pFileContent = ptr;
+                       ptr += m_file_content.m_uFileContentSize;
+                       m_file_content.m_pHashMaterial = ptr;
+                       ptr += HASH_SIZE;
+                       break;
+               }
+               case 4: {
+                       // [header][key][hash][data]
+                       m_file_content.m_pFileHeader = ptr;
+                       ptr += HEADER_SIZE;
+                       m_file_content.m_pKeyMaterial = ptr;
+                       ptr += KEY_MAT_SIZE;
+                       m_file_content.m_pHashMaterial = ptr;
+                       ptr += HASH_SIZE;
+                       m_file_content.m_pFileContent = ptr;
+                       ptr += m_file_content.m_uFileContentSize;
+                       break;
+               }
+               case 5: {
+                       // [header][data][hash][key]
+                       m_file_content.m_pFileHeader = ptr;
+                       ptr += HEADER_SIZE;
+                       m_file_content.m_pFileContent = ptr;
+                       ptr += m_file_content.m_uFileContentSize;
+                       m_file_content.m_pHashMaterial = ptr;
+                       ptr += HASH_SIZE;
+                       m_file_content.m_pKeyMaterial = ptr;
+                       ptr += KEY_MAT_SIZE;
+                       break;
+               }
+               default: {
+                       SLOGD("[%s][%d](SS_RET_FAIL) OUT OF THE FileStructureType : %d",
+                                       __FUNCTION__,
+                                       __LINE__,
+                                       FileStructureType(m_file_content.m_pFileHeader));
+                       return SS_RET_INVALID_FILE;
+               }
+               break;
+       }
+
+       // alloc meory for output content
+       m_file_content.m_pOutputContent =
+       new CBT_OCTET[m_file_content.m_uFileContentSize];
+       if (!m_file_content.m_pOutputContent) {
+               SLOGD("[%s][%d](SS_RET_MALLOC_FAILED) CAN'T Malloc 'm_FileContent.m_pOutputContent' to attach it to SDC. ",
+                               __FUNCTION__,
+                               __LINE__);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       // do we have encrypted key material attached
+       if (m_use_crypted_key) {
+               SLOGI("[%s][%d] Using attached content key", __FUNCTION__, __LINE__);
+               if (m_file_content.m_pFileHeader[5] != 1) {
+                       SLOGD("[%s][%d](SS_RET_FAIL) m_file_content.m_pFileHeader[5] != 1",
+                                       __FUNCTION__,
+                                       __LINE__);
+                       return SS_RET_FAIL;
+               }
+
+               m_file_content.m_pEncryptedKey = const_cast<CBT_OCTET*>(buffer + buf_size
+                               - ENCRYPTED_KEY_SIZE);
+               // revocer encrypted data size
+               m_file_content.m_uEncryptedKeySize =
+               (CBT_UINT32)m_file_content.m_pEncryptedKey[0]
+               | (CBT_UINT32)m_file_content.m_pEncryptedKey[1] << 8
+               | (CBT_UINT32)m_file_content.m_pEncryptedKey[2] << 16
+               | (CBT_UINT32)m_file_content.m_pEncryptedKey[3] << 24;
+               // it shall not be bigger then expected size
+               if (m_file_content.m_uEncryptedKeySize > ENCRYPTED_KEY_SIZE) {
+                       SLOGF("[%s][%d] (SS_RET_INVALID_FILE) content key size is = %d",
+                                       __FUNCTION__,
+                                       __LINE__,
+                                       m_file_content.m_uEncryptedKeySize);
+                       return SS_RET_INVALID_FILE;
+               }
+
+               SLOGI("[%s][%d] Content key size is = %d",
+                               __FUNCTION__,
+                               __LINE__,
+                               m_file_content.m_uEncryptedKeySize);
+
+               SLOGI("[%s][%d] Decrypting content key", __FUNCTION__, __LINE__);
+       }
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+int secure_file::serialize_data(unsigned char** buffer,
+    unsigned int& ret_size) {
+#ifdef _SECOS_SIM_
+       *buffer = (unsigned char*)OsaMalloc(m_write_data_size);
+    if (NULL == buffer) {
+               //SLOGE("fail to alloc memory for data.");
+               return SS_RET_MALLOC_FAILED;
+       }
+    
+       memcpy(*buffer, m_write_data, m_write_data_size);
+       ret_size = m_write_data_size;
+       return SS_RET_SUCCESS;
+#else
+
+       unsigned char* data = NULL;
+       *buffer = NULL;
+       ret_size = 0;
+
+       int buf_size = m_file_content.m_uFileHeaderSize;
+       buf_size += m_file_content.m_uKeyMaterialSize;
+       buf_size += m_file_content.m_uFileContentSize;
+       buf_size += m_file_content.m_uHashMaterialSize;
+
+       if (m_file_content.m_pFileHeader[5] == 1) {
+               buf_size += ENCRYPTED_KEY_SIZE;
+       }
+
+       data = (unsigned char*)OsaMalloc(buf_size + 1);
+       if (NULL == data) {
+               SLOGE("fail to alloc memory for data.");
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       unsigned char* ptr = data;
+       switch (FileStructureType(m_file_content.m_pFileHeader)) {
+               case 0: {
+                       // [header][hash][data][key]
+                       memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
+                       ptr += HEADER_SIZE;
+                       memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
+                       ptr += HASH_SIZE;
+                       memcpy(ptr,
+                                       m_file_content.m_pFileContent,
+                                       m_file_content.m_uFileContentSize);
+                       ptr += m_file_content.m_uFileContentSize;
+                       memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
+                       ptr += KEY_MAT_SIZE;
+                       break;
+               }
+               case 1: {
+                       // [header][hash][key][data]
+                       memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
+                       ptr += HEADER_SIZE;
+                       memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
+                       ptr += HASH_SIZE;
+                       memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
+                       ptr += KEY_MAT_SIZE;
+                       memcpy(ptr,
+                                       m_file_content.m_pFileContent,
+                                       m_file_content.m_uFileContentSize);
+                       ptr += m_file_content.m_uFileContentSize;
+                       break;
+               }
+               case 2: {
+                       // [header][data][key][hash]
+                       memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
+                       ptr += HEADER_SIZE;
+                       memcpy(ptr,
+                                       m_file_content.m_pFileContent,
+                                       m_file_content.m_uFileContentSize);
+                       ptr += m_file_content.m_uFileContentSize;
+                       memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
+                       ptr += KEY_MAT_SIZE;
+                       memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
+                       ptr += HASH_SIZE;
+                       break;
+               }
+               case 3: {
+                       // [header][key][data][hash]
+                       memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
+                       ptr += HEADER_SIZE;
+                       memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
+                       ptr += KEY_MAT_SIZE;
+                       memcpy(ptr,
+                                       m_file_content.m_pFileContent,
+                                       m_file_content.m_uFileContentSize);
+                       ptr += m_file_content.m_uFileContentSize;
+                       memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
+                       ptr += HASH_SIZE;
+                       break;
+               }
+               case 4: {
+                       // [header][key][hash][data]
+                       memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
+                       ptr += HEADER_SIZE;
+                       memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
+                       ptr += KEY_MAT_SIZE;
+                       memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
+                       ptr += HASH_SIZE;
+                       memcpy(ptr,
+                                       m_file_content.m_pFileContent,
+                                       m_file_content.m_uFileContentSize);
+                       ptr += m_file_content.m_uFileContentSize;
+                       break;
+               }
+               case 5: {
+                       // [header][data][hash][key]
+                       memcpy(ptr, m_file_content.m_pFileHeader, HEADER_SIZE);
+                       ptr += HEADER_SIZE;
+                       memcpy(ptr,
+                                       m_file_content.m_pFileContent,
+                                       m_file_content.m_uFileContentSize);
+                       ptr += m_file_content.m_uFileContentSize;
+                       memcpy(ptr, m_file_content.m_pHashMaterial, HASH_SIZE);
+                       ptr += HASH_SIZE;
+                       memcpy(ptr, m_file_content.m_pKeyMaterial, KEY_MAT_SIZE);
+                       ptr += KEY_MAT_SIZE;
+                       break;
+               }
+               default: {
+                       SLOGD("[%s][%d](SS_RET_FAIL) OUT OF THE FileStructureType : %d",
+                                       __FUNCTION__,
+                                       __LINE__,
+                                       FileStructureType(m_file_content.m_pFileHeader));
+                       delete data;
+                       return SS_RET_FAIL;
+               }
+               break;
+       }
+
+       if (m_file_content.m_pFileHeader[5] == 1) {
+               SLOGI("[%s][%d] Writing encrypted key", __FUNCTION__, __LINE__);
+               memcpy(ptr, m_file_content.m_EncryptedKeyBuffer, ENCRYPTED_KEY_SIZE);
+       }
+
+       *buffer = data;
+       ret_size = buf_size;
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+int secure_file::write_temp_store(unsigned char* data, unsigned int size) {
+       if (-1 == m_cache->write(m_full_path, data, size)) {
+               SLOGI("[%s][%d] Writing to cache storage failed.", __FUNCTION__, __LINE__);
+               delete data;
+               return SS_RET_FAIL;
+       }
+
+       delete data;
+       return SS_RET_SUCCESS;
+}
+
+int secure_file::write_persistent_store(unsigned char* data,
+    unsigned int size) {
+#ifdef _SECOS_SIM_
+       char filename[256] = {0};
+       get_data_name(filename, false);
+       int iRet = file_op::write_file(filename, data, size);
+       OsaFree(data);
+       return iRet;
+#else
+       shm_manager shm_mgr;
+       if (-1 == shm_mgr.init())
+       {
+               SLOGE("Failed to init shm manager.");
+               return SS_RET_COMM_ERR;
+       }
+
+       swdss_request req;
+       req.type = REQ_WRITE;
+       memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
+       req.data = data;
+       req.data_size = size;
+
+       SLOGE("Data size = %d.", size);
+
+       shm_mgr.lock();
+       shm_mgr.put_request(&req);
+       OsaFree(data);
+
+       if (-1 == call_ta_service())
+       {
+               SLOGE("Failed to call ta service.");
+               return SS_RET_COMM_ERR;
+       }
+
+       swdss_response rsp;
+       shm_mgr.get_response(&rsp);
+
+       return rsp.retcode;
+#endif
+}
+
+int secure_file::read_temp_store(unsigned char** buffer,
+    unsigned int& ret_size) {
+       if (0 != m_cache->read(m_full_path, buffer, ret_size)) {
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+int secure_file::read_persistent_store(unsigned char** buffer,
+    unsigned int& ret_size) {
+#ifdef _SECOS_SIM_
+       char filename[256] = {0};
+       get_data_name(filename, false);
+       return file_op::read_file(filename, buffer, ret_size);
+#else
+
+       shm_manager shm_mgr;
+       if (-1 == shm_mgr.init())
+       {
+               SLOGE("Failed to init shm manager.");
+               return SS_RET_COMM_ERR;
+       }
+
+       swdss_request req;
+       req.type = REQ_READ;
+       memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
+       req.data = NULL;
+       req.data_size = 0;
+
+       shm_mgr.lock();
+       shm_mgr.put_request(&req);
+
+       if (-1 == call_ta_service())
+       {
+               SLOGE("Failed to call ta service.");
+               return SS_RET_COMM_ERR;
+       }
+
+       swdss_response rsp;
+       shm_mgr.get_response(&rsp);
+
+       if (SS_RET_SUCCESS != rsp.retcode)
+       {
+               return rsp.retcode;
+       }
+
+       *buffer = rsp.data;
+       ret_size = rsp.data_size;
+
+       SLOGI("ret_size = %d", ret_size);
+
+       return SS_RET_SUCCESS;
+
+#endif
+}
+
+int secure_file::remove_persistent_store(bool is_dir) {
+#ifdef _SECOS_SIM_
+       char filename[256] = {0};
+       get_data_name(filename, is_dir);
+       int iret = SS_RET_SUCCESS;
+       if (is_dir) {
+               iret = file_op::remove_folder(filename);
+       } else {
+               iret = file_op::remove_file(filename);
+       }
+
+       return iret;
+
+#else
+
+       shm_manager shm_mgr;
+       if (-1 == shm_mgr.init())
+       {
+               SLOGE("Failed to init shm manager.");
+               return SS_RET_COMM_ERR;
+       }
+
+       swdss_request req;
+       req.type = is_dir ? REQ_BATCH_REMOVE: REQ_REMOVE;
+       memcpy(req.data_name, m_full_path, SS_FULL_DATA_NAME_LEN);
+       req.data = NULL;
+       req.data_size = 0;
+
+       shm_mgr.lock();
+       shm_mgr.put_request(&req);
+
+       if (-1 == call_ta_service())
+       {
+               SLOGE("Failed to call ta service.");
+               return SS_RET_COMM_ERR;
+       }
+
+       swdss_response rsp;
+       shm_mgr.get_response(&rsp);
+
+       return rsp.retcode;
+#endif
+}
+
+int secure_file::check_file_content() {
+#ifdef _SECOS_SIM_
+       return 0;
+#else
+
+       // compute file hash
+       CBT_OCTET computed_hash[CCryptoEngine::Hash_Size];
+       compute_file_hash(computed_hash);
+
+       CBT_OCTET* stored_hash;
+       stored_hash = m_file_content.m_pHashMaterial;
+
+       if (memcmp(computed_hash, stored_hash, CCryptoEngine::Hash_Size)) {
+               SLOGD("[%s][%d](SS_RET_INVALID_FILE) Hash is DIFFERENT!!!",
+                               __FUNCTION__,
+                               __LINE__);
+               return SS_RET_INVALID_FILE;
+       }
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+int secure_file::decrypt_data() {
+#ifdef _SECOS_SIM_
+       m_file_content.m_pOutputContentSize = m_read_data_size;
+       m_file_content.m_pOutputContent = m_read_data;
+       m_read_data = NULL;
+       return 0;
+#else
+
+       if (m_use_crypted_key) {
+               int ret;
+               unsigned long uDecryptedKeySize;
+               SLOGI("[%s][%d] Decrypting content key", __FUNCTION__, __LINE__);
+
+               ret = CCryptoEngine::RSADecrypt(m_file_content.m_EncryptedKeyBuffer,
+                               &uDecryptedKeySize,
+                               m_file_content.m_pEncryptedKey + 4,
+                               m_file_content.m_uEncryptedKeySize,
+                               m_rsa_key.rsa_n_data,
+                               m_rsa_key.rsa_n_len,
+                               m_rsa_key.rsa_d_data,
+                               m_rsa_key.rsa_d_len);
+
+               if (CRYPTO_SUCCESS != ret) {
+                       SLOGF("[%s][%d](SS_RET_FAIL) RSADecrypt failed!", __FUNCTION__, __LINE__);
+                       return SS_RET_FAIL;
+               }
+
+               // content key size shall be exactly as expected
+               if (uDecryptedKeySize != (unsigned long)(CCryptoEngine::Key_Size)) {
+                       SLOGF("[%s][%d](SS_RET_INVALID_FILE) Contexct key size is wrong %lu",
+                                       __FUNCTION__,
+                                       __LINE__,
+                                       uDecryptedKeySize);
+                       return SS_RET_INVALID_FILE;
+               }
+
+               m_file_content.m_pOutputContentSize =
+               DecryptEx(m_file_content.m_pOutputContent,
+                               m_file_content.m_pFileContent,
+                               m_file_content.m_uFileContentSize,
+                               m_file_content.m_EncryptedKeyBuffer);
+
+               if (0 == m_file_content.m_pOutputContentSize) {
+                       SLOGD("[%s][%d](ERROR) TZ Can't DEcrypt data WITH EncryptedKey mode (0 == m_file_content.m_pOutputContentSize)",
+                                       __FUNCTION__,
+                                       __LINE__);
+                       SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
+                       return SS_RET_INTERNAL_ERROR;
+               }
+       } else {
+               m_file_content.m_pOutputContentSize =
+               Decrypt(m_file_content.m_pOutputContent,
+                               m_file_content.m_pFileContent,
+                               m_file_content.m_uFileContentSize,
+                               m_file_content.m_pKeyMaterial,
+                               m_options);
+
+               if (0 == m_file_content.m_pOutputContentSize) {
+                       SLOGD("[%s][%d](ERROR) TZ Can't DEcrypt data WITHOUT EncryptedKey mode (0 == m_file_content.m_pOutputContentSize)",
+                                       __FUNCTION__,
+                                       __LINE__);
+                       SLOGF("[%s][%d](ERROR)", __FUNCTION__, __LINE__);
+                       return SS_RET_INTERNAL_ERROR;
+               }
+       }
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+secure_file::~secure_file() {
+       (void)finalize();
+}
+
+int secure_file::prepare_data(unsigned char** ret_buf, unsigned int * ret_size,
+    unsigned char* buffer, unsigned int buf_size, unsigned int offset) {
+       // if partial rw is not enabled.
+       if (!(m_options & SS_OPT_PARTIAL_RW)) {
+               *ret_buf = buffer;
+               *ret_size = buf_size;
+               return SS_RET_SUCCESS;
+       }
+
+       //partial write, read data first
+       m_is_partial_write = true;
+       unsigned char* data = NULL;
+       unsigned char* orig_data = NULL;
+       unsigned int ori_size = 0xffff;
+
+       bool tmp_flag = m_use_crypted_key;
+       m_use_crypted_key = false;
+       int iRet = read(&orig_data, &ori_size, 0);
+       m_use_crypted_key = tmp_flag;
+
+       if (SS_RET_SUCCESS != iRet) {
+               // data not exist and offset=0, new data entry is created.
+               if ((SS_RET_CANT_FIND_REQUESTED_DATA == iRet) && (0 == offset)) {
+                       *ret_buf = buffer;
+                       *ret_size = buf_size;
+                       m_is_partial_write = false;
+                       return SS_RET_SUCCESS;
+               }
+
+               SLOGF("[%s][%d]Read data for partial write failed.", __FUNCTION__,
+                   __LINE__);
+               return iRet;
+       }
+
+       if (offset > ori_size) {
+               SLOGF("[%s][%d]offset(%d) exceed data size(%d).", __FUNCTION__, __LINE__,
+                   offset, ori_size);
+               OsaFree(orig_data);
+               return SS_RET_OFFSET_ERR;
+       }
+
+       unsigned int add_size =
+           (offset + buf_size) > ori_size ? (offset + buf_size - ori_size) : 0;
+       data = (unsigned char*)OsaMalloc(ori_size + add_size);
+       if (NULL == data) {
+               SLOGF("[%s][%d]Failed to alloc memory for data.", __FUNCTION__, __LINE__);
+               OsaFree(orig_data);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       unsigned char* dest = data;
+       memcpy(dest, orig_data, offset);
+       dest += offset;
+       memcpy(dest, buffer, buf_size);
+       dest += buf_size;
+
+       if (0 == add_size) {
+               memcpy(dest, orig_data + offset + buf_size, ori_size - offset - buf_size);
+       }
+
+       *ret_buf = data;
+       *ret_size = ori_size + add_size;
+       OsaFree(orig_data);
+
+       return SS_RET_SUCCESS;
+}
+
+int secure_file::write(unsigned char* buffer, unsigned int buf_size,
+    unsigned int offset) {
+       SLOGE("Entering secure_file::write, buf_size = %d.", buf_size);
+
+       if ((NULL == buffer) || ('\0' == m_data_name[0]) || (0 == buf_size)) {
+               SLOGE("[%s] input param error.\n", __FUNCTION__);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
+               return SS_RET_INVALID_DATA_NAME;
+       }
+
+       if (SS_MAX_DATA_SIZE < buf_size) {
+               return SS_RET_DATA_SIZE_IS_TOO_BIG;
+       }
+
+       memset(&m_file_content, 0, sizeof(m_file_content));
+
+       int iRet = prepare_data(&m_write_data, &m_write_data_size, buffer, buf_size,
+           offset);
+       if (SS_RET_SUCCESS != iRet) {
+               SLOGF("[%s][%d]Failed to prepare data.", __FUNCTION__, __LINE__);
+               return iRet;
+       }
+
+       SLOGE(" prepare_data data size = %d.", m_write_data_size);
+
+       if (SS_MAX_DATA_SIZE < m_write_data_size) {
+               SLOGF("[%s][%d]Data size %d is too big.", __FUNCTION__, __LINE__,
+                   m_write_data_size);
+               return SS_RET_DATA_SIZE_IS_TOO_BIG;
+       }
+
+       // generating new key material
+       int ret = 0;
+
+       // preparing file content for writing
+       ret = prepare_file_content(m_write_data, m_write_data_size);
+       if (ret) {
+               return ret;
+       }
+
+       // drive path
+       derive_file_path();
+
+       // serialize data
+       unsigned char* data = NULL;
+       unsigned int size = 0;
+       if (SS_RET_SUCCESS != (ret = serialize_data(&data, size))) {
+               return ret;
+       }
+
+       // write to cache
+       if (m_options & SS_OPT_TEMPORARY) {
+               return write_temp_store(data, size);
+       }
+
+       // writing data into file
+       ret = write_persistent_store(data, size);
+
+       return ret;
+}
+
+int secure_file::read(unsigned char** ret_buf, unsigned int* read_size,
+    unsigned int offset) {
+       SLOGI("Entering secure_file::read");
+
+       if (('\0' == m_data_name[0]) || (NULL == read_size)) {
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if ((m_options & SS_OPT_PARTIAL_RW) && (0 == *read_size)) {
+               SLOGE("Read zero byte data.");
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
+               return SS_RET_INVALID_DATA_NAME;
+       }
+
+       int ret = 0;
+
+       unsigned int required_size = *read_size;
+       unsigned int off_set = offset;
+       *read_size = 0;
+
+       // cleaning internal file structure representation
+       memset(&m_file_content, 0, sizeof(m_file_content));
+
+       derive_file_path();
+
+       // read from cache storage
+       if (m_options & SS_OPT_TEMPORARY) {
+               if (SS_RET_SUCCESS
+                   != (ret = read_temp_store(&m_read_data, m_read_data_size))) {
+                       SLOGE("[%s][%d](ERROR) Read data from temp store failed.", __FUNCTION__,
+                           __LINE__);
+                       return ret;
+               }
+       } else {
+               ret = read_persistent_store(&m_read_data, m_read_data_size);
+               if (ret) {
+                       return ret;
+               }
+       }
+
+       // Parsing content
+       ret = parse_file_content(m_read_data, m_read_data_size);
+       if (ret) {
+               return ret;
+       }
+
+       // checking content integrity
+       ret = check_file_content();
+       if (ret) {
+               return ret;
+       }
+
+       // decrypting data
+       ret = decrypt_data();
+       if (ret) {
+               SLOGE("[%s][%d](ERROR) DecryptData() // iRet : %d", __FUNCTION__, __LINE__,
+                   ret);
+               return ret;
+       }
+
+       // partial rw not enabled.
+       if (!(m_options & SS_OPT_PARTIAL_RW)) {
+               off_set = 0;
+               required_size = m_file_content.m_pOutputContentSize + 1;
+       }
+
+       // partial read supported
+       if (off_set >= m_file_content.m_pOutputContentSize - 1) {
+               SLOGE("[%s][%d]offset(%d) exceed data size(%d).", __FUNCTION__, __LINE__,
+                   off_set, m_file_content.m_pOutputContentSize);
+               return SS_RET_OFFSET_ERR;
+       }
+
+       // copy data
+       unsigned ret_size =
+           m_file_content.m_pOutputContentSize >= (off_set + required_size) ?
+               required_size : (m_file_content.m_pOutputContentSize - off_set);
+
+       *ret_buf = (unsigned char*)OsaMalloc(ret_size);
+       if (*ret_buf == NULL) {
+               SLOGE("[%s][%d]Failed to alloc memory.", __FUNCTION__, __LINE__);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       memcpy(*ret_buf, m_file_content.m_pOutputContent + off_set, ret_size);
+       *read_size = ret_size;
+
+       return SS_RET_SUCCESS;
+}
+
+int secure_file::write_ex(unsigned char* buffer, unsigned int buf_size,
+    unsigned int offset, const unsigned char* rsa_n_data,
+    unsigned long rsa_n_len, const unsigned char* rsa_e_data,
+    unsigned long rsa_e_len) {
+       int ret = 0;
+
+       if ((NULL == buffer) || ('\0' == m_data_name[0]) || (0 == buf_size)) {
+               SLOGE("[%s] input param error.\n", __FUNCTION__);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
+               return SS_RET_INVALID_DATA_NAME;
+       }
+
+       if (SS_MAX_DATA_SIZE < buf_size) {
+               return SS_RET_DATA_SIZE_IS_TOO_BIG;
+       }
+
+       // checking input correctness
+       if ((NULL == rsa_n_data) || (NULL == rsa_e_data) || (rsa_n_len > RSA_KEY_SIZE)
+           || (rsa_e_len > RSA_KEY_SIZE) || (rsa_e_len > rsa_n_len)) {
+               return SS_RET_INVALID_RSA_PARAM;
+       }
+
+       // initiating special mode
+       m_use_crypted_key = true;
+
+       // initializing RSA key data
+       m_rsa_key.rsa_e_data = const_cast<uint8_t*>(rsa_e_data);
+       m_rsa_key.rsa_e_len = rsa_e_len;
+       m_rsa_key.rsa_n_data = const_cast<uint8_t*>(rsa_n_data);
+       m_rsa_key.rsa_n_len = rsa_n_len;
+       m_rsa_key.rsa_d_data = NULL;
+       m_rsa_key.rsa_d_len = 0;
+
+       // writing data into file
+       ret = write(buffer, buf_size, offset);
+
+       // removing special mode
+       m_use_crypted_key = false;
+
+       return ret;
+}
+
+int secure_file::read_ex(unsigned char** ret_buf, unsigned int* read_size,
+    unsigned int offset, const unsigned char* rsa_n_data,
+    unsigned long rsa_n_len, const unsigned char* rsa_d_data,
+    unsigned long rsa_d_len) {
+       if (('\0' == m_data_name[0]) || (NULL == read_size)) {
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if ((m_options & SS_OPT_PARTIAL_RW) && (0 == *read_size)) {
+               SLOGE("Read zero byte data.");
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
+               return SS_RET_INVALID_DATA_NAME;
+       }
+
+       int ret = 0;
+
+       // initiating special mode
+       m_use_crypted_key = true;
+
+       // checking input correctness
+       if ((NULL == rsa_n_data) || (NULL == rsa_d_data) || (rsa_n_len > RSA_KEY_SIZE)
+           || (rsa_d_len > RSA_KEY_SIZE) || (rsa_d_len > rsa_n_len)) {
+               return SS_RET_INVALID_RSA_PARAM;
+       }
+
+       // initializing RSA key data
+       m_rsa_key.rsa_d_data = const_cast<uint8_t*>(rsa_d_data);
+       m_rsa_key.rsa_d_len = rsa_d_len;
+       m_rsa_key.rsa_n_data = const_cast<uint8_t*>(rsa_n_data);
+       m_rsa_key.rsa_n_len = rsa_n_len;
+       m_rsa_key.rsa_e_data = NULL;
+       m_rsa_key.rsa_e_len = 0;
+
+       // writing data into file
+       ret = read(ret_buf, read_size, offset);
+
+       // removing special mode
+       m_use_crypted_key = false;
+
+       return ret;
+}
+
+int secure_file::validate() {
+       if ('\0' == m_data_name[0]) {
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
+               return SS_RET_INVALID_DATA_NAME;
+       }
+
+       int ret = 0;
+
+       // cleaning internal file structure representation
+       memset(&m_file_content, 0, sizeof(m_file_content));
+
+       // drive path
+       derive_file_path();
+
+       // read from cache storage
+       if (m_options & SS_OPT_TEMPORARY) {
+               if (SS_RET_SUCCESS
+                   != (ret = read_temp_store(&m_read_data, m_read_data_size))) {
+                       SLOGD("[%s][%d](ERROR) Read data from temp store failed.", __FUNCTION__,
+                           __LINE__);
+                       return ret;
+               }
+       } else {
+               ret = read_persistent_store(&m_read_data, m_read_data_size);
+               if (ret) {
+                       return ret;
+               }
+       }
+
+       // Parsing content
+       ret = parse_file_content(m_read_data, m_read_data_size);
+       if (ret) {
+               return ret;
+       }
+
+       // checking content integrity
+       return check_file_content();
+}
+
+int secure_file::remove() {
+       if ('\0' == m_data_name[0]) {
+               return SS_RET_INVALID_PARAM;
+       }
+
+       if (SS_RET_SUCCESS != is_valid_data_name(m_data_name)) {
+               return SS_RET_INVALID_DATA_NAME;
+       }
+
+       derive_file_path();
+
+       if (SS_OPT_TEMPORARY & m_options) {
+               if (SS_RET_SUCCESS != m_cache->remove(m_full_path)) {
+                       SLOGE("Data file not exist, path = [%s].", m_full_path);
+                       return SS_RET_CANT_FIND_REQUESTED_DATA;
+               }
+
+               return SS_RET_SUCCESS;
+       }
+
+       return remove_persistent_store(false);
+}
+
+int secure_file::clear_storage() {
+       derive_file_path();
+
+       if (SS_OPT_TEMPORARY & m_options) {
+               return m_cache->batch_remove(m_full_path);
+       }
+
+       return remove_persistent_store(true);
+}
+
+#ifdef _SECOS_SIM_
+#define SS_CRED_LEN 36
+void secure_file::get_data_name(char* data_name, bool is_dir) {
+       uint8_t* ptr = (uint8_t*)data_name;
+       memcpy(ptr, SWD_SS_ROOT, strlen(SWD_SS_ROOT));
+       ptr += strlen(SWD_SS_ROOT);
+
+       // first 4 bytes for directory.
+       //byte_to_hex(ptr, (uint8_t*)m_full_path, 4);
+       memcpy(ptr, m_full_path, SS_CRED_LEN);
+
+       if (is_dir) {
+               return;
+       }
+
+       // next 8 bytes for filename
+       memcpy(ptr, m_full_path, strlen(m_full_path));
+       //memset(ptr, '/', 1);
+       //ptr += 1;
+       //memcpy(ptr,m_full_path+SS_CRED_LEN,)
+       //byte_to_hex(ptr, (uint8_t*)&m_full_path[4], 8);
+}
+#endif
+
diff --git a/ssflib/dep/swdss/source/ss_api.cpp b/ssflib/dep/swdss/source/ss_api.cpp
new file mode 100755 (executable)
index 0000000..d70ad7a
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#include "ss_api.h"
+#include "secure_file.h"
+#include "slog.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+int ss_init(int strategy) {
+       return 0;
+}
+
+int ss_set_credential(ss_credential_s * cred, const char* uuid,
+    const char* module_name, unsigned long major_ver, unsigned long minor_ver) {
+       if ((NULL == cred) || (NULL == uuid) || (NULL == module_name)) {
+               SLOGE("[%s] input param error.\n", __FUNCTION__);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       int uuid_size = strlen(uuid);
+       int mn_size = strlen(module_name);
+
+       if (uuid_size > SS_MAX_UUID_LEN || mn_size > SS_MAX_MODULE_NAME_LEN) {
+               SLOGE("[%s] length of uuid or module name error.\n", __FUNCTION__);
+               return SS_RET_INVALID_PARAM;
+       }
+
+       memset(cred->uuid, '\0', SS_MAX_UUID_LEN);
+       memset(cred->module_name, '\0', SS_MAX_MODULE_NAME_LEN);
+       strncpy(cred->uuid, uuid, uuid_size);
+       strncpy(cred->module_name, module_name, mn_size);
+
+       cred->version.major = major_ver;
+       cred->version.minor = minor_ver;
+
+       return SS_RET_SUCCESS;
+}
+
+int ss_write(unsigned char* buffer, unsigned int data_size, unsigned int offset,
+    const char* data_name, const ss_credential_s * cred, unsigned int options) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, data_name, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.write(buffer, data_size, offset);
+}
+
+int ss_read(unsigned char** ret_buf, unsigned int* data_size,
+    unsigned int offset, const char* data_name, const ss_credential_s * cred,
+    unsigned int options) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, data_name, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.read(ret_buf, data_size, offset);
+}
+
+int ss_write_ex(unsigned char* buffer, unsigned int data_size,
+    unsigned int offset, const char* data_name, const ss_credential_s* cred,
+    unsigned int options, const unsigned char* rsa_n_data,
+    unsigned long rsa_n_len, const unsigned char* rsa_e_data,
+    unsigned long rsa_e_len) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, data_name, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.write_ex(buffer, data_size, offset, rsa_n_data, rsa_n_len,
+           rsa_e_data, rsa_e_len);
+}
+
+int ss_read_ex(unsigned char** ret_buf, unsigned int* data_size,
+    unsigned int offset, const char* data_name, const ss_credential_s* cred,
+    unsigned int options, const unsigned char* rsa_n_data,
+    unsigned long rsa_n_len, const unsigned char* rsa_d_data,
+    unsigned long rsa_d_len) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, data_name, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.read_ex(ret_buf, data_size, offset, rsa_n_data, rsa_n_len,
+           rsa_d_data, rsa_d_len);
+}
+
+int ss_validate(const char* data_name, const ss_credential_s* cred,
+    unsigned int options) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, data_name, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.validate();
+}
+
+int ss_delete(const char* data_name, const ss_credential_s* cred,
+    unsigned int options) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, data_name, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.remove();
+}
+
+int ss_clear_storage(const ss_credential_s* cred, unsigned int options) {
+       secure_file sec_file;
+       int ret = sec_file.initialize(cred, NULL, options);
+       if (SS_RET_SUCCESS != ret) {
+               return ret;
+       }
+
+       return sec_file.clear_storage();
+}
+
+int ss_free_buffer(unsigned char* buffer) {
+       if (NULL != buffer) {
+               OsaFree(buffer);
+       }
+
+       return SS_RET_SUCCESS;
+}
+#ifdef  __cplusplus
+}
+#endif
+
diff --git a/ssflib/dep/swdss/source/ss_crypto.cpp b/ssflib/dep/swdss/source/ss_crypto.cpp
new file mode 100755 (executable)
index 0000000..dc1d820
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#include "ss_crypto.h"
+
+static CBT_UINT32 lcg_last; /* Storing the last used LCG value */
+
+void seed_rand(CBT_UINT32 seed) {
+       lcg_last = seed;
+}
+
+CBT_UINT32 gen_rand(void) {
+       return (lcg_last = lcg_last * lcg_A + lcg_C);
+}
+
+void gen_rand_vec(CBT_OCTET* vec, CBT_UINT32 size) {
+       CBT_UINT32 i;
+
+       seed_rand((CBT_UINT32)time(NULL));
+       for (i = 0; i < size; i++) {
+               vec[i] = (CBT_OCTET)(gen_rand() % 256);
+       }
+}
+
+/**
+ * @brief    Encrypt provided data
+ */
+int CCryptoEngine::Encrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
+    const uint8_t* key, unsigned long key_type) {
+       //memcpy(dest,src,data_len);
+       //return data_len;
+       unsigned int cipherTextLen, t;
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
+
+       crt->SE_init(crt, ID_ENC_CTR, ID_PKCS5, const_cast<uint8_t*>(key), 16,
+           (cc_u8*)NULL);
+       crt->SE_process(crt, src, data_len, dest,
+           static_cast<cc_u32*>(&cipherTextLen));
+       crt->SE_final(crt, (cc_u8*)NULL, 0, (dest + cipherTextLen),
+           static_cast<cc_u32*>(&t));
+       cipherTextLen += t;
+       destroy_CryptoCoreContainer(crt);
+
+       return cipherTextLen;
+}
+
+/**
+ * @brief    Decrypt provided data
+ */
+int CCryptoEngine::Decrypt(uint8_t* dest, uint8_t* src, unsigned long data_len,
+    const uint8_t* key, unsigned long key_type) {
+       unsigned int plainTextLen, t;
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_AES);
+       crt->SE_init(crt, ID_DEC_CTR, ID_PKCS5, const_cast<uint8_t*>(key), 16,
+           (cc_u8*)NULL);
+       crt->SE_process(crt, src, data_len - 16, dest,
+           static_cast<cc_u32*>(&plainTextLen));
+       crt->SE_final(crt, src + data_len - 16, 16, (uint8_t*)(dest + plainTextLen),
+           static_cast<cc_u32*>(&t));
+       destroy_CryptoCoreContainer(crt);
+       plainTextLen += t;
+       return plainTextLen;
+}
+
+/**
+ * @brief    Compute hash value over provided data
+ */
+int CCryptoEngine::Hash(uint8_t* dest, const uint8_t* src,
+    unsigned long data_len) {
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_SHA1);
+       crt->MD_init(crt);
+       crt->MD_update(crt, static_cast<cc_u8*>((void*)const_cast<uint8_t*>(src)),
+           data_len);
+       crt->MD_final(crt, (uint8_t*)dest);
+       destroy_CryptoCoreContainer(crt);
+       return 0;
+}
+
+/**
+ * @brief    Generating random number
+ */
+int CCryptoEngine::Random(uint8_t* dest, unsigned long data_len) {
+       CryptoCoreContainer *crt = create_CryptoCoreContainer(ID_X931);
+       crt->PRNG_seed(crt, (cc_u8*)NULL);
+       crt->PRNG_get(crt, data_len * 8, (uint8_t*)dest);
+       destroy_CryptoCoreContainer(crt);
+       return 0;
+}
+
+/**
+ * @brief    Encrypt provided data by using HW based encryption engine
+ */
+int CCryptoEngine::HWEncrypt(unsigned char* dest, unsigned long* dest_len,
+    unsigned char* src, unsigned long data_len, const unsigned char* key,
+    unsigned long key_type, unsigned long mode) {
+#if defined(_SECOS_SIM_)
+       *dest_len = Encrypt(dest, src, data_len, key, key_type);
+       return SS_RET_SUCCESS;
+#else
+
+       UCI_HANDLE uh = UCI_ERROR;
+       uh = uci_context_alloc(ID_UCI_AES128,(uci_engine_config_e)key_type);
+       if ((UCI_ERROR == uh) || (UCI_MEM_ALLOR_ERROR == uh))
+       {
+               SLOGE("Failed to alloc uci context handle.\n");
+               return SS_RET_FAIL;
+       }
+
+       int ret = 0;
+
+       switch (mode)
+       {
+               case ID_UCI_ENC_CTR:
+               {
+                       ret = uci_se_init(uh,ID_UCI_ENC_CTR,ID_UCI_NO_PADDING,(unsigned char*)key,16,NULL);
+                       break;
+               }
+               case ID_UCI_ENC_ECB:
+               {
+                       ret = uci_se_init(uh,ID_UCI_ENC_ECB,ID_UCI_PKCS5,(unsigned char*)key,16,NULL);
+                       break;
+               }
+               default:
+               {
+                       SLOGE("Mode %d not supported.",mode);
+                       uci_context_free(uh);
+                       return SS_RET_INVALID_PARAM;
+               }
+       }
+
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to init context, retcode = %d.\n",ret);
+               uci_context_free(uh);
+               return SS_RET_FAIL;
+       }
+
+       ret = uci_se_process(uh,src,data_len,dest,(unsigned int*)dest_len);
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to encrypt data, retcode = %d.\n",ret);
+               uci_context_free(uh);
+               return SS_RET_FAIL;
+       }
+
+       unsigned int t;
+       ret = uci_se_final(uh,NULL,0,dest+(*dest_len),&t);
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to call uci_se_final, retcode = %d.\n",ret);
+               uci_context_free(uh);
+               return SS_RET_FAIL;
+       }
+
+       *dest_len += t;
+
+       ret = uci_context_free(uh);
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to free context, retcode = %d.\n",ret);
+       }
+
+       return SS_RET_SUCCESS;
+#endif
+}
+
+/**
+ * @brief    Decrypt provided data
+ */
+int CCryptoEngine::HWDecrypt(unsigned char* dest, unsigned long* dest_len,
+    unsigned char* src, unsigned long data_len, const unsigned char* key,
+    unsigned long key_type, unsigned long mode) {
+#if !defined(_SECOS_SIM_)
+       UCI_HANDLE uh = UCI_ERROR;
+       uh = uci_context_alloc(ID_UCI_AES128,(uci_engine_config_e)key_type);
+       if ((UCI_ERROR == uh) || (UCI_MEM_ALLOR_ERROR == uh))
+       {
+               SLOGE("Failed to alloc uci context handle.");
+               return SS_RET_FAIL;
+       }
+
+       int ret = 0;
+
+       switch (mode)
+       {
+               case ID_UCI_ENC_CTR:
+               {
+                       ret = uci_se_init(uh,ID_UCI_DEC_CTR,ID_UCI_NO_PADDING,(unsigned char*)key,16,NULL);
+                       break;
+               }
+               case ID_UCI_ENC_ECB:
+               {
+                       ret = uci_se_init(uh,ID_UCI_DEC_ECB,ID_UCI_PKCS5,(unsigned char*)key,16,NULL);
+                       break;
+               }
+               default:
+               {
+                       SLOGE("Mode %d not supported.",mode);
+                       return SS_RET_INVALID_PARAM;
+               }
+       }
+
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to init context, retcode = %d.",ret);
+               uci_context_free(uh);
+               return SS_RET_FAIL;
+       }
+
+       ret = uci_se_process(uh,src,data_len-16,dest,(unsigned int*)dest_len);
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to decrypt data, retcode = %d.",ret);
+               uci_context_free(uh);
+               return SS_RET_FAIL;
+       }
+
+       unsigned int t;
+       ret = uci_se_final(uh,src+data_len-16,16,dest+(*dest_len),&t);
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to call uci_se_final, retcode = %d.",ret);
+               uci_context_free(uh);
+               return SS_RET_FAIL;
+       }
+
+       *dest_len += t;
+
+       ret = uci_context_free(uh);
+       if (UCI_SUCCESS != ret)
+       {
+               SLOGE("Failed to free context, retcode = %d.",ret);
+       }
+
+       return SS_RET_SUCCESS;
+
+#else
+       return SS_RET_SUCCESS;
+#endif
+}
+
+/**
+ * @brief    Encrypting data by using RSA pub key
+ */
+int CCryptoEngine::RSAEncrypt(uint8_t* dest, unsigned long* dest_len,
+    const uint8_t* src, unsigned long src_len, const uint8_t* RSA_N_Data,
+    unsigned long RSA_N_Len, const uint8_t* RSA_E_Data,
+    unsigned long RSA_E_Len) {
+       int ret;
+       cc_u32 result_size;
+       CryptoCoreContainer* ccContainerRSA;
+       ccContainerRSA = create_CryptoCoreContainer(ID_RSA2048);
+
+       /* seting RSA key for AES key encryption */
+       ret = ccContainerRSA->RSA_setKeypair(ccContainerRSA, ID_RSAES_PKCS15,
+           const_cast<uint8_t*>(RSA_N_Data), RSA_N_Len,
+           const_cast<uint8_t*>(RSA_E_Data), RSA_E_Len, (cc_u8*)NULL, 0);
+       if (CRYPTO_SUCCESS != ret) {
+               destroy_CryptoCoreContainer(ccContainerRSA);
+               return ret;
+       }
+
+       /* encrypting AES key */
+       ret = ccContainerRSA->AE_encrypt(ccContainerRSA, const_cast<uint8_t*>(src),
+           src_len, dest, &result_size);
+       *dest_len = result_size;
+
+       destroy_CryptoCoreContainer(ccContainerRSA);
+
+       return ret;
+}
+
+/**
+ * @brief    Encrypting data by using RSA pub key
+ */
+int CCryptoEngine::RSADecrypt(uint8_t* dest, unsigned long* dest_len,
+    const uint8_t* src, unsigned long src_len, const uint8_t* RSA_N_Data,
+    unsigned long RSA_N_Len, const uint8_t* RSA_D_Data,
+    unsigned long RSA_D_Len) {
+       int ret;
+       cc_u32 result_size;
+       CryptoCoreContainer* ccContainerRSA;
+       ccContainerRSA = create_CryptoCoreContainer(ID_RSA2048);
+
+       /* seting RSA key for AES key encryption */
+       ret = ccContainerRSA->RSA_setKeypair(ccContainerRSA, ID_RSAES_PKCS15,
+           const_cast<uint8_t*>(RSA_N_Data), RSA_N_Len, (cc_u8*)NULL, 0,
+           const_cast<uint8_t*>(RSA_D_Data), RSA_D_Len);
+       if (CRYPTO_SUCCESS != ret) {
+               destroy_CryptoCoreContainer(ccContainerRSA);
+               return ret;
+       }
+
+       /* encrypting AES key */
+       ret = ccContainerRSA->AE_decrypt(ccContainerRSA, const_cast<uint8_t*>(src),
+           src_len, dest, &result_size);
+       *dest_len = result_size;
+
+       destroy_CryptoCoreContainer(ccContainerRSA);
+
+       return ret;
+}
+
diff --git a/ssflib/dep/swdss/source/ss_misc.cpp b/ssflib/dep/swdss/source/ss_misc.cpp
new file mode 100755 (executable)
index 0000000..78dc64d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+#include "ss_misc.h"
+#include <string.h>
+
+void byte_to_hex(uint8_t* dest, const uint8_t* src, unsigned long src_len) {
+       char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
+           'c', 'd', 'e', 'f'};
+
+       for (unsigned long j = 0; j < src_len; j++) {
+               dest[j * 2] = hexval[((src[j] >> 4) & 0xF)];
+               dest[(j * 2) + 1] = hexval[(src[j]) & 0x0F];
+       }
+}
+
+//3d3ee6d8
+void hex_to_byte(uint8_t* dest, const uint8_t* src, unsigned long src_len) {
+       char x = 0;
+       for (unsigned long j = 0; j < src_len; j++) {
+               if (src[j] >= '0' && src[j] <= '9') {
+                       x = src[j] - '0';
+               }
+
+               if (src[j] >= 'a' && src[j] <= 'f') {
+                       x = src[j] - 'a' + 10;
+               }
+
+               if (0 == j % 2) {
+                       dest[j / 2] = (x << 4) & 0xF0;
+               } else {
+                       dest[j / 2] |= x;
+               }
+       }
+}
+
+int is_hex(const char* text, char sep) {
+       for (uint32_t i = 0; i < strlen(text); ++i) {
+               if ((text[i] >= '0' && text[i] <= '9') || (text[i] >= 'a' && text[i] <= 'f')
+                   || (text[i] == sep)) {
+                       continue;
+               } else {
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
diff --git a/ssflib/dep/swdss/source/ss_temp_store.cpp b/ssflib/dep/swdss/source/ss_temp_store.cpp
new file mode 100755 (executable)
index 0000000..4d19920
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+#include "ss_temp_store.h"
+#include "slog.h"
+
+#define SS_NODE_ID_CMP(id1, id2) memcmp(static_cast<void*>(id1),static_cast<void*>(id2),SS_NODE_ID_LEN)
+#define SS_NODE_ID_CPY(dest,src) memcpy(static_cast<void*>(dest),static_cast<void*>(src),SS_NODE_ID_LEN)
+
+pthread_mutex_t auto_lock::m_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+ss_temp_store* ss_temp_store::m_instance = NULL;
+
+ss_temp_store* ss_temp_store::get_instance() {
+       if (NULL == m_instance) {
+               auto_lock lock;
+               if (NULL == m_instance) {
+                       m_instance = new ss_temp_store;
+               }
+       }
+
+       return m_instance;
+}
+
+int ss_temp_store::read(char* data_name, unsigned char** data,
+    unsigned int& data_size) {
+       auto_lock lock;
+
+       temp_ss_node* node = find_node(data_name);
+
+       if (NULL == node) {
+               SLOGE("Data not found.");
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+
+       *data = (unsigned char*)OsaMalloc(node->data_size);
+       if (NULL == *data) {
+               SLOGE("Failed to malloc data.");
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       memcpy(*data, node->data, node->data_size);
+       data_size = node->data_size;
+
+       SLOGI("Data read size :%d.", data_size);
+
+       return SS_RET_SUCCESS;
+}
+
+int ss_temp_store::write(char* data_name, unsigned char* data,
+    unsigned int data_size) {
+       auto_lock lock;
+
+       temp_ss_node* node = find_node(data_name);
+       if (NULL != node) {
+               OsaFree(node->data);
+               node->data = (unsigned char*)OsaMalloc(data_size);
+               if (NULL == node->data) {
+                       SLOGE("Failed to malloc data.");
+                       return SS_RET_MALLOC_FAILED;
+               }
+
+               memcpy(node->data, data, data_size);
+               node->data_size = data_size;
+               return SS_RET_SUCCESS;
+       }
+
+       node = new temp_ss_node;
+       if (NULL == node) {
+               SLOGE("Failed to malloc memory.");
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       SS_NODE_ID_CPY(node->node_id, data_name);
+
+       node->data = (unsigned char*)OsaMalloc(data_size);
+       if (NULL == node->data) {
+               SLOGE("Failed to malloc data.");
+               OsaFree(node);
+               return SS_RET_MALLOC_FAILED;
+       }
+
+       memcpy(node->data, data, data_size);
+       node->data_size = data_size;
+
+       if (NULL == m_head.next) {
+               m_head.next = node;
+               node->prev = &m_head;
+               node->next = NULL;
+       } else {
+               node->next = m_head.next;
+               node->prev = &m_head;
+               m_head.next->prev = node;
+               m_head.next = node;
+       }
+
+       return SS_RET_SUCCESS;
+}
+
+int ss_temp_store::remove(char* data_name) {
+       auto_lock lock;
+
+       temp_ss_node* node = find_node(data_name);
+       if (NULL == node) {
+               SLOGE("Data not found.");
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+
+       del_node(node);
+
+       return SS_RET_SUCCESS;
+}
+
+int ss_temp_store::batch_remove(char* dir) {
+       auto_lock lock;
+
+       if (NULL == m_head.next) {
+               SLOGI("ss temp storage is empty.");
+               return SS_RET_CANT_FIND_REQUESTED_DATA;
+       }
+
+       temp_ss_node* node = m_head.next;
+       int data_find = 0;
+       while (NULL != node) {
+               // is dir the same, dir len is 4 byte.
+               if (0 == memcmp(node->node_id, dir, 4)) {
+                       node = del_node(node);
+                       data_find = 1;
+                       continue;
+               }
+
+               node = node->next;
+       }
+
+       return (data_find ? SS_RET_SUCCESS : SS_RET_CANT_FIND_REQUESTED_DATA);
+
+}
+
+temp_ss_node* ss_temp_store::find_node(char* data_name) {
+       if (NULL == m_head.next) {
+               SLOGI("ss temp storage is empty.");
+               return NULL;
+       }
+
+       temp_ss_node* node = m_head.next;
+       while (NULL != node) {
+               if (0 == SS_NODE_ID_CMP(node->node_id, data_name)) {
+                       break;
+               }
+
+               node = node->next;
+       }
+
+       return node;
+}
+
+temp_ss_node* ss_temp_store::del_node(temp_ss_node* node) {
+       if (NULL == node) {
+               return NULL;
+       }
+
+       temp_ss_node* ret_node = node->next;
+
+       if (node->data) {
+               OsaFree(node->data);
+       }
+
+       node->prev->next = node->next;
+       if (NULL != node->next) {
+               node->next->prev = node->prev;
+       }
+
+       delete node;
+
+       return ret_node;
+}
+
diff --git a/ssflib/dep/time/ssf_time.cpp b/ssflib/dep/time/ssf_time.cpp
new file mode 100755 (executable)
index 0000000..105cdfc
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_time.cpp
+ *
+ *    Description:  SSF time functions
+ *
+ *        Version:  1.0
+ *        Created:  30 June 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Cheryl (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <time.h>
+#include <log.h>
+#include <unistd.h>
+#include <string.h>
+#include "tee_internal_api.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+bool isSetReqTaSpec = false;
+TEE_Time reqTaTime;
+TEE_Time reeTaTime;
+TEE_Time teeTaTime;
+
+/*-----------------------------------------------------------------------------
+ *  TEE API Implementation
+ *-----------------------------------------------------------------------------*/
+/**
+ * The TEE_GetSystemTime function retrieves the current system time.
+ * The system time has an arbitrary implementation-defined origin that can
+ * vary across TA instances. The minimum guarantee is that the system time
+ * MUST be monotonic for a given TA instance.
+ * @param time Filled with the number of seconds and milliseconds since
+ *                                              midnight on January 1, 1970, UTC
+ */
+void TEE_GetSystemTime(TEE_Time* time) {
+       uint32_t value;
+       bool reqSrcTee = true;
+       TEE_Result result = TEE_GetPropertyAsU32(
+           (TEE_PropSetHandle)TEE_PROPSET_TEE_IMPLEMENTATION,
+           "gpd.tee.systemTime.protectionLevel", &value);
+       LOGD(SSF_LIB, "TEE_GetPropertyAsU32(systemTime.protectionLevel) : %d(ret:%d)",
+           value, result);
+       if (result == TEE_SUCCESS) if (value == 1000) /* req ree time*/
+       reqSrcTee = false;
+
+       struct timespec tspec;
+       tspec.tv_sec = 0;
+       tspec.tv_nsec = 0;
+       if (reqSrcTee == true) {
+               clock_gettime(CLOCK_REALTIME, &tspec);
+               time->seconds = tspec.tv_sec;
+               time->millis = tspec.tv_nsec / 1000000ULL;
+       } else TEE_GetREETime(time);
+}
+
+/**
+ * The TEE_Wait function waits for the specified number of milliseconds or
+ * waits forever if timeout equals TEE_TIMEOUT_INFINITE (0xFFFFFFFF).
+ * When this function returns success, the implementation MUST guarantee that
+ * the difference between two calls to TEE_GetSystemTime before and after
+ * the call to TEE_Wait is greater than or equal to the requested timeout.
+ * However, there may be additional implementation-dependent delays due to
+ * the scheduling of TEE tasks.
+ * This function is cancellable, i.e. if the current task\92s cancelled flag is
+ * set and the TA has unmasked the effects of cancellation, then this
+ * function returns earlier than the requested timeout with the return code
+ * TEE_ERROR_CANCEL. See section 4.10 for more details about cancellations.
+ * @param timeout The number of milliseconds to wait, or TEE_TIMEOUT_INFINITE
+ */
+TEE_Result TEE_Wait(uint32_t timeout) {
+       bool isNeedCancel = false;
+       uint32_t decreaseTimeoutMillis = 500;
+       uint32_t remainTimeout = timeout;
+       while (1) {
+               if (timeout != TEE_TIMEOUT_INFINITE) {
+                       remainTimeout = remainTimeout - decreaseTimeoutMillis;
+                       if (remainTimeout <= 0) break;
+               }
+               usleep(decreaseTimeoutMillis * 1000);
+               if (TEE_GetCancellationFlag()) isNeedCancel = true;
+       }
+       if (isNeedCancel == true) return TEE_ERROR_CANCEL;
+       return TEE_SUCCESS;
+}
+
+/**
+ * The _TEE_Time_To_TimeSpec function converts TEE_Time to timespec.
+ * @param dstTime Pointer to output time in timespec format
+ * @param srcTime Pointer to input time in TEE_Time format
+ */
+struct timespec* _TEE_Time_To_TimeSpec(struct timespec* dstTime,
+    TEE_Time* srcTime) {
+       dstTime->tv_sec = srcTime->seconds;
+       dstTime->tv_nsec = srcTime->millis * 1000000ULL;
+       return dstTime;
+}
+
+#if 0
+/**
+ * The _TimeSpec_To_TEE_TIME function converts timespec toTEE_Time.
+ * @param dstTime Pointer to output time in TEE_Time format
+ * @param srcTime Pointer to input time in timespec format
+ */
+TEE_Time* _TimeSpec_To_TEE_TIME(TEE_Time* dstTime, struct timespec* srcTime)
+{
+       dstTime->seconds = srcTime->tv_sec;
+       dstTime->millis = srcTime->tv_nsec / 1000000ULL;
+       return dstTime;
+}
+#endif
+
+TEE_Time* _TEE_GetAdjDiffTeeTime(TEE_Time* dstTime, TEE_Time* startTime,
+    TEE_Time* endTime) {
+       struct timespec startSpec;
+       struct timespec endSpec;
+       struct timespec dstSpec;
+       _TEE_Time_To_TimeSpec(&startSpec, startTime);
+       _TEE_Time_To_TimeSpec(&endSpec, endTime);
+       _TEE_Time_To_TimeSpec(&dstSpec, dstTime);
+
+       time_t stTt = startSpec.tv_sec + (startSpec.tv_nsec + 500000000) / 1000000000;
+       time_t endTt = endSpec.tv_sec + (endSpec.tv_nsec + 500000000) / 1000000000;
+       time_t dstTt = dstSpec.tv_sec + (dstSpec.tv_nsec + 500000000) / 1000000000;
+
+       dstTt = dstTt + endTt - stTt;
+       static TEE_Time retTt;
+       retTt.seconds = dstTt;
+       retTt.millis = 0;
+       return &retTt;
+}
+
+/**
+ * The TEE_GetTAPersistentTime function retrieves the persistent time of the
+ * Trusted Application, expressed as a number of seconds and milliseconds
+ * since the arbitrary origin set by calling TEE_SetTAPersistentTime.
+ * @param time A pointer to the TEE_Time structure to be set to the current
+ *                                              TA Persistent Time. If an error other than TEE_ERROR_OVERFLOW
+ *                                              is returned, this structure is filled with zeroes.
+ */
+TEE_Result TEE_GetTAPersistentTime(TEE_Time* time) {
+       if (isSetReqTaSpec == false) return TEE_ERROR_TIME_NOT_SET;
+
+       uint32_t value;
+       bool reqSrcTee = true;
+       TEE_Result result = TEE_GetPropertyAsU32(
+           (TEE_PropSetHandle)TEE_PROPSET_TEE_IMPLEMENTATION,
+           "gpd.tee.systemTime.protectionLevel", &value);
+       LOGD(SSF_LIB, "TEE_GetPropertyAsU32(systemTime.protectionLevel) : %d(ret:%d)",
+           value, result);
+       if (result == TEE_SUCCESS) if (value == 1000) /* req ree time*/
+       reqSrcTee = false;
+
+       TEE_Time nowTime;
+       if (reqSrcTee == true) {
+               TEE_GetSystemTime(&nowTime);
+               TEE_Time* retTime = _TEE_GetAdjDiffTeeTime(&reqTaTime, &teeTaTime,
+                   &nowTime);
+               memcpy(time, retTime, sizeof(TEE_Time));
+       } else {
+               TEE_GetREETime(&nowTime);
+               TEE_Time* retTime = _TEE_GetAdjDiffTeeTime(&reqTaTime, &reeTaTime,
+                   &nowTime);
+               memcpy(time, retTime, sizeof(TEE_Time));
+       }
+       return TEE_SUCCESS;
+}
+
+/**
+ * The TEE_SetTAPersistentTime function sets the persistent time of the
+ * current Trusted Application.
+ * Only the persistent time for the current Trusted Application is modified,
+ * not the persistent time of other Trusted Applications. This will affect all
+ * instances of the current Trusted Application. The modification is atomic
+ * and persistent across device reboots.
+ * @param time Filled with the persistent time of the current TA
+ */
+TEE_Result TEE_SetTAPersistentTime(TEE_Time* time) {
+       reqTaTime = *time;
+       TEE_GetREETime(&reeTaTime);
+       TEE_GetSystemTime(&teeTaTime);
+
+       isSetReqTaSpec = true;
+       return TEE_SUCCESS;
+}
+
+/* TODO : NOT IMPLEMENTED */
+/**
+ * The TEE_GetREETime function retrieves the current REE system time. This
+ * function retrieves the current time as seen from the point of view of the
+ * REE, expressed in the number of seconds since midnight on
+ * January 1, 1970, UTC.
+ * @param time Filled with the number of seconds and milliseconds since
+ *                                              midnight on January 1, 1970, UTC
+ */
+void TEE_GetREETime(TEE_Time* time) {
+       return;
+}
diff --git a/ssflib/dep/uci/include/uci_aes_xcbc_mac.h b/ssflib/dep/uci/include/uci_aes_xcbc_mac.h
new file mode 100755 (executable)
index 0000000..47ff5f0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_cryptocore.h 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2014.3
+ **/
+#ifndef _UCI_AES_XCBC_MAC_H
+#define _UCI_AES_XCBC_MAC_H
+#include "uci_type.h"
+#include "CC_API.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXBLOCKSIZE  32
+
+typedef struct {
+       unsigned char K[3][MAXBLOCKSIZE];
+       unsigned char IV[MAXBLOCKSIZE];
+
+       unsigned char key[MAXBLOCKSIZE];
+       unsigned int buflen;
+       unsigned int blocksize;
+} aes_xcbc_state;
+
+int xcbc_init(aes_xcbc_state *xcbc, unsigned char *key, unsigned int keylen);
+int xcbc_process(aes_xcbc_state *xcbc, unsigned char *in, unsigned int inlen);
+int xcbc_done(aes_xcbc_state *xcbc, unsigned char *out, unsigned int *outlen);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/ssflib/dep/uci/include/uci_api.h b/ssflib/dep/uci/include/uci_api.h
new file mode 100755 (executable)
index 0000000..0acb7e4
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file UCI_API.h 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.7
+ **/
+
+/**
+ * @addtogroup g_uci
+ *  @{
+ */
+
+#ifndef _UCI_API_H_
+#define _UCI_API_H_
+
+#include "uci_type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief allocates memory and initializes the cryptographic context structure, and return the crypto handle..
+ *
+ * @param[in] algorithm, algorithm wants to use.
+ * @config[in] config, config specified which function to call.
+ * @retval UCI handle  if success  
+ * @retval UCI_ERROR if fail
+ * @retval UCI_MEM_ALLOR_ERROR if allocate memory error.
+ */
+UCI_HANDLE uci_context_alloc(unsigned int algorithm,
+    uci_engine_config_e config);
+
+/**
+ * @brief free allocated memory.
+ *
+ * @param[in] algorithm algorithm wants to use. 
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is not a invalid handle.
+ */
+int uci_context_free(UCI_HANDLE oh);
+
+/**
+ * @brief Digest initialization.
+ *
+ * @param[in] oh    UCI handle
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is a invalid handle.
+ */
+int uci_md_init(UCI_HANDLE oh);
+
+/**
+ * @brief    process a message block
+ * @param[in] oh    UCI operator handle.
+ * @param[in] msg   message.
+ * @param[in] msglen    byte-length of msg.    
+ * @retval UCI_SUCCESS If no error occurred.
+ * @retval UCI_INVALID_HANDLE  If oh is not a valid handle.
+ * @retval UCI_ERROR if msg is NULL while msg_len is not 0
+ */
+int uci_md_update(UCI_HANDLE oh, unsigned char *msg, unsigned int msg_len);
+
+/**    
+ * @brief get hashed message
+ * @param[in] oh UCI operator handle
+ * @param[out] output   hashed message.    
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ * @retval UCI_ERROR If operate failed. Such as output is NULL.
+ */
+int uci_md_final(UCI_HANDLE oh, unsigned char * output);
+
+/**
+ * @brief    get hashed message from message
+ * @param[in] oh UCI operator handle
+ * @param[in] msg    message
+ * @param[in] msglen byte-length of msg
+ * @param[out] output    hashed message.    
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ * @retval UCI_ERROR if output is NULL.
+ */
+int uci_md_get_hash(UCI_HANDLE oh, unsigned char *msg, unsigned int msg_len,
+    unsigned char * output);
+
+/**
+ * @brief    Parameter setting for mac code generation
+ * @param[in] oh    uci handle
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR   if key is NULL or key_len is not equal to 16.
+ */
+int uci_mac_init(UCI_HANDLE oh, unsigned char *key, unsigned int key_len);
+
+/**
+ * @brief    process data blocks
+ * @param[in] oh uci handle
+ * @param[in] msg    data block
+ * @param[in] msg_len    byte-length of Text
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    if msg is NULL.
+ */
+int uci_mac_update(UCI_HANDLE oh, unsigned char *msg, unsigned int msg_len);
+
+/**
+ * @brief    process last data block
+ * @param[in] oh    uci handle
+ * @param[out] output   generated MAC
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR   if output is NULL.
+ */
+int uci_mac_final(UCI_HANDLE oh, unsigned char *output,
+    unsigned int *output_len);
+
+/**
+ * @brief    generate c-mac code
+ * @param[in] oh    UCI handle
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of Key
+ * @param[in] msg        data block
+ * @param[in] msg_len   byte-length of Text
+ * @param[out] utput    generated MAC
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    Other error. such key is NULL or msg is NULL.
+ */
+int uci_mac_get_mac(UCI_HANDLE oh, unsigned char *key, unsigned int key_len,
+    unsigned char * msg, unsigned int msg_len, unsigned char * output,
+    unsigned int * output_len);
+
+/**
+ * @brief    initialize crypt context for symmetric cryptography
+ * @param[in] oh    UCI handle
+ * @param[in] mode  encryption|decryption and mode of operation
+ * @param[in]     padding    padding method
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of key
+ * @param[in] iv    initial vector
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_INVALID_ARGUMENT if one or moer parameter is ininvalid. 
+ * @retval UCI_ERROR    if key is null. iv is null is invalid.
+ */
+int uci_se_init(UCI_HANDLE oh, unsigned int mode, unsigned padding,
+    unsigned char *key, unsigned int key_len, unsigned char * iv);
+
+/**
+ * @brief    process message block
+ * @param[in] oh    UCI handle
+ * @param[in]     input  message block
+ * @param[in] input_len byte-length of Text
+ * @param[out] output   proecessed message
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    if output is NULL while input is not NULL.
+ */
+int uci_se_process(UCI_HANDLE oh, unsigned char * input, unsigned int input_len,
+    unsigned char * output, unsigned int *output_len);
+
+/***
+ * @brief    process final block and padding
+ * @param[in] oh UCI handle
+ * @param[in] input  message block
+ * @param[in] input_len  byte-length of Text
+ * @param[in] output processed message
+ * @param[out] output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    if output is NULL while input is not NULL..
+ */
+int uci_se_final(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char * output, unsigned int *output_len);
+
+/**
+ * @brief     Encrypt one block
+ * @param[in] oh UCI handle
+ * @param[in] cipher_tex encrypted text
+ * @param[in] plain_text plain text
+ * @param[in] user_key   user key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    cipher_text,plain_text or user_key is NULL.
+ */
+int uci_se_encrypt_oneblock(UCI_HANDLE oh, unsigned char *cipher_text,
+    unsigned char * plain_text, unsigned char *user_key);
+
+/**
+ * @brief    Decrypt one block
+ * @param[in] oh    UCI handle
+ * @param[in] cipher_text   encrypted text
+ * @param[out] plain_text   plain text
+ * @param[in] user_key  user key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE        if oh is invalid handle.
+ * @retval UCI_ERROR    cipher_text,plain_text or user_key is NULL.
+ */
+int uci_se_decrypt_oneblock(UCI_HANDLE oh, unsigned char * plain_text,
+    unsigned char *cipher_text, unsigned char* user_key);
+
+/**
+ * @brief    initialize crypt context for symmetric cryptography in whitebox aes
+ * @param[in] oh    UCI handle
+ * @param[in] flag  if flag is 1 means table was encrypted, and key is used to decrypt table. else key is set NULL.
+ * @param[in]     key    key used to decrypt table 
+ * @param[in] table_filepath   the file path where table stored.
+ * @param[in] pencoder1    encoder instance
+ * @param[in] pencoder2    encoder instance
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    such as if flag is 1 while key is NULL. and table_filepath is NULL will also return UCI_ERROR.
+ */
+int uci_wbse_init(UCI_HANDLE oh, int flag, unsigned char *key,
+    char * table_filepath, void*pencoder1, void *pencoder2);
+
+/**
+ * @brief     Encrypt message with whitebox aes
+ * @param[in] oh UCI handle
+ * @param[in] input text need to encrypt or decrypt
+ * @param[in] input_len input textlen
+ * @param[out] output   processed output data.
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    such as input , output is NULL.
+ */
+int uci_wbse_final(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char * output, unsigned int output_len);
+
+/**
+ * @brief      generate DH or DSA param
+ * @param[in] oh UCI handle
+ * @param[out] param  parameter structure
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_INVALID_ARGUMENT  if param is NULL.
+ * @retval UCI_ERROR    other error occured.
+ */
+int uci_ae_gen_param(UCI_HANDLE oh, uci_param_s *param, unsigned int size);
+
+/**
+ * @brief    generate key pair
+ * @param[in] oh    UCI handle
+ * @param[in] keymaterial   key pair structure
+ * @param[in] param parameter structure
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE  if oh is invalid handle.
+ * @retval UCI_ERROR    If keymaterial is ininvalid. except whiteboxRSA, param should   not be NULL.
+ */
+int uci_ae_gen_keypair(UCI_HANDLE oh, uci_key_s* keymaterial,
+    uci_param_s* param);
+
+/**
+ * @brief    generate key pair
+ * @param[in] oh UCI handle
+ * @param[in] keymaterial    key pair structure
+ * @param[in] param  parameter structure
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is ininvalid handle.
+ * @retval UCI_ERROR   if keymaterial is not invalid. param is not invalid(except whitebox rsa).
+
+ */
+int uci_ae_set_keypair(UCI_HANDLE oh, uci_key_s* keymaterial,
+    uci_param_s *param);
+
+/**    
+ * @brief    RSA Encryption
+ * @param[in] oh    UCI handle
+ * @param[in] input message to encrypt
+ * @param[in] input_len byte-length of input
+ * @param[out] output   encrypted message
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is ininvalid handle.
+ * @retval UCI_MSG_TOO_LONG    the input_len is too long. The correct usage is that input_len shorter than key length. 
+ * @retval UCI_ERROR    input or output is NULL..
+ */
+int uci_ae_encrypt(UCI_HANDLE oh, unsigned char * input, unsigned int input_len,
+    unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief    RSA Decryption
+ * @param[in]oh UCI handle
+ * @param[in]input  message to decrypt
+ * @param[in]input_len  byte-length of input
+ * @param[out]output    decrypted message
+ * @param[out]output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_MSG_TOO_LONG    the input_len is too long. The correct usage is that input_len shorter than key length. 
+ * @retval UCI_ERROR    input or output is NULL.
+ */
+int uci_ae_decrypt(UCI_HANDLE oh, unsigned char * input, unsigned int input_len,
+    unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief    RSA Decryption using CRT
+ * @param[in]oh UCI handle
+ * @param[in]input  message to decrypt
+ * @param[in]input_len  byte-length of input
+ * @param[out]output    decrypted message
+ * @param[out]output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_MSG_TOO_LONG    the input_len is too long. The correct usage is that input_len shorter than key length. 
+ * @retvla UCI_ERROR   input or output is NULL.
+ */
+int uci_ae_decryptbycrt(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief    whitebox rsa encryption
+ * @param[in]oh UCI handle
+ * @param[in]input  message to decrypt
+ * @param[in]input_len  byte-length of input
+ * @param[out]output    decrypted message
+ * @param[out]output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retvla UCI_ERROR    other error occured.if input, output, output_len is NULL.
+ */
+int uci_wbae_encrypt(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief    whitebox rsa decryption
+ * @param[in] oh    UCI handle
+ * @param[in] input message to decrypt
+ * @param[in] input_len byte-length of input
+ * @param[out] output   decrypted message
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    other error occured. if input, output, output_len is NULL.
+ */
+int uci_wbae_decrypt(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief    generate signature for given value
+ * @param[in]oh UCI handle
+ * @param[in]hash   hash value
+ * @param[in]hash_len   byte-length of hash
+ * @param[out]signature generated signature
+ * @param[out]sign_len        byte-length of signature
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_MSG_TOO_LONG    the input_len is too long. The correct usage is that input_len shorter than key length. 
+ * @retval UCI_ERROR    if hash or signature is NULL.
+ */
+int uci_ds_sign(UCI_HANDLE oh, unsigned char * hash, unsigned int hash_len,
+    unsigned char * signature, unsigned int* sign_len);
+
+/**
+ * @brief    generate signature for given value
+ * @param[in] oh UCI handle
+ * @param[in] hash   hash value to signature.
+ * @param[in] hash_len   byte-length of hash
+ * @param[in] signature  result of signatured value.
+ * @param[in] sign_len   byte-length of signature
+ * @param[out] result result of verifying signature
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_MSG_TOO_LONG    the input_len is too long. The correct usage is that input_len shorter than key length. 
+ * @retval UCI_ERROR    If hash or signature is NULL.
+ */
+int uci_ds_verify(UCI_HANDLE oh, unsigned char * hash, unsigned int hash_len,
+    unsigned char * signature, unsigned int sign_len, int * result);
+
+/**
+ * @brief    generate xk and its xv
+ * @param[in] oh UCI handle
+ * @param[out] pch_xk Generated Random Number
+ * @param[out] pch_xv DH 1st phase value
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR   if pch_xk or pch_xv is NULL; and the length of pch_xv should be more than 40 bytes. The length of pch_xk should be more than 20 bytes.
+ */
+int uci_dh_gen_phasekey(UCI_HANDLE oh, unsigned char*pch_xk,
+    unsigned char*pch_xv, uci_param_s * param);
+
+/**
+ * @brief genenrate auth key with Xk and Yv
+ * @param[in] oh UCI handle
+ * @param[in]     pch_xk  Generated Random Number
+ * @param[in] pch_yv DH 1st phase value
+ * @param[out] pch_kauth  authentication key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR   if pch_xk, pch_xv and pch_kauth should be not NULL. and the length of pch_kauth should be longer than 20.
+ */
+int uci_dh_gen_authkey(UCI_HANDLE oh, unsigned char*pch_xk,
+    unsigned char*pch_xv, unsigned char *pch_kauth);
+
+/**
+ * @brief    Seed RNG System
+ * @param[in] oh UCI handle
+ * @param[in] seed   seed for RNG System
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR    other error occured.If seed is NULL. and user should ensure length of seed should be at least 16  bytes, because cryptocore module need seed is  16 bytes.
+ */
+int uci_prng_seed(UCI_HANDLE oh, unsigned char * seed);
+
+/**
+ * @brief    generate random number
+ * @param[in] oh UCI handle
+ * @param[in] bit_length bit length for generated number
+ * @param[out] data  generated data
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is invalid handle.
+ * @retval UCI_ERROR  other error occured.if data is NULL.
+ */
+int uci_prng_get(UCI_HANDLE oh, unsigned int bit_len, unsigned char *data);
+
+int uci_dup_handle(UCI_HANDLE srcoh, UCI_HANDLE destoh);
+int uci_authcrypt_init(UCI_HANDLE oh, unsigned int mode, unsigned char *nonce,
+    unsigned int nonce_len, unsigned int tag_len, unsigned int aad_len,
+    unsigned int payload_len, unsigned char *key, unsigned int key_len);
+int uci_authcrypt_update_aad(UCI_HANDLE oh, unsigned char *aad,
+    unsigned int aad_len);
+int uci_authcrypt_update(UCI_HANDLE oh, unsigned char *src,
+    unsigned int src_len, unsigned char *dest, unsigned int *dest_len);
+int uci_authcrypt_encryptfinal(UCI_HANDLE oh, unsigned char *src,
+    unsigned int src_len, unsigned char *dest, unsigned int *dest_len,
+    unsigned char *tag, unsigned int *tag_len);
+
+int uci_authcrypt_decryptfinal(UCI_HANDLE oh, unsigned char *src,
+    unsigned int src_len, unsigned char *dest, unsigned int *dest_len,
+    unsigned char *tag, unsigned int tag_len);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}*/
+
+#endif
+
diff --git a/ssflib/dep/uci/include/uci_cryptocore.h b/ssflib/dep/uci/include/uci_cryptocore.h
new file mode 100755 (executable)
index 0000000..ab40685
--- /dev/null
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_cryptocore.h 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.7
+ **/
+#ifndef _UCI_CRYPTOCORE_H
+#define _UCI_CRYPTOCORE_H
+#include "uci_type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  
+
+/**
+ * @brief allocates memory and initializes the cryptographic context structure, and return the crypto handle..
+ *
+ * @param[in] algorithm, algorithm wants to use.
+ * @retval UCI handle  if success  
+ * @retval UCI_ERROR if fail
+ */
+UCI_HANDLE cryptocore_context_alloc(unsigned int algorithm);
+/**
+ * @brief free allocated memory.
+ *
+ * @param[in] algorithm algorithm wants to use. 
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ */
+int cryptocore_context_free(UCI_HANDLE oh);
+
+/**
+ * @brief Digest initialization.
+ *
+ * @param[in] oh    UCI handle
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ */
+int cryptocore_md_init(UCI_HANDLE oh);
+
+/**
+ * @brief      process a message block
+ * @param[in] oh    UCI operator handle.
+ * @param[in] msg   message.
+ * @param[in] msglen    byte-length of msg.    
+ * @UCI_SUCCESS If no error occurred.
+ * @UCI_INVALID_HANDLE  If oh is not a valid handle.
+ */
+int cryptocore_md_update(UCI_HANDLE oh, unsigned char *msg,
+    unsigned int msg_len);
+
+/**    
+ * @brief      get hashed message
+ * @param[in]   oh UCI operator handle
+ * @param[out] output   hashed message.        
+ * @   retval UCI_SUCCESS  If no error occurred.
+ * @   retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ */
+
+int cryptocore_md_final(UCI_HANDLE oh, unsigned char * output);
+
+/**
+ * @brief      get hashed message from message
+ * @param[in] oh UCI operator handle
+ * @param[in] msg    message
+ * @param[in] msglen byte-length of msg
+ * @param[out] output    hashed message.       
+ * @   retval UCI_SUCCESS  If no error occurred.
+ * @   retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ */
+
+int cryptocore_md_get_hash(UCI_HANDLE oh, unsigned char *msg,
+    unsigned int msg_len, unsigned char * output);
+
+/**
+ * @brief      Parameter setting for mac code generation
+ * @param[in] oh    uci handle
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_MEMORY_ALLOC_FAIL    if memory allocation is failed.
+ */
+
+int cryptocore_mac_init(UCI_HANDLE oh, unsigned char *key,
+    unsigned int key_len);
+
+/**
+ * @brief      process data blocks
+ * @param[in] oh uci handle
+ * @param[in] msg    data block
+ * @param[in] msg_len    byte-length of Text
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    if other error occured.
+ */
+
+int cryptocore_mac_update(UCI_HANDLE oh, unsigned char *msg,
+    unsigned int msg_len);
+
+/**
+ * @brief      process last data block
+ * @param[in] oh    uci handle
+ * @param[out] output   generated MAC
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_mac_final(UCI_HANDLE oh, unsigned char *output,
+    unsigned int *output_len);
+
+/**
+ * @brief      generate c-mac code
+ * @param[in] oh    UCI handle
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of Key
+ * @param[in] msg          data block
+ * @param[in] msg_len   byte-length of Text
+ * @param[out] utput    generated MAC
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_mac_getmac(UCI_HANDLE oh, unsigned char *key,
+    unsigned int key_len, unsigned char * msg, unsigned int msg_len,
+    unsigned char * output, unsigned int * output_len);
+
+/**
+ * @brief      initialize crypt context for symmetric cryptography
+ * @param[in] oh    UCI handle
+ * @param[in] mode  encryption|decryption and mode of operation
+ * @param[in]   padding    padding method
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of key
+ * @param[in] iv    initial vector
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_se_init(UCI_HANDLE oh, unsigned int mode, unsigned padding,
+    unsigned char *key, unsigned int key_len, unsigned char * iv);
+/**
+ * @brief      process message block
+ * @param[in] oh    UCI handle
+ * @param[in]   input  message block
+ * @param[in] input_len byte-length of Text
+ * @param[out] output   proecessed message
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_se_process(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int *output_len);
+
+/**
+ * @brief      process final block and padding
+ * @param[in] oh UCI handle
+ * @param[in] input  message block
+ * @param[in] input_len  byte-length of Text
+ * @param[in] output processed message
+ * @param[out] output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_se_final(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char * output, unsigned int *output_len);
+
+/**
+ * @brief       Encrypt one block
+ * @param[in] oh UCI handle
+ * @param[in] cipher_tex encrypted text
+ * @param[in] plain_text plain text
+ * @param[in] user_key   user key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_se_encrypt_oneblock(UCI_HANDLE oh, unsigned char *cipher_text,
+    unsigned char * plain_text, unsigned char *user_key);
+
+/**
+ * @brief      Decrypt one block
+ * @param[in] oh    UCI handle
+ * @param[in] cipher_text   encrypted text
+ * @param[out] plain_text   plain text
+ * @param[in] user_key  user key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE      if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_se_decrypt_oneblock(UCI_HANDLE oh, unsigned char * plain_text,
+    unsigned char *cipher_text, unsigned char* user_key);
+
+/**
+ * @brief      generate DH or DSA param
+ * @param[in] oh UCI handle
+ * @param[out] param  parameter structure
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_INVALID_ARGUMENT  if param is NULL.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_ae_gen_param(UCI_HANDLE oh, uci_param_s *param,
+    unsigned int size);
+
+/**
+ * @brief      generate key pair
+ * @param[in] oh UCI handle
+ * @param[in] keymaterial    key pair structure
+ * @param[in] param  parameter structure
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_ae_gen_keypair(UCI_HANDLE oh, uci_key_s* keymaterial,
+    uci_param_s* param);
+
+/**
+ * @brief      generate key pair
+ * @param[in] oh UCI handle
+ * @param[in] keymaterial    key pair structure
+ * @param[in] param  parameter structure
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_ae_set_keypair(UCI_HANDLE oh, uci_key_s* keymaterial,
+    uci_param_s* param);
+
+/**    
+ * @brief      RSA Encryption
+ * @param[in] oh    UCI handle
+ * @param[in] input message to encrypt
+ * @param[in] input_len byte-length of input
+ * @param[out] output   encrypted message
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+int cryptocore_ae_encrypt(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief      RSA Decryption
+ * @param[in]oh UCI handle
+ * @param[in]input  message to decrypt
+ * @param[in]input_len  byte-length of input
+ * @param[out]output    decrypted message
+ * @param[out]output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_ae_decrypt(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief      RSA Decryption using CRT
+ * @param[in]oh UCI handle
+ * @param[in]input  message to decrypt
+ * @param[in]input_len  byte-length of input
+ * @param[out]output    decrypted message
+ * @param[out]output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retvla UCI_ERROR    other error occured.
+ */
+int cryptocore_ae_decryptbycrt(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int* output_len);
+
+/**
+ * @brief      generate signature for given value
+ * @param[in]oh UCI handle
+ * @param[in]hash   hash value
+ * @param[in]hash_len   byte-length of hash
+ * @param[out]signature generated signature
+ * @param[out]sign_len     byte-length of signature
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_ds_sign(UCI_HANDLE oh, unsigned char * hash,
+    unsigned int hash_len, unsigned char * signature, unsigned int* sign_len);
+
+/**
+ * @brief      generate signature for given value
+ * @param[in] oh UCI handle
+ * @param[in] hash   hash value to signature.
+ * @param[in] hash_len   byte-length of hash
+ * @param[in] signature  result of signatured value.
+ * @param[in] sign_len   byte-length of signature
+ * @param[out] result result of verifying signature
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_ds_verify(UCI_HANDLE oh, unsigned char * hash,
+    unsigned int hash_len, unsigned char * signature, unsigned int sign_len,
+    int * result);
+
+/**
+ * @brief      generate xk and its xv
+ * @param[in] oh UCI handle
+ * @param[out] pch_xk Generated Random Number
+ * @param[out] pch_xv DH 1st phase value
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_dh_gen_dh1stphasekey(UCI_HANDLE oh, unsigned char*pch_xk,
+    unsigned char*pch_xv, uci_param_s * param);
+
+/**
+ * @brief genenrate auth key with Xk and Yv
+ * @param[in] oh UCI handle
+ * @param[in]   pch_xk  Generated Random Number
+ * @param[in] pch_yv DH 1st phase value
+ * @param[out] pch_kauth  authentication key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_dh_gen_dhkey(UCI_HANDLE oh, unsigned char*pch_xk,
+    unsigned char*pch_xv, unsigned char *pch_kauth);
+
+/**
+ * @brief      Seed RNG System
+ * @param[in] oh UCI handle
+ * @param[in] seed   seed for RNG System
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_prng_seed(UCI_HANDLE oh, unsigned char * seed);
+
+/**
+ * @brief      generate random number
+ * @param[in] oh UCI handle
+ * @param[in] bit_length bit length for generated number
+ * @param[out] data  generated data
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int cryptocore_prng_get(UCI_HANDLE oh, unsigned int bit_len,
+    unsigned char *data);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/ssflib/dep/uci/include/uci_hwcrypto.h b/ssflib/dep/uci/include/uci_hwcrypto.h
new file mode 100755 (executable)
index 0000000..02a7710
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_hwcrypto.h 
+ * @brief hwcrypto codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.7
+ **/
+#ifndef _UCI_HWCRYPTO_H
+#define _UCI_HWCRYPTO_H
+#include "uci_type.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif  
+
+/**
+ * @brief allocates memory and initializes the cryptographic context structure, and return the crypto handle..
+ *
+ * @param[in] algorithm, algorithm wants to use.
+ * @retval UCI handle  if success  
+ * @retval UCI_ERROR if fail
+ */
+UCI_HANDLE hwcrypto_context_alloc(unsigned int algorithm,
+    uci_engine_config_e config);
+
+/**
+ * @brief free allocated memory.
+ *
+ * @param[in] algorithm algorithm wants to use. 
+ * @retval UCI_SUCCESS  If no error occurred.
+ * @retval UCI_INVALID_HANDLE   If oh is not a valid handle.
+ */
+int hwcrypto_context_free(UCI_HANDLE oh);
+/**
+ * @brief      initialize crypt context for symmetric cryptography
+ * @param[in] oh    UCI handle
+ * @param[in] mode  encryption|decryption and mode of operation
+ * @param[in]   padding    padding method
+ * @param[in] key   user key
+ * @param[in] key_len   byte-length of key
+ * @param[in] iv    initial vector
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int hwcrypto_se_init(UCI_HANDLE oh, unsigned int mode, unsigned int padding,
+    unsigned char *key, unsigned int key_len, unsigned char * iv);
+/**
+ * @brief      process message block
+ * @param[in] oh    UCI handle
+ * @param[in]   input  message block
+ * @param[in] input_len byte-length of Text
+ * @param[out] output   proecessed message
+ * @param[out] output_len   byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR               other error occured.
+ */
+
+int hwcrypto_se_process(UCI_HANDLE oh, unsigned char * input,
+    unsigned int input_len, unsigned char * output, unsigned int *output_len);
+
+/***
+ * @brief      process final block and padding
+ * @param[in] oh UCI handle
+ * @param[in] input  message block
+ * @param[in] input_len  byte-length of Text
+ * @param[in] output processed message
+ * @param[out] output_len    byte-length of output
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+int hwcrypto_se_final(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char * output, unsigned int *output_len);
+
+/**
+ * @brief       Encrypt one block
+ * @param[in] oh UCI handle
+ * @param[in] cipher_tex encrypted text
+ * @param[in] plain_text plain text
+ * @param[in] user_key   user key
+ * @retval UCI_SUCCESS  if no error is occured.
+ * @retval UCI_INVALID_HANDLE   if oh is valid handle.
+ * @retval UCI_ERROR    other error occured.
+ */
+
+#ifdef __cplusplus
+}
+#endif  
+
+#endif
+
diff --git a/ssflib/dep/uci/include/uci_internal.h b/ssflib/dep/uci/include/uci_internal.h
new file mode 100755 (executable)
index 0000000..c1bb305
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_internal.h 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.7
+ **/
+#ifndef _UCI_INTERNAL_H
+#define _UCI_INTERNAL_H
+
+#include "uci_type.h"
+#include <stdlib.h>
+
+typedef struct uci_context {
+       unsigned int alg;
+       unsigned int config;
+       unsigned int flag; //(hwcrypt)if flag equal to 1, means encrypt. else flag equal to 0, means decrypt.  flag == ID_UCI_ENC_CTS (ID_UCI_DEC_CTS)
+       int handle;
+       void* imp;
+} uci_context_s;
+
+#endif
+
diff --git a/ssflib/dep/uci/include/uci_type.h b/ssflib/dep/uci/include/uci_type.h
new file mode 100755 (executable)
index 0000000..f3c8843
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_type.h 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.7
+ **/
+#ifndef _UCI_TYPE_H
+#define _UCI_TYPE_H
+
+#include "OsaLinuxUser.h"
+
+/**
+ * @addtogroup g_uci
+ *  @{
+ */
+
+/**
+ * @brief  UCI handle.
+ *
+ */
+typedef int UCI_HANDLE;
+/**
+ * @brief UCI return error type.
+ *
+ */
+
+#define UCI_SUCCESS              0             /**<    no error is occured                   */
+#define UCI_ERROR                -3000         /**<    error is occured                      */
+#define UCI_MEM_ALLOR_ERROR      -3001         /**<    malloc is failed                      */
+#define UCI_INVALID_ARGUMENT     -3003         /**<    argument is not correct               */
+#define UCI_MSG_TOO_LONG         -3004         /**<    length of input message is too long   */
+#define UCI_INVALID_HANDLE       -3005         /**<    hand is not valid                     */         
+#define UCI_VALID_SIGN     UCI_SUCCESS         /**<    valid sign                            */
+#define UCI_INVALID_SIGN         -3011         /**<    invalid sign                          */
+
+#define SDRM_SHIFT_HALF        16              /**<    common value at both of 32-bit and 64-bit machine    */
+#define SDRM_HIGH_HALF(A)    ((A) >> SDRM_SHIFT_HALF)
+#define SDRM_LOW_HALF(A)    ((A) & ((1 << SDRM_SHIFT_HALF) - 1))
+
+////////////////////////////////////////////////////////////////////////////
+// Algorithm Identifier (To be update)
+////////////////////////////////////////////////////////////////////////////
+enum UCICryptoAlgorithm {
+       /*!    \brief    RNG Module    */
+       ID_UCI_X931 = 1011,
+
+       /*!    \brief    Hash Algorithms    */
+       ID_UCI_MD5 = 1021,
+       ID_UCI_SHA1 = 1022,
+       ID_UCI_SHA160 = 1022,
+       ID_UCI_SHA256 = 1023,
+#ifndef _OP64_NOTSUPPORTED
+       ID_UCI_SHA384 = 1024,
+       ID_UCI_SHA512 = 1025,
+#endif //_OP64_NOTSUPPORTED
+       ID_UCI_SHA224 = 1026,
+
+       /*!    \brief    MAC Algorithms    */
+       ID_UCI_CMAC = 1031,
+       ID_UCI_HMD5 = 1032,
+       ID_UCI_HSHA1 = 1033,
+       ID_UCI_HSHA160 = 1033,
+       ID_UCI_HSHA256 = 1034,
+#ifndef _OP64_NOTSUPPORTED
+       ID_UCI_HSHA384 = 1035,
+       ID_UCI_HSHA512 = 1036,
+#endif //_OP64_NOTSUPPORTED
+       ID_UCI_HSHA224 = 1037,
+       ID_UCI_XCBCMAC = 1038,
+       /*!    \brief    Symmetric Encryption Algorithms    */
+       ID_UCI_AES = 1041,
+       ID_UCI_AES128 = 1041,
+       ID_UCI_AES192 = 1047,
+       ID_UCI_AES256 = 1048,
+       ID_UCI_DES = 1042,
+       ID_UCI_TDES = 1043,
+       ID_UCI_TDES_EDE2 = 1043,
+       ID_UCI_TDES_EDE3 = 1044,
+       ID_UCI_RC4 = 1045,
+       ID_UCI_SNOW2 = 1046,
+
+       /*!    \brief    Asymmetric Encryption Algorithms    */
+       ID_UCI_RSA = 1051,
+       ID_UCI_RSA512 = 1057,
+       ID_UCI_RSA1024 = 1054,
+       ID_UCI_RSA2048 = 1055,
+       ID_UCI_RSA3072 = 1056,
+       ID_UCI_ELGAMAL = 1052,
+       ID_UCI_ECELGAMAL = 1053,
+
+       /*!    \brief    Signature Algorithms    */
+       ID_UCI_DSA = 1061,
+       ID_UCI_ECDSA = 1062,
+
+       /*!    \brief    Key Exchange Algorithms    */
+       ID_UCI_DH = 1071,
+       ID_UCI_ECDH = 1072,
+       /*!    \brief    WhitBox Algorithms    */
+       ID_UCI_WBENC_AES = 1081,
+       ID_UCI_WBDEC_AES = 1082,
+       ID_UCI_WBRSA512 = 1083,
+       ID_UCI_WBRSA1024 = 1084,
+       ID_UCI_WBRSA2048 = 1085,
+
+       /*!    \brief    Encryption/Decryption Mode of Operations    */
+       ID_UCI_ENC_ECB = 1111,
+       ID_UCI_ENC_CBC = 1112,
+       ID_UCI_ENC_CFB = 1113,
+       ID_UCI_ENC_OFB = 1114,
+       ID_UCI_ENC_CTR = 1115,
+       ID_UCI_ENC_CTS = 1116,
+
+       ID_UCI_DEC_ECB = 1121,
+       ID_UCI_DEC_CBC = 1122,
+       ID_UCI_DEC_CFB = 1123,
+       ID_UCI_DEC_OFB = 1124,
+       ID_UCI_DEC_CTR = 1125,
+       ID_UCI_DEC_CTS = 1126,
+
+       /*!    \brief    Symmetric Encryption/Decryption Padding Methods        */
+       ID_UCI_PKCS5 = 1201,
+       ID_UCI_SSL_PADDING = 1202,
+       ID_UCI_ZERO_PADDING = 1203,
+       ID_UCI_NO_PADDING = 1204,
+
+       /*!    \brief    Asymmetric Encryption/Decryption Padding Methods    */
+       ID_UCI_RSAES_PKCS15 = 1131,
+
+       ID_UCI_RSAES_OAEP = 1132,
+       ID_UCI_RSAES_OAEP_MD5 = ID_UCI_RSAES_OAEP + (ID_UCI_MD5 << SDRM_SHIFT_HALF),
+       ID_UCI_RSAES_OAEP_SHA1 = ID_UCI_RSAES_OAEP + (ID_UCI_SHA1 << SDRM_SHIFT_HALF),
+       ID_UCI_RSAES_OAEP_SHA160 = ID_UCI_RSAES_OAEP
+           + (ID_UCI_SHA160 << SDRM_SHIFT_HALF),
+       ID_UCI_RSAES_OAEP_SHA224 = ID_UCI_RSAES_OAEP
+           + (ID_UCI_SHA224 << SDRM_SHIFT_HALF),
+       ID_UCI_RSAES_OAEP_SHA256 = ID_UCI_RSAES_OAEP
+           + (ID_UCI_SHA256 << SDRM_SHIFT_HALF),
+#ifndef _OP64_NOTSUPPORTED
+       ID_UCI_RSAES_OAEP_SHA384 = ID_UCI_RSAES_OAEP
+           + (ID_UCI_SHA384 << SDRM_SHIFT_HALF),
+       ID_UCI_RSAES_OAEP_SHA512 = ID_UCI_RSAES_OAEP
+           + (ID_UCI_SHA512 << SDRM_SHIFT_HALF),
+#endif
+
+       ID_UCI_RSASSA_PKCS15 = 1133,
+       ID_UCI_RSASSA_PKCS15_MD5 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_MD5 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PKCS15_SHA1 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_SHA1 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PKCS15_SHA160 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_SHA160 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PKCS15_SHA224 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_SHA224 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PKCS15_SHA256 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_SHA256 << SDRM_SHIFT_HALF),
+#ifndef _OP64_NOTSUPPORTED
+       ID_UCI_RSASSA_PKCS15_SHA384 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_SHA384 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PKCS15_SHA512 = ID_UCI_RSASSA_PKCS15
+           + (ID_UCI_SHA512 << SDRM_SHIFT_HALF),
+#endif
+
+       ID_UCI_RSASSA_PSS = 1134,
+       ID_UCI_RSASSA_PSS_MD5 = ID_UCI_RSASSA_PSS + (ID_UCI_MD5 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PSS_SHA1 = ID_UCI_RSASSA_PSS + (ID_UCI_SHA1 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PSS_SHA160 = ID_UCI_RSASSA_PSS
+           + (ID_UCI_SHA160 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PSS_SHA224 = ID_UCI_RSASSA_PSS
+           + (ID_UCI_SHA224 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PSS_SHA256 = ID_UCI_RSASSA_PSS
+           + (ID_UCI_SHA256 << SDRM_SHIFT_HALF),
+#ifndef _OP64_NOTSUPPORTED
+       ID_UCI_RSASSA_PSS_SHA384 = ID_UCI_RSASSA_PSS
+           + (ID_UCI_SHA384 << SDRM_SHIFT_HALF),
+       ID_UCI_RSASSA_PSS_SHA512 = ID_UCI_RSASSA_PSS
+           + (ID_UCI_SHA512 << SDRM_SHIFT_HALF),
+#endif
+       /*!\brief Authenticated Encryption Functions  */
+       ID_UCI_AE_GCM = 1091,
+       ID_UCI_AE_CCM = 1092
+
+};
+
+/** @HW engine key type    */
+
+typedef enum {
+
+       UCI_USER_KEY = 1, UCI_SECRET_KEY = 2, UCI_MASTER_KEY = 3
+} hw_keytype_e;
+
+/** @crypto types uci supported    */
+typedef enum uci_engine_config {
+       UCI_SW = 2001, UCI_SW_CRYPTOCORE = 2001, UCI_SW_OPENSSL = 2002, UCI_HW = 2003, //SHOULD NOT USED
+       UCI_WB = 2004,
+
+       UCI_HW_USER_KEY = UCI_HW + (UCI_USER_KEY << SDRM_SHIFT_HALF),
+       UCI_HW_SECRET_KEY = UCI_HW + (UCI_SECRET_KEY << SDRM_SHIFT_HALF),
+       UCI_HW_MASTER_KEY = UCI_HW + (UCI_MASTER_KEY << SDRM_SHIFT_HALF)
+} uci_engine_config_e;
+
+/**
+ * @brief  RSA  key strucsture.
+ *
+ * Including private key an public key
+ */
+typedef struct rsa_key {
+       unsigned char* n; /**< RSA public component of  key.*/
+       unsigned int n_len; /**< RSA public component size of  key.*/
+       unsigned char* e; /**< RSA public component of  key.*/
+       unsigned int e_len; /**< RSA public component size of  key.*/
+       unsigned char* d; /**< RSA private component key.*/
+       unsigned int d_len; /**< RSA private component key size.*/
+} rsa_key_s;
+
+/**
+ * @brief  dsa  key strucsture.
+ *
+ * Including private key an public key
+ */
+
+typedef struct dsa_key {
+       unsigned char* ydata; /**< DSA public  of  key.*/
+       unsigned int ydata_len; /**< DSA size of  public key.*/
+       unsigned char* xdata; /**< DSA private  key.*/
+       unsigned int xdata_len; /**< DSA key private size.*/
+} dsa_key_s;
+
+/**
+ * @brief  ecc  key strucsture.
+ *
+ * Including private key an public key
+ */
+typedef struct ecc_key {
+       unsigned char* privatekey;
+       unsigned int privatekey_len;
+       unsigned char* publickey_x;
+       unsigned int publickey_x_len;
+       unsigned char* publickey_y;
+       unsigned int publickey_y_len;
+} ecc_key_s;
+
+/**
+ * @brief  DH  key structure
+ *
+ * Including key buf and length.
+ */
+typedef struct dh_key {
+       unsigned char* privatekey;
+       unsigned int privatekey_len;
+       unsigned char* publickey;
+       unsigned int publickey_len;
+
+} dh_key_s;
+/**
+ * @brief  imp  key union.
+ *
+ *Including  rsa key structure , dsa key structure, ecc key structure.
+ */
+typedef union uci_impkey {
+       rsa_key_s rkey;
+       dsa_key_s dkey;
+       ecc_key_s ekey;
+       dh_key_s dhkey;
+} uci_impkey_u;
+
+/**
+ * @brief  UCI  key strucsture.
+ *
+ * ECC, DSA and RSA algorithm generate key will use this structure.
+ */
+typedef struct uci_key {
+       uci_impkey_u imp;
+
+       /*rsa*/
+#define ucik_rsa_n           imp.rkey.n
+#define ucik_rsa_e           imp.rkey.e
+#define ucik_rsa_d           imp.rkey.d
+#define ucik_rsa_n_len       imp.rkey.n_len
+#define ucik_rsa_e_len       imp.rkey.e_len
+#define ucik_rsa_d_len       imp.rkey.d_len
+
+       /*dsa*/
+#define ucik_dsa_privkey     imp.dkey.xdata
+#define ucik_dsa_pubkey      imp.dkey.ydata
+#define ucik_dsa_privk_len   imp.dkey.xdata_len
+#define ucik_dsa_pubk_len    imp.dkey.ydata_len
+
+       /*ecc*/
+#define ucik_ecc_privkey     imp.ekey.privatekey
+#define ucik_ecc_pubkey_x    imp.ekey.publickey_x
+#define ucik_ecc_pubkey_y    imp.ekey.publickey_y
+#define ucik_ecc_privk_len   imp.ekey.privatekey_len
+#define ucik_ecc_pubkx_len   imp.ekey.publickey_x_len
+#define ucik_ecc_pubky_len   imp.ekey.publickey_y_len
+
+       /*dh*/
+#define ucik_dh_privkey      imp.dhkey.privatekey
+#define ucik_dh_prikey_len   imp.dhkey.privatekey_len
+#define ucik_dh_pubkey       imp.dhkey.publickey
+#define ucik_dh_pubkey_len   imp.dhkey.publickey_len
+
+} uci_key_s;
+
+typedef enum rsa_kparam_flag {
+       RSA_GENKEYWITHNON = 1, RSA_GENKEYWITHE, /* *< Dispaly the sturctut is including e */
+       RSA_GENKEYWITHPQE, /* *< Dispaly the sturctut is including pqe */
+       RSA_KEYFORCRT, /* *< Dispaly the sturctut for crt */
+} rsa_kparam_flag_e;
+
+/**
+ *@brief rsa  key param structure 
+ *
+ */
+typedef struct rsa_param {
+       rsa_kparam_flag_e flag;
+       int padding;
+       unsigned char* e;
+       unsigned int e_len;
+       unsigned char* p;
+       unsigned int p_len;
+       unsigned char* q;
+       unsigned int q_len;
+       unsigned char* dmodp1;
+       unsigned int dmodp1_len;
+       unsigned char* dmodq1;
+       unsigned int dmodq1_len;
+       unsigned char* iqp;
+       unsigned int iqp_len;
+} uci_rsa_param_s;
+
+/**
+ *@brief UCI key param
+ *
+ */
+typedef struct ecc_param {
+       unsigned short dimension;
+       unsigned char* ecc_p_data;
+       unsigned int ecc_p_len;
+       unsigned char* ecc_a_data;
+       unsigned int ecc_a_len;
+       unsigned char* ecc_b_data;
+       unsigned int ecc_b_len;
+       unsigned char* ecc_g_x_data;
+       unsigned int ecc_g_x_len;
+       unsigned char* ecc_g_y_data;
+       unsigned int ecc_g_y_len;
+       unsigned char* ecc_r_data;
+       unsigned int ecc_r_len;
+} uci_ecc_param_s;
+
+/**
+ *@brief dsa key param
+ *
+ */
+typedef struct dsa_param {
+       unsigned int t_size;
+       unsigned char* dsa_p_data;
+       unsigned int dsa_p_len;
+       unsigned char* dsa_q_data;
+       unsigned int dsa_q_len;
+       unsigned char* dsa_g_data;
+       unsigned int dsa_g_len;
+} uci_dsa_param_s;
+
+/**
+ *@brief DH key param
+ *
+ */
+typedef struct dh_param {
+       unsigned int len;
+       unsigned char* prime;
+       unsigned char* generator;
+} uci_dh_param_s;
+
+/**
+ *@brief uci key param union
+ *
+ */
+typedef union uci_param_imp {
+       uci_ecc_param_s uep;
+       uci_dsa_param_s udp;
+       uci_rsa_param_s urp;
+       uci_dh_param_s udhp;
+} uci_param_imp_u;
+
+/**
+ *@brief uci key param structure
+ *
+ */
+typedef struct uci_param {
+       uci_param_imp_u uparam;
+       /*rsa*/
+#define ucip_rsa_flag                        uparam.urp.flag
+#define ucip_rsa_padding                     uparam.urp.padding
+#define ucip_rsa_e                           uparam.urp.e
+#define ucip_rsa_e_len                       uparam.urp.e_len
+#define ucip_rsa_p                           uparam.urp.p
+#define ucip_rsa_p_len                       uparam.urp.p_len
+#define ucip_rsa_q                           uparam.urp.q
+#define ucip_rsa_q_len                       uparam.urp.q_len
+#define ucip_rsa_dmodp1                      uparam.urp.dmodp1
+#define ucip_rsa_dmodp1_len                  uparam.urp.dmodp1_len
+#define ucip_rsa_dmodq1                      uparam.urp.dmodq1
+#define ucip_rsa_dmodq1_len                  uparam.urp.dmodq1_len
+#define ucip_rsa_iqmodp                      uparam.urp.iqp
+#define ucip_rsa_iqmodp_len                  uparam.urp.iqp_len
+       /*dsa*/
+#define ucip_dsa_flag                        uparam.udp.flag
+#define ucip_dsa_tsize                       uparam.udp.t_size
+#define ucip_dsa_p                           uparam.udp.dsa_p_data
+#define ucip_dsa_q                           uparam.udp.dsa_q_data
+#define ucip_dsa_g                           uparam.udp.dsa_g_data
+#define ucip_dsa_p_len                       uparam.udp.dsa_p_len
+#define ucip_dsa_q_len                       uparam.udp.dsa_q_len
+#define ucip_dsa_g_len                       uparam.udp.dsa_g_len
+       /*ecc*/
+#define ucip_ecc_dimension                   uparam.uep.dimension
+#define ucip_ecc_p                           uparam.uep.ecc_p_data
+#define ucip_ecc_a                           uparam.uep.ecc_a_data
+#define ucip_ecc_b                           uparam.uep.ecc_b_data
+#define ucip_ecc_gx                          uparam.uep.ecc_g_x_data
+#define ucip_ecc_gy                          uparam.uep.ecc_g_y_data
+#define ucip_ecc_r                           uparam.uep.ecc_r_data
+#define ucip_ecc_p_len                       uparam.uep.ecc_p_len
+#define ucip_ecc_a_len                       uparam.uep.ecc_a_len
+#define ucip_ecc_b_len                       uparam.uep.ecc_b_len
+#define ucip_ecc_gx_len                      uparam.uep.ecc_g_x_len
+#define ucip_ecc_gy_len                      uparam.uep.ecc_g_y_len
+#define ucip_ecc_r_len                       uparam.uep.ecc_r_len
+
+       /**/
+#define ucip_dh_prime                        uparam.udhp.prime
+#define ucip_dh_generator                    uparam.udhp.generator
+#define ucip_dh_len                          uparam.udhp.len
+
+} uci_param_s;
+/** @}*/
+
+#endif
diff --git a/ssflib/dep/uci/source/uci_aes_xcbc_mac.c b/ssflib/dep/uci/source/uci_aes_xcbc_mac.c
new file mode 100755 (executable)
index 0000000..ae3f3b0
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_hwcrypto.cpp 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2014.3
+ **/
+/*according to RFC3566*/
+#include "uci_aes_xcbc_mac.h"
+#include <string.h>
+#include "cc_aes.h"
+
+static unsigned char k1[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+static unsigned char k2[] = {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02};
+static unsigned char k3[] = {0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
+
+int xcbc_init(aes_xcbc_state *xcbc, unsigned char *key, unsigned int keylen) {
+       /*
+        
+        (1)  Derive 3 128-bit keys (K1, K2 and K3) from the 128-bit secret
+        key K, as follows:
+        K1 = 0x01010101010101010101010101010101 encrypted with Key K
+        K2 = 0x02020202020202020202020202020202 encrypted with Key K
+        K3 = 0x03030303030303030303030303030303 encrypted with Key K
+        
+        (2)    Define E[0](iv) = 0x00000000000000000000000000000000
+        
+        */
+       if (keylen != 16) {
+               return 0;
+       }
+       if (xcbc == NULL) {
+               return 0;
+       }
+       memcpy(xcbc->key, key, 16);
+       SDRM_AES128_Encryption(xcbc->K[0], k1, xcbc->key);
+       SDRM_AES128_Encryption(xcbc->K[1], k2, xcbc->key);
+       SDRM_AES128_Encryption(xcbc->K[2], k3, xcbc->key);
+       memset(xcbc->key, 0, MAXBLOCKSIZE);
+       memcpy(xcbc->key, xcbc->K[0], 16);
+       xcbc->blocksize = 16;
+       xcbc->buflen = 0;
+       memset(xcbc->IV, 0, MAXBLOCKSIZE);
+       return 1;
+}
+int xcbc_process(aes_xcbc_state *xcbc, unsigned char *in, unsigned int inlen) {
+       /*
+        
+        (3)  For each block M[i], where i = 1 ... n-1:
+        XOR M[i] with E[i-1], then encrypt the result with Key K1,
+        yielding E[i].
+        
+        */
+       unsigned int x;
+       if (xcbc == NULL) {
+               return 0;
+       }
+       if (xcbc->buflen == 0) {
+               while (inlen > xcbc->blocksize) {
+                       for (x = 0; x < xcbc->blocksize; x++) {
+                               xcbc->IV[x] ^= in[x];
+                       }
+                       SDRM_AES128_Encryption(xcbc->IV, xcbc->IV, xcbc->key);
+                       in += xcbc->blocksize;
+                       inlen -= xcbc->blocksize;
+               }
+       }
+       while (inlen) {
+               if (xcbc->buflen == xcbc->blocksize) {
+                       SDRM_AES128_Encryption(xcbc->IV, xcbc->IV, xcbc->key);
+                       xcbc->buflen = 0;
+               }
+               xcbc->IV[xcbc->buflen++] ^= *in++;
+               --inlen;
+       }
+       return 1;
+}
+int xcbc_done(aes_xcbc_state *xcbc, unsigned char *out, unsigned int *outlen) {
+       unsigned int x;
+       if (xcbc == NULL || out == NULL) {
+               return 0;
+       }
+       /*
+        (4)
+        a)  If the blocksize of M[n] is 128 bits:
+        XOR M[n] with E[n-1] and Key K2, then encrypt the result with
+        Key K1, yielding E[n].
+        */
+       if (xcbc->buflen == xcbc->blocksize) {
+               for (x = 0; x < xcbc->blocksize; x++) {
+                       xcbc->IV[x] ^= xcbc->K[1][x];
+               }
+       } else {
+               /*
+                (4)
+                b)     If the blocksize of M[n] is less than 128 bits:
+                
+                i)  Pad M[n] with a single "1" bit, followed by the number of
+                "0" bits (possibly none) required to increase M[n]'s
+                blocksize to 128 bits.
+                
+                ii) XOR M[n] with E[n-1] and Key K3, then encrypt the result
+                with Key K1, yielding E[n].
+                
+                */
+               xcbc->IV[xcbc->buflen] ^= 0x80;
+               for (x = 0; x < xcbc->blocksize; x++) {
+                       xcbc->IV[x] ^= xcbc->K[2][x];
+               }
+       }
+       SDRM_AES128_Encryption(out, xcbc->IV, xcbc->key);
+       if (outlen != NULL) {
+               *outlen = xcbc->blocksize;
+       }
+       return 1;
+
+}
+
diff --git a/ssflib/dep/uci/source/uci_api.c b/ssflib/dep/uci/source/uci_api.c
new file mode 100755 (executable)
index 0000000..15cb5fc
--- /dev/null
@@ -0,0 +1,674 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+/** 
+ * @file uci_api.cpp 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.9.6
+ **/
+
+#include "uci_api.h"
+#include <stdio.h>
+#include <string.h>
+#include "uci_cryptocore.h"
+#include "uci_internal.h"
+#include "uci_hwcrypto.h"
+//#include "ae.h"
+#include "CC_Context.h"
+#include "uci_aes_xcbc_mac.h"
+
+#if 1
+#define TC_PRINT(fmt...) \
+    do { printf(fmt);}while(0)
+#else
+#define TC_PRINT(fmt...)\
+    do {;}while(0)
+#endif
+/*!    \brief  print out by byte unit  */
+#undef PrintBYTE
+#define g_bTAdbug 1
+#define TZ_PRINT(fmt...) \
+               do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+#define TZ_ERROR(fmt...) \
+               do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+#define PrintBYTE(msg, Data, DataLen) {                                        \
+       int idx;                                                                                        \
+       TC_PRINT("%10s =", msg);                                                                \
+       for(idx=0; idx<(int)DataLen; idx++) {                           \
+               if((idx!=0) && ((idx%16)==0)) TC_PRINT("\n");   \
+               if((idx % 4) == 0)      TC_PRINT(" 0x");                                \
+               TC_PRINT("%.2x", Data[idx]);                                            \
+       }                                                                                                       \
+       TC_PRINT("\n");                                                                         \
+}
+
+UCI_HANDLE uci_context_alloc(unsigned int algorithm, uci_engine_config_e config) {
+       unsigned int conf = SDRM_LOW_HALF(config);
+       uci_context_s *ctx;
+
+       if (algorithm < ID_UCI_X931 || algorithm > ID_UCI_AE_CCM) {
+               return UCI_ERROR;
+       }
+#if 0
+       if(algorithm == ID_UCI_AE_GCM)
+       {
+               ctx = OsaMalloc(sizeof(uci_context_s));
+               ctx->imp = OsaMalloc(sizeof(gcm_context));
+               ctx->alg = ID_UCI_AE_GCM;
+               return (int)ctx;
+       }
+       if(algorithm == ID_UCI_AE_CCM)
+       {
+               ctx = OsaMalloc(sizeof(uci_context_s));
+               ctx->imp = OsaMalloc(sizeof(aes_ccm_context));
+               ctx->alg = ID_UCI_AE_CCM;
+               return (int)ctx;
+       }
+#endif
+       if (algorithm == ID_UCI_XCBCMAC) {
+               ctx = (uci_context_s*)OsaMalloc(sizeof(uci_context_s));
+               ctx->imp = (aes_xcbc_state *)OsaMalloc(sizeof(aes_xcbc_state));
+               ctx->alg = ID_UCI_XCBCMAC;
+               return (int)ctx;
+       }
+       if (conf == UCI_SW_CRYPTOCORE) {
+               return cryptocore_context_alloc(algorithm);
+       }
+       if (conf == UCI_HW) {
+               return hwcrypto_context_alloc(algorithm, config);
+       }
+
+       return UCI_ERROR;
+}
+
+int uci_context_free(UCI_HANDLE oh) {
+       uci_context_s *pctx = (uci_context_s*)oh;
+       unsigned int conf;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+       conf = SDRM_LOW_HALF(pctx->config);
+       if (pctx->alg == ID_UCI_AE_GCM || pctx->alg == ID_UCI_AE_CCM
+           || pctx->alg == ID_UCI_XCBCMAC) {
+               OsaFree(pctx->imp);
+               OsaFree(pctx);
+               return UCI_SUCCESS;
+       }
+       if (conf == UCI_SW_CRYPTOCORE) {
+               return cryptocore_context_free(oh);
+       }
+       if (conf == UCI_HW) {
+               return hwcrypto_context_free(oh);
+       }
+       return UCI_ERROR;
+}
+
+int uci_md_init(UCI_HANDLE oh) {
+
+       return cryptocore_md_init(oh);
+
+}
+
+int uci_md_update(UCI_HANDLE oh, unsigned char *msg, unsigned int msg_len) {
+       return cryptocore_md_update(oh, msg, msg_len);
+
+}
+
+int uci_md_final(UCI_HANDLE oh, unsigned char *output) {
+       return cryptocore_md_final(oh, output);
+}
+
+int uci_md_get_hash(UCI_HANDLE oh, unsigned char *msg, unsigned int msg_len,
+    unsigned char *output) {
+
+       if (output == NULL) {
+               return UCI_ERROR;
+       }
+       return cryptocore_md_get_hash(oh, msg, msg_len, output);
+
+}
+
+int uci_mac_init(UCI_HANDLE oh, unsigned char *key, unsigned int key_len) {
+       int ret = 0;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx->alg == ID_UCI_XCBCMAC) {
+               ret = xcbc_init((aes_xcbc_state *)(pctx->imp), key, key_len);
+               if (ret != 1) {
+                       return UCI_ERROR;
+               } else {
+                       return UCI_SUCCESS;
+               }
+       }
+       return cryptocore_mac_init(oh, key, key_len);
+}
+
+int uci_mac_update(UCI_HANDLE oh, unsigned char *msg, unsigned int msg_len) {
+       int ret = 0;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx->alg == ID_UCI_XCBCMAC) {
+               ret = xcbc_process((aes_xcbc_state*)(pctx->imp), msg, msg_len);
+               if (ret != 1) {
+                       return UCI_ERROR;
+               } else {
+                       return UCI_SUCCESS;
+               }
+       }
+
+       return cryptocore_mac_update(oh, msg, msg_len);
+}
+
+int uci_mac_final(UCI_HANDLE oh, unsigned char *output,
+    unsigned int *output_len) {
+       int ret = 0;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx->alg == ID_UCI_XCBCMAC) {
+               ret = xcbc_done((aes_xcbc_state*)(pctx->imp), output, output_len);
+               if (ret != 1) {
+                       return UCI_ERROR;
+               } else {
+                       return UCI_SUCCESS;
+               }
+       }
+
+       return cryptocore_mac_final(oh, output, output_len);
+}
+
+int uci_mac_get_mac(UCI_HANDLE oh, unsigned char *key, unsigned int key_len,
+    unsigned char *msg, unsigned int msg_len, unsigned char *output,
+    unsigned int *output_len) {
+       //int ret = 0;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx->alg == ID_UCI_XCBCMAC) {
+               if (xcbc_init((aes_xcbc_state *)(pctx->imp), key, key_len) != 1) {
+                       return UCI_ERROR;
+               }
+
+               if (xcbc_process((aes_xcbc_state*)(pctx->imp), msg, msg_len) != 1) {
+                       return UCI_ERROR;
+               }
+
+               if (xcbc_done((aes_xcbc_state*)(pctx->imp), output, output_len) != 1) {
+                       return UCI_ERROR;
+               }
+               return UCI_SUCCESS;
+
+       }
+       return cryptocore_mac_getmac(oh, key, key_len, msg, msg_len, output,
+           output_len);
+}
+
+int uci_se_init(UCI_HANDLE oh, unsigned int mode, unsigned padding,
+    unsigned char *key, unsigned int key_len, unsigned char *iv) {
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+       unsigned conf = SDRM_LOW_HALF(pctx->config);
+       if (conf == UCI_SW_CRYPTOCORE) {
+               return cryptocore_se_init(oh, mode, padding, key, key_len, iv);
+       }
+       if (conf == UCI_HW) {
+               return hwcrypto_se_init(oh, mode, padding, key, key_len, iv);
+       }
+       return UCI_ERROR;
+}
+
+int uci_se_process(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char *output, unsigned int *output_len) {
+
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+       unsigned conf = SDRM_LOW_HALF(pctx->config);
+       if (input != NULL && output == NULL) {
+               return UCI_ERROR;
+       }
+       if (conf == UCI_SW_CRYPTOCORE) {
+               return cryptocore_se_process(oh, input, input_len, output, output_len);
+       }
+       if (conf == UCI_HW) {
+               return hwcrypto_se_process(oh, input, input_len, output, output_len);
+       }
+       return UCI_ERROR;
+}
+
+int uci_se_final(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char *output, unsigned int *output_len) {
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+       unsigned conf = SDRM_LOW_HALF(pctx->config);
+       if (input != NULL && output == NULL) {
+               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__);
+               return UCI_ERROR;
+       }
+       if (conf == UCI_SW_CRYPTOCORE) {
+               return cryptocore_se_final(oh, input, input_len, output, output_len);
+       }
+       if (conf == UCI_HW) {
+               return hwcrypto_se_final(oh, input, input_len, output, output_len);
+       }
+       TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__);
+       return UCI_ERROR;
+}
+
+int uci_se_encrypt_oneblock(UCI_HANDLE oh, unsigned char *cipher_text,
+    unsigned char *plain_text, unsigned char *user_key) {
+       if (cipher_text == NULL || plain_text == NULL || user_key == NULL) {
+               return UCI_ERROR;
+       }
+       return cryptocore_se_encrypt_oneblock(oh, cipher_text, plain_text, user_key);
+}
+
+int uci_se_decrypt_oneblock(UCI_HANDLE oh, unsigned char *plain_text,
+    unsigned char *cipher_text, unsigned char *user_key) {
+       if (cipher_text == NULL || plain_text == NULL || user_key == NULL) {
+               return UCI_ERROR;
+       }
+       return cryptocore_se_decrypt_oneblock(oh, cipher_text, plain_text, user_key);
+}
+
+int uci_wbse_init(UCI_HANDLE oh, int flag, unsigned char *key,
+    char *table_filepath, void *pencoder1, void *pencoder2) {
+       return UCI_ERROR;
+}
+
+int uci_wbse_final(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char *output, unsigned int output_len) {
+       return UCI_ERROR;
+}
+int uci_ae_gen_param(UCI_HANDLE oh, uci_param_s *param, unsigned int size) {
+       return cryptocore_ae_gen_param(oh, param, size);
+}
+
+int uci_ae_gen_keypair(UCI_HANDLE oh, uci_key_s *keymaterial,
+    uci_param_s *param) {
+       if (keymaterial == NULL) {
+               return UCI_ERROR;
+       }
+       return cryptocore_ae_gen_keypair(oh, keymaterial, param);
+
+}
+
+int uci_ae_set_keypair(UCI_HANDLE oh, uci_key_s *keymaterial,
+    uci_param_s *param) {
+       if (keymaterial == NULL) {
+               return UCI_ERROR;
+       }
+       return cryptocore_ae_set_keypair(oh, keymaterial, param);
+}
+
+int uci_ae_encrypt(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char *output, unsigned int *output_len) {
+       return cryptocore_ae_encrypt(oh, input, input_len, output, output_len);
+}
+
+int uci_ae_decrypt(UCI_HANDLE oh, unsigned char *input, unsigned int input_len,
+    unsigned char *output, unsigned int *output_len) {
+       return cryptocore_ae_decrypt(oh, input, input_len, output, output_len);
+}
+
+int uci_ae_decryptbycrt(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+       return cryptocore_ae_decryptbycrt(oh, input, input_len, output, output_len);
+}
+
+int uci_wbae_encrypt(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+       return UCI_ERROR;
+}
+
+int uci_wbae_decrypt(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+       return UCI_ERROR;
+}
+
+int uci_ds_sign(UCI_HANDLE oh, unsigned char *hash, unsigned int hash_len,
+    unsigned char *signature, unsigned int *sign_len) {
+
+       return cryptocore_ds_sign(oh, hash, hash_len, signature, sign_len);
+}
+
+int uci_ds_verify(UCI_HANDLE oh, unsigned char *hash, unsigned int hash_len,
+    unsigned char *signature, unsigned int sign_len, int *result) {
+
+       return cryptocore_ds_verify(oh, hash, hash_len, signature, sign_len, result);
+}
+
+int uci_dh_gen_phasekey(UCI_HANDLE oh, unsigned char *pch_xk,
+    unsigned char *pch_xv, uci_param_s *param) {
+       return cryptocore_dh_gen_dh1stphasekey(oh, pch_xk, pch_xv, param);
+}
+
+int uci_dh_gen_authkey(UCI_HANDLE oh, unsigned char *pch_xk,
+    unsigned char *pch_xv, unsigned char *pch_kauth) {
+       return cryptocore_dh_gen_dhkey(oh, pch_xk, pch_xv, pch_kauth);
+}
+
+int uci_prng_seed(UCI_HANDLE oh, unsigned char * seed) {
+       return cryptocore_prng_seed(oh, seed);
+}
+
+int uci_prng_get(UCI_HANDLE oh, unsigned int bit_len, unsigned char *data) {
+       return cryptocore_prng_get(oh, bit_len, data);
+}
+
+int uci_authcrypt_init(UCI_HANDLE oh, unsigned int mode, unsigned char *nonce,
+    unsigned int nonce_len, unsigned int tag_len, unsigned int aad_len,
+    unsigned int payload_len, unsigned char *key, unsigned int key_len) {
+#if 0 
+       uci_context_s *pctx = (uci_context_s*)oh;
+       gcm_context *gctx = NULL;
+       aes_ccm_context *cctx = NULL;
+       int ret;
+       if(pctx->alg == ID_UCI_AE_GCM)
+       {
+               gctx = (gcm_context *)pctx->imp;
+               if(gcm_init(gctx, key, key_len) != 0)
+               {
+                       return UCI_ERROR;
+               }
+               if(gcm_starts(gctx, mode, nonce, nonce_len) != 0)
+               {
+                       return UCI_ERROR;
+               }
+               pctx->flag = tag_len;
+       }
+       else if(pctx->alg == ID_UCI_AE_CCM)
+       {
+               cctx = (aes_ccm_context *)pctx->imp;
+               ret = aes_ccm_init(cctx, mode, key, key_len, nonce, nonce_len, tag_len, aad_len, payload_len);
+               if(ret != 0)
+               {
+                       printf("aes_ccm_init error. ret = %d\n ", ret);
+                       return UCI_ERROR;
+               }
+       }
+       else
+       {
+               printf("alg type erro \n");
+               return UCI_ERROR;
+
+       }
+
+       return UCI_SUCCESS;
+#endif
+       return UCI_ERROR;
+}
+int uci_authcrypt_update_aad(UCI_HANDLE oh, unsigned char *aad,
+    unsigned int aad_len) {
+#if 0
+       uci_context_s *pctx = (uci_context_s*)oh;
+       gcm_context *gctx;
+       aes_ccm_context *cctx;
+       if(pctx->alg == ID_UCI_AE_GCM)
+       {
+               gctx = (gcm_context *)pctx->imp;
+               if(gcm_update_add(gctx, aad, aad_len) != 0)
+               {
+                       return UCI_ERROR;
+               }
+       }
+       else if(pctx->alg == ID_UCI_AE_CCM)
+       {
+               cctx = (aes_ccm_context *)pctx->imp;
+               if(aes_ccm_update_aad(cctx,aad,aad_len) != 0)
+               {
+                       return UCI_ERROR;
+               }
+       }
+       else
+       {
+               return UCI_ERROR;
+       }
+
+       return UCI_SUCCESS;
+#endif 
+       return UCI_ERROR;
+}
+int uci_authcrypt_update(UCI_HANDLE oh, unsigned char *src,
+    unsigned int src_len, unsigned char *dest, unsigned int *dest_len) {
+#if 0
+       uci_context_s *pctx = (uci_context_s*)oh;
+       gcm_context *gctx;
+       aes_ccm_context *cctx;
+
+       if(pctx->alg == ID_UCI_AE_GCM)
+       {
+               gctx = (gcm_context *)pctx->imp;
+               if(gcm_update(gctx,src_len, src, dest) != 0)
+               {
+                       return UCI_ERROR;
+               }
+               *dest_len = src_len;
+       }
+       else if(pctx->alg == ID_UCI_AE_CCM)
+       {
+               cctx = (aes_ccm_context*)pctx->imp;
+               if(aes_ccm_process(cctx,src,src_len,dest,dest_len,NULL,NULL,0) != 0)
+               {
+                       return UCI_ERROR;
+               }
+       }
+       else
+       {
+               return UCI_ERROR;
+
+       }
+
+       return UCI_SUCCESS;
+#endif
+       return UCI_ERROR;
+}
+int uci_authcrypt_encryptfinal(UCI_HANDLE oh, unsigned char *src,
+    unsigned int src_len, unsigned char *dest, unsigned int *dest_len,
+    unsigned char *tag, unsigned int *tag_len) {
+#if 0
+       uci_context_s *pctx = (uci_context_s*)oh;
+       gcm_context *gctx = NULL;
+       aes_ccm_context *cctx = NULL;
+
+       int ret;
+       if(pctx->alg == ID_UCI_AE_GCM)
+       {
+
+               gctx = (gcm_context *)pctx->imp;
+               if(gcm_update(gctx,src_len, src, dest) != 0)
+               {
+                       return UCI_ERROR;
+               }
+               if(dest_len != NULL)
+               {
+                       *dest_len = src_len;
+               }
+               if((ret = gcm_finish(gctx, tag, pctx->flag)) != 0)
+               {
+                       printf("ERROR %d\n",ret);
+                       return UCI_ERROR;
+               }
+               if(tag_len != NULL)
+               {
+                       *tag_len= pctx->flag;
+               }
+       }
+       else if(pctx->alg == ID_UCI_AE_CCM)
+       {
+               cctx = (aes_ccm_context*)pctx->imp;
+               if(aes_ccm_process(cctx,src,src_len,dest,dest_len,tag,tag_len,1) != 0)
+               {
+                       return UCI_ERROR;
+               }
+       }
+       else
+       {
+               return UCI_ERROR;
+
+       }
+       return UCI_SUCCESS;
+#endif 
+       return UCI_ERROR;
+}
+int uci_authcrypt_decryptfinal(UCI_HANDLE oh, unsigned char *src,
+    unsigned int src_len, unsigned char *dest, unsigned int *dest_len,
+    unsigned char *tag, unsigned int tag_len) {
+#if 0
+       uci_context_s *pctx = (uci_context_s*)oh;
+       gcm_context *gctx;
+       aes_ccm_context *cctx;
+
+       unsigned char tmp[16] =
+       {       0x0,};
+       unsigned int len = 0;
+       len = tag_len;
+       if(pctx->alg == ID_UCI_AE_GCM)
+       {
+               gctx = (gcm_context *)pctx->imp;
+               if(gcm_update(gctx,src_len, src, dest) != 0)
+               {
+                       return UCI_ERROR;
+               }
+               *dest_len = src_len;
+               if(gcm_finish(gctx, tmp, pctx->flag) != 0)
+               {
+                       printf("gcm_finish error \n");
+                       return UCI_ERROR;
+               }
+               if(memcmp(tmp, tag, tag_len) != 0)
+               {
+                       PrintBYTE("tmp",tmp,tag_len);
+                       PrintBYTE("tag",tag,tag_len);
+                       printf("tag not right \n");
+                       return UCI_ERROR;
+               }
+       }
+       else if(pctx->alg == ID_UCI_AE_CCM)
+       {
+               cctx = (aes_ccm_context*)pctx->imp;
+               if(aes_ccm_process(cctx,src,src_len,dest,dest_len,tag,&len,1) != 0)
+               {
+                       return UCI_ERROR;
+               }
+       }
+       else
+       {
+               return UCI_ERROR;
+
+       }
+       return UCI_SUCCESS;
+#endif
+       return UCI_ERROR;
+}
+
+int uci_dup_handle(UCI_HANDLE srcoh, UCI_HANDLE destoh) {
+       uci_context_s *srcctx = (uci_context_s *)srcoh;
+       uci_context_s *destctx = NULL;
+       destoh = uci_context_alloc(srcctx->alg, (uci_engine_config_e)srcctx->config);
+       destctx = (uci_context_s *)destoh;
+       if (destctx == NULL) {
+               return UCI_ERROR;
+       }
+
+       switch (srcctx->alg) {
+#if 0
+               case ID_UCI_AE_GCM:
+               memcpy(destctx->imp, srcctx->imp, sizeof(gcm_context));
+               break;
+               case ID_UCI_AE_CCM:
+               memcpy(destctx->imp, srcctx->imp, sizeof(aes_ccm_context));
+               break;
+#endif
+               case ID_UCI_X931:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_X931Context));
+                       break;
+               case ID_UCI_MD5:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_MD5Context));
+                       break;
+               case ID_UCI_SHA1:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_SHA1Context));
+                       break;
+               case ID_UCI_SHA224:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_SHA224Context));
+                       break;
+               case ID_UCI_SHA256:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_SHA256Context));
+                       break;
+#ifndef _OP64_NOTSUPPORTED
+               case ID_UCI_SHA384:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_SHA384Context));
+                       break;
+               case ID_UCI_SHA512:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_SHA512Context));
+                       break;
+#endif
+               case ID_UCI_CMAC:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_CMACContext));
+                       break;
+               case ID_UCI_XCBCMAC:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(aes_xcbc_state));
+                       break;
+               case ID_UCI_HMD5:
+               case ID_UCI_HSHA1:
+               case ID_UCI_HSHA256:
+               case ID_UCI_HSHA224:
+#ifndef _OP64_NOTSUPPORTED
+               case ID_UCI_HSHA384:
+               case ID_UCI_HSHA512:
+#endif //_OP64_NOTSUPPORTED
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_HMACContext));
+                       break;
+               case ID_UCI_AES128:
+               case ID_UCI_AES192:
+               case ID_UCI_AES256:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_AESContext));
+                       break;
+               case ID_UCI_DES:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_DESContext));
+                       break;
+               case ID_UCI_TDES:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_TDESContext));
+                       break;
+               case ID_UCI_RC4:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_RC4Context));
+                       break;
+               case ID_UCI_SNOW2:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_SNOW2Context));
+                       break;
+               case ID_UCI_RSA512:
+               case ID_UCI_RSA:
+               case ID_UCI_RSA1024:
+               case ID_UCI_RSA2048:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_RSAContext));
+                       break;
+               case ID_UCI_DSA:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_DSAContext));
+                       break;
+               case ID_UCI_ECDSA:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_ECDSAContext));
+                       break;
+               case ID_UCI_ECDH:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_ECDHContext));
+                       break;
+               case ID_UCI_DH:
+                       memcpy(destctx->imp, srcctx->imp, sizeof(SDRM_DHContext));
+                       break;
+       }
+
+       return UCI_SUCCESS;
+}
+
diff --git a/ssflib/dep/uci/source/uci_cryptocore.c b/ssflib/dep/uci/source/uci_cryptocore.c
new file mode 100755 (executable)
index 0000000..db15895
--- /dev/null
@@ -0,0 +1,972 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+/** 
+ * @file uci_cryptocore.cpp 
+ * @brief UCI codec. 
+ * @author guoxing.xu 
+ * @version 1.0 
+ * @date 2013.9.9
+ **/
+
+#include "uci_cryptocore.h"
+#include <CC_API.h>
+#include "uci_internal.h"
+#include "uci_aes_xcbc_mac.h"
+#define g_bTAdbug 1
+#define TZ_PRINT(fmt...) \
+               do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+#define TZ_ERROR(fmt...) \
+               do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+
+UCI_HANDLE cryptocore_context_alloc(unsigned int algorithm) {
+       UCI_HANDLE fd;
+       uci_context_s* ctx;
+       CryptoCoreContainer *crt;
+
+       ctx = (uci_context_s*)OsaMalloc(sizeof(uci_context_s));
+       if (ctx == NULL) {
+               return UCI_MEM_ALLOR_ERROR;
+       }
+       fd = (UCI_HANDLE)ctx;
+       crt = create_CryptoCoreContainer(algorithm);
+       if (crt == NULL) {
+               OsaFree(ctx);
+               return UCI_MEM_ALLOR_ERROR;
+       }
+       ctx->imp = (void*)crt;
+       ctx->config = UCI_SW;
+       ctx->alg = algorithm;
+       return fd;
+
+}
+
+int cryptocore_context_free(UCI_HANDLE oh) {
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+       destroy_CryptoCoreContainer((CryptoCoreContainer*)pctx->imp);
+       OsaFree(pctx);
+       pctx = NULL;
+
+       return UCI_SUCCESS;
+}
+
+int cryptocore_md_init(UCI_HANDLE oh) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->MD_init(
+           (CryptoCoreContainer*)(pctx->imp));
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_md_update(UCI_HANDLE oh, unsigned char *msg,
+    unsigned int msg_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->MD_update(
+           ((CryptoCoreContainer*)pctx->imp), msg, msg_len);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_md_final(UCI_HANDLE oh, unsigned char *output) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->MD_final(
+           (CryptoCoreContainer*)pctx->imp, output);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_md_get_hash(UCI_HANDLE oh, unsigned char *msg,
+    unsigned int msg_len, unsigned char * output) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->MD_getHASH(
+           (CryptoCoreContainer*)pctx->imp, msg, msg_len, output);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_mac_init(UCI_HANDLE oh, unsigned char *key, unsigned int key_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+       ret = ((CryptoCoreContainer *)pctx->imp)->MAC_init(
+           (CryptoCoreContainer*)(pctx->imp), key, key_len);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_mac_update(UCI_HANDLE oh, unsigned char *msg,
+    unsigned int msg_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+       ret = ((CryptoCoreContainer *)pctx->imp)->MAC_update(
+           (CryptoCoreContainer*)(pctx->imp), msg, msg_len);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_mac_final(UCI_HANDLE oh, unsigned char *output,
+    unsigned int *output_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->MAC_final(
+           (CryptoCoreContainer*)(pctx->imp), output, output_len);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_mac_getmac(UCI_HANDLE oh, unsigned char *key,
+    unsigned int key_len, unsigned char *msg, unsigned int msg_len,
+    unsigned char *output, unsigned int *output_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->MAC_getMAC(
+           (CryptoCoreContainer*)(pctx->imp), key, key_len, msg, msg_len, output,
+           output_len);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_se_init(UCI_HANDLE oh, unsigned int mode, unsigned padding,
+    unsigned char *key, unsigned int key_len, unsigned char *iv) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+       //deal with CTS base CBC
+       if (mode == ID_UCI_ENC_CTS || mode == ID_UCI_DEC_CTS) {
+               pctx->flag = mode;
+               if (mode == ID_UCI_ENC_CTS) {
+                       ret = ((CryptoCoreContainer *)pctx->imp)->SE_init(
+                           (CryptoCoreContainer*)(pctx->imp), ID_UCI_ENC_CBC,
+                           ID_UCI_ZERO_PADDING, key, key_len, iv);
+               } else {
+                       ret = ((CryptoCoreContainer *)pctx->imp)->SE_init(
+                           (CryptoCoreContainer*)(pctx->imp), ID_UCI_DEC_CBC,
+                           ID_UCI_ZERO_PADDING, key, key_len, iv);
+               }
+       } else {
+               ret = ((CryptoCoreContainer *)pctx->imp)->SE_init(
+                   (CryptoCoreContainer*)(pctx->imp), mode, padding, key, key_len, iv);
+       }
+       if (ret == CRYPTO_INVALID_ARGUMENT) {
+               return UCI_INVALID_ARGUMENT;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+
+       return UCI_SUCCESS;
+}
+
+int cryptocore_se_process(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->SE_process(
+           (CryptoCoreContainer*)(pctx->imp), input, input_len, output, output_len);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_se_final(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+       int ret;
+       unsigned int lastblocksize = 0;
+       unsigned char lastblock[SDRM_AES_BLOCK_SIZ];
+       unsigned char secondlastblock[SDRM_AES_BLOCK_SIZ];
+       unsigned char aIV[SDRM_AES_BLOCK_SIZ] = {0x0, };
+       uci_context_s *pctx = (uci_context_s*)oh;
+       unsigned char *psecondlastblk = NULL; //point to second last block
+       unsigned char *plastblk = NULL; //point to last block
+       CryptoCoreContainer *crt = NULL;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       crt = (CryptoCoreContainer*)(pctx->imp);
+
+       if (input_len <= SDRM_AES_BLOCK_SIZ) {
+               goto final;
+       }
+
+       plastblk = input + SDRM_AES_BLOCK_SIZ;
+       psecondlastblk = input;
+
+       //cts encrypt
+       if (pctx->flag == ID_UCI_ENC_CTS) {
+
+#if 0       
+               lastblocksize = input_len % SDRM_AES_BLOCK_SIZ;
+               if(lastblocksize == 0)
+               {
+                       lastblocksize = 16;
+               }
+
+               ret = crt->SE_process(crt, psecondlastblk, SDRM_AES_BLOCK_SIZ, lastblock, output_len);
+               if(ret!=CRYPTO_SUCCESS)
+               {
+                       return UCI_ERROR;
+               }
+#endif
+               if (input_len % SDRM_AES_BLOCK_SIZ == 0) {
+                       crt->ctx->aesctx->padding = ID_NO_PADDING;
+               }
+               ret = crt->SE_final(crt, input, input_len, output, output_len);
+               if (ret != CRYPTO_SUCCESS) {
+                       return UCI_ERROR;
+               }
+               //swap last block
+               memcpy(lastblock, output + *output_len - 2 * SDRM_AES_BLOCK_SIZ,
+               SDRM_AES_BLOCK_SIZ);
+               memcpy(output + *output_len - 2 * SDRM_AES_BLOCK_SIZ,
+                   output + *output_len - SDRM_AES_BLOCK_SIZ,
+                   SDRM_AES_BLOCK_SIZ);
+               memcpy(output + *output_len - SDRM_AES_BLOCK_SIZ, lastblock,
+               SDRM_AES_BLOCK_SIZ);
+               return UCI_SUCCESS;
+
+       }
+       //cts decrypt
+       if (pctx->flag == ID_UCI_DEC_CTS) {
+               lastblocksize = input_len % SDRM_AES_BLOCK_SIZ;
+
+               if (input_len != 2 * SDRM_AES_BLOCK_SIZ) {
+                       //1.Dn = Decrypt (K, Cn-1). Decrypt the second to last ciphertext block, using zeros as IV.
+
+                       memcpy(aIV, crt->ctx->aesctx->IV, SDRM_AES_BLOCK_SIZ);
+                       memset(crt->ctx->aesctx->IV, 0, SDRM_AES_BLOCK_SIZ);
+
+                       memset(crt->ctx->aesctx->Block, 0, SDRM_AES_BLOCK_SIZ);
+
+                       crt->ctx->aesctx->BlockLen = 0;
+                       ret = crt->SE_process(crt, psecondlastblk,
+                       SDRM_AES_BLOCK_SIZ, secondlastblock, output_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+                               return UCI_ERROR;
+                       }
+
+                       // 2. Cn = Cn || Tail (Dn, B-M). Pad the ciphertext to the nearest multiple of the block size using the last B-M bits of block cipher decryption of the second-to-last ciphertext block.
+                       memcpy(lastblock, plastblk, lastblocksize);
+                       memcpy(lastblock + lastblocksize, secondlastblock + lastblocksize,
+                       SDRM_AES_BLOCK_SIZ - lastblocksize);
+                       memcpy(crt->ctx->aesctx->IV, aIV, SDRM_AES_BLOCK_SIZ);
+                       // 3. Swap the last two ciphertext blocks.
+
+                       // 4. Decrypt the (modified) ciphertext using the standard CBC mode up to the last block.
+                       ret = crt->SE_process(crt, lastblock,
+                       SDRM_AES_BLOCK_SIZ, output, output_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+                               return UCI_ERROR;
+                       }
+                       ret = crt->SE_process(crt, psecondlastblk,
+                       SDRM_AES_BLOCK_SIZ, lastblock, output_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+                               return UCI_ERROR;
+                       }
+                       memcpy(output + SDRM_AES_BLOCK_SIZ, lastblock, lastblocksize);
+                       *output_len = input_len;
+                       return UCI_SUCCESS;
+               }
+               //swap last two block and decrypto
+               if (input_len == 2 * SDRM_AES_BLOCK_SIZ) {
+                       ret = crt->SE_process(crt, input + SDRM_AES_BLOCK_SIZ,
+                       SDRM_AES_BLOCK_SIZ, output, output_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+                               return UCI_ERROR;
+                       }
+                       crt->ctx->aesctx->padding = ID_NO_PADDING;
+                       ret = crt->SE_final(crt, input,
+                       SDRM_AES_BLOCK_SIZ, output + SDRM_AES_BLOCK_SIZ, output_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+                               return UCI_ERROR;
+                       }
+                       *output_len = 2 * SDRM_AES_BLOCK_SIZ;
+                       return UCI_SUCCESS;
+               }
+       }
+// deal with other mode except cts
+       final: ret = crt->SE_final(crt, input, input_len, output, output_len);
+       if (ret != CRYPTO_SUCCESS) {
+                               TZ_ERROR("UCI_ERROR error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+int cryptocore_se_encrypt_oneblock(UCI_HANDLE oh, unsigned char *cipher_text,
+    unsigned char * plain_text, unsigned char *user_key) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->SE_EncryptOneBlock(cipher_text,
+           plain_text, user_key);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_se_decrypt_oneblock(UCI_HANDLE oh, unsigned char *plain_text,
+    unsigned char *cipher_text, unsigned char *user_key) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->SE_DecryptOneBlock(cipher_text,
+           plain_text, user_key);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ae_gen_param(UCI_HANDLE oh, uci_param_s *param,
+    unsigned int size) {
+       int ret;
+       unsigned int alg;
+       //uci_param_imp_u *uciparm = NULL;
+       CryptoCoreContainer *crt = NULL;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (param == NULL) {
+               return UCI_INVALID_ARGUMENT;
+       }
+
+       alg = pctx->alg;
+
+       switch (alg) {
+               case ID_UCI_DH:
+                       crt = create_CryptoCoreContainer(ID_DH);
+                       if (crt == NULL) {
+                               return UCI_ERROR;
+                       }
+                       if (crt->DH_GenerateParam(crt, param->uparam.udhp.prime, size,
+                           param->uparam.udhp.generator) != CRYPTO_SUCCESS) {
+                               destroy_CryptoCoreContainer(crt);
+                               return UCI_ERROR;
+                       }
+                       param->uparam.udhp.len = size;
+                       destroy_CryptoCoreContainer(crt);
+                       break;
+               case ID_UCI_DSA:
+                       crt = create_CryptoCoreContainer(ID_DSA);
+                       if (crt == NULL) {
+                               return UCI_ERROR;
+                       }
+
+                       ret = crt->DSA_genParam(crt, size, param->uparam.udp.dsa_p_data,
+                           &(param->uparam.udp.dsa_p_len), param->uparam.udp.dsa_q_data,
+                           &(param->uparam.udp.dsa_q_len), param->uparam.udp.dsa_g_data,
+                           &(param->uparam.udp.dsa_g_len));
+
+                       if (ret != UCI_SUCCESS) {
+                               destroy_CryptoCoreContainer(crt);
+                               return UCI_ERROR;
+                       }
+                       destroy_CryptoCoreContainer(crt);
+                       break;
+               default:
+                       return UCI_INVALID_HANDLE;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ae_gen_keypair(UCI_HANDLE oh, uci_key_s *keymaterial,
+    uci_param_s *param) {
+       uci_context_s *pctx = (uci_context_s*)oh;
+       unsigned int alg;
+       unsigned int pad;
+       uci_key_s *ucikey = keymaterial;
+       int ret = UCI_ERROR;
+       uci_param_imp_u *uciparm = NULL;
+       if (param == NULL) {
+               return UCI_INVALID_ARGUMENT;
+       }
+       uciparm = &param->uparam;
+
+       if (pctx->config != UCI_SW_CRYPTOCORE) {
+               return UCI_INVALID_HANDLE;
+       }
+       alg = pctx->alg;
+       switch (alg) {
+               case ID_UCI_RSA512:
+               case ID_UCI_RSA:
+               case ID_UCI_RSA1024:
+               case ID_UCI_RSA2048:
+               case ID_UCI_RSA3072:
+                       pad = SDRM_LOW_HALF(uciparm->urp.padding);
+                       if (pad != ID_UCI_RSAES_PKCS15 && pad != ID_UCI_RSAES_OAEP
+                           && pad != ID_UCI_NO_PADDING && pad != ID_UCI_RSASSA_PKCS15
+                           && pad != ID_UCI_RSASSA_PSS) {
+                               return UCI_INVALID_ARGUMENT;
+                       }
+                       if (uciparm->urp.flag == RSA_GENKEYWITHNON) {
+                               ret = ((CryptoCoreContainer *)pctx->imp)->RSA_genKeypair(
+                                   (CryptoCoreContainer *)pctx->imp, uciparm->urp.padding,
+                                   ucikey->imp.rkey.n, &(ucikey->imp.rkey.n_len), ucikey->imp.rkey.e,
+                                   &(ucikey->imp.rkey.e_len), ucikey->imp.rkey.d,
+                                   &(ucikey->imp.rkey.d_len));
+                               break;
+                       }
+                       if (uciparm->urp.flag == RSA_GENKEYWITHE) {
+                               ret = ((CryptoCoreContainer *)pctx->imp)->RSA_genKeypairWithE(
+                                   (CryptoCoreContainer *)pctx->imp, uciparm->urp.padding,
+                                   uciparm->urp.e, uciparm->urp.e_len, ucikey->imp.rkey.n,
+                                   &(ucikey->imp.rkey.n_len), ucikey->imp.rkey.d,
+                                   &(ucikey->imp.rkey.d_len));
+                               break;
+                       }
+                       if (uciparm->urp.flag == RSA_GENKEYWITHPQE) {
+                               ret = ((CryptoCoreContainer *)pctx->imp)->RSA_genKeyDWithPQE(
+                                   (CryptoCoreContainer *)pctx->imp, uciparm->urp.padding,
+                                   uciparm->urp.e, uciparm->urp.e_len, uciparm->urp.p,
+                                   uciparm->urp.p_len, uciparm->urp.q, uciparm->urp.q_len,
+                                   ucikey->imp.rkey.n, &(ucikey->imp.rkey.n_len), ucikey->imp.rkey.d,
+                                   &(ucikey->imp.rkey.d_len));
+                               break;
+                       }
+                       if (uciparm->urp.flag == RSA_KEYFORCRT) {
+                               ret = ((CryptoCoreContainer *)pctx->imp)->RSA_genKeypairForCRT(
+                                   (CryptoCoreContainer *)pctx->imp, uciparm->urp.padding,
+                                   ucikey->imp.rkey.n, &(ucikey->imp.rkey.n_len), ucikey->imp.rkey.e,
+                                   &(ucikey->imp.rkey.e_len), ucikey->imp.rkey.d,
+                                   &(ucikey->imp.rkey.d_len), uciparm->urp.p, &(uciparm->urp.p_len),
+                                   uciparm->urp.q, &(uciparm->urp.q_len), uciparm->urp.dmodp1,
+                                   &(uciparm->urp.dmodp1_len), uciparm->urp.dmodq1,
+                                   &(uciparm->urp.dmodq1_len), uciparm->urp.iqp,
+                                   &(uciparm->urp.iqp_len));
+                       }
+                       break;
+               case ID_UCI_DSA:
+                       ret = ((CryptoCoreContainer *)pctx->imp)->DSA_setParam(
+                           (CryptoCoreContainer *)pctx->imp, uciparm->udp.dsa_p_data,
+                           uciparm->udp.dsa_p_len, uciparm->udp.dsa_q_data,
+                           uciparm->udp.dsa_q_len, uciparm->udp.dsa_g_data,
+                           uciparm->udp.dsa_g_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               return UCI_ERROR;
+                       }
+
+                       ret = ((CryptoCoreContainer *)pctx->imp)->DSA_genKeypair(
+                           (CryptoCoreContainer *)pctx->imp, ucikey->imp.dkey.ydata,
+                           &(ucikey->imp.dkey.ydata_len), ucikey->imp.dkey.xdata,
+                           &(ucikey->imp.dkey.xdata_len));
+                       break;
+               case ID_UCI_ECDSA:
+               case ID_UCI_ECDH:
+                       //set curver parameter 
+                       ret = ((CryptoCoreContainer *)pctx->imp)->EC_setCurve(
+                           (CryptoCoreContainer *)pctx->imp, uciparm->uep.dimension,
+                           uciparm->uep.ecc_p_data, uciparm->uep.ecc_p_len,
+                           uciparm->uep.ecc_a_data, uciparm->uep.ecc_a_len,
+                           uciparm->uep.ecc_b_data, uciparm->uep.ecc_b_len,
+                           uciparm->uep.ecc_g_x_data, uciparm->uep.ecc_g_x_len,
+                           uciparm->uep.ecc_g_y_data, uciparm->uep.ecc_g_y_len,
+                           uciparm->uep.ecc_r_data, uciparm->uep.ecc_r_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               break;
+                       }
+
+                       ret = ((CryptoCoreContainer *)pctx->imp)->EC_genKeypair(
+                           (CryptoCoreContainer *)pctx->imp, ucikey->imp.ekey.privatekey,
+                           &(ucikey->imp.ekey.privatekey_len), ucikey->imp.ekey.publickey_x,
+                           &(ucikey->imp.ekey.publickey_x_len), ucikey->imp.ekey.publickey_y,
+                           &(ucikey->imp.ekey.publickey_y_len));
+                       break;
+               default:
+                       return UCI_ERROR;
+       }
+       if (ret == CRYPTO_INVALID_ARGUMENT) {
+               return UCI_INVALID_ARGUMENT;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+
+}
+
+int cryptocore_ae_set_keypair(UCI_HANDLE oh, uci_key_s *keymaterial,
+    uci_param_s *param) {
+       uci_context_s *pctx = (uci_context_s*)oh;
+       uci_key_s *ucikey = keymaterial;
+       uci_param_imp_u *uciparm = &param->uparam;
+       int ret;
+       unsigned int pad;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+       int alg = pctx->alg;
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       switch (alg) {
+               case ID_UCI_RSA512:
+               case ID_UCI_RSA:
+               case ID_UCI_RSA1024:
+               case ID_UCI_RSA2048:
+               case ID_UCI_RSA3072:
+                       pad = SDRM_LOW_HALF(uciparm->urp.padding);
+
+                       if (pad != ID_UCI_RSAES_PKCS15 && pad != ID_UCI_RSAES_OAEP
+                           && pad != ID_UCI_NO_PADDING && pad != ID_UCI_RSASSA_PKCS15
+                           && pad != ID_UCI_RSASSA_PSS) {
+                               return UCI_INVALID_ARGUMENT;
+                       }
+
+                       if (uciparm->urp.flag == RSA_KEYFORCRT) {
+                               ret = ((CryptoCoreContainer *)pctx->imp)->RSA_setKeypairForCRT(
+                                   (CryptoCoreContainer *)pctx->imp, uciparm->urp.padding,
+                                   ucikey->imp.rkey.n, ucikey->imp.rkey.n_len, ucikey->imp.rkey.e,
+                                   ucikey->imp.rkey.e_len, ucikey->imp.rkey.d, ucikey->imp.rkey.d_len,
+                                   uciparm->urp.p, uciparm->urp.p_len, uciparm->urp.q,
+                                   uciparm->urp.q_len, uciparm->urp.dmodp1, uciparm->urp.dmodp1_len,
+                                   uciparm->urp.dmodq1, uciparm->urp.dmodq1_len, uciparm->urp.iqp,
+                                   uciparm->urp.iqp_len);
+                       } else {
+                               ret = ((CryptoCoreContainer *)pctx->imp)->RSA_setKeypair(
+                                   (CryptoCoreContainer *)pctx->imp, uciparm->urp.padding,
+                                   ucikey->imp.rkey.n, ucikey->imp.rkey.n_len, ucikey->imp.rkey.e,
+                                   ucikey->imp.rkey.e_len, ucikey->imp.rkey.d, ucikey->imp.rkey.d_len);
+                       }
+                       break;
+               case ID_UCI_DSA:
+                       ret = ((CryptoCoreContainer *)pctx->imp)->DSA_setParam(
+                           (CryptoCoreContainer *)pctx->imp, uciparm->udp.dsa_p_data,
+                           uciparm->udp.dsa_p_len, uciparm->udp.dsa_q_data,
+                           uciparm->udp.dsa_q_len, uciparm->udp.dsa_g_data,
+                           uciparm->udp.dsa_g_len);
+                       if (ret != CRYPTO_SUCCESS) {
+                               return UCI_ERROR;
+                       }
+                       ret = ((CryptoCoreContainer *)pctx->imp)->DSA_setKeyPair(
+                           (CryptoCoreContainer *)pctx->imp, ucikey->imp.dkey.ydata,
+                           (ucikey->imp.dkey.ydata_len), ucikey->imp.dkey.xdata,
+                           (ucikey->imp.dkey.xdata_len));
+                       break;
+               case ID_UCI_ECDSA:
+                       ret = ((CryptoCoreContainer *)pctx->imp)->EC_setCurve(
+                           (CryptoCoreContainer *)pctx->imp, uciparm->uep.dimension,
+                           uciparm->uep.ecc_p_data, uciparm->uep.ecc_p_len,
+                           uciparm->uep.ecc_a_data, uciparm->uep.ecc_a_len,
+                           uciparm->uep.ecc_b_data, uciparm->uep.ecc_b_len,
+                           uciparm->uep.ecc_g_x_data, uciparm->uep.ecc_g_x_len,
+                           uciparm->uep.ecc_g_y_data, uciparm->uep.ecc_g_y_len,
+                           uciparm->uep.ecc_r_data, uciparm->uep.ecc_r_len);
+
+                       ret = ((CryptoCoreContainer *)pctx->imp)->EC_setKeypair(
+                           (CryptoCoreContainer *)pctx->imp, ucikey->imp.ekey.privatekey,
+                           (ucikey->imp.ekey.privatekey_len), ucikey->imp.ekey.publickey_x,
+                           (ucikey->imp.ekey.publickey_x_len), ucikey->imp.ekey.publickey_y,
+                           (ucikey->imp.ekey.publickey_y_len));
+                       break;
+               case ID_UCI_DH:
+                       ret = ((CryptoCoreContainer *)pctx->imp)->DH_SetParam(
+                           (CryptoCoreContainer *)pctx->imp, uciparm->udhp.prime,
+                           uciparm->udhp.len, uciparm->udhp.generator, uciparm->udhp.len);
+                       break;
+               default:
+                       return UCI_ERROR;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ae_encrypt(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->alg < ID_UCI_RSA || pctx->alg > ID_UCI_RSA512) {
+               return UCI_INVALID_HANDLE;
+       }
+       ret = ((CryptoCoreContainer *)pctx->imp)->AE_encrypt(
+           ((CryptoCoreContainer*)pctx->imp), input, input_len, output, output_len);
+       if (ret == CRYPTO_MSG_TOO_LONG) {
+               return UCI_MSG_TOO_LONG;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ae_decrypt(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->alg < ID_UCI_RSA || pctx->alg > ID_UCI_RSA512) {
+               return UCI_INVALID_HANDLE;
+       }
+       ret = ((CryptoCoreContainer *)pctx->imp)->AE_decrypt(
+           ((CryptoCoreContainer*)pctx->imp), input, input_len, output, output_len);
+       if (ret == CRYPTO_MSG_TOO_LONG) {
+               return UCI_MSG_TOO_LONG;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ae_decryptbycrt(UCI_HANDLE oh, unsigned char *input,
+    unsigned int input_len, unsigned char *output, unsigned int *output_len) {
+
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       //  ctr=(CryptoCoreContainer *)(pctx->imp);
+       //  ctr->MD_update(ctr,msg,msg_len);
+       ret = ((CryptoCoreContainer *)pctx->imp)->AE_decryptByCRT(
+           ((CryptoCoreContainer*)pctx->imp), input, input_len, output, output_len);
+       if (ret == CRYPTO_MSG_TOO_LONG) {
+               return UCI_MSG_TOO_LONG;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ds_sign(UCI_HANDLE oh, unsigned char *hash,
+    unsigned int hash_len, unsigned char *signature, unsigned int *sign_len) {
+
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->DS_sign(
+           ((CryptoCoreContainer*)pctx->imp), hash, hash_len, signature, sign_len);
+       if (ret == CRYPTO_MSG_TOO_LONG) {
+               return UCI_MSG_TOO_LONG;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_ds_verify(UCI_HANDLE oh, unsigned char *hash,
+    unsigned int hash_len, unsigned char *signature, unsigned int sign_len,
+    int *result) {
+
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       ret = ((CryptoCoreContainer *)pctx->imp)->DS_verify(
+           (CryptoCoreContainer*)pctx->imp, hash, hash_len, signature, sign_len,
+           result);
+       if (ret == CRYPTO_MSG_TOO_LONG) {
+               return UCI_MSG_TOO_LONG;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_dh_gen_dh1stphasekey(UCI_HANDLE oh, unsigned char *pch_xk,
+    unsigned char *pch_xv, uci_param_s *param) {
+       int ret;
+       uci_param_imp_u *uciparam = &param->uparam;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       unsigned int alg;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       alg = pctx->alg;
+       if (alg == ID_UCI_ECDH) {
+               ret = ((CryptoCoreContainer *)pctx->imp)->EC_setCurve(
+                   (CryptoCoreContainer *)pctx->imp, uciparam->uep.dimension,
+                   uciparam->uep.ecc_p_data, uciparam->uep.ecc_p_len,
+                   uciparam->uep.ecc_a_data, uciparam->uep.ecc_a_len,
+                   uciparam->uep.ecc_b_data, uciparam->uep.ecc_b_len,
+                   uciparam->uep.ecc_g_x_data, uciparam->uep.ecc_g_x_len,
+                   uciparam->uep.ecc_g_y_data, uciparam->uep.ecc_g_y_len,
+                   uciparam->uep.ecc_r_data, uciparam->uep.ecc_r_len);
+
+               if (ret != CRYPTO_SUCCESS) {
+                       return UCI_ERROR;
+               }
+               ret = ((CryptoCoreContainer *)pctx->imp)->ECDH_Gen1stPhaseKey(
+                   (CryptoCoreContainer*)pctx->imp, pch_xk, pch_xv);
+               if (ret != CRYPTO_SUCCESS) {
+                       return UCI_ERROR;
+               } else {
+                       return UCI_SUCCESS;
+               }
+       }
+       if (alg == ID_UCI_DH) {
+               ret = ((CryptoCoreContainer *)pctx->imp)->DH_SetParam(
+                   (CryptoCoreContainer *)pctx->imp, uciparam->udhp.prime,
+                   uciparam->udhp.len, uciparam->udhp.generator, uciparam->udhp.len);
+
+               if (ret != CRYPTO_SUCCESS) {
+                       return UCI_ERROR;
+               }
+               ret = ((CryptoCoreContainer *)pctx->imp)->DH_Gen1stPhaseKey(
+                   (CryptoCoreContainer*)pctx->imp, pch_xk, pch_xv);
+               if (ret != CRYPTO_SUCCESS) {
+                       return UCI_ERROR;
+               } else {
+                       return UCI_SUCCESS;
+               }
+       }
+       return UCI_ERROR;
+}
+
+int cryptocore_dh_gen_dhkey(UCI_HANDLE oh, unsigned char *pch_xk,
+    unsigned char *pch_xv, unsigned char *pch_kauth) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       unsigned int alg;
+
+       if (pctx->config != UCI_SW_CRYPTOCORE) {
+               return UCI_INVALID_HANDLE;
+       }
+       alg = pctx->alg;
+
+       if (alg == ID_UCI_ECDH) {
+               ret = ((CryptoCoreContainer *)pctx->imp)->ECDH_GenAuthKey(
+                   (CryptoCoreContainer*)pctx->imp, pch_xk, pch_xv, pch_kauth);
+       } else if (alg == ID_UCI_DH) {
+               ret = ((CryptoCoreContainer *)pctx->imp)->DH_GenAuthKey(
+                   (CryptoCoreContainer*)pctx->imp, pch_xk, pch_xv, pch_kauth);
+       } else {
+               return UCI_INVALID_HANDLE;
+       }
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return CRYPTO_SUCCESS;
+
+}
+
+int cryptocore_prng_seed(UCI_HANDLE oh, unsigned char *seed) {
+
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+       if (pctx->alg != ID_UCI_X931) {
+               return UCI_INVALID_HANDLE;
+       }
+       ret = ((CryptoCoreContainer *)pctx->imp)->PRNG_seed(
+           (CryptoCoreContainer*)(pctx->imp), seed);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
+int cryptocore_prng_get(UCI_HANDLE oh, unsigned int bit_len,
+    unsigned char *data) {
+       int ret;
+       uci_context_s *pctx = (uci_context_s*)oh;
+       if (pctx == NULL) {
+               return UCI_INVALID_HANDLE;
+       }
+
+       if (pctx->config != UCI_SW) {
+               return UCI_INVALID_HANDLE;
+       }
+       if (pctx->alg != ID_UCI_X931) {
+               return UCI_INVALID_HANDLE;
+       }
+       ret = ((CryptoCoreContainer *)pctx->imp)->PRNG_get(
+           (CryptoCoreContainer*)(pctx->imp), bit_len, data);
+       if (ret != CRYPTO_SUCCESS) {
+               return UCI_ERROR;
+       }
+       return UCI_SUCCESS;
+}
+
diff --git a/ssflib/dep/uci/source/uci_hwcrypto.c b/ssflib/dep/uci/source/uci_hwcrypto.c
new file mode 100755 (executable)
index 0000000..ff15c41
--- /dev/null
@@ -0,0 +1,813 @@
+/*
+* Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#define PC_I586
+
+/** 
+* @file uci_hwcrypto.cpp
+* @brief UCI codec.
+* @author guoxing.xu
+* @version 1.0
+* @date 2013.11
+**/
+#ifndef PC_I586
+#include <fcntl.h>
+#include <crypto.h>
+#include <tee_internal_api.h>
+#include <unistd.h>
+#else
+#include <CC_API.h>
+#endif
+#include "uci_internal.h"
+#include "uci_hwcrypto.h"
+#include <stdio.h>
+
+
+/*!    \brief  print out by byte unit  */
+#undef PrintBYTE
+#define PrintBYTE(msg, Data, DataLen) {                                        \
+       int idx;                                                                                        \
+       printf("%10s =", msg);                                                          \
+       for( idx=0; idx<(int)DataLen; idx++) {                          \
+               if( (idx!=0) && ((idx%16)==0) ) printf("\n");   \
+               if((idx % 4) == 0)      printf(" 0x");                          \
+               printf("%.2x", Data[idx]);                                              \
+       }                                                                                                       \
+       printf("\n");                                                                           \
+}
+
+#define g_bTAdbug 0
+#define TA_PRINT(fmt...) \
+    do {if (g_bTAdbug) printf(fmt);}while(0)
+#define TA_ERROR(fmt...) \
+    do {if (g_bTAdbug) printf(fmt);}while(0)
+
+/*! \brief  convert 32-bit unit to 4 byte   */
+#undef GET_UINT32
+#define GET_UINT32(n,b,i)                                                              \
+        {                                                       \
+            (n) = ((unsigned int)((b)[(i)    ]) << 24 )         \
+                | ((unsigned int)((b)[(i) + 1]) << 16 )         \
+                | ((unsigned int)((b)[(i) + 2]) <<  8 )         \
+                | ((unsigned int)((b)[(i) + 3])       );        \
+        }
+
+UCI_HANDLE  hwcrypto_context_alloc(unsigned int algorithm, uci_engine_config_e config)
+{
+
+    UCI_HANDLE fd;
+    uci_context_s* ctx;
+    ctx = (uci_context_s*)malloc(sizeof(uci_context_s));
+    if(ctx == NULL)
+    {
+        return UCI_MEM_ALLOR_ERROR;
+    }
+    ctx->config = config;
+    ctx->alg    = algorithm;
+#ifndef PC_I586
+    ctx->imp    = malloc(sizeof(struct crypt_info));
+#else
+    ctx->imp    = create_CryptoCoreContainer(algorithm);
+#endif
+       if(ctx->imp == NULL)
+       {
+           free(ctx);
+               return UCI_MEM_ALLOR_ERROR;
+       }
+       fd = (UCI_HANDLE)ctx;
+    return fd;
+}
+
+int hwcrypto_context_free( UCI_HANDLE  oh )
+{
+    uci_context_s *pctx = (uci_context_s*)oh;
+    if(pctx == NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    if(pctx->imp != NULL)
+    {
+#ifndef PC_I586
+        free(pctx->imp);
+#else
+        destroy_CryptoCoreContainer((CryptoCoreContainer*)pctx->imp);
+#endif
+        pctx->imp = NULL;
+    }
+#ifndef PC_I586
+    /*close crypto handle*/
+    if(pctx->handle >= 0)
+    {
+        close(pctx->handle);
+    }
+#endif
+    free(pctx);
+    pctx = NULL;
+    return UCI_SUCCESS;
+}
+
+int hwcrypto_se_init(UCI_HANDLE  oh, unsigned int mode, unsigned int  padding, unsigned char *key, unsigned int key_len, unsigned char *iv)
+{
+#ifndef PC_I586
+    uci_context_s      *pctx;
+    struct crypt_info  *info;
+    unsigned int keytype;
+    int ret = 0;
+    pctx = (uci_context_s*)oh;
+    if(pctx == NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    info = (struct crypt_info*)pctx->imp;
+    keytype = SDRM_HIGH_HALF(pctx->config);
+
+
+    if(keytype == UCI_USER_KEY && key == NULL)
+    {
+        return UCI_ERROR;
+    }
+
+    switch(pctx->alg)
+    {
+        case ID_UCI_AES128:
+            switch(mode)
+            {
+                case ID_UCI_ENC_CBC:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_CBC_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_CBC;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_CBC;
+                    break;
+                case ID_UCI_ENC_CTR:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_CTR_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_CTR;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_CTR;
+                    break;
+                case ID_UCI_ENC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_ECB_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_ECB;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_ECB;
+                    break;
+                case ID_UCI_DEC_CBC:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_CBC_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_CBC | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_CBC;
+                    break;
+                case ID_UCI_DEC_CTR:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_CTR_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_CTR | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_CTR;
+                    break;
+                case ID_UCI_DEC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_ECB_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_ECB | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_ECB;
+                    break;
+                default:
+                    return UCI_INVALID_ARGUMENT;
+            }
+            info->keylen = 16;
+            info->ivlen = 16;
+            break;
+        case ID_UCI_AES256:/*now only support ecb and ctr*/
+            switch(mode)
+            {
+                case ID_UCI_ENC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_ECB_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_ECB;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_ECB;
+                    break;
+                case ID_UCI_DEC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_ECB_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_ECB | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_ECB;
+                    break;
+                case ID_UCI_ENC_CTR:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_CTR_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_CTR;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_CTR;
+                    break;
+                case ID_UCI_DEC_CTR:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_AES_CTR_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_AES_CTR | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_CTR;
+                    break;
+                default:
+                    return UCI_INVALID_ARGUMENT;
+            }
+            info->keylen = 32;
+            info->ivlen = 16;
+            break;
+        case ID_UCI_DES:
+            switch(mode)
+            {
+                case ID_UCI_ENC_CBC:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_DES_CBC_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_DES_CBC;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_CBC;
+                    break;
+                case ID_UCI_ENC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_DES_ECB_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_DES_ECB;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_ECB;
+                    break;
+                case ID_UCI_DEC_CBC:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_DES_CBC_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_DES_CBC | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_CBC;
+                    break;
+                case ID_UCI_DEC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_DES_ECB_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_DES_ECB | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_ECB;
+                    break;
+                default:
+                    return UCI_INVALID_ARGUMENT;
+
+            }
+            info->keylen = 8;
+            info->ivlen = 8;
+            break;
+        case ID_UCI_TDES:
+            switch(mode)
+            {
+                case ID_UCI_ENC_CBC:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_TDES_CBC_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_TDES_CBC;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_CBC;
+                    break;
+                case ID_UCI_ENC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_TDES_ECB_PAD;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_TDES_ECB;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_ECB;
+                    break;
+                case ID_UCI_DEC_CBC:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_TDES_CBC_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_TDES_CBC | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_ENC_ECB;
+                    break;
+                case ID_UCI_DEC_ECB:
+                    if(padding == ID_UCI_PKCS5)
+                    {
+                        info->mode = MI_TDES_ECB_PAD | _MODE_DEC_;
+                    }
+                    else if(padding == ID_UCI_NO_PADDING)
+                    {
+                        info->mode = MI_TDES_ECB | _MODE_DEC_;
+                    }
+                    else
+                    {
+                        return UCI_INVALID_ARGUMENT;
+                    }
+                    pctx->mode = ID_UCI_DEC_ECB;
+                    break;
+                default:
+                    return UCI_INVALID_ARGUMENT;
+
+            }
+            info->keylen = 24;
+            info->ivlen = 8;
+            break;
+        default:
+            return UCI_INVALID_HANDLE;
+
+    }
+
+    /*set info key*/
+
+    switch(keytype)
+    {
+        case UCI_USER_KEY:
+            info->keytype = KEYID_USER_KEY;
+            if(key_len != 8 && key_len != 16 && key_len != 24 && key_len != 32)
+            {
+                return UCI_INVALID_ARGUMENT;
+            }
+            memcpy(info->key, key, key_len);
+            break;
+        case UCI_SECRET_KEY:
+            info->keytype = KEYID_SECURE_KEY;
+            break;
+        case UCI_MASTER_KEY:
+            info->keytype = KEYID_MASTER_KEY;
+            break;
+        default :
+            return UCI_INVALID_ARGUMENT;
+    }
+    /*setiv*/
+    if(iv)
+    {
+        memcpy(info->iv, iv, info->ivlen);
+    }
+    else
+    {
+        memset(info->iv, 0x0, info->ivlen);
+    }
+    pctx->handle = open("/dev/crypto", 0, 0 ); //return hndl;
+    //TA_PRINT("hand = %d \n",pctx->handle);
+    if(pctx->handle < 0)
+    {
+        return UCI_ERROR;
+    }
+    if (ret = ioctl(pctx->handle, IOCTL_CRYPTO_INIT, info))
+    {
+        TA_PRINT("error:ioctl(hndl, IOCTL_CRYPTO_INIT, info) returned %d\n",ret);
+        return UCI_ERROR;
+    }
+    return UCI_SUCCESS;
+
+#else
+
+    int ret = UCI_ERROR;
+    uci_context_s *pctx = (uci_context_s*)oh;
+    unsigned int keytype;
+    unsigned int alg;
+         //!AS current hw is not ready, so using SW pseduo way temproray.
+    unsigned char hwkey_master[32]={ 0xAB, 0x12, 0x45, 0x67, 0x3F, 0x80, 0x98, 0x35,
+                                     0x06, 0x4F, 0x33, 0x39, 0x72, 0x1C, 0xDF, 0x23,
+                                     0xAB, 0x12, 0x45, 0x67, 0x3F, 0x80, 0x98, 0x35,
+                                     0x06, 0x4F, 0x33, 0x39, 0x72, 0x1C, 0xDF, 0x23};
+    unsigned char hwiv_master[16] ={ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                                     0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
+    unsigned char hwkey_unique[32]={ 0xF0, 0x22, 0x34, 0x67, 0x66, 0x88, 0xAB, 0xCD,
+                                     0x12, 0x67, 0x89, 0x54, 0x32, 0x10, 0xCC, 0xFE,
+                                     0xAB, 0x12, 0x45, 0x67, 0x3F, 0x80, 0x98, 0x35,
+                                     0x06, 0x4F, 0x33, 0x39, 0x72, 0x1C, 0xDF, 0x23};
+    unsigned char hwiv_unique[16] ={ 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88,
+                                     0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
+    if(pctx == NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    alg = pctx->alg;
+    switch(alg)
+    {
+        case ID_UCI_AES128:
+            key_len = 16;
+            break;
+        case ID_UCI_AES256:
+            key_len = 32;
+            break;
+        case ID_UCI_DES:
+            key_len = 8;
+            break;
+        case ID_UCI_TDES:
+            key_len = 24;
+
+    }
+    keytype = SDRM_HIGH_HALF(pctx->config);
+    if (keytype != UCI_USER_KEY)
+    {
+        if(keytype == UCI_MASTER_KEY)
+        {
+            ret = ((CryptoCoreContainer *)pctx->imp)->SE_init((CryptoCoreContainer *)pctx->imp, mode, padding, hwkey_master,key_len,hwiv_master);
+
+        }
+        else if(keytype == UCI_SECRET_KEY)
+        {
+            ret =((CryptoCoreContainer *)pctx->imp)->SE_init((CryptoCoreContainer *)pctx->imp, mode, padding, hwkey_unique,key_len,hwiv_unique);
+        }
+    }
+    else
+    {
+        ret = ((CryptoCoreContainer *)pctx->imp)->SE_init((CryptoCoreContainer *)pctx->imp, mode, padding, key,key_len, iv);
+
+    }
+
+    if(ret == CRYPTO_INVALID_ARGUMENT)
+    {
+        return UCI_INVALID_ARGUMENT;
+    }
+    if(ret != CRYPTO_SUCCESS)
+    {
+        return UCI_ERROR;
+    }
+
+    return UCI_SUCCESS;
+#endif
+}
+
+int hwcrypto_se_process(UCI_HANDLE oh, unsigned char *input, unsigned int input_len, unsigned char *output, unsigned int *output_len)
+{
+#ifndef PC_I586
+    uci_context_s       *pctx = NULL;
+    unsigned int         alg  = 0;
+    unsigned int         counter = 0;
+    struct crypt_oper   oper;
+    int                  ret  = 0;
+    int                  blocksize = 0;
+
+    memset(&oper, 0, sizeof(struct crypt_oper));
+
+    pctx = (uci_context_s*)oh;
+    if(pctx == NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    if(pctx->handle < 0)
+    {
+        TA_PRINT("Handle error \n");
+        return UCI_ERROR;
+    }
+    if(output_len != NULL)
+    {
+        *output_len = 0;
+    }
+
+    if(alg == ID_UCI_AES128 || alg == ID_UCI_AES256)
+    {
+        if((input_len % 16) != 0)
+        {
+            TA_PRINT("input_len error\n");
+            return UCI_ERROR;
+        }
+        blocksize = 16;
+    }
+    if(alg == ID_UCI_DES || alg == ID_UCI_TDES)
+    {
+        if((input_len % 8) != 0)
+        {
+            TA_PRINT("input_len error\n");
+            return UCI_ERROR;
+        }
+        blocksize = 8;
+    }
+
+    oper.src_addr = input;
+    oper.src_len  = input_len;
+    oper.dst_addr = output;
+    oper.dst_len  = output_len;
+    if (ret = ioctl(pctx->handle, IOCTL_CRYPTO_CRYPT, &oper))
+    {
+        TA_PRINT("error:ioctl(pctx->handle , 1, &oper) returned %d\n",ret);
+        return UCI_ERROR;
+    }
+
+    return UCI_SUCCESS;
+#else
+    int ret;
+    uci_context_s *ucictx = (uci_context_s *)oh;
+    if(ucictx == NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    ret = ((CryptoCoreContainer *)ucictx->imp)->SE_process((CryptoCoreContainer*)(ucictx->imp), input, input_len, output, output_len);
+    if(ret != CRYPTO_SUCCESS)
+    {
+        return UCI_ERROR;
+    }
+    return UCI_SUCCESS;
+
+#endif
+}
+
+int hwcrypto_se_final(UCI_HANDLE  oh, unsigned char *input, unsigned int input_len, unsigned char *output, unsigned int *output_len)
+{
+#ifndef PC_I586
+    uci_context_s       *pctx = NULL;
+    struct crypt_oper   oper;
+    struct crypt_info   *info = NULL;
+    int                  ret  = -1;
+    int                  hndl = -1;
+    unsigned int         blocksize = 0;
+    unsigned int         alg       = 0;
+    unsigned int         padlen    = 0;
+    unsigned int         len       = 0;
+    unsigned int         lastlen   = 0;
+    unsigned char        padding[32] = {0x0};
+
+    memset(padding, 0, sizeof(padding)/sizeof(padding[0]));
+    memset(&oper, 0, sizeof(struct crypt_oper));
+    pctx = (uci_context_s*)oh;
+    if(pctx == NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+
+    info = (struct crypt_info*) pctx->imp;
+    if(info == NULL)
+    {
+      return UCI_INVALID_HANDLE;
+    }
+    hndl = pctx->handle;
+    alg  = pctx->alg;
+    if(hndl < 0)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    if(alg == ID_UCI_AES128 || alg == ID_UCI_AES256)
+    {
+        blocksize = 16;
+    }
+    else if(alg == ID_UCI_DES|| alg == ID_UCI_TDES)
+    {
+        blocksize = 8;
+    }
+    else
+    {
+        return
+UCI_INVALID_HANDLE;
+    }
+
+    if(pctx->mode == ID_UCI_ENC_CBC || pctx->mode == ID_UCI_ENC_CTR || pctx->mode == ID_UCI_ENC_ECB)/*encrypt*/
+    {
+        lastlen = input_len % blocksize;
+        if(input_len > lastlen ) /* last blocksize is bigger than blocksize or equal to blocksize*/
+        {
+            len = input_len -lastlen;
+            ret = hwcrypto_se_process(oh,input,len,output,output_len);
+            if(ret != UCI_SUCCESS)
+            {
+                TA_PRINT("hwcrypto_se_process error \n");
+                return ret;
+            }
+        }
+        if(MI_GET_PADDING(info->mode) == _PAD_PKCS7_)/*do padding*/
+        {
+
+            if(lastlen >0)
+            {
+                memcpy(padding, input + len, lastlen);
+            }
+            memset(padding + lastlen, blocksize - lastlen, blocksize - lastlen);
+            oper.src_addr = padding;
+            oper.src_len  = blocksize;
+            oper.dst_addr = output + len;
+            oper.dst_len  = output_len;
+                       //oper.final   = 1;
+
+            if(ret = ioctl(hndl, IOCTL_CRYPTO_CRYPT, &oper))
+            {
+                TA_PRINT("error:ioctl(hndl, 1, &oper) returned %d\n",ret);
+                return UCI_ERROR;
+            }
+
+            *output_len = input_len - lastlen + blocksize;
+        }
+        if(MI_GET_PADDING(info->mode) == _PAD_NO_)/*do padding*/
+        {
+            if(lastlen >0)
+            {
+                memcpy(output + len, output + len, lastlen);
+            }
+            *output_len = input_len ;
+        }
+    }
+    else/*decrypt*/
+    {
+        lastlen = input_len % blocksize;
+        if(input_len > lastlen)
+        {
+            len = input_len -lastlen;
+        }
+        if(len > 0)
+        {
+
+            oper.src_addr = (char *)input;
+            oper.src_len      = len;
+            oper.dst_addr = (char *)output;
+            oper.dst_len  = output_len;
+                       //oper.final    = 1;
+            if (ret = ioctl(hndl, IOCTL_CRYPTO_CRYPT, &oper))
+            {
+                TA_PRINT("error:ioctl(hndl, 1, &oper) returned %d\n",ret);
+                return UCI_ERROR;
+            }
+        }
+        if(MI_GET_PADDING(info->mode) == _PAD_NO_)/*do padding*/
+        {
+            if(lastlen >0)
+            {
+                memcpy(output + len, input + len, lastlen);
+            }
+            *output_len = input_len ;
+        }
+        if(MI_GET_PADDING(info->mode) == _PAD_PKCS7_)/*de padding*/
+        {
+            if(lastlen >0)
+            {
+                TA_PRINT("psrc_len is not aligen to %d\n",blocksize);
+                return UCI_ERROR;
+            }
+
+            padlen = output[input_len -1];
+            //PrintBYTE("padding",output,input_len);
+            //PrintBYTE("input",input,input_len);
+            if(padlen < 1 || padlen > 16)
+            {
+                *output_len = 0;
+                TA_PRINT("padding size{%d} is incorretc ",padlen);
+                return UCI_ERROR;
+            }
+            memset(padding, padlen, blocksize);
+            if(memcmp(output + input_len - padlen ,padding, padlen) != 0)
+            {
+                *output_len = 0;
+                TA_PRINT("padding size{%d} is incorretc ",padlen);
+                return UCI_ERROR;
+            }
+
+            *output_len = input_len - padlen;
+        }
+
+    }
+
+    return UCI_SUCCESS;
+#else
+    int ret;
+    uci_context_s *ucictx = (uci_context_s *)oh;
+    if(ucictx==NULL)
+    {
+        return UCI_INVALID_HANDLE;
+    }
+    ret = ((CryptoCoreContainer *)ucictx->imp)->SE_final((CryptoCoreContainer*)(ucictx->imp), input, input_len, output, output_len);
+    if(ret!=CRYPTO_SUCCESS)
+    {
+        return UCI_ERROR;
+    }
+    return UCI_SUCCESS;
+
+#endif
+}
+
diff --git a/ssflib/inc/app_debug.h b/ssflib/inc/app_debug.h
new file mode 100755 (executable)
index 0000000..30b14de
--- /dev/null
@@ -0,0 +1,75 @@
+\r
+/** \r
+ * @file               app_debug.h\r
+ * @brief              \r
+ * @author             longhai.wu (longhai.wu@samsung.com)\r
+ * @version    0.9 Initial Draft Version\r
+ * @date               2013/04/13\r
+ *     - Revision History :\r
+ * Version        Date                         Author                  Detail description \r
+ * --------------------------------------------------------------------\r
+ *      0.9    2013/04/03                longhai.wu     \r
+ * --------------------------------------------------------------------\r
+ */\r
\r
+#ifndef _APP_DEBUG_H_\r
+#define _APP_DEBUG_H_\r
+#include <stdio.h>\r
+#define APP_MODULE_NAME "TrustApp"\r
+#define ONE_TIME_PRINT_LENGTH_MAX 10240\r
+unsigned char one_time_print_buffer[ONE_TIME_PRINT_LENGTH_MAX];\r
+extern int g_app_svc_dbglvl;\r
+\r
+\r
+unsigned char one_time_print_buffer_test[10240];\r
+\r
+//!disable all msg\r
+#define TRUSTAPP_DEBUG_LEVEL_NON     0 \r
+//!enable message level > ERROR\r
+#define TRUSTAPP_DEBUG_LEVEL_ERR     1 \r
+//!enable message level > WARNING\r
+#define TRUSTAPP_DEBUG_LEVEL_WRN     2 \r
+//!enable message level > DEBUG\r
+#define TRUSTAPP_DEBUG_LEVEL_DBG     3 \r
+//!enable message level > LOG/INFO\r
+#define TRUSTAPP_DEBUG_LEVEL_LOG     4 \r
+//!enable all level\r
+#define TRUSTAPP_DEBUG_LEVEL_ALL     5 \r
+\r
+\r
+#define APP_SVC_ERR(title, format,...) do{sprintf(one_time_print_buffer,"[%s][ERR]" format, title,##__VA_ARGS__);\\r
+                                                                               }while(0);\r
+#define APP_SVC_WRN(title, format,...) do{sprintf(one_time_print_buffer,"[%s][WRN]" format, title,##__VA_ARGS__);\\r
+                                               app_print_log(one_time_print_buffer);\\r
+                                                                               }while(0);\r
+#define APP_SVC_DBG(title, format,...) do{sprintf(one_time_print_buffer,"[%s][DBG]" format, title,##__VA_ARGS__);\\r
+                                               app_print_log(one_time_print_buffer);\\r
+                                                                               }while(0);\r
+#define APP_SVC_LOG(title, format,...) do{sprintf((char *)one_time_print_buffer,"[%s][LOG]" format, title,##__VA_ARGS__);\\r
+                                               app_print_log(one_time_print_buffer);\\r
+                                                                               }while(0);\r
+\r
+#define APP_SVC_LOG_test(title, format,...) do{sprintf(()one_time_print_buffer_test,"[%s][LOG]" format, title,##__VA_ARGS__);\\r
+                                               app_print_log_test(one_time_print_buffer_test);\\r
+                                                                               }while(0);\r
+\r
+#define TURST_APP_LOG_TEST(fmt,...)  {APP_SVC_LOG_test("test", fmt, ##__VA_ARGS__)}\r
+\r
+#define TURST_APP_ERR(fmt, ...) if(g_app_svc_dbglvl >= TRUSTAPP_DEBUG_LEVEL_ERR) {APP_SVC_ERR(APP_MODULE_NAME, fmt, ##__VA_ARGS__)}\r
+#define TURST_APP_WRN(fmt, ...) if(g_app_svc_dbglvl >= TRUSTAPP_DEBUG_LEVEL_WRN) {APP_SVC_WRN(APP_MODULE_NAME, fmt, ##__VA_ARGS__)}\r
+#define TURST_APP_DBG(fmt, ...) if(g_app_svc_dbglvl >= TRUSTAPP_DEBUG_LEVEL_DBG) {APP_SVC_DBG(APP_MODULE_NAME, fmt, ##__VA_ARGS__)}\r
+#define TURST_APP_LOG(fmt, ...) if(g_app_svc_dbglvl >= TRUSTAPP_DEBUG_LEVEL_LOG) {APP_SVC_LOG(APP_MODULE_NAME, fmt, ##__VA_ARGS__)}\r
+//#define TURST_APP_LOG(fmt, ...) TURST_APP_LOG_TEST(fmt,##__VA_ARGS__)\r
+\r
+\r
+\r
+#define TRACE_FUNCTION_IN TURST_APP_LOG("[%s][%d] In ... \n",__FUNCTION__,__LINE__);\r
+#define TRACE_FUNCTION_OUT  TURST_APP_LOG("[%s][%d] Out ... \n",__FUNCTION__,__LINE__);\r
+\r
+int app_open_log_file( char *processName);\r
+void app_print_log(unsigned char logBuffer[]);\r
+void app_close_log_file(void);\r
+\r
+void app_print_log_test(unsigned char logBuffer[]);\r
+\r
+#endif\r
diff --git a/ssflib/inc/ssf_client.h b/ssflib/inc/ssf_client.h
new file mode 100755 (executable)
index 0000000..2d50d8d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssfclient.h
+ *
+ *    Description:  SSF client header file
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Cheryl (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef SSF_CLIENT_H_
+#define SSF_CLIENT_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "tee_command.h"
+#include "log.h"
+
+int32_t connecttoServer(void);
+void disconnectfromServer(int32_t ServerSocket);
+uint32_t sendCommand(int32_t sockfd, TEE_CMD cmd, void* data, size_t size);
+
+#endif /* SSF_CLIENT_H_ */
diff --git a/ssflib/inc/ssf_lib.h b/ssflib/inc/ssf_lib.h
new file mode 100755 (executable)
index 0000000..0726a10
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssflib.h
+ *
+ *    Description:  SSF Lib header file
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef SSF_LIB_H_
+#define SSF_LIB_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_internal_api.h"
+#include "teestub_command_data.h"
+#include "OsaLinuxUser.h"
+#include <pthread.h>
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+typedef struct {
+       bool isPanicSet;
+       bool thisTaskCancel;
+       bool thisTaskMask;
+} TeeStubSSFSharedData;
+
+extern pthread_mutex_t socketLock;
+//TODO: clean up this variable location. This is not the right place
+extern TeeStubSSFSharedData sharedData;
+extern int32_t socketSimulatorDaemonFD;
+extern TEE_UUID ssf_sharedthisTAUUID;
+
+#endif /* SSF_LIB_H_ */
diff --git a/ssflib/inc/ssf_storage.h b/ssflib/inc/ssf_storage.h
new file mode 100755 (executable)
index 0000000..0000976
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_storage.h
+ *
+ *    Description:  SSF Storage header file
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+#ifndef SSF_STORAGE_H_
+#define SSF_STORAGE_H_
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "tee_internal_api.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "ss_api.h"
+#include "uci_api.h"
+#include <sys/mman.h>
+#include <fcntl.h>
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define MSG(fmt, ARG...) printf(fmt"\n", ##ARG)
+
+#define MAX_ATTRIBUTE_NUMBER 35 // Maximum number of attributes for each object
+#define FLAG_STORAGE_ENUMERATOR 0x20000000
+
+#define PO_FILE_NAME_MAX_LEN 128
+#define PO_FILE_KEY_MAT_SIZE 64
+#define PO_FILE_KEY_SIZE 16
+#define PO_FILE_HASH_SIZE 20
+#define BLOCK_SIZE 16
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+// structure definition
+struct __TEE_Attributees {
+       int attr_number;
+       TEE_Attribute attr_array[MAX_ATTRIBUTE_NUMBER];
+};
+
+typedef struct {
+       TEE_ObjectInfo info;
+       struct __TEE_Attributees attr;
+} TransientObject;
+
+struct __TEE_ObjectHandle {
+       TransientObject tr;
+};
+
+typedef struct {
+       char object_id[TEE_OBJECT_ID_MAX_LEN];
+       int obj_id_len;
+       TEE_ObjectInfo info;
+} persistent_object_info;
+
+// share rules check
+typedef struct _po_user {
+       volatile int lock;
+       uint32_t x_user;
+       uint32_t rs_user;
+       uint32_t ws_user;
+       uint32_t rws_user;
+} po_user;
+
+typedef struct {
+       char name[PO_FILE_NAME_MAX_LEN + 1];
+       int fd;
+       po_user* usr_info;
+} po_share_info;
+
+typedef struct {
+       uint32_t storageID; // reserved
+       ss_credential_s cred;
+       char filename[PO_FILE_NAME_MAX_LEN];
+       int b_inited;
+       int po_num;
+       persistent_object_info* po_info;
+} po_info_file;
+
+typedef struct {
+       ss_credential_s cred;
+       char file_name[PO_FILE_NAME_MAX_LEN + 1];
+       TEE_ObjectInfo po_info;
+       // attr
+       uint8_t* attr;
+       uint32_t attr_size;
+       // data
+       uint8_t* object_data;
+       uint32_t obj_data_size;
+} persistent_object_file;
+
+// persisent object list
+struct _persistent_object;
+
+typedef struct _po_list_node {
+       struct _persistent_object* po;
+       struct _po_list_node* next;
+       struct _po_list_node* prev;
+} po_list_node;
+
+typedef struct _persistent_object {
+       TransientObject attr;
+       uint32_t storage_id;
+       TEE_UUID TA_UUID;
+       char object_id[TEE_OBJECT_ID_MAX_LEN];
+       int obj_id_len;
+       persistent_object_file po_file;
+       po_share_info share_info;
+       struct _po_list_node po_list;
+} persistent_object;
+
+typedef enum {
+       ENUM_STATE_INIT, ENUM_STATE_STARTED, ENUM_STATE_END
+} enumerator_state;
+
+struct __TEE_ObjectEnumHandle {
+       persistent_object_info* po_info;
+       int po_num;
+       int curr_position;
+       enumerator_state state;
+};
+
+extern po_list_node g_po_list;
+
+extern po_info_file g_po_info_file;
+
+#if 0
+// Generic Object Functions
+void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo* objectInfo);
+void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage);
+TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object, uint32_t attributeID, void* buffer, size_t* size);
+TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object, uint32_t attributeID, uint32_t* a, uint32_t* b);
+void TEE_CloseObject(TEE_ObjectHandle object);
+
+// Transient Object Functions
+TEE_Result TEE_AllocateTransientObject(uint32_t objectType, uint32_t maxObjectSize, TEE_ObjectHandle* object);
+void TEE_FreeTransientObject(TEE_ObjectHandle object);
+void TEE_ResetTransientObject(TEE_ObjectHandle object);
+TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object, TEE_Attribute* attrs, uint32_t attrCount);
+void TEE_InitRefAttribute(TEE_Attribute* attr, uint32_t attributeID, void* buffer, size_t length);
+void TEE_InitValueAttribute(TEE_Attribute* attr, uint32_t attributeID, uint32_t a, uint32_t b);
+void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject, TEE_ObjectHandle srcObject);
+TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize, TEE_Attribute* params, uint32_t paramCount);
+
+// Persistent Object Functions
+TEE_Result TEE_CreatePersistentObject(uint32_t storageID, void* objectID, size_t objectIDLen, uint32_t flags, TEE_ObjectHandle attributes, void* initialData, size_t initialDataLen, TEE_ObjectHandle* object);
+TEE_Result TEE_OpenPersistentObject(uint32_t storageID, void* objectID, size_t objectIDLen, uint32_t flags, TEE_ObjectHandle* object);
+void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object);
+TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object, void* newObjectID, size_t newObjectIDLen);
+
+// Persistent Object Enumeration Functions
+TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle* objectEnumerator);
+void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator);
+void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator);
+TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator, uint32_t storageID);
+TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator, TEE_ObjectInfo* objectInfo, void* objectID, size_t* objectIDLen);
+
+// Data Stream Access Functions
+TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void* buffer, size_t size, uint32_t* count);
+TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, void* buffer, size_t size);
+TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size);
+TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset, TEE_Whence whence);
+#endif
+
+// attribute operations
+TEE_Result copy_attribute(TEE_Attribute* dest, TEE_Attribute* src);
+void free_attribute(TEE_Attribute* attr);
+
+//internal transient object operations
+TEE_Result allocate_transient_object(TransientObject* tr, uint32_t objectType,
+    uint32_t maxObjectSize);
+size_t calc_attr_size(TransientObject* tr);
+TEE_Result serialise_attr(TransientObject* tr, char* buf);
+TEE_Result deserialise_attr(char* buf, TransientObject* tr);
+
+// internal persistent object operations
+TEE_Result allocate_persistent_object(persistent_object** po,
+    uint32_t storageID, const void* objectID, size_t objectIDLen,
+    uint32_t flags);
+TEE_Result create_po(persistent_object* po, TransientObject* attr,
+    const void* init_data, size_t data_size);
+TEE_Result open_po(persistent_object* po);
+TEE_Result read_object_data(persistent_object* po, void* buffer, size_t size,
+    uint32_t* count);
+TEE_Result seek_object_data(persistent_object* po, int32_t offset,
+    TEE_Whence whence);
+TEE_Result write_object_data(persistent_object* po, const void* buffer,
+    size_t size);
+TEE_Result truncate_object_data(persistent_object* po, size_t size);
+void close_po(persistent_object* po);
+TEE_Result free_po(persistent_object* po);
+TEE_Result rename_po(persistent_object* po, const void* newObjectID,
+    size_t newObjectIDLen);
+TEE_Result exist_po(persistent_object* po);
+void init_po(persistent_object* po);
+
+// persistent object file operations
+int derive_po_file_name(const void* obj_id, int obj_id_len, char* fn);
+int load_po_file(persistent_object* po);
+int write_po_file(persistent_object* po);
+int rename_po_file(persistent_object* po, const void* newObjectID,
+    size_t newObjectIDLen);
+void clean_po_file(persistent_object* po);
+int delete_po_file(persistent_object* po);
+
+// po  info file
+int init_po_info_file(po_info_file* pi_file);
+int load_po_info_file(po_info_file* pi_file);
+int get_po_info(po_info_file* pi_file, persistent_object_info** po_info,
+    int* po_num);
+int write_po_info(po_info_file* pi_file, const void* objectID,
+    uint32_t obj_id_len, TEE_ObjectInfo* info);
+int delete_po_info(po_info_file* pi_file, const void* objectID,
+    uint32_t obj_id_len);
+persistent_object_info* find_po_info(po_info_file* pi_file,
+    const void* objectID, uint32_t obj_id_len);
+
+// po share rule
+int init_share_info(po_share_info* share_info);
+int check_share_rule(po_share_info* share_info, uint32_t handleFlags);
+int update_share_info(po_share_info* share_info, uint32_t handleFlags,
+    int b_open);
+int release_share_info(po_share_info* share_info);
+void lock_po_share_info(po_share_info* share_info);
+void unlock_po_share_info(po_share_info* share_info);
+
+// po list operations
+void add_to_po_list(persistent_object* po);
+void rem_from_po_list(persistent_object* po);
+void cleanup();
+void regist_clean_up();
+
+// misc
+void byte_to_hex(uint8_t* dest, const uint8_t* src, unsigned long src_len);
+void convert_TA_UUID(char* uuid, TEE_UUID TA_UUID);
+int gen_random(uint8_t* dest, uint8_t data_len);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* SSF_STORAGE_H_ */
diff --git a/ssflib/src/app_debug.c b/ssflib/src/app_debug.c
new file mode 100755 (executable)
index 0000000..8db9d26
--- /dev/null
@@ -0,0 +1,108 @@
+/** \r
+ * @file               app_debug.h\r
+ * @brief              \r
+ * @author             longhai.wu (longhai.wu@samsung.com)\r
+ * @version    0.9 Initial Draft Version\r
+ * @date               2013/04/13\r
+ *     - Revision History :\r
+ * Version        Date                         Author                  Detail description \r
+ * --------------------------------------------------------------------\r
+ *      0.9    2013/04/03                longhai.wu     \r
+ * --------------------------------------------------------------------\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <app_debug.h>\r
+\r
+//#define PRINT_LOG_TO_CONSOLE\r
+#ifdef PRINT_LOG_TO_CONSOLE\r
+#include <fcntl.h>\r
+#define portname "/dev/ttyS0"\r
+static int m_fd = -1;\r
+int g_app_svc_dbglvl = TRUSTAPP_DEBUG_LEVEL_NON;\r
+\r
+int app_open_log_file( char *processName)\r
+{\r
+       \r
+       /* save log to LOGFILE */\r
+       \r
+       m_fd = open( portname,O_RDWR | O_NOCTTY | O_NONBLOCK);\r
+       if(m_fd < 0)\r
+       {\r
+               return -1;\r
+       }\r
+\r
+       write(m_fd,processName,strlen(processName));\r
+       \r
+       memset(one_time_print_buffer,0,sizeof(one_time_print_buffer));\r
+       return 0;\r
+\r
+}\r
+\r
+void app_close_log_file(void)\r
+{\r
+\r
+       close(m_fd);\r
+       m_fd = -1;\r
+}\r
+void app_print_log(unsigned char logBuffer[])\r
+{\r
+\r
+       write(m_fd,logBuffer,strlen(logBuffer));\r
+}\r
+\r
+#else\r
+#define SVC1_LOGFILE   "/opt/usr/apps/tz_simulator/data/SWDLog.txt" \r
+\r
+static FILE *fp = NULL;\r
+\r
+#ifdef _TURN_ON_TALOG_\r
+int g_app_svc_dbglvl = TRUSTAPP_DEBUG_LEVEL_ALL;\r
+#else\r
+int g_app_svc_dbglvl = TRUSTAPP_DEBUG_LEVEL_NON;\r
+#endif\r
+\r
+int app_open_log_file(char *processName)\r
+{\r
+       \r
+       /* save log to LOGFILE */\r
+       fp = fopen(SVC1_LOGFILE, "a+");\r
+       if(!fp)\r
+       {\r
+               return -1;\r
+       }\r
+       \r
+       fprintf(fp,"Trust App name : %s.\n",processName);       \r
+       fflush(fp);\r
+       \r
+       memset(one_time_print_buffer,0,sizeof(one_time_print_buffer));\r
+       return 0;\r
+\r
+}\r
+\r
+void app_close_log_file(void)\r
+{\r
+\r
+       fclose(fp);\r
+       fp = NULL;\r
+}\r
+void app_print_log(unsigned char logBuffer[])\r
+{\r
+\r
+       fprintf(fp,"%s",logBuffer);\r
+       fflush(fp);\r
+}\r
+\r
+void app_print_log_test(unsigned char logBuffer[])\r
+{\r
+\r
+       fprintf(fp,"%s",logBuffer);\r
+       fflush(fp);\r
+}\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
diff --git a/ssflib/src/ssf_arithmetic.c b/ssflib/src/ssf_arithmetic.c
new file mode 100755 (executable)
index 0000000..cbe4e68
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_arithmetic.c
+ *
+ *    Description:  SSF arithmetic functions
+ *
+ *        Version:  1.0
+ *        Created:  29 June 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Cheryl (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <log.h>
+#include "tee_internal_api.h"
+#include "CC_API.h"
+#include "base/cc_bignum.h"
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define TAG SSF_LIB
+#define SDRM_API_METADATA_LENGTH_IN_U32 4
+#define CNT_OF_BIT_IN_BYTE 8
+#define PASS_NOT_IMP_CODE
+
+/*-----------------------------------------------------------------------------
+ *  TEE API implementation
+ *-----------------------------------------------------------------------------*/
+/**
+ * The TEE_BigIntInit function initializes bigInt and sets its represented
+ * value to zero. This function assumes that bigInt points to a memory area
+ * of len uint32_t.
+ * @param value A pointer to the TEE_BigInt to be initialized
+ * @param length The size in uint32_t of the memory pointed to by bigInt
+ */
+void TEE_BigIntInit(TEE_BigInt* value, const size_t length) {
+
+       LOGD(TAG, "TEE_BigIntInit - length : %d", length);
+       uint32_t teeMaxBigIntSize;
+       TEE_Result result = TEE_GetPropertyAsU32(
+           (TEE_PropSetHandle)TEE_PROPSET_TEE_IMPLEMENTATION,
+           "gpd.tee.arith.maxBigIntSize", &teeMaxBigIntSize);
+       LOGD(TAG, "TEE_GetPropertyAsU32(arith.maxBigIntSize) : %d (ret:%d)",
+           teeMaxBigIntSize, result);
+#ifndef PASS_NOT_IMP_CODE
+       if(result == TEE_SUCCESS)
+       {
+               if(teeMaxBigIntSize == 0 ||
+                               (length - SDRM_API_METADATA_LENGTH_IN_U32) * SDRM_SIZE_OF_DWORD * CNT_OF_BIT_IN_BYTE < teeMaxBigIntSize)
+               {
+                       LOGE(TAG, "Panic Reason: BN size is creater than max allowed");
+                       TEE_Panic(TEE_ERROR_OUT_OF_MEMORY);
+               }
+       }
+#endif
+       if (length <= SDRM_API_METADATA_LENGTH_IN_U32) {
+               LOGE(TAG, "Panic Reason: insufficient length");
+               TEE_Panic(TEE_ERROR_OUT_OF_MEMORY);
+       }
+       SDRM_BIG_NUM *bn = SDRM_BN_Alloc((cc_u8*)value,
+           length - SDRM_API_METADATA_LENGTH_IN_U32);
+       if (bn == NULL) {
+               LOGE(TAG, "Panic Reason: SDRM_BN_Alloc fail");
+               TEE_Panic(TEE_ERROR_OUT_OF_MEMORY);
+       }
+       LOGD(TAG, "Success");
+}
+
+/**
+ * The TEE_BigIntConvertFromOctetString function converts a bufferLen byte
+ * octet string buffer into a TEE_BigInt format. The octet string is in most
+ * significant byte first representation. The input parameter sign will set
+ * the sign of dest. It will be set to negative if sign<0 and to positive if
+ * sign>=0.
+ * @param dest Pointer to a TEE_BigInt to hold the result
+ * @param buffer Pointer to the buffer containing the octet string
+ *                             representation of the integer
+ * @param sz_buffer The length of *buffer in bytes
+ * @param sign The sign of dest is set to the sign of sign
+ */
+TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt* dest,
+    const uint8_t* buffer, const size_t sz_buffer, const int32_t sign) {
+
+       LOGD(TAG,
+           "TEE_BigIntConvertFromOctetString - dest:%p buffer:%p sz_buffer:%d sign:%d",
+           dest, buffer, sz_buffer, sign);
+       TEE_Result result = TEE_SUCCESS;
+       SDRM_BIG_NUM *bn = (SDRM_BIG_NUM*)dest;
+
+       if (bn->Size * SDRM_SIZE_OF_DWORD < sz_buffer) {
+               LOGD(TAG, "Fail Reason: TEE_ERROR_OVERFLOW(%d %d)",
+                   bn->Size * SDRM_SIZE_OF_DWORD, sz_buffer);
+               return TEE_ERROR_OVERFLOW;
+       }
+       int ret = SDRM_OS2BN((cc_u8*)buffer, sz_buffer, bn);
+       if (ret == CRYPTO_SUCCESS) {
+               bn->sign = ((sign < 0) ? 1 : 0);
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_OS2BN fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       return result;
+}
+
+/**
+ * The TEE_BigIntConvertToOctetString function converts the absolute value of
+ * an integer in TEE_BigInt format into an octet string. The octet string is
+ * written in a most significant byte first representation.
+ * @param buffer Output buffer where converted octet string representation
+ *                             of the integer is written
+ * @param sz_buffer_out The length of *buffer in bytes
+ * @param value Pointer to the integer that will be converted to an octet
+ *                             string
+ */
+TEE_Result TEE_BigIntConvertToOctetString(void* buffer, size_t* sz_buffer_out,
+    const TEE_BigInt* value) {
+
+       LOGD(TAG, "TEE_BigIntConvertToOctetString - buffer:%p value:%p", buffer,
+           value);
+       TEE_Result result = TEE_SUCCESS;
+       SDRM_BIG_NUM *bn = (SDRM_BIG_NUM*)value;
+       if (*sz_buffer_out == 0) {
+               if (bn->Length != 0) {
+                       *sz_buffer_out = bn->Length * 4;
+                       result = TEE_ERROR_SHORT_BUFFER;
+               }
+               return result;
+       }
+       int ret = SDRM_BN2OS(bn, *sz_buffer_out, (cc_u8 *)buffer);
+       if (ret == CRYPTO_BUFFER_TOO_SMALL || ret == CRYPTO_NULL_POINTER) {
+               LOGD(TAG, "Fail Reason: CRYPTO_BUFFER_TOO_SMALL or CRYPTO_NULL_POINTER");
+               *sz_buffer_out = bn->Length * 4;
+               result = TEE_ERROR_SHORT_BUFFER;
+       } else if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN2OS fail(%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       return result;
+}
+
+/**
+ * The TEE_BigIntConvertFromS32 function sets *result to the value input.
+ * @param result Pointer to a TEE_BigInt to store the result
+ * @param input Input value
+ */
+void TEE_BigIntConvertFromS32(TEE_BigInt* result, const int32_t input) {
+       SDRM_BIG_NUM *bn = (SDRM_BIG_NUM*)result;
+       bn->pData[0] = ((input < 0) ? (input * -1) : (input));
+       bn->Length = 1;
+       bn->sign = ((input < 0) ? 1 : 0);
+       LOGD(TAG, "Success");
+}
+
+/**
+ * The TEE_BigIntConvertToS32 function sets *result to the value of input,
+ * including the sign of input. If input does not fit within an int32_t,
+ * the value of *result is undefined.
+ * @param result Pointer to an int32_t to store the result
+ * @param input Pointer to the input value
+ */
+TEE_Result TEE_BigIntConvertToS32(int32_t* value_result,
+    const TEE_BigInt* input) {
+       SDRM_BIG_NUM *bn = (SDRM_BIG_NUM*)input;
+       *value_result = (bn->sign == 1) ? (bn->pData[0] * -1) : (bn->pData[0]);
+       LOGD(TAG, "Success");
+       return TEE_SUCCESS;
+}
+
+/**
+ * The TEE_BigIntCmp function checks whether op1>op2, op1==op2, or op1<op2.
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ */
+int32_t TEE_BigIntCmp(const TEE_BigInt* op1, const TEE_BigInt* op2) {
+       SDRM_BIG_NUM *bn1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bn2 = (SDRM_BIG_NUM*)op2;
+       int ret = SDRM_BN_Cmp_sign(bn1, bn2);
+       LOGD(TAG, "Success");
+       return ret;
+}
+
+/**
+ * The TEE_BigIntCmpS32 function checks whether value1_raw>value2,
+ * value1_raw==value2, or value1_raw<value2.
+ * @param value1_raw Pointer to the first operand
+ * @param value2 Pointer to the second operand
+ */
+int32_t TEE_BigIntCmpS32(const TEE_BigInt* value1_raw, const int32_t value2) {
+       int32_t value1 = 0;
+       TEE_Result result = TEE_BigIntConvertToS32(&value1, value1_raw);
+       if (result != TEE_SUCCESS) {
+               LOGE(TAG, "Panic Reason: TEE_BigIntConvertToS32 fail");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       int ret = 0;
+       if (value1 == value2)
+               ret = 0;
+       else if (value1 > value2)
+               ret = 1;
+       else ret = -1;
+       return ret;
+}
+
+/**
+ * The TEE_BigIntShiftRight function computes
+ * |destination_raw| = |source_raw| >> bits and destination_raw will have the
+ * same sign as source_raw.4 If bits is greater than the bit length of
+ * source_raw then the result is zero. destination_raw and source_raw MAY
+ * point to the same memory region.
+ * @param destination_raw Pointer to TEE_BigInt to hold the shifted result
+ * @param source_raw Pointer to the operand to be shifted
+ * @param bits Number of bits to shift
+ */
+void TEE_BigIntShiftRight(TEE_BigInt* destination_raw,
+    const TEE_BigInt* source_raw, const size_t bits) {
+       SDRM_BIG_NUM *dstBn = (SDRM_BIG_NUM*)destination_raw;
+       SDRM_BIG_NUM *srcBn = (SDRM_BIG_NUM*)source_raw;
+       int ret = SDRM_BN_SHR(dstBn, srcBn, bits);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_SHR fail");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntGetBit function returns the indexth bit of the natural binary
+ * representation of |object_raw|. A true return value indicates a \931\94 and a
+ * false return value indicates a \930\94 in the indexth position. If index is
+ * larger than the number of bits in object_raw, the return value is false,
+ * thus indicating a \930\94.
+ * @param object_raw Pointer to the integer
+ * @param index The offset of the bit to be read, starting at offset 0 for the
+ * least significant bit
+ */
+bool TEE_BigIntGetBit(const TEE_BigInt* object_raw, const uint32_t index) {
+       SDRM_BIG_NUM *objBn = (SDRM_BIG_NUM*)object_raw;
+       bool bitValue = (bool)SDRM_BN_num_bits_index(objBn, index);
+       LOGD(TAG, "Success");
+       return bitValue;
+
+}
+
+/**
+ * The TEE_BigIntGetBitCount function returns the number of bits in the
+ * natural binary representation of |object_raw|; that is, the magnitude of
+ * object_raw.
+ * @param object_raw Pointer to the integer
+ */
+uint32_t TEE_BigIntGetBitCount(const TEE_BigInt* object_raw) {
+       SDRM_BIG_NUM *objBn = (SDRM_BIG_NUM*)object_raw;
+       int retCnt = SDRM_BN_num_bits(objBn);
+       LOGD(TAG, "Success");
+       return retCnt;
+}
+
+/**
+ * The TEE_BigIntAdd function computes dest = op1 + op2. All or some of dest,
+ * op1, and op2 MAY point to the same memory region.
+ * @param dest Pointer to TEE_BigInt to store the result op1 + op2
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ */
+void TEE_BigIntAdd(TEE_BigInt* dest, const TEE_BigInt* op1,
+    const TEE_BigInt* op2) {
+       SDRM_BIG_NUM *bn1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bn2 = (SDRM_BIG_NUM*)op2;
+       SDRM_BIG_NUM *dst = (SDRM_BIG_NUM*)dest;
+       int ret = SDRM_BN_Add(dst, bn1, bn2);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_Add fail");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntSub function computes dest = op1 \96 op2. All or some of dest,
+ * op1, and op2 MAY point to the same memory region.
+ * @param dest Pointer to TEE_BigInt to store the result op1 - op2
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ */
+void TEE_BigIntSub(TEE_BigInt* dest, const TEE_BigInt* op1,
+    const TEE_BigInt* op2) {
+       SDRM_BIG_NUM *bn1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bn2 = (SDRM_BIG_NUM*)op2;
+       SDRM_BIG_NUM *dst = (SDRM_BIG_NUM*)dest;
+       int ret = SDRM_BN_Sub(dst, bn1, bn2);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_Sub fail");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntNeg function negates an operand: dest = -op. dest and op MAY
+ * point to the same memory region.
+ * @param dest Pointer to TEE_BigInt to store the result -op
+ * @param op Pointer to the operand to be negated
+ */
+void TEE_BigIntNeg(TEE_BigInt* dest, const TEE_BigInt* op) {
+       SDRM_BIG_NUM *bnOp = (SDRM_BIG_NUM*)op;
+       if (dest == op)
+               bnOp->sign = ((bnOp->sign == 1) ? 0 : 1);
+       else {
+               SDRM_BIG_NUM *dst = (SDRM_BIG_NUM*)dest;
+               SDRM_BN_Copy(dst, bnOp);
+               dst->sign = ((dst->sign == 1) ? 0 : 1);
+       }
+       LOGD(TAG, "Success");
+}
+
+/**
+ * The TEE_BigIntMul function computes dest = op1 * op2. All or some of dest,
+ * op1, and op2 MAY point to the same memory region.
+ * @param dest Pointer to TEE_BigInt to store the result op1 * op2
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ */
+void TEE_BigIntMul(TEE_BigInt* dest, const TEE_BigInt* op1,
+    const TEE_BigInt* op2) {
+       SDRM_BIG_NUM *bn1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bn2 = (SDRM_BIG_NUM*)op2;
+       SDRM_BIG_NUM *dst = (SDRM_BIG_NUM*)dest;
+       int ret = SDRM_BN_Mul(dst, bn1, bn2);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_Mul fail");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntSquare function computes dest = op * op. dest and op MAY point
+ * to the same memory region.
+ * @param dest Pointer to TEE_BigInt to store the result op * op
+ * @param op Pointer to the operand to be squared
+ */
+void TEE_BigIntSquare(TEE_BigInt* dest, const TEE_BigInt* op) {
+       TEE_BigIntMul(dest, op, op);
+       LOGD(TAG, "Called");
+}
+
+/**
+ * The TEE_BigIntDiv function computes dest_r and dest_q such that
+ * op1 = dest_q * op2 + dest_r. It will round dest_q towards zero and dest_r
+ * will have the same sign as op1.
+ * @param dest_q Pointer to a TEE_BigInt to store the quotient.
+ *                             dest_q can be NULL.
+ * @param dest_r Pointer to a TEE_BigInt to store the remainder.
+ *                             dest_r can be NULL.
+ * @param op1 Pointer to the first operand, the dividend
+ * @param op2 Pointer to the second operand, the divisor
+ */
+void TEE_BigIntDiv(TEE_BigInt* dest_q, TEE_BigInt* dest_r,
+    const TEE_BigInt* op1, const TEE_BigInt* op2) {
+       SDRM_BIG_NUM *dst_q = (SDRM_BIG_NUM*)dest_q;
+       SDRM_BIG_NUM *dst_r = (SDRM_BIG_NUM*)dest_r;
+       SDRM_BIG_NUM *bn1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bn2 = (SDRM_BIG_NUM*)op2;
+
+       if (dst_q == NULL) {
+               SDRM_BIG_NUM *tmp = SDRM_BN_Init(bn1->Size);
+               if (tmp != NULL) {
+                       SDRM_BN_Copy(tmp, bn1);
+                       dst_q = tmp;
+               }
+       }
+       int ret = SDRM_BN_Div(dst_q, dst_r, bn1, bn2);
+       if ((void*)dst_q != (void*)dest_q) {
+               SDRM_BN_FREE(dst_q);
+       }
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_Div fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntMod function computes dest = op (mod n) such that
+ * 0 <= dest < n. dest and op MAY point to the same memory region but n MUST
+ * point to a unique memory region. For negative op the function follows the
+ * normal convention that -1 = (n-1) mod n.
+ * @param dest Pointer to TEE_BigInt to hold the result op (mod n). The
+ * result dest will be in the interval [0, n-1].
+ * @param op Pointer to the operand to be reduced mod n
+ * @param n Pointer to the modulus. Modulus MUST be larger than 1.
+ */
+void TEE_BigIntMod(TEE_BigInt* dest, const TEE_BigInt* op, const TEE_BigInt* n) {
+
+       SDRM_BIG_NUM *bnDst = (SDRM_BIG_NUM*)dest;
+       SDRM_BIG_NUM *bnOp = (SDRM_BIG_NUM*)op;
+       SDRM_BIG_NUM *bnN = (SDRM_BIG_NUM*)n;
+       int32_t integerN = 0;
+       TEE_BigIntConvertToS32(&integerN, (TEE_BigInt*)bnN);
+       if (integerN < 2) {
+               LOGE(TAG, "Panic Reason: Modulus should be large than 2");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       int ret = SDRM_BN_ModRed(bnDst, bnOp, bnN);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_ModRed fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntAddMod function computes dest = (op1 + op2) (mod n). All or
+ * some of dest, op1, and op2 MAY point to the same memory region but n MUST
+ * point to a unique memory region.
+ * @param dest Pointer to TEE_BigInt to hold the result (op1 + op2) (mod n)
+ * @param op1 Pointer to the first operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param op2 Pointer to the second operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param n Pointer to the modulus. Modulus MUST be larger than 1.
+ */
+void TEE_BigIntAddMod(TEE_BigInt* dest, const TEE_BigInt* op1,
+    const TEE_BigInt* op2, const TEE_BigInt* n) {
+
+       SDRM_BIG_NUM *bnDst = (SDRM_BIG_NUM*)dest;
+       SDRM_BIG_NUM *bnOp1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bnOp2 = (SDRM_BIG_NUM*)op2;
+       SDRM_BIG_NUM *bnN = (SDRM_BIG_NUM*)n;
+       int32_t integerN = 0;
+       TEE_BigIntConvertToS32(&integerN, (TEE_BigInt*)bnN);
+       if (integerN < 2) {
+               LOGE(TAG, "Panic Reason: Modulus should be large than 2");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       int ret = SDRM_BN_ModAdd(bnDst, bnOp1, bnOp2, bnN);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_ModAdd fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntSubMod function computes dest = (op1 - op2) (mod n). All or
+ * some of dest, op1, and op2 MAY point to the same memory region but n MUST
+ * point to a unique memory region.
+ * @param dest Pointer to TEE_BigInt to hold the result (op1 - op2) (mod n)
+ * @param op1 Pointer to the first operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param op2 Pointer to the second operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param n Pointer to the modulus. Modulus MUST be larger than 1.
+ */
+void TEE_BigIntSubMod(TEE_BigInt* dest, const TEE_BigInt* op1,
+    const TEE_BigInt* op2, const TEE_BigInt* n) {
+
+       SDRM_BIG_NUM *bnDst = (SDRM_BIG_NUM*)dest;
+       SDRM_BIG_NUM *bnOp1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bnOp2 = (SDRM_BIG_NUM*)op2;
+       SDRM_BIG_NUM *bnN = (SDRM_BIG_NUM*)n;
+       int32_t integerN = 0;
+       TEE_BigIntConvertToS32(&integerN, (TEE_BigInt*)bnN);
+       if (integerN < 2) {
+               LOGE(TAG, "Panic Reason: Modulus should be large than 2");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       int ret = SDRM_BN_ModSub(bnDst, bnOp1, bnOp2, bnN);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_ModSub fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntMulMod function computes dest = (op1 * op2) (mod n). All or
+ * some of dest, op1, and op2 MAY point to the same memory region but n MUST
+ * point to a unique memory region.
+ * @param dest Pointer to TEE_BigInt to hold the result (op1 * op2) (mod n)
+ * @param op1 Pointer to the first operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param op2 Pointer to the second operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param n Pointer to the modulus. Modulus MUST be larger than 1.
+ */
+void TEE_BigIntMulMod(TEE_BigInt* dest, const TEE_BigInt* op1,
+    const TEE_BigInt* op2, const TEE_BigInt* n) {
+
+       SDRM_BIG_NUM *bnDst = (SDRM_BIG_NUM*)dest;
+       SDRM_BIG_NUM *bnOp1 = (SDRM_BIG_NUM*)op1;
+       SDRM_BIG_NUM *bnOp2 = (SDRM_BIG_NUM*)op2;
+       SDRM_BIG_NUM *bnN = (SDRM_BIG_NUM*)n;
+       int32_t integerN = 0;
+       TEE_BigIntConvertToS32(&integerN, (TEE_BigInt*)bnN);
+       if (integerN < 2) {
+               LOGE(TAG, "Panic Reason: Modulus should be large than 2");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       int ret = SDRM_BN_ModMul(bnDst, bnOp1, bnOp2, bnN);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_ModMul fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/**
+ * The TEE_BigIntSquareMod function computes dest = (op * op) (mod n).
+ * dest and op MAY point to the same memory region but n MUST
+ * point to a unique memory region.
+ * @param dest Pointer to TEE_BigInt to hold the result (op * op) (mod n)
+ * @param op Pointer to the operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param n Pointer to the modulus. Modulus MUST be larger than 1.
+ */
+void TEE_BigIntSquareMod(TEE_BigInt* dest, const TEE_BigInt* op,
+    const TEE_BigInt* n) {
+
+       SDRM_BIG_NUM *bnN = (SDRM_BIG_NUM*)n;
+       int32_t integerN = 0;
+       TEE_BigIntConvertToS32(&integerN, (TEE_BigInt*)bnN);
+       if (integerN < 2) {
+               LOGE(TAG, "Panic Reason: Modulus should be large than 2");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       TEE_BigIntMulMod(dest, op, op, n);
+       LOGD(TAG, "Called");
+}
+
+/**
+ * The TEE_BigIntInvMod function computes dest such that dest * op = 1 (mod n).
+ * dest and op MAY point to the same memory region. This function assumes that
+ * gcd(op,n) is equal to 1. If gcd(op,n) is greater than 1 then the result is
+ * unreliable.
+ * @param dest Pointer to TEE_BigInt to hold the result (op^-1) (mod n)
+ * @param op Pointer to the operand. Operand MUST be in the interval
+ *                             [0,n-1].
+ * @param n Pointer to the modulus. Modulus MUST be larger than 1.
+ */
+void TEE_BigIntInvMod(TEE_BigInt* dest, const TEE_BigInt* op,
+    const TEE_BigInt* n) {
+
+       SDRM_BIG_NUM *bnDst = (SDRM_BIG_NUM*)dest;
+       SDRM_BIG_NUM *bnOp = (SDRM_BIG_NUM*)op;
+       SDRM_BIG_NUM *bnN = (SDRM_BIG_NUM*)n;
+
+       int32_t integerOp = 0;
+       int32_t integerN = 0;
+       TEE_BigIntConvertToS32(&integerN, (TEE_BigInt*)bnN);
+       TEE_BigIntConvertToS32(&integerOp, (TEE_BigInt*)bnOp);
+       if (integerN < 2 || integerOp == 0) {
+               LOGE(TAG, "Panic Reason: Modulus should be large than 2");
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+       int ret = SDRM_BN_ModInv(bnDst, bnOp, bnN);
+       if (ret == CRYPTO_SUCCESS) {
+               LOGD(TAG, "Success");
+       } else {
+               LOGE(TAG, "Panic Reason: SDRM_BN_ModInv fail(ret:%d)", ret);
+               TEE_Panic(TEE_ERROR_GENERIC);
+       }
+}
+
+/* TODO : NOT IMPLEMENTED */
+/**
+ * The TEE_BigIntRelativePrime function determines whether gcd(op1, op2)==1.
+ * op1 and op2 MAY point to the same memory region.
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ */
+bool TEE_BigIntRelativePrime(const TEE_BigInt* op1, const TEE_BigInt* op2) {
+       (void)op1;
+       (void)op2;
+       return false;
+}
+
+/* TODO : NOT IMPLEMENTED */
+/**
+ * The TEE_BigIntComputeExtendedGcd function computes the greatest common
+ * divisor of the input parameters op1 and op2. Furthermore it computes the
+ * coefficients u and v such that u*op1+v*op2==gcd. op1 and op2 MAY point to
+ * the same memory region. u, v, or both can be NULL. If both are NULL then
+ * the function only computes the gcd of op1 and op2.
+ * @param gcd Pointer to TEE_BigInt to hold the greatest common divisor of
+ *                             op1 and op2
+ * @param u Pointer to TEE_BigInt to hold the first coefficient
+ * @param v Pointer to TEE_BigInt to hold the second coefficient
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ */
+void TEE_BigIntComputeExtendedGcd(TEE_BigInt* gcd, TEE_BigInt* u, TEE_BigInt* v,
+    const TEE_BigInt* op1, const TEE_BigInt* op2) {
+       (void)gcd;
+       (void)u;
+       (void)v;
+       (void)op1;
+       (void)op2;
+}
+
+/* TODO : NOT IMPLEMENTED */
+/**
+ * The TEE_BigIntIsProbablePrime function performs a probabilistic primality
+ * test on op. The parameter confidenceLevel is used to specify the probability
+ * of a non-conclusive answer. If the function cannot guarantee that op is
+ * prime or composite, it MUST iterate the test until the probability that op
+ * is composite is less than 2^(-confidenceLevel). Values smaller than 80 for
+ * confidenceLevel will not be recognized and will default to 80. The maximum
+ * honored value of confidenceLevel is implementation-specific, but MUST be at
+ * least 80.
+ * The algorithm for performing the primality test is implementation-specific,
+ * but its correctness and efficiency MUST be equal to or better than the
+ * Miller-Rabin test.
+ * @param op Candidate number that is tested for primality
+ * @param confidenceLevel The desired confidence level for a non-conclusive
+ * test. This parameter (usually) maps to the number of iterations and thus to
+ * the running time of the test. Values smaller than 80 will be treated as 80.
+ */
+int32_t TEE_BigIntIsProbablePrime(const TEE_BigInt* op,
+    uint32_t confidenceLevel) {
+       (void)op;
+       (void)confidenceLevel;
+       return 0;
+}
+
+/**
+ * The TEE_BigIntFMMSizeInU32 function returns the size of the array of
+ * uint32_t values needed to represent an integer in the fast modular
+ * multiplication representation, given the size of the modulus in bits.
+ * This function MUST never fail.
+ * @param modulusSizeInBits Size of modulus in bits
+ */
+size_t TEE_BigIntFMMSizeInU32(size_t modulusSizeInBits) {
+       return TEE_BigIntSizeInU32(modulusSizeInBits);
+}
+
+/**
+ * The TEE_BigIntInitFMM function initializes bigIntFMM and sets its
+ * represented value to zero. This function assumes that bigIntFMM points to
+ * a memory area of len uint32_t.
+ * @param object A pointer to the TEE_BigIntFMM to be initialized
+ * @param len The size in uint32_t of the memory pointed to by bigIntFMM
+ */
+void TEE_BigIntInitFMM(TEE_BigIntFMM* object, const size_t len) {
+       TEE_BigIntInit((TEE_BigInt*)object, len);
+}
+
+/**
+ * The TEE_BigIntFMMContextSizeInU32 function returns the size of the array
+ * of uint32_t values needed to represent a fast modular context using a
+ * given modulus size. This function MUST never fail.
+ * @param modulusSizeInBits Size of modulus in bits
+ */
+size_t TEE_BigIntFMMContextSizeInU32(const size_t modulusSizeInBits) {
+       return TEE_BigIntSizeInU32(modulusSizeInBits);
+}
+
+/**
+ * The TEE_BigIntInitFMMContext function calculates the necessary
+ * prerequisites for the fast modular multiplication and stores them in a
+ * context. This function assumes that context points to a memory area of
+ * len uint32_t.
+ * @param context A pointer to the TEE_BigIntFMMContext to be initialized
+ * @param len The size in uint32_t of the memory pointed to by context
+ * @param modulus The modulus, an odd integer larger than 2 and less than 2
+ * to the power of gpd.tee.arith.maxBigIntSize
+ */
+void TEE_BigIntInitFMMContext(TEE_BigIntFMMContext* context, const size_t len,
+    const TEE_BigInt* modulus) {
+}
+
+/**
+ * The TEE_BigIntConvertToFMM function converts src into a representation
+ * suitable for doing fast modular multiplication. If the operation is
+ * successful, the result will be written in implementation-specific format
+ * into the buffer dest, which MUST have been allocated by the TA and
+ * initialized using TEE_BigIntInitFMM.
+ * @param dest Pointer to an initialized TEE_BigIntFMM memory area
+ * @param src Pointer to the TEE_BigInt to convert
+ * @param n Pointer to the modulus
+ * @param context Pointer to a context previously initialized using
+ *                             TEE_BigIntInitFMMContext
+ */
+void TEE_BigIntConvertToFMM(TEE_BigIntFMM* dest, const TEE_BigInt* src,
+    const TEE_BigInt* n, const TEE_BigIntFMMContext* context) {
+}
+
+/**
+ * The TEE_BigIntConvertFromFMM function converts src in the fast modular
+ * multiplication representation back to a TEE_BigInt representation.
+ * @param dest Pointer to an initialized TEE_BigInt memory area to hold
+ *                                              the converted result
+ * @param src Pointer to a TEE_BigIntFMM holding the value in the fast
+ *                                             modular multiplication representation
+ * @param n Pointer to the modulus
+ * @param context Pointer to a context previously initialized using
+ *                                                             TEE_BigIntInitFMMContext
+ */
+void TEE_BigIntConvertFromFMM(TEE_BigInt* dest, const TEE_BigIntFMM* src,
+    const TEE_BigInt* n, const TEE_BigIntFMMContext* context) {
+}
+
+/**
+ * The TEE_BigIntComputeFMM function calculates dest = op1 * op2 in the fast
+ * modular multiplication representation. The pointers dest, op1, and op2 MUST
+ * each point to a TEE_BigIntFMM which has been previously initialized with
+ * the same modulus and context as used in this function call; otherwise the
+ * result is undefined. All or some of dest, op1, and op2 MAY point to the
+ * same memory region.
+ * @param dest Pointer to TEE_BigIntFMM to hold the result op1 * op2 in the
+ *                                              fast modular multiplication representation
+ * @param op1 Pointer to the first operand
+ * @param op2 Pointer to the second operand
+ * @param n Pointer to the modulus
+ * @param context Pointer to a context previously initialized using
+ *                                                             TEE_BigIntInitFMMContext
+ */
+void TEE_BigIntComputeFMM(TEE_BigIntFMM* dest, const TEE_BigIntFMM* op1,
+    const TEE_BigIntFMM* op2, const TEE_BigInt* n,
+    const TEE_BigIntFMMContext* context) {
+}
diff --git a/ssflib/src/ssf_client.c b/ssflib/src/ssf_client.c
new file mode 100755 (executable)
index 0000000..b76f0c8
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssfclient.c
+ *
+ *    Description:  SSF client functions
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  Cheryl (cb), cheryl.b@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "teestub_command_data.h"
+#include "tee_internal_api.h"
+#include <errno.h>
+#include <assert.h>
+#include "ssf_client.h"
+#include <unistd.h>
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define SOCKPATH "/tmp/simdaemon" //path to be updated
+
+//#define TEST
+
+/*-----------------------------------------------------------------------------
+ *  local functions
+ *-----------------------------------------------------------------------------*/
+/**
+ * API (Interface for TEECAPI) implementation for connecting to
+ * the Simulator daemon through socket
+ * @return socket file descriptor to connected server
+ */
+int32_t connecttoServer(void) {
+       LOGD(SSF_LIB, "Entry");
+       int serverSocket, socklen;
+       size_t sock_path_len = 0;
+       struct sockaddr* sockptr;
+       struct sockaddr_un daemonsock;
+
+       if ((serverSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+               LOGE(SSF_LIB, "No socket for simdaemon");
+               return -1;
+       }
+       daemonsock.sun_family = AF_UNIX;
+       
+       sock_path_len = strlen(SOCKPATH);
+       strncpy(daemonsock.sun_path, SOCKPATH, sock_path_len+1);
+
+       socklen = sizeof(daemonsock);
+       sockptr = (struct sockaddr*)&daemonsock;
+       if (connect(serverSocket, sockptr, socklen) == -1) {
+               LOGE(SSF_LIB, "connection to simdaemon failed");
+               close(serverSocket);
+               return -1;
+       }
+       return serverSocket;
+}
+
+/**
+ * API (Interface for TEECAPI) implementation for disconnecting
+ * from the Simulator daemon through socket
+ * @param ServerSocket
+ */
+void disconnectfromServer(int32_t serverSocket) {
+       int32_t result;
+       LOGD(SSF_LIB, "Entry");
+       if (serverSocket > 0) {
+               result = shutdown(serverSocket, SHUT_WR);
+               if (result != 0) LOGE(SSF_LIB, "disconnectfromServer failed");
+               close(serverSocket);
+       } else {
+               LOGE(SSF_LIB, "Invalid socket, disconnectfromServer failed");
+       }
+}
+
+/**
+ * Function implementation for sending data to Simulator daemon
+ * through socket
+ * @param sockfd file descriptor
+ * @param fdata structured data to daemon
+ * @param size size of fdata in bytes
+ * @return
+ */
+static uint32_t sendCommandtoDaemon(int32_t sockfd, char* fdata, size_t size) {
+       LOGD(SSF_LIB, "Entry");
+       ssize_t nwrite = 0;
+       size_t nbytes = 0;
+       if (sockfd > 0) {
+               do {
+                       nwrite = send(sockfd, fdata + nbytes, size - nbytes, 0);
+               } while ((nwrite == -1 && errno == EINTR) || (nwrite > 0 && ((nbytes +=
+                   nwrite) < size)));
+               return (size != nbytes) ? errno : 0;
+       }
+       LOGE(SSF_LIB, "failed");
+       return TEEC_ERROR_COMMUNICATION;
+}
+
+/**
+ * Function implementation for recieving data from Simulator
+ * daemon through socket
+ * @param sockfd file descriptor
+ * @param fdata structured data to be received
+ * @param size size of fdata in bytes
+ * @return
+ */
+static uint32_t receiveResponse(int32_t sockfd, char* fdata, size_t size) {
+       LOGD(SSF_LIB, "Entry");
+       ssize_t nread = 0;
+       size_t nbytes = 0;
+       if (sockfd > 0) {
+               do {
+                       nread = recv(sockfd, fdata + nbytes, size - nbytes, 0);
+               } while ((nread == -1 && errno == EINTR)
+                   || (nread > 0 && ((nbytes += nread) < size)));
+               return (size != nbytes) ? errno : 0;
+       }
+       LOGE(SSF_LIB, "failed");
+       return TEEC_ERROR_COMMUNICATION;
+}
+
+/**
+ * Test function to test the daemon
+ * @param cmd
+ * @param fdata
+ * @param size
+ * @param in
+ * @return
+ */
+#ifdef TEST
+static uint32_t Test(char cmd, char* fdata, size_t size, uint32_t in) {
+       //TODO: Implementation
+       return TEE_SUCCESS;
+}
+#endif
+
+/**
+ * API (Interface for TEECAPI) implementation for sending a
+ * command to Simulator daemon
+ * @param sockfd file descriptor
+ * @param cmd command to simulator daemon
+ * @param data structured data to daemon
+ * @param size size of data
+ * @return
+ */
+uint32_t sendCommand(int32_t sockfd, TEE_CMD cmd, void* data, size_t size) {
+       LOGD(SSF_LIB, "Entry");
+       TEE_Result result = TEE_SUCCESS;
+       char command = (char)cmd;
+#ifdef TEST
+       result = Test(command, (char*)data, size, 1);
+       if (result != TEE_SUCCESS) {
+               return TEE_ERROR_GENERIC;
+       }
+#endif
+       result = sendCommandtoDaemon(sockfd, (char*)&command, sizeof(char));
+       if (result != TEE_SUCCESS) {
+               return TEE_ERROR_GENERIC;
+       }
+       result = sendCommandtoDaemon(sockfd, (char*)data, size);
+       if (result != TEE_SUCCESS) {
+               return TEE_ERROR_GENERIC;
+       }
+       result = receiveResponse(sockfd, (char*)&command, sizeof(char));
+       if (result != TEE_SUCCESS) {
+               return TEE_ERROR_GENERIC;
+       }
+       result = receiveResponse(sockfd, (char*)data, size);
+       if (result != TEE_SUCCESS) {
+               return TEE_ERROR_GENERIC;
+       }
+#ifdef TEST
+       result = Test(command, (char*)data, size, 0);
+       if (result != TEE_SUCCESS) {
+               return TEE_ERROR_GENERIC;
+       }
+#endif
+       return result;
+}
diff --git a/ssflib/src/ssf_crypto.c b/ssflib/src/ssf_crypto.c
new file mode 100755 (executable)
index 0000000..655eabd
--- /dev/null
@@ -0,0 +1,2598 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_crypto.c
+ *
+ *    Description:  SSF crypto functions
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+#define _CRT_RAND_S
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "uci_api.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "unistd.h"
+#include "uci_internal.h"
+#include "tee_internal_api.h"
+#include <time.h>
+#include <sys/time.h>
+
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define g_bTAdbug 1
+#define TZ_PRINT(fmt...) \
+               do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+#define TZ_ERROR(fmt...) \
+               do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+#undef PrintBYTE
+#define PrintBYTE(msg, Data, DataLen) {                 \
+               int idx;                                            \
+               TZ_PRINT("%10s =", msg);                                \
+               for(idx=0; idx<(int)DataLen; idx++) {              \
+                       if((idx!=0) && ((idx%16)==0)) TZ_PRINT("\n"); \
+                       if((idx % 4) == 0)  TZ_PRINT(" 0x");                \
+                       TZ_PRINT("%.2x", Data[idx]);                        \
+               }                                                   \
+               TZ_PRINT("\n");                                     \
+               }
+
+/*-----------------------------------------------------------------------------
+ *  Definitions
+ *-----------------------------------------------------------------------------*/
+struct __TEE_ObjectHandle {
+       TEE_ObjectInfo info;
+};
+
+struct __TEE_OperationHandle {
+       TEE_OperationInfo info;
+};
+
+struct TEE_Operation {
+       TEE_OperationInfo info;
+       TEE_ObjectHandle key1;
+       TEE_ObjectHandle key2;
+       int crypto; // handle to crypto driver or ponter to crypto library context
+};
+
+static long getClock(void) {
+       struct timeval tv;
+       gettimeofday (&tv, NULL);
+       return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
+}
+
+/*-----------------------------------------------------------------------------
+ *  Local functions
+ *-----------------------------------------------------------------------------*/
+static uint32_t object_type_from_algorithm(uint32_t alg, uint32_t *obj_type,
+    uint32_t * uci_type) {
+       switch (alg) {
+
+               // KRISHNA: ADDED BELOW, VERIFY ONCE
+               case TEE_ALG_AES_ECB_PKCS5:
+               case TEE_ALG_AES_ECB_PKCS7:
+               case TEE_ALG_AES_ECB_ISO9797_M1:
+               case TEE_ALG_AES_ECB_ISO9797_M2:
+               case TEE_ALG_AES_CBC_PKCS5:
+               case TEE_ALG_AES_CBC_PKCS7:
+               case TEE_ALG_AES_CBC_ISO9797_M1:
+               case TEE_ALG_AES_CBC_ISO9797_M2:
+               // OLD CODE
+               case TEE_ALG_AES_ECB_NOPAD:
+               case TEE_ALG_AES_CBC_NOPAD:
+               case TEE_ALG_AES_CTR:
+               case TEE_ALG_AES_CTR_NOPAD:
+               case TEE_ALG_AES_CTS:
+               case TEE_ALG_AES_XTS:
+               case TEE_ALG_AES_CCM:
+               case TEE_ALG_AES_GCM:
+                       *obj_type = TEE_TYPE_AES;
+                       *uci_type = ID_UCI_AES;
+                       break;
+               case TEE_ALG_AES_CBC_MAC_NOPAD:
+                       *obj_type = TEE_TYPE_AES;
+                       *uci_type = ID_UCI_XCBCMAC;
+                       break;
+               case TEE_ALG_AES_CBC_MAC_PKCS5:
+               case TEE_ALG_AES_CMAC:
+               case TEE_ALG_DES_CBC_MAC_NOPAD:
+               case TEE_ALG_DES_CBC_MAC_PKCS5:
+               case TEE_ALG_DES3_CBC_MAC_NOPAD:
+               case TEE_ALG_DES3_CBC_MAC_PKCS5:
+                       *obj_type = TEE_TYPE_AES;
+                       *uci_type = ID_UCI_CMAC;
+                       break;
+               case TEE_ALG_DES_ECB_NOPAD:
+               case TEE_ALG_DES_CBC_NOPAD:
+                       *obj_type = TEE_TYPE_DES;
+                       *uci_type = ID_UCI_DES;
+                       break;
+               case TEE_ALG_DES3_ECB_NOPAD:
+               case TEE_ALG_DES3_CBC_NOPAD:
+                       *obj_type = TEE_TYPE_DES3;
+                       *uci_type = ID_UCI_TDES;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
+               case TEE_ALG_RSAES_PKCS1_V1_5:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
+               case TEE_ALG_RSA_NOPAD:
+                       *obj_type = TEE_TYPE_RSA_KEYPAIR;
+                       *uci_type = 0;
+                       break;
+               case TEE_ALG_DSA_SHA1:
+                       *obj_type = TEE_TYPE_DSA_KEYPAIR;
+                       *uci_type = ID_UCI_DSA;
+                       break;
+#ifdef ECC_IMPLEMENTATION
+               case TEE_ALG_ECDSA_P160:
+               case TEE_ALG_ECDSA_P192:
+               case TEE_ALG_ECDSA_P224:
+               case TEE_ALG_ECDSA_P256:
+               case TEE_ALG_ECDSA_P384:
+               case TEE_ALG_ECDSA_P521:
+                       *obj_type = TEE_TYPE_ECDSA_KEYPAIR;
+                       *uci_type = ID_UCI_ECDSA;
+                       break;
+               case TEE_ALG_ECDH_P192:
+               case TEE_ALG_ECDH_P224:
+               case TEE_ALG_ECDH_P256:
+               case TEE_ALG_ECDH_P384:
+               case TEE_ALG_ECDH_P521:
+                       *obj_type = TEE_TYPE_ECDH_KEYPAIR;
+                       *uci_type = ID_UCI_ECDH;
+                       break;
+#endif
+               case TEE_ALG_DH_DERIVE_SHARED_SECRET:
+                       *obj_type = TEE_TYPE_DH_KEYPAIR;
+                       *uci_type = ID_UCI_DH;
+                       break;
+               case TEE_ALG_HMAC_MD5:
+                       *obj_type = TEE_TYPE_HMAC_MD5;
+                       *uci_type = ID_UCI_HMD5;
+                       break;
+               case TEE_ALG_HMAC_SHA1:
+                       *obj_type = TEE_TYPE_HMAC_SHA1;
+                       *uci_type = ID_UCI_HSHA1;
+                       break;
+               case TEE_ALG_HMAC_SHA224:
+                       *obj_type = TEE_TYPE_HMAC_SHA224;
+                       *uci_type = ID_UCI_HSHA224;
+                       break;
+               case TEE_ALG_HMAC_SHA256:
+                       *obj_type = TEE_TYPE_HMAC_SHA256;
+                       *uci_type = ID_UCI_HSHA256;
+                       break;
+               case TEE_ALG_HMAC_SHA384:
+                       *obj_type = TEE_TYPE_HMAC_SHA384;
+                       *uci_type = ID_UCI_HSHA384;
+                       break;
+               case TEE_ALG_HMAC_SHA512:
+                       *obj_type = TEE_TYPE_HMAC_SHA512;
+                       *uci_type = ID_UCI_HSHA512;
+                       break;
+               case TEE_ALG_MD5:
+                       *uci_type = ID_UCI_MD5;
+                       break;
+               case TEE_ALG_SHA1:
+                       *uci_type = ID_UCI_SHA1;
+                       break;
+               case TEE_ALG_SHA224:
+                       *uci_type = ID_UCI_SHA224;
+                       break;
+               case TEE_ALG_SHA256:
+                       *uci_type = ID_UCI_SHA256;
+                       break;
+               case TEE_ALG_SHA384:
+                       *uci_type = ID_UCI_SHA384;
+                       break;
+               case TEE_ALG_SHA512:
+                       *uci_type = ID_UCI_SHA512;
+                       break;
+       }
+       return *obj_type;
+}
+
+static int crypto_lib_init_operation(TEE_OperationHandle operation) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+       if (uci_md_init(op->crypto) != UCI_SUCCESS) {
+               TEE_Panic(0);
+       }
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+ *  TEE API implementation
+ *-----------------------------------------------------------------------------*/
+// Generic Operation Functions
+TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation,
+    uint32_t algorithm, uint32_t mode, uint32_t maxKeySize) {
+       struct TEE_Operation * op;
+       uint32_t alg_class = 0;
+       uint32_t object_type = 0;
+       uint32_t uci_type = 0;
+       TEE_Result rc;
+       TEE_ObjectHandle key1 = TEE_HANDLE_NULL;
+       TEE_ObjectHandle key2 = TEE_HANDLE_NULL;
+       int digest_len = 0;
+       uint32_t block_len = 0;
+       uint32_t key_object_type = 0;
+       /* NEW CODE FROM PLATFORM CODE BASE OF SECURE OS */
+       // check parameters compatibility
+       switch(algorithm)
+       {
+               /* Algorithm Class is SYMMETRIC CIPHER */
+               case TEE_ALG_AES_ECB_NOPAD:
+               case TEE_ALG_AES_CBC_NOPAD:
+               case TEE_ALG_AES_CTR:
+               case TEE_ALG_AES_CTR_NOPAD:
+               case TEE_ALG_AES_ECB_PKCS5:
+               case TEE_ALG_AES_ECB_PKCS7:
+               case TEE_ALG_AES_ECB_ISO9797_M1:
+               case TEE_ALG_AES_ECB_ISO9797_M2:
+               case TEE_ALG_AES_CBC_PKCS5:
+               case TEE_ALG_AES_CBC_PKCS7:
+               case TEE_ALG_AES_CBC_ISO9797_M1:
+               case TEE_ALG_AES_CBC_ISO9797_M2:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_AES;
+                       block_len = 16;
+                       digest_len = 0;
+                       break;
+
+               case TEE_ALG_AES_XTS:
+               case TEE_ALG_AES_CTS:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+
+               case TEE_ALG_DES_ECB_NOPAD:
+               case TEE_ALG_DES_CBC_NOPAD:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_DES;
+                       block_len = 8;
+                       digest_len = 0;
+                       break;
+
+               case TEE_ALG_DES3_ECB_NOPAD:
+               case TEE_ALG_DES3_CBC_NOPAD:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_DES3;
+                       block_len = 8;
+                       digest_len = 0;
+                       break;
+
+               /* Algorithm Class is AE */
+               case TEE_ALG_AES_CCM:
+               case TEE_ALG_AES_GCM:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+
+               /* Algorithm Class is MAC */
+               case TEE_ALG_AES_CBC_MAC_NOPAD:
+               case TEE_ALG_AES_CBC_MAC_PKCS5:
+               case TEE_ALG_DES_CBC_MAC_NOPAD:
+               case TEE_ALG_DES_CBC_MAC_PKCS5:
+               case TEE_ALG_AES_CMAC:
+               case TEE_ALG_DES3_CBC_MAC_NOPAD:
+               case TEE_ALG_DES3_CBC_MAC_PKCS5:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+          
+
+
+               case TEE_ALG_HMAC_MD5:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_MD5;
+                       block_len = 64;
+                       digest_len =    16;
+                       break;
+
+               case TEE_ALG_HMAC_SHA1:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA1;
+                       block_len = 64;
+                       digest_len =    20;
+                       break;
+
+               case TEE_ALG_HMAC_SHA224:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA224;
+                       block_len = 64;
+                       digest_len =    28;
+                       break;
+
+               case TEE_ALG_HMAC_SHA256:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA256;
+                       block_len = 64;
+                       digest_len =    32;
+                       break;
+
+               case TEE_ALG_HMAC_SHA384:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA384;
+                       block_len = 64;
+                       digest_len =    48;
+                       break;
+
+               case TEE_ALG_HMAC_SHA512:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA512;
+                       block_len = 64;
+                       digest_len =    64;
+                       break;
+
+               /* Algorithm Class is DIGIT */
+               case TEE_ALG_MD5:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 16;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA1:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 20;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA224:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 28;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA256:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 32;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA384:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 48;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA512:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 64;
+                       block_len = 64;
+                       break;
+
+               /* Algorithm Class is ASYMMETRIC CIPHER */
+               case TEE_ALG_RSAES_PKCS1_V1_5:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
+               case TEE_ALG_RSA_NOPAD:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_CIPHER;
+                       key_object_type = TEE_TYPE_RSA_KEYPAIR;
+                       block_len = 0;
+                       digest_len =    0;
+                       break;
+
+               /* Algorithm Class is SIGNATURE */
+               case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
+               if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
+                       key_object_type = TEE_TYPE_RSA_KEYPAIR;
+                       break;
+
+               case TEE_ALG_ECDSA_P160:
+               case TEE_ALG_ECDSA_P192:
+               case TEE_ALG_ECDSA_P224:
+               case TEE_ALG_ECDSA_P256:
+               case TEE_ALG_ECDSA_P384:
+               case TEE_ALG_ECDSA_P521:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+
+               case TEE_ALG_DSA_SHA1:
+               case TEE_ALG_ECDH_P192:
+               case TEE_ALG_ECDH_P224:
+               case TEE_ALG_ECDH_P256:
+               case TEE_ALG_ECDH_P384:
+               case TEE_ALG_ECDH_P521:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+
+               /* Algorithm Class is KEY DERIVATION */
+               case TEE_ALG_DH_DERIVE_SHARED_SECRET:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+
+               default:
+                       //printf("Not Support Algorithm : %X", algorithm);
+                       TZ_ERROR("Not Support Algorithm  %d,%s %X\n", __LINE__, __func__, algorithm);
+                       rc =  TEE_ERROR_NOT_SUPPORTED;
+                       goto exit;
+                       break;
+       }
+
+
+
+
+
+
+       /*
+       // OLD SWITCH
+       switch (algorithm) {
+               case TEE_ALG_AES_XTS:
+                       return TEE_ERROR_NOT_SUPPORTED;
+                       break;
+               case TEE_ALG_AES_ECB_NOPAD:
+               case TEE_ALG_AES_CBC_NOPAD:
+               case TEE_ALG_AES_CTR:
+               case TEE_ALG_AES_CTS:
+               case TEE_ALG_DES_ECB_NOPAD:
+               case TEE_ALG_DES_CBC_NOPAD:
+               case TEE_ALG_DES3_ECB_NOPAD:
+               case TEE_ALG_DES3_CBC_NOPAD:
+                       if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       alg_class = TEE_OPERATION_CIPHER;
+                       break;
+               case TEE_ALG_AES_CCM:
+                       if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 0; // will be set during initialisation
+                       alg_class = TEE_OPERATION_AE;
+                       break;
+               case TEE_ALG_AES_GCM:
+                       if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 0; // will be set during initialisation
+                       alg_class = TEE_OPERATION_AE;
+                       break;
+               case TEE_ALG_AES_CBC_MAC_NOPAD:
+               case TEE_ALG_AES_CBC_MAC_PKCS5:
+               case TEE_ALG_AES_CMAC:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               case TEE_ALG_DES_CBC_MAC_NOPAD:
+               case TEE_ALG_DES_CBC_MAC_PKCS5:
+               case TEE_ALG_DES3_CBC_MAC_NOPAD:
+               case TEE_ALG_DES3_CBC_MAC_PKCS5:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       alg_class = TEE_OPERATION_MAC;
+                       return TEE_ERROR_NOT_SUPPORTED;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
+               case TEE_ALG_DSA_SHA1:
+#ifdef ECC_IMPLEMENTATION
+               case TEE_ALG_ECDSA_P160:
+               case TEE_ALG_ECDSA_P192:
+               case TEE_ALG_ECDSA_P224:
+               case TEE_ALG_ECDSA_P256:
+               case TEE_ALG_ECDSA_P384:
+               case TEE_ALG_ECDSA_P521:
+#endif
+                       if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       alg_class = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
+                       break;
+               case TEE_ALG_RSAES_PKCS1_V1_5:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
+               case TEE_ALG_RSA_NOPAD:
+                       if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       alg_class = TEE_OPERATION_ASYMMETRIC_CIPHER;
+                       break;
+               case TEE_ALG_DH_DERIVE_SHARED_SECRET:
+                       if (mode != TEE_MODE_DERIVE) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       alg_class = TEE_OPERATION_KEY_DERIVATION;
+                       break;
+               case TEE_ALG_MD5:
+                       if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 16;
+                       alg_class = TEE_OPERATION_DIGEST;
+                       break;
+               case TEE_ALG_SHA1:
+                       if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 20;
+                       alg_class = TEE_OPERATION_DIGEST;
+                       break;
+               case TEE_ALG_SHA224:
+                       if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 28;
+                       alg_class = TEE_OPERATION_DIGEST;
+                       break;
+               case TEE_ALG_SHA256:
+                       if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 32;
+                       alg_class = TEE_OPERATION_DIGEST;
+                       break;
+               case TEE_ALG_SHA384:
+                       if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 48;
+                       alg_class = TEE_OPERATION_DIGEST;
+                       break;
+               case TEE_ALG_SHA512:
+                       if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 64;
+                       alg_class = TEE_OPERATION_DIGEST;
+                       break;
+               case TEE_ALG_HMAC_MD5:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 16;
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               case TEE_ALG_HMAC_SHA1:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 20;
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               case TEE_ALG_HMAC_SHA224:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 28;
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               case TEE_ALG_HMAC_SHA256:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 32;
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               case TEE_ALG_HMAC_SHA384:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 48;
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               case TEE_ALG_HMAC_SHA512:
+                       if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       digest_len = 64;
+                       alg_class = TEE_OPERATION_MAC;
+                       break;
+               default:
+                       TZ_ERROR("algorithm error %d,%s\n", __LINE__, __func__);
+                       return TEE_ERROR_NOT_SUPPORTED;
+       }
+       */
+       object_type = object_type_from_algorithm(algorithm, &object_type, &uci_type);
+       if (alg_class != TEE_OPERATION_DIGEST) {
+               rc = TEE_AllocateTransientObject(object_type, maxKeySize, &key1);
+               if (rc != TEE_SUCCESS) {
+                       TZ_ERROR("TEE_AllocateTransientObject error %d,%s\n", __LINE__, __func__);
+                       return rc;
+               }
+#if 0
+               // TODO: TEE_ALG_AES_XTS not supported
+               if (algorithm == TEE_ALG_AES_XTS)// 2 keys for TEE_ALG_AES_XTS
+               {
+                       rc = TEE_AllocateTransientObject(object_type, maxKeySize, &key2);
+                       if (rc != TEE_SUCCESS) {
+                               TEE_CloseObject(key1);
+                               TZ_ERROR("TEE_AllocateTransientObject error %d,%s\n",
+                                               __LINE__,
+                                               __func__);
+                               return rc;
+                       }
+               }
+#endif
+       }
+       //ALLOC MEMORY
+       op = (TEE_Operation*)OsaMalloc(sizeof(struct TEE_Operation));
+       if (!op) {
+               if (key1) {
+                       TEE_CloseObject(key1);
+               }
+#if 0
+               // TODO: TEE_ALG_AES_XTS not supported
+               if (key2) {
+                       TEE_CloseObject(key2);
+               }
+#endif
+               TZ_ERROR("malloc error %d,%s\n", __LINE__, __func__);
+               return TEE_ERROR_OUT_OF_MEMORY;
+       }
+       memset(op, 0, sizeof(struct TEE_Operation));
+       op->info.algorithm = algorithm;
+       op->info.mode = mode;
+       op->info.maxKeySize = maxKeySize;
+       op->info.digestLength = digest_len;
+       op->info.keySize = 0;
+       op->info.operationClass = alg_class;
+       op->info.requiredKeyUsage = 0;
+       switch (mode) {
+               case TEE_MODE_ENCRYPT:
+                       op->info.requiredKeyUsage |= TEE_USAGE_ENCRYPT;
+                       break;
+               case TEE_MODE_DECRYPT:
+                       op->info.requiredKeyUsage |= TEE_USAGE_DECRYPT;
+                       break;
+               case TEE_MODE_MAC:
+                       op->info.requiredKeyUsage |= TEE_USAGE_MAC;
+                       break;
+               case TEE_MODE_DERIVE:
+                       op->info.requiredKeyUsage |= TEE_USAGE_DERIVE;
+                       break;
+               case TEE_MODE_SIGN:
+                       op->info.requiredKeyUsage |= TEE_USAGE_SIGN;
+                       break;
+               case TEE_MODE_VERIFY:
+                       op->info.requiredKeyUsage |= TEE_USAGE_VERIFY;
+                       break;
+       }
+       op->info.handleState = 0;
+       if (alg_class == TEE_OPERATION_DIGEST) {
+               op->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
+       }
+#if 1
+       // TODO: TEE_ALG_AES_XTS not supported
+       if (algorithm == TEE_ALG_AES_XTS) {
+               op->info.handleState |= TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
+       }
+
+       /* key1 alloc */
+       if (key_object_type) {
+               if (TEE_AllocateTransientObject(key_object_type, maxKeySize, &key1) != TEE_SUCCESS) {
+                       rc = TEE_ERROR_OUT_OF_MEMORY;
+                       goto error;
+               }
+       }
+
+       /* key2 alloc for XTS */
+       if (algorithm == TEE_ALG_AES_XTS) {
+               if (TEE_AllocateTransientObject(key_object_type, maxKeySize, &key2) != TEE_SUCCESS) {
+                       rc = TEE_ERROR_OUT_OF_MEMORY;
+                       goto error;
+               }
+       }
+#endif
+       op->key1 = key1;
+       op->key2 = key2;
+       // [TODO] NEED TO FIX THIS STRUCTURE TO INCLUDE BLOCK_LEN MEMBER
+       //op->block_len = block_len;
+       if (uci_type != 0) {
+               op->crypto = uci_context_alloc(uci_type, UCI_SW);
+       } else {
+               op->crypto = 0;
+       }
+       *operation = (TEE_OperationHandle)&op->info;
+
+       if (alg_class == TEE_OPERATION_DIGEST) {
+               crypto_lib_init_operation(*operation); //in case hash contex will not inited.
+       }
+       return TEE_SUCCESS;
+
+
+error:
+       if (key1) {
+               TEE_CloseObject(key1);
+       }
+       if (key2) {
+               TEE_CloseObject(key2);
+       }
+       if (op) {
+               free(op);
+       }
+exit:
+       *operation = TEE_HANDLE_NULL;
+        printf("Error : %X", rc);
+
+        return rc;
+
+}
+// KRISHNA - OLD CODE
+
+
+/*TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, uint32_t algorithm, uint32_t mode, uint32_t maxKeySize)
+{
+       //PERMISSION_CHECK(PERM_CRYPTO);
+
+       crypto_internal_operation * op;
+       TEE_Result rc=TEE_SUCCESS;
+       uint32_t alg_class = 0;
+       uint32_t key_object_type = 0;
+       uint32_t digest_len = 0;
+       uint32_t block_len = 0;
+       TEE_ObjectHandle key1 = TEE_HANDLE_NULL;
+       TEE_ObjectHandle key2 = TEE_HANDLE_NULL;
+
+       // check parameters compatibility
+       switch(algorithm)
+       {
+               // Algorithm Class is SYMMETRIC CIPHER 
+               case TEE_ALG_AES_ECB_NOPAD:
+               case TEE_ALG_AES_CBC_NOPAD:
+               case TEE_ALG_AES_CTR:
+               case TEE_ALG_AES_CTR_NOPAD:
+               case TEE_ALG_AES_ECB_PKCS5:
+               case TEE_ALG_AES_ECB_PKCS7:
+               case TEE_ALG_AES_ECB_ISO9797_M1:
+               case TEE_ALG_AES_ECB_ISO9797_M2:
+               case TEE_ALG_AES_CBC_PKCS5:
+               case TEE_ALG_AES_CBC_PKCS7:
+               case TEE_ALG_AES_CBC_ISO9797_M1:
+               case TEE_ALG_AES_CBC_ISO9797_M2:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_AES;
+                       block_len = 16;
+                       digest_len = 0;
+                       break;
+
+               case TEE_ALG_AES_XTS:
+               case TEE_ALG_AES_CTS:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_AES;
+                       block_len = 32; // for CTS & XTS need 2 AES blocks
+                       digest_len = 0;
+                       break;
+
+               case TEE_ALG_DES_ECB_NOPAD:
+               case TEE_ALG_DES_CBC_NOPAD:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_DES;
+                       block_len = 8;
+                       digest_len = 0;
+                       break;
+
+               case TEE_ALG_DES3_ECB_NOPAD:
+               case TEE_ALG_DES3_CBC_NOPAD:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_CIPHER;
+                       key_object_type = TEE_TYPE_DES3;
+                       block_len = 8;
+                       digest_len = 0;
+                       break;
+
+               // Algorithm Class is AE 
+               case TEE_ALG_AES_CCM:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_AE;
+                       key_object_type = TEE_TYPE_AES;
+                       block_len = 16;
+                       digest_len = 0;
+                       break;
+
+               case TEE_ALG_AES_GCM:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_AE;
+                       key_object_type = TEE_TYPE_AES;
+                       block_len = 16;
+                       digest_len = 0;
+                       break;
+
+               // Algorithm Class is MAC 
+               case TEE_ALG_AES_CBC_MAC_NOPAD:
+               case TEE_ALG_AES_CBC_MAC_PKCS5:
+               case TEE_ALG_AES_CMAC:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_AES;
+                       block_len = 16;
+                       digest_len = 16;
+                       break;
+
+               case TEE_ALG_DES_CBC_MAC_NOPAD:
+               case TEE_ALG_DES_CBC_MAC_PKCS5:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_DES;
+                       block_len = 8;
+                       digest_len = 8;
+                       break;
+
+               case TEE_ALG_DES3_CBC_MAC_NOPAD:
+               case TEE_ALG_DES3_CBC_MAC_PKCS5:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_DES3;
+                       block_len = 8;
+                       digest_len = 8;
+                       break;
+
+               case TEE_ALG_HMAC_MD5:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_MD5;
+                       block_len = 64;
+                       digest_len =    16;
+                       break;
+
+               case TEE_ALG_HMAC_SHA1:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA1;
+                       block_len = 64;
+                       digest_len =    20;
+                       break;
+
+               case TEE_ALG_HMAC_SHA224:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA224;
+                       block_len = 64;
+                       digest_len =    28;
+                       break;
+
+               case TEE_ALG_HMAC_SHA256:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA256;
+                       block_len = 64;
+                       digest_len =    32;
+                       break;
+
+               case TEE_ALG_HMAC_SHA384:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA384;
+                       block_len = 64;
+                       digest_len =    48;
+                       break;
+
+               case TEE_ALG_HMAC_SHA512:
+               if (mode != TEE_MODE_MAC) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_MAC;
+                       key_object_type = TEE_TYPE_HMAC_SHA512;
+                       block_len = 64;
+                       digest_len =    64;
+                       break;
+
+               // Algorithm Class is DIGIT 
+               case TEE_ALG_MD5:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 16;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA1:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 20;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA224:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 28;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA256:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 32;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA384:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 48;
+                       block_len = 64;
+                       break;
+
+               case TEE_ALG_SHA512:
+               if (mode != TEE_MODE_DIGEST) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_DIGEST;
+                       key_object_type = 0;
+                       digest_len = 64;
+                       block_len = 64;
+                       break;
+
+               // Algorithm Class is ASYMMETRIC CIPHER 
+               case TEE_ALG_RSAES_PKCS1_V1_5:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
+               case TEE_ALG_RSA_NOPAD:
+               if (mode != TEE_MODE_ENCRYPT && mode != TEE_MODE_DECRYPT) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_CIPHER;
+                       key_object_type = TEE_TYPE_RSA_KEYPAIR;
+                       block_len = 0;
+                       digest_len =    0;
+                       break;
+
+               // Algorithm Class is SIGNATURE 
+               case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
+               if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
+                       key_object_type = TEE_TYPE_RSA_KEYPAIR;
+                       break;
+
+               case TEE_ALG_ECDSA_P160:
+               case TEE_ALG_ECDSA_P192:
+               case TEE_ALG_ECDSA_P224:
+               case TEE_ALG_ECDSA_P256:
+               case TEE_ALG_ECDSA_P384:
+               case TEE_ALG_ECDSA_P521:
+               if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
+                       key_object_type = TEE_TYPE_RSA_KEYPAIR;
+                       break;
+
+               case TEE_ALG_DSA_SHA1:
+               if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
+                       key_object_type = TEE_TYPE_DSA_KEYPAIR;
+                       break;
+
+               case TEE_ALG_ECDH_P192:
+               case TEE_ALG_ECDH_P224:
+               case TEE_ALG_ECDH_P256:
+               case TEE_ALG_ECDH_P384:
+               case TEE_ALG_ECDH_P521:
+               if (mode != TEE_MODE_SIGN && mode != TEE_MODE_VERIFY) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
+                       key_object_type = TEE_TYPE_ECDH_KEYPAIR;
+                       break;
+
+               // Algorithm Class is KEY DERIVATION 
+               case TEE_ALG_DH_DERIVE_SHARED_SECRET:
+               if (mode != TEE_MODE_DERIVE) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+               }
+
+                       alg_class = TEE_OPERATION_KEY_DERIVATION;
+                       key_object_type = TEE_TYPE_DH_KEYPAIR;
+                       break;
+
+               default:
+                       LOGE(TAG, "Not Support Algorithm : %X", algorithm);
+                       rc =  TEE_ERROR_NOT_SUPPORTED;
+                       goto exit;
+                       break;
+       }
+
+       // first malloc for crypto operation 
+       op = malloc(sizeof (crypto_internal_operation));
+       if (!op) {
+               rc = TEE_ERROR_OUT_OF_MEMORY;
+               goto exit;
+       }
+
+       memset(op, 0, sizeof (crypto_internal_operation));
+
+       // Set TEE_OperationInfo 
+       op->info.algorithm = algorithm;
+       op->info.operationClass = alg_class;
+       op->info.mode = mode;
+       op->info.digestLength = digest_len;
+       op->info.maxKeySize = maxKeySize;
+       op->info.keySize = maxKeySize;
+
+       if (mode == TEE_MODE_ENCRYPT) {
+               op->info.requiredKeyUsage |= TEE_USAGE_ENCRYPT;
+       }
+       if (mode == TEE_MODE_DECRYPT) {
+               op->info.requiredKeyUsage |= TEE_USAGE_DECRYPT;
+       }
+       if (mode == TEE_MODE_MAC) {
+               op->info.requiredKeyUsage |= TEE_USAGE_MAC;
+       }
+       if (mode == TEE_MODE_DERIVE) {
+               op->info.requiredKeyUsage |= TEE_USAGE_DERIVE;
+       }
+       if (mode == TEE_MODE_SIGN) {
+               op->info.requiredKeyUsage |= TEE_USAGE_SIGN;
+       }
+       if (mode == TEE_MODE_VERIFY) {
+               op->info.requiredKeyUsage |= TEE_USAGE_VERIFY;
+       }
+       if (algorithm == TEE_ALG_RSA_NOPAD)
+       {
+               if (mode == TEE_MODE_ENCRYPT) {
+                       op->info.requiredKeyUsage |= TEE_USAGE_VERIFY;
+               }
+               else if (mode == TEE_MODE_DECRYPT) {
+                       op->info.requiredKeyUsage |= TEE_USAGE_SIGN;
+               }
+       }
+
+       if (algorithm == TEE_ALG_AES_XTS) {
+               op->info.handleState |= TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
+       }
+
+       // get handle 
+       if(crypto_internal_open(op)!=0) {
+               rc = TEE_ERROR_NOT_SUPPORTED;
+               goto error;
+       }
+
+       // key1 alloc 
+       if (key_object_type) {
+               if (TEE_AllocateTransientObject(key_object_type, maxKeySize, &key1) != TEE_SUCCESS) {
+                       rc = TEE_ERROR_OUT_OF_MEMORY;
+                       goto error;
+               }
+       }
+
+       // key2 alloc for XTS 
+       if (algorithm == TEE_ALG_AES_XTS) {
+               if (TEE_AllocateTransientObject(key_object_type, maxKeySize, &key2) != TEE_SUCCESS) {
+                       rc = TEE_ERROR_OUT_OF_MEMORY;
+                       goto error;
+               }
+       }
+
+       // key map for crypto operation 
+       op->key1 = key1;
+       op->key2 = key2;
+       op->block_len = block_len;
+
+       *operation = (TEE_OperationHandle) &op->info;
+       if (alg_class == TEE_OPERATION_DIGEST) {
+               TEE_DigestInit(*operation);
+       }
+
+       return TEE_SUCCESS;
+
+error:
+       crypto_internal_close(op);
+       if (key1) {
+               TEE_CloseObject(key1);
+       }
+       if (key2) {
+               TEE_CloseObject(key2);
+       }
+       if (op) {
+               free(op);
+       }
+exit:
+       *operation = TEE_HANDLE_NULL;
+       LOGE(TAG, "Error : %X", rc);
+       return rc;
+}
+*/
+
+
+
+void TEE_FreeOperation(TEE_OperationHandle operation) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+       if (op->key1) {
+               TEE_CloseObject(op->key1);
+       }
+       if (op->key2) {
+               TEE_CloseObject(op->key2);
+       }
+       if (uci_context_free(op->crypto) != UCI_SUCCESS) {
+               TZ_ERROR("free error %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       OsaFree(op);
+}
+
+void TEE_GetOperationInfo(TEE_OperationHandle operation,
+    TEE_OperationInfo* operationInfo) {
+       operationInfo->algorithm = operation->info.algorithm;
+       operationInfo->digestLength = operation->info.digestLength;
+       operationInfo->handleState = operation->info.handleState;
+       operationInfo->keySize = operation->info.keySize;
+       operationInfo->maxKeySize = operation->info.maxKeySize;
+       operationInfo->mode = operation->info.mode;
+       operationInfo->operationClass = operation->info.operationClass;
+       operationInfo->requiredKeyUsage = operation->info.requiredKeyUsage;
+}
+
+void TEE_ResetOperation(TEE_OperationHandle operation) {
+       operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
+}
+
+TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation,
+    TEE_ObjectHandle key) {
+       uci_key_s ucikey;
+       uci_param_s uciparam;
+       TEE_Result rc;
+       unsigned char pub[384];
+       unsigned char priv[384];
+       unsigned char module[384];
+       unsigned int pubLen = 384;
+       unsigned int privLen = 384;
+       unsigned int moduleLen = 384;
+       unsigned int alg;
+       memset(&ucikey, 0, sizeof(uci_key_s));
+       memset(&uciparam, 0, sizeof(uci_param_s));
+
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass == TEE_OPERATION_DIGEST
+           || operation->info.algorithm == TEE_ALG_AES_XTS) {
+               TZ_ERROR("operation error %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (key == TEE_HANDLE_NULL) {
+               TEE_CloseObject(op->key1);
+               op->key1 = TEE_HANDLE_NULL;
+               return TEE_SUCCESS;
+       }
+       // check key usage flags
+       if ((key->info.objectUsage | ~op->info.requiredKeyUsage) != 0xffffffff) {
+               TZ_ERROR("Usage don't match line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+
+       //set key pair
+       switch (op->info.algorithm) {
+               //SIGN OR VERIFY
+               case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PKCS15_MD5;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PKCS15_SHA1;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PKCS15_SHA224;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PKCS15_SHA256;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PKCS15_SHA384;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PKCS15_SHA512;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PSS_SHA1;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PSS_SHA224;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PSS_SHA256;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PSS_SHA384;
+                       break;
+               case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSASSA_PSS_SHA512;
+                       break;
+               case TEE_ALG_DSA_SHA1:
+                       break;
+                       //ENCRYPT OR DECRYPT
+               case TEE_ALG_RSAES_PKCS1_V1_5:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSAES_PKCS15;
+                       break;
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSAES_OAEP_SHA1;
+                       break;
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSAES_OAEP_SHA224;
+                       break;
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSAES_OAEP_SHA256;
+                       break;
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSAES_OAEP_SHA384;
+                       break;
+               case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
+                       uciparam.ucip_rsa_padding = ID_UCI_RSAES_OAEP_SHA512;
+                       break;
+               case TEE_ALG_RSA_NOPAD:
+                       uciparam.ucip_rsa_padding = ID_UCI_NO_PADDING;
+                       break;
+       }
+       switch (key->info.objectType) {
+               case TEE_TYPE_RSA_PUBLIC_KEY:
+               case TEE_TYPE_RSA_KEYPAIR:
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_RSA_MODULUS, module,
+                           &moduleLen);
+                       if (rc != TEE_SUCCESS) {
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_RSA_PUBLIC_EXPONENT, pub,
+                           &pubLen);
+                       if (rc != TEE_SUCCESS) {
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       ucikey.ucik_rsa_n = module;
+                       ucikey.ucik_rsa_n_len = moduleLen;
+                       ucikey.ucik_rsa_e = pub;
+                       ucikey.ucik_rsa_e_len = pubLen;
+                       ucikey.ucik_rsa_d = NULL;
+                       ucikey.ucik_rsa_d_len = 0;
+
+                       if (key->info.objectType == TEE_TYPE_RSA_KEYPAIR) {
+                               rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_RSA_PRIVATE_EXPONENT,
+                                   priv, &privLen);
+                               if (rc != TEE_SUCCESS) {
+                                       TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n",
+                                           __LINE__, __func__);
+                                       return rc;
+                               }
+                               ucikey.ucik_rsa_d = priv;
+                               ucikey.ucik_rsa_d_len = privLen;
+                       }
+                       switch (key->info.objectSize) {
+                               case 512:
+                                       alg = ID_UCI_RSA512;
+                                       break;
+                               case 1024:
+                                       alg = ID_UCI_RSA1024;
+                                       break;
+                               case 2048:
+                                       alg = ID_UCI_RSA2048;
+                                       break;
+                               case 3072:
+                                       alg = ID_UCI_RSA3072;
+                                       break;
+                               default:
+                                       TZ_ERROR("key->info.objectSize = %d,%s\n", __LINE__, __func__);
+                                       return TEE_ERROR_BAD_PARAMETERS;
+                       }
+
+                       //PrintBYTE("N",module,moduleLen);
+                       //PrintBYTE("E",pub,pubLen);
+                       op->crypto = uci_context_alloc(alg, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               return TEE_ERROR_BAD_PARAMETERS;
+                       }
+
+                       if (uci_ae_set_keypair(op->crypto, &ucikey, &uciparam) != UCI_SUCCESS) {
+                               TZ_ERROR("uci_ae_set_keypair error line = %d,%s\n", __LINE__, __func__);
+                               return TEE_ERROR_BAD_PARAMETERS;
+                       }
+
+                       break;
+               case TEE_TYPE_DSA_PUBLIC_KEY:
+               case TEE_TYPE_DSA_KEYPAIR:
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DSA_PUBLIC_VALUE, pub,
+                           &pubLen);
+                       if (rc != TEE_SUCCESS) {
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+
+                       if (key->info.objectType == TEE_TYPE_DSA_KEYPAIR) {
+                               rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DSA_PRIVATE_VALUE, priv,
+                                   &privLen);
+                               if (rc != TEE_SUCCESS) {
+                                       TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n",
+                                           __LINE__, __func__);
+                                       return rc;
+                               }
+                               ucikey.ucik_dsa_privkey = priv;
+                               ucikey.ucik_dsa_privk_len = privLen;
+                       }
+                       ucikey.ucik_dsa_pubkey = pub;
+                       ucikey.ucik_dsa_pubk_len = pubLen;
+
+                       uciparam.ucip_dsa_tsize = 0;
+                       uciparam.ucip_dsa_p = (unsigned char*)OsaMalloc(key->info.objectSize);
+                       uciparam.ucip_dsa_q = (unsigned char*)OsaMalloc(key->info.objectSize);
+                       uciparam.ucip_dsa_g = (unsigned char*)OsaMalloc(key->info.objectSize);
+                       uciparam.ucip_dsa_p_len = key->info.objectSize;
+                       uciparam.ucip_dsa_g_len = key->info.objectSize;
+                       uciparam.ucip_dsa_q_len = key->info.objectSize;
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DSA_PRIME,
+                           uciparam.ucip_dsa_p, &uciparam.ucip_dsa_p_len);
+                       if (rc != TEE_SUCCESS) {
+                               OsaFree(uciparam.ucip_dsa_p);
+                               OsaFree(uciparam.ucip_dsa_q);
+                               OsaFree(uciparam.ucip_dsa_g);
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DSA_BASE,
+                           uciparam.ucip_dsa_g, &uciparam.ucip_dsa_g_len);
+                       if (rc != TEE_SUCCESS) {
+                               OsaFree(uciparam.ucip_dsa_p);
+                               OsaFree(uciparam.ucip_dsa_q);
+                               OsaFree(uciparam.ucip_dsa_g);
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DSA_SUBPRIME,
+                           uciparam.ucip_dsa_q, &uciparam.ucip_dsa_q_len);
+                       if (rc != TEE_SUCCESS) {
+                               OsaFree(uciparam.ucip_dsa_p);
+                               OsaFree(uciparam.ucip_dsa_q);
+                               OsaFree(uciparam.ucip_dsa_g);
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       if (uci_ae_set_keypair(op->crypto, &ucikey, &uciparam) != UCI_SUCCESS) {
+                               OsaFree(uciparam.ucip_dsa_p);
+                               OsaFree(uciparam.ucip_dsa_q);
+                               OsaFree(uciparam.ucip_dsa_g);
+                               TZ_ERROR("uci_ae_set_keypair error line = %d,%s\n", __LINE__, __func__);
+                               return TEE_ERROR_BAD_PARAMETERS;
+                       }
+
+                       OsaFree(uciparam.ucip_dsa_p);
+                       OsaFree(uciparam.ucip_dsa_q);
+                       OsaFree(uciparam.ucip_dsa_g);
+                       break;
+               case TEE_TYPE_DH_KEYPAIR:
+                       uciparam.ucip_dh_prime = (unsigned char*)OsaMalloc(key->info.objectSize);
+                       uciparam.ucip_dh_generator = (unsigned char*)OsaMalloc(
+                           key->info.objectSize);
+                       uciparam.ucip_dh_len = key->info.objectSize;
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DH_PRIME,
+                           uciparam.ucip_dh_prime, &uciparam.ucip_dh_len);
+                       if (rc != TEE_SUCCESS) {
+                               OsaFree(uciparam.ucip_dh_prime);
+                               OsaFree(uciparam.ucip_dh_generator);
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       rc = TEE_GetObjectBufferAttribute(key, TEE_ATTR_DH_BASE,
+                           uciparam.ucip_dh_generator, &uciparam.ucip_dh_len);
+                       if (rc != TEE_SUCCESS) {
+                               OsaFree(uciparam.ucip_dh_prime);
+                               OsaFree(uciparam.ucip_dh_generator);
+                               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                                   __func__);
+                               return rc;
+                       }
+                       if (uci_ae_set_keypair(op->crypto, &ucikey, &uciparam) != UCI_SUCCESS) {
+                               OsaFree(uciparam.ucip_dh_prime);
+                               OsaFree(uciparam.ucip_dh_generator);
+                               TZ_ERROR("uci_ae_set_keypair error line = %d,%s\n", __LINE__, __func__);
+                               return TEE_ERROR_BAD_PARAMETERS;
+                       }
+                       OsaFree(uciparam.ucip_dh_prime);
+                       OsaFree(uciparam.ucip_dh_generator);
+       }
+       if ((key->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY
+           && op->key1->info.objectType == TEE_TYPE_RSA_KEYPAIR)
+           || (key->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY
+               && op->key1->info.objectType == TEE_TYPE_DSA_KEYPAIR)) {
+
+               op->key1->info.objectType = key->info.objectType; // change object object type of key1 in DSA or RSA case
+       }
+       TEE_CopyObjectAttributes(op->key1, key); // will Panic inside in the case of incompatible objects
+       operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation,
+    TEE_ObjectHandle key1, TEE_ObjectHandle key2) {
+
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+       if ((key1 && !key2) || (!key1 && key2)) {
+               TZ_ERROR("key error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (operation->info.algorithm != TEE_ALG_AES_XTS) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!key1 && !key2) {
+               TEE_CloseObject(op->key1);
+               op->key1 = TEE_HANDLE_NULL;
+               TEE_CloseObject(op->key2);
+               op->key2 = TEE_HANDLE_NULL;
+               return TEE_SUCCESS;
+       }
+       // check key usage flags
+       if (key1 && (key1->info.objectUsage | ~op->info.requiredKeyUsage) != 0xffffffff) {
+               TZ_ERROR("Usage don't match line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (key2 && (key2->info.objectUsage | ~op->info.requiredKeyUsage) != 0xffffffff) {
+               TZ_ERROR("Usage don't match line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if(key1 != NULL) {
+               TEE_CopyObjectAttributes(op->key1, key1);
+       }
+       if(key2 != NULL) {
+               TEE_CopyObjectAttributes(op->key2, key2);
+       }
+       operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
+       return TEE_SUCCESS;
+}
+
+void TEE_CopyOperation(TEE_OperationHandle dstOperation,
+    TEE_OperationHandle srcOperation) {
+
+       struct TEE_Operation * dstOp = (struct TEE_Operation*)dstOperation;
+       struct TEE_Operation * srcOp = (struct TEE_Operation*)srcOperation;
+
+       if (dstOperation->info.mode != srcOperation->info.mode
+           || dstOperation->info.algorithm != srcOperation->info.algorithm) {
+               TZ_ERROR("Operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (dstOperation->info.maxKeySize < srcOperation->info.maxKeySize) {
+               TZ_ERROR("Operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       dstOperation->info.algorithm = srcOperation->info.algorithm;
+       dstOperation->info.digestLength = srcOperation->info.digestLength;
+       dstOperation->info.handleState = srcOperation->info.handleState;
+       dstOperation->info.keySize = srcOperation->info.keySize;
+       dstOperation->info.maxKeySize = srcOperation->info.maxKeySize;
+       dstOperation->info.mode = srcOperation->info.mode;
+       dstOperation->info.operationClass = srcOperation->info.operationClass;
+       dstOperation->info.requiredKeyUsage = srcOperation->info.requiredKeyUsage;
+
+       if (dstOp->key1) {
+               TEE_CopyObjectAttributes(dstOp->key1, srcOp->key1);
+       }
+       if (dstOp->key2) {
+               TEE_CopyObjectAttributes(dstOp->key2, srcOp->key2);
+       }
+       if (uci_dup_handle(srcOp->crypto, dstOp->crypto) != UCI_SUCCESS) {
+               TZ_ERROR("uci_dup_handle error , line = %d, %s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+}
+
+// Message Digest Functions
+void TEE_DigestUpdate(TEE_OperationHandle operation, const void* chunk,
+    size_t chunkSize) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_DIGEST) {
+               TZ_ERROR("param error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_md_update(op->crypto, (unsigned char*)chunk, chunkSize) != UCI_SUCCESS) {
+               TZ_ERROR("uci_md_update error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+}
+
+TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void* chunk,
+    size_t chunkLen, void* hash, size_t *hashLen) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (!hash || !hashLen) {
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       if (operation->info.operationClass != TEE_OPERATION_DIGEST) {
+               TZ_ERROR("param error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (chunk
+           != NULL&& uci_md_update(op->crypto, (unsigned char*)chunk, chunkLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_md_update error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_md_final(op->crypto, (unsigned char*)hash) != UCI_SUCCESS) {
+               TZ_ERROR("uci_md_final error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       *hashLen = op->info.digestLength;
+       return TEE_SUCCESS;
+}
+
+// Symmetric Cipher Functions
+void TEE_CipherInit(TEE_OperationHandle operation, const void* IV, size_t IVLen) {
+       int ret;
+       unsigned int mode;
+       unsigned char key1[32] = {0x0, };
+       //unsigned char key2[32] = {0x0, };
+       unsigned int key_len1 = sizeof(key1);
+       //unsigned int key_len2 = sizeof(key2);
+       unsigned int uci_alg;
+       TEE_Result rc;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (op->key1) {
+               rc = TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_SECRET_VALUE, key1,
+                   &key_len1);
+               if (rc != TEE_SUCCESS) {
+                       TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+       }
+       switch (op->info.algorithm) {
+               case TEE_ALG_AES_ECB_NOPAD:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_ECB;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_ECB;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       switch (key_len1) {
+                               case 16:
+                                       uci_alg = ID_UCI_AES128;
+                                       break;
+                               case 24:
+                                       uci_alg = ID_UCI_AES192;
+                                       break;
+                               case 32:
+                                       uci_alg = ID_UCI_AES256;
+                                       break;
+                               default:
+                                       TZ_ERROR("key len error line = %d,%s\n", __LINE__, __func__);
+                                       TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(uci_alg, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+
+
+                       // KRISHNA - ADDED NEW ALGO
+               case TEE_ALG_AES_ECB_PKCS7:
+               case TEE_ALG_AES_ECB_PKCS5:
+               case    TEE_ALG_AES_ECB_ISO9797_M1 :
+               case TEE_ALG_AES_ECB_ISO9797_M2 :
+
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_ECB;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_ECB;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       switch (key_len1) {
+                               case 16:
+                                       uci_alg = ID_UCI_AES128;
+                                       break;
+                               case 24:
+                                       uci_alg = ID_UCI_AES192;
+                                       break;
+                               case 32:
+                                       uci_alg = ID_UCI_AES256;
+                                       break;
+                               default:
+                                       TZ_ERROR("key len error line = %d,%s\n", __LINE__, __func__);
+                                       TEE_Panic(0);
+                       }
+
+                       op->crypto = uci_context_alloc(uci_alg, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                                       (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+
+
+
+
+               case TEE_ALG_AES_CBC_NOPAD:
+               case TEE_ALG_AES_CBC_PKCS5:
+               case TEE_ALG_AES_CBC_PKCS7:
+               case TEE_ALG_AES_CBC_ISO9797_M1:
+               case    TEE_ALG_AES_CBC_ISO9797_M2:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_CBC;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_CBC;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       switch (key_len1) {
+                               case 16:
+                                       uci_alg = ID_UCI_AES128;
+                                       break;
+                               case 24:
+                                       uci_alg = ID_UCI_AES192;
+                                       break;
+                               case 32:
+                                       uci_alg = ID_UCI_AES256;
+                                       break;
+                               default:
+                                       TZ_ERROR("key len error line = %d,%s\n", __LINE__, __func__);
+                                       TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(uci_alg, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_ALG_AES_CTR:
+               case TEE_ALG_AES_CTR_NOPAD:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_CTR;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_CTR;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       switch (key_len1) {
+                               case 16:
+                                       uci_alg = ID_UCI_AES128;
+                                       break;
+                               case 24:
+                                       uci_alg = ID_UCI_AES192;
+                                       break;
+                               case 32:
+                                       uci_alg = ID_UCI_AES256;
+                                       break;
+                               default:
+                                       TZ_ERROR("key len error line = %d,%s\n", __LINE__, __func__);
+                                       TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(uci_alg, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_ALG_AES_CTS:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_CTS;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_CTS;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       switch (key_len1) {
+                               case 16:
+                                       uci_alg = ID_UCI_AES128;
+                                       break;
+                               case 24:
+                                       uci_alg = ID_UCI_AES192;
+                                       break;
+                               case 32:
+                                       uci_alg = ID_UCI_AES256;
+                                       break;
+                               default:
+                                       TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                                       TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(uci_alg, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_ZERO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_ALG_AES_XTS:
+                       TZ_ERROR("TEE_ALG_AES_XTS not support NOW!!");
+                       TEE_Panic(0);
+                       break;
+               case TEE_ALG_DES_ECB_NOPAD:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_ECB;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_ECB;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(ID_UCI_DES, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_ALG_DES_CBC_NOPAD:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_CBC;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_CBC;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(ID_UCI_DES, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_ALG_DES3_ECB_NOPAD:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_ECB;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_ECB;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(ID_UCI_TDES, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_ALG_DES3_CBC_NOPAD:
+                       if (op->info.mode == TEE_MODE_ENCRYPT) {
+                               mode = ID_UCI_ENC_CBC;
+                       } else if (op->info.mode == TEE_MODE_DECRYPT) {
+                               mode = ID_UCI_DEC_CBC;
+                       } else {
+                               TZ_ERROR("Invalid mode error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       op->crypto = uci_context_alloc(ID_UCI_TDES, UCI_SW);
+                       if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                               TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       ret = uci_se_init(op->crypto, mode, ID_UCI_NO_PADDING, key1, key_len1,
+                           (unsigned char *)IV);
+                       if (ret != UCI_SUCCESS) {
+                               TZ_ERROR("uci_se_init error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               default:
+                       TZ_ERROR("algorithm error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+       }
+       operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
+}
+
+TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void* srcData,
+    size_t srcLen, void* destData, size_t *destLen) {
+       int ret;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (destData == NULL) {
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       ret = uci_se_process(op->crypto, (unsigned char *)srcData, srcLen,
+           (unsigned char*)destData, (unsigned int*)destLen);
+       if (ret != UCI_SUCCESS) {
+               TZ_ERROR("uci_se_process error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+               ;
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, const void* srcData,
+    size_t srcLen, void* destData, size_t *destLen) {
+       int ret;
+       size_t blocksize = 8;
+       int tmp = 0;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (destData == NULL) {
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       *destLen = 0;
+       if (op->info.algorithm == TEE_ALG_AES_CTS) {
+
+               ret = uci_se_final(op->crypto, (unsigned char *)srcData, srcLen,
+                   (unsigned char*)destData, (unsigned int*)destLen);
+               if (ret != UCI_SUCCESS) {
+                       TZ_ERROR("uci_se_final error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+                       ;
+               }
+               return TEE_SUCCESS;
+       }
+       if (op->info.algorithm == TEE_ALG_AES_ECB_NOPAD
+           || op->info.algorithm == TEE_ALG_AES_CBC_NOPAD
+           || op->info.algorithm == TEE_ALG_AES_CTR
+           || op->info.algorithm == TEE_ALG_AES_XTS
+               ) {
+
+               blocksize = 16;
+       }
+       //    printf("srcLen is %d, blocksize is %d\n",srcLen, blocksize);
+       if (srcLen > blocksize) {
+               ret = uci_se_process(op->crypto, (unsigned char *)srcData,
+                   srcLen - blocksize, (unsigned char*)destData, (unsigned int*)&tmp);
+               if (ret != UCI_SUCCESS) {
+                       TZ_ERROR("uci_se_final error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+
+               *destLen = tmp;
+               ret = uci_se_final(op->crypto, (unsigned char *)srcData + tmp, blocksize,
+                   (unsigned char*)destData + tmp, (unsigned int*)&tmp);
+               if (ret != UCI_SUCCESS) {
+                       TZ_ERROR("uci_se_final error line = %d,%s,ret=%d\n", __LINE__, __func__, ret);
+                       TEE_Panic(0);
+                       ;
+               }
+               *destLen += tmp;
+       } else {
+
+               ret = uci_se_final(op->crypto, (unsigned char *)srcData, srcLen,
+                   (unsigned char*)destData, (unsigned int*)destLen);
+               if (ret != UCI_SUCCESS) {
+                       TZ_ERROR("uci_se_final error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+                       ;
+               }
+       }
+       return TEE_SUCCESS;
+}
+
+// MAC Functions
+void TEE_MACInit(TEE_OperationHandle operation, const void* IV, size_t IVLen) {
+       TEE_Result rc = TEE_SUCCESS;
+       unsigned char key[128] = {0x0, };
+       size_t key_len = sizeof(key);
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_MAC) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (op->key1) {
+               rc = TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_SECRET_VALUE, key,
+                   &key_len);
+               if (rc != TEE_SUCCESS) {
+                       TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                           __func__);
+                       TEE_Panic(0);
+               }
+       }
+       if (uci_mac_init(op->crypto, key, key_len) != UCI_SUCCESS) {
+               TZ_ERROR("uci_mac_init error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
+}
+
+void TEE_MACUpdate(TEE_OperationHandle operation, const void* chunk,
+    size_t chunkSize) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_MAC) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_mac_update(op->crypto, (unsigned char *)chunk,
+           chunkSize) != UCI_SUCCESS) {
+               TZ_ERROR("uci_mac_update error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+}
+
+TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation,
+    const void* message, size_t messageLen, void* mac, size_t *macLen) {
+
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_MAC) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_mac_update(op->crypto, (unsigned char *)message,
+           messageLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_mac_update error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_mac_final(op->crypto, (unsigned char*)mac, macLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_mac_final error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation,
+    const void* message, size_t messageLen, const void* mac, size_t *macLen) {
+       unsigned char tmpmac[128];
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_MAC) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_mac_update(op->crypto, (unsigned char*)message,
+           messageLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_mac_update error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_mac_final(op->crypto, tmpmac, macLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_mac_final error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (memcmp(mac, tmpmac, *macLen) != 0) {
+               return TEE_ERROR_MAC_INVALID;
+       }
+       return TEE_SUCCESS;
+}
+
+// Authenticated Encryption Functions
+
+TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void* nonce,
+    size_t nonceLen, uint32_t tagLen, uint32_t AADLen, uint32_t payloadLen) {
+
+       TEE_Result rc = TEE_SUCCESS;
+       unsigned char key[128];
+       size_t key_len = sizeof(key);
+       int ret;
+       int mode;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_AE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (op->key1) {
+               rc = TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_SECRET_VALUE, key,
+                   &key_len);
+               if (rc != TEE_SUCCESS) {
+                       TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                           __func__);
+                       TEE_Panic(0);
+               }
+       }
+       if (op->info.mode == TEE_MODE_ENCRYPT) {
+               mode = 1;
+       } else {
+               mode = 0;
+       }
+       if (operation->info.algorithm == TEE_ALG_AES_CCM) {
+               if (tagLen != 128 && tagLen != 112 && tagLen != 96 && tagLen != 64
+                   && tagLen != 48 && tagLen != 32) {
+                       TZ_ERROR("tagLen error line = %d,%s\n", __LINE__, __func__);
+                       return TEE_ERROR_NOT_SUPPORTED;
+               }
+               op->crypto = uci_context_alloc(ID_UCI_AE_CCM, UCI_SW);
+               if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                       TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+
+               ret = uci_authcrypt_init(op->crypto, mode, (unsigned char*)nonce, nonceLen,
+                   tagLen / 8, AADLen, payloadLen, key, key_len);
+               if (ret != UCI_SUCCESS) {
+                       TZ_ERROR("uci_authcrypt_init error line = %d,%s \n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+       } else if (operation->info.algorithm == TEE_ALG_AES_GCM) {
+               if (tagLen != 128 && tagLen != 120 && tagLen != 112 && tagLen != 104
+                   && tagLen != 96) {
+                       TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                       return TEE_ERROR_NOT_SUPPORTED;
+               }
+               op->crypto = uci_context_alloc(ID_UCI_AE_GCM, UCI_SW);
+               if (op->crypto == UCI_ERROR || op->crypto == UCI_MEM_ALLOR_ERROR) {
+                       TZ_ERROR("uci_context_alloc error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+               ret = uci_authcrypt_init(op->crypto, mode, (unsigned char*)nonce, nonceLen,
+                   tagLen / 8, 0, 0, key, key_len);
+               if (ret != UCI_SUCCESS) {
+                       TZ_ERROR("uci_authcrypt_init error line = %d,%s \n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+       }
+       operation->info.digestLength = tagLen;
+       operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
+       return TEE_SUCCESS;
+}
+
+void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void* AADdata,
+    size_t AADdataLen) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_AE) {
+               TZ_ERROR("operation error line = %d,%s \n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s \n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (operation->info.algorithm == TEE_ALG_AES_CCM
+           || operation->info.algorithm == TEE_ALG_AES_GCM) {
+               if (uci_authcrypt_update_aad(op->crypto, (unsigned char*)AADdata,
+                   AADdataLen) != UCI_SUCCESS) {
+                       TZ_ERROR("uci_authcrypt_update_aad error line = %d,%s \n", __LINE__,
+                           __func__);
+                       TEE_Panic(0);
+               }
+       }
+}
+
+TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void* srcData,
+    size_t srcLen, void* destData, size_t *destLen) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_AE) {
+               TZ_ERROR("operation error line = %d,%s \n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s \n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (*destLen < srcLen) {
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       if (operation->info.algorithm == TEE_ALG_AES_CCM
+           || operation->info.algorithm == TEE_ALG_AES_GCM) {
+               if (uci_authcrypt_update(op->crypto, (unsigned char*)srcData, srcLen,
+                   (unsigned char*)destData, destLen) != UCI_SUCCESS) {
+                       TZ_ERROR("uci_authcrypt_update_aad error line = %d,%s \n", __LINE__,
+                           __func__);
+                       TEE_Panic(0);
+               }
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation,
+    const void* srcData, size_t srcLen, void* destData, size_t* destLen,
+    void* tag, size_t* tagLen) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_AE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (*destLen < srcLen) {
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       if (uci_authcrypt_encryptfinal(op->crypto, (unsigned char*)srcData, srcLen,
+           (unsigned char*)destData, destLen, (unsigned char*)tag,
+           tagLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_authcrypt_encryptfinal error line = %d,%s \n", __LINE__,
+                   __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation,
+    const void* srcData, size_t srcLen, void* destData, size_t *destLen,
+    void* tag, size_t tagLen) {
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_AE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (*destLen < srcLen) {
+               TZ_ERROR("destLen error line = %d,%s \n", __LINE__, __func__);
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       if (uci_authcrypt_decryptfinal(op->crypto, (unsigned char*)srcData, srcLen,
+           (unsigned char*)destData, destLen, (unsigned char*)tag,
+           tagLen) != UCI_SUCCESS) {
+               TZ_ERROR("uci_authcrypt_decryptfinal error line = %d,%s \n", __LINE__,
+                   __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation,
+    const TEE_Attribute* params, uint32_t paramCount, const void* srcData,
+    size_t srcLen, void* destData, size_t *destLen) {
+       int ret;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       ret = uci_ae_encrypt(op->crypto, (unsigned char *)srcData, srcLen,
+           (unsigned char*)destData, destLen);
+       if (ret != UCI_SUCCESS) {
+               TZ_ERROR("uci_ae_encrypt error. ret= %d,line = %d,%s\n", ret, __LINE__,
+                   __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation,
+    const TEE_Attribute* params, uint32_t paramCount, const void* srcData,
+    size_t srcLen, void* destData, size_t *destLen) {
+       int ret;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       ret = uci_ae_decrypt(op->crypto, (unsigned char *)srcData, srcLen,
+           (unsigned char*)destData, destLen);
+       if (ret != UCI_SUCCESS) {
+               TZ_ERROR("uci_ae_decrypt error. ret= %d,line = %d,%s\n", ret, __LINE__,
+                   __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation,
+    const TEE_Attribute* params, uint32_t paramCount, const void* digest,
+    size_t digestLen, void* signature, size_t *signatureLen) {
+       int ret;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       ret = uci_ds_sign(op->crypto, (unsigned char *)digest, digestLen,
+           (unsigned char*)signature, signatureLen);
+       if (ret != UCI_SUCCESS) {
+               TZ_ERROR("uci_ds_sign error. ret= %d,line = %d,%s\n", ret, __LINE__,
+                   __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,
+    const TEE_Attribute* params, uint32_t paramCount, const void* digest,
+    size_t digestLen, void* signature, size_t signatureLen) {
+       int ret = UCI_ERROR;
+       int result = -1;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       ret = uci_ds_verify(op->crypto, (unsigned char *)digest, digestLen,
+           (unsigned char*)signature, signatureLen, &result);
+       if (ret != UCI_SUCCESS) {
+               TZ_ERROR("uci_ds_verify error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (result != UCI_VALID_SIGN) {
+               TZ_ERROR("uci_ds_verify error. ret= %d,line = %d,%s\n", result, __LINE__,
+                   __func__);
+               TEE_Panic(0);
+       }
+       return TEE_SUCCESS;
+}
+
+void TEE_DeriveKey(TEE_OperationHandle operation, const TEE_Attribute* params,
+    uint32_t paramCount, TEE_ObjectHandle derivedKey) {
+       uint32_t i = 0;
+       unsigned char authkey[512];
+       unsigned char privkey[512];
+       unsigned char *pubkey = NULL;
+       unsigned int pubkey_len = 0;
+       unsigned int privkey_len = sizeof(privkey);
+       TEE_Attribute attrs[1];
+       TEE_Result rc;
+       struct TEE_Operation * op = (struct TEE_Operation*)operation;
+
+       if (op->info.operationClass != TEE_OPERATION_KEY_DERIVATION) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!params) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (op->info.mode != TEE_MODE_DERIVE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       for (i = 0; i < paramCount; i++) {
+               if (params[i].attributeID == TEE_ATTR_DH_PUBLIC_VALUE) {
+                       pubkey = (unsigned char*)params[i].content.ref.buffer;
+                       pubkey_len = params[i].content.ref.length / 8;
+                       break;
+               }
+       }
+       rc = TEE_GetObjectBufferAttribute(op->key1, TEE_ATTR_DH_PRIVATE_VALUE,
+           privkey, &privkey_len);
+       if (rc != TEE_SUCCESS) {
+               TZ_ERROR("TEE_GetObjectBufferAttribute error line = %d,%s\n", __LINE__,
+                   __func__);
+               return;
+       }
+       if (pubkey_len == 0 || !pubkey || privkey_len == 0) {
+               TZ_ERROR("params error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if ((i = uci_dh_gen_authkey(op->crypto, privkey, pubkey, authkey))
+           != UCI_SUCCESS) {
+               TZ_ERROR(" uci_dh_gen_authkey error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       PrintBYTE("privkey", privkey, privkey_len);
+       PrintBYTE("pubkey", pubkey, privkey_len);
+       TEE_InitRefAttribute(&attrs[0], TEE_ATTR_SECRET_VALUE, authkey, pubkey_len);
+       TEE_PopulateTransientObject(derivedKey, attrs, 1);
+}
+
+void TEE_GenerateRandom(void* randomBuffer, size_t randomBufferLen) {
+       int i = 0;
+       unsigned char seed[16];
+       //unsigned int seedLen = 16;
+       unsigned int res;
+       unsigned long get_time = getClock();
+       
+       srand(get_time);
+
+       for (i = 0; i < 16; i++) {
+               res = rand();
+               seed[i] = res & 0xFF;
+       }
+       UCI_HANDLE oh = uci_context_alloc(ID_UCI_X931, UCI_SW);
+       if (oh == UCI_ERROR || oh == UCI_MEM_ALLOR_ERROR) {
+               TZ_ERROR("uci_context_alloc error line = %d, %s", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_prng_seed(oh, seed) != UCI_SUCCESS) {
+               TZ_ERROR("uci_prng_seed line = %d, %s", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (uci_prng_get(oh, randomBufferLen,
+           (unsigned char*)randomBuffer) != UCI_SUCCESS) {
+               TZ_ERROR("uci_prng_get line = %d, %s", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+}
diff --git a/ssflib/src/ssf_lib.c b/ssflib/src/ssf_lib.c
new file mode 100755 (executable)
index 0000000..428c053
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssflib.c
+ *
+ *    Description:  SSF Library functions
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ssf_lib.h"
+#include "ssf_client.h"
+#include <stdio.h>
+#include <assert.h>
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+extern TEE_UUID sharedthisTAUUID;
+int32_t socketSimulatorDaemonFD = 0;
+pthread_mutex_t socketLock = PTHREAD_MUTEX_INITIALIZER;
+TeeStubSSFSharedData sharedData = {false, false, true};
+
+/*-----------------------------------------------------------------------------
+ *  Local functions
+ *-----------------------------------------------------------------------------*/
+extern "C"{
+
+/**
+ * Initializes SSF for use by TA
+ */
+__attribute__((constructor)) void initializeSSF() {
+
+       socketSimulatorDaemonFD = connecttoServer();
+       assert(socketSimulatorDaemonFD != -1);
+       LOGD(SIM_DAEMON, "Done");}
+
+/**
+ * Deinits SSF. Should be called by TA once
+ */
+
+__attribute__((destructor)) void deinitializeSSF() {
+       disconnectfromServer(socketSimulatorDaemonFD);
+       LOGD(SIM_DAEMON, "Done"); }
+
+}
+/* =========================================================================
+ * OPERATION CANCELLATION
+ * =========================================================================
+ */
+
+/**
+ * Determines whether the current task's Cancellation Flag is set
+ *
+ * The TEE_GetCancellationFlag function determines whether the current task's
+ * Cancellation Flag is set. If cancellations are masked, this function must
+ * return false.
+ *
+ * @return 'false' if the cancellation flag is not set or if cancellations are
+ * masked; 'true' if the cancellation flag is set and cancellations are not
+ * masked
+ */
+bool TEE_GetCancellationFlag(void) {
+return (sharedData.thisTaskMask ? false : sharedData.thisTaskCancel);
+}
+
+/**
+ * Unmasks the effects of cancellation
+ *
+ * The TEE_UnmaskCancellation function unmasks the effects of cancellation for
+ * the current task. When cancellation requests are unmasked, the Cancellation
+ * Flag interrupts cancellable functions such as @ref TEE_Wait and requests the
+ * cancellation of operations started with @ref TEE_OpenTASession or
+ * @ref TEE_InvokeTACommand. By default, tasks created to handle a TA entry
+ * point have cancellation masked, so that a TA does not have to cope with the
+ * effects of cancellation requests.
+ * @return 'true' if cancellations were masked prior to calling this function;
+ * 'false' otherwise
+ */
+bool TEE_UnmaskCancellation(void) {
+bool preState = sharedData.thisTaskMask;
+sharedData.thisTaskMask = false;
+return (preState ? true : false);
+}
+
+/**
+ * Masks the effects of cancellation
+ *
+ * The TEE_MaskCancellation function masks the effects of cancellation for the
+ * current task. When cancellation requests are masked, the Cancellation Flag
+ * does not have an effect on the cancellable functions and cannot be retrieved
+ * using @ref TEE_GetCancellationFlag. By default, tasks created to handle a TA
+ * entry point have cancellation masked, so that a TA does not have to cope with
+ * the effects of cancellation requests.
+ *
+ * @return 'true' if cancellations were masked prior to calling this function;
+ * 'false' otherwise
+ */
+bool TEE_MaskCancellation(void) {
+bool preState = sharedData.thisTaskMask;
+sharedData.thisTaskMask = true;
+return (preState ? true : false);
+}
diff --git a/ssflib/src/ssf_malloc.c b/ssflib/src/ssf_malloc.c
new file mode 100755 (executable)
index 0000000..77e27a7
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_malloc.c
+ *
+ *    Description:  SSF malloc functions
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <tee_internal_api.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ssf_lib.h"
+
+/*-----------------------------------------------------------------------------
+ *  Globals
+ *-----------------------------------------------------------------------------*/
+/**
+ * For use by: TEE_GetInstanceData and TEE_SetInstanceData
+ */
+static void* globalTAInstanceData = 0;
+
+/*-----------------------------------------------------------------------------
+ *  TEE API implementation
+ *-----------------------------------------------------------------------------*/
+/**
+ * Allocates space for an object
+ *
+ * The TEE_Malloc function allocates space for an object whose size in bytes is
+ * specified in the parameter size.
+ *
+ * @param[in] size The size of the buffer to be allocated.
+ * @param[in] hint A hint to the allocator. Currently defined values are as
+ * follows:
+ *
+ * + The default value, 0, guarantees that the returned block of memory is
+ * filled with zeros.
+ *
+ * + Values in the range [0x00000001, 0x7FFFFFFF] are reserved for future
+ * version of this specification.
+ *
+ * + Values in the range [0x80000000, 0xFFFFFFFF] can be used for
+ * implementation-defined hints.
+ *
+ * @return Upon successful completion, with size not equal to zero, the function
+ * returns a pointer to the allocated space. If the space cannot be allocated, a
+ * NULL pointer is returned.
+ */
+void* TEE_Malloc(size_t size, uint32_t hint) {
+       void* buf = OsaMalloc(size);
+       if (NULL == buf) {
+               return NULL;
+       }
+       if (0 == hint) {
+               memset(buf, 0, size);
+       }
+       return buf;
+}
+
+/**
+ * Changes the size of the memory object
+ *
+ * The TEE_Realloc function changes the size of the memory object pointed to by
+ * buffer to the size specified by nNewSize.
+ *
+ * @param[in] buffer: The pointer to the object to be reallocated
+ * @param[in] newSize: The new size required for the object
+ *
+ * @return Upon successful completion, TEE_Realloc returns a pointer to the
+ * (possibly moved) allocated space. If there is not enough available memory,
+ * TEE_Realloc returns a NULL pointer.
+ */
+void* TEE_Realloc(const void* buffer, uint32_t newSize) {
+       return realloc((void*)buffer, newSize);
+}
+
+/**
+ * Causes the space pointed to by buffer to be deallocated
+ *
+ * The TEE_Free function causes the space pointed to by buffer to be
+ * deallocated; that is, made available for further allocation. If buffer is a
+ * NULL pointer, TEE_Free does nothing. Otherwise, it is a Programmer Error
+ * if the argument does not match a pointer previously returned by the
+ * @ref TEE_Malloc or @ref TEE_Realloc, or if the space has been deallocated by
+ * a call to TEE_Free or @ref TEE_Realloc.
+ *
+ * @param[in] buffer The pointer to the memory block to be freed
+ */
+void TEE_Free(const void *buffer) {
+       if (buffer) {
+               OsaFree((void*)buffer);
+       }
+}
+
+/**
+ * Copies size bytes from one object to another
+ *
+ * The TEE_MemMove function copies size bytes from the object pointed to by src
+ * into the object pointed to by dest. Note that the buffers dest and src can
+ * reside in any kinds of memory, including shared memory.
+ *
+ * @param[in] dest A pointer to the destination buffer
+ * @param[in] src A pointer to the source buffer
+ * @param[in] size The number of bytes to be copied
+ */
+void TEE_MemMove(void* dest, const void* src, uint32_t size) {
+       memmove(dest, src, size);
+}
+
+/**
+ * Compares bytes of one object to another
+ *
+ * The TEE_MemCompare function compares the first size bytes of the object
+ * pointed to by buffer1 to the first size bytes of the object pointed to by
+ * buffer2. Note that buffer1 and buffer2 can reside in any kinds of memory,
+ * including shared memory.
+ *
+ * @param[in] buffer1 A pointer to the first buffer
+ * @param[in] buffer2 A pointer to the second buffer
+ * @param[in] size The number of bytes to be compared
+ *
+ * @return The sign of a non-zero return value is determined by the sign of the
+ * difference between the values of the first pair of bytes (both interpreted as
+ * type uint8_t) that differ in the objects being compared.
+ *
+ * + If the first byte that differs is higher in buffer1, then return an integer
+ * greater than zero.
+ *
+ * + If the first size bytes of the two buffers are identical, then return zero.
+ *
+ * + If the first byte that differs is higher in buffer2, then return an integer
+ * lower than zero.
+ */
+int32_t TEE_MemCompare(const void *buffer1, const void *buffer2, uint32_t size) {
+       uint32_t i = 0;
+       uint8_t* buf1 = (uint8_t*)buffer1;
+       uint8_t* buf2 = (uint8_t*)buffer2;
+       for (; i < size; ++i) {
+               if (buf1[i] > buf2[i]) {
+                       return 1;
+               } else if (buf1[i] < buf2[i]) {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/**
+ * Writes the byte x into the object
+ *
+ * The TEE_MemFill function writes the byte x (converted to a uint8_t) into the
+ * first size bytes of the object pointed to by buffer. Note that buffer can
+ * reside in any kinds of memory, including shared memory.
+ *
+ * @param[in] buffer A pointer to the destination buffer
+ * @param[in] x The value to be set
+ * @param[in] size The number of bytes to be set
+ */
+void TEE_MemFill(void* buffer, uint32_t x, uint32_t size) {
+       if (NULL == buffer) {
+               return;
+       }
+       uint32_t i = 0;
+       uint8_t* buf = (uint8_t*)buffer;
+       for (; i < size; ++i) {
+               buf[i] = (uint8_t)x;
+       }
+}
+
+/**
+ * Checks specified buffer for access rights
+ *
+ * The TEE_CheckMemoryAccessRights function causes the Implementation to examine
+ * a buffer of memory specified in the parameters buffer and size and to
+ * determine whether the current Trusted Application instance has the access
+ * rights requested in the parameter accessFlags. If the characteristics of the
+ * buffer are compatible with accessFlags, then the function returns
+ * TEE_SUCCESS. Otherwise, it returns TEE_ERROR_ACCESS_DENIED. Note that the
+ * buffer should not be accessed by the function, but the Implementation should
+ * check the access rights based on the address of the buffer and internal
+ * memory management information.
+ * This function MUST NOT panic for any reason.
+ *
+ * @param[in] buffer Pointer to the buffer to check
+ * @param[in] size Size of the buffer to check
+ * @param[in] accessFlags The access flags to check
+ *
+ * @return TEE_SUCCESS: If the entire buffer allows the requested accesses or
+ * TEE_ERROR_ACCESS_DENIED: If at least one byte in the buffer is not accessible
+ * with the requested accesses
+ */
+TEE_Result TEE_CheckMemoryAccessRights(uint32_t accessFlags, void* buffer,
+    size_t size) {
+       //TODO: Need to verify ow this function will be used
+       return TEE_SUCCESS;
+}
+
+/**
+ *  Provides an alternative to writable global data
+ *
+ * The TEE_SetInstanceData and TEE_GetInstanceData functions provide an
+ * alternative to writable global data (writable variables with global scope and
+ * writable static variables with global or function scope). While an
+ * Implementation supports C global variables, using these functions may be
+ * sometimes more efficient, especially if only a single instance data variable
+ * is required.
+ *
+ * @param[in] instanceData A pointer to the global Trusted Application instance
+ * data. This pointer may be NULL.
+ */
+void TEE_SetInstanceData(void* instanceData) {
+       globalTAInstanceData = instanceData;
+}
+
+/**
+ * Retrieves the instance data pointer
+ *
+ * The TEE_GetInstanceData function retrieves the instance data pointer set by
+ * the Trusted Application using the @ref TEE_GetInstanceData function.
+ *
+ * @return The value returned is the previously set pointer to the Trusted
+ * Application instance data, or NULre:\L if no instance data pointer has yet been
+ * set.
+ */
+void* TEE_GetInstanceData(void) {
+       return globalTAInstanceData;
+}
diff --git a/ssflib/src/ssf_panic.c b/ssflib/src/ssf_panic.c
new file mode 100755 (executable)
index 0000000..e08f5f2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_panic.c
+ *
+ *    Description:  SSF oanic functions
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include <tee_internal_api.h>
+#include "ssf_lib.h"
+#include "ssf_client.h"
+#include "tee_command.h"
+
+/* =========================================================================
+ * PANIC
+ * =========================================================================
+ */
+/* Krishna Devale:
+ * Options to implement panic and send back a signal to the execution logic of
+ * TEEStub to clean up and exit
+ * 1. Use pthread lock on a global variable "bool panic"
+ * The TEEStub will wait on this lock for read/write access to global variable "panic"
+ * When "panic" is detected as true in execution engine, TEEStub exits.
+ * Here TEE_Panic allows the the called entry point to complete and exit
+ * This behaviour may be not desirable. [Confirm this]
+ *
+ * 2. Use a callback function registered to SSFLib on its init.
+ * This callback is defined in TEEStub. The TEE_Panic function calls the callback function.
+ * This callback is expected to perform cleanup and do a clean exit.
+ * This callback never returns to TEE_Panic. Thus, TEE_Panic is guaranteed to exit
+ * without returning to its calling function
+ */
+void TEE_Panic(TEE_Result panic_code) {
+       exit(0);
+}
diff --git a/ssflib/src/ssf_storage.c b/ssflib/src/ssf_storage.c
new file mode 100755 (executable)
index 0000000..60ad4fb
--- /dev/null
@@ -0,0 +1,2037 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_storage.c
+ *
+ *    Description:  SSF storage functions
+ *
+ *        Version:  1.0
+ *        Created:  23 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ssf_storage.h"
+#include <sys/mman.h>
+#include <string.h>
+
+/*-----------------------------------------------------------------------------
+ *  MACROS
+ *-----------------------------------------------------------------------------*/
+#define __FREE(buf) if(buf) {OsaFree(buf); buf = NULL;}
+#define FREE_PO(po) if(po) {clean_po_file(po);OsaFree(po); po = NULL;}
+
+#define PO_INTERNAL_MODULE_NAME "po_file"
+#define PO_STAT_INTERNAL_MODULE_NAME "po_stat"
+#define PI_FILE_NAME "pi_file"
+#define UUID_FILE "/usr/apps/tee/TA-UUID.list"
+
+TEE_UUID ssf_sharedthisTAUUID;
+static TEE_UUID this_uuid;
+static int uuid_got = 0;
+
+#define g_bTAdbug 1
+#define TZ_PRINT(fmt...) \
+    do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+#define TZ_ERROR(fmt...) \
+    do {if (g_bTAdbug) printf("[SSFLIB] ");printf(fmt);}while(0)
+
+#if 0
+int get_ta_name(char* ta_name) {
+       pid_t pid = getpid();
+       char path[256] = {0};
+       char ta_path[256] = {0};
+       sprintf(path, "/proc/%d/exe", pid);
+       int cnt = readlink(path, ta_path, 256);
+       if (cnt < 0 || cnt > 256) {
+               MSG("Error readlink.");
+               return -1;
+       }
+       ta_path[cnt] = '\0';
+       int idx = cnt - 1;
+       for (; idx >= 0; idx--) {
+               if (ta_path[idx] == '/') {
+                       strcpy(ta_name, ta_path + idx + 1);
+                       return 0;
+               }
+       }
+       return -1;
+}
+#endif
+
+/*-----------------------------------------------------------------------------
+ *  Local functions
+ *-----------------------------------------------------------------------------*/
+int get_uuid() {
+//assigns UIID obtained from TEEStub
+       this_uuid = ssf_sharedthisTAUUID;
+       uuid_got = 1;
+       return 0;
+#if 0
+       if (uuid_got)
+       {
+               return 0;
+       }
+       char ta_name[256] =
+       {       0};
+       if (0 != get_ta_name(ta_name))
+       {
+               MSG("Failed to get ta name.");
+               return -1;
+       }
+       FILE* f = fopen(UUID_FILE, "r");
+       if (!f)
+       {
+               MSG("Can't open file %s\n", UUID_FILE);
+               return -1;
+       }
+       char name[256];
+       char *line = NULL;
+       size_t len = 0;
+       ssize_t read_bytes;
+       int matched = 0;
+       TEE_UUID uuid;
+       while (-1 != getline(&line, &len, f))
+       {
+               matched =
+               sscanf(line,
+                               "TA={ %x , %hx , %hx , { %hhx , %hhx , %hhx , %hhx , %hhx , %hhx , %hhx , %hhx } } : %64s",
+                               &uuid.timeLow, &uuid.timeMid, &uuid.timeHiAndVersion,
+                               &uuid.clockSeqAndNode[0], &uuid.clockSeqAndNode[1],
+                               &uuid.clockSeqAndNode[2], &uuid.clockSeqAndNode[3],
+                               &uuid.clockSeqAndNode[4], &uuid.clockSeqAndNode[5],
+                               &uuid.clockSeqAndNode[6], &uuid.clockSeqAndNode[7],
+                               name);
+               if (matched != 12 || matched == EOF)
+               {
+                       MSG("bad format for uuid:%s\n", line);
+                       continue;
+               }
+               OsaFree(line);
+               line = NULL;
+               MSG("ta_name [%s] <=> name [%s]", ta_name, name);
+               if (0 == memcmp(ta_name, name, strlen(ta_name)))
+               {
+                       this_uuid = uuid;
+                       uuid_got = 1;
+                       fclose(f);
+                       return 0;
+               }
+       }
+       fclose(f);
+       return -1;
+#endif
+}
+
+void printhex(unsigned char* buf, unsigned int size) {
+       MSG("---------------------------------------------------");
+       unsigned int i;
+       for (i = 0; i < size; ++i) {
+               if (0 == (i % 16) && i) {
+                       printf("\n");
+               }
+               printf("%02x ", buf[i]);
+       }
+       MSG("\n---------------------------------------------------");
+}
+
+/*-----------------------------------------------------------------------------
+ *  TEE API implementation
+ *-----------------------------------------------------------------------------*/
+////////////////////////////////////////////////////////////////////////////////////
+// internal attribute  operations
+////////////////////////////////////////////////////////////////////////////////////
+TEE_Result copy_attribute(TEE_Attribute* dest, TEE_Attribute* src) {
+       if (!dest || !src) {
+               return TEE_ERROR_BAD_PARAMETERS;
+       }
+       dest->attributeID = src->attributeID;
+       if (src->attributeID & TEE_ATTR_FLAG_VALUE) {
+               dest->content.value.a = src->content.value.a;
+               dest->content.value.b = src->content.value.b;
+       } else {
+               int buf_size = (src->content.ref.length + 7) / 8;
+               void* buffer = OsaMalloc(buf_size);
+               if (!buffer) {
+                       return TEE_ERROR_OUT_OF_MEMORY;
+               }
+               memcpy(buffer, src->content.ref.buffer, buf_size);
+               dest->content.ref.buffer = buffer;
+               dest->content.ref.length = src->content.ref.length;
+       }
+       return TEE_SUCCESS;
+}
+
+void free_attribute(TEE_Attribute* attr) {
+       if (!attr) {
+               return;
+       }
+       if (!(attr->attributeID & TEE_ATTR_FLAG_VALUE)) {
+               OsaFree((void*)attr->content.ref.buffer);
+       }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// Internal transient Object Operations
+/////////////////////////////////////////////////////////////////////////////////////////////
+TEE_Result allocate_transient_object(TransientObject* tr, uint32_t objectType,
+    uint32_t maxObjectSize) {
+       tr->attr.attr_number = 0;
+
+/*     switch (objectType) {
+               case TEE_TYPE_AES:
+                       if (maxObjectSize != 128 && maxObjectSize != 192
+                           && maxObjectSize != 256) {
+                               return TEE_ERROR_NOT_SUPPORTED;
+                       }
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_DES:
+                       //if (maxObjectSize != 64) {
+                       //      return TEE_ERROR_NOT_SUPPORTED;
+                       //}
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_DES3:
+                       if (maxObjectSize != 128 && maxObjectSize != 192)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_HMAC_MD5:
+                       if (maxObjectSize < 64 || maxObjectSize > 512 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_HMAC_SHA1:
+                       if (maxObjectSize < 80 || maxObjectSize > 512 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_HMAC_SHA224:
+                       if (maxObjectSize < 112 || maxObjectSize > 512 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_HMAC_SHA256:
+                       if (maxObjectSize < 192 || maxObjectSize > 1024 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_HMAC_SHA384:
+                       if (maxObjectSize < 256 || maxObjectSize > 1024 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_HMAC_SHA512:
+                       if (maxObjectSize < 256 || maxObjectSize > 1024 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               case TEE_TYPE_RSA_PUBLIC_KEY:
+               case TEE_TYPE_RSA_KEYPAIR:
+                       if (maxObjectSize < 256 || maxObjectSize > 3072)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = sizeof(rsa_context);
+                       break;
+               case TEE_TYPE_DSA_PUBLIC_KEY:
+               case TEE_TYPE_DSA_KEYPAIR:
+                       if (maxObjectSize < 512 || maxObjectSize > 1024 || maxObjectSize % 64)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = sizeof(dsa_context);
+                       break;
+               case TEE_TYPE_DH_KEYPAIR:
+                       if (maxObjectSize < 256 || maxObjectSize > 2048)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = sizeof(dh_context);
+                       break;
+               case TEE_TYPE_GENERIC_SECRET:
+                       if (maxObjectSize > 4096 || maxObjectSize % 8)
+                         return TEE_ERROR_NOT_SUPPORTED;
+                       //tr->attr.buf_len = (maxObjectSize + 7)>>3;
+                       break;
+               default:
+                       return TEE_ERROR_NOT_SUPPORTED;
+       }
+*/
+       // Object info
+       tr->info.objectType = objectType;
+       tr->info.objectSize = 0;
+       tr->info.maxObjectSize = maxObjectSize;
+       //tr->info.dataSize = 0;
+       //tr->info.dataPosition = 0;
+       //tr->info.handleFlags = 0;
+       tr->info.objectUsage = 0xffffffff;
+       return TEE_SUCCESS;
+}
+
+size_t calc_attr_size(TransientObject* tr) {
+       size_t size = 0;
+       size += sizeof(int);
+       size += tr->attr.attr_number * 4;  //attrID
+       TEE_Attribute* attrs = tr->attr.attr_array;
+       int i;
+       for (i = 0; i < tr->attr.attr_number; ++i) {
+               if (attrs[i].attributeID & TEE_ATTR_FLAG_VALUE) {
+                       size += 2 * sizeof(uint32_t);
+               } else {
+                       size += sizeof(size_t);
+                       size += (attrs[i].content.ref.length + 7) / 8;
+               }
+       }
+       return size;
+}
+
+TEE_Result serialise_attr(TransientObject* tr, char* buf) {
+       if (!buf) {
+               return TEE_ERROR_OUT_OF_MEMORY;
+       }
+       memcpy(buf, (void*)&tr->attr.attr_number, sizeof(int));
+       buf += sizeof(int);
+
+       TEE_Attribute* attrs = tr->attr.attr_array;
+       int i;
+       for (i = 0; i < tr->attr.attr_number; ++i) {
+               //AttrID
+               memcpy(buf, &(attrs[i].attributeID), 4);
+               buf += 4;
+               if (attrs[i].attributeID & TEE_ATTR_FLAG_VALUE) {
+                       memcpy(buf, (void*)&(attrs[i].content.value.a), 2 * sizeof(uint32_t));
+                       buf += 2 * sizeof(uint32_t);
+               } else {
+                       memcpy(buf, &(attrs[i].content.ref.length), 4);
+                       buf += 4;
+                       memcpy(buf, (void*)attrs[i].content.ref.buffer,
+                           (attrs[i].content.ref.length + 7) / 8);
+                       buf += (attrs[i].content.ref.length + 7) / 8;
+               }
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result deserialise_attr(char* buf, TransientObject* tr) {
+       if (!buf) {
+               return TEE_SUCCESS;
+       }
+       TEE_Attribute* attrs = tr->attr.attr_array;
+       memcpy(&tr->attr.attr_number, buf, sizeof(int));
+       buf += sizeof(int);
+
+       int i;
+       for (i = 0; i < tr->attr.attr_number; ++i) {
+               memcpy(&attrs[i].attributeID, buf, 4);
+               buf += 4;
+               if (attrs[i].attributeID & TEE_ATTR_FLAG_VALUE) {
+                       memcpy((void*)&(attrs[i].content.value.a), buf, 2 * sizeof(uint32_t));
+                       buf += 2 * sizeof(uint32_t);
+               } else {
+                       memcpy((void*)&attrs[i].content.ref.length, buf, 4);
+                       buf += 4;
+                       void* buffer = OsaMalloc((attrs[i].content.ref.length + 7) / 8);
+                       if (!buffer) {
+                               return TEE_ERROR_OUT_OF_MEMORY;
+                       }
+                       memcpy(buffer, buf, (attrs[i].content.ref.length + 7) / 8);
+                       attrs[i].content.ref.buffer = buffer;
+                       buf += (attrs[i].content.ref.length + 7) / 8;
+               }
+       }
+       return TEE_SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// Internal Persistent Object Operations
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+TEE_Result allocate_persistent_object(persistent_object** po,
+    uint32_t storageID, const void* objectID, size_t objectIDLen,
+    uint32_t flags) {
+       if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (storageID != TEE_STORAGE_PRIVATE) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       persistent_object* tmp_po = (persistent_object*)OsaMalloc(
+           sizeof(persistent_object));
+       if (!tmp_po) {
+               return TEE_ERROR_OUT_OF_MEMORY;
+       }
+       memset(tmp_po, 0, sizeof(persistent_object));
+
+       tmp_po->storage_id = storageID;
+       tmp_po->attr.info.handleFlags = flags;
+       tmp_po->obj_id_len = objectIDLen;
+       memcpy(tmp_po->object_id, objectID, objectIDLen);
+       if (0 != get_uuid()) {
+               MSG("Failed to get UUID of TA.");
+               FREE_PO(tmp_po);
+               return TEE_ERROR_GENERIC;
+       }
+       tmp_po->TA_UUID = this_uuid;
+       *po = tmp_po;
+       init_po(tmp_po);
+       return TEE_SUCCESS;
+}
+
+TEE_Result create_po(persistent_object* po, TransientObject* attr,
+    const void* init_data, size_t data_size) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       TEE_Result rc;
+       if (NULL != attr) {
+               if (!(attr->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) {
+                       TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+               rc = allocate_transient_object(&po->attr, attr->info.objectType,
+                   attr->info.maxObjectSize);
+               if (rc != TEE_SUCCESS) {
+                       return TEE_ERROR_OUT_OF_MEMORY;
+               }
+               // copy attributes
+//        TEE_CopyObjectAttributes((TEE_ObjectHandle) & po->attr,
+//                        (TEE_ObjectHandle) attr);
+
+               TEE_CopyObjectAttributes((TEE_ObjectHandle)&po->attr.info,
+                   (TEE_ObjectHandle)attr);
+
+               // get required buffer length
+               po->po_file.attr_size = calc_attr_size(&po->attr);
+               po->po_file.attr = (uint8_t*)OsaMalloc(po->po_file.attr_size);
+               if (NULL == po->po_file.attr) {
+                       return TEE_ERROR_OUT_OF_MEMORY;
+               }
+               // fill attr
+               rc = serialise_attr(&po->attr, (char*)po->po_file.attr);
+               if (rc) {
+                       TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+       }
+
+       // fill data object
+       if (init_data && data_size) {
+               po->po_file.obj_data_size = data_size;
+               if (0 != po->po_file.obj_data_size) {
+                       po->po_file.object_data = (uint8_t*)OsaMalloc(po->po_file.obj_data_size);
+                       if (!po->po_file.object_data) {
+                               return TEE_ERROR_OUT_OF_MEMORY;
+                       }
+                       memcpy(po->po_file.object_data, init_data, po->po_file.obj_data_size);
+               }
+       }
+
+       // init object info
+       po->attr.info.dataPosition = 0;
+       po->attr.info.dataSize = data_size;
+       po->attr.info.handleFlags |= TEE_HANDLE_FLAG_PERSISTENT
+           | TEE_HANDLE_FLAG_INITIALIZED;
+       po->attr.info.objectUsage = 0xffffff;
+       po->attr.info.objectSize =
+           attr == TEE_HANDLE_NULL ? 0 : attr->info.objectSize;
+
+       // write po file to ss
+       po->po_file.po_info = po->attr.info;
+       if (0 != write_po_file(po)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       memset(&g_po_info_file, 0, sizeof(po_info_file));
+       // write to stat file.
+       if (write_po_info(&g_po_info_file, po->object_id, po->obj_id_len,
+           &po->attr.info)) {
+               return TEE_ERROR_GENERIC;
+       }
+       // update po share info
+       if (0 != update_share_info(&po->share_info, po->attr.info.handleFlags, 1)) {
+               return TEE_ERROR_GENERIC;
+       }
+       // add to po list
+       add_to_po_list(po);
+       return TEE_SUCCESS;
+}
+
+TEE_Result open_po(persistent_object* po) {
+       int handleFlages;
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       int ret = update_share_info(&po->share_info, po->attr.info.handleFlags, 1);
+       if (0 != ret) {
+               return (1 == ret) ? TEE_ERROR_ACCESS_CONFLICT : TEE_ERROR_GENERIC;
+       }
+       // read and parse
+       ret = load_po_file(po);
+       if (0 != ret) {
+               ret = (1 == ret) ? TEE_ERROR_ITEM_NOT_FOUND : TEE_ERROR_GENERIC;
+               goto out;
+       }
+       if (deserialise_attr((char*)po->po_file.attr, (TransientObject*)&po->attr)) {
+               ret = TEE_ERROR_GENERIC;
+               goto out;
+       }
+       handleFlages = po->attr.info.handleFlags | TEE_HANDLE_FLAG_PERSISTENT
+           | TEE_HANDLE_FLAG_INITIALIZED;
+       po->attr.info = po->po_file.po_info;
+       po->attr.info.handleFlags = handleFlages;
+       po->attr.info.dataPosition = 0;
+       // add to po list
+       add_to_po_list(po);
+       ret = TEE_SUCCESS;
+       out:
+       if (ret) {
+               update_share_info(&po->share_info, po->attr.info.handleFlags, 0);
+       }
+       return ret;
+}
+
+TEE_Result read_object_data(persistent_object* po, void* buffer, size_t size,
+    uint32_t* count) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!buffer) {
+               return TEE_ERROR_BAD_PARAMETERS;
+       }
+       if (0 == size || 0 == po->attr.info.dataSize) {
+               *count = 0;
+               return TEE_SUCCESS;
+       }
+       if (po->attr.info.dataPosition >= po->attr.info.dataSize) {
+               return TEE_ERROR_OVERFLOW;
+       }
+       int cpsz =
+           (po->attr.info.dataPosition + size >= po->attr.info.dataSize) ?
+               (po->attr.info.dataSize - po->attr.info.dataPosition) : size;
+
+       void* src = po->po_file.object_data + po->attr.info.dataPosition;
+       memcpy(buffer, src, cpsz);
+       //update object info
+       po->attr.info.dataPosition += cpsz;
+       *count = cpsz;
+       return TEE_SUCCESS;
+}
+
+TEE_Result seek_object_data(persistent_object* po, int32_t offset,
+    TEE_Whence whence) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       uint32_t begin_pos = 0;
+       if (TEE_DATA_SEEK_CUR == whence) {
+               begin_pos = po->attr.info.dataPosition;
+       } else if (TEE_DATA_SEEK_END == whence) {
+               begin_pos = po->attr.info.dataSize;
+       }
+       int32_t dataPos = begin_pos + offset;
+       if ((uint32_t)dataPos >= TEE_DATA_MAX_POSITION) {
+               return TEE_ERROR_OVERFLOW;
+       }
+       if (dataPos < 0) {
+               dataPos = 0;
+       }
+       // Not support "hole" in file in this version.
+       if ((uint32_t)dataPos > (po->attr.info.dataSize - 1)) {
+               dataPos = po->attr.info.dataSize;
+       }
+       po->attr.info.dataPosition = dataPos;
+       return TEE_SUCCESS;
+}
+
+TEE_Result write_object_data(persistent_object* po, const void* buffer,
+    size_t size) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!buffer || !size) {
+               return TEE_SUCCESS;
+       }
+       if (po->attr.info.dataPosition > po->attr.info.dataSize) {
+               return TEE_ERROR_OVERFLOW;
+       }
+       uint32_t modified_size = po->attr.info.dataPosition + size;
+       if (modified_size <= po->attr.info.dataSize) {
+               memcpy(po->po_file.object_data + po->attr.info.dataPosition, buffer, size);
+       } else {
+               void* tmp_buf = OsaMalloc(modified_size);
+               if (NULL == tmp_buf) {
+                       return TEE_ERROR_OUT_OF_MEMORY;
+               }
+               memcpy(tmp_buf, po->po_file.object_data, po->attr.info.dataPosition);
+               memcpy((uint8_t*)tmp_buf + po->attr.info.dataPosition, buffer, size);
+               OsaFree(po->po_file.object_data);
+               po->po_file.object_data = (unsigned char*)tmp_buf;
+       }
+       //update object info
+       po->attr.info.dataPosition += size;
+       po->attr.info.dataSize =
+           (modified_size > po->attr.info.dataSize) ? modified_size :
+                                                      po->attr.info.dataSize;
+       // sync to ss.
+       po->po_file.po_info.dataSize = po->attr.info.dataSize;
+       if (-1 == write_po_file(po)) {
+               MSG("Failed to write po file to secure storage.");
+               return TEE_ERROR_GENERIC;
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result truncate_object_data(persistent_object* po, size_t size) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       // now not support the "hole" in file.
+       size_t trunc_sz =
+           po->attr.info.dataSize > size ? size : po->attr.info.dataSize;
+       if (trunc_sz == po->attr.info.dataSize) {
+               return TEE_SUCCESS;
+       }
+       po->attr.info.dataSize = trunc_sz;
+       po->po_file.po_info.dataSize = trunc_sz;
+       // write to ss
+       if (-1 == write_po_file(po)) {
+               return TEE_ERROR_GENERIC;
+       }
+       return TEE_SUCCESS;
+}
+
+void close_po(persistent_object* po) {
+       if (NULL == po) {
+               return;
+       }
+       update_share_info(&po->share_info, po->attr.info.handleFlags, 0);
+
+       // remove from po list
+       rem_from_po_list(po);
+       // free online attributes
+       TEE_Attribute* attrs = po->attr.attr.attr_array;
+       int i;
+       for (i = 0; i < po->attr.attr.attr_number; ++i) {
+               free_attribute(&attrs[i]);
+       }
+       FREE_PO(po);
+}
+
+TEE_Result free_po(persistent_object* po) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (-1 == delete_po_file(po)) {
+               return TEE_ERROR_GENERIC;
+       }
+       // free online attributes
+       TEE_Attribute* attrs = po->attr.attr.attr_array;
+       int i;
+       for (i = 0; i < po->attr.attr.attr_number; ++i) {
+               free_attribute(&attrs[i]);
+       }
+       // remove from po list
+       rem_from_po_list(po);
+       release_share_info(&po->share_info);
+       FREE_PO(po);
+       return TEE_SUCCESS;
+}
+
+TEE_Result rename_po(persistent_object* po, const void* newObjectID,
+    size_t newObjectIDLen) {
+       if (NULL == po) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (-1 == rename_po_file(po, newObjectID, newObjectIDLen)) {
+               return TEE_ERROR_GENERIC;
+       }
+       memcpy(po->object_id, newObjectID, newObjectIDLen);
+       po->obj_id_len = newObjectIDLen;
+       return TEE_SUCCESS;
+}
+
+TEE_Result exist_po(persistent_object* po) {
+       int ret = ss_validate(po->po_file.file_name, &po->po_file.cred,
+           SS_OPT_DEFAULT);
+       if (SS_RET_CANT_FIND_REQUESTED_DATA == ret) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       if (SS_RET_SUCCESS == ret) {
+               return TEE_SUCCESS;
+       }
+       return TEE_ERROR_GENERIC;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Persistent file operations
+////////////////////////////////////////////////////////////////////////////////////
+void init_po(persistent_object* po) {
+       char uuid[64] = {0};
+       convert_TA_UUID(uuid, po->TA_UUID);
+       MSG("UUID of the TA is %s.", uuid);
+       ss_set_credential(&po->po_file.cred, uuid, PO_INTERNAL_MODULE_NAME, 1, 0);
+
+       //derive file name
+       derive_po_file_name((void*)po->object_id, po->obj_id_len,
+           po->po_file.file_name);
+       po->po_file.attr = NULL;
+       po->po_file.attr_size = 0;
+       po->po_file.object_data = NULL;
+       po->po_file.obj_data_size = 0;
+       // init po_share_info
+       po->share_info.fd = -1;
+       po->share_info.usr_info = NULL;
+       memcpy(po->share_info.name, po->po_file.file_name, PO_FILE_NAME_MAX_LEN);
+       po->po_list.prev = NULL;
+       po->po_list.next = NULL;
+       po->po_list.po = po;
+       regist_clean_up();
+}
+
+int derive_po_file_name(const void* obj_id, int obj_id_len, char* fn) {
+       byte_to_hex((unsigned char*)fn, (unsigned char*)obj_id, obj_id_len);
+       fn[2 * obj_id_len] = '\0';
+       return 0;
+}
+
+int load_po_file(persistent_object* po) {
+       uint8_t* retbuf = NULL;
+       uint8_t* tmp_ptr = NULL;
+       uint32_t read_size = 0;
+       int ret = ss_read(&retbuf, &read_size, 0, po->po_file.file_name,
+           &po->po_file.cred, SS_OPT_DEFAULT);
+       if (SS_RET_CANT_FIND_REQUESTED_DATA == ret) {
+               MSG("Po file not exist.");
+               return 1;
+       }
+       if (SS_RET_SUCCESS != ret) {
+               MSG("Failed to read data from secure storage, ret = %d.", ret);
+               return -1;
+       }
+       tmp_ptr = retbuf;
+
+       // load po info
+       memcpy(&po->po_file.po_info, tmp_ptr, sizeof(TEE_ObjectInfo));
+       tmp_ptr += sizeof(TEE_ObjectInfo);
+       // load attr
+       size_t attr_size = read_size - sizeof(TEE_ObjectInfo)
+           - po->po_file.po_info.dataSize;
+       po->po_file.attr_size = attr_size;
+       if (0 < po->po_file.attr_size) {
+               po->po_file.attr = (unsigned char*)OsaMalloc(attr_size);
+               memcpy(po->po_file.attr, tmp_ptr, attr_size);
+       }
+       tmp_ptr += attr_size;
+
+       // load object data
+       po->po_file.obj_data_size = po->po_file.po_info.dataSize;
+       if (0 < po->po_file.obj_data_size) {
+               po->po_file.object_data = (unsigned char*)OsaMalloc(
+                   po->po_file.obj_data_size);
+               memcpy(po->po_file.object_data, tmp_ptr, po->po_file.obj_data_size);
+       }
+       ss_free_buffer(retbuf);
+       return 0;
+}
+
+int write_po_file(persistent_object* po) {
+       uint8_t* buf = NULL;
+       po->po_file.obj_data_size = po->attr.info.dataSize;
+       uint32_t buf_size = po->po_file.attr_size + po->po_file.obj_data_size
+           + sizeof(TEE_ObjectInfo);
+       buf = (unsigned char*)OsaMalloc(buf_size);
+       if (NULL == buf) {
+               MSG("Failed to allocate memory.");
+               OsaFree(buf);
+               return -1;
+       }
+       uint8_t* tmp_buf = buf;
+
+       // po_info
+       memcpy(tmp_buf, &po->po_file.po_info, sizeof(TEE_ObjectInfo));
+       tmp_buf += sizeof(TEE_ObjectInfo);
+       // attr
+       memcpy(tmp_buf, (void*)po->po_file.attr, po->po_file.attr_size);
+       tmp_buf += po->po_file.attr_size;
+       // object data
+       memcpy(tmp_buf, (void*)po->po_file.object_data, po->po_file.obj_data_size);
+       int ret = ss_write(buf, buf_size, 0, po->po_file.file_name, &po->po_file.cred,
+           SS_OPT_DEFAULT);
+       if (SS_RET_SUCCESS != ret) {
+               MSG("Failed to write data to securestorage, ret = %d.", ret);
+               OsaFree(buf);
+               return -1;
+       }
+       OsaFree(buf);
+       return 0;
+}
+
+int rename_po_file(persistent_object* po, const void* newObjectID,
+    size_t newObjectIDLen) {
+       // first delete old file
+       if (-1 == delete_po_file(po)) {
+               MSG("Failed to delete old po file.");
+               return -1;
+       }
+       derive_po_file_name(newObjectID, newObjectIDLen, po->po_file.file_name);
+       if (0 != write_po_file(po)) {
+               MSG("Failed to write po file.");
+               return -1;
+       }
+       write_po_info(&g_po_info_file, newObjectID, newObjectIDLen, &po->attr.info);
+       return 0;
+}
+
+void clean_po_file(persistent_object* po) {
+       if (!po) {
+               return;
+       }
+       __FREE(po->po_file.attr);
+       __FREE(po->po_file.object_data);
+}
+
+int delete_po_file(persistent_object* po) {
+       int ret = ss_delete(po->po_file.file_name, &po->po_file.cred, SS_OPT_DEFAULT);
+       if (SS_RET_SUCCESS != ret) {
+               MSG("Failed to delete data from secure storage. ret = %d.", ret);
+               return -1;
+       }
+       ret = delete_po_info(&g_po_info_file, po->object_id, po->obj_id_len);
+       if (-1 == ret) {
+               MSG("Failed to delete po info.");
+               return -1;
+       }
+       return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// misc operations
+////////////////////////////////////////////////////////////////////////////////////
+po_info_file g_po_info_file;
+
+int init_po_info_file(po_info_file* pi_file) {
+       if (pi_file->b_inited) {
+               return 0;
+       }
+       TEE_UUID tmp_uuid;
+       if (0 != get_uuid()) {
+               MSG("Failed to get UUID of TA.");
+               return -1;
+       }
+       tmp_uuid = this_uuid;
+       char uuid[64] = {0};
+       convert_TA_UUID(uuid, tmp_uuid);
+       ss_set_credential(&pi_file->cred, uuid, PO_INTERNAL_MODULE_NAME, 1, 0);
+       uint32_t fn_sz = strlen(PI_FILE_NAME);
+       memcpy(pi_file->filename, PI_FILE_NAME, fn_sz);
+       pi_file->filename[fn_sz] = '\0';
+       pi_file->b_inited = 1;
+       return 0;
+}
+
+int load_po_info_file(po_info_file* pi_file) {
+       if (init_po_info_file(pi_file)) {
+               return -1;
+       }
+       uint8_t* ret_buf = NULL;
+       uint32_t read_sz = 0;
+       int ret = ss_read(&ret_buf, &read_sz, 0, pi_file->filename, &pi_file->cred,
+           SS_OPT_DEFAULT);
+       if (SS_RET_CANT_FIND_REQUESTED_DATA == ret) {
+               pi_file->po_num = 0;
+               return 0;
+       }
+       if (SS_RET_SUCCESS != ret) {
+               MSG("Failed to read from secure storage, ret = %d.", ret);
+               return -1;
+       }
+       if (0 == read_sz) {
+               pi_file->po_num = 0;
+               return 0;
+       }
+       uint32_t po_info_sz = sizeof(persistent_object_info);
+       if (read_sz % po_info_sz) {
+               MSG("po_info file data error.");
+               ss_free_buffer(ret_buf);
+               return -1;
+       }
+       pi_file->po_num = read_sz / po_info_sz;
+       pi_file->po_info = (persistent_object_info*)ret_buf;
+       return 0;
+}
+
+int get_po_info(po_info_file* pi_file, persistent_object_info** po_info,
+    int* po_num) {
+       if (-1 == load_po_info_file(pi_file)) {
+               return -1;
+       }
+       if (0 == pi_file->po_num) {
+               *po_num = 0;
+               return 0;
+       }
+       persistent_object_info* tmp_info = NULL;
+       tmp_info = (persistent_object_info*)OsaMalloc(
+           pi_file->po_num * sizeof(persistent_object_info));
+       if (NULL == tmp_info) {
+               MSG("Failed to alloc memory.");
+               __FREE(pi_file->po_info);
+               return -1;
+       }
+       int32_t i = 0;
+       persistent_object_info* tmp_po_info = pi_file->po_info;
+       for (; i < pi_file->po_num; ++i) {
+               tmp_info[i] = *tmp_po_info;
+               tmp_po_info++;
+       }
+       *po_num = pi_file->po_num;
+       *po_info = tmp_info;
+       __FREE(pi_file->po_info);
+       return 0;
+}
+
+int write_po_info(po_info_file* pi_file, const void* objectID,
+    uint32_t obj_id_len, TEE_ObjectInfo* info) {
+       if (-1 == load_po_info_file(pi_file)) {
+               return -1;
+       }
+       persistent_object_info po_info;
+       memcpy((void*)po_info.object_id, objectID, obj_id_len);
+       po_info.obj_id_len = obj_id_len;
+       po_info.info = *info;
+       persistent_object_info* po_infos = NULL;
+       uint32_t po_info_sz = sizeof(persistent_object_info);
+       po_infos = (persistent_object_info*)OsaMalloc(
+           (pi_file->po_num + 1) * po_info_sz);
+       uint32_t po_num = pi_file->po_num;
+
+       memcpy((void*)po_infos, (void*)pi_file->po_info, po_num * po_info_sz);
+       memcpy((uint8_t*)po_infos + po_num * po_info_sz, (void*)&po_info, po_info_sz);
+
+       pi_file->po_num += 1;
+       __FREE(pi_file->po_info);
+       int ret = ss_write((uint8_t*)po_infos, po_info_sz * pi_file->po_num, 0,
+           pi_file->filename, &pi_file->cred, SS_OPT_DEFAULT);
+       if (SS_RET_SUCCESS != ret) {
+               MSG("Failed to write po stat to secure storage,ret = %d.", ret);
+               __FREE(po_infos);
+               return -1;
+       }
+       __FREE(po_infos);
+       return 0;
+}
+
+int delete_po_info(po_info_file* pi_file, const void* objectID,
+    uint32_t obj_id_len) {
+       persistent_object_info* po_del = NULL;
+
+       if (-1 == load_po_info_file(pi_file)) {
+               return -1;
+       }
+       uint32_t po_info_sz = sizeof(persistent_object_info);
+       po_del = find_po_info(pi_file, objectID, obj_id_len);
+       if (NULL == po_del) {
+               MSG("po info to del not found.");
+               return 0;
+       }
+       uint8_t* po_del_pos = (uint8_t*)po_del;
+       uint8_t* cp_begin = po_del_pos + po_info_sz;
+       uint32_t cp_sz = po_info_sz * pi_file->po_num
+           - (cp_begin - (uint8_t*)pi_file->po_info);
+
+       memcpy(po_del_pos, cp_begin, cp_sz);
+       pi_file->po_num--;
+       int ret = ss_write((uint8_t*)pi_file->po_info, po_info_sz * pi_file->po_num,
+           0, pi_file->filename, &pi_file->cred, SS_OPT_DEFAULT);
+       if (SS_RET_SUCCESS != ret) {
+               MSG("Failed to write po stat to secure storage,ret = %d.", ret);
+               __FREE(pi_file->po_info);
+               return -1;
+       }
+       __FREE(pi_file->po_info);
+       return 0;
+}
+
+persistent_object_info* find_po_info(po_info_file* pi_file,
+    const void* objectID, uint32_t obj_id_len) {
+       if (NULL == objectID || 0 == obj_id_len) {
+               MSG("objectID is invalid.");
+               return NULL;
+       }
+       int32_t i = 0;
+       int b_find = 0;
+       persistent_object_info* po_info_tmp = pi_file->po_info;
+       for (; i < pi_file->po_num; ++i) {
+               if (0 == memcmp(po_info_tmp->object_id, objectID, obj_id_len)) {
+                       b_find = 1;
+                       break;
+               }
+               po_info_tmp++;
+       }
+       return (b_find ? po_info_tmp : NULL);
+}
+
+// po share rule
+// TODO: locking mechanism to be improved using pthread locks ORr
+// As ssflib is shared lib, instead of malloc'ing the share_info,
+// just use a global variable, there by no need of locking
+void lock_po_share_info(po_share_info* share_info) {
+       while (share_info->usr_info->lock) {
+       }
+       share_info->usr_info->lock = 1;
+}
+
+void unlock_po_share_info(po_share_info* share_info) {
+       if (share_info->usr_info->lock) {
+               share_info->usr_info->lock = 0;
+       }
+}
+
+int init_share_info(po_share_info* share_info) {
+       if (NULL != share_info->usr_info) {
+               MSG("Share info has been inited.");
+               return 0;
+       }
+       // is the shm exist
+       share_info->usr_info = (po_user*)OsaMalloc(sizeof(po_user));
+       memset(share_info->usr_info, 0, sizeof(po_user));
+#if 0
+       int b_shm_exist = 1;
+       if (0 > shm_open(share_info->name, O_EXCL | O_CREAT, 0666))
+       {
+               b_shm_exist = 1;
+       }
+       share_info->fd = shm_open(share_info->name, O_RDWR | O_CREAT, 0666);
+       if (0 > share_info->fd)
+       {
+               MSG("Failed to open shm %s.", share_info->name);
+               return -1;
+       }
+       // linux posix shm need this
+       if (!b_shm_exist)
+       {
+               ftruncate(share_info->fd, sizeof(po_user));
+       }
+       share_info->usr_info = (po_user*) mmap(NULL, sizeof(po_user),
+                       PROT_READ | PROT_WRITE, MAP_SHARED, share_info->fd, 0);
+       if (share_info->usr_info == (void *) 0xFFFFFFFF)
+       {
+               MSG("Failed to mmap shm.");
+               return -1;
+       }
+       if (!b_shm_exist)
+       {
+               share_info->usr_info->lock = 0;
+               memset(share_info->usr_info, 0, sizeof(po_user));
+       }
+#endif
+       return 0;
+}
+
+int check_share_rule(po_share_info* share_info, uint32_t handleFlags) {
+       if ((NULL == share_info) || (-1 == init_share_info(share_info))) {
+               return -1;
+       }
+       int ret = 0;
+       // no user
+       if ((0 == share_info->usr_info->x_user)
+           && (0 == share_info->usr_info->rs_user)
+           && (0 == share_info->usr_info->ws_user)
+           && (0 == share_info->usr_info->rws_user)) {
+               goto out;
+       }
+       if (handleFlags & TEE_DATA_FLAG_ACCESS_READ) {
+               if (!((handleFlags & TEE_DATA_FLAG_SHARE_READ)
+                   && (0 == share_info->usr_info->x_user)
+                   && (0 == share_info->usr_info->ws_user))) {
+                       ret = -1;
+                       goto out;
+               }
+       }
+       if (handleFlags & TEE_DATA_FLAG_ACCESS_WRITE) {
+               if (!((handleFlags & TEE_DATA_FLAG_SHARE_WRITE)
+                   && (0 == share_info->usr_info->x_user)
+                   && (0 == share_info->usr_info->rs_user))) {
+                       ret = -1;
+                       goto out;
+               }
+       }
+       if (handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META) {
+               if (!((0 == share_info->usr_info->x_user)
+                   && (0 == share_info->usr_info->rs_user)
+                   && (0 == share_info->usr_info->ws_user)
+                   && (0 == share_info->usr_info->rws_user))) {
+                       ret = -1;
+               }
+       }
+       out: return ret;
+}
+
+int update_share_info(po_share_info* share_info, uint32_t handleFlags,
+    int b_open) {
+       if (NULL == share_info->usr_info) {
+               if (-1 == init_share_info(share_info)) {
+                       return -1;
+               }
+       }
+       // lock
+       // TODO: Commented for debugging, to be uncommented
+       lock_po_share_info(share_info);
+       int ret = 0;
+       if (b_open) {
+               if (check_share_rule(share_info, handleFlags)) {
+                       MSG("Access conflict!");
+                       ret = 1;
+                       goto out;
+               }
+       }
+       handleFlags &= ~TEE_DATA_FLAG_ACCESS_READ;
+       handleFlags &= ~TEE_DATA_FLAG_ACCESS_WRITE;
+       handleFlags &= ~TEE_HANDLE_FLAG_PERSISTENT;
+       handleFlags &= ~TEE_HANDLE_FLAG_INITIALIZED;
+
+       if ((handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META)
+           || (handleFlags & TEE_DATA_FLAG_EXCLUSIVE) || (0 == handleFlags)) {
+               b_open ? share_info->usr_info->x_user++ : share_info->usr_info->x_user--;
+               goto out;
+       }
+       if ((handleFlags & TEE_DATA_FLAG_SHARE_READ)
+           && (handleFlags & TEE_DATA_FLAG_SHARE_WRITE)) {
+               b_open ? share_info->usr_info->rws_user++ :
+                        share_info->usr_info->rws_user--;
+               goto out;
+       }
+       if (handleFlags & TEE_DATA_FLAG_SHARE_READ) {
+               b_open ? share_info->usr_info->rs_user++ : share_info->usr_info->rs_user--;
+               goto out;
+       }
+       if (handleFlags & TEE_DATA_FLAG_SHARE_WRITE) {
+               b_open ? share_info->usr_info->ws_user++ : share_info->usr_info->ws_user--;
+               goto out;
+       }
+       out:
+
+       if ((0 == share_info->usr_info->x_user)
+           && (0 == share_info->usr_info->rs_user)
+           && (0 == share_info->usr_info->ws_user)
+           && (0 == share_info->usr_info->rws_user)) {
+               release_share_info(share_info);
+       }
+       unlock_po_share_info(share_info);
+       return ret;
+}
+
+int release_share_info(po_share_info* share_info) {
+#if 0
+       if ((NULL == share_info) || (0 > share_info->fd))
+       {
+               MSG("Share info has been inited.");
+               return 0;
+       }
+       shm_unlink(share_info->name);
+#endif
+       OsaFree(share_info->usr_info);
+       return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// misc operations
+////////////////////////////////////////////////////////////////////////////////////
+void byte_to_hex(uint8_t* dest, const uint8_t* src, unsigned long src_len) {
+       char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',
+           'c', 'd', 'e', 'f'};
+
+       unsigned long j;
+       for (j = 0; j < src_len; j++) {
+               dest[j * 2] = hexval[((src[j] >> 4) & 0xF)];
+               dest[(j * 2) + 1] = hexval[(src[j]) & 0x0F];
+       }
+}
+
+void convert_TA_UUID(char* uuid, TEE_UUID TA_UUID) {
+       // In its canonical form, a UUID consists of 32 hexadecimal digits, displayed in 5 groups separated by hyphens,
+       // in the form 8-4-4-4-12 for a total of 36 characters(32 digits and 4 '-'). For example:
+       // 550e8400-e29b-41d4-a716-446655440000
+       // Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the version number as well
+       // as two reserved bits. All other bits are set using a random or pseudorandom data source.
+       // Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal digits x and hexadecimal
+       // digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+
+       char* tmp = uuid;
+       
+       snprintf(tmp, 9, "%08x", TA_UUID.timeLow);
+       tmp[8] = '-';
+       tmp += 9;
+       snprintf(tmp, 5, "%04x", TA_UUID.timeMid);
+       tmp[4] = '-';
+       tmp += 5;
+       snprintf(tmp, 5, "%04x", TA_UUID.timeHiAndVersion);
+       tmp[4] = '-';
+       tmp += 5;
+       uint32_t i = 0;
+       for (; i < 2; ++i) {
+               snprintf(tmp, 3,"%02x", TA_UUID.clockSeqAndNode[i]);
+               tmp += 2;
+       }
+       tmp[0] = '-';
+
+       tmp += 1;
+       for (; i < 8; ++i) {
+               snprintf(tmp, 3, "%02x", TA_UUID.clockSeqAndNode[i]);
+               tmp += 2;
+       }
+       MSG("this_uuid : %s ", uuid);
+}
+
+int gen_random(uint8_t* dest, uint8_t data_len) {
+       UCI_HANDLE uh = UCI_ERROR;
+       uh = uci_context_alloc(ID_UCI_X931, UCI_SW_CRYPTOCORE);
+       if (uh == UCI_ERROR || uh == UCI_MEM_ALLOR_ERROR) {
+               return -1;
+       }
+       unsigned char seed[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+           0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
+       int ret = uci_prng_seed(uh, seed);
+       if (ret != UCI_SUCCESS) {
+               goto out;
+       }
+       ret = uci_prng_get(uh, data_len * 8, dest);
+       if (ret != UCI_SUCCESS) {
+               goto out;
+       }
+       out: uci_context_free(uh);
+       return ret;
+}
+
+// persistent object list operations
+po_list_node g_po_list = {NULL, NULL, NULL};
+
+void debug_list() {
+       po_list_node* node = g_po_list.next;
+       while (node != NULL) {
+               MSG("PO [%s] ==>", node->po->po_file.file_name);
+               node = node->next;
+       }
+}
+
+void add_to_po_list(persistent_object* po) {
+       if (NULL == po) {
+               return;
+       }
+       po->po_list.po = po;
+       // first po
+       if (NULL == g_po_list.next) {
+               g_po_list.next = &po->po_list;
+               po->po_list.prev = &g_po_list;
+               po->po_list.next = NULL;
+       } else {
+               g_po_list.next->prev = &po->po_list;
+               po->po_list.next = g_po_list.next;
+               po->po_list.prev = &g_po_list;
+               g_po_list.next = &po->po_list;
+       }
+       MSG("=====PO %s added=====", po->po_file.file_name);
+       //debug_list();
+}
+
+void rem_from_po_list(persistent_object* po) {
+       if (NULL == po) {
+               return;
+       }
+       MSG("=====To remove PO %s=====", po->po_file.file_name);
+       //debug_list();
+       if (po->po_list.prev) {
+               po->po_list.prev->next = po->po_list.next;
+       }
+       if (po->po_list.next) {
+               po->po_list.next->prev = po->po_list.prev;
+       }
+       MSG("======PO removed=====");
+       //debug_list();
+}
+
+void cleanup(void) {
+       po_list_node* node = g_po_list.next;
+       while (NULL != node) {
+               TEE_CloseObject((TEE_ObjectHandle)node->po);
+               node = node->next;
+       }
+}
+
+void regist_clean_up() {
+       static int b_reg = 0;
+       if (b_reg) {
+               return;
+       }
+       if (0 == atexit(cleanup)) {
+               b_reg = 1;
+       }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// object general  operations
+////////////////////////////////////////////////////////////////////////////////////
+void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo* objectInfo) {
+       if (objectInfo) {
+               objectInfo->objectType = object->tr.info.objectType;
+               objectInfo->objectSize = object->tr.info.objectSize;
+               objectInfo->maxObjectSize = object->tr.info.maxObjectSize;
+               objectInfo->objectUsage = object->tr.info.objectUsage;
+               objectInfo->dataSize = object->tr.info.dataSize;
+               objectInfo->dataPosition = object->tr.info.dataPosition;
+               objectInfo->handleFlags = object->tr.info.handleFlags;
+       }
+}
+
+// usage ??
+void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage) {
+       object->tr.info.objectUsage &= objectUsage;
+}
+
+TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
+    uint32_t attributeID, void* buffer, size_t* size) {
+       uint32_t len;
+       int i, n = -1;
+       TransientObject * obj = &object->tr;
+
+       if (!(obj->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       // search for attributeID in attr_array
+       for (i = 0; i < obj->attr.attr_number; i++) {
+               if (obj->attr.attr_array[i].attributeID == attributeID) {
+                       n = i;
+                       break;
+               }
+       }
+       if (n == -1) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       // bit[29] == 1 -> not a buffer attribute
+       if (attributeID & TEE_ATTR_FLAG_VALUE) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       // protected attribute
+       if (!(attributeID & TEE_ATTR_FLAG_PUBLIC)
+           && !(obj->info.objectUsage & TEE_USAGE_EXTRACTABLE)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       //len = ((obj->attr.attr_array[n].content.ref.length & 0x7FFFFFFF) + 7) >> 3 ;
+       len = (obj->attr.attr_array[n].content.ref.length + 7) >> 3;
+
+       // out buffer is too small
+       if (len > *size) {
+               return TEE_ERROR_SHORT_BUFFER;
+       }
+       memcpy(buffer, obj->attr.attr_array[n].content.ref.buffer, len);
+       *size = len;
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
+    uint32_t attributeID, uint32_t* a, uint32_t* b) {
+       int i, n = -1;
+       TransientObject * obj = &object->tr;
+
+       if (!(obj->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       // search for attributeID in attr_array
+       for (i = 0; i < obj->attr.attr_number; i++) {
+               if (obj->attr.attr_array[i].attributeID == attributeID) {
+                       n = i;
+                       break;
+               }
+       }
+       if (n == -1) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       // bit[29] == 0 -> not a value attribute
+       if (!(attributeID & TEE_ATTR_FLAG_VALUE)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       // protected attribute
+       if (!(attributeID & TEE_ATTR_FLAG_PUBLIC)
+           && !(obj->info.objectUsage & TEE_USAGE_EXTRACTABLE)) {
+               return TEE_ERROR_ACCESS_DENIED;
+       }
+       if (a) {
+               *a = obj->attr.attr_array[i].content.value.a;
+       }
+       if (b) {
+               *b = obj->attr.attr_array[i].content.value.b;
+       }
+       return TEE_SUCCESS;
+}
+
+void TEE_CloseObject(TEE_ObjectHandle object) {
+       if (object == TEE_HANDLE_NULL) {
+               return;
+       }
+       if (object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) // persistent object
+       {
+               persistent_object *po = (persistent_object*)object;
+               close_po(po);
+       } else {
+               TEE_FreeTransientObject(object);
+       }
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Transient Object operations
+////////////////////////////////////////////////////////////////////////////////////
+TEE_Result TEE_AllocateTransientObject(uint32_t objectType,
+    uint32_t maxObjectSize, TEE_ObjectHandle* object) {
+       TEE_Result rc;
+
+
+       TransientObject * tr = (TransientObject*)OsaMalloc(sizeof(TransientObject));
+       if (!tr) {
+               OsaFree(tr);
+               return TEE_ERROR_OUT_OF_MEMORY;
+       }
+       memset(tr, 0, sizeof(TransientObject));
+       rc = allocate_transient_object(tr, objectType, maxObjectSize);
+       if (rc != TEE_SUCCESS) {
+               OsaFree(tr);
+               return rc;
+       }
+       *object = (TEE_ObjectHandle)&tr->info;
+       OsaFree(tr);
+       return TEE_SUCCESS;
+}
+
+void TEE_FreeTransientObject(TEE_ObjectHandle object) {
+       TransientObject * tr = NULL;
+
+       if (object == TEE_HANDLE_NULL) {
+               return;
+       }
+       tr = &object->tr;
+       TEE_Attribute* attrs = tr->attr.attr_array;
+       int i;
+       for (i = 0; i < tr->attr.attr_number; ++i) {
+               free_attribute(&attrs[i]);
+       }
+       memset(&tr->attr, 0, sizeof(tr->attr));
+       OsaFree(tr);
+}
+
+void TEE_ResetTransientObject(TEE_ObjectHandle object) {
+       TransientObject* tr;
+
+       if (object == TEE_HANDLE_NULL) {
+               return;
+       }
+       tr = &object->tr;
+       TEE_Attribute* attrs = tr->attr.attr_array;
+       int i;
+       for (i = 0; i < tr->attr.attr_number; ++i) {
+               free_attribute(&attrs[i]);
+       }
+       memset(tr->attr.attr_array, 0, sizeof(tr->attr.attr_array));
+       tr->attr.attr_number = 0;
+
+       tr->info.objectSize = 0;
+       tr->info.dataSize = 0;
+       tr->info.dataPosition = 0;
+       tr->info.handleFlags = 0;
+       tr->info.objectUsage = 0xffffffff;
+}
+
+TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
+    const TEE_Attribute* attrs, uint32_t attrCount) {
+       unsigned int i;
+
+       TransientObject* tr = &object->tr;
+       if (tr->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       TEE_Attribute* curr_attr = &tr->attr.attr_array[tr->attr.attr_number];
+       for (i = 0; i < attrCount; i++) {
+
+               if (attrs[i].content.ref.length > tr->info.maxObjectSize) {
+                       TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                       TEE_Panic(0);
+               }
+               copy_attribute(&curr_attr[i], (TEE_Attribute*)&attrs[i]);
+               tr->attr.attr_number++;
+               tr->info.objectSize =
+                   tr->info.objectSize > attrs[i].content.ref.length ?
+                       tr->info.objectSize : attrs[i].content.ref.length;
+       }
+
+       switch (tr->info.objectType) {
+               case TEE_TYPE_AES:
+               case TEE_TYPE_DES:
+               case TEE_TYPE_DES3:
+               case TEE_TYPE_HMAC_MD5:
+               case TEE_TYPE_HMAC_SHA1:
+               case TEE_TYPE_HMAC_SHA224:
+               case TEE_TYPE_HMAC_SHA256:
+               case TEE_TYPE_HMAC_SHA384:
+               case TEE_TYPE_HMAC_SHA512:
+               case TEE_TYPE_GENERIC_SECRET:
+                       if (tr->attr.attr_number != 1) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       break;
+               case TEE_TYPE_RSA_PUBLIC_KEY:
+               case TEE_TYPE_RSA_KEYPAIR: {
+                       // Krishna: Incorrect to check this condition 
+                       /*if ((tr->info.objectType == TEE_TYPE_RSA_KEYPAIR)
+                           && (tr->attr.attr_number != 3) && (tr->attr.attr_number != 8)) {
+                               TZ_ERROR("tr->attr.attr_number = %d\n", tr->attr.attr_number);
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }*/
+                       if ((tr->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY)
+                           && (tr->attr.attr_number != 2)) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+               }
+                       break;
+               case TEE_TYPE_DSA_PUBLIC_KEY:
+               case TEE_TYPE_DSA_KEYPAIR: {
+                       if ((tr->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY)
+                           && (tr->attr.attr_number != 4)) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       } else if ((tr->info.objectType == TEE_TYPE_DSA_KEYPAIR)
+                           && (tr->attr.attr_number != 5)) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+               }
+                       break;
+               case TEE_TYPE_DH_KEYPAIR: {
+                       if ((tr->attr.attr_number != 3) && (tr->attr.attr_number != 4)) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+               }
+                       break;
+               default:
+                       return TEE_ERROR_BAD_PARAMETERS;
+       }
+       tr->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
+       return TEE_SUCCESS;
+}
+
+void TEE_InitRefAttribute(TEE_Attribute* attr, uint32_t attributeID,
+    const void* buffer, size_t length) {
+       attr->attributeID = attributeID;
+       attr->content.ref.buffer = buffer;
+       attr->content.ref.length = length;
+}
+
+void TEE_InitValueAttribute(TEE_Attribute* attr, uint32_t attributeID,
+    uint32_t a, uint32_t b) {
+       attr->attributeID = attributeID;
+       attr->content.value.a = a;
+       attr->content.value.b = b;
+}
+
+void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
+    TEE_ObjectHandle srcObject) {
+       int attrCount, i;
+       //int offset = 0;
+       TEE_Attribute * attrs;
+
+       TransientObject* src = &srcObject->tr;
+       TransientObject* dest = &destObject->tr;
+
+       if (dest->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       dest->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED;
+       if (!(src->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       // check compatibility of source & destination
+       if (!((src->info.objectType == dest->info.objectType)
+           || ((dest->info.objectType == TEE_TYPE_RSA_PUBLIC_KEY)
+               && (src->info.objectType == TEE_TYPE_RSA_KEYPAIR))
+           || ((dest->info.objectType == TEE_TYPE_DSA_PUBLIC_KEY)
+               && (src->info.objectType == TEE_TYPE_DSA_KEYPAIR)))) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (src->info.objectSize > dest->info.maxObjectSize) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       dest->info.objectUsage &= src->info.objectUsage;
+       // copy attributes
+       attrs = src->attr.attr_array;
+       attrCount = src->attr.attr_number;
+       //offset = 0;
+       for (i = 0; i < attrCount; i++) {
+               copy_attribute(&dest->attr.attr_array[i], &attrs[i]);
+               dest->attr.attr_number++;
+       }
+}
+
+TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
+    const TEE_Attribute* params, uint32_t paramCount) {
+       char key[256];
+       TEE_Attribute attrs[MAX_ATTRIBUTE_NUMBER];
+       unsigned int i, check = 0;
+       TransientObject* tr = &object->tr;
+
+       if (tr->info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (keySize > tr->info.maxObjectSize) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       tr->info.objectSize = keySize;
+       switch (tr->info.objectType) {
+               case TEE_TYPE_AES:
+               case TEE_TYPE_DES:
+               case TEE_TYPE_DES3:
+               case TEE_TYPE_HMAC_MD5:
+               case TEE_TYPE_HMAC_SHA1:
+               case TEE_TYPE_HMAC_SHA224:
+               case TEE_TYPE_HMAC_SHA256:
+               case TEE_TYPE_HMAC_SHA384:
+               case TEE_TYPE_HMAC_SHA512:
+               case TEE_TYPE_GENERIC_SECRET:
+                       // generate 1 random key
+                       gen_random((unsigned char*)key, (keySize + 7) / 8);
+                       TEE_InitRefAttribute(&attrs[0], TEE_ATTR_SECRET_VALUE, key, keySize);
+                       TEE_PopulateTransientObject(object, attrs, 1);
+                       break;
+               case TEE_TYPE_RSA_KEYPAIR: {
+                       uci_key_s uci_key;
+                       int key_size = (keySize + 7) / 8;
+                       uci_key.ucik_rsa_n = (unsigned char*)OsaMalloc(key_size);
+                       uci_key.ucik_rsa_n_len = key_size;
+                       uci_key.ucik_rsa_e = (unsigned char*)OsaMalloc(key_size);
+                       uci_key.ucik_rsa_e_len = key_size;
+                       uci_key.ucik_rsa_d = (unsigned char*)OsaMalloc(key_size);
+                       uci_key.ucik_rsa_d_len = key_size;
+                       uci_param_s up;
+                       up.ucip_rsa_flag = RSA_GENKEYWITHNON;
+                       up.ucip_rsa_padding = ID_UCI_RSAES_PKCS15;
+                       //alg
+                       int alg = ID_UCI_RSA;
+                       if (512 == keySize) {
+                               alg = ID_UCI_RSA512;
+                       } else if (1024 == keySize) {
+                               alg = ID_UCI_RSA1024;
+                       } else if (2048 == keySize) {
+                               alg = ID_UCI_RSA2048;
+                       } else if (3072 == keySize) {
+                               alg = ID_UCI_RSA3072;
+                       }
+                       UCI_HANDLE uh = uci_context_alloc(alg, UCI_SW);
+                       uci_ae_gen_keypair(uh, &uci_key, &up);
+                       uci_context_free(uh);
+
+                       TEE_InitRefAttribute(&attrs[0], TEE_ATTR_RSA_MODULUS, uci_key.ucik_rsa_n,
+                           keySize);
+                       TEE_InitRefAttribute(&attrs[1], TEE_ATTR_RSA_PUBLIC_EXPONENT,
+                           uci_key.ucik_rsa_e, keySize);
+                       TEE_InitRefAttribute(&attrs[2], TEE_ATTR_RSA_PRIVATE_EXPONENT,
+                           uci_key.ucik_rsa_d, keySize);
+                       TEE_PopulateTransientObject(object, attrs, 3);
+
+                       OsaFree(uci_key.ucik_rsa_n);
+                       OsaFree(uci_key.ucik_rsa_e);
+                       OsaFree(uci_key.ucik_rsa_d);
+               }
+                       break;
+
+               case TEE_TYPE_DSA_KEYPAIR: {
+                       uci_key_s uci_key;
+                       int key_size = (keySize + 7) / 8;
+                       uci_key.ucik_dsa_pubk_len = key_size;
+                       uci_key.ucik_dsa_pubkey = (unsigned char*)OsaMalloc(key_size);
+                       uci_key.ucik_dsa_privk_len = key_size;
+                       uci_key.ucik_dsa_privkey = (unsigned char*)OsaMalloc(key_size);
+                       uci_param_s up;
+                       up.ucip_dsa_tsize = 0;
+
+                       // check the mandatory attributes
+                       for (i = 0; i < paramCount; i++) {
+                               if (params[i].attributeID == TEE_ATTR_DSA_PRIME) {
+                                       up.ucip_dsa_p = (unsigned char*)params[i].content.ref.buffer;
+                                       up.ucip_dsa_p_len = (params[i].content.ref.length + 7) / 8;
+                                       check |= 0x01;
+                               } else if (params[i].attributeID == TEE_ATTR_DSA_BASE) {
+                                       up.ucip_dsa_g = (unsigned char*)params[i].content.ref.buffer;
+                                       up.ucip_dsa_g_len = (params[i].content.ref.length + 7) / 8;
+                                       check |= 0x02;
+                               } else if (params[i].attributeID == TEE_ATTR_DSA_SUBPRIME) {
+                                       up.ucip_dsa_q = (unsigned char*)params[i].content.ref.buffer;
+                                       up.ucip_dsa_q_len = (params[i].content.ref.length + 7) / 8;
+                                       check |= 0x04;
+                               }
+                       }
+                       if (check != 0x07) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       // generate public & private keys. algorithm is the same as for DH
+                       UCI_HANDLE handle = uci_context_alloc(ID_UCI_DSA, UCI_SW);
+                       uci_ae_gen_keypair(handle, &uci_key, &up);
+                       uci_context_free(handle);
+                       for (i = 0; i < paramCount; i++) {
+                               TEE_InitRefAttribute(&attrs[i], params[i].attributeID,
+                                   params[i].content.ref.buffer, params[i].content.ref.length);
+                       }
+                       TEE_InitRefAttribute(&attrs[3], TEE_ATTR_DSA_PUBLIC_VALUE,
+                           uci_key.ucik_dsa_pubkey, uci_key.ucik_dsa_pubk_len * 8);
+                       TEE_InitRefAttribute(&attrs[4], TEE_ATTR_DSA_PRIVATE_VALUE,
+                           uci_key.ucik_dsa_privkey, uci_key.ucik_dsa_privk_len * 8);
+                       TEE_PopulateTransientObject(object, attrs, 5);
+                       OsaFree(uci_key.ucik_dsa_pubkey);
+                       OsaFree(uci_key.ucik_dsa_privkey);
+               }
+                       break;
+
+               case TEE_TYPE_DH_KEYPAIR: {
+                       int key_size = (keySize + 7) / 8;
+                       uint8_t* privKey = (unsigned char*)OsaMalloc(key_size);
+                       uint8_t* pubKey = (unsigned char*)OsaMalloc(key_size);
+                       uci_param_s uciparam;
+
+                       for (i = 0; i < paramCount; i++) {
+                               if (params[i].attributeID == TEE_ATTR_DH_PRIME) {
+                                       check |= 0x01;
+                                       uciparam.ucip_dh_prime = (unsigned char*)params[i].content.ref.buffer;
+                                       uciparam.ucip_dh_len = (params[i].content.ref.length + 7) / 8;
+                               } else if (params[i].attributeID == TEE_ATTR_DH_BASE) {
+                                       check |= 0x02;
+                                       uciparam.ucip_dh_generator = (unsigned char*)params[i].content.ref
+                                           .buffer;
+                               }
+                       }
+                       if (check != 0x03) {
+                               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+                               TEE_Panic(0);
+                       }
+                       UCI_HANDLE handle = uci_context_alloc(ID_UCI_DH, UCI_SW);
+                       uci_dh_gen_phasekey(handle, privKey, pubKey, &uciparam);
+                       uci_context_free(handle);
+                       for (i = 0; i < paramCount; i++) {
+                               TEE_InitRefAttribute(&attrs[i], params[i].attributeID,
+                                   params[i].content.ref.buffer, params[i].content.ref.length);
+                       }
+                       TEE_InitRefAttribute(&attrs[2], TEE_ATTR_DH_PRIVATE_VALUE, privKey,
+                           keySize);
+                       TEE_InitRefAttribute(&attrs[3], TEE_ATTR_DH_PUBLIC_VALUE, pubKey,
+                           keySize);
+                       TEE_PopulateTransientObject(object, attrs, 4);
+
+                       OsaFree(privKey);
+                       OsaFree(pubKey);
+               }
+                       break;
+       }
+       return TEE_SUCCESS;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Persistent object  operations
+////////////////////////////////////////////////////////////////////////////////////
+
+TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void* objectID,
+    size_t objectIDLen, uint32_t flags, TEE_ObjectHandle attributes,
+    const void* initialData, size_t initialDataLen, TEE_ObjectHandle* object) {
+       persistent_object* po = NULL;
+       TEE_Result rc = allocate_persistent_object(&po, storageID, objectID,
+           objectIDLen, flags);
+       TransientObject* tr_obj = NULL;
+       if (TEE_HANDLE_NULL != attributes) {
+               tr_obj = &attributes->tr;
+       }
+       rc = exist_po(po);
+       // already exist
+       if (TEE_SUCCESS == rc) {
+               if (flags & TEE_DATA_FLAG_EXCLUSIVE) {
+                       MSG("Persistent object already exist.");
+                       FREE_PO(po);
+                       return TEE_ERROR_ACCESS_CONFLICT;
+               }
+               if (!object) {
+                       FREE_PO(po);
+                       return TEE_SUCCESS;
+               }
+               rc = open_po(po);
+       } else {
+               rc = create_po(po, tr_obj, initialData, initialDataLen);
+       }
+       if (rc) {
+               FREE_PO(po);
+               return rc;
+       }
+       if (object) {
+               *object = (TEE_ObjectHandle)&po->attr.info;
+       } else {
+               close_po(po);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void* objectID,
+    size_t objectIDLen, uint32_t flags, TEE_ObjectHandle* object) {
+       persistent_object* po = NULL;
+       TEE_Result rc = allocate_persistent_object(&po, storageID, objectID,
+           objectIDLen, flags);
+       if (rc) {
+               return rc;
+       }
+       rc = open_po(po);
+       if (rc) {
+               FREE_PO(po);
+               return rc;
+       }
+       *object = (TEE_ObjectHandle)&po->attr.info;
+       return TEE_SUCCESS;
+}
+
+void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object) {
+       persistent_object* op;
+       if (object == TEE_HANDLE_NULL) {
+               return;
+       }
+       if (!(object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       op = (persistent_object*)object;
+       if (!(op->attr.info.handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       free_po(op);
+}
+
+TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
+    const void* newObjectID, size_t newObjectIDLen) {
+       if (object == TEE_HANDLE_NULL) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) {
+               // transient object
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       persistent_object* po;
+       po = (persistent_object*)object;
+       if (!(po->attr.info.handleFlags & TEE_DATA_FLAG_EXCLUSIVE)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(po->attr.info.handleFlags & TEE_DATA_FLAG_ACCESS_WRITE_META)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       return rename_po(po, newObjectID, newObjectIDLen);
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Persistent enumerator operations
+////////////////////////////////////////////////////////////////////////////////////
+TEE_Result TEE_AllocatePersistentObjectEnumerator(
+    TEE_ObjectEnumHandle* objectEnumerator) {
+       struct __TEE_ObjectEnumHandle* eh;
+       eh = (__TEE_ObjectEnumHandle *)OsaMalloc(
+           sizeof(struct __TEE_ObjectEnumHandle));
+       if (!eh) {
+               return TEE_ERROR_OUT_OF_MEMORY;
+       }
+       eh->po_info = NULL;
+       eh->po_num = 0;
+       eh->curr_position = 0;
+       eh->state = ENUM_STATE_INIT;
+
+       *objectEnumerator = eh;
+       return TEE_SUCCESS;
+}
+
+void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) {
+       if (TEE_HANDLE_NULL == objectEnumerator) {
+               return;
+       }
+       __FREE(objectEnumerator->po_info);
+       __FREE(objectEnumerator);
+}
+
+void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator) {
+       if (TEE_HANDLE_NULL == objectEnumerator) {
+               return;
+       }
+       objectEnumerator->curr_position = 0;
+       objectEnumerator->po_num = 0;
+       objectEnumerator->state = ENUM_STATE_INIT;
+       __FREE(objectEnumerator->po_info);
+       objectEnumerator->po_info = NULL;
+}
+
+TEE_Result TEE_StartPersistentObjectEnumerator(
+    TEE_ObjectEnumHandle objectEnumerator, uint32_t storageID) {
+       if (TEE_HANDLE_NULL == objectEnumerator) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (storageID != TEE_STORAGE_PRIVATE) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       TEE_UUID uuid;
+       if (0 != get_uuid()) {
+               MSG("Failed to get UUID of TA.");
+               return -1;
+       }
+       uuid = this_uuid;
+
+       if (objectEnumerator->state == ENUM_STATE_STARTED) {
+               TEE_ResetPersistentObjectEnumerator(objectEnumerator);
+       }
+       int ret = get_po_info(&g_po_info_file, &objectEnumerator->po_info,
+           &objectEnumerator->po_num);
+       if (ret || !objectEnumerator->po_num) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       objectEnumerator->state = ENUM_STATE_STARTED;
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
+    TEE_ObjectInfo* objectInfo, void* objectID, size_t* objectIDLen) {
+       if (TEE_HANDLE_NULL == objectEnumerator) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if ((objectEnumerator->state != ENUM_STATE_STARTED)
+           || (objectEnumerator->state == ENUM_STATE_END)) {
+               return TEE_ERROR_ITEM_NOT_FOUND;
+       }
+       persistent_object_info* po_info = objectEnumerator->po_info;
+       int curr_pos = objectEnumerator->curr_position;
+       *objectInfo = po_info[curr_pos].info;
+       *objectIDLen = po_info[curr_pos].obj_id_len;
+       memcpy(objectID, po_info[curr_pos].object_id, po_info[curr_pos].obj_id_len);
+
+       objectEnumerator->curr_position++;
+       if (objectEnumerator->curr_position >= objectEnumerator->po_num) {
+               objectEnumerator->state = ENUM_STATE_END;
+       }
+       return TEE_SUCCESS;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// Data stream access operations
+////////////////////////////////////////////////////////////////////////////////////
+
+TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void* buffer,
+    size_t size, uint32_t* count) {
+       int num;
+       if (object == TEE_HANDLE_NULL) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       persistent_object* po = (persistent_object*)object;
+       if (!(po->attr.info.handleFlags & TEE_DATA_FLAG_ACCESS_READ)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (size == 0) {
+               num = 0;
+       } else {
+               TEE_Result rc = read_object_data(po, buffer, size, (uint32_t*)&num);
+               if (rc) {
+                       return rc;
+               }
+       }
+       *count = num;
+
+       MSG("Data read is:");
+       printhex((unsigned char*)buffer, num);
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void* buffer,
+    size_t size) {
+       if (object == TEE_HANDLE_NULL) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       persistent_object* po = (persistent_object*)object;
+       if (!(po->attr.info.handleFlags & TEE_DATA_FLAG_ACCESS_WRITE)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (size != 0) {
+               return write_object_data(po, buffer, size);
+       }
+       return TEE_SUCCESS;
+}
+
+TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size) {
+       if (object == TEE_HANDLE_NULL) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       persistent_object* po = (persistent_object*)object;
+       if (!(po->attr.info.handleFlags & TEE_DATA_FLAG_ACCESS_WRITE)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       return truncate_object_data(po, size);
+}
+
+TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
+    TEE_Whence whence) {
+       if (object == TEE_HANDLE_NULL) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       if (!(object->tr.info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT)) {
+               TZ_ERROR("operation error line = %d,%s\n", __LINE__, __func__);
+               TEE_Panic(0);
+       }
+       persistent_object* po = (persistent_object*)object;
+       return seek_object_data(po, offset, whence);
+}
diff --git a/ssflib/src/ssf_taentrypoint.c b/ssflib/src/ssf_taentrypoint.c
new file mode 100755 (executable)
index 0000000..c4695bc
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * =====================================================================================
+ *
+ *       Filename:  ssf_taentrypoint.c
+ *
+ *    Description:  SSF TA Internal functions
+ *
+ *        Version:  1.0
+ *        Created:  20 April 2015 12:41:39  IST
+ *       Revision:  Original
+ *       Compiler:  gcc
+ *
+ *         Author:  krishna (Kr), k.devale@samsung.com
+ *   Organization:  Samsung Electronics
+ *
+ * =====================================================================================
+ */
+
+/*-----------------------------------------------------------------------------
+ *  Include files
+ *-----------------------------------------------------------------------------*/
+#include "ssf_lib.h"
+#include "ssf_client.h"
+#include <unistd.h>
+#ifdef __DEBUG__
+#include <stdio.h>
+#endif
+
+/*-----------------------------------------------------------------------------
+ *  TEE Internal API implementation
+ *-----------------------------------------------------------------------------*/
+
+TEE_Result TEE_OpenTASession(const TEE_UUID* destination,
+    uint32_t cancellationRequestTimeout, uint32_t paramTypes,
+    TEE_Param params[4], TEE_TASessionHandle* session, uint32_t* returnOrigin) {
+
+       IntTAOpenSessionData data;
+       data.destination = *destination;
+       data.cancelTimeOut = cancellationRequestTimeout;
+       data.operation.paramTypes = paramTypes;
+
+       memcpy(data.operation.params, params, sizeof(TEE_Param[4]));
+
+       pthread_mutex_lock(&socketLock);
+       sendCommand(socketSimulatorDaemonFD, OPEN_TA_SESSION, &data,
+           sizeof(IntTAOpenSessionData));
+       pthread_mutex_unlock(&socketLock);
+#if 0
+       printf("Inside: %s \n", __FUNCTION__);
+       data.params[0].value.a = 1;
+       data.params[0].value.b = 1;
+       data.params[1].value.a = 2;
+       data.params[1].value.b = 2;
+       data.params[2].value.a = 3;
+       data.params[2].value.b = 3;
+       data.params[3].value.a = 4;
+       data.params[3].value.b = 4;
+       data.returnOrigin = TEE_ORIGIN_TRUSTED_APP;
+       data.returnValue = TEE_SUCCESS;
+#endif
+
+       //  Return from the function call
+       //      [inout] TEE_Param params[4],
+       //      [out] TEE_TASessionHandle* session,
+       //      [out] uint32_t* returnOrigin);
+       uint32_t* sessionData = (uint32_t*)OsaMalloc(sizeof(uint32_t));
+       memcpy(params, data.operation.params, sizeof(TEE_Param[4]));
+       *sessionData = data.session;
+       *session = (TEE_TASessionHandle)sessionData;
+       *returnOrigin = data.returnOrigin;
+       return data.returnValue;
+}
+
+void TEE_CloseTASession(TEE_TASessionHandle session) {
+
+       IntTACloseSessionData data;
+       data.session = *(uint32_t*)session;
+       pthread_mutex_lock(&socketLock);
+       sendCommand(socketSimulatorDaemonFD, CLOSE_TA_SESSION, &data,
+           sizeof(IntTACloseSessionData));
+       pthread_mutex_unlock(&socketLock);
+       OsaFree(session);
+}
+
+TEE_Result TEE_InvokeTACommand(TEE_TASessionHandle session,
+    uint32_t cancellationRequestTimeout, uint32_t commandID,
+    uint32_t paramTypes, TEE_Param params[4], uint32_t* returnOrigin) {
+       IntTAInvokeCommandData data;
+       data.session = *(uint32_t*)session;
+       data.cancelTimeOut = cancellationRequestTimeout;
+       data.commandID = commandID;
+       data.operation.paramTypes = paramTypes;
+       memcpy(data.operation.params, params, sizeof(TEE_Param[4]));
+       pthread_mutex_lock(&socketLock);
+       sendCommand(socketSimulatorDaemonFD, INVOKE_TA_COMMAND, &data,
+           sizeof(IntTAInvokeCommandData));
+       pthread_mutex_unlock(&socketLock);
+#if 0
+       printf("Inside: %s \n", __FUNCTION__);
+       data.params[0].value.a = 1;
+       data.params[0].value.b = 1;
+       data.params[1].value.a = 2;
+       data.params[1].value.b = 2;
+       data.params[2].value.a = 3;
+       data.params[2].value.b = 3;
+       data.params[3].value.a = 4;
+       data.params[3].value.b = 4;
+
+       data.returnOrigin = TEE_ORIGIN_TRUSTED_APP;
+       data.returnValue = TEE_SUCCESS;
+#endif
+       //  Return from the function call
+       //      [inout] TEE_Param params[4],
+       //      [out] uint32_t* returnOrigin);
+       memcpy(params, data.operation.params, sizeof(TEE_Param[4]));
+       *returnOrigin = data.returnOrigin;
+       return data.returnValue;
+}