--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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=""${workspace_loc:/include/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/}/include""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ </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="..\..\..\toolchain\windows\i386-linux-gnueabi-gcc-4.6\lib\gcc\i386-linux-gnueabi\4.6.4"" 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=""${workspace_loc:/osal/Debug}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log/Debug}""/>
+ </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>
--- /dev/null
+<?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>
--- /dev/null
+<?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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
+ <language-scope id="org.eclipse.cdt.core.gcc"/>
+ <language-scope id="org.eclipse.cdt.core.g++"/>
+ </provider>
+ </extension>
+ </configuration>
+</project>
--- /dev/null
+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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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__ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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(®mem, 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, ®mem,
+ 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(®mem, 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, ®mem,
+ 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+<?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=""${workspace_loc:/include/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}/../ssflib/inc""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
+ </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=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/ssflib/inc}""/>
+ </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=""${workspace_loc:/ssflib/Debug}""/>
+ <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="${workspace_loc:/${ProjName}}/../ssflib/Debug"" 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>
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+eclipse.preferences.version=1
+formatter_settings_version=1
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
--- /dev/null
+# 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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+#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 (' & " < > &#...;)\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
+ // & '\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
+ // "\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
+ // >\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
+ // <\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
--- /dev/null
+#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
--- /dev/null
+#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 (< > ' " &)\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
--- /dev/null
+#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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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));
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+# 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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS := -losal -lrt -llog
+
--- /dev/null
+################################################################################
+# 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 \
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
--- /dev/null
+################################################################################
+# 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 \
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+#!/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
+
--- /dev/null
+-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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
--- /dev/null
+################################################################################
+# 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 := \
+. \
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+-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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
--- /dev/null
+################################################################################
+# 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 := \
+. \
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS := -lrt -llog -losal -lpthread -lboost_system -lboost_thread
+
--- /dev/null
+################################################################################
+# 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 \
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+# 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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS := -lboost_thread -llog -losal -lrt
+
--- /dev/null
+################################################################################
+# 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 \
+
--- /dev/null
+# 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 ' '
+
+
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
+ <language-scope id="org.eclipse.cdt.core.gcc"/>
+ <language-scope id="org.eclipse.cdt.core.g++"/>
+ </provider>
+ </extension>
+ </configuration>
+</project>
--- /dev/null
+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
--- /dev/null
+/*
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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__ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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__ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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__ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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__ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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__ */
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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 "${INPUTS}"" 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 "${INPUTS}"" 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 "${INPUTS}"" prefer-non-shared="true">
+ <language-scope id="org.eclipse.cdt.core.gcc"/>
+ <language-scope id="org.eclipse.cdt.core.g++"/>
+ </provider>
+ </extension>
+ </configuration>
+</project>
--- /dev/null
+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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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, ¶m_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, ¶m_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, ¶m_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, ¶m_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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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 */
+
--- /dev/null
+<?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=""${workspace_loc:/include/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/TABinaryManager}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
+ </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=""${workspace_loc:/include/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/src/TABinaryManager}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
+ </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="..\..\..\toolchain\windows\i386-linux-gnueabi-gcc-4.6\lib\gcc\i386-linux-gnueabi\4.6.4"" 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=""${workspace_loc:/log/Debug}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal/Debug}""/>
+ </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>
--- /dev/null
+<?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>
--- /dev/null
+<?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 "${INPUTS}"" 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
--- /dev/null
+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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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 */
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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 */
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+<?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>
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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");
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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();
+}
--- /dev/null
+<?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=""${workspace_loc:/${ProjName}/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}/../../include""/>
+ </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=""${workspace_loc:/${ProjName}/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}/../../include""/>
+ </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>
--- /dev/null
+<?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>
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+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:
--- /dev/null
+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:
--- /dev/null
+TAUnpack.d: ../TAUnpack.cpp ../TAUnpack.h
+
+../TAUnpack.h:
--- /dev/null
+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:
--- /dev/null
+################################################################################
+# 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
--- /dev/null
+################################################################################
+# Automatically-generated file. Do not edit!
+################################################################################
+
+USER_OBJS :=
+
+LIBS :=
+
--- /dev/null
+################################################################################
+# 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 := \
+. \
+
--- /dev/null
+################################################################################
+# 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 ' '
+
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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() {
+
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#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 (' & " < > &#...;)
+ // - 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]) {
+
+ // & '
+ 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;
+
+ // "
+ 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;
+
+ // >
+ case Ch('g'):
+ if (src[2] == Ch('t') && src[3] == Ch(';')) {
+ *dest = Ch('>');
+ ++dest;
+ src += 4;
+ continue;
+ }
+ break;
+
+ // <
+ 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
--- /dev/null
+#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
--- /dev/null
+#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 (< > ' " &)
+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
--- /dev/null
+#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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+#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 (' & " < > &#...;)
+ // - 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]) {
+
+ // & '
+ 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;
+
+ // "
+ 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;
+
+ // >
+ case Ch('g'):
+ if (src[2] == Ch('t') && src[3] == Ch(';')) {
+ *dest = Ch('>');
+ ++dest;
+ src += 4;
+ continue;
+ }
+ break;
+
+ // <
+ 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
--- /dev/null
+#!/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
--- /dev/null
+<?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=""${workspace_loc:/${ProjName}/dep/cryptocore/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/include/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/cryptocore/include/base}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/cryptocore/include/middle}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/swdss/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/uci/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
+ </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=""${workspace_loc:/${ProjName}/dep/cryptocore/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/log}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/include/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/cryptocore/include/base}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/cryptocore/include/middle}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/swdss/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/dep/uci/include}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
+ </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="..\..\..\toolchain\windows\i386-linux-gnueabi-gcc-4.6\lib\gcc\i386-linux-gnueabi\4.6.4"" 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=""${workspace_loc:/log/Debug}""/>
+ <listOptionValue builtIn="false" value=""${workspace_loc:/osal/Debug}""/>
+ </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>
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
+
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * 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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * @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*/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/*
+ * 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 *****************************/
--- /dev/null
+/*
+ * 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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * 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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * @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;
+}
--- /dev/null
+/**
+ * \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
--- /dev/null
+/*
+ * 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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/* 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 *****************************/
+
--- /dev/null
+/*
+ * 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]);
+ }
+}
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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
--- /dev/null
+/**
+ * \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;
+}
+
+
--- /dev/null
+/**
+ * \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 *****************************/
--- /dev/null
+/**
+ * \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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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 = ¶m->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 = ¶m->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 = ¶m->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;
+}
+
--- /dev/null
+/*
+* 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
+}
+
--- /dev/null
+\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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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_ */
--- /dev/null
+/** \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
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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) {
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+ }
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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);
+}
--- /dev/null
+/*
+ * =====================================================================================
+ *
+ * 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;
+}