diff options
137 files changed, 10621 insertions, 3887 deletions
diff --git a/SoftHSMv2/.appveyor.yml b/SoftHSMv2/.appveyor.yml new file mode 100644 index 0000000..4a46ea5 --- /dev/null +++ b/SoftHSMv2/.appveyor.yml @@ -0,0 +1,65 @@ +version: 2.2.{build} +configuration: Release +platform: +- x86 +- x64 +init: +- ps: >- + If ($env:Platform -Match "x86") { + $env:VCVARS_PLATFORM="x86" + $env:MSBUILD_PLATFORM="Win32" + $env:ENV_PLATFORM="x86" + $env:CONFIGURE_OPTIONS="disable-debug $env:ADDITIONAL_CONFIGURE_OPTIONS" + } Else { + $env:VCVARS_PLATFORM="amd64" + $env:MSBUILD_PLATFORM="x64" + $env:ENV_PLATFORM="x64" + $env:CONFIGURE_OPTIONS="enable-64bit disable-debug $env:ADDITIONAL_CONFIGURE_OPTIONS" + } + + + $CURRENT_DIR_PATH = (Get-Item -Path ".\" -Verbose).FullName + + $env:BUILD_DIR = Join-Path $CURRENT_DIR_PATH build + + $env:CRYPTO_PACKAGE= "$env:CRYPTO_PACKAGE_NAME-$env:ENV_PLATFORM.zip" + + $env:CRYPTO_PACKAGE_PATH = Join-Path $env:BUILD_DIR "$env:CRYPTO_PACKAGE_NAME-$env:ENV_PLATFORM" + + $env:CPPUNIT_VERSION_NAME = "CppUnit-1.13.2" + + $env:CPPUNIT_PACKAGE_NAME = "cppunit-1.13.2" + + $env:CPPUNIT_PACKAGE = "$env:CPPUNIT_PACKAGE_NAME-$env:ENV_PLATFORM.zip" + + $env:PYTHON_PATH = Join-Path $env:BUILD_DIR python + + $env:CPPUNIT_PATH = Join-Path $env:BUILD_DIR "$env:CPPUNIT_PACKAGE_NAME-$env:ENV_PLATFORM" + + $env:PYTHON_EXE = Join-Path $env:PYTHON_PATH python.exe + + $env:RELEASE_DIR=Join-Path $env:BUILD_DIR "SoftHSMv2-$env:ENV_PLATFORM" + + $env:CONFIGURE_OPTIONS = "$env:CONFIGURE_OPTIONS with-crypto-backend=$env:CRYPTO_BACKEND with-$env:CRYPTO_BACKEND=$env:CRYPTO_PACKAGE_PATH\ with-cppunit=$env:CPPUNIT_PATH\" +environment: + matrix: + - CRYPTO_BACKEND: openssl + PACKAGE_VERSION_NAME: OpenSSL-1.0.2j + CRYPTO_PACKAGE_NAME: openssl-1.0.2j + ADDITIONAL_CONFIGURE_OPTIONS: disable-eddsa + - CRYPTO_BACKEND: botan + PACKAGE_VERSION_NAME: Botan-1.10.13 + CRYPTO_PACKAGE_NAME: botan-1.10.13 + ADDITIONAL_CONFIGURE_OPTIONS: disable-eddsa + - CRYPTO_BACKEND: openssl + PACKAGE_VERSION_NAME: OpenSSL-1.1.0b + CRYPTO_PACKAGE_NAME: openssl-1.1.0b + ADDITIONAL_CONFIGURE_OPTIONS: disable-eddsa disable-gost +install: +- cmd: powershell -File testing/appveyor/appveyor_download_requirements.ps1 +build_script: +- cmd: testing/appveyor/appveyor_build.bat +test: off +artifacts: +- path: build/SoftHSMv2-$(Platform) + name: SoftHSMv2-$(PACKAGE_VERSION_NAME)-$(Platform) diff --git a/SoftHSMv2/Makefile.am b/SoftHSMv2/Makefile.am index cfc0c62..786affe 100644 --- a/SoftHSMv2/Makefile.am +++ b/SoftHSMv2/Makefile.am @@ -18,8 +18,14 @@ endif EXTRA_DIST = $(srcdir)/aes_wrap_key_with_pad/botan-diff \ $(srcdir)/aes_wrap_key_with_pad/README \ + $(srcdir)/CMakeLists.txt \ + $(srcdir)/CMAKE-NOTES.md \ + $(srcdir)/config.h.in.cmake \ $(srcdir)/FIPS-NOTES.md \ $(srcdir)/LICENSE \ $(srcdir)/m4/*.m4 \ + $(srcdir)/modules/*.cmake \ + $(srcdir)/modules/tests/*.c \ + $(srcdir)/modules/tests/*.cpp \ $(srcdir)/OSX-NOTES.md \ - $(srcdir)/README.md + $(srcdir)/README.md diff --git a/SoftHSMv2/NEWS b/SoftHSMv2/NEWS index feae4e4..bc32026 100644 --- a/SoftHSMv2/NEWS +++ b/SoftHSMv2/NEWS @@ -1,6 +1,35 @@ NEWS for SoftHSM -- History of user visible changes -SoftHSM 2.4.0 - 2017-02-27 +SoftHSM 2.5.0 - 2018-09-24 + +* Issue #323: Support for EDDSA with vendor defined mechanisms. + (Patch from Francis Dupont) +* Issue #362: CMake Build System Support for SoftHSM. + (Patch from Constantine Grantcharov) +* Issue #368: Support migrating 32-bit SoftHSMv1 DB on 64-bit system (LP64). +* Issue #385: Default is not to build EDDSA since it has not been released in + OpenSSL. +* Issue #387: Windows: Add VS2017 detection to Configure.py. + (Patch from Jaroslav Imrich) +* Issue #412: Replace PKCS11 headers with a version from p11-kit. + (Patch from Alexander Bokovoy) + +Bugfixes: +* Issue #366: Support cross-compilation. + (Patch from Michael Weiser) +* Issue #377: Duplicate symbol error with custom p11test. +* Issue #386: Use RDRAND in OpenSSL if that engine is available. +* Issue #388: Update DBTests.cpp to fix x86 test failure. + (Patch from tcely) +* Issue #393: Not setting CKA_PUBLIC_KEY_INFO correctly. + (Patch from pkalapat) +* Issue #401: Wrong key and keyserver mentioned in installation documentation. + (Patch from Berry A.W. van Halderen) +* Issue #408: Remove mutex callbacks after C_Finalize(). + (Patch from Alexander Bokovoy) + + +SoftHSM 2.4.0 - 2018-02-27 * Issue #135: Support PKCS#8 for GOST. * Issue #140: Support for CKA_ALLOWED_MECHANISMS. diff --git a/SoftHSMv2/OSX-NOTES.md b/SoftHSMv2/OSX-NOTES.md deleted file mode 100644 index f1c7ee2..0000000 --- a/SoftHSMv2/OSX-NOTES.md +++ /dev/null @@ -1,182 +0,0 @@ -# Building SoftHSMv2 on macOS 10.12.3 (Sierra) - -This document contains instructions for building SoftHSMv2 from the command -line on macOS 10.12.3. - -This may work for other versions of OS X/macOS, but this has not been verified. - -## Command Line Tools - -We assume that XCode has been installed. To find out where Xcode keeps the C++ -compiler type the following at the command line: - - $ xcode-select --print-path - /Applications/Xcode.app/Contents/Developer - -The gcc compiler in this case can be found at -/Applications/Xcode.app/Contents/Developer/usr/bin/gcc - -Alternatively if you don't want to install XCode you could install command line -tools for macOS that can be downloaded from Apple. - -e.g. currently the following package for the Sierra release of macOS is -available for download. - - Command_Line_Tools_macOS_10.12_for_Xcode_8.2.dmg - -This dmg file is ~150MB but it is at least orders of magnitude smaller than -installing all of XCode. - -## Homebrew - -The libraries that come as part of macOS are rather old. We need to use more -recent versions of these libraries to avoid unexpected failures during building -and running. - -There is a community supported command line package manager for installing the -dependencies we need. It's called homebrew. First we'll need to install it as -follows: - - $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" - -Now we need to install some dependencies - - $ brew install automake - $ brew install pkg-config - $ brew install openssl - $ brew install sqlite - $ brew install cppunit - $ brew install libtool - -openssl, sqlite, and libtool are pre-installed on the system. The versions downloaded -by brew are stored in an alternative location under /usr/local - -The only brew warning of note is for libtool: - - ==> Caveats - In order to prevent conflicts with Apple's own libtool we have prepended a "g" - so, you have instead: glibtool and glibtoolize. - -Note: gblitoolize seems to be found in the configuration step below just fine. It's unclear -if glibtool is used since autogen.sh generates its own libtool script that is used by make. - -During configure, the paths to the newly installed libraries need to be passed -in so configure can actually find the libraries. We'll show how to do that -later. - -## Cloning SoftHSMv2 - -We now need to clone SoftHSMv2 from github. - - $ git clone https://github.com/opendnssec/SoftHSMv2.git - $ cd SoftHSMv2 - -## Configuring the build - -Start by installing autoconf in the source directory by executing the -autogen.sh script. - - $ sh ./autogen.sh - -If all went well a configure script should have been generated. To find out the -options available for building issue the following command: - - $ ./configure --help - -In the example below I will enable the optional token object store database -backend. - - $ ./configure --with-objectstore-backend-db \ - --with-openssl=/usr/local/opt/openssl \ - --with-sqlite3=/usr/local/opt/sqlite - -Now if for some reason the compilers are not found, do the following at the -command line. - - $ export CC="xcrun gcc" - $ export CPP="xcrun cpp" - $ export CXX="xcrun g++" - $ ./configure --with-objectstore-backend-db \ - --with-openssl=/usr/local/opt/openssl \ - --with-sqlite3=/usr/local/opt/sqlite - -By exporting these environment variables we are instructing configure to use -the compilers stored inside the installed XCode.app. - -## Building and Testing SoftHSMv2 - -Now we can build SoftHSMv2 by just executing make. - - $ make - -And we can check that it works by running all tests. - - $ make check - -To try a specific test, e.g. to check just the PKCS#11 test cases use the -following make command: - - $ make -C src/lib/test check - -Then change src/lib/test/softhsm2.conf so it contains the following lines. - - # SoftHSM v2 configuration file - directories.tokendir = ./tokens - objectstore.backend = db - log.level = INFO - slots.removable = false - -Then change src/lib/test/softhsm2-alt.conf so it contains the following lines. - - # SoftHSM v2 configuration file - directories.tokendir = ./tokens - objectstore.backend = db - log.level = INFO - slots.removable = true - -We are now ready to run the tests again. - - $ make -C src/lib/test check - -Because the object store backend was changed from file to db we have used -sqlite for storing the token objects. Verify this by looking in the sub-folders -of src/lib/test/tokens There you should find a database file named sqlite3.db - -## Performance - -The file backend currently exhibits the best performance. It is normally at -least twice as fast as the database backend. - -The idea behind storing token objects in a database is that it has advantages -when a large number (> 100K) of keys are stored in a token. A database allows -for selectively querying and loading in only a subset of the keys into memory. -The file based storage backend reads in the complete contents of the token. -Also because the database is only a single file, we should not hit any system -limitations w.r.t. the number of files that can be stored in a file system. - -The database backend uses transactions to write changes to the token database. -For modifiable attributes this will require a round trip to the database every -time an attribute has been read as another process may have modified the given -attribute. - -The database backend uses approximately 20% less memory because it will only -load in object attributes on demand. For non-mutable attributes that is not a -problem because once an object with its attributes is created those attributes -won't change. On the other hand the mutable attributes of the object are always -read when the object is accessed, making it slower because this will require a -roundtrip to the database for every mutable attribute. Note that most -attributes are non-mutable and especially the key material is non-mutable. So -once this (encrypted !) material has been read into memory it will remain -cached (encrypted !). - -Currently the query functionality for only retrieving a subset of the objects -is not yet implemented. Therefore the database solution has no advantages -w.r.t. the file based solution for large number of files other than the 20% -less memory usage mentioned before. - -For applications that need the highest speed possible and only read/use the -token, a solution would be to copy the whole of the token database to a -ramdisk. This should only be used when the application doesn't modify the -token, because a power-cycle of the host will wipe out the ramdisk. - -3-January-2017 diff --git a/SoftHSMv2/README.md b/SoftHSMv2/README.md index c8230e8..e3b46a3 100644 --- a/SoftHSMv2/README.md +++ b/SoftHSMv2/README.md @@ -41,11 +41,21 @@ Minimum required versions: If you are using Botan, make sure that it has support for GNU MP (--with-gnump). This will improve the performance when doing public key operations. -The GNU Autotools are also required for building the software. +The GNU Autotools (Autoconf, Automake, Libtool) are also required for building +the software. It is also recommended to install pkg-config so that the +configure script can find the installed software. There is a migration tool for converting token databases from SoftHSMv1 into -the new type of tokens. If this tool is built, then SQLite3 is required (>= -3.4.2). +the new type of tokens. If this tool is built (--with-migrate), then SQLite3 +is required (>= 3.4.2). + +SQLite3 is also required if building with the database object store +(--with-objectstore-backend-db). + +To install SoftHSM as a PKCS#11 module on the system, please install +libp11-kit-dev. + +The unit tests requires CppUnit. ## Installation @@ -62,6 +72,7 @@ Options: Disable non-paged memory for secure storage (default enabled) --disable-ecc Disable support for ECC (default enabled) + --disable-eddsa Disable support for EDDSA (default enabled) --disable-gost Disable support for GOST (default enabled) --disable-visibility Disable hidden visibilty link mode [enabled] --with-crypto-backend Select crypto backend (openssl|botan) @@ -87,6 +98,12 @@ Compile the source code using the following command: make +### Unit tests + +Running the unit tests requires CppUnit. + + make check + ### Install Library Install the library using the follow command: @@ -144,6 +161,6 @@ the source file name and line number. If the code is downloaded directly from the code repository, you have to prepare the configuration scripts before continuing with the real README. -1. You need to install automake, autoconf, libtool, etc. +1. You need to install automake, autoconf, libtool, libtool-ltdl-devel (RHEL/CentOS), pkg-config. 2. Run the command 'sh autogen.sh' 3. Continue reading this README. diff --git a/SoftHSMv2/configure.ac b/SoftHSMv2/configure.ac index 48a4bc2..eecd6eb 100644 --- a/SoftHSMv2/configure.ac +++ b/SoftHSMv2/configure.ac @@ -7,8 +7,8 @@ # Program version define([SOFTHSM_VERSION_MAJOR], [2]) -define([SOFTHSM_VERSION_MINOR], [4]) -define([SOFTHSM_VERSION_FIX], [0]) +define([SOFTHSM_VERSION_MINOR], [5]) +define([SOFTHSM_VERSION_FIX], [1]) define([PACKAGE_SUFFIX], []) # Library version @@ -20,7 +20,7 @@ define([PACKAGE_SUFFIX], []) define([SOFTHSM_VERSION_CURRENT], [2]) define([SOFTHSM_VERSION_AGE], [1]) -define([SOFTHSM_VERSION_REVISION], [4]) +define([SOFTHSM_VERSION_REVISION], [5]) ################## # # @@ -44,6 +44,7 @@ AC_SUBST(VERSION_INFO) # Checks for compilers AC_PROG_CC AC_PROG_CXX +PKG_PROG_PKG_CONFIG # Compiler flags ACX_PEDANTIC @@ -219,6 +220,7 @@ AC_CONFIG_FILES([ src/bin/Makefile src/bin/common/Makefile src/bin/dump/Makefile + src/bin/keyconv/Makefile src/bin/migrate/Makefile src/bin/util/Makefile ]) diff --git a/SoftHSMv2/m4/acx_64bit.m4 b/SoftHSMv2/m4/acx_64bit.m4 index f610b21..4620184 100644 --- a/SoftHSMv2/m4/acx_64bit.m4 +++ b/SoftHSMv2/m4/acx_64bit.m4 @@ -7,23 +7,42 @@ AC_DEFUN([ACX_64BIT],[ if test "x$enable_64bit" = "xyes" then - AC_MSG_CHECKING(if we can compile in 64-bit mode) tmp_CFLAGS=$CFLAGS CFLAGS="-m64" - AC_RUN_IFELSE( - [ + AC_CACHE_CHECK([if we can compile in 64-bit mode], [acx_cv_prog_cc_64bit],[ + acx_cv_prog_cc_64bit=no + AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([],[return sizeof(void*) == 8 ? 0 : 1;]) ], [ - AC_MSG_RESULT(yes) - CXXFLAGS="-m64 $CXXFLAGS" - LDFLAGS="-m64 $LDFLAGS" - CFLAGS="-m64 $tmp_CFLAGS" - ],[ - AC_MSG_RESULT(no) - AC_MSG_ERROR([Don't know how to compile in 64-bit mode.]) - CFLAGS=$tmp_CFLAGS - ] - ) + acx_cv_prog_cc_64bit=yes + ]) + ]) + + if test "x$acx_cv_prog_cc_64bit" = xyes; then + AC_MSG_CHECKING([if we can run 64-bit programs]) + AC_CACHE_VAL([acx_cv_sys_64bit],[ + acx_cv_sys_64bit=no + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([],[return sizeof(void*) == 8 ? 0 : 1;]) + ], [ + AC_MSG_RESULT(yes) + acx_cv_sys_64bit=yes + ],[ + AC_MSG_RESULT(no) + AC_MSG_ERROR([Don't know how to compile in 64-bit mode.]) + CFLAGS=$tmp_CFLAGS + ],[ + AC_MSG_WARN([Cannot test, assuming 64-bit]) + acx_cv_sys_64bit=yes + ]) + ]) + + CXXFLAGS="-m64 $CXXFLAGS" + LDFLAGS="-m64 $LDFLAGS" + CFLAGS="-m64 $tmp_CFLAGS" + else + CFLAGS=$tmp_CFLAGS + fi fi ]) diff --git a/SoftHSMv2/m4/acx_botan.m4 b/SoftHSMv2/m4/acx_botan.m4 index ed93786..346a180 100644 --- a/SoftHSMv2/m4/acx_botan.m4 +++ b/SoftHSMv2/m4/acx_botan.m4 @@ -1,39 +1,64 @@ AC_DEFUN([ACX_BOTAN],[ + WITH_BOTAN= AC_ARG_WITH(botan, AC_HELP_STRING([--with-botan=PATH],[Specify prefix of path of Botan]), [ BOTAN_PATH="$withval" + WITH_BOTAN=1 ], [ BOTAN_PATH="/usr/local" ]) - BOTAN_VERSION_MAJOR=2 - BOTAN_VERSION_MINOR=0 - AC_CHECK_FILE($BOTAN_PATH/include/botan-2/botan/version.h, - BOTAN_VERSION_MAJOR=2 - BOTAN_VERSION_MINOR=0, - AC_CHECK_FILE($BOTAN_PATH/include/botan-1.11/botan/version.h, - BOTAN_VERSION_MAJOR=1 - BOTAN_VERSION_MINOR=11, - AC_CHECK_FILE($BOTAN_PATH/include/botan-1.10/botan/version.h, - BOTAN_VERSION_MAJOR=1 - BOTAN_VERSION_MINOR=10, - AC_MSG_ERROR([Cannot find Botan includes])))) - AC_MSG_CHECKING(what are the Botan includes) - if test "x${BOTAN_VERSION_MAJOR}" = "x2"; then - BOTAN_INCLUDES="-I$BOTAN_PATH/include/botan-2" + if test -n "${PKG_CONFIG}" && test -z "${WITH_BOTAN}"; then + PKG_CHECK_MODULES([BOTAN], [botan-2 >= $1.$2.$3], [ + BOTAN_VERSION_MAJOR=2 + BOTAN_VERSION_MINOR=0 + ],[ + PKG_CHECK_MODULES([BOTAN], [botan-1.11 >= $1.$2.$3], [ + BOTAN_VERSION_MAJOR=1 + BOTAN_VERSION_MINOR=11 + ],[ + PKG_CHECK_MODULES([BOTAN], [botan-1.10 >= $1.$2.$3], [ + BOTAN_VERSION_MAJOR=1 + BOTAN_VERSION_MINOR=10 + ],[ + AC_MSG_ERROR([Cannot find Botan]) + ]) + ]) + ]) else - BOTAN_INCLUDES="-I$BOTAN_PATH/include/botan-1.$BOTAN_VERSION_MINOR" + BOTAN_VERSION_MAJOR=2 + BOTAN_VERSION_MINOR=0 + if test -f "$BOTAN_PATH/include/botan-2/botan/version.h"; then + BOTAN_VERSION_MAJOR=2 + BOTAN_VERSION_MINOR=0 + elif test -f "$BOTAN_PATH/include/botan-1.11/botan/version.h"; then + BOTAN_VERSION_MAJOR=1 + BOTAN_VERSION_MINOR=11 + elif test -f "$BOTAN_PATH/include/botan-1.10/botan/version.h"; then + BOTAN_VERSION_MAJOR=1 + BOTAN_VERSION_MINOR=10 + else + AC_MSG_ERROR([Cannot find Botan includes]) + fi + + if test "x${BOTAN_VERSION_MAJOR}" = "x2"; then + BOTAN_CFLAGS="-I$BOTAN_PATH/include/botan-2" + BOTAN_LIBS="-L$BOTAN_PATH/lib -lbotan-2" + else + BOTAN_CFLAGS="-I$BOTAN_PATH/include/botan-1.$BOTAN_VERSION_MINOR" + BOTAN_LIBS="-L$BOTAN_PATH/lib -lbotan-1.$BOTAN_VERSION_MINOR" + fi + + AC_SUBST(BOTAN_CFLAGS) + AC_SUBST(BOTAN_LIBS) fi - AC_MSG_RESULT($BOTAN_INCLUDES) + + AC_MSG_CHECKING(what are the Botan includes) + AC_MSG_RESULT($BOTAN_CFLAGS) AC_MSG_CHECKING(what are the Botan libs) - if test "x${BOTAN_VERSION_MAJOR}" = "x2"; then - BOTAN_LIBS="-L$BOTAN_PATH/lib -lbotan-2" - else - BOTAN_LIBS="-L$BOTAN_PATH/lib -lbotan-1.$BOTAN_VERSION_MINOR" - fi AC_MSG_RESULT($BOTAN_LIBS) if test "x${BOTAN_VERSION_MAJOR}" != "x1" -o "x${BOTAN_VERSION_MINOR}" != "x10"; then @@ -43,7 +68,7 @@ AC_DEFUN([ACX_BOTAN],[ tmp_CPPFLAGS=$CPPFLAGS tmp_LIBS=$LIBS - CPPFLAGS="$CPPFLAGS $BOTAN_INCLUDES" + CPPFLAGS="$CPPFLAGS $BOTAN_CFLAGS" LIBS="$LIBS $BOTAN_LIBS" AC_LANG_PUSH([C++]) @@ -65,8 +90,6 @@ AC_DEFUN([ACX_BOTAN],[ CPPFLAGS=$tmp_CPPFLAGS LIBS=$tmp_LIBS - AC_SUBST(BOTAN_INCLUDES) - AC_SUBST(BOTAN_LIBS) AC_SUBST(BOTAN_VERSION_MAJOR) AC_SUBST(BOTAN_VERSION_MINOR) ]) diff --git a/SoftHSMv2/m4/acx_botan_aes_gcm.m4 b/SoftHSMv2/m4/acx_botan_aes_gcm.m4 index d52c9cb..4873e30 100644 --- a/SoftHSMv2/m4/acx_botan_aes_gcm.m4 +++ b/SoftHSMv2/m4/acx_botan_aes_gcm.m4 @@ -8,29 +8,35 @@ AC_DEFUN([ACX_BOTAN_AES_GCM],[ LIBS="$CRYPTO_LIBS $LIBS" AC_LANG_PUSH([C++]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <botan/botan.h> - #include <botan/version.h> - int main() - { - using namespace Botan; + AC_CACHE_VAL([acx_cv_lib_botan_aes_gcm_support],[ + acx_cv_lib_botan_aes_gcm_support=no + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([[ + #include <botan/botan.h> + #include <botan/version.h> + int main() + { + using namespace Botan; #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0) - return 0; + return 0; +#else +#error "Botan too old" #endif - return 1; - } - ]]) - ],[ - AC_MSG_RESULT([Found AES GCM]) - AC_DEFINE([WITH_AES_GCM], [1], - [Compile with AES GCM]) - ],[ - AC_MSG_RESULT([Cannot find AES GCM support, upgrade to Botan >= v2.0.0]) - + } + ]]) + ],[ + AC_MSG_RESULT([Found AES GCM]) + acx_cv_lib_botan_aes_gcm_support=yes + ],[ + AC_MSG_RESULT([Cannot find AES GCM support, upgrade to Botan >= v2.0.0]) + ]) ]) AC_LANG_POP([C++]) + if test "x$acx_cv_lib_botan_aes_gcm_support" = xyes; then + AC_DEFINE([WITH_AES_GCM], [1], + [Compile with AES GCM]) + fi CPPFLAGS=$tmp_CPPFLAGS LIBS=$tmp_LIBS diff --git a/SoftHSMv2/m4/acx_botan_ecc.m4 b/SoftHSMv2/m4/acx_botan_ecc.m4 index 9bce21d..1dd067e 100644 --- a/SoftHSMv2/m4/acx_botan_ecc.m4 +++ b/SoftHSMv2/m4/acx_botan_ecc.m4 @@ -8,42 +8,49 @@ AC_DEFUN([ACX_BOTAN_ECC],[ LIBS="$CRYPTO_LIBS $LIBS" AC_LANG_PUSH([C++]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <botan/init.h> - #include <botan/ec_group.h> - #include <botan/oids.h> - #include <botan/version.h> - int main() - { - Botan::LibraryInitializer::initialize(); - const std::string name("secp256r1"); - const Botan::OID oid(Botan::OIDS::lookup(name)); - const Botan::EC_Group ecg(oid); - try { + AC_CACHE_VAL([acx_cv_lib_botan_ecc_support],[ + acx_cv_lib_botan_ecc_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <botan/init.h> + #include <botan/ec_group.h> + #include <botan/oids.h> + #include <botan/version.h> + int main() + { + Botan::LibraryInitializer::initialize(); + const std::string name("secp256r1"); + const Botan::OID oid(Botan::OIDS::lookup(name)); + const Botan::EC_Group ecg(oid); + try { #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) - const std::vector<Botan::byte> der = - ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); + const std::vector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); #else - const Botan::SecureVector<Botan::byte> der = - ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); + const Botan::SecureVector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); #endif - } catch(...) { - return 1; + } catch(...) { + return 1; + } + return 0; } - return 0; - } - ]]) - ],[ - AC_MSG_RESULT([Found P256]) - ],[ - AC_MSG_RESULT([Cannot find P256]) - AC_MSG_ERROR([ + ]]) + ],[ + AC_MSG_RESULT([Found P256]) + acx_cv_lib_botan_ecc_support=yes + ],[ + AC_MSG_RESULT([Cannot find P256]) + AC_MSG_ERROR([ Botan library has no valid ECC support. Please upgrade to a later version of Botan, above or including version 1.10.6 or 1.11.5. Alternatively disable ECC support in SoftHSM with --disable-ecc ]) - ],[]) + ],[ + AC_MSG_WARN([Cannot test, assuming P256]) + acx_cv_lib_botan_ecc_support=yes + ]) + ]) AC_LANG_POP([C++]) CPPFLAGS=$tmp_CPPFLAGS diff --git a/SoftHSMv2/m4/acx_botan_eddsa.m4 b/SoftHSMv2/m4/acx_botan_eddsa.m4 new file mode 100644 index 0000000..88090b7 --- /dev/null +++ b/SoftHSMv2/m4/acx_botan_eddsa.m4 @@ -0,0 +1,49 @@ +AC_DEFUN([ACX_BOTAN_EDDSA],[ + AC_MSG_CHECKING(for Botan EDDSA support) + + tmp_CPPFLAGS=$CPPFLAGS + tmp_LIBS=$LIBS + + CPPFLAGS="$CPPFLAGS $CRYPTO_INCLUDES" + LIBS="$CRYPTO_LIBS $LIBS" + + AC_LANG_PUSH([C++]) + AC_CACHE_VAL([acx_cv_lib_botan_eddsa_support],[ + acx_cv_lib_botan_eddsa_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <botan/init.h> + #include <botan/ed25519.h> + #include <botan/version.h> + int main() + { + Botan::secure_vector<uint8_t> k(32); + try { + Botan::Ed25519_PrivateKey* key = + new Botan::Ed25519_PrivateKey(k); + } catch(...) { + return 1; + } + return 0; + } + ]]) + ],[ + AC_MSG_RESULT([Found Ed25519]) + acx_cv_lib_botan_eddsa_support=yes + ],[ + AC_MSG_RESULT([Cannot find Ed25519]) + AC_MSG_ERROR([ +Botan library has no valid EDDSA support. Please upgrade to a later version +of Botan with EDDSA support. +Alternatively disable EDDSA support in SoftHSM with --disable-eddsa +]) + ],[ + AC_MSG_WARN([Cannot test, assuming EDDSA]) + acx_cv_lib_botan_eddsa_support=yes + ]) + ]) + AC_LANG_POP([C++]) + + CPPFLAGS=$tmp_CPPFLAGS + LIBS=$tmp_LIBS +]) diff --git a/SoftHSMv2/m4/acx_botan_gnump.m4 b/SoftHSMv2/m4/acx_botan_gnump.m4 index d15859a..28272ab 100644 --- a/SoftHSMv2/m4/acx_botan_gnump.m4 +++ b/SoftHSMv2/m4/acx_botan_gnump.m4 @@ -2,7 +2,7 @@ AC_DEFUN([ACX_BOTAN_GNUMP],[ tmp_CPPFLAGS=$CPPFLAGS tmp_LIBS=$LIBS - CPPFLAGS="$CPPFLAGS $BOTAN_INCLUDES" + CPPFLAGS="$CPPFLAGS $BOTAN_CFLAGS" LIBS="$LIBS $BOTAN_LIBS" AC_LANG_PUSH([C++]) diff --git a/SoftHSMv2/m4/acx_botan_gost.m4 b/SoftHSMv2/m4/acx_botan_gost.m4 index 3720f4a..ba4c334 100644 --- a/SoftHSMv2/m4/acx_botan_gost.m4 +++ b/SoftHSMv2/m4/acx_botan_gost.m4 @@ -8,43 +8,50 @@ AC_DEFUN([ACX_BOTAN_GOST],[ LIBS="$CRYPTO_LIBS $LIBS" AC_LANG_PUSH([C++]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <botan/init.h> - #include <botan/gost_3410.h> - #include <botan/oids.h> - #include <botan/version.h> - int main() - { - Botan::LibraryInitializer::initialize(); - const std::string name("gost_256A"); - const Botan::OID oid(Botan::OIDS::lookup(name)); - const Botan::EC_Group ecg(oid); - try { + AC_CACHE_VAL([acx_cv_lib_botan_gost_support],[ + acx_cv_lib_botan_gost_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <botan/init.h> + #include <botan/gost_3410.h> + #include <botan/oids.h> + #include <botan/version.h> + int main() + { + Botan::LibraryInitializer::initialize(); + const std::string name("gost_256A"); + const Botan::OID oid(Botan::OIDS::lookup(name)); + const Botan::EC_Group ecg(oid); + try { #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) - const std::vector<Botan::byte> der = - ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); + const std::vector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); #else - const Botan::SecureVector<Botan::byte> der = - ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); + const Botan::SecureVector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); #endif - } catch(...) { - return 1; - } + } catch(...) { + return 1; + } - return 0; - } - ]]) - ],[ - AC_MSG_RESULT([Found GOST]) - ],[ - AC_MSG_RESULT([Cannot find GOST]) - AC_MSG_ERROR([ + return 0; + } + ]]) + ],[ + AC_MSG_RESULT([Found GOST]) + acx_cv_lib_botan_gost_support=yes + ],[ + AC_MSG_RESULT([Cannot find GOST]) + AC_MSG_ERROR([ Botan library has no valid GOST support. Please upgrade to a later version of Botan, above or including version 1.10.6 or 1.11.5. Alternatively disable GOST support in SoftHSM with --disable-gost ]) - ],[]) + ],[ + AC_MSG_WARN([Cannot test, assuming GOST]) + acx_cv_lib_botan_gost_support=yes + ]) + ]) AC_LANG_POP([C++]) CPPFLAGS=$tmp_CPPFLAGS diff --git a/SoftHSMv2/m4/acx_botan_rawpss.m4 b/SoftHSMv2/m4/acx_botan_rawpss.m4 index 018e324..92b56ff 100644 --- a/SoftHSMv2/m4/acx_botan_rawpss.m4 +++ b/SoftHSMv2/m4/acx_botan_rawpss.m4 @@ -8,29 +8,35 @@ AC_DEFUN([ACX_BOTAN_RAWPSS],[ LIBS="$CRYPTO_LIBS $LIBS" AC_LANG_PUSH([C++]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <botan/botan.h> - #include <botan/version.h> - int main() - { - using namespace Botan; + AC_CACHE_VAL([acx_cv_lib_botan_raw_pss_support],[ + acx_cv_lib_botan_raw_pss_support=no + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([[ + #include <botan/botan.h> + #include <botan/version.h> + int main() + { + using namespace Botan; #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,3,0) - return 0; + return 0; +#else +#error "Botan too old" #endif - return 1; - } - ]]) - ],[ - AC_MSG_RESULT([Found raw PSS]) - AC_DEFINE([WITH_RAW_PSS], [1], - [Compile with raw RSA PKCS PSS]) - ],[ - AC_MSG_RESULT([Cannot find raw PSS support, upgrade to Botan >= v2.3.0]) - + } + ]]) + ],[ + AC_MSG_RESULT([Found raw PSS]) + acx_cv_lib_botan_raw_pss_support=yes + ],[ + AC_MSG_RESULT([Cannot find raw PSS support, upgrade to Botan >= v2.3.0]) + ]) ]) AC_LANG_POP([C++]) + if test "x$acx_cv_lib_botan_raw_pss_support" = xyes; then + AC_DEFINE([WITH_RAW_PSS], [1], + [Compile with raw RSA PKCS PSS]) + fi CPPFLAGS=$tmp_CPPFLAGS LIBS=$tmp_LIBS diff --git a/SoftHSMv2/m4/acx_cppunit.m4 b/SoftHSMv2/m4/acx_cppunit.m4 index 2720d81..1e04244 100644 --- a/SoftHSMv2/m4/acx_cppunit.m4 +++ b/SoftHSMv2/m4/acx_cppunit.m4 @@ -1,21 +1,15 @@ AC_DEFUN([ACX_CPPUNIT],[ AC_PATH_PROG([CPPUNIT_CONFIG], [cppunit-config]) - AC_PATH_PROG([PKG_CONFIG], [pkg-config]) - if test -n "${CPPUNIT_CONFIG}"; then + if test -n "${PKG_CONFIG}"; then + PKG_CHECK_MODULES([CPPUNIT], [cppunit], [], [:]) + elif test -n "${CPPUNIT_CONFIG}"; then AC_MSG_CHECKING([cppunit cflags]) CPPUNIT_CFLAGS=`${CPPUNIT_CONFIG} --cflags` AC_MSG_RESULT([${CPPUNIT_CFLAGS}]) AC_MSG_CHECKING([cppunit libs]) CPPUNIT_LIBS=`${CPPUNIT_CONFIG} --libs` AC_MSG_RESULT([${CPPUNIT_LIBS}]) - elif test -n "${PKG_CONFIG}"; then - AC_MSG_CHECKING([cppunit cflags]) - CPPUNIT_CFLAGS=`${PKG_CONFIG} cppunit --cflags` - AC_MSG_RESULT([${CPPUNIT_CFLAGS}]) - AC_MSG_CHECKING([cppunit libs]) - CPPUNIT_LIBS=`${PKG_CONFIG} cppunit --libs` - AC_MSG_RESULT([${CPPUNIT_LIBS}]) + AC_SUBST([CPPUNIT_CFLAGS]) + AC_SUBST([CPPUNIT_LIBS]) fi - AC_SUBST([CPPUNIT_CFLAGS]) - AC_SUBST([CPPUNIT_LIBS]) ]) diff --git a/SoftHSMv2/m4/acx_crypto_backend.m4 b/SoftHSMv2/m4/acx_crypto_backend.m4 index c860c89..f815bcd 100644 --- a/SoftHSMv2/m4/acx_crypto_backend.m4 +++ b/SoftHSMv2/m4/acx_crypto_backend.m4 @@ -42,6 +42,28 @@ AC_DEFUN([ACX_CRYPTO_BACKEND],[ fi AM_CONDITIONAL([WITH_GOST], [test "x${enable_gost}" = "xyes"]) + # Add Eddsa check + + AC_ARG_ENABLE(eddsa, + AC_HELP_STRING([--enable-eddsa], + [Enable support for EDDSA (default disabled)] + ), + [enable_eddsa="${enableval}"], + [enable_eddsa="no"] + ) + AC_MSG_CHECKING(for EDDSA support) + if test "x${enable_eddsa}" = "xyes"; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED( + [WITH_EDDSA], + [], + [Compile with EDDSA support] + ) + else + AC_MSG_RESULT(no) + fi + AM_CONDITIONAL([WITH_EDDSA], [test "x${enable_eddsa}" = "xyes"]) + # Second check for the FIPS 140-2 mode AC_ARG_ENABLE(fips, @@ -92,6 +114,10 @@ AC_DEFUN([ACX_CRYPTO_BACKEND],[ ACX_OPENSSL_ECC fi + if test "x${enable_eddsa}" = "xyes"; then + ACX_OPENSSL_EDDSA + fi + if test "x${enable_gost}" = "xyes"; then if test "x${enable_fips}" = "xyes"; then AC_MSG_ERROR([GOST is not FIPS approved]) @@ -126,13 +152,17 @@ AC_DEFUN([ACX_CRYPTO_BACKEND],[ ACX_BOTAN(1,10,0) - CRYPTO_INCLUDES=$BOTAN_INCLUDES + CRYPTO_INCLUDES=$BOTAN_CFLAGS CRYPTO_LIBS=$BOTAN_LIBS if test "x${enable_ecc}" = "xyes"; then ACX_BOTAN_ECC fi + if test "x${enable_eddsa}" = "xyes"; then + ACX_BOTAN_EDDSA + fi + if test "x${enable_fips}" = "xyes"; then AC_MSG_ERROR([Botan does not support FIPS 140-2 mode]) fi diff --git a/SoftHSMv2/m4/acx_openssl.m4 b/SoftHSMv2/m4/acx_openssl.m4 index e90c78f..2f1adad 100644 --- a/SoftHSMv2/m4/acx_openssl.m4 +++ b/SoftHSMv2/m4/acx_openssl.m4 @@ -2,18 +2,19 @@ AC_DEFUN([ACX_OPENSSL],[ AC_ARG_WITH(openssl, AC_HELP_STRING([--with-openssl=PATH],[Specify prefix of path of OpenSSL]), [ - OPENSSL_PATH="$withval" + OPENSSL_INCLUDES="-I$withval/include" + OPENSSL_LIBDIRS="-L$withval/lib" ], [ - OPENSSL_PATH="/usr/local" + OPENSSL_INCLUDES="" + OPENSSL_LIBDIRS="" ]) AC_MSG_CHECKING(what are the OpenSSL includes) - OPENSSL_INCLUDES="-I$OPENSSL_PATH/include" AC_MSG_RESULT($OPENSSL_INCLUDES) AC_MSG_CHECKING(what are the OpenSSL libs) - OPENSSL_LIBS="-L$OPENSSL_PATH/lib -lcrypto" + OPENSSL_LIBS="$OPENSSL_LIBDIRS -lcrypto" AC_MSG_RESULT($OPENSSL_LIBS) tmp_CPPFLAGS=$CPPFLAGS @@ -28,28 +29,32 @@ AC_DEFUN([ACX_OPENSSL],[ AC_MSG_CHECKING([for OpenSSL version]) CHECK_OPENSSL_VERSION=m4_format(0x%02x%02x%02x000L, $1, $2, $3) AC_LANG_PUSH([C]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <openssl/ssl.h> - #include <openssl/opensslv.h> - int main() - { - #ifndef OPENSSL_VERSION_NUMBER - return -1; - #endif - #if OPENSSL_VERSION_NUMBER >= $CHECK_OPENSSL_VERSION - return 0; - #else - return 1; - #endif - } - ]]) - ],[ - AC_MSG_RESULT([>= $1.$2.$3]) - ],[ - AC_MSG_RESULT([< $1.$2.$3]) - AC_MSG_ERROR([OpenSSL library too old ($1.$2.$3 or later required)]) - ],[]) + AC_CACHE_VAL([acx_cv_lib_openssl_sufficient],[ + acx_cv_lib_openssl_sufficient=no + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([[ + #include <openssl/ssl.h> + #include <openssl/opensslv.h> + int main() + { + #ifndef OPENSSL_VERSION_NUMBER + #error "OpenSSL version undefined" + #endif + #if OPENSSL_VERSION_NUMBER >= $CHECK_OPENSSL_VERSION + return 0; + #else + #error "OpenSSL too old" + #endif + } + ]]) + ],[ + AC_MSG_RESULT([>= $1.$2.$3]) + acx_cv_lib_openssl_sufficient=yes + ],[ + AC_MSG_RESULT([< $1.$2.$3]) + AC_MSG_ERROR([OpenSSL library too old ($1.$2.$3 or later required)]) + ]) + ]) AC_LANG_POP([C]) CPPFLAGS=$tmp_CPPFLAGS diff --git a/SoftHSMv2/m4/acx_openssl_ecc.m4 b/SoftHSMv2/m4/acx_openssl_ecc.m4 index 612c505..3ecf7a9 100644 --- a/SoftHSMv2/m4/acx_openssl_ecc.m4 +++ b/SoftHSMv2/m4/acx_openssl_ecc.m4 @@ -8,28 +8,35 @@ AC_DEFUN([ACX_OPENSSL_ECC],[ LIBS="$CRYPTO_LIBS $LIBS" AC_LANG_PUSH([C]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <openssl/ecdsa.h> - #include <openssl/objects.h> - int main() - { - EC_KEY *ec256, *ec384, *ec521; + AC_CACHE_VAL([acx_cv_lib_openssl_ecc_support],[ + acx_cv_lib_openssl_ecc_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <openssl/ecdsa.h> + #include <openssl/objects.h> + int main() + { + EC_KEY *ec256, *ec384, *ec521; - ec256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - ec384 = EC_KEY_new_by_curve_name(NID_secp384r1); - ec521 = EC_KEY_new_by_curve_name(NID_secp521r1); - if (ec256 == NULL || ec384 == NULL || ec521 == NULL) - return 1; - return 0; - } - ]]) - ],[ - AC_MSG_RESULT([Found P256, P384, and P521]) - ],[ - AC_MSG_RESULT([Cannot find P256, P384, or P521]) - AC_MSG_ERROR([OpenSSL library has no ECC support]) - ],[]) + ec256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + ec384 = EC_KEY_new_by_curve_name(NID_secp384r1); + ec521 = EC_KEY_new_by_curve_name(NID_secp521r1); + if (ec256 == NULL || ec384 == NULL || ec521 == NULL) + return 1; + return 0; + } + ]]) + ],[ + AC_MSG_RESULT([Found P256, P384, and P521]) + acx_cv_lib_openssl_ecc_support=yes + ],[ + AC_MSG_RESULT([Cannot find P256, P384, or P521]) + AC_MSG_ERROR([OpenSSL library has no ECC support]) + ],[ + AC_MSG_WARN([Cannot test, assuming P256, P384, and P521]) + acx_cv_lib_openssl_ecc_support=yes + ]) + ]) AC_LANG_POP([C]) CPPFLAGS=$tmp_CPPFLAGS diff --git a/SoftHSMv2/m4/acx_openssl_eddsa.m4 b/SoftHSMv2/m4/acx_openssl_eddsa.m4 new file mode 100644 index 0000000..0b629e2 --- /dev/null +++ b/SoftHSMv2/m4/acx_openssl_eddsa.m4 @@ -0,0 +1,68 @@ +AC_DEFUN([ACX_OPENSSL_EDDSA],[ + AC_MSG_CHECKING(for OpenSSL EDDSA support) + + tmp_CPPFLAGS=$CPPFLAGS + tmp_LIBS=$LIBS + + CPPFLAGS="$CPPFLAGS $CRYPTO_INCLUDES" + LIBS="$CRYPTO_LIBS $LIBS" + + AC_LANG_PUSH([C]) + AC_CACHE_VAL([acx_cv_lib_openssl_ed25519_support],[ + acx_cv_lib_openssl_ed25519_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <openssl/evp.h> + #include <openssl/objects.h> + int main() + { + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL); + if (ctx == NULL) + return 1; + return 0; + } + ]]) + ],[ + AC_MSG_RESULT([Found ED25519]) + acx_cv_lib_openssl_ed25519_support=yes + ],[ + AC_MSG_RESULT([Cannot find ED25519]) + AC_MSG_ERROR([OpenSSL library has no EDDSA support]) + ],[ + AC_MSG_WARN([Cannot test, ED25519]) + acx_cv_lib_openssl_ed25519_support=yes + ]) + ]) + AC_CACHE_VAL([acx_cv_lib_openssl_ed448_support],[ + acx_cv_lib_openssl_ed448_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <openssl/evp.h> + #include <openssl/objects.h> + int main() + { + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL); + if (ctx == NULL) + return 1; + return 0; + } + ]]) + ],[ + AC_MSG_RESULT([Found ED448]) + acx_cv_lib_openssl_ed448_support=yes + ],[ + AC_MSG_RESULT([Cannot find ED448]) + ],[ + AC_MSG_WARN([Cannot test, ED448]) + acx_cv_lib_openssl_ed448_support=yes + ]) + ]) + AC_LANG_POP([C]) + + CPPFLAGS=$tmp_CPPFLAGS + LIBS=$tmp_LIBS +]) diff --git a/SoftHSMv2/m4/acx_openssl_fips.m4 b/SoftHSMv2/m4/acx_openssl_fips.m4 index 0491397..a55c209 100644 --- a/SoftHSMv2/m4/acx_openssl_fips.m4 +++ b/SoftHSMv2/m4/acx_openssl_fips.m4 @@ -11,20 +11,27 @@ AC_DEFUN([ACX_OPENSSL_FIPS],[ # "reference the OpenSSL FIPS object module" AC_LANG_PUSH([C]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <openssl/crypto.h> - int main() - { - return !FIPS_mode_set(1); - } - ]]) - ],[ - AC_MSG_RESULT([Found working FIPS_mode_set()]) - ],[ - AC_MSG_RESULT([FIPS_mode_set(1) failed]) - AC_MSG_ERROR([OpenSSL library is not FIPS capable]) - ],[]) + AC_CACHE_VAL([acx_cv_lib_openssl_fips],[ + acx_cv_lib_openssl_fips=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <openssl/crypto.h> + int main() + { + return !FIPS_mode_set(1); + } + ]]) + ],[ + AC_MSG_RESULT([Found working FIPS_mode_set()]) + acx_cv_lib_openssl_fips=yes + ],[ + AC_MSG_RESULT([FIPS_mode_set(1) failed]) + AC_MSG_ERROR([OpenSSL library is not FIPS capable]) + ],[ + AC_MSG_WARN([Cannot test, assuming FIPS]) + acx_cv_lib_openssl_fips=yes + ]) + ]) AC_LANG_POP([C]) # build missing fips_premain_dso tool diff --git a/SoftHSMv2/m4/acx_openssl_gost.m4 b/SoftHSMv2/m4/acx_openssl_gost.m4 index dca489b..7deaacb 100644 --- a/SoftHSMv2/m4/acx_openssl_gost.m4 +++ b/SoftHSMv2/m4/acx_openssl_gost.m4 @@ -8,56 +8,63 @@ AC_DEFUN([ACX_OPENSSL_GOST],[ LIBS="$CRYPTO_LIBS $LIBS" AC_LANG_PUSH([C]) - AC_RUN_IFELSE([ - AC_LANG_SOURCE([[ - #include <openssl/engine.h> - #include <openssl/crypto.h> - #include <openssl/opensslv.h> - int main() - { - ENGINE* eg; - const EVP_MD* EVP_GOST_34_11; + AC_CACHE_VAL([acx_cv_lib_openssl_gost_support],[ + acx_cv_lib_openssl_gost_support=no + AC_RUN_IFELSE([ + AC_LANG_SOURCE([[ + #include <openssl/engine.h> + #include <openssl/crypto.h> + #include <openssl/opensslv.h> + int main() + { + ENGINE* eg; + const EVP_MD* EVP_GOST_34_11; - /* Initialise OpenSSL */ - OpenSSL_add_all_algorithms(); + /* Initialise OpenSSL */ + OpenSSL_add_all_algorithms(); - /* Load engines */ - #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) - ENGINE_load_builtin_engines(); - #else - OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | OPENSSL_INIT_LOAD_CONFIG, NULL); - #endif + /* Load engines */ + #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + ENGINE_load_builtin_engines(); + #else + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | OPENSSL_INIT_LOAD_CONFIG, NULL); + #endif - /* Initialise the GOST engine */ - eg = ENGINE_by_id("gost"); - if (eg == NULL) - return 1; - if (ENGINE_init(eg) <= 0) - return 1; + /* Initialise the GOST engine */ + eg = ENGINE_by_id("gost"); + if (eg == NULL) + return 1; + if (ENGINE_init(eg) <= 0) + return 1; - /* better than digest_gost */ - EVP_GOST_34_11 = ENGINE_get_digest(eg, NID_id_GostR3411_94); - if (EVP_GOST_34_11 == NULL) - return 1; + /* better than digest_gost */ + EVP_GOST_34_11 = ENGINE_get_digest(eg, NID_id_GostR3411_94); + if (EVP_GOST_34_11 == NULL) + return 1; - /* from the openssl.cnf */ - if (ENGINE_register_pkey_asn1_meths(eg) <= 0) - return 1; - if (ENGINE_ctrl_cmd_string(eg, - "CRYPT_PARAMS", - "id-Gost28147-89-CryptoPro-A-ParamSet", - 0) <= 0) - return 1; + /* from the openssl.cnf */ + if (ENGINE_register_pkey_asn1_meths(eg) <= 0) + return 1; + if (ENGINE_ctrl_cmd_string(eg, + "CRYPT_PARAMS", + "id-Gost28147-89-CryptoPro-A-ParamSet", + 0) <= 0) + return 1; - return 0; - } - ]]) - ],[ - AC_MSG_RESULT([Found GOST engine]) - ],[ - AC_MSG_RESULT([Cannot find GOST engine]) - AC_MSG_ERROR([OpenSSL library has no GOST support]) - ],[]) + return 0; + } + ]]) + ],[ + AC_MSG_RESULT([Found GOST engine]) + acx_cv_lib_openssl_gost_support=yes + ],[ + AC_MSG_RESULT([Cannot find GOST engine]) + AC_MSG_ERROR([OpenSSL library has no GOST support]) + ],[ + AC_MSG_WARN([Cannot test, assuming GOST engine]) + acx_cv_lib_openssl_gost_support=yes + ]) + ]) AC_LANG_POP([C]) CPPFLAGS=$tmp_CPPFLAGS diff --git a/SoftHSMv2/m4/acx_p11kit.m4 b/SoftHSMv2/m4/acx_p11kit.m4 index 20c7b7e..9545e7e 100644 --- a/SoftHSMv2/m4/acx_p11kit.m4 +++ b/SoftHSMv2/m4/acx_p11kit.m4 @@ -17,9 +17,8 @@ AC_DEFUN([ACX_P11KIT],[ if test "x${enable_p11kit}" = "xyes"; then AC_MSG_RESULT(yes) if test "x${P11KIT_PATH}" = "x"; then - AC_PATH_PROG(PKGCONFIG, [pkg-config]) - if test "x${PKGCONFIG}" != "x" && ${PKGCONFIG} --exists p11-kit-1; then - P11KIT_PATH=`${PKGCONFIG} --variable=p11_module_configs p11-kit-1` + if test "x${PKG_CONFIG}" != "x" && ${PKG_CONFIG} --exists p11-kit-1; then + P11KIT_PATH=`${PKG_CONFIG} --variable=p11_module_configs p11-kit-1` fi fi AC_MSG_CHECKING(where to install the p11-kit module) diff --git a/SoftHSMv2/m4/acx_sqlite3.m4 b/SoftHSMv2/m4/acx_sqlite3.m4 index cf829b7..fd942a7 100644 --- a/SoftHSMv2/m4/acx_sqlite3.m4 +++ b/SoftHSMv2/m4/acx_sqlite3.m4 @@ -2,11 +2,13 @@ AC_DEFUN([ACX_SQLITE3],[ AC_ARG_WITH(sqlite3, AC_HELP_STRING([--with-sqlite3=PATH],[Specify prefix of path of SQLite3]), [ - SQLITE3_PATH="$withval" + SQLITE3_INCLUDES="-I$withval/include" + SQLITE3_LIBDIRS="-L$withval/lib" AC_PATH_PROGS(SQLITE3, sqlite3, sqlite3, $withval/bin) ],[ - SQLITE3_PATH="/usr/local" + SQLITE3_INCLUDES="" + SQLITE3_LIBDIRS="" AC_PATH_PROGS(SQLITE3, sqlite3, sqlite3, $PATH) ]) @@ -16,11 +18,10 @@ AC_DEFUN([ACX_SQLITE3],[ fi AC_MSG_CHECKING(what are the SQLite3 includes) - SQLITE3_INCLUDES="-I$SQLITE3_PATH/include" AC_MSG_RESULT($SQLITE3_INCLUDES) AC_MSG_CHECKING(what are the SQLite3 libs) - SQLITE3_LIBS="-L$SQLITE3_PATH/lib -lsqlite3" + SQLITE3_LIBS="$SQLITE3_LIBDIRS -lsqlite3" AC_MSG_RESULT($SQLITE3_LIBS) tmp_CPPFLAGS=$CPPFLAGS diff --git a/SoftHSMv2/modules/CompilerOptions.cmake b/SoftHSMv2/modules/CompilerOptions.cmake new file mode 100644 index 0000000..29a0ae5 --- /dev/null +++ b/SoftHSMv2/modules/CompilerOptions.cmake @@ -0,0 +1,506 @@ +include(CheckCXXCompilerFlag) +include(CheckFunctionExists) +include(CheckIncludeFiles) +include(CheckLibraryExists) +include(CheckSymbolExists) +include(CheckTypeSize) + +function(enable_cxx_compiler_flag_if_supported flag) + string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set) + if(flag_already_set EQUAL -1) + check_cxx_compiler_flag("${flag}" flag_supported) + if(flag_supported) + add_compile_options(${flag}) + elseif(flag_supported) + message(WARNING "unsupported compiler flag: ${flag}") + endif(flag_supported) + unset(flag_supported CACHE) + endif() +endfunction() + +# Configures C++11 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(HAVE_CXX11 1) + +if(ENABLE_PEDANTIC) + enable_cxx_compiler_flag_if_supported(-pedantic) + set(ENABLE_STRICT ON) +endif(ENABLE_PEDANTIC) + +if(ENABLE_STRICT) + set(CMAKE_CXX_EXTENSIONS OFF) +endif(ENABLE_STRICT) + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# Compiler Options/Macros + +# FIXME: These options need to be set on a per object file basis (*.o). Do not belong here. +# Are these even required? They just modify the Makefile representation of the target. +#add_compile_options(-MD) +#add_compile_options(-MP) +#add_compile_options(-MF) +#add_compile_options(-MT) + +# FIXME: [Implement AC_HEADER_STDC]: +# Find a CMake mechanism performs the check as defined in +# AC_HEADER_STDC: +# https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Particular-Headers.html +# +# Not sure if this is a legacy check, or it's something that we need to +# continue to check with modern compiler versions. +set(STDC_HEADERS 1) + +# acx_strict.m4 +if(ENABLE_STRICT) + enable_cxx_compiler_flag_if_supported(-Wall) + enable_cxx_compiler_flag_if_supported(-Wextra) +endif(ENABLE_STRICT) + +# acx_64bit.m4 +if(ENABLE_64BIT) + if(CMAKE_SIZEOF_VOID_P STREQUAL "8") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64") + else(CMAKE_SIZEOF_VOID_P STREQUAL "8") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") + endif(CMAKE_SIZEOF_VOID_P STREQUAL "8") +endif(ENABLE_64BIT) + +# Equivalent of acx_visibility.m4 +if(DISABLE_VISIBILITY) + message(STATUS "-fvisibility=hidden has been disabled") +else(DISABLE_VISIBILITY) + set(CRYPTOKI_VISIBILITY 1) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) +endif(DISABLE_VISIBILITY) + +# acx_non_paged_memory.m4 +if(DISABLE_NON_PAGED_MEMORY) + message(STATUS "non-paged-memory disabled") +else(DISABLE_NON_PAGED_MEMORY) + set(SENSITIVE_NON_PAGE 1) + check_include_files(sys/mman.h HAVE_SYS_MMAN_H) + execute_process(COMMAND bash -c "ulimit -l" + OUTPUT_VARIABLE MLOCK_SIZE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT "${MLOCK_SIZE}" STREQUAL "unlimited") + message(WARNING "\ + ====================================================================== + SoftHSM has been configured to store sensitive data in non-page RAM + (i.e. memory that is not swapped out to disk). This is the default and + most secure configuration. Your system, however, is not configured to + support this model in non-privileged accounts (i.e. user accounts). + + You can check the setting on your system by running the following + command in a shell: + + ulimit -l + + If this does not return \"unlimited\" and you plan to run SoftHSM from + non-privileged accounts then you should edit the configuration file + /etc/security/limits.conf (on most systems). + + You will need to add the following lines to this file: + + #<domain> <type> <item> <value> + * - memlock unlimited + + Alternatively, you can elect to disable this feature of SoftHSM by + re-running cmake with the option \"-DDISABLE_NON_PAGED_MEMORY=ON\". + Please be advised that this may seriously degrade the security of + SoftHSM. + ======================================================================") + endif(NOT "${MLOCK_SIZE}" STREQUAL "unlimited") +endif(DISABLE_NON_PAGED_MEMORY) + +# Check if -ldl exists (equivalent of acx_dlopen.m4) +check_library_exists(dl dlopen "" HAVE_DLOPEN) +check_function_exists(LoadLibrary HAVE_LOADLIBRARY) + +# acx_libtool.m4 +check_include_files(dlfcn.h HAVE_DLFCN_H) + +# configure: + +# STDC_HEADERS +check_include_files(sys/types.h HAVE_SYS_TYPES_H) +check_include_files(sys/stat.h HAVE_SYS_STAT_H) +check_include_files(stdlib.h HAVE_STDLIB_H) +check_include_files(stddef.h HAVE_STDDEF_H) +check_include_files(string.h HAVE_STRING_H) +check_include_files(strings.h HAVE_STRINGS_H) +check_include_files(inttypes.h HAVE_INTTYPES_H) +check_include_files(stdint.h HAVE_STDINT_H) +check_include_files(unistd.h HAVE_UNISTD_H) + +check_include_files(memory.h HAVE_MEMORY_H) +check_include_files(pthread.h HAVE_PTHREAD_H) +check_function_exists(getpwuid_r HAVE_GETPWUID_R) + +# Find Botan Crypto Backend +if(WITH_CRYPTO_BACKEND STREQUAL "botan") + set(WITH_BOTAN 1) + + include(FindBotan) + if(NOT BOTAN_FOUND) + message(FATAL_ERROR "Failed to find Botan!") + endif() + + set(CRYPTO_INCLUDES ${BOTAN_INCLUDE_DIRS}) + set(CRYPTO_LIBS ${BOTAN_LIBRARIES}) + message(STATUS "Botan: Includes: ${CRYPTO_INCLUDES}") + message(STATUS "Botan: Libs: ${CRYPTO_LIBS}") + + # CXX11 flag is not added to try_run, so set it locally. + CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) + CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) + set(TMP_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + elseif(COMPILER_SUPPORTS_CXX0X) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + endif() + + # acx_botan_ecc.m4 + if(ENABLE_ECC) + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_botan_ecc.cpp) + try_run(RUN_ECC COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_ECC EQUAL 0) + set(WITH_ECC 1) + message(STATUS "Botan: Found P-256") + else() + set(error_msg "Botan: Cannot find P-256! Botan library has no ECC support!") + message(FATAL_ERROR ${error_msg}) + endif() + else(ENABLE_ECC) + message(STATUS "Botan: Support for ECC is disabled") + endif(ENABLE_ECC) + + # acx_botan_eddsa.m4 + if(ENABLE_EDDSA) + # ED25519 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_botan_ed25519.cpp) + try_run(RUN_ED25519 COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_ED25519 EQUAL 0) + set(WITH_EDDSA 1) + message(STATUS "Botan: Found ED25519") + else() + set(error_msg "Botan: Cannot find ED25519! Botan library has no EDDSA support!") + message(FATAL_ERROR ${error_msg}) + endif() + else(ENABLE_EDDSA) + message(STATUS "Botan: Support for EDDSA is disabled") + endif(ENABLE_EDDSA) + + # acx_botan_gost.m4 + if(ENABLE_GOST) + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_botan_gost.cpp) + try_run(RUN_GOST COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_GOST EQUAL 0) + set(WITH_GOST 1) + message(STATUS "Botan: Found GOST") + else() + set(error_msg "Botan: Cannot find GOST! Botan library has no GOST support!") + message(FATAL_ERROR ${error_msg}) + endif() + else(ENABLE_GOST) + message(STATUS "Botan: Support for GOST is disabled") + endif(ENABLE_GOST) + + if(ENABLE_FIPS) + message(FATAL_ERROR "Botan does not support FIPS 140-2 mode") + endif(ENABLE_FIPS) + + # Compile with AES KEY WRAP + set(HAVE_AES_KEY_WRAP 1) + + # acx_botan_rfc5649.m4 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_botan_rfc5649.cpp) + try_run(RUN_AES_KEY_WRAP_PAD COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_AES_KEY_WRAP_PAD EQUAL 0) + set(HAVE_AES_KEY_WRAP_PAD 1) + message(STATUS "Botan: RFC 5649 is supported") + else() + message(STATUS "Botan: RFC 5649 is not supported") + endif() + + # acx_botan_rawpss.m4 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_botan_rawpss.cpp) + try_run(RUN_RAWPSS COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_RAWPSS EQUAL 0) + set(WITH_RAW_PSS 1) + message(STATUS "Botan: Found raw PSS") + else() + message(STATUS "Botan: Cannot find raw PSS support, upgrade to Botan >= v2.3.0") + endif() + + # acx_botan_aes_gcm.m4 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_botan_aes_gcm.cpp) + try_run(RUN_AESGCM COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_AESGCM EQUAL 0) + set(WITH_AES_GCM 1) + message(STATUS "Botan: Found AES GCM") + else() + message(STATUS "Botan: Cannot find AES GCM support, upgrade to Botan >= v2.0.0") + endif() + + # Restore flags + set(CMAKE_CXX_FLAGS ${TMP_CXX_FLAGS}) + +# Find OpenSSL Crypto Backend +elseif(WITH_CRYPTO_BACKEND STREQUAL "openssl") + set(WITH_OPENSSL 1) + + include(FindOpenSSL) + if(NOT OPENSSL_FOUND) + message(FATAL_ERROR "Failed to find OpenSSL!") + endif() + + set(CRYPTO_INCLUDES ${OPENSSL_INCLUDE_DIR}) + set(CRYPTO_LIBS ${OPENSSL_LIBRARIES}) + message(STATUS "OpenSSL: Found version ${OPENSSL_VERSION}") + message(STATUS "OpenSSL: Includes: ${CRYPTO_INCLUDES}") + message(STATUS "OpenSSL: Libs: ${CRYPTO_LIBS}") + + check_include_files(openssl/ssl.h HAVE_OPENSSL_SSL_H) + get_filename_component(CRYPTO_LIB_DIR "${OPENSSL_CRYPTO_LIBRARY}" DIRECTORY) + check_library_exists(crypto "BN_new" "${CRYPTO_LIB_DIR}" HAVE_LIBCRYPTO) + + # acx_openssl_ecc.m4 + if(ENABLE_ECC) + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_ecc.c) + try_run(RUN_ECC COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_ECC EQUAL 0) + set(WITH_ECC 1) + message(STATUS "OpenSSL: Found P-256, P-384, and P-521") + else() + set(error_msg "OpenSSL: Cannot find P-256, P-384, or P-521! OpenSSL library has no ECC support!") + message(FATAL_ERROR ${error_msg}) + endif() + else(ENABLE_ECC) + message(STATUS "OpenSSL: Support for ECC is disabled") + endif(ENABLE_ECC) + + # acx_openssl_eddsa.m4 + if(ENABLE_EDDSA) + # ED25519 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_ed25519.c) + try_run(RUN_ED25519 COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_ED25519 EQUAL 0) + set(WITH_EDDSA 1) + message(STATUS "OpenSSL: Found ED25519") + else() + set(error_msg "OpenSSL: Cannot find ED25519! OpenSSL library has no EDDSA support!") + message(FATAL_ERROR ${error_msg}) + endif() + # ED448 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_ed448.c) + try_run(RUN_ED448 COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_ED448 EQUAL 0) + message(STATUS "OpenSSL: Found ED448") + else() + # Not used in SoftHSM + message(STATUS "OpenSSL: Cannot find ED448!") + endif() + else(ENABLE_EDDSA) + message(STATUS "OpenSSL: Support for EDDSA is disabled") + endif(ENABLE_EDDSA) + + # acx_openssl_gost.m4 + if(ENABLE_GOST) + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_gost.c) + try_run(RUN_GOST COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_GOST EQUAL 0) + set(WITH_GOST 1) + message(STATUS "OpenSSL: Found GOST engine") + else() + set(error_msg "OpenSSL: Cannot find GOST engine! OpenSSL library has no GOST support!") + message(FATAL_ERROR ${error_msg}) + endif() + else(ENABLE_GOST) + message(STATUS "OpenSSL: Support for GOST is disabled") + endif(ENABLE_GOST) + + # acx_openssl_fips.m4 + if(ENABLE_FIPS) + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_fips.c) + try_run(RUN_FIPS COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_FIPS EQUAL 0) + set(WITH_FIPS 1) + message(STATUS "OpenSSL: Found working FIPS_mode_set()") + else() + set(error_msg "OpenSSL: FIPS_mode_set(1) failed. OpenSSL library is not FIPS capable!") + message(FATAL_ERROR ${error_msg}) + endif() + else(ENABLE_FIPS) + message(STATUS "OpenSSL: Support for FIPS 140-2 mode is disabled") + endif(ENABLE_FIPS) + + # acx_openssl_rfc3349 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_rfc3394.c) + try_run(RUN_AES_KEY_WRAP COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_AES_KEY_WRAP EQUAL 0) + set(HAVE_AES_KEY_WRAP 1) + message(STATUS "OpenSSL: RFC 3394 is supported") + else() + message(STATUS "OpenSSL: RFC 3394 is not supported") + endif() + + # acx_openssl_rfc5649 + set(testfile ${CMAKE_SOURCE_DIR}/modules/tests/test_openssl_rfc5649.c) + try_run(RUN_AES_KEY_WRAP_PAD COMPILE_RESULT + "${CMAKE_BINARY_DIR}/prebuild_santity_tests" ${testfile} + LINK_LIBRARIES ${CRYPTO_LIBS} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${CRYPTO_INCLUDES}" + ) + if(COMPILE_RESULT AND RUN_AES_KEY_WRAP_PAD EQUAL 0) + set(HAVE_AES_KEY_WRAP_PAD 1) + message(STATUS "OpenSSL: RFC 5649 is supported") + else() + message(STATUS "OpenSSL: RFC 5649 is not supported") + endif() + + # Compile with RAW PKCS PSS + set(WITH_RAW_PSS 1) + # Compile with AES_GCM + set(WITH_AES_GCM 1) + +else() + message(FATAL_ERROR "Crypto backend '${WITH_CRYPTO_BACKEND}' not supported. Use openssl or botan.") +endif() + +# Find SQLite3 +if(WITH_SQLITE3) + include(FindSQLite3) + if(NOT SQLITE3_FOUND) + message(FATAL_ERROR "Failed to find SQLite3!") + endif(NOT SQLITE3_FOUND) + + set(SQLITE3_INCLUDES ${SQLITE3_INCLUDE_DIRS}) + set(SQLITE3_LIBS ${SQLITE3_LIBRARIES}) + message(STATUS "SQLite3: Includes: ${SQLITE3_INCLUDES}") + message(STATUS "SQLite3: Libs: ${SQLITE3_LIBS}") + + check_include_files(sqlite3.h HAVE_SQLITE3_H) + check_library_exists(sqlite3 sqlite3_prepare_v2 "" HAVE_LIBSQLITE3) + find_program(SQLITE3_COMMAND NAMES sqlite3) + if(SQLITE3_COMMAND MATCHES "-NOTFOUND") + message(FATAL_ERROR "SQLite3: Command was not found") + endif(SQLITE3_COMMAND MATCHES "-NOTFOUND") +else(WITH_SQLITE3) + message(STATUS "Not including SQLite3 in build") +endif(WITH_SQLITE3) + +# acx_p11kit.m4 +if(ENABLE_P11_KIT) + if("${WITH_P11_KIT}" STREQUAL "") + find_package(PkgConfig) + if(PKG_CONFIG_FOUND) + function(pkg_check_variable _pkg _name) + string(TOUPPER ${_pkg} _pkg_upper) + string(TOUPPER ${_name} _name_upper) + string(REPLACE "-" "_" _pkg_upper ${_pkg_upper}) + string(REPLACE "-" "_" _name_upper ${_name_upper}) + set(_output_name "${_pkg_upper}_${_name_upper}") + + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_name} ${_pkg} OUTPUT_VARIABLE _pkg_result OUTPUT_STRIP_TRAILING_WHITESPACE) + set("${_output_name}" "${_pkg_result}" CACHE STRING "pkg-config variable ${_name} of ${_pkg}") + endfunction() + pkg_check_modules(PC_p11kit QUIET p11-kit-1) + pkg_check_variable(p11-kit-1 p11_module_configs) + set(P11KIT_PATH ${P11_KIT_1_P11_MODULE_CONFIGS}) + endif(PKG_CONFIG_FOUND) + else() + set(P11KIT_PATH ${WITH_P11_KIT}) + endif() + message(STATUS "P11-kit: Install path: ${P11KIT_PATH}") + if("${P11KIT_PATH}" STREQUAL "") + message(WARNING "P11-kit: Missing install path for the p11-kit module, skipping module") + SET(ENABLE_P11_KIT OFF) + endif() +else(ENABLE_P11_KIT) + message(STATUS "P11-kit: No integration") +endif(ENABLE_P11_KIT) + +if(BUILD_TESTS) + # Find CppUnit (equivalent of acx_cppunit.m4) + set(CppUnit_FIND_QUIETLY ON) + include(FindCppUnit) + if(NOT CPPUNIT_FOUND) + message(FATAL_ERROR "Failed to find CppUnit!") + endif(NOT CPPUNIT_FOUND) + + set(CPPUNIT_INCLUDES ${CPPUNIT_INCLUDE_DIR}) + set(CPPUNIT_LIBS ${CPPUNIT_LIBRARY}) + message(STATUS "CppUnit: Includes: ${CPPUNIT_INCLUDES}") + message(STATUS "CppUnit: Libs: ${CPPUNIT_LIBS}") +else(BUILD_TESTS) + message(STATUS "Not building tests") +endif(BUILD_TESTS) + +configure_file(config.h.in.cmake ${CMAKE_BINARY_DIR}/config.h) diff --git a/SoftHSMv2/modules/FindBotan.cmake b/SoftHSMv2/modules/FindBotan.cmake new file mode 100644 index 0000000..6cb85a6 --- /dev/null +++ b/SoftHSMv2/modules/FindBotan.cmake @@ -0,0 +1,46 @@ +# - Try to find the Botan library +# +# Once done this will define +# +# BOTAN_FOUND - System has Botan +# BOTAN_INCLUDE_DIR - The Botan include directory +# BOTAN_LIBRARIES - The libraries needed to use Botan +# BOTAN_DEFINITIONS - Compiler switches required for using Botan + +IF (BOTAN_INCLUDE_DIR AND BOTAN_LIBRARY) + # in cache already + SET(Botan_FIND_QUIETLY TRUE) +ENDIF (BOTAN_INCLUDE_DIR AND BOTAN_LIBRARY) + +IF (NOT WIN32) + # try using pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + # also fills in BOTAN_DEFINITIONS, although that isn't normally useful + FIND_PACKAGE(PkgConfig) + PKG_SEARCH_MODULE(PC_BOTAN botan-2 botan-1.11 botan-1.10) + SET(BOTAN_DEFINITIONS ${PC_BOTAN_CFLAGS}) +ENDIF (NOT WIN32) + +FIND_PATH(BOTAN_INCLUDE_DIR botan/botan.h + HINTS + ${PC_BOTAN_INCLUDEDIR} + ${PC_BOTAN_INCLUDE_DIRS} + ) + +FIND_LIBRARY(BOTAN_LIBRARY NAMES ${PC_BOTAN_LIBRARIES} + HINTS + ${PC_BOTAN_LIBDIR} + ${PC_BOTAN_LIBRARY_DIRS} + ) + +MARK_AS_ADVANCED(BOTAN_INCLUDE_DIR BOTAN_LIBRARY) + +# handle the QUIETLY and REQUIRED arguments and set BOTAN_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Botan DEFAULT_MSG BOTAN_LIBRARY BOTAN_INCLUDE_DIR) + +IF(BOTAN_FOUND) + SET(BOTAN_LIBRARIES ${BOTAN_LIBRARY}) + SET(BOTAN_INCLUDE_DIRS ${BOTAN_INCLUDE_DIR}) +ENDIF(BOTAN_FOUND) diff --git a/SoftHSMv2/modules/FindCppUnit.cmake b/SoftHSMv2/modules/FindCppUnit.cmake new file mode 100644 index 0000000..0980d1d --- /dev/null +++ b/SoftHSMv2/modules/FindCppUnit.cmake @@ -0,0 +1,33 @@ +# +# http://root.cern.ch/viewvc/trunk/cint/reflex/cmake/modules/FindCppUnit.cmake +# +# - Find CppUnit +# This module finds an installed CppUnit package. +# +# It sets the following variables: +# CPPUNIT_FOUND - Set to false, or undefined, if CppUnit isn't found. +# CPPUNIT_INCLUDE_DIR - The CppUnit include directory. +# CPPUNIT_LIBRARY - The CppUnit library to link against. + +FIND_PATH(CPPUNIT_INCLUDE_DIR cppunit/Test.h) +FIND_LIBRARY(CPPUNIT_LIBRARY NAMES cppunit) + +IF (CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARY) + SET(CPPUNIT_FOUND TRUE) +ENDIF (CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARY) + +IF (CPPUNIT_FOUND) + + # show which CppUnit was found only if not quiet + IF (NOT CppUnit_FIND_QUIETLY) + MESSAGE(STATUS "Found CppUnit: ${CPPUNIT_LIBRARY}") + ENDIF (NOT CppUnit_FIND_QUIETLY) + +ELSE (CPPUNIT_FOUND) + + # fatal error if CppUnit is required but not found + IF (CppUnit_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find CppUnit") + ENDIF (CppUnit_FIND_REQUIRED) + +ENDIF (CPPUNIT_FOUND) diff --git a/SoftHSMv2/modules/FindSQLite3.cmake b/SoftHSMv2/modules/FindSQLite3.cmake new file mode 100644 index 0000000..dc7a3b3 --- /dev/null +++ b/SoftHSMv2/modules/FindSQLite3.cmake @@ -0,0 +1,37 @@ +# Copyright (C) 2007-2009 LuaDist. +# Created by Peter Kapec <kapecp@gmail.com> +# Redistribution and use of this file is allowed according to the terms of the MIT license. +# For details see the COPYRIGHT file distributed with LuaDist. +# Note: +# Searching headers and libraries is very simple and is NOT as powerful as scripts +# distributed with CMake, because LuaDist defines directories to search for. +# Everyone is encouraged to contact the author with improvements. Maybe this file +# becomes part of CMake distribution sometimes. + +# - Find sqlite3 +# Find the native SQLITE3 headers and libraries. +# +# SQLITE3_INCLUDE_DIRS - where to find sqlite3.h, etc. +# SQLITE3_LIBRARIES - List of libraries when using sqlite. +# SQLITE3_FOUND - True if sqlite found. + +# Look for the header file. +FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h) + +# Look for the library. +FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite sqlite3) + +# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE. +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR) + +# Copy the results to the output variables. +IF(SQLITE3_FOUND) + SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY}) + SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR}) +ELSE(SQLITE3_FOUND) + SET(SQLITE3_LIBRARIES) + SET(SQLITE3_INCLUDE_DIRS) +ENDIF(SQLITE3_FOUND) + +MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) diff --git a/SoftHSMv2/modules/tests/test_botan_aes_gcm.cpp b/SoftHSMv2/modules/tests/test_botan_aes_gcm.cpp new file mode 100644 index 0000000..3769342 --- /dev/null +++ b/SoftHSMv2/modules/tests/test_botan_aes_gcm.cpp @@ -0,0 +1,11 @@ +#include <botan/botan.h> +#include <botan/version.h> +int main() +{ + using namespace Botan; + +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0) + return 0; +#endif + return 1; +} diff --git a/SoftHSMv2/modules/tests/test_botan_ecc.cpp b/SoftHSMv2/modules/tests/test_botan_ecc.cpp new file mode 100644 index 0000000..cb1be21 --- /dev/null +++ b/SoftHSMv2/modules/tests/test_botan_ecc.cpp @@ -0,0 +1,23 @@ +#include <botan/init.h> +#include <botan/ec_group.h> +#include <botan/oids.h> +#include <botan/version.h> +int main() +{ + Botan::LibraryInitializer::initialize(); + const std::string name("secp256r1"); + const Botan::OID oid(Botan::OIDS::lookup(name)); + const Botan::EC_Group ecg(oid); + try { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + const std::vector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); +#else + const Botan::SecureVector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); +#endif + } catch(...) { + return 1; + } + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_botan_ed25519.cpp b/SoftHSMv2/modules/tests/test_botan_ed25519.cpp new file mode 100644 index 0000000..8ac4bac --- /dev/null +++ b/SoftHSMv2/modules/tests/test_botan_ed25519.cpp @@ -0,0 +1,14 @@ +#include <botan/init.h> +#include <botan/ed25519.h> +#include <botan/version.h> +int main() +{ + Botan::secure_vector<uint8_t> k(32); + try { + Botan::Ed25519_PrivateKey* key = + new Botan::Ed25519_PrivateKey(k); + } catch(...) { + return 1; + } + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_botan_gost.cpp b/SoftHSMv2/modules/tests/test_botan_gost.cpp new file mode 100644 index 0000000..a141e4b --- /dev/null +++ b/SoftHSMv2/modules/tests/test_botan_gost.cpp @@ -0,0 +1,24 @@ +#include <botan/init.h> +#include <botan/gost_3410.h> +#include <botan/oids.h> +#include <botan/version.h> +int main() +{ + Botan::LibraryInitializer::initialize(); + const std::string name("gost_256A"); + const Botan::OID oid(Botan::OIDS::lookup(name)); + const Botan::EC_Group ecg(oid); + try { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + const std::vector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); +#else + const Botan::SecureVector<Botan::byte> der = + ecg.DER_encode(Botan::EC_DOMPAR_ENC_OID); +#endif + } catch(...) { + return 1; + } + + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_botan_rawpss.cpp b/SoftHSMv2/modules/tests/test_botan_rawpss.cpp new file mode 100644 index 0000000..ba7ad01 --- /dev/null +++ b/SoftHSMv2/modules/tests/test_botan_rawpss.cpp @@ -0,0 +1,11 @@ +#include <botan/botan.h> +#include <botan/version.h> +int main() +{ + using namespace Botan; + +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,3,0) + return 0; +#endif + return 1; +} diff --git a/SoftHSMv2/modules/tests/test_botan_rfc5649.cpp b/SoftHSMv2/modules/tests/test_botan_rfc5649.cpp new file mode 100644 index 0000000..7f1fae4 --- /dev/null +++ b/SoftHSMv2/modules/tests/test_botan_rfc5649.cpp @@ -0,0 +1,19 @@ +#include <botan/botan.h> +#include <botan/rfc3394.h> +#include <botan/version.h> +int main() +{ + using namespace Botan; + +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + secure_vector<byte> key(10); + SymmetricKey kek("AABB"); + secure_vector<byte> x = rfc5649_keywrap(key, kek); +#else + SecureVector<byte> key(10); + SymmetricKey kek("AABB"); + Algorithm_Factory& af = global_state().algorithm_factory(); + SecureVector<byte> x = rfc5649_keywrap(key, kek, af); +#endif + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_openssl_ecc.c b/SoftHSMv2/modules/tests/test_openssl_ecc.c new file mode 100644 index 0000000..d1eb22b --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_ecc.c @@ -0,0 +1,13 @@ +#include <openssl/ecdsa.h> +#include <openssl/objects.h> +int main() +{ + EC_KEY *ec256, *ec384, *ec521; + + ec256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + ec384 = EC_KEY_new_by_curve_name(NID_secp384r1); + ec521 = EC_KEY_new_by_curve_name(NID_secp521r1); + if (ec256 == NULL || ec384 == NULL || ec521 == NULL) + return 1; + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_openssl_ed25519.c b/SoftHSMv2/modules/tests/test_openssl_ed25519.c new file mode 100644 index 0000000..70dd92f --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_ed25519.c @@ -0,0 +1,11 @@ +#include <openssl/evp.h> +#include <openssl/objects.h> +int main() +{ + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED25519, NULL); + if (ctx == NULL) + return 1; + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_openssl_ed448.c b/SoftHSMv2/modules/tests/test_openssl_ed448.c new file mode 100644 index 0000000..c97b094 --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_ed448.c @@ -0,0 +1,11 @@ +#include <openssl/evp.h> +#include <openssl/objects.h> +int main() +{ + EVP_PKEY_CTX *ctx; + + ctx = EVP_PKEY_CTX_new_id(NID_ED448, NULL); + if (ctx == NULL) + return 1; + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_openssl_fips.c b/SoftHSMv2/modules/tests/test_openssl_fips.c new file mode 100644 index 0000000..51e75cd --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_fips.c @@ -0,0 +1,5 @@ +#include <openssl/crypto.h> +int main() +{ + return !FIPS_mode_set(1); +} diff --git a/SoftHSMv2/modules/tests/test_openssl_gost.c b/SoftHSMv2/modules/tests/test_openssl_gost.c new file mode 100644 index 0000000..33487e1 --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_gost.c @@ -0,0 +1,41 @@ +#include <openssl/engine.h> +#include <openssl/crypto.h> +#include <openssl/opensslv.h> +int main() +{ + ENGINE* eg; + const EVP_MD* EVP_GOST_34_11; + + /* Initialise OpenSSL */ + OpenSSL_add_all_algorithms(); + + /* Load engines */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + ENGINE_load_builtin_engines(); +#else + OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + + /* Initialise the GOST engine */ + eg = ENGINE_by_id("gost"); + if (eg == NULL) + return 1; + if (ENGINE_init(eg) <= 0) + return 1; + + /* better than digest_gost */ + EVP_GOST_34_11 = ENGINE_get_digest(eg, NID_id_GostR3411_94); + if (EVP_GOST_34_11 == NULL) + return 1; + + /* from the openssl.cnf */ + if (ENGINE_register_pkey_asn1_meths(eg) <= 0) + return 1; + if (ENGINE_ctrl_cmd_string(eg, + "CRYPT_PARAMS", + "id-Gost28147-89-CryptoPro-A-ParamSet", + 0) <= 0) + return 1; + + return 0; +} diff --git a/SoftHSMv2/modules/tests/test_openssl_rfc3394.c b/SoftHSMv2/modules/tests/test_openssl_rfc3394.c new file mode 100644 index 0000000..97343ee --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_rfc3394.c @@ -0,0 +1,7 @@ +#include <openssl/evp.h> +int main() +{ + EVP_aes_128_wrap(); + return 0; +} + diff --git a/SoftHSMv2/modules/tests/test_openssl_rfc5649.c b/SoftHSMv2/modules/tests/test_openssl_rfc5649.c new file mode 100644 index 0000000..17d63ba --- /dev/null +++ b/SoftHSMv2/modules/tests/test_openssl_rfc5649.c @@ -0,0 +1,6 @@ +#include <openssl/evp.h> +int main() +{ + EVP_aes_128_wrap_pad(); + return 0; +} diff --git a/SoftHSMv2/src/Makefile.am b/SoftHSMv2/src/Makefile.am index 7f51142..0985325 100644 --- a/SoftHSMv2/src/Makefile.am +++ b/SoftHSMv2/src/Makefile.am @@ -1,3 +1,5 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in SUBDIRS = lib bin + +EXTRA_DIST = $(srcdir)/CMakeLists.txt diff --git a/SoftHSMv2/src/bin/Makefile.am b/SoftHSMv2/src/bin/Makefile.am index b4a4f57..18d5586 100644 --- a/SoftHSMv2/src/bin/Makefile.am +++ b/SoftHSMv2/src/bin/Makefile.am @@ -1,9 +1,9 @@ MAINTAINERCLEANFILES = $(srcdir)/Makefile.in -SUBDIRS = common util dump +SUBDIRS = common keyconv util dump if BUILD_MIGRATE SUBDIRS += migrate endif -#EXTRA_DIST = +EXTRA_DIST = $(srcdir)/CMakeLists.txt diff --git a/SoftHSMv2/src/bin/dump/Makefile.am b/SoftHSMv2/src/bin/dump/Makefile.am index c70d6f6..64bfa8c 100644 --- a/SoftHSMv2/src/bin/dump/Makefile.am +++ b/SoftHSMv2/src/bin/dump/Makefile.am @@ -20,5 +20,6 @@ softhsm2_dump_db_SOURCES = softhsm2-dump-db.cpp softhsm2_dump_db_LDADD = @SQLITE3_LIBS@ @YIELD_LIB@ -EXTRA_DIST = $(srcdir)/*.h \ +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ softhsm2-dump-db.1 diff --git a/SoftHSMv2/src/bin/dump/tables.h b/SoftHSMv2/src/bin/dump/tables.h index 76d64fb..e6db516 100644 --- a/SoftHSMv2/src/bin/dump/tables.h +++ b/SoftHSMv2/src/bin/dump/tables.h @@ -88,7 +88,7 @@ void fill_CKA_table(std::map<unsigned long, std::string> &t) t[CKA_SUBPRIME] = "CKA_SUBPRIME"; t[CKA_BASE] = "CKA_BASE"; t[CKA_PRIME_BITS] = "CKA_PRIME_BITS"; - t[CKA_SUBPRIME_BITS] = "CKA_SUBPRIME_BITS"; + t[CKA_SUB_PRIME_BITS] = "CKA_SUB_PRIME_BITS"; t[CKA_VALUE_BITS] = "CKA_VALUE_BITS"; t[CKA_VALUE_LEN] = "CKA_VALUE_LEN"; t[CKA_EXTRACTABLE] = "CKA_EXTRACTABLE"; @@ -476,6 +476,8 @@ void fill_CKM_table(std::map<unsigned long, std::string> &t) t[CKM_AES_KEY_WRAP_PAD] = "CKM_AES_KEY_WRAP_PAD"; t[CKM_RSA_PKCS_TPM_1_1] = "CKM_RSA_PKCS_TPM_1_1"; t[CKM_RSA_PKCS_OAEP_TPM_1_1] = "CKM_RSA_PKCS_OAEP_TPM_1_1"; + t[CKM_EC_EDWARDS_KEY_PAIR_GEN] = "CKM_EC_EDWARDS_KEY_PAIR_GEN"; + t[CKM_EDDSA] = "CKM_EDDSA"; } void fill_CKO_table(std::map<unsigned long, std::string> &t) @@ -541,6 +543,7 @@ void fill_CKK_table(std::map<unsigned long, std::string> &t) t[CKK_GOSTR3410] = "CKK_GOSTR3410"; t[CKK_GOSTR3411] = "CKK_GOSTR3411"; t[CKK_GOST28147] = "CKK_GOST28147"; + t[CKK_EC_EDWARDS] = "CKK_EC_EDWARDS"; } void fill_CKC_table(std::map<unsigned long, std::string> &t) diff --git a/SoftHSMv2/src/bin/keyconv/Makefile.am b/SoftHSMv2/src/bin/keyconv/Makefile.am new file mode 100644 index 0000000..5565017 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/Makefile.am @@ -0,0 +1,27 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +AM_CPPFLAGS = -I$(srcdir)/../../lib/crypto \ + @CRYPTO_INCLUDES@ + +dist_man_MANS = softhsm2-keyconv.1 + +bin_PROGRAMS = softhsm2-keyconv + +softhsm2_keyconv_SOURCES = softhsm2-keyconv.cpp \ + base64.c +softhsm2_keyconv_LDADD = @CRYPTO_LIBS@ + +# Compile with OpenSSL support +if WITH_OPENSSL +softhsm2_keyconv_SOURCES += softhsm2-keyconv-ossl.cpp \ + ../../lib/crypto/OSSLComp.cpp +endif + +# Compile with Botan support +if WITH_BOTAN +softhsm2_keyconv_SOURCES += softhsm2-keyconv-botan.cpp +endif + +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ + $(srcdir)/*.cpp diff --git a/SoftHSMv2/src/bin/keyconv/base64.c b/SoftHSMv2/src/bin/keyconv/base64.c new file mode 100644 index 0000000..3eb1201 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/base64.c @@ -0,0 +1,311 @@ +/* $OpenBSD: base64.c,v 1.3 2002/06/09 08:13:07 todd Exp $ */ + +/* + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#if !defined(LINT) && !defined(CODECENTER) +static const char rcsid[] = "$ISC: base64.c,v 8.6 1999/01/08 19:25:18 vixie Exp $"; +#endif /* not lint */ + +#include <sys/types.h> +#ifndef _WIN32 +#include <sys/param.h> +#include <sys/socket.h> +#endif + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(unsigned char const *src, size_t srclength, char *target, size_t targsize) { + size_t datalength = 0; + unsigned char input[3]; + unsigned char output[4]; + size_t i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, unsigned char *target, size_t targsize) { + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for ((void)NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp new file mode 100644 index 0000000..cb5700f --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + softhsm2-keyconv-botan.cpp + + Code specific for Botan + *****************************************************************************/ + +#include <config.h> +#define KEYCONV_BOTAN +#include "softhsm2-keyconv.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <fstream> + +#include <botan/init.h> +#include <botan/auto_rng.h> +#include <botan/pkcs8.h> +#include <botan/rsa.h> +#include <botan/dsa.h> +#include <botan/bigint.h> +#include <botan/version.h> + +// Init Botan +void crypto_init() +{ + Botan::LibraryInitializer::initialize(); +} + +// Final Botan +void crypto_final() +{ + Botan::LibraryInitializer::deinitialize(); +} + +// Save the RSA key as a PKCS#8 file +int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + int result = 0; + Botan::Private_Key* priv_key = NULL; + Botan::AutoSeeded_RNG* rng = NULL; + Botan::BigInt bigE, bigP, bigQ, bigN, bigD; + + // See if the key material was found. + if + ( + pkey[TAG_MODULUS].size <= 0 || + pkey[TAG_PUBEXP].size <= 0 || + pkey[TAG_PRIVEXP].size <= 0 || + pkey[TAG_PRIME1].size <= 0 || + pkey[TAG_PRIME2].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + bigE = Botan::BigInt((Botan::byte*)pkey[TAG_PUBEXP].big, pkey[TAG_PUBEXP].size); + bigP = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME1].big, pkey[TAG_PRIME1].size); + bigQ = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME2].big, pkey[TAG_PRIME2].size); + bigN = Botan::BigInt((Botan::byte*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size); + bigD = Botan::BigInt((Botan::byte*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size); + + rng = new Botan::AutoSeeded_RNG(); + + try + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34) + priv_key = new Botan::RSA_PrivateKey(bigP, bigQ, bigE, bigD, bigN); +#else + priv_key = new Botan::RSA_PrivateKey(*rng, bigP, bigQ, bigE, bigD, bigN); +#endif + } + catch(std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not extract the private key from the file.\n"); + delete rng; + return 1; + } + + std::ofstream priv_file(out_path); + if (!priv_file.is_open()) + { + fprintf(stderr, "ERROR: Could not open file for output.\n"); + delete rng; + delete priv_key; + return 1; + } + + try + { + if (file_pin == NULL) + { + priv_file << Botan::PKCS8::PEM_encode(*priv_key); + } + else + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, std::chrono::milliseconds(300), "PBE-PKCS5v15(MD5,DES/CBC)"); +#else + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)"); +#endif + } + + printf("The key has been written to %s\n", out_path); + } + catch(std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not write to file.\n"); + result = 1; + } + + delete rng; + delete priv_key; + priv_file.close(); + + return result; +} + +// Save the DSA key as a PKCS#8 file +int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + int result = 0; + Botan::Private_Key* priv_key = NULL; + Botan::AutoSeeded_RNG* rng = NULL; + Botan::BigInt bigDP, bigDQ, bigDG, bigDX; + + // See if the key material was found. + if + ( + pkey[TAG_PRIME].size <= 0 || + pkey[TAG_SUBPRIME].size <= 0 || + pkey[TAG_BASE].size <= 0 || + pkey[TAG_PRIVVAL].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + bigDP = Botan::BigInt((Botan::byte*)pkey[TAG_PRIME].big, pkey[TAG_PRIME].size); + bigDQ = Botan::BigInt((Botan::byte*)pkey[TAG_SUBPRIME].big, pkey[TAG_SUBPRIME].size); + bigDG = Botan::BigInt((Botan::byte*)pkey[TAG_BASE].big, pkey[TAG_BASE].size); + bigDX = Botan::BigInt((Botan::byte*)pkey[TAG_PRIVVAL].big, pkey[TAG_PRIVVAL].size); + + rng = new Botan::AutoSeeded_RNG(); + + try + { + priv_key = new Botan::DSA_PrivateKey(*rng, Botan::DL_Group(bigDP, bigDQ, bigDG), bigDX); + } + catch (std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not extract the private key from the file.\n"); + delete rng; + return 1; + } + + std::ofstream priv_file(out_path); + if (!priv_file.is_open()) + { + fprintf(stderr, "ERROR: Could not open file for output.\n"); + delete rng; + delete priv_key; + return 1; + } + + try + { + if (file_pin == NULL) + { + priv_file << Botan::PKCS8::PEM_encode(*priv_key); + } + else + { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, std::chrono::milliseconds(300), "PBE-PKCS5v15(MD5,DES/CBC)"); +#else + priv_file << Botan::PKCS8::PEM_encode(*priv_key, *rng, file_pin, "PBE-PKCS5v15(MD5,DES/CBC)"); +#endif + } + + printf("The key has been written to %s\n", out_path); + } + catch (std::exception& e) + { + fprintf(stderr, "%s\n", e.what()); + fprintf(stderr, "ERROR: Could not write to file.\n"); + result = 1; + } + + delete rng; + delete priv_key; + priv_file.close(); + + return result; +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp new file mode 100644 index 0000000..a5cd8eb --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + softhsm2-keyconv-ossl.cpp + + Code specific for OpenSSL + *****************************************************************************/ + +#include <config.h> +#define KEYCONV_OSSL +#include "softhsm2-keyconv.h" +#include "OSSLComp.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <iostream> +#include <fstream> + +#include <openssl/pem.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include <openssl/pkcs12.h> +#include <openssl/dsa.h> +#include <openssl/rsa.h> + +// Init OpenSSL +void crypto_init() +{ + OpenSSL_add_all_algorithms(); +#ifdef WITH_FIPS + if (!FIPS_mode_set(1)) + { + fprintf(stderr, "ERROR: can't enter into FIPS mode.\n"); + exit(0); + } +#endif +} + +// Final OpenSSL +void crypto_final() +{ + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +} + +// Save the RSA key as a PKCS#8 file +int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + RSA* rsa = NULL; + EVP_PKEY* ossl_pkey = NULL; + PKCS8_PRIV_KEY_INFO* p8inf = NULL; + BIO* out = NULL; + X509_SIG* p8 = NULL; + int result = 0; + + // See if the key material was found. + if + ( + pkey[TAG_MODULUS].size <= 0 || + pkey[TAG_PUBEXP].size <= 0 || + pkey[TAG_PRIVEXP].size <= 0 || + pkey[TAG_PRIME1].size <= 0 || + pkey[TAG_PRIME2].size <= 0 || + pkey[TAG_EXP1].size <= 0 || + pkey[TAG_EXP2].size <= 0 || + pkey[TAG_COEFF].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + rsa = RSA_new(); + BIGNUM* bn_p = BN_bin2bn((unsigned char*)pkey[TAG_PRIME1].big, pkey[TAG_PRIME1].size, NULL); + BIGNUM* bn_q = BN_bin2bn((unsigned char*)pkey[TAG_PRIME2].big, pkey[TAG_PRIME2].size, NULL); + BIGNUM* bn_d = BN_bin2bn((unsigned char*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size, NULL); + BIGNUM* bn_n = BN_bin2bn((unsigned char*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size, NULL); + BIGNUM* bn_e = BN_bin2bn((unsigned char*)pkey[TAG_PUBEXP].big, pkey[TAG_PUBEXP].size, NULL); + BIGNUM* bn_dmp1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP1].big, pkey[TAG_EXP1].size, NULL); + BIGNUM* bn_dmq1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP2].big, pkey[TAG_EXP2].size, NULL); + BIGNUM* bn_iqmp = BN_bin2bn((unsigned char*)pkey[TAG_COEFF].big, pkey[TAG_COEFF].size, NULL); + RSA_set0_factors(rsa, bn_p, bn_q); + RSA_set0_crt_params(rsa, bn_dmp1, bn_dmq1, bn_iqmp); + RSA_set0_key(rsa, bn_n, bn_e, bn_d); + + ossl_pkey = EVP_PKEY_new(); + + // Convert RSA to EVP_PKEY + if (!EVP_PKEY_set1_RSA(ossl_pkey, rsa)) + { + fprintf(stderr, "ERROR: Could not convert RSA key to EVP_PKEY.\n"); + RSA_free(rsa); + EVP_PKEY_free(ossl_pkey); + return 1; + } + RSA_free(rsa); + + // Convert EVP_PKEY to PKCS#8 + if (!(p8inf = EVP_PKEY2PKCS8(ossl_pkey))) + { + fprintf(stderr, "ERROR: Could not convert EVP_PKEY to PKCS#8.\n"); + EVP_PKEY_free(ossl_pkey); + return 1; + } + EVP_PKEY_free(ossl_pkey); + + // Open output file + if (!(out = BIO_new_file (out_path, "wb"))) + { + fprintf(stderr, "ERROR: Could not open the output file.\n"); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 1; + } + + // Write to disk + if (file_pin == NULL) + { + PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); + printf("The key has been written to %s\n", out_path); + } + else + { + // Encrypt p8 + if (!(p8 = PKCS8_encrypt(NID_pbeWithMD5AndDES_CBC, NULL, + file_pin, strlen(file_pin), NULL, + 0, PKCS12_DEFAULT_ITER, p8inf))) + { + fprintf(stderr, "ERROR: Could not encrypt the PKCS#8 file\n"); + result = 1; + } + else + { + PEM_write_bio_PKCS8(out, p8); + X509_SIG_free(p8); + printf("The key has been written to %s\n", out_path); + } + } + + PKCS8_PRIV_KEY_INFO_free(p8inf); + BIO_free_all(out); + + return result; +} + +// Save the DSA key as a PKCS#8 file +int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) +{ + DSA* dsa = NULL; + EVP_PKEY* ossl_pkey = NULL; + PKCS8_PRIV_KEY_INFO* p8inf = NULL; + BIO* out = NULL; + X509_SIG* p8 = NULL; + int result = 0; + + // See if the key material was found. + if + ( + pkey[TAG_PRIME].size <= 0 || + pkey[TAG_SUBPRIME].size <= 0 || + pkey[TAG_BASE].size <= 0 || + pkey[TAG_PRIVVAL].size <= 0 || + pkey[TAG_PUBVAL].size <= 0 + ) + { + fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); + return 1; + } + + dsa = DSA_new(); + BIGNUM* bn_p = BN_bin2bn((unsigned char*)pkey[TAG_PRIME].big, pkey[TAG_PRIME].size, NULL); + BIGNUM* bn_q = BN_bin2bn((unsigned char*)pkey[TAG_SUBPRIME].big, pkey[TAG_SUBPRIME].size, NULL); + BIGNUM* bn_g = BN_bin2bn((unsigned char*)pkey[TAG_BASE].big, pkey[TAG_BASE].size, NULL); + BIGNUM* bn_priv_key = BN_bin2bn((unsigned char*)pkey[TAG_PRIVVAL].big, pkey[TAG_PRIVVAL].size, NULL); + BIGNUM* bn_pub_key = BN_bin2bn((unsigned char*)pkey[TAG_PUBVAL].big, pkey[TAG_PUBVAL].size, NULL); + + DSA_set0_pqg(dsa, bn_p, bn_q, bn_g); + DSA_set0_key(dsa, bn_pub_key, bn_priv_key); + + ossl_pkey = EVP_PKEY_new(); + + // Convert DSA to EVP_PKEY + if (!EVP_PKEY_set1_DSA(ossl_pkey, dsa)) + { + fprintf(stderr, "ERROR: Could not convert DSA key to EVP_PKEY.\n"); + DSA_free(dsa); + EVP_PKEY_free(ossl_pkey); + return 1; + } + DSA_free(dsa); + + // Convert EVP_PKEY to PKCS#8 + if (!(p8inf = EVP_PKEY2PKCS8(ossl_pkey))) + { + fprintf(stderr, "ERROR: Could not convert EVP_PKEY to PKCS#8.\n"); + EVP_PKEY_free(ossl_pkey); + return 1; + } + EVP_PKEY_free(ossl_pkey); + + // Open output file + if (!(out = BIO_new_file (out_path, "wb"))) + { + fprintf(stderr, "ERROR: Could not open the output file.\n"); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 1; + } + + // Write to disk + if (file_pin == NULL) + { + PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); + printf("The key has been written to %s\n", out_path); + } + else + { + // Encrypt p8 + if (!(p8 = PKCS8_encrypt(NID_pbeWithMD5AndDES_CBC, NULL, + file_pin, strlen(file_pin), NULL, + 0, PKCS12_DEFAULT_ITER, p8inf))) + { + fprintf(stderr, "ERROR: Could not encrypt the PKCS#8 file\n"); + result = 1; + } + else + { + PEM_write_bio_PKCS8(out, p8); + X509_SIG_free(p8); + printf("The key has been written to %s\n", out_path); + } + } + + PKCS8_PRIV_KEY_INFO_free(p8inf); + BIO_free_all(out); + + return result; +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 new file mode 100644 index 0000000..b716bc8 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 @@ -0,0 +1,63 @@ +.TH SOFTHSM2-KEYCONV 1 "20 March 2014" "SoftHSM" +.SH NAME +softhsm2-keyconv \- converting from BIND to PKCS#8 key file format +.SH SYNOPSIS +.B softhsm2-keyconv +.B \-\-in +.I path +.B \-\-out +.I path +.RB [ \-\-pin +.IR PIN ] +.SH DESCRIPTION +.B softhsm2-keyconv +can convert BIND .private-key files to the PKCS#8 file format. +This is so that you can import the PKCS#8 file into +libsofthsm using the command +.BR softhsm2\-util . +If you have another file format, then +.B openssl +probably can help you to convert it into the PKCS#8 file format. +.SH OPTIONS +.B \-\-help\fR, \fB\-h\fR +Shows the help screen. +.TP +.B \-\-in \fIpath\fR +The +.I path +to the input file. +.TP +.B \-\-out \fIpath\fR +The +.I path +to the output file. +.TP +.B \-\-pin \fIPIN\fR +The +.I PIN +will be used to encrypt the PKCS#8 file. +If not given then the PKCS#8 file will be unencrypted. +.TP +.B \-\-version\fR, \fB\-v\fR +Show the version info. +.SH EXAMPLES +The following command can be used to convert a BIND .private-key file to a PKCS#8 file: +.LP +.RS +.nf +softhsm2-keyconv \-\-in Kexample.com.+007+05474.private \\ +.ti +0.7i +\-\-out rsa.pem +.fi +.RE +.LP +.SH AUTHORS +Written by Rickard Bellgrim, Francis Dupont, René Post, and Roland van Rijswijk. +.SH "SEE ALSO" +.IR softhsm2-migrate (1), +.IR softhsm2-util (1), +.IR softhsm2.conf (5), +.IR openssl (1), +.IR named (1), +.IR dnssec-keygen (1), +.IR dnssec-signzone (1) diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp new file mode 100644 index 0000000..aeb75c3 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/************************************************************ +* +* softhsm2-keyconv +* +* This program is for converting from BIND .private-key +* format to PKCS#8 key file format. So that keys can be +* imported from BIND to SoftHSM. +* +* Some of the design/code is from keyconv.c written by +* Hakan Olsson and Jakob Schlyter in 2000 and 2001. +* +************************************************************/ + +#include <config.h> +#include "softhsm2-keyconv.h" + +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <string.h> +#ifndef _WIN32 +#include <unistd.h> +#else +#include <io.h> +#define S_IRUSR 0400 +#define S_IWUSR 0200 +#define open _open +#define close _close +#endif +#include <iostream> +#include <fstream> +#include <stdint.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +void usage() +{ + printf("Converting from BIND .private-key format to PKCS#8 key file format.\n"); + printf("Usage: softhsm2-keyconv [OPTIONS]\n"); + printf("Options:\n"); + printf(" -h Shows this help screen.\n"); + printf(" --help Shows this help screen.\n"); + printf(" --in <path> The path to the input file.\n"); + printf(" --out <path> The path to the output file.\n"); + printf(" --pin <PIN> To encrypt PKCS#8 file. Optional.\n"); + printf(" -v Show version info.\n"); + printf(" --version Show version info.\n"); +} + +// Give a number to each option +enum { + OPT_HELP = 0x100, + OPT_IN, + OPT_OUT, + OPT_PIN, + OPT_VERSION +}; + +// Define the options +static const struct option long_options[] = { + { "help", 0, NULL, OPT_HELP }, + { "in", 1, NULL, OPT_IN }, + { "out", 1, NULL, OPT_OUT }, + { "pin", 1, NULL, OPT_PIN }, + { "version", 0, NULL, OPT_VERSION }, + { NULL, 0, NULL, 0 } +}; + +int main(int argc, char* argv[]) +{ + int option_index = 0; + int opt, result; + + char* in_path = NULL; + char* out_path = NULL; + char* file_pin = NULL; + + if (argc == 1) + { + usage(); + exit(0); + } + + while ((opt = getopt_long(argc, argv, "hv", long_options, &option_index)) != -1) + { + switch (opt) + { + case OPT_IN: + in_path = optarg; + break; + case OPT_OUT: + out_path = optarg; + break; + case OPT_PIN: + file_pin = optarg; + break; + case OPT_VERSION: + case 'v': + printf("%s\n", PACKAGE_VERSION); + exit(0); + break; + case OPT_HELP: + case 'h': + default: + usage(); + exit(0); + break; + } + } + + // We should convert to PKCS#8 + result = to_pkcs8(in_path, out_path, file_pin); + + return result; +} + +// Convert from BIND to PKCS#8 +int to_pkcs8(char* in_path, char* out_path, char* file_pin) +{ + FILE* file_pointer = NULL; + char line[MAX_LINE], data[MAX_LINE]; + char* value_pointer = NULL; + int lineno = 0, m, n, error = 0, found, algorithm = DNS_KEYALG_ERROR, data_length; + uint32_t bitfield = 0; + key_material_t pkey[TAG_MAX]; + + if (in_path == NULL) + { + fprintf(stderr, "ERROR: A path to the input file must be supplied. Use --in <path>\n"); + return 1; + } + + if (out_path == NULL) + { + fprintf(stderr, "ERROR: A path to the output file must be supplied. Use --out <path>\n"); + return 1; + } + + file_pointer = fopen(in_path, "r"); + if (file_pointer == NULL) + { + fprintf(stderr, "ERROR: Could not open input file %.100s for reading.\n", in_path); + return 1; + } + + // Loop over all of the lines + while (fgets(line, MAX_LINE, file_pointer) != NULL) + { + lineno++; + + // Find the current text field in the BIND file. + for (m = 0, found = -1; found == -1 && file_tags[m]; m++) + { + if (strncasecmp(line, file_tags[m], strlen(file_tags[m])) == 0) + { + found = m; + } + } + + // The text files is not recognized. + if (found == -1) + { + fprintf(stderr, "ERROR: Unrecognized input line %i\n", lineno); + fprintf(stderr, "ERROR: --> %s", line); + continue; + } + + // Point to the data for this text field. + value_pointer = line + strlen(file_tags[found]) + 1; + + // Continue if we are at the end of the string + if (*value_pointer == 0) + { + continue; + } + + // Check that we do not get duplicates. + if (bitfield & (1 << found)) + { + fprintf(stderr, "ERROR: Duplicate \"%s\" field, line %i - ignored\n", + file_tags[found], lineno); + continue; + } + bitfield |= (1 << found); + + // Handle the data for this text field. + switch (found) + { + case TAG_VERSION: + if (sscanf(value_pointer, "v%i.%i", &m, &n) != 2) + { + fprintf(stderr, "ERROR: Invalid/unknown version string " + "(%.100s).\n", value_pointer); + error = 1; + break; + } + if (m > FILE_MAJOR_VERSION || (m == FILE_MAJOR_VERSION && n > FILE_MINOR_VERSION)) + { + fprintf(stderr, "ERROR: Cannot parse this version of file format, " + "v%i.%i.\n", m, n); + error = 1; + } + break; + case TAG_ALGORITHM: + algorithm = strtol(value_pointer, NULL, 10); + break; + // RSA + case TAG_MODULUS: + case TAG_PUBEXP: + case TAG_PRIVEXP: + case TAG_PRIME1: + case TAG_PRIME2: + case TAG_EXP1: + case TAG_EXP2: + case TAG_COEFF: + // DSA + case TAG_PRIME: + case TAG_SUBPRIME: + case TAG_BASE: + case TAG_PRIVVAL: + case TAG_PUBVAL: + data_length = b64_pton(value_pointer, (unsigned char*)data, MAX_LINE); + if (data_length == -1) + { + error = 1; + fprintf(stderr, "ERROR: Could not parse the base64 string on line %i.\n", lineno); + } + else + { + pkey[found].big = malloc(data_length); + if (!pkey[found].big) + { + fprintf(stderr, "ERROR: Could not allocate memory.\n"); + error = 1; + break; + } + memcpy(pkey[found].big, data, data_length); + pkey[found].size = data_length; + } + break; + // Do not need these + case TAG_CREATED: + case TAG_PUBLISH: + case TAG_ACTIVATE: + default: + break; + } + } + + fclose(file_pointer); + + // Something went wrong. Clean up and quit. + if (error) + { + free_key_material(pkey); + return error; + } + + // Create and set file permissions if the file does not exist. + int fd = open(out_path, O_CREAT, S_IRUSR | S_IWUSR); + if (fd == -1) + { + fprintf(stderr, "ERROR: Could not open the output file: %s (errno %i)\n", + out_path, errno); + free_key_material(pkey); + return 1; + } + ::close(fd); + + crypto_init(); + + // Save the the key to the disk + switch (algorithm) + { + case DNS_KEYALG_ERROR: + fprintf(stderr, "ERROR: The algorithm %i was not given in the file.\n", + algorithm); + error = 1; + break; + case DNS_KEYALG_RSAMD5: + case DNS_KEYALG_RSASHA1: + case DNS_KEYALG_RSASHA1_NSEC3_SHA1: + case DNS_KEYALG_RSASHA256: + case DNS_KEYALG_RSASHA512: + error = save_rsa_pkcs8(out_path, file_pin, pkey); + break; + case DNS_KEYALG_DSA: + case DNS_KEYALG_DSA_NSEC3_SHA1: + error = save_dsa_pkcs8(out_path, file_pin, pkey); + break; + case DNS_KEYALG_ECC: + case DNS_KEYALG_ECC_GOST: + default: + fprintf(stderr, "ERROR: The algorithm %i is not supported.\n", + algorithm); + error = 1; + break; + } + + crypto_final(); + free_key_material(pkey); + + return error; +} + +// Free allocated memory +void free_key_material(key_material_t* pkey) +{ + int i; + + if (!pkey) + { + return; + } + + for (i = 0; i < TAG_MAX; i++) + { + if (pkey[i].big) + { + free(pkey[i].big); + } + } +} diff --git a/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h new file mode 100644 index 0000000..fdeb719 --- /dev/null +++ b/SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _SOFTHSM_V2_SOFTHSM2_KEYCONV_H +#define _SOFTHSM_V2_SOFTHSM2_KEYCONV_H 1 + +#include <stdlib.h> + +typedef struct key_material_t { + unsigned long size; + void* big; + key_material_t() { + size = 0; + big = NULL; + } +} key_material_t; + +// Main functions + +void usage(); +int to_pkcs8(char* in_path, char* out_path, char* file_pin); + +// Support functions + +int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey); +int save_dsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey); +void free_key_material(key_material_t* pkey); +void crypto_init(); +void crypto_final(); + +// base64.c prototypes + +#ifdef __cplusplus +extern "C" { +#endif +int b64_pton(const char* , unsigned char*, size_t); +int b64_ntop(const unsigned char*, size_t, char*, size_t); +#ifdef __cplusplus +} +#endif + +// The BIND file version number. +#define FILE_MAJOR_VERSION 1 +#define FILE_MINOR_VERSION 3 + +// Key algorithm number +#define DNS_KEYALG_ERROR -1 +#define DNS_KEYALG_RSAMD5 1 +#define DNS_KEYALG_DSA 3 +#define DNS_KEYALG_ECC 4 +#define DNS_KEYALG_RSASHA1 5 +#define DNS_KEYALG_DSA_NSEC3_SHA1 6 +#define DNS_KEYALG_RSASHA1_NSEC3_SHA1 7 +#define DNS_KEYALG_RSASHA256 8 +#define DNS_KEYALG_RSASHA512 10 +#define DNS_KEYALG_ECC_GOST 12 + +// Maximum number of lines / line length +#define MAX_LINE 4096 + +// The text fields supported +#if !defined(KEYCONV_BOTAN) && !defined(KEYCONV_OSSL) +static const char* file_tags[] = { + "Private-key-format:", + "Algorithm:", + "Modulus:", + "PublicExponent:", + "PrivateExponent:", + "Prime1:", + "Prime2:", + "Exponent1:", + "Exponent2:", + "Coefficient:", + "Prime(p):", + "Private_value(x):", + "Public_value(y):", + "Subprime(q):", + "Base(g):", + "Created:", + "Publish:", + "Activate:", + NULL +}; +#endif + +// The number of each text field. +// Must match the tags above. +enum FILE_TAGS { + TAG_VERSION = 0, + TAG_ALGORITHM, + TAG_MODULUS, + TAG_PUBEXP, + TAG_PRIVEXP, + TAG_PRIME1, + TAG_PRIME2, + TAG_EXP1, + TAG_EXP2, + TAG_COEFF, + TAG_PRIME, + TAG_PRIVVAL, + TAG_PUBVAL, + TAG_SUBPRIME, + TAG_BASE, + TAG_CREATED, + TAG_PUBLISH, + TAG_ACTIVATE, + // So we know how long this list is + TAG_MAX +}; + +#endif /* _SOFTHSM_V2_SOFTHSM2_KEYCONV_H */ diff --git a/SoftHSMv2/src/bin/migrate/Makefile.am b/SoftHSMv2/src/bin/migrate/Makefile.am index 020c6a7..d903764 100644 --- a/SoftHSMv2/src/bin/migrate/Makefile.am +++ b/SoftHSMv2/src/bin/migrate/Makefile.am @@ -17,4 +17,5 @@ softhsm2_migrate_SOURCES = softhsm2-migrate.cpp \ softhsm2_migrate_LDADD = @SQLITE3_LIBS@ \ @YIELD_LIB@ -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/bin/migrate/softhsm2-migrate.cpp b/SoftHSMv2/src/bin/migrate/softhsm2-migrate.cpp index 0e6dc90..3ce04eb 100644 --- a/SoftHSMv2/src/bin/migrate/softhsm2-migrate.cpp +++ b/SoftHSMv2/src/bin/migrate/softhsm2-migrate.cpp @@ -503,9 +503,18 @@ CK_KEY_TYPE getKeyType(CK_OBJECT_HANDLE objectRef) CK_VOID_PTR pValue = (CK_VOID_PTR)sqlite3_column_blob(select_an_attribute_sql, 0); CK_ULONG length = sqlite3_column_int(select_an_attribute_sql, 1); - if (pValue != NULL_PTR && length == sizeof(CK_KEY_TYPE)) + if (pValue != NULL_PTR) { - retVal = *(CK_KEY_TYPE*)pValue; + // 32/64-bit DB on 32/64-bit system + if (length == sizeof(CK_KEY_TYPE)) + { + retVal = *(CK_KEY_TYPE*)pValue; + } + // 32-bit DB on 64-bit system (LP64) + else if (length == sizeof(unsigned int)) + { + retVal = *(unsigned int*)pValue; + } } } @@ -535,9 +544,18 @@ CK_OBJECT_CLASS getObjectClass(CK_OBJECT_HANDLE objectRef) CK_VOID_PTR pValue = (CK_VOID_PTR)sqlite3_column_blob(select_an_attribute_sql, 0); CK_ULONG length = sqlite3_column_int(select_an_attribute_sql, 1); - if (pValue != NULL_PTR && length == sizeof(CK_OBJECT_CLASS)) + if (pValue != NULL_PTR) { - retVal = *(CK_OBJECT_CLASS*)pValue; + // 32/64-bit DB on 32/64-bit system + if (length == sizeof(CK_OBJECT_CLASS)) + { + retVal = *(CK_OBJECT_CLASS*)pValue; + } + // 32-bit DB on 64-bit system (LP64) + else if (length == sizeof(unsigned int)) + { + retVal = *(unsigned int*)pValue; + } } } @@ -617,10 +635,15 @@ int dbRSAPub2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HAND int i; CK_OBJECT_HANDLE hKey; CK_RV rv; + CK_OBJECT_CLASS ckClass = CKO_PUBLIC_KEY; + CK_KEY_TYPE ckType = CKK_RSA; + // All required CK_ULONG attributes have known/fixed values. + // So no need read them from the DB and no need to handle + // convertion from 32-bit to 64-bit. CK_ATTRIBUTE pubTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_KEY_TYPE, NULL, 0 }, + { CKA_CLASS, &ckClass, sizeof(ckClass) }, + { CKA_KEY_TYPE, &ckType, sizeof(ckType) }, { CKA_TOKEN, NULL, 0 }, { CKA_PRIVATE, NULL, 0 }, { CKA_MODIFIABLE, NULL, 0 }, @@ -638,12 +661,12 @@ int dbRSAPub2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HAND { CKA_PUBLIC_EXPONENT, NULL, 0 } }; - for (i = 0; i < 17; i++) + for (i = 2; i < 17; i++) { result = getAttribute(objectID, &pubTemplate[i]); if (result) { - freeTemplate(pubTemplate, 17); + freeTemplate(pubTemplate, 2, 17); return 1; } } @@ -660,7 +683,7 @@ int dbRSAPub2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HAND printf("Object %lu has been migrated\n", objectID); } - freeTemplate(pubTemplate, 17); + freeTemplate(pubTemplate, 2, 17); return result; } @@ -672,9 +695,13 @@ int dbRSAPriv2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HAN int i; CK_OBJECT_HANDLE hKey; CK_RV rv; + CK_OBJECT_CLASS ckClass = CKO_PRIVATE_KEY; + // All required CK_ULONG attributes have known/fixed values. + // So no need read them from the DB and no need to handle + // convertion from 32-bit to 64-bit. CK_ATTRIBUTE privTemplate[] = { - { CKA_CLASS, NULL, 0 }, + { CKA_CLASS, &ckClass, sizeof(ckClass) }, { CKA_TOKEN, NULL, 0 }, { CKA_PRIVATE, NULL, 0 }, { CKA_MODIFIABLE, NULL, 0 }, @@ -703,12 +730,12 @@ int dbRSAPriv2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HAN // { CKA_COEFFICIENT, NULL, 0 } }; - for (i = 0; i < 23; i++) + for (i = 1; i < 23; i++) { result = getAttribute(objectID, &privTemplate[i]); if (result) { - freeTemplate(privTemplate, 23); + freeTemplate(privTemplate, 1, 23); return 1; } } @@ -725,7 +752,7 @@ int dbRSAPriv2session(sqlite3* /*db*/, CK_OBJECT_HANDLE objectID, CK_SESSION_HAN printf("Object %lu has been migrated\n", objectID); } - freeTemplate(privTemplate, 23); + freeTemplate(privTemplate, 1, 23); return result; } @@ -782,13 +809,13 @@ int getAttribute(CK_OBJECT_HANDLE objectRef, CK_ATTRIBUTE* attTemplate) } // Free allocated memory in the template -void freeTemplate(CK_ATTRIBUTE* attTemplate, int size) +void freeTemplate(CK_ATTRIBUTE* attTemplate, int startIndex, int size) { int i; if (!attTemplate) return; - for (i = 0; i < size; i++) + for (i = startIndex; i < size; i++) { if(attTemplate[i].pValue) { diff --git a/SoftHSMv2/src/bin/migrate/softhsm2-migrate.h b/SoftHSMv2/src/bin/migrate/softhsm2-migrate.h index 1b5a066..a02221c 100644 --- a/SoftHSMv2/src/bin/migrate/softhsm2-migrate.h +++ b/SoftHSMv2/src/bin/migrate/softhsm2-migrate.h @@ -49,7 +49,7 @@ int openP11(CK_SLOT_ID slotID, char* userPIN, CK_SESSION_HANDLE* hSession); int db2session(sqlite3* db, CK_SESSION_HANDLE hSession, int noPublicKey); int dbRSAPub2session(sqlite3* db, CK_OBJECT_HANDLE objectID, CK_SESSION_HANDLE hSession); int dbRSAPriv2session(sqlite3* db, CK_OBJECT_HANDLE objectID, CK_SESSION_HANDLE hSession); -void freeTemplate(CK_ATTRIBUTE* attTemplate, int size); +void freeTemplate(CK_ATTRIBUTE* attTemplate, int startIndex, int size); // Database functions diff --git a/SoftHSMv2/src/bin/util/Makefile.am b/SoftHSMv2/src/bin/util/Makefile.am index a552e14..788ea87 100644 --- a/SoftHSMv2/src/bin/util/Makefile.am +++ b/SoftHSMv2/src/bin/util/Makefile.am @@ -36,5 +36,6 @@ if WITH_BOTAN softhsm2_util_SOURCES += softhsm2-util-botan.cpp endif -EXTRA_DIST = $(srcdir)/*.h \ +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ $(srcdir)/*.cpp diff --git a/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp b/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp index cecc0ce..c7b1da3 100644 --- a/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp +++ b/SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp @@ -47,6 +47,7 @@ #include <botan/bigint.h> #include <botan/version.h> #include <botan/der_enc.h> +#include <botan/oids.h> #if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14) #include <botan/libstate.h> @@ -162,6 +163,10 @@ int crypto_import_key_pair #ifdef WITH_ECC Botan::ECDSA_PrivateKey* ecdsa = NULL; #endif +#ifdef WITH_EDDSA + Botan::Curve25519_PrivateKey* x25519 = NULL; + Botan::Ed25519_PrivateKey* ed25519 = NULL; +#endif if (pkey->algo_name().compare("RSA") == 0) { @@ -177,6 +182,16 @@ int crypto_import_key_pair ecdsa = dynamic_cast<Botan::ECDSA_PrivateKey*>(pkey); } #endif +#ifdef WITH_EDDSA + else if (pkey->algo_name().compare("Curve25519") == 0) + { + x25519 = dynamic_cast<Botan::Curve25519_PrivateKey*>(pkey); + } + else if (pkey->algo_name().compare("Ed25519") == 0) + { + ed25519 = dynamic_cast<Botan::Ed25519_PrivateKey*>(pkey); + } +#endif else { fprintf(stderr, "ERROR: %s is not a supported algorithm.\n", @@ -201,6 +216,16 @@ int crypto_import_key_pair result = crypto_save_ecdsa(hSession, label, objID, objIDLen, noPublicKey, ecdsa); } #endif +#ifdef WITH_EDDSA + else if (x25519) + { + result = crypto_save_eddsa(hSession, label, objID, objIDLen, noPublicKey, x25519, 0); + } + else if (ed25519) + { + result = crypto_save_eddsa(hSession, label, objID, objIDLen, noPublicKey, 0, ed25519); + } +#endif else { fprintf(stderr, "ERROR: Could not get the key material.\n"); @@ -702,3 +727,156 @@ void crypto_free_ecdsa(ecdsa_key_material_t* keyMat) free(keyMat); } #endif + +#ifdef WITH_EDDSA +// Save the key data in PKCS#11 +int crypto_save_eddsa +( + CK_SESSION_HANDLE hSession, + char* label, + char* objID, + size_t objIDLen, + int noPublicKey, + Botan::Curve25519_PrivateKey* x25519, + Botan::Ed25519_PrivateKey* ed25519 +) +{ + eddsa_key_material_t* keyMat = crypto_malloc_eddsa(x25519, ed25519); + if (keyMat == NULL) + { + fprintf(stderr, "ERROR: Could not convert the key material to binary information.\n"); + return 1; + } + + CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY, privClass = CKO_PRIVATE_KEY; + CK_KEY_TYPE keyType = CKK_EC_EDWARDS; + CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE; + if (noPublicKey) + { + ckToken = CK_FALSE; + } + CK_ATTRIBUTE pubTemplate[] = { + { CKA_CLASS, &pubClass, sizeof(pubClass) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_LABEL, label, strlen(label) }, + { CKA_ID, objID, objIDLen }, + { CKA_TOKEN, &ckToken, sizeof(ckToken) }, + { CKA_VERIFY, &ckTrue, sizeof(ckTrue) }, + { CKA_ENCRYPT, &ckFalse, sizeof(ckFalse) }, + { CKA_WRAP, &ckFalse, sizeof(ckFalse) }, + { CKA_EC_PARAMS, keyMat->derOID, keyMat->sizeOID }, + { CKA_EC_POINT, keyMat->bigA, keyMat->sizeA }, + }; + CK_ATTRIBUTE privTemplate[] = { + { CKA_CLASS, &privClass, sizeof(privClass) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_LABEL, label, strlen(label) }, + { CKA_ID, objID, objIDLen }, + { CKA_SIGN, &ckTrue, sizeof(ckTrue) }, + { CKA_DECRYPT, &ckFalse, sizeof(ckFalse) }, + { CKA_UNWRAP, &ckFalse, sizeof(ckFalse) }, + { CKA_SENSITIVE, &ckTrue, sizeof(ckTrue) }, + { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, + { CKA_PRIVATE, &ckTrue, sizeof(ckTrue) }, + { CKA_EXTRACTABLE, &ckFalse, sizeof(ckFalse) }, + { CKA_EC_PARAMS, keyMat->derOID, keyMat->sizeOID }, + { CKA_VALUE, keyMat->bigK, keyMat->sizeK } + }; + + CK_OBJECT_HANDLE hKey1, hKey2; + CK_RV rv = p11->C_CreateObject(hSession, privTemplate, 13, &hKey1); + if (rv != CKR_OK) + { + fprintf(stderr, "ERROR: Could not save the private key in the token. " + "Maybe the algorithm is not supported.\n"); + crypto_free_eddsa(keyMat); + return 1; + } + + rv = p11->C_CreateObject(hSession, pubTemplate, 10, &hKey2); + crypto_free_eddsa(keyMat); + + if (rv != CKR_OK) + { + p11->C_DestroyObject(hSession, hKey1); + fprintf(stderr, "ERROR: Could not save the public key in the token.\n"); + return 1; + } + + printf("The key pair has been imported.\n"); + + return 0; +} + +// Convert the OpenSSL key to binary +eddsa_key_material_t* crypto_malloc_eddsa +( + Botan::Curve25519_PrivateKey* x25519, + Botan::Ed25519_PrivateKey* ed25519 + ) +{ + if ((x25519 == NULL) && (ed25519 == NULL)) + { + return NULL; + } + + eddsa_key_material_t* keyMat = (eddsa_key_material_t*)malloc(sizeof(eddsa_key_material_t)); + if (keyMat == NULL) + { + return NULL; + } + + Botan::OID oid; + if (x25519) oid = Botan::OIDS::lookup("Curve25519"); + if (ed25519) oid = Botan::OIDS::lookup("Ed25519"); + if (oid.empty()) + { + return NULL; + } + + Botan::secure_vector<Botan::byte> derOID; + derOID = Botan::DER_Encoder().encode(oid).get_contents(); + + memset(keyMat, 0, sizeof(*keyMat)); + keyMat->sizeOID = derOID.size(); + keyMat->derOID = (CK_VOID_PTR)malloc(keyMat->sizeOID); + + std::vector<Botan::byte> pub; + if (x25519) pub = x25519->public_value(); + if (ed25519) pub = ed25519->get_public_key(); + keyMat->sizeA = pub.size(); + keyMat->bigA = (CK_VOID_PTR)malloc(keyMat->sizeA); + + Botan::secure_vector<Botan::byte> priv; + if (x25519) priv = x25519->get_x(); + if (ed25519) + { + priv = ed25519->get_private_key(); + priv.resize(32); + } + keyMat->sizeK = priv.size(); + keyMat->bigK = (CK_VOID_PTR)malloc(keyMat->sizeK); + + if (!keyMat->derOID || !keyMat->bigK || !keyMat->bigA) + { + crypto_free_eddsa(keyMat); + return NULL; + } + + memcpy(keyMat->derOID, derOID.data(), keyMat->sizeOID); + memcpy(keyMat->bigA, pub.data(), keyMat->sizeA); + memcpy(keyMat->bigK, priv.data(), keyMat->sizeK); + + return keyMat; +} + +// Free the memory of the key +void crypto_free_eddsa(eddsa_key_material_t* keyMat) +{ + if (keyMat == NULL) return; + if (keyMat->derOID) free(keyMat->derOID); + if (keyMat->bigK) free(keyMat->bigK); + if (keyMat->bigA) free(keyMat->bigA); + free(keyMat); +} +#endif diff --git a/SoftHSMv2/src/bin/util/softhsm2-util-botan.h b/SoftHSMv2/src/bin/util/softhsm2-util-botan.h index 8cd4a5e..6ad7664 100644 --- a/SoftHSMv2/src/bin/util/softhsm2-util-botan.h +++ b/SoftHSMv2/src/bin/util/softhsm2-util-botan.h @@ -38,6 +38,12 @@ #ifdef WITH_ECC #include <botan/ecdsa.h> #endif +#ifdef WITH_EDDSA +#include <botan/curve25519.h> +#include <botan/ed25519.h> +// #include <botan/curve448.h> +// #include <botan/ed448.h> +#endif typedef struct rsa_key_material_t { CK_ULONG sizeE; @@ -120,6 +126,25 @@ typedef struct ecdsa_key_material_t { } ecdsa_key_material_t; #endif +#ifdef WITH_EDDSA +typedef struct eddsa_key_material_t { + CK_ULONG sizeOID; + CK_ULONG sizeK; + CK_ULONG sizeA; + CK_VOID_PTR derOID; + CK_VOID_PTR bigK; + CK_VOID_PTR bigA; + eddsa_key_material_t() { + sizeOID = 0; + sizeK = 0; + sizeA = 0; + derOID = NULL_PTR; + bigK = NULL_PTR; + bigA = NULL_PTR; + } +} eddsa_key_material_t; +#endif + Botan::Private_Key* crypto_read_file(char* filePath, char* filePIN); // RSA @@ -139,4 +164,11 @@ ecdsa_key_material_t* crypto_malloc_ecdsa(Botan::ECDSA_PrivateKey* ecdsa); void crypto_free_ecdsa(ecdsa_key_material_t* keyMat); #endif -#endif // !_SOFTHSM_V2_SOFTHSM2_UTIL_OSSL_H +// EDDSA +#ifdef WITH_EDDSA +int crypto_save_eddsa(CK_SESSION_HANDLE hSession, char* label, char* objID, size_t objIDLen, int noPublicKey, Botan::Curve25519_PrivateKey* x25519, Botan::Ed25519_PrivateKey* ed25519); +eddsa_key_material_t* crypto_malloc_eddsa(Botan::Curve25519_PrivateKey* x25519, Botan::Ed25519_PrivateKey* ed25519); +void crypto_free_eddsa(eddsa_key_material_t* keyMat); +#endif + +#endif // !_SOFTHSM_V2_SOFTHSM2_UTIL_BOTAN_H diff --git a/SoftHSMv2/src/bin/util/softhsm2-util-ossl.cpp b/SoftHSMv2/src/bin/util/softhsm2-util-ossl.cpp index fedfd28..e56dfba 100644 --- a/SoftHSMv2/src/bin/util/softhsm2-util-ossl.cpp +++ b/SoftHSMv2/src/bin/util/softhsm2-util-ossl.cpp @@ -46,6 +46,7 @@ #include <openssl/evp.h> #include <openssl/err.h> #include <openssl/pkcs12.h> +#include <openssl/objects.h> // Init OpenSSL void crypto_init() @@ -146,6 +147,9 @@ int crypto_import_key_pair #ifdef WITH_ECC EC_KEY* ecdsa = NULL; #endif +#ifdef WITH_EDDSA + EVP_PKEY* eddsa = NULL; +#endif switch (EVP_PKEY_type(EVP_PKEY_id(pkey))) { @@ -160,6 +164,15 @@ int crypto_import_key_pair ecdsa = EVP_PKEY_get1_EC_KEY(pkey); break; #endif +#ifdef WITH_EDDSA + case NID_X25519: + case NID_ED25519: + case NID_X448: + case NID_ED448: + EVP_PKEY_up_ref(pkey); + eddsa = pkey; + break; +#endif default: fprintf(stderr, "ERROR: Cannot handle this algorithm.\n"); EVP_PKEY_free(pkey); @@ -187,6 +200,13 @@ int crypto_import_key_pair EC_KEY_free(ecdsa); } #endif +#ifdef WITH_EDDSA + else if (eddsa) + { + result = crypto_save_eddsa(hSession, label, objID, objIDLen, noPublicKey, eddsa); + EVP_PKEY_free(eddsa); + } +#endif else { fprintf(stderr, "ERROR: Could not get the key material.\n"); @@ -788,3 +808,183 @@ void crypto_free_ecdsa(ecdsa_key_material_t* keyMat) } #endif + +#ifdef WITH_EDDSA + +// Save the key data in PKCS#11 +int crypto_save_eddsa +( + CK_SESSION_HANDLE hSession, + char* label, + char* objID, + size_t objIDLen, + int noPublicKey, + EVP_PKEY* eddsa +) +{ + eddsa_key_material_t* keyMat = crypto_malloc_eddsa(eddsa); + if (keyMat == NULL) + { + fprintf(stderr, "ERROR: Could not convert the key material to binary information.\n"); + return 1; + } + + CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY, privClass = CKO_PRIVATE_KEY; + CK_KEY_TYPE keyType = CKK_EC_EDWARDS; + CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE; + if (noPublicKey) + { + ckToken = CK_FALSE; + } + CK_ATTRIBUTE pubTemplate[] = { + { CKA_CLASS, &pubClass, sizeof(pubClass) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_LABEL, label, strlen(label) }, + { CKA_ID, objID, objIDLen }, + { CKA_TOKEN, &ckToken, sizeof(ckToken) }, + { CKA_VERIFY, &ckTrue, sizeof(ckTrue) }, + { CKA_ENCRYPT, &ckFalse, sizeof(ckFalse) }, + { CKA_WRAP, &ckFalse, sizeof(ckFalse) }, + { CKA_EC_PARAMS, keyMat->derOID, keyMat->sizeOID }, + { CKA_EC_POINT, keyMat->bigA, keyMat->sizeA }, + }; + CK_ATTRIBUTE privTemplate[] = { + { CKA_CLASS, &privClass, sizeof(privClass) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_LABEL, label, strlen(label) }, + { CKA_ID, objID, objIDLen }, + { CKA_SIGN, &ckTrue, sizeof(ckTrue) }, + { CKA_DECRYPT, &ckFalse, sizeof(ckFalse) }, + { CKA_UNWRAP, &ckFalse, sizeof(ckFalse) }, + { CKA_SENSITIVE, &ckTrue, sizeof(ckTrue) }, + { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, + { CKA_PRIVATE, &ckTrue, sizeof(ckTrue) }, + { CKA_EXTRACTABLE, &ckFalse, sizeof(ckFalse) }, + { CKA_EC_PARAMS, keyMat->derOID, keyMat->sizeOID }, + { CKA_VALUE, keyMat->bigK, keyMat->sizeK } + }; + + CK_OBJECT_HANDLE hKey1, hKey2; + CK_RV rv = p11->C_CreateObject(hSession, privTemplate, 13, &hKey1); + if (rv != CKR_OK) + { + fprintf(stderr, "ERROR: Could not save the private key in the token. " + "Maybe the algorithm is not supported.\n"); + crypto_free_eddsa(keyMat); + return 1; + } + + rv = p11->C_CreateObject(hSession, pubTemplate, 10, &hKey2); + crypto_free_eddsa(keyMat); + + if (rv != CKR_OK) + { + p11->C_DestroyObject(hSession, hKey1); + fprintf(stderr, "ERROR: Could not save the public key in the token.\n"); + return 1; + } + + printf("The key pair has been imported.\n"); + + return 0; +} + +// Convert the OpenSSL key to binary + +#define X25519_KEYLEN 32 +#define X448_KEYLEN 57 + +#define PUBPREFIXLEN 12 +#define PRIVPREFIXLEN 16 + +eddsa_key_material_t* crypto_malloc_eddsa(EVP_PKEY* pkey) +{ + int result; + int len; + unsigned char *buf; + + if (pkey == NULL) + { + return NULL; + } + + eddsa_key_material_t* keyMat = (eddsa_key_material_t*)malloc(sizeof(eddsa_key_material_t)); + if (keyMat == NULL) + { + return NULL; + } + + int nid = EVP_PKEY_id(pkey); + memset(keyMat, 0, sizeof(*keyMat)); + keyMat->sizeOID = i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL); + keyMat->derOID = (CK_VOID_PTR)malloc(keyMat->sizeOID); + + switch (nid) { + case NID_X25519: + case NID_ED25519: + keyMat->sizeK = X25519_KEYLEN; + keyMat->sizeA = X25519_KEYLEN; + break; + case NID_X448: + case NID_ED448: + keyMat->sizeK = X448_KEYLEN; + keyMat->sizeA = X448_KEYLEN; + break; + default: + crypto_free_eddsa(keyMat); + return NULL; + } + keyMat->bigK = (CK_VOID_PTR)malloc(keyMat->sizeK); + keyMat->bigA = (CK_VOID_PTR)malloc(keyMat->sizeA); + if (!keyMat->derOID || !keyMat->bigK || !keyMat->bigA) + { + crypto_free_eddsa(keyMat); + return NULL; + } + + unsigned char *p = (unsigned char*) keyMat->derOID; + result = i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p); + if (result <= 0) + { + crypto_free_eddsa(keyMat); + return NULL; + } + + len = i2d_PUBKEY(pkey, NULL); + if (((CK_ULONG) len != PUBPREFIXLEN + keyMat->sizeA) || + ((buf = (unsigned char*) malloc(len)) == NULL)) + { + crypto_free_eddsa(keyMat); + return NULL; + } + p = buf; + i2d_PUBKEY(pkey, &p); + memcpy(keyMat->bigA, buf + PUBPREFIXLEN, keyMat->sizeA); + free(buf); + + len = i2d_PrivateKey(pkey, NULL); + if (((CK_ULONG) len != PRIVPREFIXLEN + keyMat->sizeK) || + ((buf = (unsigned char*) malloc(len)) == NULL)) + { + crypto_free_eddsa(keyMat); + return NULL; + } + p = buf; + i2d_PrivateKey(pkey, &p); + memcpy(keyMat->bigK, buf + PRIVPREFIXLEN, keyMat->sizeK); + free(buf); + + return keyMat; +} + +// Free the memory of the key +void crypto_free_eddsa(eddsa_key_material_t* keyMat) +{ + if (keyMat == NULL) return; + if (keyMat->derOID) free(keyMat->derOID); + if (keyMat->bigK) free(keyMat->bigK); + if (keyMat->bigA) free(keyMat->bigA); + free(keyMat); +} + +#endif diff --git a/SoftHSMv2/src/bin/util/softhsm2-util-ossl.h b/SoftHSMv2/src/bin/util/softhsm2-util-ossl.h index 7a2a31a..8fac612 100644 --- a/SoftHSMv2/src/bin/util/softhsm2-util-ossl.h +++ b/SoftHSMv2/src/bin/util/softhsm2-util-ossl.h @@ -38,6 +38,9 @@ #ifdef WITH_ECC #include <openssl/ec.h> #endif +#ifdef WITH_EDDSA +#include <openssl/evp.h> +#endif typedef struct rsa_key_material_t { CK_ULONG sizeE; @@ -120,6 +123,25 @@ typedef struct ecdsa_key_material_t { } ecdsa_key_material_t; #endif +#ifdef WITH_EDDSA +typedef struct eddsa_key_material_t { + CK_ULONG sizeOID; + CK_ULONG sizeK; + CK_ULONG sizeA; + CK_VOID_PTR derOID; + CK_VOID_PTR bigK; + CK_VOID_PTR bigA; + eddsa_key_material_t() { + sizeOID = 0; + sizeK = 0; + sizeA = 0; + derOID = NULL_PTR; + bigK = NULL_PTR; + bigA = NULL_PTR; + } +} eddsa_key_material_t; +#endif + EVP_PKEY* crypto_read_file(char* filePath, char* filePIN); // RSA @@ -139,4 +161,11 @@ ecdsa_key_material_t* crypto_malloc_ecdsa(EC_KEY* ecdsa); void crypto_free_ecdsa(ecdsa_key_material_t* keyMat); #endif +#ifdef WITH_EDDSA +// EDDSA +int crypto_save_eddsa(CK_SESSION_HANDLE hSession, char* label, char* objID, size_t objIDLen, int noPublicKey, EVP_PKEY* eddsa); +eddsa_key_material_t* crypto_malloc_eddsa(EVP_PKEY* eddsa); +void crypto_free_eddsa(eddsa_key_material_t* keyMat); +#endif + #endif // !_SOFTHSM_V2_SOFTHSM2_UTIL_OSSL_H diff --git a/SoftHSMv2/src/lib/HwInfra/README b/SoftHSMv2/src/lib/HwInfra/README index ea301af..ea301af 100755..100644 --- a/SoftHSMv2/src/lib/HwInfra/README +++ b/SoftHSMv2/src/lib/HwInfra/README diff --git a/SoftHSMv2/src/lib/HwInfra/hwpluginif.h b/SoftHSMv2/src/lib/HwInfra/hwpluginif.h index 34a91f0..34a91f0 100755..100644 --- a/SoftHSMv2/src/lib/HwInfra/hwpluginif.h +++ b/SoftHSMv2/src/lib/HwInfra/hwpluginif.h diff --git a/SoftHSMv2/src/lib/Makefile.am b/SoftHSMv2/src/lib/Makefile.am index eac1704..8c4837e 100644 --- a/SoftHSMv2/src/lib/Makefile.am +++ b/SoftHSMv2/src/lib/Makefile.am @@ -48,5 +48,6 @@ SUBDIRS = common \ handle_mgr \ test -EXTRA_DIST = $(srcdir)/*.h \ - $(srcdir)/pkcs11/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ + $(srcdir)/pkcs11/*.h
\ No newline at end of file diff --git a/SoftHSMv2/src/lib/P11Attributes.cpp b/SoftHSMv2/src/lib/P11Attributes.cpp index 5a56097..264a0d8 100644 --- a/SoftHSMv2/src/lib/P11Attributes.cpp +++ b/SoftHSMv2/src/lib/P11Attributes.cpp @@ -2354,7 +2354,7 @@ CK_RV P11AttrWrapTemplate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK_V case CKA_KEY_GEN_MECHANISM: case CKA_MODULUS_BITS: case CKA_PRIME_BITS: - case CKA_SUBPRIME_BITS: + case CKA_SUB_PRIME_BITS: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_AUTH_PIN_FLAGS: @@ -2453,7 +2453,7 @@ CK_RV P11AttrUnwrapTemplate::updateAttr(Token* /*token*/, bool /*isPrivate*/, CK case CKA_KEY_GEN_MECHANISM: case CKA_MODULUS_BITS: case CKA_PRIME_BITS: - case CKA_SUBPRIME_BITS: + case CKA_SUB_PRIME_BITS: case CKA_VALUE_BITS: case CKA_VALUE_LEN: case CKA_AUTH_PIN_FLAGS: diff --git a/SoftHSMv2/src/lib/P11Attributes.h b/SoftHSMv2/src/lib/P11Attributes.h index 8c9b98b..d40a9f5 100644 --- a/SoftHSMv2/src/lib/P11Attributes.h +++ b/SoftHSMv2/src/lib/P11Attributes.h @@ -346,7 +346,7 @@ class P11AttrPublicKeyInfo : public P11Attribute { public: // Constructor - P11AttrPublicKeyInfo(OSObject* inobject, CK_ULONG inchecks) : P11Attribute(inobject) { type = CKA_OBJECT_ID; checks = inchecks; } + P11AttrPublicKeyInfo(OSObject* inobject, CK_ULONG inchecks) : P11Attribute(inobject) { type = CKA_PUBLIC_KEY_INFO; checks = inchecks; } protected: // Set the default value of the attribute diff --git a/SoftHSMv2/src/lib/P11Objects.cpp b/SoftHSMv2/src/lib/P11Objects.cpp index 3e663b2..8ba9801 100644 --- a/SoftHSMv2/src/lib/P11Objects.cpp +++ b/SoftHSMv2/src/lib/P11Objects.cpp @@ -886,6 +886,51 @@ bool P11ECPublicKeyObj::init(OSObject *inobject) } // Constructor +P11EDPublicKeyObj::P11EDPublicKeyObj() +{ + initialized = false; +} + +// Add attributes +bool P11EDPublicKeyObj::init(OSObject *inobject) +{ + if (initialized) return true; + if (inobject == NULL) return false; + + if (!inobject->attributeExists(CKA_KEY_TYPE) || inobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_EC_EDWARDS) { + OSAttribute setKeyType((unsigned long)CKK_EC_EDWARDS); + inobject->setAttribute(CKA_KEY_TYPE, setKeyType); + } + + // Create parent + if (!P11PublicKeyObj::init(inobject)) return false; + + // Create attributes + P11Attribute* attrEcParams = new P11AttrEcParams(osobject,P11Attribute::ck3); + P11Attribute* attrEcPoint = new P11AttrEcPoint(osobject); + + // Initialize the attributes + if + ( + !attrEcParams->init() || + !attrEcPoint->init() + ) + { + ERROR_MSG("Could not initialize the attribute"); + delete attrEcParams; + delete attrEcPoint; + return false; + } + + // Add them to the map + attributes[attrEcParams->getType()] = attrEcParams; + attributes[attrEcPoint->getType()] = attrEcPoint; + + initialized = true; + return true; +} + +// Constructor P11DHPublicKeyObj::P11DHPublicKeyObj() { initialized = false; @@ -1247,7 +1292,51 @@ bool P11ECPrivateKeyObj::init(OSObject *inobject) // Add them to the map attributes[attrEcParams->getType()] = attrEcParams; attributes[attrValue->getType()] = attrValue; - attributes[attrPrivateHandle->getType()] = attrPrivateHandle; + attributes[attrPrivateHandle->getType()] = attrPrivateHandle; + initialized = true; + return true; +} + +// Constructor +P11EDPrivateKeyObj::P11EDPrivateKeyObj() +{ + initialized = false; +} + +// Add attributes +bool P11EDPrivateKeyObj::init(OSObject *inobject) +{ + if (initialized) return true; + if (inobject == NULL) return false; + + if (!inobject->attributeExists(CKA_KEY_TYPE) || inobject->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_EC_EDWARDS) { + OSAttribute setKeyType((unsigned long)CKK_EC_EDWARDS); + inobject->setAttribute(CKA_KEY_TYPE, setKeyType); + } + + // Create parent + if (!P11PrivateKeyObj::init(inobject)) return false; + + // Create attributes + P11Attribute* attrEcParams = new P11AttrEcParams(osobject,P11Attribute::ck4|P11Attribute::ck6); + P11Attribute* attrValue = new P11AttrValue(osobject,P11Attribute::ck1|P11Attribute::ck4|P11Attribute::ck6|P11Attribute::ck7); + + // Initialize the attributes + if + ( + !attrEcParams->init() || + !attrValue->init() + ) + { + ERROR_MSG("Could not initialize the attribute"); + delete attrEcParams; + delete attrValue; + return false; + } + + // Add them to the map + attributes[attrEcParams->getType()] = attrEcParams; + attributes[attrValue->getType()] = attrValue; initialized = true; return true; diff --git a/SoftHSMv2/src/lib/P11Objects.h b/SoftHSMv2/src/lib/P11Objects.h index 942a8c4..9d223ac 100644 --- a/SoftHSMv2/src/lib/P11Objects.h +++ b/SoftHSMv2/src/lib/P11Objects.h @@ -185,6 +185,19 @@ protected: bool initialized; }; +class P11EDPublicKeyObj : public P11PublicKeyObj +{ +public: + // Constructor + P11EDPublicKeyObj(); + + // Add attributes + virtual bool init(OSObject *inobject); + +protected: + bool initialized; +}; + class P11DHPublicKeyObj : public P11PublicKeyObj { public: @@ -261,6 +274,19 @@ protected: bool initialized; }; +class P11EDPrivateKeyObj : public P11PrivateKeyObj +{ +public: + // Constructor + P11EDPrivateKeyObj(); + + // Add attributes + virtual bool init(OSObject *inobject); + +protected: + bool initialized; +}; + class P11DHPrivateKeyObj : public P11PrivateKeyObj { public: diff --git a/SoftHSMv2/src/lib/SoftHSM.cpp b/SoftHSMv2/src/lib/SoftHSM.cpp index acb90a3..bdf5a90 100644 --- a/SoftHSMv2/src/lib/SoftHSM.cpp +++ b/SoftHSMv2/src/lib/SoftHSM.cpp @@ -42,6 +42,7 @@ #include "AsymmetricAlgorithm.h" #include "SymmetricAlgorithm.h" #include "AESKey.h" +#include "DerUtil.h" #include "DESKey.h" #include "RNG.h" #include "RSAParameters.h" @@ -53,6 +54,8 @@ #include "ECPublicKey.h" #include "ECPrivateKey.h" #include "ECParameters.h" +#include "EDPublicKey.h" +#include "EDPrivateKey.h" #include "DHParameters.h" #include "DHPublicKey.h" #include "DHPrivateKey.h" @@ -150,6 +153,8 @@ static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERT *p11object = new P11DHPublicKeyObj(); else if (keyType == CKK_GOSTR3410) *p11object = new P11GOSTPublicKeyObj(); + else if (keyType == CKK_EC_EDWARDS) + *p11object = new P11EDPublicKeyObj(); else return CKR_ATTRIBUTE_VALUE_INVALID; break; @@ -165,6 +170,8 @@ static CK_RV newP11Object(CK_OBJECT_CLASS objClass, CK_KEY_TYPE keyType, CK_CERT *p11object = new P11DHPrivateKeyObj(); else if (keyType == CKK_GOSTR3410) *p11object = new P11GOSTPrivateKeyObj(); + else if (keyType == CKK_EC_EDWARDS) + *p11object = new P11EDPrivateKeyObj(); else return CKR_ATTRIBUTE_VALUE_INVALID; break; @@ -338,6 +345,15 @@ static CK_ATTRIBUTE bsAttribute(CK_ATTRIBUTE_TYPE type, const ByteString &value) /***************************************************************************** Implementation of SoftHSM class specific functions *****************************************************************************/ +static void resetMutexFactoryCallbacks() +{ + // Reset MutexFactory callbacks to our versions + MutexFactory::i()->setCreateMutex(OSCreateMutex); + MutexFactory::i()->setDestroyMutex(OSDestroyMutex); + MutexFactory::i()->setLockMutex(OSLockMutex); + MutexFactory::i()->setUnlockMutex(OSUnlockMutex); +} + // Return the one-and-only instance SoftHSM* SoftHSM::i() @@ -373,10 +389,17 @@ SoftHSM::SoftHSM() SoftHSM::~SoftHSM() { if (handleManager != NULL) delete handleManager; + handleManager = NULL; if (sessionManager != NULL) delete sessionManager; + sessionManager = NULL; if (slotManager != NULL) delete slotManager; + slotManager = NULL; if (objectStore != NULL) delete objectStore; + objectStore = NULL; if (sessionObjectStore != NULL) delete sessionObjectStore; + sessionObjectStore = NULL; + + resetMutexFactoryCallbacks(); } /***************************************************************************** @@ -427,10 +450,7 @@ CK_RV SoftHSM::C_Initialize(CK_VOID_PTR pInitArgs) if (args->flags & CKF_OS_LOCKING_OK) { // Use our own mutex functions. - MutexFactory::i()->setCreateMutex(OSCreateMutex); - MutexFactory::i()->setDestroyMutex(OSDestroyMutex); - MutexFactory::i()->setLockMutex(OSLockMutex); - MutexFactory::i()->setUnlockMutex(OSUnlockMutex); + resetMutexFactoryCallbacks(); MutexFactory::i()->enable(); } else @@ -663,9 +683,12 @@ CK_RV SoftHSM::C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) CK_RV SoftHSM::C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { // A list with the supported mechanisms - CK_ULONG nrSupportedMechanisms = 61; + CK_ULONG nrSupportedMechanisms = 62; #ifdef WITH_ECC - nrSupportedMechanisms += 3; + nrSupportedMechanisms += 2; +#endif +#if defined(WITH_ECC) || defined(WITH_EDDSA) + nrSupportedMechanisms += 1; #endif #ifdef WITH_FIPS nrSupportedMechanisms -= 9; @@ -682,6 +705,9 @@ CK_RV SoftHSM::C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMech #ifdef WITH_AES_GCM nrSupportedMechanisms += 1; #endif +#ifdef WITH_EDDSA + nrSupportedMechanisms += 2; +#endif CK_MECHANISM_TYPE supportedMechanisms[] = { @@ -721,6 +747,7 @@ CK_RV SoftHSM::C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMech CKM_SHA256_RSA_PKCS_PSS, CKM_SHA384_RSA_PKCS_PSS, CKM_SHA512_RSA_PKCS_PSS, + CKM_GENERIC_SECRET_KEY_GEN, #ifndef WITH_FIPS CKM_DES_KEY_GEN, #endif @@ -768,6 +795,8 @@ CK_RV SoftHSM::C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMech #ifdef WITH_ECC CKM_EC_KEY_PAIR_GEN, CKM_ECDSA, +#endif +#if defined(WITH_ECC) || defined(WITH_EDDSA) CKM_ECDH1_DERIVE, #endif #ifdef WITH_GOST @@ -775,7 +804,11 @@ CK_RV SoftHSM::C_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMech CKM_GOSTR3411_HMAC, CKM_GOSTR3410_KEY_PAIR_GEN, CKM_GOSTR3410, - CKM_GOSTR3410_WITH_GOSTR3411 + CKM_GOSTR3410_WITH_GOSTR3411, +#endif +#ifdef WITH_EDDSA + CKM_EC_EDWARDS_KEY_PAIR_GEN, + CKM_EDDSA, #endif }; @@ -820,7 +853,10 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ unsigned long dhMinSize, dhMaxSize; #ifdef WITH_ECC unsigned long ecdsaMinSize, ecdsaMaxSize; - unsigned long ecdhMinSize, ecdhMaxSize; +#endif +#if defined(WITH_ECC) || defined(WITH_EDDSA) + unsigned long ecdhMinSize = 0, ecdhMaxSize = 0; + unsigned long eddsaMinSize = 0, eddsaMaxSize = 0; #endif if (!isInitialised) return CKR_CRYPTOKI_NOT_INITIALIZED; @@ -905,6 +941,19 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh); #endif +#ifdef WITH_EDDSA + AsymmetricAlgorithm* eddsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA); + if (eddsa != NULL) + { + eddsaMinSize = eddsa->getMinKeySize(); + eddsaMaxSize = eddsa->getMaxKeySize(); + } + else + { + return CKR_GENERAL_ERROR; + } + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); +#endif switch (type) { #ifndef WITH_FIPS @@ -992,6 +1041,11 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ pInfo->ulMaxKeySize = rsaMaxSize; pInfo->flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; break; + case CKM_GENERIC_SECRET_KEY_GEN: + pInfo->ulMinKeySize = 1; + pInfo->ulMaxKeySize = 0x80000000; + pInfo->flags = CKF_GENERATE; + break; #ifndef WITH_FIPS case CKM_DES_KEY_GEN: #endif @@ -1114,9 +1168,11 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ pInfo->ulMaxKeySize = ecdsaMaxSize; pInfo->flags = CKF_SIGN | CKF_VERIFY | CKF_EC_COMMOM; break; +#endif +#if defined(WITH_ECC) || defined(WITH_EDDSA) case CKM_ECDH1_DERIVE: - pInfo->ulMinKeySize = ecdhMinSize; - pInfo->ulMaxKeySize = ecdhMaxSize; + pInfo->ulMinKeySize = ecdhMinSize ? ecdhMinSize : eddsaMinSize; + pInfo->ulMaxKeySize = ecdhMaxSize ? ecdhMaxSize : eddsaMaxSize; pInfo->flags = CKF_DERIVE; break; #endif @@ -1152,6 +1208,18 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_ pInfo->flags = CKF_SIGN | CKF_VERIFY; break; #endif +#ifdef WITH_EDDSA + case CKM_EC_EDWARDS_KEY_PAIR_GEN: + pInfo->ulMinKeySize = eddsaMinSize; + pInfo->ulMaxKeySize = eddsaMaxSize; + pInfo->flags = CKF_GENERATE_KEY_PAIR; + break; + case CKM_EDDSA: + pInfo->ulMinKeySize = eddsaMinSize; + pInfo->ulMaxKeySize = eddsaMaxSize; + pInfo->flags = CKF_SIGN | CKF_VERIFY; + break; +#endif default: DEBUG_MSG("The selected mechanism is not supported"); return CKR_MECHANISM_INVALID; @@ -3880,7 +3948,12 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan bool bAllowMultiPartOp; bool isRSA = false; bool isDSA = false; +#ifdef WITH_ECC bool isECDSA = false; +#endif +#ifdef WITH_EDDSA + bool isEDDSA = false; +#endif switch(pMechanism->mechanism) { case CKM_RSA_PKCS: mechanism = AsymMech::RSA_PKCS; @@ -4115,6 +4188,13 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan bAllowMultiPartOp = true; break; #endif +#ifdef WITH_EDDSA + case CKM_EDDSA: + mechanism = AsymMech::EDDSA; + bAllowMultiPartOp = false; + isEDDSA = true; + break; +#endif default: return CKR_MECHANISM_INVALID; } @@ -4180,6 +4260,27 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan } } #endif +#ifdef WITH_EDDSA + else if (isEDDSA) + { + asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA); + if (asymCrypto == NULL) return CKR_MECHANISM_INVALID; + + privateKey = asymCrypto->newPrivateKey(); + if (privateKey == NULL) + { + CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto); + return CKR_HOST_MEMORY; + } + + if (getEDPrivateKey((EDPrivateKey*)privateKey, token, key) != CKR_OK) + { + asymCrypto->recyclePrivateKey(privateKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto); + return CKR_GENERAL_ERROR; + } + } +#endif else { #ifdef WITH_GOST @@ -5070,7 +5171,12 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech bool bAllowMultiPartOp; bool isRSA = false; bool isDSA = false; +#ifdef WITH_ECC bool isECDSA = false; +#endif +#ifdef WITH_EDDSA + bool isEDDSA = false; +#endif switch(pMechanism->mechanism) { case CKM_RSA_PKCS: mechanism = AsymMech::RSA_PKCS; @@ -5303,6 +5409,13 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech bAllowMultiPartOp = true; break; #endif +#ifdef WITH_EDDSA + case CKM_EDDSA: + mechanism = AsymMech::EDDSA; + bAllowMultiPartOp = false; + isEDDSA = true; + break; +#endif default: return CKR_MECHANISM_INVALID; } @@ -5368,6 +5481,27 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech } } #endif +#ifdef WITH_EDDSA + else if (isEDDSA) + { + asymCrypto = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA); + if (asymCrypto == NULL) return CKR_MECHANISM_INVALID; + + publicKey = asymCrypto->newPublicKey(); + if (publicKey == NULL) + { + CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto); + return CKR_HOST_MEMORY; + } + + if (getEDPublicKey((EDPublicKey*)publicKey, token, key) != CKR_OK) + { + asymCrypto->recyclePublicKey(publicKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(asymCrypto); + return CKR_GENERAL_ERROR; + } + } +#endif else { #ifdef WITH_GOST @@ -5827,6 +5961,10 @@ CK_RV SoftHSM::C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMecha objClass = CKO_SECRET_KEY; keyType = CKK_AES; break; + case CKM_GENERIC_SECRET_KEY_GEN: + objClass = CKO_SECRET_KEY; + keyType = CKK_GENERIC_SECRET; + break; default: return CKR_MECHANISM_INVALID; } @@ -5859,6 +5997,9 @@ CK_RV SoftHSM::C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMecha if (pMechanism->mechanism == CKM_AES_KEY_GEN && (objClass != CKO_SECRET_KEY || keyType != CKK_AES)) return CKR_TEMPLATE_INCONSISTENT; + if (pMechanism->mechanism == CKM_GENERIC_SECRET_KEY_GEN && + (objClass != CKO_SECRET_KEY || keyType != CKK_GENERIC_SECRET)) + return CKR_TEMPLATE_INCONSISTENT; // Check authorization CK_RV rv = haveWrite(session->getState(), isOnToken, isPrivate); @@ -5908,6 +6049,12 @@ CK_RV SoftHSM::C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMecha return this->generateAES(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate); } + // Generate generic secret key + if (pMechanism->mechanism == CKM_GENERIC_SECRET_KEY_GEN) + { + return this->generateGeneric(hSession, pTemplate, ulCount, phKey, isOnToken, isPrivate); + } + return CKR_GENERAL_ERROR; } @@ -5957,6 +6104,11 @@ CK_RV SoftHSM::C_GenerateKeyPair keyType = CKK_GOSTR3410; break; #endif +#ifdef WITH_EDDSA + case CKM_EC_EDWARDS_KEY_PAIR_GEN: + keyType = CKK_EC_EDWARDS; + break; +#endif default: return CKR_MECHANISM_INVALID; } @@ -5982,6 +6134,8 @@ CK_RV SoftHSM::C_GenerateKeyPair return CKR_TEMPLATE_INCONSISTENT; if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN && keyType != CKK_GOSTR3410) return CKR_TEMPLATE_INCONSISTENT; + if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN && keyType != CKK_EC_EDWARDS) + return CKR_TEMPLATE_INCONSISTENT; // Extract information from the private key template that is needed to create the object. CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY; @@ -6003,6 +6157,8 @@ CK_RV SoftHSM::C_GenerateKeyPair return CKR_TEMPLATE_INCONSISTENT; if (pMechanism->mechanism == CKM_GOSTR3410_KEY_PAIR_GEN && keyType != CKK_GOSTR3410) return CKR_TEMPLATE_INCONSISTENT; + if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN && keyType != CKK_EC_EDWARDS) + return CKR_TEMPLATE_INCONSISTENT; // Check user credentials CK_RV rv = haveWrite(session->getState(), ispublicKeyToken || isprivateKeyToken, ispublicKeyPrivate || isprivateKeyPrivate); @@ -6066,6 +6222,16 @@ CK_RV SoftHSM::C_GenerateKeyPair ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate); } + // Generate EDDSA keys + if (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN) + { + return this->generateED(hSession, + pPublicKeyTemplate, ulPublicKeyAttributeCount, + pPrivateKeyTemplate, ulPrivateKeyAttributeCount, + phPublicKey, phPrivateKey, + ispublicKeyToken, ispublicKeyPrivate, isprivateKeyToken, isprivateKeyPrivate); + } + return CKR_GENERAL_ERROR; } @@ -6412,6 +6578,9 @@ CK_RV SoftHSM::C_WrapKey alg = AsymAlgo::ECDSA; break; #endif +#ifdef WITH_EDDSA + // Not yet +#endif #ifdef WITH_GOST case CKK_GOSTR3410: alg = AsymAlgo::GOST; @@ -6927,7 +7096,7 @@ CK_RV SoftHSM::C_DeriveKey switch (pMechanism->mechanism) { case CKM_DH_PKCS_DERIVE: -#ifdef WITH_ECC +#if defined(WITH_ECC) || defined(WITH_EDDSA) case CKM_ECDH1_DERIVE: #endif #ifndef WITH_FIPS @@ -6939,6 +7108,7 @@ CK_RV SoftHSM::C_DeriveKey case CKM_AES_ECB_ENCRYPT_DATA: case CKM_AES_CBC_ENCRYPT_DATA: break; + default: ERROR_MSG("Invalid mechanism"); return CKR_MECHANISM_INVALID; @@ -7021,17 +7191,23 @@ CK_RV SoftHSM::C_DeriveKey return this->deriveDH(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate); } -#ifdef WITH_ECC +#if defined(WITH_ECC) || defined(WITH_EDDSA) // Derive ECDH secret if (pMechanism->mechanism == CKM_ECDH1_DERIVE) { // Check key class and type if (key->getUnsignedLongValue(CKA_CLASS, CKO_VENDOR_DEFINED) != CKO_PRIVATE_KEY) return CKR_KEY_TYPE_INCONSISTENT; - if (key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) != CKK_EC) +#ifdef WITH_ECC + else if (key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) == CKK_EC) + return this->deriveECDH(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate); +#endif +#ifdef WITH_EDDSA + else if (key->getUnsignedLongValue(CKA_KEY_TYPE, CKK_VENDOR_DEFINED) == CKK_EC_EDWARDS) + return this->deriveEDDSA(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate); +#endif + else return CKR_KEY_TYPE_INCONSISTENT; - - return this->deriveECDH(hSession, pMechanism, hBaseKey, pTemplate, ulCount, phKey, keyType, isOnToken, isPrivate); } #endif @@ -7152,6 +7328,177 @@ CK_RV SoftHSM::C_WaitForSlotEvent(CK_FLAGS /*flags*/, CK_SLOT_ID_PTR /*pSlot*/, return CKR_FUNCTION_NOT_SUPPORTED; } +CK_RV SoftHSM::generateGeneric +(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey, + CK_BBOOL isOnToken, + CK_BBOOL isPrivate) +{ + *phKey = CK_INVALID_HANDLE; + + // Get the session + Session* session = (Session*)handleManager->getSession(hSession); + if (session == NULL) + return CKR_SESSION_HANDLE_INVALID; + + // Get the token + Token* token = session->getToken(); + if (token == NULL) + return CKR_GENERAL_ERROR; + + // Extract desired parameter information + size_t keyLen = 0; + bool checkValue = true; + for (CK_ULONG i = 0; i < ulCount; i++) + { + switch (pTemplate[i].type) + { + case CKA_VALUE_LEN: + if (pTemplate[i].ulValueLen != sizeof(CK_ULONG)) + { + INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + keyLen = *(CK_ULONG*)pTemplate[i].pValue; + break; + case CKA_CHECK_VALUE: + if (pTemplate[i].ulValueLen > 0) + { + INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + checkValue = false; + break; + default: + break; + } + } + + // CKA_VALUE_LEN must be specified + if (keyLen == 0) + { + INFO_MSG("Missing CKA_VALUE_LEN in pTemplate"); + return CKR_TEMPLATE_INCOMPLETE; + } + + // Check keyLen + if (keyLen < 1 || keyLen > 0x8000000) + { + INFO_MSG("bad generic key length"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + + // Generate the secret key + RNG* rng = CryptoFactory::i()->getRNG(); + if (rng == NULL) return CKR_GENERAL_ERROR; + ByteString key; + if (!rng->generateRandom(key, keyLen)) return CKR_GENERAL_ERROR; + + CK_RV rv = CKR_OK; + + // Create the secret key object using C_CreateObject + const CK_ULONG maxAttribs = 32; + CK_OBJECT_CLASS objClass = CKO_SECRET_KEY; + CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; + CK_ATTRIBUTE keyAttribs[maxAttribs] = { + { CKA_CLASS, &objClass, sizeof(objClass) }, + { CKA_TOKEN, &isOnToken, sizeof(isOnToken) }, + { CKA_PRIVATE, &isPrivate, sizeof(isPrivate) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + }; + CK_ULONG keyAttribsCount = 4; + + // Add the additional + if (ulCount > (maxAttribs - keyAttribsCount)) + rv = CKR_TEMPLATE_INCONSISTENT; + for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i) + { + switch (pTemplate[i].type) + { + case CKA_CLASS: + case CKA_TOKEN: + case CKA_PRIVATE: + case CKA_KEY_TYPE: + case CKA_CHECK_VALUE: + continue; + default: + keyAttribs[keyAttribsCount++] = pTemplate[i]; + break; + } + } + + if (rv == CKR_OK) + rv = CreateObject(hSession, keyAttribs, keyAttribsCount, phKey, OBJECT_OP_GENERATE); + + // Store the attributes that are being supplied + if (rv == CKR_OK) + { + OSObject* osobject = (OSObject*)handleManager->getObject(*phKey); + if (osobject == NULL_PTR || !osobject->isValid()) { + rv = CKR_FUNCTION_FAILED; + } else if (osobject->startTransaction()) { + bool bOK = true; + + // Common Attributes + bOK = bOK && osobject->setAttribute(CKA_LOCAL,true); + CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_GENERIC_SECRET_KEY_GEN; + bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism); + + // Common Secret Key Attributes + bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false); + bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive); + bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false; + bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable); + + // Generic Secret Key Attributes + ByteString value; + ByteString kcv; + SymmetricKey symKey; + symKey.setKeyBits(key); + symKey.setBitLen(keyLen); + if (isPrivate) + { + token->encrypt(symKey.getKeyBits(), value); + token->encrypt(symKey.getKeyCheckValue(), kcv); + } + else + { + value = symKey.getKeyBits(); + kcv = symKey.getKeyCheckValue(); + } + bOK = bOK && osobject->setAttribute(CKA_VALUE, value); + if (checkValue) + bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv); + + if (bOK) + bOK = osobject->commitTransaction(); + else + osobject->abortTransaction(); + + if (!bOK) + rv = CKR_FUNCTION_FAILED; + } else + rv = CKR_FUNCTION_FAILED; + } + + // Clean up + // Remove the key that may have been created already when the function fails. + if (rv != CKR_OK) + { + if (*phKey != CK_INVALID_HANDLE) + { + OSObject* oskey = (OSObject*)handleManager->getObject(*phKey); + handleManager->destroyObject(*phKey); + if (oskey) oskey->destroyObject(); + *phKey = CK_INVALID_HANDLE; + } + } + + return rv; +} + // Generate an AES secret key CK_RV SoftHSM::generateAES (CK_SESSION_HANDLE hSession, @@ -8430,10 +8777,10 @@ CK_RV SoftHSM::generateDSAParameters } bitLen = *(CK_ULONG*)pTemplate[i].pValue; break; - case CKA_SUBPRIME_BITS: + case CKA_SUB_PRIME_BITS: if (pTemplate[i].ulValueLen != sizeof(CK_ULONG)) { - INFO_MSG("CKA_SUBPRIME_BITS does not have the size of CK_ULONG"); + INFO_MSG("CKA_SUB_PRIME_BITS does not have the size of CK_ULONG"); return CKR_ATTRIBUTE_VALUE_INVALID; } qLen = *(CK_ULONG*)pTemplate[i].pValue; @@ -8450,11 +8797,11 @@ CK_RV SoftHSM::generateDSAParameters return CKR_TEMPLATE_INCOMPLETE; } - // No real choice for CKA_SUBPRIME_BITS + // No real choice for CKA_SUB_PRIME_BITS if ((qLen != 0) && (((bitLen >= 2048) && (qLen != 256)) || ((bitLen < 2048) && (qLen != 160)))) - INFO_MSG("CKA_SUBPRIME_BITS is ignored"); + INFO_MSG("CKA_SUB_PRIME_BITS is ignored"); // Generate domain parameters @@ -8814,6 +9161,252 @@ CK_RV SoftHSM::generateEC return rv; } +// Generate an EDDSA key pair +CK_RV SoftHSM::generateED +(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey, + CK_BBOOL isPublicKeyOnToken, + CK_BBOOL isPublicKeyPrivate, + CK_BBOOL isPrivateKeyOnToken, + CK_BBOOL isPrivateKeyPrivate) +{ + *phPublicKey = CK_INVALID_HANDLE; + *phPrivateKey = CK_INVALID_HANDLE; + + // Get the session + Session* session = (Session*)handleManager->getSession(hSession); + if (session == NULL) + return CKR_SESSION_HANDLE_INVALID; + + // Get the token + Token* token = session->getToken(); + if (token == NULL) + return CKR_GENERAL_ERROR; + + // Extract desired key information + ByteString params; + for (CK_ULONG i = 0; i < ulPublicKeyAttributeCount; i++) + { + switch (pPublicKeyTemplate[i].type) + { + case CKA_EC_PARAMS: + params = ByteString((unsigned char*)pPublicKeyTemplate[i].pValue, pPublicKeyTemplate[i].ulValueLen); + break; + default: + break; + } + } + + // The parameters must be specified to be able to generate a key pair. + if (params.size() == 0) { + INFO_MSG("Missing parameter(s) in pPublicKeyTemplate"); + return CKR_TEMPLATE_INCOMPLETE; + } + + // Set the parameters + ECParameters p; + p.setEC(params); + + // Generate key pair + AsymmetricKeyPair* kp = NULL; + AsymmetricAlgorithm* ec = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA); + if (ec == NULL) return CKR_GENERAL_ERROR; + if (!ec->generateKeyPair(&kp, &p)) + { + ERROR_MSG("Could not generate key pair"); + CryptoFactory::i()->recycleAsymmetricAlgorithm(ec); + return CKR_GENERAL_ERROR; + } + + EDPublicKey* pub = (EDPublicKey*) kp->getPublicKey(); + EDPrivateKey* priv = (EDPrivateKey*) kp->getPrivateKey(); + + CK_RV rv = CKR_OK; + + // Create a public key using C_CreateObject + if (rv == CKR_OK) + { + const CK_ULONG maxAttribs = 32; + CK_OBJECT_CLASS publicKeyClass = CKO_PUBLIC_KEY; + CK_KEY_TYPE publicKeyType = CKK_EC_EDWARDS; + CK_ATTRIBUTE publicKeyAttribs[maxAttribs] = { + { CKA_CLASS, &publicKeyClass, sizeof(publicKeyClass) }, + { CKA_TOKEN, &isPublicKeyOnToken, sizeof(isPublicKeyOnToken) }, + { CKA_PRIVATE, &isPublicKeyPrivate, sizeof(isPublicKeyPrivate) }, + { CKA_KEY_TYPE, &publicKeyType, sizeof(publicKeyType) }, + }; + CK_ULONG publicKeyAttribsCount = 4; + + // Add the additional + if (ulPublicKeyAttributeCount > (maxAttribs - publicKeyAttribsCount)) + rv = CKR_TEMPLATE_INCONSISTENT; + for (CK_ULONG i=0; i < ulPublicKeyAttributeCount && rv == CKR_OK; ++i) + { + switch (pPublicKeyTemplate[i].type) + { + case CKA_CLASS: + case CKA_TOKEN: + case CKA_PRIVATE: + case CKA_KEY_TYPE: + continue; + default: + publicKeyAttribs[publicKeyAttribsCount++] = pPublicKeyTemplate[i]; + } + } + + if (rv == CKR_OK) + rv = this->CreateObject(hSession,publicKeyAttribs,publicKeyAttribsCount,phPublicKey,OBJECT_OP_GENERATE); + + // Store the attributes that are being supplied by the key generation to the object + if (rv == CKR_OK) + { + OSObject* osobject = (OSObject*)handleManager->getObject(*phPublicKey); + if (osobject == NULL_PTR || !osobject->isValid()) { + rv = CKR_FUNCTION_FAILED; + } else if (osobject->startTransaction()) { + bool bOK = true; + + // Common Key Attributes + bOK = bOK && osobject->setAttribute(CKA_LOCAL,true); + CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_EDWARDS_KEY_PAIR_GEN; + bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism); + + // EDDSA Public Key Attributes + ByteString value; + if (isPublicKeyPrivate) + { + token->encrypt(pub->getA(), value); + } + else + { + value = pub->getA(); + } + bOK = bOK && osobject->setAttribute(CKA_EC_POINT, value); + + if (bOK) + bOK = osobject->commitTransaction(); + else + osobject->abortTransaction(); + + if (!bOK) + rv = CKR_FUNCTION_FAILED; + } else + rv = CKR_FUNCTION_FAILED; + } + } + + // Create a private key using C_CreateObject + if (rv == CKR_OK) + { + const CK_ULONG maxAttribs = 32; + CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY; + CK_KEY_TYPE privateKeyType = CKK_EC_EDWARDS; + CK_ATTRIBUTE privateKeyAttribs[maxAttribs] = { + { CKA_CLASS, &privateKeyClass, sizeof(privateKeyClass) }, + { CKA_TOKEN, &isPrivateKeyOnToken, sizeof(isPrivateKeyOnToken) }, + { CKA_PRIVATE, &isPrivateKeyPrivate, sizeof(isPrivateKeyPrivate) }, + { CKA_KEY_TYPE, &privateKeyType, sizeof(privateKeyType) }, + }; + CK_ULONG privateKeyAttribsCount = 4; + if (ulPrivateKeyAttributeCount > (maxAttribs - privateKeyAttribsCount)) + rv = CKR_TEMPLATE_INCONSISTENT; + for (CK_ULONG i=0; i < ulPrivateKeyAttributeCount && rv == CKR_OK; ++i) + { + switch (pPrivateKeyTemplate[i].type) + { + case CKA_CLASS: + case CKA_TOKEN: + case CKA_PRIVATE: + case CKA_KEY_TYPE: + continue; + default: + privateKeyAttribs[privateKeyAttribsCount++] = pPrivateKeyTemplate[i]; + } + } + + if (rv == CKR_OK) + rv = this->CreateObject(hSession,privateKeyAttribs,privateKeyAttribsCount,phPrivateKey,OBJECT_OP_GENERATE); + + // Store the attributes that are being supplied by the key generation to the object + if (rv == CKR_OK) + { + OSObject* osobject = (OSObject*)handleManager->getObject(*phPrivateKey); + if (osobject == NULL_PTR || !osobject->isValid()) { + rv = CKR_FUNCTION_FAILED; + } else if (osobject->startTransaction()) { + bool bOK = true; + + // Common Key Attributes + bOK = bOK && osobject->setAttribute(CKA_LOCAL,true); + CK_ULONG ulKeyGenMechanism = (CK_ULONG)CKM_EC_EDWARDS_KEY_PAIR_GEN; + bOK = bOK && osobject->setAttribute(CKA_KEY_GEN_MECHANISM,ulKeyGenMechanism); + + // Common Private Key Attributes + bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false); + bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive); + bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false; + bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE, bNeverExtractable); + + // EDDSA Private Key Attributes + ByteString group; + ByteString value; + if (isPrivateKeyPrivate) + { + token->encrypt(priv->getEC(), group); + token->encrypt(priv->getK(), value); + } + else + { + group = priv->getEC(); + value = priv->getK(); + } + bOK = bOK && osobject->setAttribute(CKA_EC_PARAMS, group); + bOK = bOK && osobject->setAttribute(CKA_VALUE, value); + + if (bOK) + bOK = osobject->commitTransaction(); + else + osobject->abortTransaction(); + + if (!bOK) + rv = CKR_FUNCTION_FAILED; + } else + rv = CKR_FUNCTION_FAILED; + } + } + + // Clean up + ec->recycleKeyPair(kp); + CryptoFactory::i()->recycleAsymmetricAlgorithm(ec); + + // Remove keys that may have been created already when the function fails. + if (rv != CKR_OK) + { + if (*phPrivateKey != CK_INVALID_HANDLE) + { + OSObject* ospriv = (OSObject*)handleManager->getObject(*phPrivateKey); + handleManager->destroyObject(*phPrivateKey); + if (ospriv) ospriv->destroyObject(); + *phPrivateKey = CK_INVALID_HANDLE; + } + + if (*phPublicKey != CK_INVALID_HANDLE) + { + OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey); + handleManager->destroyObject(*phPublicKey); + if (ospub) ospub->destroyObject(); + *phPublicKey = CK_INVALID_HANDLE; + } + } + + return rv; +} + // Generate a DH key pair CK_RV SoftHSM::generateDH (CK_SESSION_HANDLE hSession, @@ -9820,6 +10413,7 @@ CK_RV SoftHSM::deriveDH } // Derive an ECDH secret +#ifdef WITH_ECC CK_RV SoftHSM::deriveECDH (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, @@ -9831,7 +10425,6 @@ CK_RV SoftHSM::deriveECDH CK_BBOOL isOnToken, CK_BBOOL isPrivate) { -#ifdef WITH_ECC *phKey = CK_INVALID_HANDLE; if ((pMechanism->pParameter == NULL_PTR) || @@ -10170,10 +10763,362 @@ CK_RV SoftHSM::deriveECDH } return rv; -#else - return CKR_MECHANISM_INVALID; +} +#endif + +// Derive an ECDH secret using Montgomery curves +#ifdef WITH_EDDSA +CK_RV SoftHSM::deriveEDDSA +(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey, + CK_KEY_TYPE keyType, + CK_BBOOL isOnToken, + CK_BBOOL isPrivate) +{ + *phKey = CK_INVALID_HANDLE; + + if ((pMechanism->pParameter == NULL_PTR) || + (pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS))) + { + DEBUG_MSG("pParameter must be of type CK_ECDH1_DERIVE_PARAMS"); + return CKR_MECHANISM_PARAM_INVALID; + } + if (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->kdf != CKD_NULL) + { + DEBUG_MSG("kdf must be CKD_NULL"); + return CKR_MECHANISM_PARAM_INVALID; + } + if ((CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulSharedDataLen != 0) || + (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pSharedData != NULL_PTR)) + { + DEBUG_MSG("there must be no shared data"); + return CKR_MECHANISM_PARAM_INVALID; + } + if ((CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen == 0) || + (CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData == NULL_PTR)) + { + DEBUG_MSG("there must be a public data"); + return CKR_MECHANISM_PARAM_INVALID; + } + + // Get the session + Session* session = (Session*)handleManager->getSession(hSession); + if (session == NULL) + return CKR_SESSION_HANDLE_INVALID; + + // Get the token + Token* token = session->getToken(); + if (token == NULL) + return CKR_GENERAL_ERROR; + + // Extract desired parameter information + size_t byteLen = 0; + bool checkValue = true; + for (CK_ULONG i = 0; i < ulCount; i++) + { + switch (pTemplate[i].type) + { + case CKA_VALUE: + INFO_MSG("CKA_VALUE must not be included"); + return CKR_ATTRIBUTE_READ_ONLY; + case CKA_VALUE_LEN: + if (pTemplate[i].ulValueLen != sizeof(CK_ULONG)) + { + INFO_MSG("CKA_VALUE_LEN does not have the size of CK_ULONG"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + byteLen = *(CK_ULONG*)pTemplate[i].pValue; + break; + case CKA_CHECK_VALUE: + if (pTemplate[i].ulValueLen > 0) + { + INFO_MSG("CKA_CHECK_VALUE must be a no-value (0 length) entry"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + checkValue = false; + break; + default: + break; + } + } + + // Check the length + // byteLen == 0 impiles return max size the ECC can derive + switch (keyType) + { + case CKK_GENERIC_SECRET: + break; +#ifndef WITH_FIPS + case CKK_DES: + if (byteLen != 0 && byteLen != 8) + { + INFO_MSG("CKA_VALUE_LEN must be 0 or 8"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + byteLen = 8; + break; #endif + case CKK_DES2: + if (byteLen != 0 && byteLen != 16) + { + INFO_MSG("CKA_VALUE_LEN must be 0 or 16"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + byteLen = 16; + break; + case CKK_DES3: + if (byteLen != 0 && byteLen != 24) + { + INFO_MSG("CKA_VALUE_LEN must be 0 or 24"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + byteLen = 24; + break; + case CKK_AES: + if (byteLen != 0 && byteLen != 16 && byteLen != 24 && byteLen != 32) + { + INFO_MSG("CKA_VALUE_LEN must be 0, 16, 24, or 32"); + return CKR_ATTRIBUTE_VALUE_INVALID; + } + break; + default: + return CKR_ATTRIBUTE_VALUE_INVALID; + } + + // Get the base key handle + OSObject *baseKey = (OSObject *)handleManager->getObject(hBaseKey); + if (baseKey == NULL || !baseKey->isValid()) + return CKR_KEY_HANDLE_INVALID; + + // Get the EDDSA algorithm handler + AsymmetricAlgorithm* eddsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA); + if (eddsa == NULL) + return CKR_MECHANISM_INVALID; + + // Get the keys + PrivateKey* privateKey = eddsa->newPrivateKey(); + if (privateKey == NULL) + { + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); + return CKR_HOST_MEMORY; + } + if (getEDPrivateKey((EDPrivateKey*)privateKey, token, baseKey) != CKR_OK) + { + eddsa->recyclePrivateKey(privateKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); + return CKR_GENERAL_ERROR; + } + + ByteString publicData; + publicData.resize(CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen); + memcpy(&publicData[0], + CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData, + CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen); + PublicKey* publicKey = eddsa->newPublicKey(); + if (publicKey == NULL) + { + eddsa->recyclePrivateKey(privateKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); + return CKR_HOST_MEMORY; + } + if (getEDDHPublicKey((EDPublicKey*)publicKey, (EDPrivateKey*)privateKey, publicData) != CKR_OK) + { + eddsa->recyclePrivateKey(privateKey); + eddsa->recyclePublicKey(publicKey); + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); + return CKR_GENERAL_ERROR; + } + + // Derive the secret + SymmetricKey* secret = NULL; + CK_RV rv = CKR_OK; + if (!eddsa->deriveKey(&secret, publicKey, privateKey)) + rv = CKR_GENERAL_ERROR; + eddsa->recyclePrivateKey(privateKey); + eddsa->recyclePublicKey(publicKey); + + // Create the secret object using C_CreateObject + const CK_ULONG maxAttribs = 32; + CK_OBJECT_CLASS objClass = CKO_SECRET_KEY; + CK_ATTRIBUTE secretAttribs[maxAttribs] = { + { CKA_CLASS, &objClass, sizeof(objClass) }, + { CKA_TOKEN, &isOnToken, sizeof(isOnToken) }, + { CKA_PRIVATE, &isPrivate, sizeof(isPrivate) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + }; + CK_ULONG secretAttribsCount = 4; + + // Add the additional + if (ulCount > (maxAttribs - secretAttribsCount)) + rv = CKR_TEMPLATE_INCONSISTENT; + for (CK_ULONG i=0; i < ulCount && rv == CKR_OK; ++i) + { + switch (pTemplate[i].type) + { + case CKA_CLASS: + case CKA_TOKEN: + case CKA_PRIVATE: + case CKA_KEY_TYPE: + case CKA_CHECK_VALUE: + continue; + default: + secretAttribs[secretAttribsCount++] = pTemplate[i]; + } + } + + if (rv == CKR_OK) + rv = this->CreateObject(hSession, secretAttribs, secretAttribsCount, phKey, OBJECT_OP_DERIVE); + + // Store the attributes that are being supplied + if (rv == CKR_OK) + { + OSObject* osobject = (OSObject*)handleManager->getObject(*phKey); + if (osobject == NULL_PTR || !osobject->isValid()) { + rv = CKR_FUNCTION_FAILED; + } else if (osobject->startTransaction()) { + bool bOK = true; + + // Common Attributes + bOK = bOK && osobject->setAttribute(CKA_LOCAL,false); + + // Common Secret Key Attributes + if (baseKey->getBooleanValue(CKA_ALWAYS_SENSITIVE, false)) + { + bool bAlwaysSensitive = osobject->getBooleanValue(CKA_SENSITIVE, false); + bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,bAlwaysSensitive); + } + else + { + bOK = bOK && osobject->setAttribute(CKA_ALWAYS_SENSITIVE,false); + } + if (baseKey->getBooleanValue(CKA_NEVER_EXTRACTABLE, true)) + { + bool bNeverExtractable = osobject->getBooleanValue(CKA_EXTRACTABLE, false) == false; + bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,bNeverExtractable); + } + else + { + bOK = bOK && osobject->setAttribute(CKA_NEVER_EXTRACTABLE,false); + } + + // Secret Attributes + ByteString secretValue = secret->getKeyBits(); + ByteString value; + ByteString plainKCV; + ByteString kcv; + + // For generic and AES keys: + // default to return max size available. + if (byteLen == 0) + { + switch (keyType) + { + case CKK_GENERIC_SECRET: + byteLen = secretValue.size(); + break; + case CKK_AES: + if (secretValue.size() >= 32) + byteLen = 32; + else if (secretValue.size() >= 24) + byteLen = 24; + else + byteLen = 16; + } + } + + if (byteLen > secretValue.size()) + { + INFO_MSG("The derived secret is too short"); + bOK = false; + } + else + { + // Truncate value when requested, remove from the leading end + if (byteLen < secretValue.size()) + secretValue.split(secretValue.size() - byteLen); + + // Fix the odd parity for DES + if (keyType == CKK_DES || + keyType == CKK_DES2 || + keyType == CKK_DES3) + { + for (size_t i = 0; i < secretValue.size(); i++) + { + secretValue[i] = odd_parity[secretValue[i]]; + } + } + + // Get the KCV + switch (keyType) + { + case CKK_GENERIC_SECRET: + secret->setBitLen(byteLen * 8); + plainKCV = secret->getKeyCheckValue(); + break; + case CKK_DES: + case CKK_DES2: + case CKK_DES3: + secret->setBitLen(byteLen * 7); + plainKCV = ((DESKey*)secret)->getKeyCheckValue(); + break; + case CKK_AES: + secret->setBitLen(byteLen * 8); + plainKCV = ((AESKey*)secret)->getKeyCheckValue(); + break; + default: + bOK = false; + break; + } + + if (isPrivate) + { + token->encrypt(secretValue, value); + token->encrypt(plainKCV, kcv); + } + else + { + value = secretValue; + kcv = plainKCV; + } + } + bOK = bOK && osobject->setAttribute(CKA_VALUE, value); + if (checkValue) + bOK = bOK && osobject->setAttribute(CKA_CHECK_VALUE, kcv); + + if (bOK) + bOK = osobject->commitTransaction(); + else + osobject->abortTransaction(); + + if (!bOK) + rv = CKR_FUNCTION_FAILED; + } else + rv = CKR_FUNCTION_FAILED; + } + + // Clean up + eddsa->recycleSymmetricKey(secret); + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); + + // Remove secret that may have been created already when the function fails. + if (rv != CKR_OK) + { + if (*phKey != CK_INVALID_HANDLE) + { + OSObject* ossecret = (OSObject*)handleManager->getObject(*phKey); + handleManager->destroyObject(*phKey); + if (ossecret) ossecret->destroyObject(); + *phKey = CK_INVALID_HANDLE; + } + } + + return rv; } +#endif // Derive an symmetric secret CK_RV SoftHSM::deriveSymmetric @@ -10994,6 +11939,70 @@ CK_RV SoftHSM::getECPublicKey(ECPublicKey* publicKey, Token* token, OSObject* ke return CKR_OK; } +CK_RV SoftHSM::getEDPrivateKey(EDPrivateKey* privateKey, Token* token, OSObject* key) +{ + if (privateKey == NULL) return CKR_ARGUMENTS_BAD; + if (token == NULL) return CKR_ARGUMENTS_BAD; + if (key == NULL) return CKR_ARGUMENTS_BAD; + + // Get the CKA_PRIVATE attribute, when the attribute is not present use default false + bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false); + + // EDDSA Private Key Attributes + ByteString group; + ByteString value; + if (isKeyPrivate) + { + bool bOK = true; + bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_PARAMS), group); + bOK = bOK && token->decrypt(key->getByteStringValue(CKA_VALUE), value); + if (!bOK) + return CKR_GENERAL_ERROR; + } + else + { + group = key->getByteStringValue(CKA_EC_PARAMS); + value = key->getByteStringValue(CKA_VALUE); + } + + privateKey->setEC(group); + privateKey->setK(value); + + return CKR_OK; +} + +CK_RV SoftHSM::getEDPublicKey(EDPublicKey* publicKey, Token* token, OSObject* key) +{ + if (publicKey == NULL) return CKR_ARGUMENTS_BAD; + if (token == NULL) return CKR_ARGUMENTS_BAD; + if (key == NULL) return CKR_ARGUMENTS_BAD; + + // Get the CKA_PRIVATE attribute, when the attribute is not present use default false + bool isKeyPrivate = key->getBooleanValue(CKA_PRIVATE, false); + + // EC Public Key Attributes + ByteString group; + ByteString value; + if (isKeyPrivate) + { + bool bOK = true; + bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_PARAMS), group); + bOK = bOK && token->decrypt(key->getByteStringValue(CKA_EC_POINT), value); + if (!bOK) + return CKR_GENERAL_ERROR; + } + else + { + group = key->getByteStringValue(CKA_EC_PARAMS); + value = key->getByteStringValue(CKA_EC_POINT); + } + + publicKey->setEC(group); + publicKey->setA(value); + + return CKR_OK; +} + CK_RV SoftHSM::getDHPrivateKey(DHPrivateKey* privateKey, Token* token, OSObject* key) { if (privateKey == NULL) return CKR_ARGUMENTS_BAD; @@ -11060,15 +12069,32 @@ CK_RV SoftHSM::getECDHPublicKey(ECPublicKey* publicKey, ECPrivateKey* privateKey return CKR_OK; } +CK_RV SoftHSM::getEDDHPublicKey(EDPublicKey* publicKey, EDPrivateKey* privateKey, ByteString& pubData) +{ + if (publicKey == NULL) return CKR_ARGUMENTS_BAD; + if (privateKey == NULL) return CKR_ARGUMENTS_BAD; + + // Copy Domain Parameters from Private Key + publicKey->setEC(privateKey->getEC()); + + // Set value + ByteString data = getECDHPubData(pubData); + publicKey->setA(data); + + return CKR_OK; +} + // ECDH pubData can be in RAW or DER format. // Need to convert RAW as SoftHSM uses DER. ByteString SoftHSM::getECDHPubData(ByteString& pubData) { size_t len = pubData.size(); size_t controlOctets = 2; - if (len == 65 || len == 97 || len == 133) + if (len == 32 || len == 65 || len == 97 || len == 133) { - // Raw: Length matches the public key size of P-256, P-384, or P-521 + // Raw: Length matches the public key size of: + // EDDSA: X25519 + // ECDSA: P-256, P-384, or P-521 controlOctets = 0; } else if (len < controlOctets || pubData[0] != 0x04) @@ -11106,36 +12132,7 @@ ByteString SoftHSM::getECDHPubData(ByteString& pubData) // DER format if (controlOctets != 0) return pubData; - // RAW format - ByteString header; - if (len < 0x80) - { - header.resize(2); - header[0] = (unsigned char)0x04; - header[1] = (unsigned char)(len & 0x7F); - } - else - { - // Count significate bytes - size_t bytes = sizeof(size_t); - for(; bytes > 0; bytes--) - { - size_t value = len >> ((bytes - 1) * 8); - if (value & 0xFF) break; - } - - // Set header data - header.resize(2 + bytes); - header[0] = (unsigned char)0x04; - header[1] = (unsigned char)(0x80 | bytes); - for (size_t i = 1; i <= bytes; i++) - { - header[2+bytes-i] = (unsigned char) (len & 0xFF); - len >>= 8; - } - } - - return header + pubData; + return DERUTIL::raw2Octet(pubData); } CK_RV SoftHSM::getGOSTPrivateKey(GOSTPrivateKey* privateKey, Token* token, OSObject* key) diff --git a/SoftHSMv2/src/lib/SoftHSM.h b/SoftHSMv2/src/lib/SoftHSM.h index 323f3a5..6456cbe 100644 --- a/SoftHSMv2/src/lib/SoftHSM.h +++ b/SoftHSMv2/src/lib/SoftHSM.h @@ -46,6 +46,8 @@ #include "DSAPrivateKey.h" #include "ECPublicKey.h" #include "ECPrivateKey.h" +#include "EDPublicKey.h" +#include "EDPrivateKey.h" #include "DHPublicKey.h" #include "DHPrivateKey.h" #include "GOSTPublicKey.h" @@ -291,6 +293,20 @@ private: CK_BBOOL isPrivateKeyOnToken, CK_BBOOL isPrivateKeyPrivate ); + CK_RV generateED + ( + CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey, + CK_BBOOL isPublicKeyOnToken, + CK_BBOOL isPublicKeyPrivate, + CK_BBOOL isPrivateKeyOnToken, + CK_BBOOL isPrivateKeyPrivate + ); CK_RV generateDH ( CK_SESSION_HANDLE hSession, @@ -328,6 +344,15 @@ private: CK_BBOOL isPrivateKeyOnToken, CK_BBOOL isPrivateKeyPrivate ); + CK_RV generateGeneric + ( + CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey, + CK_BBOOL isOnToken, + CK_BBOOL isPrivate + ); CK_RV deriveDH ( CK_SESSION_HANDLE hSession, @@ -340,6 +365,7 @@ private: CK_BBOOL isOnToken, CK_BBOOL isPrivate ); +#ifdef WITH_ECC CK_RV deriveECDH ( CK_SESSION_HANDLE hSession, @@ -352,6 +378,21 @@ private: CK_BBOOL isOnToken, CK_BBOOL isPrivate ); +#endif +#ifdef WITH_EDDSA + CK_RV deriveEDDSA + ( + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey, + CK_KEY_TYPE keyType, + CK_BBOOL isOnToken, + CK_BBOOL isPrivate + ); +#endif CK_RV deriveSymmetric ( CK_SESSION_HANDLE hSession, @@ -379,9 +420,12 @@ private: CK_RV getDSAPublicKey(DSAPublicKey* publicKey, Token* token, OSObject* key); CK_RV getECPrivateKey(ECPrivateKey* privateKey, Token* token, OSObject* key); CK_RV getECPublicKey(ECPublicKey* publicKey, Token* token, OSObject* key); + CK_RV getEDPrivateKey(EDPrivateKey* privateKey, Token* token, OSObject* key); + CK_RV getEDPublicKey(EDPublicKey* publicKey, Token* token, OSObject* key); CK_RV getDHPrivateKey(DHPrivateKey* privateKey, Token* token, OSObject* key); CK_RV getDHPublicKey(DHPublicKey* publicKey, DHPrivateKey* privateKey, ByteString& pubParams); CK_RV getECDHPublicKey(ECPublicKey* publicKey, ECPrivateKey* privateKey, ByteString& pubData); + CK_RV getEDDHPublicKey(EDPublicKey* publicKey, EDPrivateKey* privateKey, ByteString& pubData); CK_RV getGOSTPrivateKey(GOSTPrivateKey* privateKey, Token* token, OSObject* key); CK_RV getGOSTPublicKey(GOSTPublicKey* publicKey, Token* token, OSObject* key); CK_RV getSymmetricKey(SymmetricKey* skey, Token* token, OSObject* key); diff --git a/SoftHSMv2/src/lib/common/Makefile.am b/SoftHSMv2/src/lib/common/Makefile.am index bf18b1a..29f5c7a 100644 --- a/SoftHSMv2/src/lib/common/Makefile.am +++ b/SoftHSMv2/src/lib/common/Makefile.am @@ -15,7 +15,8 @@ libsofthsm_common_la_SOURCES = Configuration.cpp \ man_MANS = softhsm2.conf.5 -EXTRA_DIST = $(srcdir)/*.h \ +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ $(srcdir)/softhsm2.conf.5.in install-data-hook: diff --git a/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h b/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h index ca0d840..b0f02fd 100644 --- a/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h +++ b/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h @@ -52,7 +52,8 @@ struct AsymAlgo DH, ECDH, ECDSA, - GOST + GOST, + EDDSA }; }; @@ -85,7 +86,8 @@ struct AsymMech DSA_SHA512, ECDSA, GOST, - GOST_GOST + GOST_GOST, + EDDSA }; }; diff --git a/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp index b4df224..405570c 100644 --- a/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp +++ b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp @@ -53,6 +53,9 @@ #include "BotanGOSTR3411.h" #endif #include "BotanMAC.h" +#ifdef WITH_EDDSA +#include "BotanEDDSA.h" +#endif #include <botan/init.h> @@ -176,6 +179,10 @@ AsymmetricAlgorithm* BotanCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type a case AsymAlgo::GOST: return new BotanGOST(); #endif +#ifdef WITH_EDDSA + case AsymAlgo::EDDSA: + return new BotanEDDSA(); +#endif default: // No algorithm implementation is available ERROR_MSG("Unknown algorithm '%i'", algorithm); diff --git a/SoftHSMv2/src/lib/crypto/BotanEDDSA.cpp b/SoftHSMv2/src/lib/crypto/BotanEDDSA.cpp new file mode 100644 index 0000000..f5c7bd5 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDDSA.cpp @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDDSA.cpp + + Botan EDDSA asymmetric algorithm implementation + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "BotanEDDSA.h" +#include "BotanRNG.h" +#include "CryptoFactory.h" +#include "BotanCryptoFactory.h" +#include "ECParameters.h" +#include "BotanEDKeyPair.h" +#include "BotanUtil.h" +#include <algorithm> +#include <botan/curve25519.h> +#include <botan/ed25519.h> +// #include <botan/curve448.h> +// #include <botan/ed448.h> +#include <botan/version.h> +#include <iostream> + +const Botan::OID x25519_oid("1.3.101.110"); +// const Botan::OID x448_oid("1.3.101.111"); +const Botan::OID ed25519_oid("1.3.101.112"); +// const Botan::OID ed448_oid("1.3.101.113"); + +// Constructor +BotanEDDSA::BotanEDDSA() +{ + signer = NULL; + verifier = NULL; +} + +// Destructor +BotanEDDSA::~BotanEDDSA() +{ + delete signer; + delete verifier; +} + +// Signing functions +bool BotanEDDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, + ByteString& signature, const AsymMech::Type mechanism, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + std::string emsa; + + if (mechanism == AsymMech::EDDSA) + { + emsa = "Pure"; + } + else + { + ERROR_MSG("Invalid mechanism supplied (%i)", mechanism); + return false; + } + + // Check if the private key is the right type + if (!privateKey->isOfType(BotanEDPrivateKey::type)) + { + ERROR_MSG("Invalid key type supplied"); + + return false; + } + + BotanEDPrivateKey* pk = (BotanEDPrivateKey*) privateKey; + Botan::Ed25519_PrivateKey* botanKey = dynamic_cast<Botan::Ed25519_PrivateKey*>(pk->getBotanKey()); + + if (botanKey == NULL) + { + ERROR_MSG("Could not get the Botan private key"); + + return false; + } + + try + { + BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); + signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa); + // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster. + } + catch (...) + { + ERROR_MSG("Could not create the signer token"); + + return false; + } + + // Perform the signature operation + std::vector<Botan::byte> signResult; + try + { + BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); + signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG()); + } + catch (...) + { + ERROR_MSG("Could not sign the data"); + + delete signer; + signer = NULL; + + return false; + } + + // Return the result + signature.resize(signResult.size()); + memcpy(&signature[0], signResult.data(), signResult.size()); + + delete signer; + signer = NULL; + + return true; +} + +// Signing functions +bool BotanEDDSA::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + ERROR_MSG("EDDSA does not support multi part signing"); + + return false; +} + +bool BotanEDDSA::signUpdate(const ByteString& /*dataToSign*/) +{ + ERROR_MSG("EDDSA does not support multi part signing"); + + return false; +} + +bool BotanEDDSA::signFinal(ByteString& /*signature*/) +{ + ERROR_MSG("EDDSA does not support multi part signing"); + + return false; +} + +// Verification functions +bool BotanEDDSA::verify(PublicKey* publicKey, const ByteString& originalData, + const ByteString& signature, const AsymMech::Type mechanism, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + std::string emsa; + + if (mechanism == AsymMech::EDDSA) + { + emsa = "Pure"; + } + else + { + ERROR_MSG("Invalid mechanism supplied (%i)", mechanism); + + return false; + } + + // Check if the public key is the right type + if (!publicKey->isOfType(BotanEDPublicKey::type)) + { + ERROR_MSG("Invalid key type supplied"); + + return false; + } + + BotanEDPublicKey* pk = (BotanEDPublicKey*) publicKey; + Botan::Ed25519_PublicKey* botanKey = dynamic_cast<Botan::Ed25519_PublicKey*>(pk->getBotanKey()); + + if (botanKey == NULL) + { + ERROR_MSG("Could not get the Botan public key"); + + return false; + } + + try + { + verifier = new Botan::PK_Verifier(*botanKey, emsa); + } + catch (...) + { + ERROR_MSG("Could not create the verifier token"); + + return false; + } + + // Perform the verify operation + bool verResult; + try + { + verResult = verifier->verify_message(originalData.const_byte_str(), + originalData.size(), + signature.const_byte_str(), + signature.size()); + } + catch (...) + { + ERROR_MSG("Could not check the signature"); + + delete verifier; + verifier = NULL; + + return false; + } + + delete verifier; + verifier = NULL; + + return verResult; +} + +// Verification functions +bool BotanEDDSA::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + ERROR_MSG("EDDSA does not support multi part verifying"); + + return false; +} + +bool BotanEDDSA::verifyUpdate(const ByteString& /*originalData*/) +{ + ERROR_MSG("EDDSA does not support multi part verifying"); + + return false; +} + +bool BotanEDDSA::verifyFinal(const ByteString& /*signature*/) +{ + ERROR_MSG("EDDSA does not support multi part verifying"); + + return false; +} + +// Encryption functions +bool BotanEDDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) +{ + ERROR_MSG("EDDSA does not support encryption"); + + return false; +} + +// Decryption functions +bool BotanEDDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, + ByteString& /*data*/, const AsymMech::Type /*padding*/) +{ + ERROR_MSG("EDDSA does not support decryption"); + + return false; +} + +// Key factory +bool BotanEDDSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */) +{ + // Check parameters + if ((ppKeyPair == NULL) || + (parameters == NULL)) + { + return false; + } + + if (!parameters->areOfType(ECParameters::type)) + { + ERROR_MSG("Invalid parameters supplied for EDDSA key generation"); + + return false; + } + + ECParameters* params = (ECParameters*) parameters; + Botan::OID oid = BotanUtil::byteString2Oid(params->getEC()); + + // Generate the key-pair + Botan::Private_Key* eckp = NULL; + try + { + BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); + if (oid == x25519_oid) + { + eckp = new Botan::Curve25519_PrivateKey(*rng->getRNG()); + } + else if (oid == ed25519_oid) + { + eckp = new Botan::Ed25519_PrivateKey(*rng->getRNG()); + } + else + { + return false; + } + } + catch (...) + { + ERROR_MSG("EDDSA key generation failed"); + + return false; + } + + // Create an asymmetric key-pair object to return + BotanEDKeyPair* kp = new BotanEDKeyPair(); + + ((BotanEDPublicKey*) kp->getPublicKey())->setFromBotan(eckp); + ((BotanEDPrivateKey*) kp->getPrivateKey())->setFromBotan(eckp); + + *ppKeyPair = kp; + + // Release the key + delete eckp; + + return true; +} + +bool BotanEDDSA::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey) +{ + // Check parameters + if ((ppSymmetricKey == NULL) || + (publicKey == NULL) || + (privateKey == NULL)) + { + return false; + } + + // Get keys + BotanEDPublicKey* pubk = (BotanEDPublicKey*) publicKey; + Botan::Curve25519_PublicKey* pub = dynamic_cast<Botan::Curve25519_PublicKey*>(pubk->getBotanKey()); + BotanEDPrivateKey* privk = (BotanEDPrivateKey*) privateKey; + Botan::Curve25519_PrivateKey* priv = dynamic_cast<Botan::Curve25519_PrivateKey*>(privk->getBotanKey()); + if (pub == NULL || priv == NULL) + { + ERROR_MSG("Failed to get Botan EDDSA keys"); + + return false; + } + + // Derive the secret + Botan::SymmetricKey sk; + try + { + BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG(); + Botan::PK_Key_Agreement ka(*priv, *rng->getRNG(), "Raw"); + sk = ka.derive_key(0, pub->public_value()); + } + catch (...) + { + ERROR_MSG("Botan EDDSA key agreement failed"); + + return false; + } + + ByteString secret; + + // We compensate that Botan removes leading zeros + int size = pubk->getOrderLength(); + int keySize = sk.length(); + secret.wipe(size); + memcpy(&secret[0] + size - keySize, sk.begin(), keySize); + + *ppSymmetricKey = new SymmetricKey(secret.size() * 8); + if (*ppSymmetricKey == NULL) + { + ERROR_MSG("Can't create EDDSA secret"); + + return false; + } + if (!(*ppSymmetricKey)->setKeyBits(secret)) + { + delete *ppSymmetricKey; + *ppSymmetricKey = NULL; + return false; + } + + return true; +} + +unsigned long BotanEDDSA::getMinKeySize() +{ + // Only Ed25519 is supported + return 32*8; +} + +unsigned long BotanEDDSA::getMaxKeySize() +{ + // Only Ed25519 is supported + return 32*8; +} + +bool BotanEDDSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData) +{ + // Check input + if ((ppKeyPair == NULL) || + (serialisedData.size() == 0)) + { + return false; + } + + ByteString dPub = ByteString::chainDeserialise(serialisedData); + ByteString dPriv = ByteString::chainDeserialise(serialisedData); + + BotanEDKeyPair* kp = new BotanEDKeyPair(); + + bool rv = true; + + if (!((EDPublicKey*) kp->getPublicKey())->deserialise(dPub)) + { + rv = false; + } + + if (!((EDPrivateKey*) kp->getPrivateKey())->deserialise(dPriv)) + { + rv = false; + } + + if (!rv) + { + delete kp; + + return false; + } + + *ppKeyPair = kp; + + return true; +} + +bool BotanEDDSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData) +{ + // Check input + if ((ppPublicKey == NULL) || + (serialisedData.size() == 0)) + { + return false; + } + + BotanEDPublicKey* pub = new BotanEDPublicKey(); + + if (!pub->deserialise(serialisedData)) + { + delete pub; + + return false; + } + + *ppPublicKey = pub; + + return true; +} + +bool BotanEDDSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData) +{ + // Check input + if ((ppPrivateKey == NULL) || + (serialisedData.size() == 0)) + { + return false; + } + + BotanEDPrivateKey* priv = new BotanEDPrivateKey(); + + if (!priv->deserialise(serialisedData)) + { + delete priv; + + return false; + } + + *ppPrivateKey = priv; + + return true; +} + +PublicKey* BotanEDDSA::newPublicKey() +{ + return (PublicKey*) new BotanEDPublicKey(); +} + +PrivateKey* BotanEDDSA::newPrivateKey() +{ + return (PrivateKey*) new BotanEDPrivateKey(); +} + +AsymmetricParameters* BotanEDDSA::newParameters() +{ + return (AsymmetricParameters*) new ECParameters(); +} + +bool BotanEDDSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData) +{ + // Check input parameters + if ((ppParams == NULL) || (serialisedData.size() == 0)) + { + return false; + } + + ECParameters* params = new ECParameters(); + + if (!params->deserialise(serialisedData)) + { + delete params; + + return false; + } + + *ppParams = params; + + return true; +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/BotanEDDSA.h b/SoftHSMv2/src/lib/crypto/BotanEDDSA.h new file mode 100644 index 0000000..552bca4 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDDSA.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDDSA.h + + Botan EDDSA asymmetric algorithm implementation + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_BOTANEDDSA_H +#define _SOFTHSM_V2_BOTANEDDSA_H + +#include "config.h" +#include "AsymmetricAlgorithm.h" +#include <botan/pubkey.h> + +class BotanEDDSA : public AsymmetricAlgorithm +{ +public: + // Constructor + BotanEDDSA(); + + // Destructor + virtual ~BotanEDDSA(); + + // Signing functions + virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool signUpdate(const ByteString& dataToSign); + virtual bool signFinal(ByteString& signature); + + // Verification functions + virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool verifyUpdate(const ByteString& originalData); + virtual bool verifyFinal(const ByteString& signature); + + // Encryption functions + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + + // Decryption functions + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + + // Key factory + virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); + virtual unsigned long getMinKeySize(); + virtual unsigned long getMaxKeySize(); + virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey); + virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData); + virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData); + virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData); + virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData); + virtual PublicKey* newPublicKey(); + virtual PrivateKey* newPrivateKey(); + virtual AsymmetricParameters* newParameters(); + +private: + Botan::PK_Signer* signer; + Botan::PK_Verifier* verifier; +}; +#endif // !_SOFTHSM_V2_BOTANEDDSA_H diff --git a/SoftHSMv2/src/lib/crypto/BotanEDKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanEDKeyPair.cpp new file mode 100644 index 0000000..3e967e5 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDKeyPair.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDKeyPair.cpp + + Botan EDDSA key-pair class + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "BotanEDKeyPair.h" + +// Set the public key +void BotanEDKeyPair::setPublicKey(BotanEDPublicKey& publicKey) +{ + pubKey = publicKey; +} + +// Set the private key +void BotanEDKeyPair::setPrivateKey(BotanEDPrivateKey& privateKey) +{ + privKey = privateKey; +} + +// Return the public key +PublicKey* BotanEDKeyPair::getPublicKey() +{ + return &pubKey; +} + +const PublicKey* BotanEDKeyPair::getConstPublicKey() const +{ + return &pubKey; +} + +// Return the private key +PrivateKey* BotanEDKeyPair::getPrivateKey() +{ + return &privKey; +} + +const PrivateKey* BotanEDKeyPair::getConstPrivateKey() const +{ + return &privKey; +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/BotanEDKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanEDKeyPair.h new file mode 100644 index 0000000..4f2cffe --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDKeyPair.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDKeyPair.h + + Botan EDDSA key-pair class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_BOTANEDKEYPAIR_H +#define _SOFTHSM_V2_BOTANEDKEYPAIR_H + +#include "config.h" +#ifdef WITH_EDDSA +#include "AsymmetricKeyPair.h" +#include "BotanEDPublicKey.h" +#include "BotanEDPrivateKey.h" + +class BotanEDKeyPair : public AsymmetricKeyPair +{ +public: + // Set the public key + void setPublicKey(BotanEDPublicKey& publicKey); + + // Set the private key + void setPrivateKey(BotanEDPrivateKey& privateKey); + + // Return the public key + virtual PublicKey* getPublicKey(); + virtual const PublicKey* getConstPublicKey() const; + + // Return the private key + virtual PrivateKey* getPrivateKey(); + virtual const PrivateKey* getConstPrivateKey() const; + +private: + // The public key + BotanEDPublicKey pubKey; + + // The private key + BotanEDPrivateKey privKey; +}; +#endif +#endif // !_SOFTHSM_V2_BOTANEDKEYPAIR_H + diff --git a/SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.cpp new file mode 100644 index 0000000..bef9e7b --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDPrivateKey.cpp + + Botan EDDSA private key class + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "BotanEDPrivateKey.h" +#include "BotanCryptoFactory.h" +#include "BotanRNG.h" +#include "BotanUtil.h" +#include <string.h> +#include <botan/pkcs8.h> +#include <botan/ber_dec.h> +#include <botan/der_enc.h> +#include <botan/asn1_oid.h> +#include <botan/oids.h> +#include <botan/pkcs8.h> +#include <botan/version.h> +#include <botan/curve25519.h> +#include <botan/ed25519.h> +// #include <botan/curve448.h> +// #include <botan/ed448.h> + +const Botan::OID x25519_oid("1.3.101.110"); +// const Botan::OID x448_oid("1.3.101.111"); +const Botan::OID ed25519_oid("1.3.101.112"); +// const Botan::OID ed448_oid("1.3.101.113"); + +// Constructors +BotanEDPrivateKey::BotanEDPrivateKey() +{ + edkey = NULL; +} + +BotanEDPrivateKey::BotanEDPrivateKey(const Botan::Private_Key* inEDKEY) +{ + edkey = NULL; + + setFromBotan(inEDKEY); +} + +// Destructor +BotanEDPrivateKey::~BotanEDPrivateKey() +{ + delete edkey; +} + +// The type +/*static*/ const char* BotanEDPrivateKey::type = "Botan EDDSA Private Key"; + +// Get the base point order length +unsigned long BotanEDPrivateKey::getOrderLength() const +{ + // Only Ed25519 is supported + return 32; +} + +// Set from Botan representation +void BotanEDPrivateKey::setFromBotan(const Botan::Private_Key* inEDKEY) +{ + Botan::OID oid; + Botan::secure_vector<uint8_t> priv; + + for (;;) + { + const Botan::Curve25519_PrivateKey* x25519 = dynamic_cast<const Botan::Curve25519_PrivateKey*>(inEDKEY); + if (x25519) { + oid = x25519_oid; + priv = x25519->get_x(); + break; + } + const Botan::Ed25519_PrivateKey* ed25519 = dynamic_cast<const Botan::Ed25519_PrivateKey*>(inEDKEY); + if (ed25519) { + oid = ed25519_oid; + priv = ed25519->get_private_key(); + // Botan returns public part too + priv.resize(32); + break; + } + return; + } + ByteString inEC = BotanUtil::oid2ByteString(oid); + setEC(inEC); + ByteString inK; + inK.resize(priv.size()); + memcpy(&inK[0], &priv[0], priv.size()); + setK(inK); +} + +// Check if the key is of the given type +bool BotanEDPrivateKey::isOfType(const char* inType) +{ + return !strcmp(type, inType); +} + +// Setters for the EDDSA private key components +void BotanEDPrivateKey::setK(const ByteString& inK) +{ + EDPrivateKey::setK(inK); + + if (edkey) + { + delete edkey; + edkey = NULL; + } +} + +// Setters for the EDDSA public key components +void BotanEDPrivateKey::setEC(const ByteString& inEC) +{ + EDPrivateKey::setEC(inEC); + + if (edkey) + { + delete edkey; + edkey = NULL; + } +} + +// Encode into PKCS#8 DER +ByteString BotanEDPrivateKey::PKCS8Encode() +{ + ByteString der; + createBotanKey(); + if (edkey == NULL) return der; + const Botan::secure_vector<Botan::byte> ber = Botan::PKCS8::BER_encode(*edkey); + der.resize(ber.size()); + memcpy(&der[0], &ber[0], ber.size()); + return der; +} + +// Decode from PKCS#8 BER +bool BotanEDPrivateKey::PKCS8Decode(const ByteString& ber) +{ + Botan::DataSource_Memory source(ber.const_byte_str(), ber.size()); + if (source.end_of_data()) return false; + Botan::secure_vector<Botan::byte> keydata; + Botan::AlgorithmIdentifier alg_id; + Botan::Private_Key* key = NULL; + try + { + Botan::BER_Decoder(source) + .start_cons(Botan::SEQUENCE) + .decode_and_check<size_t>(0, "Unknown PKCS #8 version number") + .decode(alg_id) + .decode(keydata, Botan::OCTET_STRING) + .discard_remaining() + .end_cons(); + if (keydata.empty()) + throw Botan::Decoding_Error("PKCS #8 private key decoding failed"); + if (alg_id.oid == x25519_oid) + { + key = new Botan::Curve25519_PrivateKey(alg_id, keydata); + } + else if (alg_id.oid == ed25519_oid) + { + key = new Botan::Ed25519_PrivateKey(alg_id, keydata); + } + else + { + ERROR_MSG("Decoded private key not Ed25519"); + + return false; + } + if (key == NULL) return false; + + setFromBotan(key); + + delete key; + } + catch (std::exception& e) + { + ERROR_MSG("Decode failed on %s", e.what()); + + return false; + } + + return true; +} + +// Retrieve the Botan representation of the key +Botan::Private_Key* BotanEDPrivateKey::getBotanKey() +{ + if (!edkey) + { + createBotanKey(); + } + + return edkey; +} + +// Create the Botan representation of the key +void BotanEDPrivateKey::createBotanKey() +{ + if (ec.size() != 0 && + k.size() != 0) + { + if (edkey) + { + delete edkey; + edkey = NULL; + } + + try + { + Botan::secure_vector<uint8_t> priv(k.size()); + memcpy(&priv[0], k.const_byte_str(), k.size()); + Botan::OID oid = BotanUtil::byteString2Oid(ec); + if (oid == x25519_oid) + { + edkey = new Botan::Curve25519_PrivateKey(priv); + } + else if (oid == ed25519_oid) + { + edkey = new Botan::Ed25519_PrivateKey(priv); + } + } + catch (...) + { + ERROR_MSG("Could not create the Botan private key"); + } + } +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.h new file mode 100644 index 0000000..ac236bb --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDPrivateKey.h + + Botan EDDSA private key class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_BOTANEDPRIVATEKEY_H +#define _SOFTHSM_V2_BOTANEDPRIVATEKEY_H + +#include "config.h" +#ifdef WITH_EDDSA +#include "EDPrivateKey.h" +#include <botan/pk_keys.h> + +class BotanEDPrivateKey : public EDPrivateKey +{ +public: + // Constructors + BotanEDPrivateKey(); + + BotanEDPrivateKey(const Botan::Private_Key* inEDKEY); + + // Destructor + virtual ~BotanEDPrivateKey(); + + // The type + static const char* type; + + // Check if the key is of the given type + virtual bool isOfType(const char* inType); + + // Get the base point order length + virtual unsigned long getOrderLength() const; + + // Setters for the ED private key components + virtual void setK(const ByteString& inK); + + // Setters for the ED public key components + virtual void setEC(const ByteString& inEC); + + // Encode into PKCS#8 DER + virtual ByteString PKCS8Encode(); + + // Decode from PKCS#8 BER + virtual bool PKCS8Decode(const ByteString& ber); + + // Set from Botan representation + virtual void setFromBotan(const Botan::Private_Key* inEDKEY); + + // Retrieve the Botan representation of the key + Botan::Private_Key* getBotanKey(); + +private: + // The internal Botan representation + Botan::Private_Key* edkey; + + // Create the Botan representation of the key + void createBotanKey(); +}; +#endif +#endif // !_SOFTHSM_V2_BOTANEDPRIVATEKEY_H diff --git a/SoftHSMv2/src/lib/crypto/BotanEDPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanEDPublicKey.cpp new file mode 100644 index 0000000..3cf8474 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDPublicKey.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDPublicKey.cpp + + Botan EDDSA public key class + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "BotanEDPublicKey.h" +#include "BotanUtil.h" +#include "DerUtil.h" +#include <string.h> +#include <botan/curve25519.h> +#include <botan/ed25519.h> +// #include <botan/curve448.h> +// #include <botan/ed448.h> + +const Botan::OID x25519_oid("1.3.101.110"); +// const Botan::OID x448_oid("1.3.101.111"); +const Botan::OID ed25519_oid("1.3.101.112"); +// const Botan::OID ed448_oid("1.3.101.113"); + +// Constructors +BotanEDPublicKey::BotanEDPublicKey() +{ + edkey = NULL; +} + +BotanEDPublicKey::BotanEDPublicKey(const Botan::Public_Key* inEDKEY) +{ + edkey = NULL; + + setFromBotan(inEDKEY); +} + +// Destructor +BotanEDPublicKey::~BotanEDPublicKey() +{ + delete edkey; +} + +// The type +/*static*/ const char* BotanEDPublicKey::type = "Botan EDDSA Public Key"; + +// Get the base point order length +unsigned long BotanEDPublicKey::getOrderLength() const +{ + // Only Ed25519 is supported + return 32; +} + +// Set from Botan representation +void BotanEDPublicKey::setFromBotan(const Botan::Public_Key* inEDKEY) +{ + Botan::OID oid; + std::vector<uint8_t> pub; + + for (;;) + { + const Botan::Curve25519_PublicKey* x25519 = dynamic_cast<const Botan::Curve25519_PublicKey*>(inEDKEY); + if (x25519) { + oid = x25519_oid; + pub = x25519->public_value(); + break; + } + const Botan::Ed25519_PublicKey* ed25519 = dynamic_cast<const Botan::Ed25519_PublicKey*>(inEDKEY); + if (ed25519) { + oid = ed25519_oid; + pub = ed25519->get_public_key(); + break; + } + return; + } + ByteString inEC = BotanUtil::oid2ByteString(oid); + setEC(inEC); + ByteString inA; + inA.resize(pub.size()); + memcpy(&inA[0], &pub[0], pub.size()); + setA(DERUTIL::raw2Octet(inA)); +} + +// Check if the key is of the given type +bool BotanEDPublicKey::isOfType(const char* inType) +{ + return !strcmp(type, inType); +} + +// Setters for the EDDSA public key components +void BotanEDPublicKey::setEC(const ByteString& inEC) +{ + EDPublicKey::setEC(inEC); + + if (edkey) + { + delete edkey; + edkey = NULL; + } +} + +void BotanEDPublicKey::setA(const ByteString& inA) +{ + EDPublicKey::setA(inA); + + if (edkey) + { + delete edkey; + edkey = NULL; + } +} + +// Retrieve the Botan representation of the key +Botan::Public_Key* BotanEDPublicKey::getBotanKey() +{ + if (!edkey) + { + createBotanKey(); + } + + return edkey; +} + +// Create the Botan representation of the key +void BotanEDPublicKey::createBotanKey() +{ + if (ec.size() != 0 && + a.size() != 0) + { + if (edkey) + { + delete edkey; + edkey = NULL; + } + + try + { + ByteString raw = DERUTIL::octet2Raw(a); + size_t len = raw.size(); + if (len == 0) return; + + std::vector<uint8_t> pub(len); + memcpy(&pub[0], raw.const_byte_str(), len); + Botan::OID oid = BotanUtil::byteString2Oid(ec); + if (oid == x25519_oid) + { + edkey = new Botan::Curve25519_PublicKey(pub); + } + else if (oid == ed25519_oid) + { + edkey = new Botan::Ed25519_PublicKey(pub); + } + } + catch (...) + { + ERROR_MSG("Could not create the Botan public key"); + } + } +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/BotanEDPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanEDPublicKey.h new file mode 100644 index 0000000..15e6d45 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/BotanEDPublicKey.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation) + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + BotanEDPublicKey.h + + Botan EDDSA public key class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_BOTANEDPUBLICKEY_H +#define _SOFTHSM_V2_BOTANEDPUBLICKEY_H + +#include "config.h" +#ifdef WITH_EDDSA +#include "EDPublicKey.h" +#include <botan/pk_keys.h> + +class BotanEDPublicKey : public EDPublicKey +{ +public: + // Constructors + BotanEDPublicKey(); + + BotanEDPublicKey(const Botan::Public_Key* inEDKEY); + + // Destructor + virtual ~BotanEDPublicKey(); + + // The type + static const char* type; + + // Check if the key is of the given type + virtual bool isOfType(const char* inType); + + // Get the base point order length + virtual unsigned long getOrderLength() const; + + // Setters for the ED public key components + virtual void setEC(const ByteString& inEC); + virtual void setA(const ByteString& inA); + + // Set from Botan representation + virtual void setFromBotan(const Botan::Public_Key* inEDKEY); + + // Retrieve the Botan representation of the key + Botan::Public_Key* getBotanKey(); + +private: + // The internal Botan representation + Botan::Public_Key* edkey; + + // Create the Botan representation of the key + void createBotanKey(); +}; +#endif +#endif // !_SOFTHSM_V2_BOTANEDPUBLICKEY_H diff --git a/SoftHSMv2/src/lib/crypto/BotanUtil.cpp b/SoftHSMv2/src/lib/crypto/BotanUtil.cpp index e5da460..c623fed 100644 --- a/SoftHSMv2/src/lib/crypto/BotanUtil.cpp +++ b/SoftHSMv2/src/lib/crypto/BotanUtil.cpp @@ -144,3 +144,22 @@ Botan::PointGFp BotanUtil::byteString2ECPoint(const ByteString& byteString, cons return Botan::OS2ECP(&repr[0], repr.size(), ecGroup.get_curve()); } #endif + +#ifdef WITH_EDDSA +// Convert a Botan OID to a ByteString +ByteString BotanUtil::oid2ByteString(const Botan::OID& oid) +{ + const Botan::secure_vector<Botan::byte>& der = Botan::DER_Encoder().encode(oid).get_contents(); + return ByteString(&der[0], der.size()); +} + +// Convert a ByteString to a Botan OID +Botan::OID BotanUtil::byteString2Oid(const ByteString& byteString) +{ + Botan::OID oid; + Botan::BER_Decoder(byteString.const_byte_str(), byteString.size()) + .decode(oid) + .verify_end(); + return oid; +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/BotanUtil.h b/SoftHSMv2/src/lib/crypto/BotanUtil.h index 67f6ca6..ca86041 100644 --- a/SoftHSMv2/src/lib/crypto/BotanUtil.h +++ b/SoftHSMv2/src/lib/crypto/BotanUtil.h @@ -62,6 +62,13 @@ namespace BotanUtil // Convert a ByteString to a Botan EC point in the given EC group Botan::PointGFp byteString2ECPoint(const ByteString& byteString, const Botan::EC_Group& ecGroup); #endif +#ifdef WITH_EDDSA + // Convert a Botan OID to a ByteString + ByteString oid2ByteString(const Botan::OID& oid); + + // Convert a ByteString to a Botan OID + Botan::OID byteString2Oid(const ByteString& byteString); +#endif } #endif // !_SOFTHSM_V2_BOTANUTIL_H diff --git a/SoftHSMv2/src/lib/crypto/DerUtil.cpp b/SoftHSMv2/src/lib/crypto/DerUtil.cpp new file mode 100644 index 0000000..1117b2e --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/DerUtil.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2018 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + DerUtil.h + + DER encoding convenience functions + *****************************************************************************/ + +#include "config.h" +#include "DerUtil.h" + +// Convert a raw ByteString to a DER encoded octet string +ByteString DERUTIL::raw2Octet(const ByteString& byteString) +{ + ByteString header; + size_t len = byteString.size(); + + // Definite, short + if (len < 0x80) + { + header.resize(2); + header[0] = (unsigned char)0x04; + header[1] = (unsigned char)(len & 0x7F); + } + // Definite, long + else + { + // Count significate bytes + size_t bytes = sizeof(size_t); + for(; bytes > 0; bytes--) + { + size_t value = len >> ((bytes - 1) * 8); + if (value & 0xFF) break; + } + + // Set header data + header.resize(2 + bytes); + header[0] = (unsigned char)0x04; + header[1] = (unsigned char)(0x80 | bytes); + for (size_t i = 1; i <= bytes; i++) + { + header[2+bytes-i] = (unsigned char) (len & 0xFF); + len >>= 8; + } + } + + return header + byteString; +} + +// Convert a DER encoded octet string to a raw ByteString +ByteString DERUTIL::octet2Raw(const ByteString& byteString) +{ + ByteString rv; + ByteString repr = byteString; + size_t len = repr.size(); + size_t controlOctets = 2; + + if (len < controlOctets) + { + ERROR_MSG("Undersized octet string"); + + return rv; + } + + if (repr[0] != 0x04) + { + ERROR_MSG("ByteString is not an octet string"); + + return rv; + } + + // Definite, short + if (repr[1] < 0x80) + { + if (repr[1] != (len - controlOctets)) + { + if (repr[1] < (len - controlOctets)) + { + ERROR_MSG("Underrun octet string"); + } + else + { + ERROR_MSG("Overrun octet string"); + } + + return rv; + } + } + // Definite, long + else + { + size_t lengthOctets = repr[1] & 0x7f; + controlOctets += lengthOctets; + + if (controlOctets >= repr.size()) + { + ERROR_MSG("Undersized octet string"); + + return rv; + } + + ByteString length(&repr[2], lengthOctets); + + if (length.long_val() != (len - controlOctets)) + { + if (length.long_val() < (len - controlOctets)) + { + ERROR_MSG("Underrun octet string"); + } + else + { + ERROR_MSG("Overrun octet string"); + } + + return rv; + } + } + + return repr.substr(controlOctets, len - controlOctets); +} + diff --git a/SoftHSMv2/src/lib/crypto/DerUtil.h b/SoftHSMv2/src/lib/crypto/DerUtil.h new file mode 100644 index 0000000..d4df5fb --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/DerUtil.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + CryptoUtil.h + + DER encoding convenience functions + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_DERUTIL_H +#define _SOFTHSM_V2_DERUTIL_H + +#include "config.h" +#include "ByteString.h" + +namespace DERUTIL +{ + // Convert a raw ByteString to a DER encoded octet string + ByteString raw2Octet(const ByteString& byteString); + + // Convert a DER encoded octet string to a raw ByteString + ByteString octet2Raw(const ByteString& byteString); +} + +#endif // !_SOFTHSM_V2_DERUTIL_H + diff --git a/SoftHSMv2/src/lib/crypto/EDPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/EDPrivateKey.cpp new file mode 100644 index 0000000..23f9f71 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/EDPrivateKey.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + EDPrivateKey.cpp + + EDDSA private key class + *****************************************************************************/ + +#include "config.h" +#include "log.h" +#include "EDPrivateKey.h" +#include <string.h> + +// Set the type +/*static*/ const char* EDPrivateKey::type = "Abstract EDDSA private key"; + +// Check if the key is of the given type +bool EDPrivateKey::isOfType(const char* inType) +{ + return !strcmp(type, inType); +} + +// Get the bit length +unsigned long EDPrivateKey::getBitLength() const +{ + return getK().bits(); +} + +// Get the output length +unsigned long EDPrivateKey::getOutputLength() const +{ + return getOrderLength() * 2; +} + +// Setters for the EDDSA private key components +void EDPrivateKey::setK(const ByteString& inK) +{ + k = inK; +} + +// Setters for the EDDSA public key components +void EDPrivateKey::setEC(const ByteString& inEC) +{ + ec = inEC; +} + +// Getters for the EDDSA private key components +const ByteString& EDPrivateKey::getK() const +{ + return k; +} + +// Getters for the EDDSA public key components +const ByteString& EDPrivateKey::getEC() const +{ + return ec; +} + +// Serialisation +ByteString EDPrivateKey::serialise() const +{ + return ec.serialise() + + k.serialise(); +} + +bool EDPrivateKey::deserialise(ByteString& serialised) +{ + ByteString dEC = ByteString::chainDeserialise(serialised); + ByteString dK = ByteString::chainDeserialise(serialised); + + if ((dEC.size() == 0) || + (dK.size() == 0)) + { + return false; + } + + setEC(dEC); + setK(dK); + + return true; +} + diff --git a/SoftHSMv2/src/lib/crypto/EDPrivateKey.h b/SoftHSMv2/src/lib/crypto/EDPrivateKey.h new file mode 100644 index 0000000..778cf34 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/EDPrivateKey.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + EDPrivateKey.h + + EDDSA private key class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_EDPRIVATEKEY_H +#define _SOFTHSM_V2_EDPRIVATEKEY_H + +#include "config.h" +#include "PrivateKey.h" + +class EDPrivateKey : public PrivateKey +{ +public: + // The type + static const char* type; + + // Check if the key is of the given type + virtual bool isOfType(const char* inType); + + // Get the bit length + virtual unsigned long getBitLength() const; + + // Get the output length + virtual unsigned long getOutputLength() const; + + // Get the base point order length + virtual unsigned long getOrderLength() const = 0; + + // Setters for the EDDSA private key components + virtual void setK(const ByteString& inK); + + // Setters for the EDDSA public key components + virtual void setEC(const ByteString& inEC); + + // Getters for the EDDSA private key components + virtual const ByteString& getK() const; + + // Getters for the EDDSA public key components + virtual const ByteString& getEC() const; + + // Serialisation + virtual ByteString serialise() const; + virtual bool deserialise(ByteString& serialised); + +protected: + // Private components + ByteString k; + + // Public components + ByteString ec; +}; + +#endif // !_SOFTHSM_V2_EDPRIVATEKEY_H + diff --git a/SoftHSMv2/src/lib/crypto/EDPublicKey.cpp b/SoftHSMv2/src/lib/crypto/EDPublicKey.cpp new file mode 100644 index 0000000..cd7033e --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/EDPublicKey.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + EDPublicKey.cpp + + EDDSA public key class + *****************************************************************************/ + +#include "config.h" +#include "log.h" +#include "EDPublicKey.h" +#include <string.h> + +// Set the type +/*static*/ const char* EDPublicKey::type = "Abstract EDDSA public key"; + +// Check if the key is of the given type +bool EDPublicKey::isOfType(const char* inType) +{ + return !strcmp(type, inType); +} + +// Get the bit length +unsigned long EDPublicKey::getBitLength() const +{ + return getA().size() * 8; +} + +// Get the output length +unsigned long EDPublicKey::getOutputLength() const +{ + return getOrderLength() * 2; +} + +// Setters for the EC public key components +void EDPublicKey::setEC(const ByteString& inEC) +{ + ec = inEC; +} + +void EDPublicKey::setA(const ByteString& inA) +{ + a = inA; +} + +// Getters for the EC public key components +const ByteString& EDPublicKey::getEC() const +{ + return ec; +} + +const ByteString& EDPublicKey::getA() const +{ + return a; +} + +// Serialisation +ByteString EDPublicKey::serialise() const +{ + return ec.serialise() + + a.serialise(); +} + +bool EDPublicKey::deserialise(ByteString& serialised) +{ + ByteString dEC = ByteString::chainDeserialise(serialised); + ByteString dA = ByteString::chainDeserialise(serialised); + + if ((dEC.size() == 0) || + (dA.size() == 0)) + { + return false; + } + + setEC(dEC); + setA(dA); + + return true; +} + diff --git a/SoftHSMv2/src/lib/crypto/EDPublicKey.h b/SoftHSMv2/src/lib/crypto/EDPublicKey.h new file mode 100644 index 0000000..0d60634 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/EDPublicKey.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + EDPublicKey.h + + EDDSA public key class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_EDPUBLICKEY_H +#define _SOFTHSM_V2_EDPUBLICKEY_H + +#include "config.h" +#include "PublicKey.h" + +class EDPublicKey : public PublicKey +{ +public: + // The type + static const char* type; + + // Check if the key is of the given type + virtual bool isOfType(const char* inType); + + // Get the bit length + virtual unsigned long getBitLength() const; + + // Get the output length + virtual unsigned long getOutputLength() const; + + // Get the base point order length + virtual unsigned long getOrderLength() const = 0; + + // Setters for the EDDSA public key components + virtual void setEC(const ByteString& inEc); + virtual void setA(const ByteString& inA); + + // Getters for the EDDSA public key components + virtual const ByteString& getEC() const; + virtual const ByteString& getA() const; + + // Serialisation + virtual ByteString serialise() const; + virtual bool deserialise(ByteString& serialised); + +protected: + // Public components + ByteString ec, a; +}; + +#endif // !_SOFTHSM_V2_EDPUBLICKEY_H + diff --git a/SoftHSMv2/src/lib/crypto/Makefile.am b/SoftHSMv2/src/lib/crypto/Makefile.am index f65e0a4..e23848f 100644 --- a/SoftHSMv2/src/lib/crypto/Makefile.am +++ b/SoftHSMv2/src/lib/crypto/Makefile.am @@ -11,6 +11,7 @@ libsofthsm_crypto_la_SOURCES = AESKey.cpp \ AsymmetricAlgorithm.cpp \ AsymmetricKeyPair.cpp \ CryptoFactory.cpp \ + DerUtil.cpp \ DESKey.cpp \ DHParameters.cpp \ DHPublicKey.cpp \ @@ -21,6 +22,8 @@ libsofthsm_crypto_la_SOURCES = AESKey.cpp \ ECParameters.cpp \ ECPublicKey.cpp \ ECPrivateKey.cpp \ + EDPublicKey.cpp \ + EDPrivateKey.cpp \ GOSTPublicKey.cpp \ GOSTPrivateKey.cpp \ HashAlgorithm.cpp \ @@ -34,7 +37,9 @@ libsofthsm_crypto_la_LIBADD = @CRYPTO_LIBS@ SUBDIRS = test -EXTRA_DIST = $(srcdir)/*.h $(srcdir)/*.cpp +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ + $(srcdir)/*.cpp # Compile with support of OpenSSL if WITH_OPENSSL @@ -55,6 +60,10 @@ libsofthsm_crypto_la_SOURCES += OSSLAES.cpp \ OSSLECKeyPair.cpp \ OSSLECPrivateKey.cpp \ OSSLECPublicKey.cpp \ + OSSLEDDSA.cpp \ + OSSLEDKeyPair.cpp \ + OSSLEDPrivateKey.cpp \ + OSSLEDPublicKey.cpp \ OSSLEVPHashAlgorithm.cpp \ OSSLEVPMacAlgorithm.cpp \ OSSLEVPCMacAlgorithm.cpp \ @@ -101,6 +110,10 @@ libsofthsm_crypto_la_SOURCES += BotanAES.cpp \ BotanECDSAKeyPair.cpp \ BotanECDSAPrivateKey.cpp \ BotanECDSAPublicKey.cpp \ + BotanEDDSA.cpp \ + BotanEDKeyPair.cpp \ + BotanEDPrivateKey.cpp \ + BotanEDPublicKey.cpp \ BotanGOST.cpp \ BotanGOSTKeyPair.cpp \ BotanGOSTPrivateKey.cpp \ diff --git a/SoftHSMv2/src/lib/crypto/OSSLComp.h b/SoftHSMv2/src/lib/crypto/OSSLComp.h index 4bced32..5b2a424 100644 --- a/SoftHSMv2/src/lib/crypto/OSSLComp.h +++ b/SoftHSMv2/src/lib/crypto/OSSLComp.h @@ -82,6 +82,11 @@ void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); #endif +// EDDSA +#ifdef WITH_EDDSA +#error This OpenSSL version is incompatible with EDDSA +#endif + // RSA routines int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); diff --git a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp index ad27482..04d383d 100644 --- a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp +++ b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp @@ -55,6 +55,9 @@ #include "OSSLGOSTR3411.h" #include "OSSLGOST.h" #endif +#ifdef WITH_EDDSA +#include "OSSLEDDSA.h" +#endif #include <algorithm> #include <string.h> @@ -138,6 +141,27 @@ OSSLCryptoFactory::OSSLCryptoFactory() // Initialise OpenSSL OpenSSL_add_all_algorithms(); +#if !( OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) ) + // Make sure RDRAND is loaded first + ENGINE_load_rdrand(); +#endif + // Locate the engine + rdrand_engine = ENGINE_by_id("rdrand"); + // Use RDRAND if available + if (rdrand_engine != NULL) + { + // Initialize RDRAND engine + if (!ENGINE_init(rdrand_engine)) + { + WARNING_MSG("ENGINE_init returned %lu\n", ERR_get_error()); + } + // Set RDRAND engine as the default for RAND_ methods + else if (!ENGINE_set_default(rdrand_engine, ENGINE_METHOD_RAND)) + { + WARNING_MSG("ENGINE_set_default returned %lu\n", ERR_get_error()); + } + } + // Initialise the one-and-only RNG rng = new OSSLRNG(); @@ -147,6 +171,10 @@ OSSLCryptoFactory::OSSLCryptoFactory() ENGINE_load_builtin_engines(); #else OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN | + OPENSSL_INIT_ENGINE_RDRAND | + OPENSSL_INIT_LOAD_CRYPTO_STRINGS | + OPENSSL_INIT_ADD_ALL_CIPHERS | + OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); #endif @@ -291,6 +319,10 @@ AsymmetricAlgorithm* OSSLCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type al case AsymAlgo::GOST: return new OSSLGOST(); #endif +#ifdef WITH_EDDSA + case AsymAlgo::EDDSA: + return new OSSLEDDSA(); +#endif default: // No algorithm implementation is available ERROR_MSG("Unknown algorithm '%i'", algorithm); diff --git a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h index e8bfa2c..d718b69 100644 --- a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h +++ b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h @@ -41,10 +41,8 @@ #include "MacAlgorithm.h" #include "RNG.h" #include <memory> -#ifdef WITH_GOST #include <openssl/conf.h> #include <openssl/engine.h> -#endif class OSSLCryptoFactory : public CryptoFactory { @@ -105,6 +103,8 @@ private: // The one-and-only RNG instance RNG* rng; + // And RDRAND engine to use with it + ENGINE *rdrand_engine; #ifdef WITH_GOST // The GOST engine diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDDSA.cpp b/SoftHSMv2/src/lib/crypto/OSSLEDDSA.cpp new file mode 100644 index 0000000..8fde7e2 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDDSA.cpp @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDDSA.cpp + + OpenSSL EDDSA asymmetric algorithm implementation + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "OSSLEDDSA.h" +#include "CryptoFactory.h" +#include "ECParameters.h" +#include "OSSLEDKeyPair.h" +#include "OSSLComp.h" +#include "OSSLUtil.h" +#include <algorithm> +#include <openssl/evp.h> +#include <openssl/pem.h> +#include <openssl/err.h> +#include <string.h> + +// Signing functions +bool OSSLEDDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, + ByteString& signature, const AsymMech::Type mechanism, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + if (mechanism != AsymMech::EDDSA) + { + ERROR_MSG("Invalid mechanism supplied (%i)", mechanism); + return false; + } + + // Check if the private key is the right type + if (!privateKey->isOfType(OSSLEDPrivateKey::type)) + { + ERROR_MSG("Invalid key type supplied"); + + return false; + } + + OSSLEDPrivateKey* pk = (OSSLEDPrivateKey*) privateKey; + EVP_PKEY* pkey = pk->getOSSLKey(); + + if (pkey == NULL) + { + ERROR_MSG("Could not get the OpenSSL private key"); + + return false; + } + + // Perform the signature operation + size_t len = pk->getOrderLength(); + if (len == 0) + { + ERROR_MSG("Could not get the order length"); + return false; + } + len *= 2; + signature.resize(len); + memset(&signature[0], 0, len); + EVP_MD_CTX* ctx = EVP_MD_CTX_new(); + if (!EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey)) + { + ERROR_MSG("EDDSA sign init failed (0x%08X)", ERR_get_error()); + EVP_MD_CTX_free(ctx); + return false; + } + if (!EVP_DigestSign(ctx, &signature[0], &len, dataToSign.const_byte_str(), dataToSign.size())) + { + ERROR_MSG("EDDSA sign failed (0x%08X)", ERR_get_error()); + EVP_MD_CTX_free(ctx); + return false; + } + EVP_MD_CTX_free(ctx); + return true; +} + +bool OSSLEDDSA::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + ERROR_MSG("EDDSA does not support multi part signing"); + + return false; +} + +bool OSSLEDDSA::signUpdate(const ByteString& /*dataToSign*/) +{ + ERROR_MSG("EDDSA does not support multi part signing"); + + return false; +} + +bool OSSLEDDSA::signFinal(ByteString& /*signature*/) +{ + ERROR_MSG("EDDSA does not support multi part signing"); + + return false; +} + +// Verification functions +bool OSSLEDDSA::verify(PublicKey* publicKey, const ByteString& originalData, + const ByteString& signature, const AsymMech::Type mechanism, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + if (mechanism != AsymMech::EDDSA) + { + ERROR_MSG("Invalid mechanism supplied (%i)", mechanism); + return false; + } + + // Check if the private key is the right type + if (!publicKey->isOfType(OSSLEDPublicKey::type)) + { + ERROR_MSG("Invalid key type supplied"); + + return false; + } + + OSSLEDPublicKey* pk = (OSSLEDPublicKey*) publicKey; + EVP_PKEY* pkey = pk->getOSSLKey(); + + if (pkey == NULL) + { + ERROR_MSG("Could not get the OpenSSL public key"); + + return false; + } + + // Perform the verify operation + size_t len = pk->getOrderLength(); + if (len == 0) + { + ERROR_MSG("Could not get the order length"); + return false; + } + len *= 2; + if (signature.size() != len) + { + ERROR_MSG("Invalid buffer length"); + return false; + } + EVP_MD_CTX* ctx = EVP_MD_CTX_new(); + if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey)) + { + ERROR_MSG("EDDSA verify init failed (0x%08X)", ERR_get_error()); + EVP_MD_CTX_free(ctx); + return false; + } + int ret = EVP_DigestVerify(ctx, signature.const_byte_str(), len, originalData.const_byte_str(), originalData.size()); + if (ret != 1) + { + if (ret < 0) + ERROR_MSG("EDDSA verify failed (0x%08X)", ERR_get_error()); + EVP_MD_CTX_free(ctx); + return false; + } + EVP_MD_CTX_free(ctx); + return true; +} + +bool OSSLEDDSA::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/, + const void* /* param = NULL */, const size_t /* paramLen = 0 */) +{ + ERROR_MSG("EDDSA does not support multi part verifying"); + + return false; +} + +bool OSSLEDDSA::verifyUpdate(const ByteString& /*originalData*/) +{ + ERROR_MSG("EDDSA does not support multi part verifying"); + + return false; +} + +bool OSSLEDDSA::verifyFinal(const ByteString& /*signature*/) +{ + ERROR_MSG("EDDSA does not support multi part verifying"); + + return false; +} + +// Encryption functions +bool OSSLEDDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/, + ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/) +{ + ERROR_MSG("EDDSA does not support encryption"); + + return false; +} + +// Decryption functions +bool OSSLEDDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/, + ByteString& /*data*/, const AsymMech::Type /*padding*/) +{ + ERROR_MSG("EDDSA does not support decryption"); + + return false; +} + +// Key factory +bool OSSLEDDSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */) +{ + // Check parameters + if ((ppKeyPair == NULL) || + (parameters == NULL)) + { + return false; + } + + if (!parameters->areOfType(ECParameters::type)) + { + ERROR_MSG("Invalid parameters supplied for EDDSA key generation"); + + return false; + } + + ECParameters* params = (ECParameters*) parameters; + int nid = OSSL::byteString2oid(params->getEC()); + + // Generate the key-pair + EVP_PKEY* pkey = NULL; + EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(nid, NULL); + if (ctx == NULL) + { + ERROR_MSG("Failed to instantiate OpenSSL EDDSA context"); + + return false; + } + int ret = EVP_PKEY_keygen_init(ctx); + if (ret != 1) + { + ERROR_MSG("EDDSA key generation init failed (0x%08X)", ERR_get_error()); + EVP_PKEY_CTX_free(ctx); + return false; + } + ret = EVP_PKEY_keygen(ctx, &pkey); + if (ret != 1) + { + ERROR_MSG("EDDSA key generation failed (0x%08X)", ERR_get_error()); + EVP_PKEY_CTX_free(ctx); + return false; + } + EVP_PKEY_CTX_free(ctx); + + // Create an asymmetric key-pair object to return + OSSLEDKeyPair* kp = new OSSLEDKeyPair(); + + ((OSSLEDPublicKey*) kp->getPublicKey())->setFromOSSL(pkey); + ((OSSLEDPrivateKey*) kp->getPrivateKey())->setFromOSSL(pkey); + + *ppKeyPair = kp; + + // Release the key + EVP_PKEY_free(pkey); + + return true; +} + +bool OSSLEDDSA::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey) +{ + // Check parameters + if ((ppSymmetricKey == NULL) || + (publicKey == NULL) || + (privateKey == NULL)) + { + return false; + } + + // Get keys + EVP_PKEY *pub = ((OSSLEDPublicKey *)publicKey)->getOSSLKey(); + EVP_PKEY *priv = ((OSSLEDPrivateKey *)privateKey)->getOSSLKey(); + if (pub == NULL || priv == NULL) + { + ERROR_MSG("Failed to get OpenSSL ECDH keys"); + + return false; + } + + // Get and set context + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(priv, NULL); + if (ctx == NULL) + { + ERROR_MSG("Failed to get OpenSSL ECDH context"); + + return false; + } + if (EVP_PKEY_derive_init(ctx) <= 0) + { + ERROR_MSG("Failed to init OpenSSL key derive"); + + EVP_PKEY_CTX_free(ctx); + return false; + } + if (EVP_PKEY_derive_set_peer(ctx, pub) <= 0) + { + ERROR_MSG("Failed to set OpenSSL ECDH public key"); + + EVP_PKEY_CTX_free(ctx); + return false; + } + + // Derive the secret + size_t len; + if (EVP_PKEY_derive(ctx, NULL, &len) <= 0) + { + ERROR_MSG("Failed to get OpenSSL ECDH key length"); + + EVP_PKEY_CTX_free(ctx); + return false; + } + ByteString secret; + secret.resize(len); + if (EVP_PKEY_derive(ctx, &secret[0], &len) <= 0) + { + ERROR_MSG("Failed to derive OpenSSL ECDH secret"); + + EVP_PKEY_CTX_free(ctx); + return false; + } + EVP_PKEY_CTX_free(ctx); + + // Create derived key + *ppSymmetricKey = new SymmetricKey(secret.size() * 8); + if (*ppSymmetricKey == NULL) + return false; + if (!(*ppSymmetricKey)->setKeyBits(secret)) + { + delete *ppSymmetricKey; + *ppSymmetricKey = NULL; + return false; + } + + return true; +} + +unsigned long OSSLEDDSA::getMinKeySize() +{ + // Ed25519 is supported + return 32*8; +} + +unsigned long OSSLEDDSA::getMaxKeySize() +{ + // Ed448 will be supported + return 57*8; +} + +bool OSSLEDDSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData) +{ + // Check input + if ((ppKeyPair == NULL) || + (serialisedData.size() == 0)) + { + return false; + } + + ByteString dPub = ByteString::chainDeserialise(serialisedData); + ByteString dPriv = ByteString::chainDeserialise(serialisedData); + + OSSLEDKeyPair* kp = new OSSLEDKeyPair(); + + bool rv = true; + + if (!((EDPublicKey*) kp->getPublicKey())->deserialise(dPub)) + { + rv = false; + } + + if (!((EDPrivateKey*) kp->getPrivateKey())->deserialise(dPriv)) + { + rv = false; + } + + if (!rv) + { + delete kp; + + return false; + } + + *ppKeyPair = kp; + + return true; +} + +bool OSSLEDDSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData) +{ + // Check input + if ((ppPublicKey == NULL) || + (serialisedData.size() == 0)) + { + return false; + } + + OSSLEDPublicKey* pub = new OSSLEDPublicKey(); + + if (!pub->deserialise(serialisedData)) + { + delete pub; + + return false; + } + + *ppPublicKey = pub; + + return true; +} + +bool OSSLEDDSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData) +{ + // Check input + if ((ppPrivateKey == NULL) || + (serialisedData.size() == 0)) + { + return false; + } + + OSSLEDPrivateKey* priv = new OSSLEDPrivateKey(); + + if (!priv->deserialise(serialisedData)) + { + delete priv; + + return false; + } + + *ppPrivateKey = priv; + + return true; +} + +PublicKey* OSSLEDDSA::newPublicKey() +{ + return (PublicKey*) new OSSLEDPublicKey(); +} + +PrivateKey* OSSLEDDSA::newPrivateKey() +{ + return (PrivateKey*) new OSSLEDPrivateKey(); +} + +AsymmetricParameters* OSSLEDDSA::newParameters() +{ + return (AsymmetricParameters*) new ECParameters(); +} + +bool OSSLEDDSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData) +{ + // Check input parameters + if ((ppParams == NULL) || (serialisedData.size() == 0)) + { + return false; + } + + ECParameters* params = new ECParameters(); + + if (!params->deserialise(serialisedData)) + { + delete params; + + return false; + } + + *ppParams = params; + + return true; +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDDSA.h b/SoftHSMv2/src/lib/crypto/OSSLEDDSA.h new file mode 100644 index 0000000..02b8a11 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDDSA.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDDSA.h + + OpenSSL EDDSA asymmetric algorithm implementation + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_OSSLEDDSA_H +#define _SOFTHSM_V2_OSSLEDDSA_H + +#include "config.h" +#include "AsymmetricAlgorithm.h" +#include <openssl/evp.h> + +class OSSLEDDSA : public AsymmetricAlgorithm +{ +public: + // Destructor + virtual ~OSSLEDDSA() { } + + // Signing functions + virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool signUpdate(const ByteString& dataToSign); + virtual bool signFinal(ByteString& signature); + + // Verification functions + virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0); + virtual bool verifyUpdate(const ByteString& originalData); + virtual bool verifyFinal(const ByteString& signature); + + // Encryption functions + virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding); + + // Decryption functions + virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding); + + // Key factory + virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL); + virtual unsigned long getMinKeySize(); + virtual unsigned long getMaxKeySize(); + virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey); + virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData); + virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData); + virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData); + virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData); + virtual PublicKey* newPublicKey(); + virtual PrivateKey* newPrivateKey(); + virtual AsymmetricParameters* newParameters(); + +private: +}; + +#endif // !_SOFTHSM_V2_OSSLEDDSA_H + diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.cpp b/SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.cpp new file mode 100644 index 0000000..c452785 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDKeyPair.cpp + + OpenSSL EDDSA key-pair class + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "OSSLEDKeyPair.h" + +// Set the public key +void OSSLEDKeyPair::setPublicKey(OSSLEDPublicKey& publicKey) +{ + pubKey = publicKey; +} + +// Set the private key +void OSSLEDKeyPair::setPrivateKey(OSSLEDPrivateKey& privateKey) +{ + privKey = privateKey; +} + +// Return the public key +PublicKey* OSSLEDKeyPair::getPublicKey() +{ + return &pubKey; +} + +const PublicKey* OSSLEDKeyPair::getConstPublicKey() const +{ + return &pubKey; +} + +// Return the private key +PrivateKey* OSSLEDKeyPair::getPrivateKey() +{ + return &privKey; +} + +const PrivateKey* OSSLEDKeyPair::getConstPrivateKey() const +{ + return &privKey; +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.h b/SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.h new file mode 100644 index 0000000..3efe9f4 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDKeyPair.h + + OpenSSL EDDSA key-pair class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_OSSLEDKEYPAIR_H +#define _SOFTHSM_V2_OSSLEDKEYPAIR_H + +#include "config.h" +#include "AsymmetricKeyPair.h" +#include "OSSLEDPublicKey.h" +#include "OSSLEDPrivateKey.h" + +class OSSLEDKeyPair : public AsymmetricKeyPair +{ +public: + // Set the public key + void setPublicKey(OSSLEDPublicKey& publicKey); + + // Set the private key + void setPrivateKey(OSSLEDPrivateKey& privateKey); + + // Return the public key + virtual PublicKey* getPublicKey(); + virtual const PublicKey* getConstPublicKey() const; + + // Return the private key + virtual PrivateKey* getPrivateKey(); + virtual const PrivateKey* getConstPrivateKey() const; + +private: + // The public key + OSSLEDPublicKey pubKey; + + // The private key + OSSLEDPrivateKey privKey; +}; + +#endif // !_SOFTHSM_V2_OSSLEDKEYPAIR_H + diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.cpp new file mode 100644 index 0000000..7c91b54 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDPrivateKey.cpp + + OpenSSL EDDSA private key class + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "OSSLEDPrivateKey.h" +#include "OSSLUtil.h" +#include <openssl/x509.h> + +#define X25519_KEYLEN 32 +#define X448_KEYLEN 57 + +#define PREFIXLEN 16 + +// Prefixes +const unsigned char x25519_prefix[] = { + 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, + 0x03, 0x2b, 0x65, 0x6e, 0x04, 0x22, 0x04, 0x20 +}; + +const unsigned char x448_prefix[] = { + 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, + 0x03, 0x2b, 0x65, 0x6f, 0x04, 0x22, 0x04, 0x20 +}; + +const unsigned char ed25519_prefix[] = { + 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, + 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20 +}; + +const unsigned char ed448_prefix[] = { + 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, + 0x03, 0x2b, 0x65, 0x71, 0x04, 0x22, 0x04, 0x20 +}; + +// Constructors +OSSLEDPrivateKey::OSSLEDPrivateKey() +{ + nid = NID_undef; + pkey = NULL; +} + +OSSLEDPrivateKey::OSSLEDPrivateKey(const EVP_PKEY* inPKEY) +{ + nid = NID_undef; + pkey = NULL; + + setFromOSSL(inPKEY); +} + +// Destructor +OSSLEDPrivateKey::~OSSLEDPrivateKey() +{ + EVP_PKEY_free(pkey); +} + +// The type +/*static*/ const char* OSSLEDPrivateKey::type = "OpenSSL EDDSA Private Key"; + +// Get the base point order length +unsigned long OSSLEDPrivateKey::getOrderLength() const +{ + if (nid == NID_ED25519) + return X25519_KEYLEN; + if (nid == NID_ED448) + return X448_KEYLEN; + return 0; +} + +// Set from OpenSSL representation +void OSSLEDPrivateKey::setFromOSSL(const EVP_PKEY* inPKEY) +{ + nid = EVP_PKEY_id(inPKEY); + if (nid == NID_undef) + { + return; + } + ByteString inEC = OSSL::oid2ByteString(nid); + EDPrivateKey::setEC(inEC); + + // i2d_PrivateKey incorrectly does not const the key argument?! + EVP_PKEY* key = const_cast<EVP_PKEY*>(inPKEY); + int len = i2d_PrivateKey(key, NULL); + if (len <= 0) + { + ERROR_MSG("Could not encode EDDSA private key"); + return; + } + ByteString der; + der.resize(len); + unsigned char *p = &der[0]; + i2d_PrivateKey(key, &p); + ByteString inK; + switch (nid) { + case NID_X25519: + case NID_ED25519: + if (len != (X25519_KEYLEN + PREFIXLEN)) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X25519_KEYLEN + PREFIXLEN, len); + return; + } + inK.resize(X25519_KEYLEN); + memcpy(&inK[0], &der[PREFIXLEN], X25519_KEYLEN); + break; + case NID_X448: + case NID_ED448: + if (len != (X448_KEYLEN + PREFIXLEN)) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X448_KEYLEN + PREFIXLEN, len); + return; + } + inK.resize(X448_KEYLEN); + memcpy(&inK[0], &der[PREFIXLEN], X448_KEYLEN); + break; + default: + return; + } + setK(inK); +} + +// Check if the key is of the given type +bool OSSLEDPrivateKey::isOfType(const char* inType) +{ + return !strcmp(type, inType); +} + +// Setters for the EDDSA private key components +void OSSLEDPrivateKey::setK(const ByteString& inK) +{ + EDPrivateKey::setK(inK); + + if (pkey) + { + EVP_PKEY_free(pkey); + pkey = NULL; + } +} + + +// Setters for the EDDSA public key components +void OSSLEDPrivateKey::setEC(const ByteString& inEC) +{ + EDPrivateKey::setEC(inEC); + + nid = OSSL::byteString2oid(inEC); + if (pkey) + { + EVP_PKEY_free(pkey); + pkey = NULL; + } +} + +// Encode into PKCS#8 DER +ByteString OSSLEDPrivateKey::PKCS8Encode() +{ + ByteString der; + EVP_PKEY* key = getOSSLKey(); + if (key == NULL) return der; + PKCS8_PRIV_KEY_INFO* p8 = EVP_PKEY2PKCS8(key); + if (p8 == NULL) return der; + int len = i2d_PKCS8_PRIV_KEY_INFO(p8, NULL); + if (len <= 0) + { + PKCS8_PRIV_KEY_INFO_free(p8); + return der; + } + der.resize(len); + unsigned char* p = &der[0]; + i2d_PKCS8_PRIV_KEY_INFO(p8, &p); + PKCS8_PRIV_KEY_INFO_free(p8); + return der; +} + +// Decode from PKCS#8 BER +bool OSSLEDPrivateKey::PKCS8Decode(const ByteString& ber) +{ + int len = ber.size(); + if (len <= 0) return false; + const unsigned char* p = ber.const_byte_str(); + PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + if (p8 == NULL) return false; + EVP_PKEY* key = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (key == NULL) return false; + setFromOSSL(key); + EVP_PKEY_free(key); + return true; +} + +// Retrieve the OpenSSL representation of the key +EVP_PKEY* OSSLEDPrivateKey::getOSSLKey() +{ + if (pkey == NULL) createOSSLKey(); + + return pkey; +} + +// Create the OpenSSL representation of the key +void OSSLEDPrivateKey::createOSSLKey() +{ + if (pkey != NULL) return; + + ByteString der; + switch (nid) { + case NID_X25519: + if (k.size() != X25519_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X25519_KEYLEN, k.size()); + return; + } + der.resize(PREFIXLEN + X25519_KEYLEN); + memcpy(&der[0], x25519_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], k.const_byte_str(), X25519_KEYLEN); + break; + case NID_ED25519: + if (k.size() != X25519_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X25519_KEYLEN, k.size()); + return; + } + der.resize(PREFIXLEN + X25519_KEYLEN); + memcpy(&der[0], ed25519_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], k.const_byte_str(), X25519_KEYLEN); + break; + case NID_X448: + if (k.size() != X448_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X448_KEYLEN, k.size()); + return; + } + der.resize(PREFIXLEN + X448_KEYLEN); + memcpy(&der[0], x448_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], k.const_byte_str(), X448_KEYLEN); + break; + case NID_ED448: + if (k.size() != X448_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X448_KEYLEN, k.size()); + return; + } + der.resize(PREFIXLEN + X448_KEYLEN); + memcpy(&der[0], ed448_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], k.const_byte_str(), X448_KEYLEN); + break; + default: + return; + } + const unsigned char *p = &der[0]; + pkey = d2i_PrivateKey(nid, NULL, &p, (long)der.size()); +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.h b/SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.h new file mode 100644 index 0000000..f097718 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDPrivateKey.h + + OpenSSL EDDSA private key class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_OSSLEDPRIVATEKEY_H +#define _SOFTHSM_V2_OSSLEDPRIVATEKEY_H + +#include "config.h" +#include "EDPrivateKey.h" +#include <openssl/bn.h> +#include <openssl/evp.h> + +class OSSLEDPrivateKey : public EDPrivateKey +{ +public: + // Constructors + OSSLEDPrivateKey(); + + OSSLEDPrivateKey(const EVP_PKEY* inPKEY); + + // Destructor + virtual ~OSSLEDPrivateKey(); + + // The type + static const char* type; + + // Check if the key is of the given type + virtual bool isOfType(const char* inType); + + // Get the base point order length + virtual unsigned long getOrderLength() const; + + // Setters for the EDDSA private key components + virtual void setK(const ByteString& inK); + + // Setters for the EDDSA public key components + virtual void setEC(const ByteString& inEC); + + // Encode into PKCS#8 DER + virtual ByteString PKCS8Encode(); + + // Decode from PKCS#8 BER + virtual bool PKCS8Decode(const ByteString& ber); + + // Set from OpenSSL representation + virtual void setFromOSSL(const EVP_PKEY* inPKEY); + + // Retrieve the OpenSSL representation of the key + EVP_PKEY* getOSSLKey(); + +private: + // The internal OpenSSL representation + int nid; + EVP_PKEY* pkey; + + // Create the OpenSSL representation of the key + void createOSSLKey(); +}; + +#endif // !_SOFTHSM_V2_OSSLEDPRIVATEKEY_H + diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.cpp new file mode 100644 index 0000000..e4515ff --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDPublicKey.cpp + + OpenSSL EDDSA public key class + *****************************************************************************/ + +#include "config.h" +#ifdef WITH_EDDSA +#include "log.h" +#include "DerUtil.h" +#include "OSSLEDPublicKey.h" +#include "OSSLUtil.h" +#include <openssl/x509.h> +#include <string.h> + +#define X25519_KEYLEN 32 +#define X448_KEYLEN 57 + +#define PREFIXLEN 12 + +// Prefixes +const unsigned char x25519_prefix[] = { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, + 0x6e, 0x03, 0x21, 0x00 +}; + +const unsigned char x448_prefix[] = { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, + 0x6f, 0x03, 0x21, 0x00 +}; + +const unsigned char ed25519_prefix[] = { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, + 0x70, 0x03, 0x21, 0x00 +}; + +const unsigned char ed448_prefix[] = { + 0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, + 0x71, 0x03, 0x21, 0x00 +}; + +// Constructors +OSSLEDPublicKey::OSSLEDPublicKey() +{ + nid = NID_undef; + pkey = NULL; +} + +OSSLEDPublicKey::OSSLEDPublicKey(const EVP_PKEY* inPKEY) +{ + nid = NID_undef; + pkey = NULL; + + setFromOSSL(inPKEY); +} + +// Destructor +OSSLEDPublicKey::~OSSLEDPublicKey() +{ + EVP_PKEY_free(pkey); +} + +// The type +/*static*/ const char* OSSLEDPublicKey::type = "OpenSSL EDDSA Public Key"; + +// Get the base point order length +unsigned long OSSLEDPublicKey::getOrderLength() const +{ + if (nid == NID_ED25519) + return X25519_KEYLEN; + if (nid == NID_ED448) + return X448_KEYLEN; + return 0; +} + +// Set from OpenSSL representation +void OSSLEDPublicKey::setFromOSSL(const EVP_PKEY* inPKEY) +{ + nid = EVP_PKEY_id(inPKEY); + if (nid == NID_undef) + { + return; + } + ByteString inEC = OSSL::oid2ByteString(nid); + EDPublicKey::setEC(inEC); + + // i2d_PUBKEY incorrectly does not const the key argument?! + EVP_PKEY* key = const_cast<EVP_PKEY*>(inPKEY); + int len = i2d_PUBKEY(key, NULL); + if (len <= 0) + { + ERROR_MSG("Could not encode EDDSA public key"); + return; + } + ByteString der; + der.resize(len); + unsigned char *p = &der[0]; + i2d_PUBKEY(key, &p); + ByteString raw; + switch (nid) { + case NID_X25519: + case NID_ED25519: + if (len != (X25519_KEYLEN + PREFIXLEN)) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X25519_KEYLEN + PREFIXLEN, len); + return; + } + raw.resize(X25519_KEYLEN); + memcpy(&raw[0], &der[PREFIXLEN], X25519_KEYLEN); + break; + case NID_X448: + case NID_ED448: + if (len != (X448_KEYLEN + PREFIXLEN)) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X448_KEYLEN + PREFIXLEN, len); + return; + } + raw.resize(X448_KEYLEN); + memcpy(&raw[0], &der[PREFIXLEN], X448_KEYLEN); + break; + default: + return; + } + setA(DERUTIL::raw2Octet(raw)); +} + +// Check if the key is of the given type +bool OSSLEDPublicKey::isOfType(const char* inType) +{ + return !strcmp(type, inType); +} + +// Setters for the EDDSA public key components +void OSSLEDPublicKey::setEC(const ByteString& inEC) +{ + EDPublicKey::setEC(inEC); + + nid = OSSL::byteString2oid(inEC); + if (pkey) + { + EVP_PKEY_free(pkey); + pkey = NULL; + } +} + +void OSSLEDPublicKey::setA(const ByteString& inA) +{ + EDPublicKey::setA(inA); + + if (pkey) + { + EVP_PKEY_free(pkey); + pkey = NULL; + } +} + +// Retrieve the OpenSSL representation of the key +EVP_PKEY* OSSLEDPublicKey::getOSSLKey() +{ + if (pkey == NULL) createOSSLKey(); + + return pkey; +} + +// Create the OpenSSL representation of the key +void OSSLEDPublicKey::createOSSLKey() +{ + if (pkey != NULL) return; + + ByteString der; + ByteString raw = DERUTIL::octet2Raw(a); + size_t len = raw.size(); + if (len == 0) return; + + switch (nid) { + case NID_X25519: + if (len != X25519_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X25519_KEYLEN, len); + return; + } + der.resize(PREFIXLEN + X25519_KEYLEN); + memcpy(&der[0], x25519_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], raw.const_byte_str(), X25519_KEYLEN); + break; + case NID_ED25519: + if (len != X25519_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X25519_KEYLEN, len); + return; + } + der.resize(PREFIXLEN + X25519_KEYLEN); + memcpy(&der[0], ed25519_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], raw.const_byte_str(), X25519_KEYLEN); + break; + case NID_X448: + if (len != X448_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X448_KEYLEN, len); + return; + } + der.resize(PREFIXLEN + X448_KEYLEN); + memcpy(&der[0], x448_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], raw.const_byte_str(), X448_KEYLEN); + break; + case NID_ED448: + if (len != X448_KEYLEN) + { + ERROR_MSG("Invalid size. Expected: %lu, Actual: %lu", X448_KEYLEN, len); + return; + } + der.resize(PREFIXLEN + X448_KEYLEN); + memcpy(&der[0], ed448_prefix, PREFIXLEN); + memcpy(&der[PREFIXLEN], raw.const_byte_str(), X448_KEYLEN); + break; + default: + return; + } + const unsigned char *p = &der[0]; + pkey = d2i_PUBKEY(NULL, &p, (long)der.size()); +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.h b/SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.h new file mode 100644 index 0000000..6951a2b --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + OSSLEDPublicKey.h + + OpenSSL EDDSA public key class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_OSSLEDPUBLICKEY_H +#define _SOFTHSM_V2_OSSLEDPUBLICKEY_H + +#include "config.h" +#include "EDPublicKey.h" +#include <openssl/evp.h> + +class OSSLEDPublicKey : public EDPublicKey +{ +public: + // Constructors + OSSLEDPublicKey(); + + OSSLEDPublicKey(const EVP_PKEY* inPKEY); + + // Destructor + virtual ~OSSLEDPublicKey(); + + // The type + static const char* type; + + // Check if the key is of the given type + virtual bool isOfType(const char* inType); + + // Get the base point order length + virtual unsigned long getOrderLength() const; + + // Setters for the EDDSA public key components + virtual void setEC(const ByteString& inEC); + virtual void setA(const ByteString& inA); + + // Set from OpenSSL representation + virtual void setFromOSSL(const EVP_PKEY* inPKEY); + + // Retrieve the OpenSSL representation of the key + EVP_PKEY* getOSSLKey(); + +private: + // The internal OpenSSL representation + int nid; + EVP_PKEY* pkey; + + // Create the OpenSSL representation of the key + void createOSSLKey(); +}; + +#endif // !_SOFTHSM_V2_OSSLDSAPUBLICKEY_H + diff --git a/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp b/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp index 981bb98..3a9c742 100644 --- a/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp +++ b/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp @@ -32,6 +32,7 @@ #include "config.h" #include "log.h" +#include "DerUtil.h" #include "OSSLUtil.h" #include <openssl/asn1.h> #include <openssl/err.h> @@ -86,114 +87,56 @@ EC_GROUP* OSSL::byteString2grp(const ByteString& byteString) // Convert an OpenSSL EC POINT in the given EC GROUP to a ByteString ByteString OSSL::pt2ByteString(const EC_POINT* pt, const EC_GROUP* grp) { - ByteString rv; + ByteString raw; - if (pt != NULL && grp != NULL) - { - size_t len = EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); - // Definite, short - if (len <= 0x7f) - { - rv.resize(2 + len); - rv[0] = V_ASN1_OCTET_STRING; - rv[1] = len & 0x7f; - EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2], len, NULL); - } - // Definite, long - else - { - // Get the number of length octets - ByteString length(len); - unsigned int counter = 0; - while (length[counter] == 0 && counter < (length.size()-1)) counter++; - ByteString lengthOctets(&length[counter], length.size() - counter); - - rv.resize(len + 2 + lengthOctets.size()); - rv[0] = V_ASN1_OCTET_STRING; - rv[1] = 0x80 | lengthOctets.size(); - memcpy(&rv[2], &lengthOctets[0], lengthOctets.size()); - EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2 + lengthOctets.size()], len, NULL); - } - } + if (pt == NULL || grp == NULL) + return raw; - return rv; + size_t len = EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + raw.resize(len); + EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &raw[0], len, NULL); + + return DERUTIL::raw2Octet(raw); } // Convert a ByteString to an OpenSSL EC POINT in the given EC GROUP EC_POINT* OSSL::byteString2pt(const ByteString& byteString, const EC_GROUP* grp) { - size_t len = byteString.size(); - size_t controlOctets = 2; - if (len < controlOctets) - { - ERROR_MSG("Undersized EC point"); + ByteString raw = DERUTIL::octet2Raw(byteString); + size_t len = raw.size(); + if (len == 0) return NULL; + EC_POINT* pt = EC_POINT_new(grp); + if (!EC_POINT_oct2point(grp, pt, &raw[0], len, NULL)) + { + ERROR_MSG("EC_POINT_oct2point failed: %s", ERR_error_string(ERR_get_error(), NULL)); + EC_POINT_free(pt); return NULL; } + return pt; +} +#endif - ByteString repr = byteString; +#ifdef WITH_EDDSA +// Convert an OpenSSL NID to a ByteString +ByteString OSSL::oid2ByteString(int nid) +{ + ByteString rv; - if (repr[0] != V_ASN1_OCTET_STRING) + if (nid != NID_undef) { - ERROR_MSG("EC point tag is not OCTET STRING"); - - return NULL; + rv.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL)); + unsigned char *p = &rv[0]; + i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p); } - // Definite, short - if (repr[1] < 0x80) - { - if (repr[1] != (len - controlOctets)) - { - if (repr[1] < (len - controlOctets)) - { - ERROR_MSG("Underrun EC point"); - } - else - { - ERROR_MSG("Overrun EC point"); - } - - return NULL; - } - } - // Definite, long - else - { - size_t lengthOctets = repr[1] & 0x7f; - controlOctets += lengthOctets; - - if (controlOctets >= repr.size()) - { - ERROR_MSG("Undersized EC point"); - - return NULL; - } - - ByteString length(&repr[2], lengthOctets); - - if (length.long_val() != (len - controlOctets)) - { - if (length.long_val() < (len - controlOctets)) - { - ERROR_MSG("Underrun EC point"); - } - else - { - ERROR_MSG("Overrun EC point"); - } - - return NULL; - } - } + return rv; +} - EC_POINT* pt = EC_POINT_new(grp); - if (!EC_POINT_oct2point(grp, pt, &repr[controlOctets], len - controlOctets, NULL)) - { - ERROR_MSG("EC_POINT_oct2point failed: %s", ERR_error_string(ERR_get_error(), NULL)); - EC_POINT_free(pt); - return NULL; - } - return pt; +// Convert a ByteString to an OpenSSL NID +int OSSL::byteString2oid(const ByteString& byteString) +{ + const unsigned char *p = byteString.const_byte_str(); + return OBJ_obj2nid(d2i_ASN1_OBJECT(NULL, &p, byteString.size())); } #endif diff --git a/SoftHSMv2/src/lib/crypto/OSSLUtil.h b/SoftHSMv2/src/lib/crypto/OSSLUtil.h index f353cc6..7b86c50 100644 --- a/SoftHSMv2/src/lib/crypto/OSSLUtil.h +++ b/SoftHSMv2/src/lib/crypto/OSSLUtil.h @@ -39,6 +39,9 @@ #ifdef WITH_ECC #include <openssl/ec.h> #endif +#ifdef WITH_EDDSA +#include <openssl/objects.h> +#endif namespace OSSL { @@ -61,6 +64,14 @@ namespace OSSL // Convert a ByteString to an OpenSSL EC POINT in the given EC GROUP EC_POINT* byteString2pt(const ByteString& byteString, const EC_GROUP* grp); #endif + +#ifdef WITH_EDDSA + // Convert an OpenSSL NID to a ByteString + ByteString oid2ByteString(int nid); + + // Convert a ByteString to an OpenSSL NID + int byteString2oid(const ByteString& byteString); +#endif } #endif // !_SOFTHSM_V2_OSSLUTIL_H diff --git a/SoftHSMv2/src/lib/crypto/test/EDDSATests.cpp b/SoftHSMv2/src/lib/crypto/test/EDDSATests.cpp new file mode 100644 index 0000000..ecb6078 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/test/EDDSATests.cpp @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + EDDSATests.cpp + + Contains test cases to test the EDDSA class + *****************************************************************************/ + +#include <stdlib.h> +#include <utility> +#include <vector> +#include <cppunit/extensions/HelperMacros.h> +#include "EDDSATests.h" +#include "CryptoFactory.h" +#include "RNG.h" +#include "AsymmetricKeyPair.h" +#include "AsymmetricAlgorithm.h" +#ifdef WITH_EDDSA +#include "ECParameters.h" +#include "EDPublicKey.h" +#include "EDPrivateKey.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(EDDSATests); + +void EDDSATests::setUp() +{ + eddsa = NULL; + + eddsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA); + + // Check the EDDSA object + CPPUNIT_ASSERT(eddsa != NULL); +} + +void EDDSATests::tearDown() +{ + if (eddsa != NULL) + { + CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa); + } + + fflush(stdout); +} + +void EDDSATests::testKeyGeneration() +{ + AsymmetricKeyPair* kp; + + // Curves to test + std::vector<ByteString> curves; + // Add x25519 + curves.push_back(ByteString("06032b656e")); + // Add ed25519 + curves.push_back(ByteString("06032b6570")); + + for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++) + { + // Set domain parameters + ECParameters* p = new ECParameters; + p->setEC(*c); + + // Generate key-pair + CPPUNIT_ASSERT(eddsa->generateKeyPair(&kp, p)); + + EDPublicKey* pub = (EDPublicKey*) kp->getPublicKey(); + EDPrivateKey* priv = (EDPrivateKey*) kp->getPrivateKey(); + + CPPUNIT_ASSERT(pub->getEC() == *c); + CPPUNIT_ASSERT(priv->getEC() == *c); + + eddsa->recycleParameters(p); + eddsa->recycleKeyPair(kp); + } +} + +void EDDSATests::testSerialisation() +{ + // Get ed25519 domain parameters + ECParameters* p = new ECParameters; + p->setEC(ByteString("06032b6570")); + + // Serialise the parameters + ByteString serialisedParams = p->serialise(); + + // Deserialise the parameters + AsymmetricParameters* dEC; + + CPPUNIT_ASSERT(eddsa->reconstructParameters(&dEC, serialisedParams)); + + CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type)); + + ECParameters* ddEC = (ECParameters*) dEC; + + CPPUNIT_ASSERT(p->getEC() == ddEC->getEC()); + + // Generate a key-pair + AsymmetricKeyPair* kp; + + CPPUNIT_ASSERT(eddsa->generateKeyPair(&kp, dEC)); + + // Serialise the key-pair + ByteString serialisedKP = kp->serialise(); + + // Deserialise the key-pair + AsymmetricKeyPair* dKP; + + CPPUNIT_ASSERT(eddsa->reconstructKeyPair(&dKP, serialisedKP)); + + // Check the deserialised key-pair + EDPrivateKey* privKey = (EDPrivateKey*) kp->getPrivateKey(); + EDPublicKey* pubKey = (EDPublicKey*) kp->getPublicKey(); + + EDPrivateKey* dPrivKey = (EDPrivateKey*) dKP->getPrivateKey(); + EDPublicKey* dPubKey = (EDPublicKey*) dKP->getPublicKey(); + + CPPUNIT_ASSERT(privKey->getEC() == dPrivKey->getEC()); + CPPUNIT_ASSERT(privKey->getK() == dPrivKey->getK()); + + CPPUNIT_ASSERT(pubKey->getEC() == dPubKey->getEC()); + CPPUNIT_ASSERT(pubKey->getA() == dPubKey->getA()); + + eddsa->recycleParameters(p); + eddsa->recycleParameters(dEC); + eddsa->recycleKeyPair(kp); + eddsa->recycleKeyPair(dKP); +} + +void EDDSATests::testPKCS8() +{ + // Get ed25519 domain parameters + ECParameters* p = new ECParameters; + p->setEC(ByteString("06032b6570")); + + // Generate a key-pair + AsymmetricKeyPair* kp; + + CPPUNIT_ASSERT(eddsa->generateKeyPair(&kp, p)); + CPPUNIT_ASSERT(kp != NULL); + + EDPrivateKey* priv = (EDPrivateKey*) kp->getPrivateKey(); + CPPUNIT_ASSERT(priv != NULL); + + // Encode and decode the private key + ByteString pkcs8 = priv->PKCS8Encode(); + CPPUNIT_ASSERT(pkcs8.size() != 0); + + EDPrivateKey* dPriv = (EDPrivateKey*) eddsa->newPrivateKey(); + CPPUNIT_ASSERT(dPriv != NULL); + + CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8)); + + CPPUNIT_ASSERT(priv->getEC() == dPriv->getEC()); + CPPUNIT_ASSERT(priv->getK() == dPriv->getK()); + + eddsa->recycleParameters(p); + eddsa->recycleKeyPair(kp); + eddsa->recyclePrivateKey(dPriv); +} + +void EDDSATests::testSigningVerifying() +{ + AsymmetricKeyPair* kp; + ECParameters *p; + + // Curves to test + std::vector<ByteString> curves; + // Add ed25519 + curves.push_back(ByteString("06032b6570")); + + for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++) + { + // Get parameters + p = new ECParameters; + CPPUNIT_ASSERT(p != NULL); + p->setEC(*c); + + // Generate key-pair + CPPUNIT_ASSERT(eddsa->generateKeyPair(&kp, p)); + + // Generate some data to sign + ByteString dataToSign; + + RNG* rng = CryptoFactory::i()->getRNG(); + CPPUNIT_ASSERT(rng != NULL); + + CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567)); + + // Sign the data + ByteString sig; + CPPUNIT_ASSERT(eddsa->sign(kp->getPrivateKey(), dataToSign, sig, AsymMech::EDDSA)); + + // And verify it + CPPUNIT_ASSERT(eddsa->verify(kp->getPublicKey(), dataToSign, sig, AsymMech::EDDSA)); + + eddsa->recycleKeyPair(kp); + eddsa->recycleParameters(p); + } +} + +void EDDSATests::testSignVerifyKnownVector() +{ + EDPublicKey* pubKey1 = (EDPublicKey*) eddsa->newPublicKey(); + EDPublicKey* pubKey2 = (EDPublicKey*) eddsa->newPublicKey(); + EDPrivateKey* privKey1 = (EDPrivateKey*) eddsa->newPrivateKey(); + EDPrivateKey* privKey2 = (EDPrivateKey*) eddsa->newPrivateKey(); + + // Reconstruct public and private key #1 + ByteString ec1 = "06032b6570"; // ed25519 + ByteString k1 = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"; + ByteString a1 = "0420d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; + + pubKey1->setEC(ec1); + pubKey1->setA(a1); + privKey1->setEC(ec1); + privKey1->setK(k1); + + // Test with key #1 + ByteString data1; // "" + ByteString goodSignature1 = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"; + ByteString badSignature1 = "e5564300c360ac728086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"; + + // Reconstruct public and private key #2 + ByteString ec2 = "06032b6570"; // ed25519 + ByteString k2 = "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7"; + ByteString a2 = "0420fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"; + + pubKey2->setEC(ec2); + pubKey2->setA(a2); + privKey2->setEC(ec2); + privKey2->setK(k2); + + // Test with key #2 + ByteString data2 = "af82"; + ByteString goodSignature2 = "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a"; + ByteString badSignature2 = "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027bedeea1ec40a"; + + CPPUNIT_ASSERT(eddsa->verify(pubKey1, data1, goodSignature1, AsymMech::EDDSA)); + CPPUNIT_ASSERT(!eddsa->verify(pubKey1, data1, badSignature1, AsymMech::EDDSA)); + CPPUNIT_ASSERT(eddsa->verify(pubKey2, data2, goodSignature2, AsymMech::EDDSA)); + CPPUNIT_ASSERT(!eddsa->verify(pubKey2, data2, badSignature2, AsymMech::EDDSA)); + + eddsa->recyclePublicKey(pubKey1); + eddsa->recyclePublicKey(pubKey2); + eddsa->recyclePrivateKey(privKey1); + eddsa->recyclePrivateKey(privKey2); +} + +void EDDSATests::testDerivation() +{ + AsymmetricKeyPair* kpa; + AsymmetricKeyPair* kpb; + ECParameters* p; + + // Curves to test + std::vector<ByteString> curves; + // Add x25519 + curves.push_back(ByteString("06032b656e")); + + for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++) + { + // Get parameters + p = new ECParameters; + CPPUNIT_ASSERT(p != NULL); + p->setEC(*c); + + // Generate key-pairs + CPPUNIT_ASSERT(eddsa->generateKeyPair(&kpa, p)); + CPPUNIT_ASSERT(eddsa->generateKeyPair(&kpb, p)); + + // Derive secrets + SymmetricKey* sa; + CPPUNIT_ASSERT(eddsa->deriveKey(&sa, kpb->getPublicKey(), kpa->getPrivateKey())); + SymmetricKey* sb; + CPPUNIT_ASSERT(eddsa->deriveKey(&sb, kpa->getPublicKey(), kpb->getPrivateKey())); + + // Must be the same + CPPUNIT_ASSERT(sa->getKeyBits() == sb->getKeyBits()); + + // Clean up + eddsa->recycleSymmetricKey(sa); + eddsa->recycleSymmetricKey(sb); + eddsa->recycleKeyPair(kpa); + eddsa->recycleKeyPair(kpb); + eddsa->recycleParameters(p); + } +} + +void EDDSATests::testDeriveKnownVector() +{ + EDPublicKey* pubKeya = (EDPublicKey*) eddsa->newPublicKey(); + EDPublicKey* pubKeyb = (EDPublicKey*) eddsa->newPublicKey(); + EDPrivateKey* privKeya = (EDPrivateKey*) eddsa->newPrivateKey(); + EDPrivateKey* privKeyb = (EDPrivateKey*) eddsa->newPrivateKey(); + + // Reconstruct public and private key for Alice + ByteString ec = "06032b656e"; // x25519 + ByteString ka = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"; + ByteString aa = "04208520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"; + + pubKeya->setEC(ec); + pubKeya->setA(aa); + privKeya->setEC(ec); + privKeya->setK(ka); + + // Reconstruct public and private key for Bob + ByteString kb = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"; + ByteString ab = "0420de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"; + + pubKeyb->setEC(ec); + pubKeyb->setA(ab); + privKeyb->setEC(ec); + privKeyb->setK(kb); + + // Test + ByteString expected = "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"; + SymmetricKey* sa; + CPPUNIT_ASSERT(eddsa->deriveKey(&sa, pubKeya, privKeyb)); + CPPUNIT_ASSERT(sa->getKeyBits() == expected); + SymmetricKey* sb; + CPPUNIT_ASSERT(eddsa->deriveKey(&sb, pubKeyb, privKeya)); + CPPUNIT_ASSERT(sb->getKeyBits() == expected); + + eddsa->recyclePublicKey(pubKeya); + eddsa->recyclePublicKey(pubKeyb); + eddsa->recyclePrivateKey(privKeya); + eddsa->recyclePrivateKey(privKeyb); + eddsa->recycleSymmetricKey(sa); + eddsa->recycleSymmetricKey(sb); +} +#endif diff --git a/SoftHSMv2/src/lib/crypto/test/EDDSATests.h b/SoftHSMv2/src/lib/crypto/test/EDDSATests.h new file mode 100644 index 0000000..1f9da74 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/test/EDDSATests.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010 SURFnet bv + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/***************************************************************************** + EDDSATests.h + + Contains test cases to test the EDDSA class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_EDDSATESTS_H +#define _SOFTHSM_V2_EDDSATESTS_H + +#include <cppunit/extensions/HelperMacros.h> +#include "AsymmetricAlgorithm.h" + +class EDDSATests : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(EDDSATests); + CPPUNIT_TEST(testKeyGeneration); + CPPUNIT_TEST(testSerialisation); + CPPUNIT_TEST(testPKCS8); + CPPUNIT_TEST(testSigningVerifying); + CPPUNIT_TEST(testSignVerifyKnownVector); + CPPUNIT_TEST(testDerivation); + CPPUNIT_TEST(testDeriveKnownVector); + CPPUNIT_TEST_SUITE_END(); + +public: + void testKeyGeneration(); + void testSerialisation(); + void testPKCS8(); + void testSigningVerifying(); + void testSignVerifyKnownVector(); + void testDerivation(); + void testDeriveKnownVector(); + + void setUp(); + void tearDown(); + +private: + // EDDSA instance + AsymmetricAlgorithm* eddsa; +}; + +#endif // !_SOFTHSM_V2_EDDSATESTS_H + diff --git a/SoftHSMv2/src/lib/crypto/test/Makefile.am b/SoftHSMv2/src/lib/crypto/test/Makefile.am index bf63ae6..4065ef9 100644 --- a/SoftHSMv2/src/lib/crypto/test/Makefile.am +++ b/SoftHSMv2/src/lib/crypto/test/Makefile.am @@ -20,6 +20,7 @@ cryptotest_SOURCES = cryptotest.cpp \ DSATests.cpp \ ECDHTests.cpp \ ECDSATests.cpp \ + EDDSATests.cpp \ GOSTTests.cpp \ HashTests.cpp \ MacTests.cpp \ @@ -36,4 +37,5 @@ cryptotest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install TESTS = cryptotest -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/data_mgr/Makefile.am b/SoftHSMv2/src/lib/data_mgr/Makefile.am index 85aa4d7..0c21bdb 100644 --- a/SoftHSMv2/src/lib/data_mgr/Makefile.am +++ b/SoftHSMv2/src/lib/data_mgr/Makefile.am @@ -14,4 +14,5 @@ libsofthsm_datamgr_la_SOURCES = ByteString.cpp \ SUBDIRS = test -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/data_mgr/test/Makefile.am b/SoftHSMv2/src/lib/data_mgr/test/Makefile.am index e1ebcdd..59039cb 100644 --- a/SoftHSMv2/src/lib/data_mgr/test/Makefile.am +++ b/SoftHSMv2/src/lib/data_mgr/test/Makefile.am @@ -18,10 +18,11 @@ datamgrtest_SOURCES = datamgrtest.cpp \ RFC4880Tests.cpp \ SecureDataMgrTests.cpp -datamgrtest_LDADD = ../../libsofthsm_convarch.la +datamgrtest_LDADD = ../../libsofthsm_convarch.la datamgrtest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install TESTS = datamgrtest -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/handle_mgr/Makefile.am b/SoftHSMv2/src/lib/handle_mgr/Makefile.am index 108f74d..b588009 100644 --- a/SoftHSMv2/src/lib/handle_mgr/Makefile.am +++ b/SoftHSMv2/src/lib/handle_mgr/Makefile.am @@ -14,4 +14,5 @@ libsofthsm_handlemgr_la_SOURCES = HandleManager.cpp \ SUBDIRS = test -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/handle_mgr/test/Makefile.am b/SoftHSMv2/src/lib/handle_mgr/test/Makefile.am index 8d110b0..536a7b5 100644 --- a/SoftHSMv2/src/lib/handle_mgr/test/Makefile.am +++ b/SoftHSMv2/src/lib/handle_mgr/test/Makefile.am @@ -16,11 +16,12 @@ check_PROGRAMS = handlemgrtest handlemgrtest_SOURCES = handlemgrtest.cpp \ HandleManagerTests.cpp -handlemgrtest_LDADD = ../../libsofthsm_convarch.la +handlemgrtest_LDADD = ../../libsofthsm_convarch.la handlemgrtest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install TESTS = handlemgrtest -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/object_store/DBObject.cpp b/SoftHSMv2/src/lib/object_store/DBObject.cpp index a55a32a..bf40bc8 100644 --- a/SoftHSMv2/src/lib/object_store/DBObject.cpp +++ b/SoftHSMv2/src/lib/object_store/DBObject.cpp @@ -453,7 +453,7 @@ static AttributeKind attributeKind(CK_ATTRIBUTE_TYPE type) case CKA_SUBPRIME: return akBinary; case CKA_BASE: return akBinary; case CKA_PRIME_BITS: return akInteger; - case CKA_SUBPRIME_BITS: return akInteger; + case CKA_SUB_PRIME_BITS: return akInteger; case CKA_VALUE_BITS: return akInteger; case CKA_VALUE_LEN: return akInteger; case CKA_EXTRACTABLE: return akBoolean; diff --git a/SoftHSMv2/src/lib/object_store/Makefile.am b/SoftHSMv2/src/lib/object_store/Makefile.am index d3e89d3..6af0d2c 100644 --- a/SoftHSMv2/src/lib/object_store/Makefile.am +++ b/SoftHSMv2/src/lib/object_store/Makefile.am @@ -31,4 +31,5 @@ libsofthsm_objectstore_la_LDFLAGS = @SQLITE3_LIBS@ SUBDIRS = test -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/object_store/test/DBObjectTests.cpp b/SoftHSMv2/src/lib/object_store/test/DBObjectTests.cpp index d856b06..22d252c 100644 --- a/SoftHSMv2/src/lib/object_store/test/DBObjectTests.cpp +++ b/SoftHSMv2/src/lib/object_store/test/DBObjectTests.cpp @@ -202,7 +202,7 @@ void test_a_dbobject_with_an_object::should_store_unsigned_long_attributes() CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS_BITS, attr1)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_AUTH_PIN_FLAGS, attr3)); - CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBPRIME_BITS, attr4)); + CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUB_PRIME_BITS, attr4)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_KEY_TYPE, attr5)); } @@ -215,20 +215,20 @@ void test_a_dbobject_with_an_object::should_store_unsigned_long_attributes() CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_PRIME_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_AUTH_PIN_FLAGS)); - CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBPRIME_BITS)); + CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUB_PRIME_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_KEY_TYPE)); CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID)); CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS).isUnsignedLongAttribute()); - CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS).isUnsignedLongAttribute()); + CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUB_PRIME_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE).isUnsignedLongAttribute()); CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_MODULUS_BITS).getUnsignedLongValue(), (unsigned long)0x12345678); CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue(), (unsigned long)0x87654321); CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_AUTH_PIN_FLAGS).getUnsignedLongValue(), (unsigned long)0x01010101); - CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_SUBPRIME_BITS).getUnsignedLongValue(), (unsigned long)0x10101010); + CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_SUB_PRIME_BITS).getUnsignedLongValue(), (unsigned long)0x10101010); CPPUNIT_ASSERT_EQUAL(testObject.getAttribute(CKA_KEY_TYPE).getUnsignedLongValue(), (unsigned long)0xABCDEF); unsigned long value6 = 0x90909090; diff --git a/SoftHSMv2/src/lib/object_store/test/DBTests.cpp b/SoftHSMv2/src/lib/object_store/test/DBTests.cpp index d787a83..0e68358 100644 --- a/SoftHSMv2/src/lib/object_store/test/DBTests.cpp +++ b/SoftHSMv2/src/lib/object_store/test/DBTests.cpp @@ -348,7 +348,7 @@ void test_a_db_with_a_connection_with_tables::can_update_integer_attribute_bound // insert integer attribute statement = connection->prepare( - "insert into attribute_integer (value,type,object_id) values (%lld,%d,%lld)", + "insert into attribute_integer (value,type,object_id) values (%d,%d,%lld)", 1111, 1235, object_id); diff --git a/SoftHSMv2/src/lib/object_store/test/Makefile.am b/SoftHSMv2/src/lib/object_store/test/Makefile.am index 71de7dd..0ba05c1 100644 --- a/SoftHSMv2/src/lib/object_store/test/Makefile.am +++ b/SoftHSMv2/src/lib/object_store/test/Makefile.am @@ -30,10 +30,11 @@ objstoretest_SOURCES += DBTests.cpp \ DBObjectStoreTests.cpp endif -objstoretest_LDADD = ../../libsofthsm_convarch.la +objstoretest_LDADD = ../../libsofthsm_convarch.la objstoretest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install -pthread TESTS = objstoretest -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/object_store/test/ObjectFileTests.cpp b/SoftHSMv2/src/lib/object_store/test/ObjectFileTests.cpp index 9f0f5bd..f3c3ae5 100644 --- a/SoftHSMv2/src/lib/object_store/test/ObjectFileTests.cpp +++ b/SoftHSMv2/src/lib/object_store/test/ObjectFileTests.cpp @@ -158,7 +158,7 @@ void ObjectFileTests::testULongAttr() CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS_BITS, attr1)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_AUTH_PIN_FLAGS, attr3)); - CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBPRIME_BITS, attr4)); + CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUB_PRIME_BITS, attr4)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_KEY_TYPE, attr5)); } @@ -175,20 +175,20 @@ void ObjectFileTests::testULongAttr() CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_PRIME_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_AUTH_PIN_FLAGS)); - CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBPRIME_BITS)); + CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUB_PRIME_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_KEY_TYPE)); CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID)); CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS).isUnsignedLongAttribute()); - CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS).isUnsignedLongAttribute()); + CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUB_PRIME_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS).getUnsignedLongValue() == 0x12345678); CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == 0x87654321); CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS).getUnsignedLongValue() == 0x01010101); - CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS).getUnsignedLongValue() == 0x10101010); + CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUB_PRIME_BITS).getUnsignedLongValue() == 0x10101010); CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE).getUnsignedLongValue() == 0xABCDEF); unsigned long value6 = 0x90909090; diff --git a/SoftHSMv2/src/lib/object_store/test/SessionObjectTests.cpp b/SoftHSMv2/src/lib/object_store/test/SessionObjectTests.cpp index 6183ec6..20d9052 100644 --- a/SoftHSMv2/src/lib/object_store/test/SessionObjectTests.cpp +++ b/SoftHSMv2/src/lib/object_store/test/SessionObjectTests.cpp @@ -125,7 +125,7 @@ void SessionObjectTests::testULongAttr() CPPUNIT_ASSERT(testObject.setAttribute(CKA_MODULUS_BITS, attr1)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_PRIME_BITS, attr2)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_AUTH_PIN_FLAGS, attr3)); - CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUBPRIME_BITS, attr4)); + CPPUNIT_ASSERT(testObject.setAttribute(CKA_SUB_PRIME_BITS, attr4)); CPPUNIT_ASSERT(testObject.setAttribute(CKA_KEY_TYPE, attr5)); CPPUNIT_ASSERT(testObject.isValid()); @@ -133,20 +133,20 @@ void SessionObjectTests::testULongAttr() CPPUNIT_ASSERT(testObject.attributeExists(CKA_MODULUS_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_PRIME_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_AUTH_PIN_FLAGS)); - CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUBPRIME_BITS)); + CPPUNIT_ASSERT(testObject.attributeExists(CKA_SUB_PRIME_BITS)); CPPUNIT_ASSERT(testObject.attributeExists(CKA_KEY_TYPE)); CPPUNIT_ASSERT(!testObject.attributeExists(CKA_ID)); CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS).isUnsignedLongAttribute()); - CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS).isUnsignedLongAttribute()); + CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUB_PRIME_BITS).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE).isUnsignedLongAttribute()); CPPUNIT_ASSERT(testObject.getAttribute(CKA_MODULUS_BITS).getUnsignedLongValue() == 0x12345678); CPPUNIT_ASSERT(testObject.getAttribute(CKA_PRIME_BITS).getUnsignedLongValue() == 0x87654321); CPPUNIT_ASSERT(testObject.getAttribute(CKA_AUTH_PIN_FLAGS).getUnsignedLongValue() == 0x01010101); - CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUBPRIME_BITS).getUnsignedLongValue() == 0x10101010); + CPPUNIT_ASSERT(testObject.getAttribute(CKA_SUB_PRIME_BITS).getUnsignedLongValue() == 0x10101010); CPPUNIT_ASSERT(testObject.getAttribute(CKA_KEY_TYPE).getUnsignedLongValue() == 0xABCDEF); unsigned long value6 = 0x90909090; diff --git a/SoftHSMv2/src/lib/pkcs11/pkcs11.h b/SoftHSMv2/src/lib/pkcs11/pkcs11.h index 0d78dd7..9d31ce8 100644 --- a/SoftHSMv2/src/lib/pkcs11/pkcs11.h +++ b/SoftHSMv2/src/lib/pkcs11/pkcs11.h @@ -1,265 +1,1750 @@ -/* Copyright (c) OASIS Open 2016. All Rights Reserved./ - * /Distributed under the terms of the OASIS IPR Policy, - * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY - * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. - */ - -/* Latest version of the specification: - * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html - */ - -#ifndef _PKCS11_H_ -#define _PKCS11_H_ 1 - -#ifdef __cplusplus +/* pkcs11.h + Copyright 2006, 2007 g10 Code GmbH + Copyright 2006 Andreas Jellinghaus + Copyright 2017 Red Hat, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. */ + +/* Please submit any changes back to the p11-kit project at + https://github.com/p11-glue/p11-kit/, so that + they can be picked up by other projects from there as well. */ + +/* This file is a modified implementation of the PKCS #11 standard by + OASIS group. It is mostly a drop-in replacement, with the + following change: + + This header file does not require any macro definitions by the user + (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros + for you (if useful, some are missing, let me know if you need + more). + + There is an additional API available that does comply better to the + GNU coding standard. It can be switched on by defining + CRYPTOKI_GNU before including this header file. For this, the + following changes are made to the specification: + + All structure types are changed to a "struct ck_foo" where CK_FOO + is the type name in PKCS #11. + + All non-structure types are changed to ck_foo_t where CK_FOO is the + lowercase version of the type name in PKCS #11. The basic types + (CK_ULONG et al.) are removed without substitute. + + All members of structures are modified in the following way: Type + indication prefixes are removed, and underscore characters are + inserted before words. Then the result is lowercased. + + Note that function names are still in the original case, as they + need for ABI compatibility. + + CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use + <stdbool.h>. + + If CRYPTOKI_COMPAT is defined before including this header file, + then none of the API changes above take place, and the API is the + one defined by the PKCS #11 standard. */ + +#ifndef PKCS11_H +#define PKCS11_H 1 + +#if defined(__cplusplus) extern "C" { #endif -/* Before including this file (pkcs11.h) (or pkcs11t.h by - * itself), 5 platform-specific macros must be defined. These - * macros are described below, and typical definitions for them - * are also given. Be advised that these definitions can depend - * on both the platform and the compiler used (and possibly also - * on whether a Cryptoki library is linked statically or - * dynamically). - * - * In addition to defining these 5 macros, the packing convention - * for Cryptoki structures should be set. The Cryptoki - * convention on packing is that structures should be 1-byte - * aligned. - * - * If you're using Microsoft Developer Studio 5.0 to produce - * Win32 stuff, this might be done by using the following - * preprocessor directive before including pkcs11.h or pkcs11t.h: - * - * #pragma pack(push, cryptoki, 1) - * - * and using the following preprocessor directive after including - * pkcs11.h or pkcs11t.h: - * - * #pragma pack(pop, cryptoki) - * - * If you're using an earlier version of Microsoft Developer - * Studio to produce Win16 stuff, this might be done by using - * the following preprocessor directive before including - * pkcs11.h or pkcs11t.h: - * - * #pragma pack(1) - * - * In a UNIX environment, you're on your own for this. You might - * not need to do (or be able to do!) anything. - * - * - * Now for the macros: - * - * - * 1. CK_PTR: The indirection string for making a pointer to an - * object. It can be used like this: - * - * typedef CK_BYTE CK_PTR CK_BYTE_PTR; - * - * If you're using Microsoft Developer Studio 5.0 to produce - * Win32 stuff, it might be defined by: - * - * #define CK_PTR * - * - * If you're using an earlier version of Microsoft Developer - * Studio to produce Win16 stuff, it might be defined by: - * - * #define CK_PTR far * - * - * In a typical UNIX environment, it might be defined by: - * - * #define CK_PTR * - * - * - * 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes - * an importable Cryptoki library function declaration out of a - * return type and a function name. It should be used in the - * following fashion: - * - * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( - * CK_VOID_PTR pReserved - * ); - * - * If you're using Microsoft Developer Studio 5.0 to declare a - * function in a Win32 Cryptoki .dll, it might be defined by: - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType __declspec(dllimport) name - * - * If you're using an earlier version of Microsoft Developer - * Studio to declare a function in a Win16 Cryptoki .dll, it - * might be defined by: - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType __export _far _pascal name - * - * In a UNIX environment, it might be defined by: - * - * #define CK_DECLARE_FUNCTION(returnType, name) \ - * returnType name - * - * - * 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro - * which makes a Cryptoki API function pointer declaration or - * function pointer type declaration out of a return type and a - * function name. It should be used in the following fashion: - * - * // Define funcPtr to be a pointer to a Cryptoki API function - * // taking arguments args and returning CK_RV. - * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); - * - * or - * - * // Define funcPtrType to be the type of a pointer to a - * // Cryptoki API function taking arguments args and returning - * // CK_RV, and then define funcPtr to be a variable of type - * // funcPtrType. - * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); - * funcPtrType funcPtr; - * - * If you're using Microsoft Developer Studio 5.0 to access - * functions in a Win32 Cryptoki .dll, in might be defined by: - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType __declspec(dllimport) (* name) - * - * If you're using an earlier version of Microsoft Developer - * Studio to access functions in a Win16 Cryptoki .dll, it might - * be defined by: - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType __export _far _pascal (* name) - * - * In a UNIX environment, it might be defined by: - * - * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ - * returnType (* name) - * - * - * 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes - * a function pointer type for an application callback out of - * a return type for the callback and a name for the callback. - * It should be used in the following fashion: - * - * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); - * - * to declare a function pointer, myCallback, to a callback - * which takes arguments args and returns a CK_RV. It can also - * be used like this: - * - * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); - * myCallbackType myCallback; - * - * If you're using Microsoft Developer Studio 5.0 to do Win32 - * Cryptoki development, it might be defined by: - * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType (* name) - * - * If you're using an earlier version of Microsoft Developer - * Studio to do Win16 development, it might be defined by: - * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType _far _pascal (* name) - * - * In a UNIX environment, it might be defined by: - * - * #define CK_CALLBACK_FUNCTION(returnType, name) \ - * returnType (* name) - * - * - * 5. NULL_PTR: This macro is the value of a NULL pointer. - * - * In any ANSI/ISO C environment (and in many others as well), - * this should best be defined by - * - * #ifndef NULL_PTR - * #define NULL_PTR 0 - * #endif - */ - - -/* All the various Cryptoki types and #define'd values are in the - * file pkcs11t.h. - */ -#include "pkcs11t.h" - -#define __PASTE(x,y) x##y - - -/* ============================================================== - * Define the "extern" form of all the entry points. - * ============================================================== - */ - -#define CK_NEED_ARG_LIST 1 -#define CK_PKCS11_FUNCTION_INFO(name) \ - extern CK_DECLARE_FUNCTION(CK_RV, name) - -/* pkcs11f.h has all the information about the Cryptoki - * function prototypes. - */ -#include "pkcs11f.h" - -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO - - -/* ============================================================== - * Define the typedef form of all the entry points. That is, for - * each Cryptoki function C_XXX, define a type CK_C_XXX which is - * a pointer to that kind of function. - * ============================================================== - */ - -#define CK_NEED_ARG_LIST 1 -#define CK_PKCS11_FUNCTION_INFO(name) \ - typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) - -/* pkcs11f.h has all the information about the Cryptoki - * function prototypes. - */ -#include "pkcs11f.h" - -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO - - -/* ============================================================== - * Define structed vector of entry points. A CK_FUNCTION_LIST - * contains a CK_VERSION indicating a library's Cryptoki version - * and then a whole slew of function pointers to the routines in - * the library. This type was declared, but not defined, in - * pkcs11t.h. - * ============================================================== - */ - -#define CK_PKCS11_FUNCTION_INFO(name) \ - __PASTE(CK_,name) name; - -struct CK_FUNCTION_LIST { - - CK_VERSION version; /* Cryptoki version */ - -/* Pile all the function pointers into the CK_FUNCTION_LIST. */ -/* pkcs11f.h has all the information about the Cryptoki - * function prototypes. - */ -#include "pkcs11f.h" +/* The version of cryptoki we implement. The revision is changed with + each modification of this file. */ +#define CRYPTOKI_VERSION_MAJOR 2 +#define CRYPTOKI_VERSION_MINOR 40 +#define P11_KIT_CRYPTOKI_VERSION_REVISION 0 + + +/* Compatibility interface is default, unless CRYPTOKI_GNU is + given. */ +#ifndef CRYPTOKI_GNU +#ifndef CRYPTOKI_COMPAT +#define CRYPTOKI_COMPAT 1 +#endif +#endif + +/* System dependencies. */ + +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) + +/* There is a matching pop below. */ +#pragma pack(push, cryptoki, 1) + +#ifdef CRYPTOKI_EXPORTS +#define CK_SPEC __declspec(dllexport) +#else +#define CK_SPEC __declspec(dllimport) +#endif + +#else + +#define CK_SPEC + +#endif + + +#ifdef CRYPTOKI_COMPAT + /* If we are in compatibility mode, switch all exposed names to the + PKCS #11 variant. There are corresponding #undefs below. */ + +#define ck_flags_t CK_FLAGS +#define ck_version _CK_VERSION + +#define ck_info _CK_INFO +#define cryptoki_version cryptokiVersion +#define manufacturer_id manufacturerID +#define library_description libraryDescription +#define library_version libraryVersion + +#define ck_notification_t CK_NOTIFICATION +#define ck_slot_id_t CK_SLOT_ID + +#define ck_slot_info _CK_SLOT_INFO +#define slot_description slotDescription +#define hardware_version hardwareVersion +#define firmware_version firmwareVersion + +#define ck_token_info _CK_TOKEN_INFO +#define serial_number serialNumber +#define max_session_count ulMaxSessionCount +#define session_count ulSessionCount +#define max_rw_session_count ulMaxRwSessionCount +#define rw_session_count ulRwSessionCount +#define max_pin_len ulMaxPinLen +#define min_pin_len ulMinPinLen +#define total_public_memory ulTotalPublicMemory +#define free_public_memory ulFreePublicMemory +#define total_private_memory ulTotalPrivateMemory +#define free_private_memory ulFreePrivateMemory +#define utc_time utcTime + +#define ck_session_handle_t CK_SESSION_HANDLE +#define ck_user_type_t CK_USER_TYPE +#define ck_state_t CK_STATE + +#define ck_session_info _CK_SESSION_INFO +#define slot_id slotID +#define device_error ulDeviceError + +#define ck_object_handle_t CK_OBJECT_HANDLE +#define ck_object_class_t CK_OBJECT_CLASS +#define ck_hw_feature_type_t CK_HW_FEATURE_TYPE +#define ck_key_type_t CK_KEY_TYPE +#define ck_certificate_type_t CK_CERTIFICATE_TYPE +#define ck_attribute_type_t CK_ATTRIBUTE_TYPE + +#define ck_attribute _CK_ATTRIBUTE +#define value pValue +#define value_len ulValueLen + +#define count ulCount + +#define ck_date _CK_DATE + +#define ck_mechanism_type_t CK_MECHANISM_TYPE + +#define ck_mechanism _CK_MECHANISM +#define parameter pParameter +#define parameter_len ulParameterLen + +#define params pParams + +#define ck_mechanism_info _CK_MECHANISM_INFO +#define min_key_size ulMinKeySize +#define max_key_size ulMaxKeySize + +#define ck_param_type CK_PARAM_TYPE +#define ck_otp_param CK_OTP_PARAM +#define ck_otp_params CK_OTP_PARAMS +#define ck_otp_signature_info CK_OTP_SIGNATURE_INFO + +#define ck_rv_t CK_RV +#define ck_notify_t CK_NOTIFY + +#define ck_function_list _CK_FUNCTION_LIST + +#define ck_createmutex_t CK_CREATEMUTEX +#define ck_destroymutex_t CK_DESTROYMUTEX +#define ck_lockmutex_t CK_LOCKMUTEX +#define ck_unlockmutex_t CK_UNLOCKMUTEX + +#define ck_c_initialize_args _CK_C_INITIALIZE_ARGS +#define create_mutex CreateMutex +#define destroy_mutex DestroyMutex +#define lock_mutex LockMutex +#define unlock_mutex UnlockMutex +#define reserved pReserved + +#define ck_rsa_pkcs_mgf_type_t CK_RSA_PKCS_MGF_TYPE +#define ck_rsa_pkcs_oaep_source_type_t CK_RSA_PKCS_OAEP_SOURCE_TYPE +#define hash_alg hashAlg +#define s_len sLen +#define source_data pSourceData +#define source_data_len ulSourceDataLen + +#define counter_bits ulCounterBits +#define iv_ptr pIv +#define iv_len ulIvLen +#define iv_bits ulIvBits +#define aad_ptr pAAD +#define aad_len ulAADLen +#define tag_bits ulTagBits +#define shared_data_len ulSharedDataLen +#define shared_data pSharedData +#define public_data_len ulPublicDataLen +#define public_data pPublicData +#define string_data pData +#define string_data_len ulLen +#define data_params pData +#endif /* CRYPTOKI_COMPAT */ + + + +typedef unsigned long ck_flags_t; + +struct ck_version +{ + unsigned char major; + unsigned char minor; }; -#undef CK_PKCS11_FUNCTION_INFO +struct ck_info +{ + struct ck_version cryptoki_version; + unsigned char manufacturer_id[32]; + ck_flags_t flags; + unsigned char library_description[32]; + struct ck_version library_version; +}; -#undef __PASTE -#ifdef __cplusplus -} +typedef unsigned long ck_notification_t; + +#define CKN_SURRENDER (0UL) + + +typedef unsigned long ck_slot_id_t; + + +struct ck_slot_info +{ + unsigned char slot_description[64]; + unsigned char manufacturer_id[32]; + ck_flags_t flags; + struct ck_version hardware_version; + struct ck_version firmware_version; +}; + + +#define CKF_TOKEN_PRESENT (1UL << 0) +#define CKF_REMOVABLE_DEVICE (1UL << 1) +#define CKF_HW_SLOT (1UL << 2) +#define CKF_ARRAY_ATTRIBUTE (1UL << 30) + + +struct ck_token_info +{ + unsigned char label[32]; + unsigned char manufacturer_id[32]; + unsigned char model[16]; + unsigned char serial_number[16]; + ck_flags_t flags; + unsigned long max_session_count; + unsigned long session_count; + unsigned long max_rw_session_count; + unsigned long rw_session_count; + unsigned long max_pin_len; + unsigned long min_pin_len; + unsigned long total_public_memory; + unsigned long free_public_memory; + unsigned long total_private_memory; + unsigned long free_private_memory; + struct ck_version hardware_version; + struct ck_version firmware_version; + unsigned char utc_time[16]; +}; + + +#define CKF_RNG (1UL << 0) +#define CKF_WRITE_PROTECTED (1UL << 1) +#define CKF_LOGIN_REQUIRED (1UL << 2) +#define CKF_USER_PIN_INITIALIZED (1UL << 3) +#define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) +#define CKF_CLOCK_ON_TOKEN (1UL << 6) +#define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) +#define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) +#define CKF_TOKEN_INITIALIZED (1UL << 10) +#define CKF_SECONDARY_AUTHENTICATION (1UL << 11) +#define CKF_USER_PIN_COUNT_LOW (1UL << 16) +#define CKF_USER_PIN_FINAL_TRY (1UL << 17) +#define CKF_USER_PIN_LOCKED (1UL << 18) +#define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) +#define CKF_SO_PIN_COUNT_LOW (1UL << 20) +#define CKF_SO_PIN_FINAL_TRY (1UL << 21) +#define CKF_SO_PIN_LOCKED (1UL << 22) +#define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) + +#define CK_UNAVAILABLE_INFORMATION ((unsigned long)-1L) +#define CK_EFFECTIVELY_INFINITE (0UL) + + +typedef unsigned long ck_session_handle_t; + +#define CK_INVALID_HANDLE (0UL) + + +typedef unsigned long ck_user_type_t; + +#define CKU_SO (0UL) +#define CKU_USER (1UL) +#define CKU_CONTEXT_SPECIFIC (2UL) + + +typedef unsigned long ck_state_t; + +#define CKS_RO_PUBLIC_SESSION (0UL) +#define CKS_RO_USER_FUNCTIONS (1UL) +#define CKS_RW_PUBLIC_SESSION (2UL) +#define CKS_RW_USER_FUNCTIONS (3UL) +#define CKS_RW_SO_FUNCTIONS (4UL) + + +struct ck_session_info +{ + ck_slot_id_t slot_id; + ck_state_t state; + ck_flags_t flags; + unsigned long device_error; +}; + +#define CKF_RW_SESSION (1UL << 1) +#define CKF_SERIAL_SESSION (1UL << 2) + + +typedef unsigned long ck_object_handle_t; + + +typedef unsigned long ck_object_class_t; + +#define CKO_DATA (0UL) +#define CKO_CERTIFICATE (1UL) +#define CKO_PUBLIC_KEY (2UL) +#define CKO_PRIVATE_KEY (3UL) +#define CKO_SECRET_KEY (4UL) +#define CKO_HW_FEATURE (5UL) +#define CKO_DOMAIN_PARAMETERS (6UL) +#define CKO_MECHANISM (7UL) +#define CKO_OTP_KEY (8UL) +#define CKO_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + + +typedef unsigned long ck_hw_feature_type_t; + +#define CKH_MONOTONIC_COUNTER (1UL) +#define CKH_CLOCK (2UL) +#define CKH_USER_INTERFACE (3UL) +#define CKH_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + + +typedef unsigned long ck_key_type_t; + +#define CKK_RSA (0UL) +#define CKK_DSA (1UL) +#define CKK_DH (2UL) +#define CKK_ECDSA (3UL) +#define CKK_EC (3UL) +#define CKK_X9_42_DH (4UL) +#define CKK_KEA (5UL) +#define CKK_GENERIC_SECRET (0x10UL) +#define CKK_RC2 (0x11UL) +#define CKK_RC4 (0x12UL) +#define CKK_DES (0x13UL) +#define CKK_DES2 (0x14UL) +#define CKK_DES3 (0x15UL) +#define CKK_CAST (0x16UL) +#define CKK_CAST3 (0x17UL) +#define CKK_CAST128 (0x18UL) +#define CKK_RC5 (0x19UL) +#define CKK_IDEA (0x1aUL) +#define CKK_SKIPJACK (0x1bUL) +#define CKK_BATON (0x1cUL) +#define CKK_JUNIPER (0x1dUL) +#define CKK_CDMF (0x1eUL) +#define CKK_AES (0x1fUL) +#define CKK_BLOWFISH (0x20UL) +#define CKK_TWOFISH (0x21UL) +#define CKK_SECURID (0x22UL) +#define CKK_HOTP (0x23UL) +#define CKK_ACTI (0x24UL) +#define CKK_CAMELLIA (0x25UL) +#define CKK_ARIA (0x26UL) +#define CKK_MD5_HMAC (0x27UL) +#define CKK_SHA_1_HMAC (0x28UL) +#define CKK_RIPEMD128_HMAC (0x29UL) +#define CKK_RIPEMD160_HMAC (0x2aUL) +#define CKK_SHA256_HMAC (0x2bUL) +#define CKK_SHA384_HMAC (0x2cUL) +#define CKK_SHA512_HMAC (0x2dUL) +#define CKK_SHA224_HMAC (0x2eUL) +#define CKK_SEED (0x2fUL) +#define CKK_GOSTR3410 (0x30UL) +#define CKK_GOSTR3411 (0x31UL) +#define CKK_GOST28147 (0x32UL) +#define CKK_EC_EDWARDS (0x40UL) +#define CKK_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + + +typedef unsigned long ck_certificate_type_t; + +#define CKC_X_509 (0UL) +#define CKC_X_509_ATTR_CERT (1UL) +#define CKC_WTLS (2UL) +#define CKC_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + +#define CKC_OPENPGP (CKC_VENDOR_DEFINED|0x504750UL) + +typedef unsigned long ck_attribute_type_t; + +#define CKA_CLASS (0UL) +#define CKA_TOKEN (1UL) +#define CKA_PRIVATE (2UL) +#define CKA_LABEL (3UL) +#define CKA_APPLICATION (0x10UL) +#define CKA_VALUE (0x11UL) +#define CKA_OBJECT_ID (0x12UL) +#define CKA_CERTIFICATE_TYPE (0x80UL) +#define CKA_ISSUER (0x81UL) +#define CKA_SERIAL_NUMBER (0x82UL) +#define CKA_AC_ISSUER (0x83UL) +#define CKA_OWNER (0x84UL) +#define CKA_ATTR_TYPES (0x85UL) +#define CKA_TRUSTED (0x86UL) +#define CKA_CERTIFICATE_CATEGORY (0x87UL) +#define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) +#define CKA_URL (0x89UL) +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) +#define CKA_NAME_HASH_ALGORITHM (0x8cUL) +#define CKA_CHECK_VALUE (0x90UL) +#define CKA_KEY_TYPE (0x100UL) +#define CKA_SUBJECT (0x101UL) +#define CKA_ID (0x102UL) +#define CKA_SENSITIVE (0x103UL) +#define CKA_ENCRYPT (0x104UL) +#define CKA_DECRYPT (0x105UL) +#define CKA_WRAP (0x106UL) +#define CKA_UNWRAP (0x107UL) +#define CKA_SIGN (0x108UL) +#define CKA_SIGN_RECOVER (0x109UL) +#define CKA_VERIFY (0x10aUL) +#define CKA_VERIFY_RECOVER (0x10bUL) +#define CKA_DERIVE (0x10cUL) +#define CKA_START_DATE (0x110UL) +#define CKA_END_DATE (0x111UL) +#define CKA_MODULUS (0x120UL) +#define CKA_MODULUS_BITS (0x121UL) +#define CKA_PUBLIC_EXPONENT (0x122UL) +#define CKA_PRIVATE_EXPONENT (0x123UL) +#define CKA_PRIME_1 (0x124UL) +#define CKA_PRIME_2 (0x125UL) +#define CKA_EXPONENT_1 (0x126UL) +#define CKA_EXPONENT_2 (0x127UL) +#define CKA_COEFFICIENT (0x128UL) +#define CKA_PUBLIC_KEY_INFO (0x129UL) +#define CKA_PRIME (0x130UL) +#define CKA_SUBPRIME (0x131UL) +#define CKA_BASE (0x132UL) +#define CKA_PRIME_BITS (0x133UL) +#define CKA_SUB_PRIME_BITS (0x134UL) +#define CKA_VALUE_BITS (0x160UL) +#define CKA_VALUE_LEN (0x161UL) +#define CKA_EXTRACTABLE (0x162UL) +#define CKA_LOCAL (0x163UL) +#define CKA_NEVER_EXTRACTABLE (0x164UL) +#define CKA_ALWAYS_SENSITIVE (0x165UL) +#define CKA_KEY_GEN_MECHANISM (0x166UL) +#define CKA_MODIFIABLE (0x170UL) +#define CKA_COPYABLE (0x171UL) +#define CKA_DESTROYABLE (0x172UL) +#define CKA_ECDSA_PARAMS (0x180UL) +#define CKA_EC_PARAMS (0x180UL) +#define CKA_EC_POINT (0x181UL) +#define CKA_SECONDARY_AUTH (0x200UL) +#define CKA_AUTH_PIN_FLAGS (0x201UL) +#define CKA_ALWAYS_AUTHENTICATE (0x202UL) +#define CKA_WRAP_WITH_TRUSTED (0x210UL) +#define CKA_OTP_FORMAT (0x220UL) +#define CKA_OTP_LENGTH (0x221UL) +#define CKA_OTP_TIME_INTERVAL (0x222UL) +#define CKA_OTP_USER_FRIENDLY_MODE (0x223UL) +#define CKA_OTP_CHALLENGE_REQUIREMENT (0x224UL) +#define CKA_OTP_TIME_REQUIREMENT (0x225UL) +#define CKA_OTP_COUNTER_REQUIREMENT (0x226UL) +#define CKA_OTP_PIN_REQUIREMENT (0x227UL) +#define CKA_OTP_USER_IDENTIFIER (0x22AUL) +#define CKA_OTP_SERVICE_IDENTIFIER (0x22BUL) +#define CKA_OTP_SERVICE_LOGO (0x22CUL) +#define CKA_OTP_SERVICE_LOGO_TYPE (0x22DUL) +#define CKA_OTP_COUNTER (0x22EUL) +#define CKA_OTP_TIME (0x22FUL) +#define CKA_GOSTR3410_PARAMS (0x250UL) +#define CKA_GOSTR3411_PARAMS (0x251UL) +#define CKA_GOST28147_PARAMS (0x252UL) +#define CKA_HW_FEATURE_TYPE (0x300UL) +#define CKA_RESET_ON_INIT (0x301UL) +#define CKA_HAS_RESET (0x302UL) +#define CKA_PIXEL_X (0x400UL) +#define CKA_PIXEL_Y (0x401UL) +#define CKA_RESOLUTION (0x402UL) +#define CKA_CHAR_ROWS (0x403UL) +#define CKA_CHAR_COLUMNS (0x404UL) +#define CKA_COLOR (0x405UL) +#define CKA_BITS_PER_PIXEL (0x406UL) +#define CKA_CHAR_SETS (0x480UL) +#define CKA_ENCODING_METHODS (0x481UL) +#define CKA_MIME_TYPES (0x482UL) +#define CKA_MECHANISM_TYPE (0x500UL) +#define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) +#define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) +#define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) +#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x213UL) +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) +#define CKA_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + + +struct ck_attribute +{ + ck_attribute_type_t type; + void *value; + unsigned long value_len; +}; + + +struct ck_date +{ + unsigned char year[4]; + unsigned char month[2]; + unsigned char day[2]; +}; + + +typedef unsigned long ck_mechanism_type_t; + +#define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) +#define CKM_RSA_PKCS (1UL) +#define CKM_RSA_9796 (2UL) +#define CKM_RSA_X_509 (3UL) +#define CKM_MD2_RSA_PKCS (4UL) +#define CKM_MD5_RSA_PKCS (5UL) +#define CKM_SHA1_RSA_PKCS (6UL) +#define CKM_RIPEMD128_RSA_PKCS (7UL) +#define CKM_RIPEMD160_RSA_PKCS (8UL) +#define CKM_RSA_PKCS_OAEP (9UL) +#define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) +#define CKM_RSA_X9_31 (0xbUL) +#define CKM_SHA1_RSA_X9_31 (0xcUL) +#define CKM_RSA_PKCS_PSS (0xdUL) +#define CKM_SHA1_RSA_PKCS_PSS (0xeUL) +#define CKM_DSA_KEY_PAIR_GEN (0x10UL) +#define CKM_DSA (0x11UL) +#define CKM_DSA_SHA1 (0x12UL) +#define CKM_DSA_SHA224 (0x13UL) +#define CKM_DSA_SHA256 (0x14UL) +#define CKM_DSA_SHA384 (0x15UL) +#define CKM_DSA_SHA512 (0x16UL) +#define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) +#define CKM_DH_PKCS_DERIVE (0x21UL) +#define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) +#define CKM_X9_42_DH_DERIVE (0x31UL) +#define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) +#define CKM_X9_42_MQV_DERIVE (0x33UL) +#define CKM_SHA256_RSA_PKCS (0x40UL) +#define CKM_SHA384_RSA_PKCS (0x41UL) +#define CKM_SHA512_RSA_PKCS (0x42UL) +#define CKM_SHA256_RSA_PKCS_PSS (0x43UL) +#define CKM_SHA384_RSA_PKCS_PSS (0x44UL) +#define CKM_SHA512_RSA_PKCS_PSS (0x45UL) +#define CKM_SHA512_224 (0x48UL) +#define CKM_SHA512_224_HMAC (0x49UL) +#define CKM_SHA512_224_HMAC_GENERAL (0x4aUL) +#define CKM_SHA512_224_KEY_DERIVATION (0x4bUL) +#define CKM_SHA512_256 (0x4cUL) +#define CKM_SHA512_256_HMAC (0x4dUL) +#define CKM_SHA512_256_HMAC_GENERAL (0x4eUL) +#define CKM_SHA512_256_KEY_DERIVATION (0x4fUL) +#define CKM_SHA512_T (0x50UL) +#define CKM_SHA512_T_HMAC (0x51UL) +#define CKM_SHA512_T_HMAC_GENERAL (0x52UL) +#define CKM_SHA512_T_KEY_DERIVATION (0x53UL) +#define CKM_RC2_KEY_GEN (0x100UL) +#define CKM_RC2_ECB (0x101UL) +#define CKM_RC2_CBC (0x102UL) +#define CKM_RC2_MAC (0x103UL) +#define CKM_RC2_MAC_GENERAL (0x104UL) +#define CKM_RC2_CBC_PAD (0x105UL) +#define CKM_RC4_KEY_GEN (0x110UL) +#define CKM_RC4 (0x111UL) +#define CKM_DES_KEY_GEN (0x120UL) +#define CKM_DES_ECB (0x121UL) +#define CKM_DES_CBC (0x122UL) +#define CKM_DES_MAC (0x123UL) +#define CKM_DES_MAC_GENERAL (0x124UL) +#define CKM_DES_CBC_PAD (0x125UL) +#define CKM_DES2_KEY_GEN (0x130UL) +#define CKM_DES3_KEY_GEN (0x131UL) +#define CKM_DES3_ECB (0x132UL) +#define CKM_DES3_CBC (0x133UL) +#define CKM_DES3_MAC (0x134UL) +#define CKM_DES3_MAC_GENERAL (0x135UL) +#define CKM_DES3_CBC_PAD (0x136UL) +#define CKM_DES3_CMAC_GENERAL (0x137UL) +#define CKM_DES3_CMAC (0x138UL) +#define CKM_CDMF_KEY_GEN (0x140UL) +#define CKM_CDMF_ECB (0x141UL) +#define CKM_CDMF_CBC (0x142UL) +#define CKM_CDMF_MAC (0x143UL) +#define CKM_CDMF_MAC_GENERAL (0x144UL) +#define CKM_CDMF_CBC_PAD (0x145UL) +#define CKM_DES_OFB64 (0x150UL) +#define CKM_DES_OFB8 (0x151UL) +#define CKM_DES_CFB64 (0x152UL) +#define CKM_DES_CFB8 (0x153UL) +#define CKM_MD2 (0x200UL) +#define CKM_MD2_HMAC (0x201UL) +#define CKM_MD2_HMAC_GENERAL (0x202UL) +#define CKM_MD5 (0x210UL) +#define CKM_MD5_HMAC (0x211UL) +#define CKM_MD5_HMAC_GENERAL (0x212UL) +#define CKM_SHA_1 (0x220UL) +#define CKM_SHA_1_HMAC (0x221UL) +#define CKM_SHA_1_HMAC_GENERAL (0x222UL) +#define CKM_RIPEMD128 (0x230UL) +#define CKM_RIPEMD128_HMAC (0x231UL) +#define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) +#define CKM_RIPEMD160 (0x240UL) +#define CKM_RIPEMD160_HMAC (0x241UL) +#define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) +#define CKM_SHA256 (0x250UL) +#define CKM_SHA256_HMAC (0x251UL) +#define CKM_SHA256_HMAC_GENERAL (0x252UL) +#define CKM_SHA384 (0x260UL) +#define CKM_SHA384_HMAC (0x261UL) +#define CKM_SHA384_HMAC_GENERAL (0x262UL) +#define CKM_SHA512 (0x270UL) +#define CKM_SHA512_HMAC (0x271UL) +#define CKM_SHA512_HMAC_GENERAL (0x272UL) +#define CKM_SECURID_KEY_GEN (0x280UL) +#define CKM_SECURID (0x282UL) +#define CKM_HOTP_KEY_GEN (0x290UL) +#define CKM_HOTP (0x291UL) +#define CKM_ACTI (0x2a0UL) +#define CKM_ACTI_KEY_GEN (0x2a1UL) +#define CKM_CAST_KEY_GEN (0x300UL) +#define CKM_CAST_ECB (0x301UL) +#define CKM_CAST_CBC (0x302UL) +#define CKM_CAST_MAC (0x303UL) +#define CKM_CAST_MAC_GENERAL (0x304UL) +#define CKM_CAST_CBC_PAD (0x305UL) +#define CKM_CAST3_KEY_GEN (0x310UL) +#define CKM_CAST3_ECB (0x311UL) +#define CKM_CAST3_CBC (0x312UL) +#define CKM_CAST3_MAC (0x313UL) +#define CKM_CAST3_MAC_GENERAL (0x314UL) +#define CKM_CAST3_CBC_PAD (0x315UL) +#define CKM_CAST5_KEY_GEN (0x320UL) +#define CKM_CAST128_KEY_GEN (0x320UL) +#define CKM_CAST5_ECB (0x321UL) +#define CKM_CAST128_ECB (0x321UL) +#define CKM_CAST5_CBC (0x322UL) +#define CKM_CAST128_CBC (0x322UL) +#define CKM_CAST5_MAC (0x323UL) +#define CKM_CAST128_MAC (0x323UL) +#define CKM_CAST5_MAC_GENERAL (0x324UL) +#define CKM_CAST128_MAC_GENERAL (0x324UL) +#define CKM_CAST5_CBC_PAD (0x325UL) +#define CKM_CAST128_CBC_PAD (0x325UL) +#define CKM_RC5_KEY_GEN (0x330UL) +#define CKM_RC5_ECB (0x331UL) +#define CKM_RC5_CBC (0x332UL) +#define CKM_RC5_MAC (0x333UL) +#define CKM_RC5_MAC_GENERAL (0x334UL) +#define CKM_RC5_CBC_PAD (0x335UL) +#define CKM_IDEA_KEY_GEN (0x340UL) +#define CKM_IDEA_ECB (0x341UL) +#define CKM_IDEA_CBC (0x342UL) +#define CKM_IDEA_MAC (0x343UL) +#define CKM_IDEA_MAC_GENERAL (0x344UL) +#define CKM_IDEA_CBC_PAD (0x345UL) +#define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) +#define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) +#define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) +#define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) +#define CKM_XOR_BASE_AND_DATA (0x364UL) +#define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) +#define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) +#define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) +#define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) +#define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) +#define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) +#define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) +#define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) +#define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) +#define CKM_TLS_PRF (0x378UL) +#define CKM_SSL3_MD5_MAC (0x380UL) +#define CKM_SSL3_SHA1_MAC (0x381UL) +#define CKM_MD5_KEY_DERIVATION (0x390UL) +#define CKM_MD2_KEY_DERIVATION (0x391UL) +#define CKM_SHA1_KEY_DERIVATION (0x392UL) +#define CKM_SHA256_KEY_DERIVATION (0x393UL) +#define CKM_SHA384_KEY_DERIVATION (0x394UL) +#define CKM_SHA512_KEY_DERIVATION (0x395UL) +#define CKM_PBE_MD2_DES_CBC (0x3a0UL) +#define CKM_PBE_MD5_DES_CBC (0x3a1UL) +#define CKM_PBE_MD5_CAST_CBC (0x3a2UL) +#define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) +#define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) +#define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) +#define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) +#define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) +#define CKM_PBE_SHA1_RC4_128 (0x3a6UL) +#define CKM_PBE_SHA1_RC4_40 (0x3a7UL) +#define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) +#define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) +#define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) +#define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) +#define CKM_PKCS5_PBKD2 (0x3b0UL) +#define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) +#define CKM_WTLS_PRE_MASTER_KEY_GEN (0x3d0UL) +#define CKM_WTLS_MASTER_KEY_DERIVE (0x3d1UL) +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC (0x3d2UL) +#define CKM_WTLS_PRF (0x3d3UL) +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE (0x3d4UL) +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE (0x3d5UL) +#define CKM_TLS10_MAC_SERVER (0x3d6UL) +#define CKM_TLS10_MAC_CLIENT (0x3d7UL) +#define CKM_TLS12_MAC (0x3d8UL) +#define CKM_TLS12_KDF (0x3d9UL) +#define CKM_TLS12_MASTER_KEY_DERIVE (0x3e0UL) +#define CKM_TLS12_KEY_AND_MAC_DERIVE (0x3e1UL) +#define CKM_TLS12_MASTER_KEY_DERIVE_DH (0x3e2UL) +#define CKM_TLS12_KEY_SAFE_DERIVE (0x3e3UL) +#define CKM_TLS_MAC (0x3e4UL) +#define CKM_TLS_KDF (0x3e5UL) +#define CKM_KEY_WRAP_LYNKS (0x400UL) +#define CKM_KEY_WRAP_SET_OAEP (0x401UL) +#define CKM_CMS_SIG (0x500UL) +#define CKM_KIP_DERIVE (0x510UL) +#define CKM_KIP_WRAP (0x511UL) +#define CKM_KIP_MAC (0x512UL) +#define CKM_CAMELLIA_KEY_GEN (0x550UL) +#define CKM_CAMELLIA_CTR (0x558UL) +#define CKM_ARIA_KEY_GEN (0x560UL) +#define CKM_ARIA_ECB (0x561UL) +#define CKM_ARIA_CBC (0x562UL) +#define CKM_ARIA_MAC (0x563UL) +#define CKM_ARIA_MAC_GENERAL (0x564UL) +#define CKM_ARIA_CBC_PAD (0x565UL) +#define CKM_ARIA_ECB_ENCRYPT_DATA (0x566UL) +#define CKM_ARIA_CBC_ENCRYPT_DATA (0x567UL) +#define CKM_SEED_KEY_GEN (0x650UL) +#define CKM_SEED_ECB (0x651UL) +#define CKM_SEED_CBC (0x652UL) +#define CKM_SEED_MAC (0x653UL) +#define CKM_SEED_MAC_GENERAL (0x654UL) +#define CKM_SEED_CBC_PAD (0x655UL) +#define CKM_SEED_ECB_ENCRYPT_DATA (0x656UL) +#define CKM_SEED_CBC_ENCRYPT_DATA (0x657UL) +#define CKM_SKIPJACK_KEY_GEN (0x1000UL) +#define CKM_SKIPJACK_ECB64 (0x1001UL) +#define CKM_SKIPJACK_CBC64 (0x1002UL) +#define CKM_SKIPJACK_OFB64 (0x1003UL) +#define CKM_SKIPJACK_CFB64 (0x1004UL) +#define CKM_SKIPJACK_CFB32 (0x1005UL) +#define CKM_SKIPJACK_CFB16 (0x1006UL) +#define CKM_SKIPJACK_CFB8 (0x1007UL) +#define CKM_SKIPJACK_WRAP (0x1008UL) +#define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) +#define CKM_SKIPJACK_RELAYX (0x100aUL) +#define CKM_KEA_KEY_PAIR_GEN (0x1010UL) +#define CKM_KEA_KEY_DERIVE (0x1011UL) +#define CKM_FORTEZZA_TIMESTAMP (0x1020UL) +#define CKM_BATON_KEY_GEN (0x1030UL) +#define CKM_BATON_ECB128 (0x1031UL) +#define CKM_BATON_ECB96 (0x1032UL) +#define CKM_BATON_CBC128 (0x1033UL) +#define CKM_BATON_COUNTER (0x1034UL) +#define CKM_BATON_SHUFFLE (0x1035UL) +#define CKM_BATON_WRAP (0x1036UL) +#define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) +#define CKM_EC_KEY_PAIR_GEN (0x1040UL) +#define CKM_ECDSA (0x1041UL) +#define CKM_ECDSA_SHA1 (0x1042UL) +#define CKM_ECDSA_SHA224 (0x1043UL) +#define CKM_ECDSA_SHA256 (0x1044UL) +#define CKM_ECDSA_SHA384 (0x1045UL) +#define CKM_ECDSA_SHA512 (0x1046UL) +#define CKM_ECDH1_DERIVE (0x1050UL) +#define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) +#define CKM_ECMQV_DERIVE (0x1052UL) +#define CKM_ECDH_AES_KEY_WRAP (0x1053UL) +#define CKM_RSA_AES_KEY_WRAP (0x1054UL) +#define CKM_JUNIPER_KEY_GEN (0x1060UL) +#define CKM_JUNIPER_ECB128 (0x1061UL) +#define CKM_JUNIPER_CBC128 (0x1062UL) +#define CKM_JUNIPER_COUNTER (0x1063UL) +#define CKM_JUNIPER_SHUFFLE (0x1064UL) +#define CKM_JUNIPER_WRAP (0x1065UL) +#define CKM_FASTHASH (0x1070UL) +#define CKM_AES_KEY_GEN (0x1080UL) +#define CKM_AES_ECB (0x1081UL) +#define CKM_AES_CBC (0x1082UL) +#define CKM_AES_MAC (0x1083UL) +#define CKM_AES_MAC_GENERAL (0x1084UL) +#define CKM_AES_CBC_PAD (0x1085UL) +#define CKM_AES_CTR (0x1086UL) +#define CKM_AES_GCM (0x1087UL) +#define CKM_AES_CCM (0x1088UL) +#define CKM_AES_CTS (0x1089UL) +#define CKM_AES_CMAC (0x108aUL) +#define CKM_AES_CMAC_GENERAL (0x108bUL) +#define CKM_AES_XCBC_MAC (0x108cUL) +#define CKM_AES_XCBC_MAC_96 (0x108dUL) +#define CKM_AES_GMAC (0x108eUL) +#define CKM_BLOWFISH_KEY_GEN (0x1090UL) +#define CKM_BLOWFISH_CBC (0x1091UL) +#define CKM_TWOFISH_KEY_GEN (0x1092UL) +#define CKM_TWOFISH_CBC (0x1093UL) +#define CKM_BLOWFISH_CBC_PAD (0x1094UL) +#define CKM_TWOFISH_CBC_PAD (0x1095UL) +#define CKM_DES_ECB_ENCRYPT_DATA (0x1100UL) +#define CKM_DES_CBC_ENCRYPT_DATA (0x1101UL) +#define CKM_DES3_ECB_ENCRYPT_DATA (0x1102UL) +#define CKM_DES3_CBC_ENCRYPT_DATA (0x1103UL) +#define CKM_AES_ECB_ENCRYPT_DATA (0x1104UL) +#define CKM_AES_CBC_ENCRYPT_DATA (0x1105UL) +#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) +#define CKM_GOSTR3410 (0x1201UL) +#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) +#define CKM_GOSTR3410_KEY_WRAP (0x1203UL) +#define CKM_GOSTR3410_DERIVE (0x1204UL) +#define CKM_GOSTR3411 (0x1210UL) +#define CKM_GOSTR3411_HMAC (0x1211UL) +#define CKM_GOST28147_KEY_GEN (0x1220UL) +#define CKM_GOST28147_ECB (0x1221UL) +#define CKM_GOST28147 (0x1222UL) +#define CKM_GOST28147_MAC (0x1223UL) +#define CKM_GOST28147_KEY_WRAP (0x1224UL) +#define CKM_DSA_PARAMETER_GEN (0x2000UL) +#define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) +#define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) +#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN (0x2003UL) +#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN (0x2004UL) +#define CKM_AES_OFB (0x2104UL) +#define CKM_AES_CFB64 (0x2105UL) +#define CKM_AES_CFB8 (0x2106UL) +#define CKM_AES_CFB128 (0x2107UL) +#define CKM_AES_CFB1 (0x2108UL) + +#define CKM_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + +/* Ammendments */ +#define CKM_SHA224 (0x255UL) +#define CKM_SHA224_HMAC (0x256UL) +#define CKM_SHA224_HMAC_GENERAL (0x257UL) +#define CKM_SHA224_RSA_PKCS (0x46UL) +#define CKM_SHA224_RSA_PKCS_PSS (0x47UL) +#define CKM_SHA224_KEY_DERIVATION (0x396UL) + +#define CKM_CAMELLIA_KEY_GEN (0x550UL) +#define CKM_CAMELLIA_ECB (0x551UL) +#define CKM_CAMELLIA_CBC (0x552UL) +#define CKM_CAMELLIA_MAC (0x553UL) +#define CKM_CAMELLIA_MAC_GENERAL (0x554UL) +#define CKM_CAMELLIA_CBC_PAD (0x555UL) +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA (0x556UL) +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA (0x557UL) + +#define CKM_AES_KEY_WRAP (0x2109UL) +#define CKM_AES_KEY_WRAP_PAD (0x210aUL) + +#define CKM_RSA_PKCS_TPM_1_1 (0x4001UL) +#define CKM_RSA_PKCS_OAEP_TPM_1_1 (0x4002UL) + +/* From version 3.0 */ +#define CKM_EC_EDWARDS_KEY_PAIR_GEN (0x1055UL) +#define CKM_EDDSA (0x1057UL) + +/* Attribute and other constants related to OTP */ +#define CK_OTP_FORMAT_DECIMAL (0UL) +#define CK_OTP_FORMAT_HEXADECIMAL (1UL) +#define CK_OTP_FORMAT_ALPHANUMERIC (2UL) +#define CK_OTP_FORMAT_BINARY (3UL) +#define CK_OTP_PARAM_IGNORED (0UL) +#define CK_OTP_PARAM_OPTIONAL (1UL) +#define CK_OTP_PARAM_MANDATORY (2UL) + +#define CK_OTP_VALUE (0UL) +#define CK_OTP_PIN (1UL) +#define CK_OTP_CHALLENGE (2UL) +#define CK_OTP_TIME (3UL) +#define CK_OTP_COUNTER (4UL) +#define CK_OTP_FLAGS (5UL) +#define CK_OTP_OUTPUT_LENGTH (6UL) +#define CK_OTP_FORMAT (7UL) + +/* OTP mechanism flags */ +#define CKF_NEXT_OTP (0x01UL) +#define CKF_EXCLUDE_TIME (0x02UL) +#define CKF_EXCLUDE_COUNTER (0x04UL) +#define CKF_EXCLUDE_CHALLENGE (0x08UL) +#define CKF_EXCLUDE_PIN (0x10UL) +#define CKF_USER_FRIENDLY_OTP (0x20UL) + +#define CKN_OTP_CHANGED (0x01UL) + +struct ck_mechanism +{ + ck_mechanism_type_t mechanism; + void *parameter; + unsigned long parameter_len; +}; + + +struct ck_mechanism_info +{ + unsigned long min_key_size; + unsigned long max_key_size; + ck_flags_t flags; +}; + +typedef unsigned long ck_param_type; + +typedef struct ck_otp_param { + ck_param_type type; + void *value; + unsigned long value_len; +} ck_otp_param; + +typedef struct ck_otp_params { + struct ck_otp_param *params; + unsigned long count; +} ck_otp_params; + +typedef struct ck_otp_signature_info +{ + struct ck_otp_param *params; + unsigned long count; +} ck_otp_signature_info; + +#define CKG_MGF1_SHA1 0x00000001UL +#define CKG_MGF1_SHA224 0x00000005UL +#define CKG_MGF1_SHA256 0x00000002UL +#define CKG_MGF1_SHA384 0x00000003UL +#define CKG_MGF1_SHA512 0x00000004UL + +typedef unsigned long ck_rsa_pkcs_mgf_type_t; + +struct ck_rsa_pkcs_pss_params { + ck_mechanism_type_t hash_alg; + ck_rsa_pkcs_mgf_type_t mgf; + unsigned long s_len; +}; + +typedef unsigned long ck_rsa_pkcs_oaep_source_type_t; + +struct ck_rsa_pkcs_oaep_params { + ck_mechanism_type_t hash_alg; + ck_rsa_pkcs_mgf_type_t mgf; + ck_rsa_pkcs_oaep_source_type_t source; + void *source_data; + unsigned long source_data_len; +}; + +struct ck_aes_ctr_params { + unsigned long counter_bits; + unsigned char cb[16]; +}; + +struct ck_gcm_params { + unsigned char *iv_ptr; + unsigned long iv_len; + unsigned long iv_bits; + unsigned char *aad_ptr; + unsigned long aad_len; + unsigned long tag_bits; +}; + + +/* The following EC Key Derivation Functions are defined */ +#define CKD_NULL (0x01UL) +#define CKD_SHA1_KDF (0x02UL) + +/* The following X9.42 DH key derivation functions are defined */ +#define CKD_SHA1_KDF_ASN1 (0x03UL) +#define CKD_SHA1_KDF_CONCATENATE (0x04UL) +#define CKD_SHA224_KDF (0x05UL) +#define CKD_SHA256_KDF (0x06UL) +#define CKD_SHA384_KDF (0x07UL) +#define CKD_SHA512_KDF (0x08UL) +#define CKD_CPDIVERSIFY_KDF (0x09UL) + +typedef unsigned long ck_ec_kdf_t; + +struct ck_ecdh1_derive_params { + ck_ec_kdf_t kdf; + unsigned long shared_data_len; + unsigned char *shared_data; + unsigned long public_data_len; + unsigned char *public_data; +}; + +struct ck_key_derivation_string_data { + unsigned char *string_data; + unsigned long string_data_len; +}; + +struct ck_des_cbc_encrypt_data_params { + unsigned char iv[8]; + unsigned char *data_params; + unsigned long length; +}; + +struct ck_aes_cbc_encrypt_data_params { + unsigned char iv[16]; + unsigned char *data_params; + unsigned long length; +}; + +#define CKF_HW (1UL << 0) +#define CKF_ENCRYPT (1UL << 8) +#define CKF_DECRYPT (1UL << 9) +#define CKF_DIGEST (1UL << 10) +#define CKF_SIGN (1UL << 11) +#define CKF_SIGN_RECOVER (1UL << 12) +#define CKF_VERIFY (1UL << 13) +#define CKF_VERIFY_RECOVER (1UL << 14) +#define CKF_GENERATE (1UL << 15) +#define CKF_GENERATE_KEY_PAIR (1UL << 16) +#define CKF_WRAP (1UL << 17) +#define CKF_UNWRAP (1UL << 18) +#define CKF_DERIVE (1UL << 19) +#define CKF_EXTENSION ((unsigned long) (1UL << 31)) + +#define CKF_EC_F_P (1UL << 20) +#define CKF_EC_NAMEDCURVE (1UL << 23) +#define CKF_EC_UNCOMPRESS (1UL << 24) +#define CKF_EC_COMPRESS (1UL << 25) + + +/* Flags for C_WaitForSlotEvent. */ +#define CKF_DONT_BLOCK (1UL) + + +typedef unsigned long ck_rv_t; + + +typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, + ck_notification_t event, void *application); + +/* Forward reference. */ +struct ck_function_list; + +#define _CK_DECLARE_FUNCTION(name, args) \ +typedef ck_rv_t (*CK_ ## name) args; \ +ck_rv_t CK_SPEC name args + +_CK_DECLARE_FUNCTION (C_Initialize, (void *init_args)); +_CK_DECLARE_FUNCTION (C_Finalize, (void *reserved)); +_CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info)); +_CK_DECLARE_FUNCTION (C_GetFunctionList, + (struct ck_function_list **function_list)); + +_CK_DECLARE_FUNCTION (C_GetSlotList, + (unsigned char token_present, ck_slot_id_t *slot_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION (C_GetSlotInfo, + (ck_slot_id_t slot_id, struct ck_slot_info *info)); +_CK_DECLARE_FUNCTION (C_GetTokenInfo, + (ck_slot_id_t slot_id, struct ck_token_info *info)); +_CK_DECLARE_FUNCTION (C_WaitForSlotEvent, + (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); +_CK_DECLARE_FUNCTION (C_GetMechanismList, + (ck_slot_id_t slot_id, + ck_mechanism_type_t *mechanism_list, + unsigned long *count)); +_CK_DECLARE_FUNCTION (C_GetMechanismInfo, + (ck_slot_id_t slot_id, ck_mechanism_type_t type, + struct ck_mechanism_info *info)); +_CK_DECLARE_FUNCTION (C_InitToken, + (ck_slot_id_t slot_id, unsigned char *pin, + unsigned long pin_len, unsigned char *label)); +_CK_DECLARE_FUNCTION (C_InitPIN, + (ck_session_handle_t session, unsigned char *pin, + unsigned long pin_len)); +_CK_DECLARE_FUNCTION (C_SetPIN, + (ck_session_handle_t session, unsigned char *old_pin, + unsigned long old_len, unsigned char *new_pin, + unsigned long new_len)); + +_CK_DECLARE_FUNCTION (C_OpenSession, + (ck_slot_id_t slot_id, ck_flags_t flags, + void *application, ck_notify_t notify, + ck_session_handle_t *session)); +_CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id)); +_CK_DECLARE_FUNCTION (C_GetSessionInfo, + (ck_session_handle_t session, + struct ck_session_info *info)); +_CK_DECLARE_FUNCTION (C_GetOperationState, + (ck_session_handle_t session, + unsigned char *operation_state, + unsigned long *operation_state_len)); +_CK_DECLARE_FUNCTION (C_SetOperationState, + (ck_session_handle_t session, + unsigned char *operation_state, + unsigned long operation_state_len, + ck_object_handle_t encryption_key, + ck_object_handle_t authentiation_key)); +_CK_DECLARE_FUNCTION (C_Login, + (ck_session_handle_t session, ck_user_type_t user_type, + unsigned char *pin, unsigned long pin_len)); +_CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_CreateObject, + (ck_session_handle_t session, + struct ck_attribute *templ, + unsigned long count, ck_object_handle_t *object)); +_CK_DECLARE_FUNCTION (C_CopyObject, + (ck_session_handle_t session, ck_object_handle_t object, + struct ck_attribute *templ, unsigned long count, + ck_object_handle_t *new_object)); +_CK_DECLARE_FUNCTION (C_DestroyObject, + (ck_session_handle_t session, + ck_object_handle_t object)); +_CK_DECLARE_FUNCTION (C_GetObjectSize, + (ck_session_handle_t session, + ck_object_handle_t object, + unsigned long *size)); +_CK_DECLARE_FUNCTION (C_GetAttributeValue, + (ck_session_handle_t session, + ck_object_handle_t object, + struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION (C_SetAttributeValue, + (ck_session_handle_t session, + ck_object_handle_t object, + struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION (C_FindObjectsInit, + (ck_session_handle_t session, + struct ck_attribute *templ, + unsigned long count)); +_CK_DECLARE_FUNCTION (C_FindObjects, + (ck_session_handle_t session, + ck_object_handle_t *object, + unsigned long max_object_count, + unsigned long *object_count)); +_CK_DECLARE_FUNCTION (C_FindObjectsFinal, + (ck_session_handle_t session)); + +_CK_DECLARE_FUNCTION (C_EncryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Encrypt, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *encrypted_data, + unsigned long *encrypted_data_len)); +_CK_DECLARE_FUNCTION (C_EncryptUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len, + unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION (C_EncryptFinal, + (ck_session_handle_t session, + unsigned char *last_encrypted_part, + unsigned long *last_encrypted_part_len)); + +_CK_DECLARE_FUNCTION (C_DecryptInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Decrypt, + (ck_session_handle_t session, + unsigned char *encrypted_data, + unsigned long encrypted_data_len, + unsigned char *data, unsigned long *data_len)); +_CK_DECLARE_FUNCTION (C_DecryptUpdate, + (ck_session_handle_t session, + unsigned char *encrypted_part, + unsigned long encrypted_part_len, + unsigned char *part, unsigned long *part_len)); +_CK_DECLARE_FUNCTION (C_DecryptFinal, + (ck_session_handle_t session, + unsigned char *last_part, + unsigned long *last_part_len)); + +_CK_DECLARE_FUNCTION (C_DigestInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism)); +_CK_DECLARE_FUNCTION (C_Digest, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *digest, + unsigned long *digest_len)); +_CK_DECLARE_FUNCTION (C_DigestUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len)); +_CK_DECLARE_FUNCTION (C_DigestKey, + (ck_session_handle_t session, ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_DigestFinal, + (ck_session_handle_t session, + unsigned char *digest, + unsigned long *digest_len)); + +_CK_DECLARE_FUNCTION (C_SignInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Sign, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_SignUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len)); +_CK_DECLARE_FUNCTION (C_SignFinal, + (ck_session_handle_t session, + unsigned char *signature, + unsigned long *signature_len)); +_CK_DECLARE_FUNCTION (C_SignRecoverInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_SignRecover, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *signature, + unsigned long *signature_len)); + +_CK_DECLARE_FUNCTION (C_VerifyInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_Verify, + (ck_session_handle_t session, + unsigned char *data, unsigned long data_len, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_VerifyUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len)); +_CK_DECLARE_FUNCTION (C_VerifyFinal, + (ck_session_handle_t session, + unsigned char *signature, + unsigned long signature_len)); +_CK_DECLARE_FUNCTION (C_VerifyRecoverInit, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t key)); +_CK_DECLARE_FUNCTION (C_VerifyRecover, + (ck_session_handle_t session, + unsigned char *signature, + unsigned long signature_len, + unsigned char *data, + unsigned long *data_len)); + +_CK_DECLARE_FUNCTION (C_DigestEncryptUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len, + unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION (C_DecryptDigestUpdate, + (ck_session_handle_t session, + unsigned char *encrypted_part, + unsigned long encrypted_part_len, + unsigned char *part, + unsigned long *part_len)); +_CK_DECLARE_FUNCTION (C_SignEncryptUpdate, + (ck_session_handle_t session, + unsigned char *part, unsigned long part_len, + unsigned char *encrypted_part, + unsigned long *encrypted_part_len)); +_CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate, + (ck_session_handle_t session, + unsigned char *encrypted_part, + unsigned long encrypted_part_len, + unsigned char *part, + unsigned long *part_len)); + +_CK_DECLARE_FUNCTION (C_GenerateKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + struct ck_attribute *templ, + unsigned long count, + ck_object_handle_t *key)); +_CK_DECLARE_FUNCTION (C_GenerateKeyPair, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + struct ck_attribute *public_key_template, + unsigned long public_key_attribute_count, + struct ck_attribute *private_key_template, + unsigned long private_key_attribute_count, + ck_object_handle_t *public_key, + ck_object_handle_t *private_key)); +_CK_DECLARE_FUNCTION (C_WrapKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t wrapping_key, + ck_object_handle_t key, + unsigned char *wrapped_key, + unsigned long *wrapped_key_len)); +_CK_DECLARE_FUNCTION (C_UnwrapKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t unwrapping_key, + unsigned char *wrapped_key, + unsigned long wrapped_key_len, + struct ck_attribute *templ, + unsigned long attribute_count, + ck_object_handle_t *key)); +_CK_DECLARE_FUNCTION (C_DeriveKey, + (ck_session_handle_t session, + struct ck_mechanism *mechanism, + ck_object_handle_t base_key, + struct ck_attribute *templ, + unsigned long attribute_count, + ck_object_handle_t *key)); + +_CK_DECLARE_FUNCTION (C_SeedRandom, + (ck_session_handle_t session, unsigned char *seed, + unsigned long seed_len)); +_CK_DECLARE_FUNCTION (C_GenerateRandom, + (ck_session_handle_t session, + unsigned char *random_data, + unsigned long random_len)); + +_CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); +_CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); + + +struct ck_function_list +{ + struct ck_version version; + CK_C_Initialize C_Initialize; + CK_C_Finalize C_Finalize; + CK_C_GetInfo C_GetInfo; + CK_C_GetFunctionList C_GetFunctionList; + CK_C_GetSlotList C_GetSlotList; + CK_C_GetSlotInfo C_GetSlotInfo; + CK_C_GetTokenInfo C_GetTokenInfo; + CK_C_GetMechanismList C_GetMechanismList; + CK_C_GetMechanismInfo C_GetMechanismInfo; + CK_C_InitToken C_InitToken; + CK_C_InitPIN C_InitPIN; + CK_C_SetPIN C_SetPIN; + CK_C_OpenSession C_OpenSession; + CK_C_CloseSession C_CloseSession; + CK_C_CloseAllSessions C_CloseAllSessions; + CK_C_GetSessionInfo C_GetSessionInfo; + CK_C_GetOperationState C_GetOperationState; + CK_C_SetOperationState C_SetOperationState; + CK_C_Login C_Login; + CK_C_Logout C_Logout; + CK_C_CreateObject C_CreateObject; + CK_C_CopyObject C_CopyObject; + CK_C_DestroyObject C_DestroyObject; + CK_C_GetObjectSize C_GetObjectSize; + CK_C_GetAttributeValue C_GetAttributeValue; + CK_C_SetAttributeValue C_SetAttributeValue; + CK_C_FindObjectsInit C_FindObjectsInit; + CK_C_FindObjects C_FindObjects; + CK_C_FindObjectsFinal C_FindObjectsFinal; + CK_C_EncryptInit C_EncryptInit; + CK_C_Encrypt C_Encrypt; + CK_C_EncryptUpdate C_EncryptUpdate; + CK_C_EncryptFinal C_EncryptFinal; + CK_C_DecryptInit C_DecryptInit; + CK_C_Decrypt C_Decrypt; + CK_C_DecryptUpdate C_DecryptUpdate; + CK_C_DecryptFinal C_DecryptFinal; + CK_C_DigestInit C_DigestInit; + CK_C_Digest C_Digest; + CK_C_DigestUpdate C_DigestUpdate; + CK_C_DigestKey C_DigestKey; + CK_C_DigestFinal C_DigestFinal; + CK_C_SignInit C_SignInit; + CK_C_Sign C_Sign; + CK_C_SignUpdate C_SignUpdate; + CK_C_SignFinal C_SignFinal; + CK_C_SignRecoverInit C_SignRecoverInit; + CK_C_SignRecover C_SignRecover; + CK_C_VerifyInit C_VerifyInit; + CK_C_Verify C_Verify; + CK_C_VerifyUpdate C_VerifyUpdate; + CK_C_VerifyFinal C_VerifyFinal; + CK_C_VerifyRecoverInit C_VerifyRecoverInit; + CK_C_VerifyRecover C_VerifyRecover; + CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; + CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; + CK_C_SignEncryptUpdate C_SignEncryptUpdate; + CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; + CK_C_GenerateKey C_GenerateKey; + CK_C_GenerateKeyPair C_GenerateKeyPair; + CK_C_WrapKey C_WrapKey; + CK_C_UnwrapKey C_UnwrapKey; + CK_C_DeriveKey C_DeriveKey; + CK_C_SeedRandom C_SeedRandom; + CK_C_GenerateRandom C_GenerateRandom; + CK_C_GetFunctionStatus C_GetFunctionStatus; + CK_C_CancelFunction C_CancelFunction; + CK_C_WaitForSlotEvent C_WaitForSlotEvent; +}; + + +typedef ck_rv_t (*ck_createmutex_t) (void **mutex); +typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); +typedef ck_rv_t (*ck_lockmutex_t) (void *mutex); +typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex); + + +struct ck_c_initialize_args +{ + ck_createmutex_t create_mutex; + ck_destroymutex_t destroy_mutex; + ck_lockmutex_t lock_mutex; + ck_unlockmutex_t unlock_mutex; + ck_flags_t flags; + void *reserved; +}; + + +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) +#define CKF_OS_LOCKING_OK (1UL << 1) + +#define CKR_OK (0UL) +#define CKR_CANCEL (1UL) +#define CKR_HOST_MEMORY (2UL) +#define CKR_SLOT_ID_INVALID (3UL) +#define CKR_GENERAL_ERROR (5UL) +#define CKR_FUNCTION_FAILED (6UL) +#define CKR_ARGUMENTS_BAD (7UL) +#define CKR_NO_EVENT (8UL) +#define CKR_NEED_TO_CREATE_THREADS (9UL) +#define CKR_CANT_LOCK (0xaUL) +#define CKR_ATTRIBUTE_READ_ONLY (0x10UL) +#define CKR_ATTRIBUTE_SENSITIVE (0x11UL) +#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) +#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) +#define CKR_ACTION_PROHIBITED (0x1BUL) +#define CKR_DATA_INVALID (0x20UL) +#define CKR_DATA_LEN_RANGE (0x21UL) +#define CKR_DEVICE_ERROR (0x30UL) +#define CKR_DEVICE_MEMORY (0x31UL) +#define CKR_DEVICE_REMOVED (0x32UL) +#define CKR_ENCRYPTED_DATA_INVALID (0x40UL) +#define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) +#define CKR_FUNCTION_CANCELED (0x50UL) +#define CKR_FUNCTION_NOT_PARALLEL (0x51UL) +#define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) +#define CKR_KEY_HANDLE_INVALID (0x60UL) +#define CKR_KEY_SIZE_RANGE (0x62UL) +#define CKR_KEY_TYPE_INCONSISTENT (0x63UL) +#define CKR_KEY_NOT_NEEDED (0x64UL) +#define CKR_KEY_CHANGED (0x65UL) +#define CKR_KEY_NEEDED (0x66UL) +#define CKR_KEY_INDIGESTIBLE (0x67UL) +#define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) +#define CKR_KEY_NOT_WRAPPABLE (0x69UL) +#define CKR_KEY_UNEXTRACTABLE (0x6aUL) +#define CKR_MECHANISM_INVALID (0x70UL) +#define CKR_MECHANISM_PARAM_INVALID (0x71UL) +#define CKR_OBJECT_HANDLE_INVALID (0x82UL) +#define CKR_OPERATION_ACTIVE (0x90UL) +#define CKR_OPERATION_NOT_INITIALIZED (0x91UL) +#define CKR_PIN_INCORRECT (0xa0UL) +#define CKR_PIN_INVALID (0xa1UL) +#define CKR_PIN_LEN_RANGE (0xa2UL) +#define CKR_PIN_EXPIRED (0xa3UL) +#define CKR_PIN_LOCKED (0xa4UL) +#define CKR_SESSION_CLOSED (0xb0UL) +#define CKR_SESSION_COUNT (0xb1UL) +#define CKR_SESSION_HANDLE_INVALID (0xb3UL) +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) +#define CKR_SESSION_READ_ONLY (0xb5UL) +#define CKR_SESSION_EXISTS (0xb6UL) +#define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) +#define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) +#define CKR_SIGNATURE_INVALID (0xc0UL) +#define CKR_SIGNATURE_LEN_RANGE (0xc1UL) +#define CKR_TEMPLATE_INCOMPLETE (0xd0UL) +#define CKR_TEMPLATE_INCONSISTENT (0xd1UL) +#define CKR_TOKEN_NOT_PRESENT (0xe0UL) +#define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) +#define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) +#define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) +#define CKR_USER_ALREADY_LOGGED_IN (0x100UL) +#define CKR_USER_NOT_LOGGED_IN (0x101UL) +#define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) +#define CKR_USER_TYPE_INVALID (0x103UL) +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) +#define CKR_USER_TOO_MANY_TYPES (0x105UL) +#define CKR_WRAPPED_KEY_INVALID (0x110UL) +#define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) +#define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) +#define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) +#define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) +#define CKR_RANDOM_NO_RNG (0x121UL) +#define CKR_DOMAIN_PARAMS_INVALID (0x130UL) +#define CKR_BUFFER_TOO_SMALL (0x150UL) +#define CKR_SAVED_STATE_INVALID (0x160UL) +#define CKR_INFORMATION_SENSITIVE (0x170UL) +#define CKR_STATE_UNSAVEABLE (0x180UL) +#define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) +#define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) +#define CKR_MUTEX_BAD (0x1a0UL) +#define CKR_MUTEX_NOT_LOCKED (0x1a1UL) +#define CKR_NEW_PIN_MODE (0x1b0UL) +#define CKR_NEXT_OTP (0x1b1UL) +#define CKR_EXCEEDED_MAX_ITERATIONS (0x1c0UL) +#define CKR_FIPS_SELF_TEST_FAILED (0x1c1UL) +#define CKR_LIBRARY_LOAD_FAILED (0x1c2UL) +#define CKR_PIN_TOO_WEAK (0x1c3UL) +#define CKR_PUBLIC_KEY_INVALID (0x1c4UL) +#define CKR_FUNCTION_REJECTED (0x200UL) +#define CKR_VENDOR_DEFINED ((unsigned long) (1UL << 31)) + + +#define CKZ_DATA_SPECIFIED (0x01UL) + + + +/* Compatibility layer. */ + +#ifdef CRYPTOKI_COMPAT + +#undef CK_DEFINE_FUNCTION +#define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name + +/* For NULL. */ +#include <stddef.h> + +typedef unsigned char CK_BYTE; +typedef unsigned char CK_CHAR; +typedef unsigned char CK_UTF8CHAR; +typedef unsigned char CK_BBOOL; +typedef unsigned long int CK_ULONG; +typedef long int CK_LONG; +typedef CK_BYTE *CK_BYTE_PTR; +typedef CK_CHAR *CK_CHAR_PTR; +typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; +typedef CK_ULONG *CK_ULONG_PTR; +typedef void *CK_VOID_PTR; +typedef void **CK_VOID_PTR_PTR; +#define CK_FALSE 0 +#define CK_TRUE 1 +#ifndef CK_DISABLE_TRUE_FALSE +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#endif + +typedef struct ck_version CK_VERSION; +typedef struct ck_version *CK_VERSION_PTR; + +typedef struct ck_info CK_INFO; +typedef struct ck_info *CK_INFO_PTR; + +typedef ck_slot_id_t *CK_SLOT_ID_PTR; + +typedef struct ck_slot_info CK_SLOT_INFO; +typedef struct ck_slot_info *CK_SLOT_INFO_PTR; + +typedef struct ck_token_info CK_TOKEN_INFO; +typedef struct ck_token_info *CK_TOKEN_INFO_PTR; + +typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; + +typedef struct ck_session_info CK_SESSION_INFO; +typedef struct ck_session_info *CK_SESSION_INFO_PTR; + +typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; + +typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; + +typedef struct ck_attribute CK_ATTRIBUTE; +typedef struct ck_attribute *CK_ATTRIBUTE_PTR; + +typedef struct ck_date CK_DATE; +typedef struct ck_date *CK_DATE_PTR; + +typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; + +typedef struct ck_mechanism CK_MECHANISM; +typedef struct ck_mechanism *CK_MECHANISM_PTR; + +typedef struct ck_mechanism_info CK_MECHANISM_INFO; +typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; + +typedef struct ck_otp_mechanism_info CK_OTP_MECHANISM_INFO; +typedef struct ck_otp_mechanism_info *CK_OTP_MECHANISM_INFO_PTR; + +typedef struct ck_function_list CK_FUNCTION_LIST; +typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; +typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; + +typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; +typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; + +typedef struct ck_rsa_pkcs_pss_params CK_RSA_PKCS_PSS_PARAMS; +typedef struct ck_rsa_pkcs_pss_params *CK_RSA_PKCS_PSS_PARAMS_PTR; + +typedef struct ck_rsa_pkcs_oaep_params CK_RSA_PKCS_OAEP_PARAMS; +typedef struct ck_rsa_pkcs_oaep_params *CK_RSA_PKCS_OAEP_PARAMS_PTR; + +typedef struct ck_aes_ctr_params CK_AES_CTR_PARAMS; +typedef struct ck_aes_ctr_params *CK_AES_CTR_PARAMS_PTR; + +typedef struct ck_gcm_params CK_GCM_PARAMS; +typedef struct ck_gcm_params *CK_GCM_PARAMS_PTR; + +typedef struct ck_ecdh1_derive_params CK_ECDH1_DERIVE_PARAMS; +typedef struct ck_ecdh1_derive_params *CK_ECDH1_DERIVE_PARAMS_PTR; + +typedef struct ck_key_derivation_string_data CK_KEY_DERIVATION_STRING_DATA; +typedef struct ck_key_derivation_string_data *CK_KEY_DERIVATION_STRING_DATA_PTR; + +typedef struct ck_des_cbc_encrypt_data_params CK_DES_CBC_ENCRYPT_DATA_PARAMS; +typedef struct ck_des_cbc_encrypt_data_params *CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +typedef struct ck_aes_cbc_encrypt_data_params CK_AES_CBC_ENCRYPT_DATA_PARAMS; +typedef struct ck_aes_cbc_encrypt_data_params *CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +#ifndef NULL_PTR +#define NULL_PTR NULL #endif -#endif /* _PKCS11_H_ */ +/* Delete the helper macros defined at the top of the file. */ +#undef ck_flags_t +#undef ck_version + +#undef ck_info +#undef cryptoki_version +#undef manufacturer_id +#undef library_description +#undef library_version + +#undef ck_notification_t +#undef ck_slot_id_t + +#undef ck_slot_info +#undef slot_description +#undef hardware_version +#undef firmware_version + +#undef ck_token_info +#undef serial_number +#undef max_session_count +#undef session_count +#undef max_rw_session_count +#undef rw_session_count +#undef max_pin_len +#undef min_pin_len +#undef total_public_memory +#undef free_public_memory +#undef total_private_memory +#undef free_private_memory +#undef utc_time + +#undef ck_session_handle_t +#undef ck_user_type_t +#undef ck_state_t + +#undef ck_session_info +#undef slot_id +#undef device_error + +#undef ck_object_handle_t +#undef ck_object_class_t +#undef ck_hw_feature_type_t +#undef ck_key_type_t +#undef ck_certificate_type_t +#undef ck_attribute_type_t + +#undef ck_attribute +#undef value +#undef value_len + +#undef params +#undef count + +#undef ck_date + +#undef ck_mechanism_type_t + +#undef ck_mechanism +#undef parameter +#undef parameter_len + +#undef ck_mechanism_info + +#undef ck_param_type +#undef ck_otp_param +#undef ck_otp_params +#undef ck_otp_signature_info + +#undef min_key_size +#undef max_key_size + +#undef ck_rv_t +#undef ck_notify_t + +#undef ck_function_list + +#undef ck_createmutex_t +#undef ck_destroymutex_t +#undef ck_lockmutex_t +#undef ck_unlockmutex_t + +#undef ck_c_initialize_args +#undef create_mutex +#undef destroy_mutex +#undef lock_mutex +#undef unlock_mutex +#undef reserved + +#endif /* CRYPTOKI_COMPAT */ + + +/* System dependencies. */ +#if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) +#pragma pack(pop, cryptoki) +#endif + +#if defined(__cplusplus) +} +#endif +#endif /* PKCS11_H */ diff --git a/SoftHSMv2/src/lib/pkcs11/pkcs11f.h b/SoftHSMv2/src/lib/pkcs11/pkcs11f.h deleted file mode 100644 index ed90aff..0000000 --- a/SoftHSMv2/src/lib/pkcs11/pkcs11f.h +++ /dev/null @@ -1,939 +0,0 @@ -/* Copyright (c) OASIS Open 2016. All Rights Reserved./ - * /Distributed under the terms of the OASIS IPR Policy, - * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY - * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. - */ - -/* Latest version of the specification: - * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html - */ - -/* This header file contains pretty much everything about all the - * Cryptoki function prototypes. Because this information is - * used for more than just declaring function prototypes, the - * order of the functions appearing herein is important, and - * should not be altered. - */ - -/* General-purpose */ - -/* C_Initialize initializes the Cryptoki library. */ -CK_PKCS11_FUNCTION_INFO(C_Initialize) -#ifdef CK_NEED_ARG_LIST -( - CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets - * cast to CK_C_INITIALIZE_ARGS_PTR - * and dereferenced - */ -); -#endif - - -/* C_Finalize indicates that an application is done with the - * Cryptoki library. - */ -CK_PKCS11_FUNCTION_INFO(C_Finalize) -#ifdef CK_NEED_ARG_LIST -( - CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ -); -#endif - - -/* C_GetInfo returns general information about Cryptoki. */ -CK_PKCS11_FUNCTION_INFO(C_GetInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_INFO_PTR pInfo /* location that receives information */ -); -#endif - - -/* C_GetFunctionList returns the function list. */ -CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) -#ifdef CK_NEED_ARG_LIST -( - CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to - * function list - */ -); -#endif - - - -/* Slot and token management */ - -/* C_GetSlotList obtains a list of slots in the system. */ -CK_PKCS11_FUNCTION_INFO(C_GetSlotList) -#ifdef CK_NEED_ARG_LIST -( - CK_BBOOL tokenPresent, /* only slots with tokens */ - CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ - CK_ULONG_PTR pulCount /* receives number of slots */ -); -#endif - - -/* C_GetSlotInfo obtains information about a particular slot in - * the system. - */ -CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* the ID of the slot */ - CK_SLOT_INFO_PTR pInfo /* receives the slot information */ -); -#endif - - -/* C_GetTokenInfo obtains information about a particular token - * in the system. - */ -CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of the token's slot */ - CK_TOKEN_INFO_PTR pInfo /* receives the token information */ -); -#endif - - -/* C_GetMechanismList obtains a list of mechanism types - * supported by a token. - */ -CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of token's slot */ - CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ - CK_ULONG_PTR pulCount /* gets # of mechs. */ -); -#endif - - -/* C_GetMechanismInfo obtains information about a particular - * mechanism possibly supported by a token. - */ -CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of the token's slot */ - CK_MECHANISM_TYPE type, /* type of mechanism */ - CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ -); -#endif - - -/* C_InitToken initializes a token. */ -CK_PKCS11_FUNCTION_INFO(C_InitToken) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* ID of the token's slot */ - CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ - CK_ULONG ulPinLen, /* length in bytes of the PIN */ - CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ -); -#endif - - -/* C_InitPIN initializes the normal user's PIN. */ -CK_PKCS11_FUNCTION_INFO(C_InitPIN) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ - CK_ULONG ulPinLen /* length in bytes of the PIN */ -); -#endif - - -/* C_SetPIN modifies the PIN of the user who is logged in. */ -CK_PKCS11_FUNCTION_INFO(C_SetPIN) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ - CK_ULONG ulOldLen, /* length of the old PIN */ - CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ - CK_ULONG ulNewLen /* length of the new PIN */ -); -#endif - - - -/* Session management */ - -/* C_OpenSession opens a session between an application and a - * token. - */ -CK_PKCS11_FUNCTION_INFO(C_OpenSession) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID, /* the slot's ID */ - CK_FLAGS flags, /* from CK_SESSION_INFO */ - CK_VOID_PTR pApplication, /* passed to callback */ - CK_NOTIFY Notify, /* callback function */ - CK_SESSION_HANDLE_PTR phSession /* gets session handle */ -); -#endif - - -/* C_CloseSession closes a session between an application and a - * token. - */ -CK_PKCS11_FUNCTION_INFO(C_CloseSession) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - -/* C_CloseAllSessions closes all sessions with a token. */ -CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) -#ifdef CK_NEED_ARG_LIST -( - CK_SLOT_ID slotID /* the token's slot */ -); -#endif - - -/* C_GetSessionInfo obtains information about the session. */ -CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_SESSION_INFO_PTR pInfo /* receives session info */ -); -#endif - - -/* C_GetOperationState obtains the state of the cryptographic operation - * in a session. - */ -CK_PKCS11_FUNCTION_INFO(C_GetOperationState) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pOperationState, /* gets state */ - CK_ULONG_PTR pulOperationStateLen /* gets state length */ -); -#endif - - -/* C_SetOperationState restores the state of the cryptographic - * operation in a session. - */ -CK_PKCS11_FUNCTION_INFO(C_SetOperationState) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pOperationState, /* holds state */ - CK_ULONG ulOperationStateLen, /* holds state length */ - CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ - CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ -); -#endif - - -/* C_Login logs a user into a token. */ -CK_PKCS11_FUNCTION_INFO(C_Login) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_USER_TYPE userType, /* the user type */ - CK_UTF8CHAR_PTR pPin, /* the user's PIN */ - CK_ULONG ulPinLen /* the length of the PIN */ -); -#endif - - -/* C_Logout logs a user out from a token. */ -CK_PKCS11_FUNCTION_INFO(C_Logout) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - - -/* Object management */ - -/* C_CreateObject creates a new object. */ -CK_PKCS11_FUNCTION_INFO(C_CreateObject) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ - CK_ULONG ulCount, /* attributes in template */ - CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ -); -#endif - - -/* C_CopyObject copies an object, creating a new object for the - * copy. - */ -CK_PKCS11_FUNCTION_INFO(C_CopyObject) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ - CK_ULONG ulCount, /* attributes in template */ - CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ -); -#endif - - -/* C_DestroyObject destroys an object. */ -CK_PKCS11_FUNCTION_INFO(C_DestroyObject) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject /* the object's handle */ -); -#endif - - -/* C_GetObjectSize gets the size of an object in bytes. */ -CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ULONG_PTR pulSize /* receives size of object */ -); -#endif - - -/* C_GetAttributeValue obtains the value of one or more object - * attributes. - */ -CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ - CK_ULONG ulCount /* attributes in template */ -); -#endif - - -/* C_SetAttributeValue modifies the value of one or more object - * attributes. - */ -CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hObject, /* the object's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ - CK_ULONG ulCount /* attributes in template */ -); -#endif - - -/* C_FindObjectsInit initializes a search for token and session - * objects that match a template. - */ -CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ - CK_ULONG ulCount /* attrs in search template */ -); -#endif - - -/* C_FindObjects continues a search for token and session - * objects that match a template, obtaining additional object - * handles. - */ -CK_PKCS11_FUNCTION_INFO(C_FindObjects) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ - CK_ULONG ulMaxObjectCount, /* max handles to get */ - CK_ULONG_PTR pulObjectCount /* actual # returned */ -); -#endif - - -/* C_FindObjectsFinal finishes a search for token and session - * objects. - */ -CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - - -/* Encryption and decryption */ - -/* C_EncryptInit initializes an encryption operation. */ -CK_PKCS11_FUNCTION_INFO(C_EncryptInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ - CK_OBJECT_HANDLE hKey /* handle of encryption key */ -); -#endif - - -/* C_Encrypt encrypts single-part data. */ -CK_PKCS11_FUNCTION_INFO(C_Encrypt) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pData, /* the plaintext data */ - CK_ULONG ulDataLen, /* bytes of plaintext */ - CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ -); -#endif - - -/* C_EncryptUpdate continues a multiple-part encryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pPart, /* the plaintext data */ - CK_ULONG ulPartLen, /* plaintext data len */ - CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ -); -#endif - - -/* C_EncryptFinal finishes a multiple-part encryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session handle */ - CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ - CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ -); -#endif - - -/* C_DecryptInit initializes a decryption operation. */ -CK_PKCS11_FUNCTION_INFO(C_DecryptInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ - CK_OBJECT_HANDLE hKey /* handle of decryption key */ -); -#endif - - -/* C_Decrypt decrypts encrypted data in a single part. */ -CK_PKCS11_FUNCTION_INFO(C_Decrypt) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedData, /* ciphertext */ - CK_ULONG ulEncryptedDataLen, /* ciphertext length */ - CK_BYTE_PTR pData, /* gets plaintext */ - CK_ULONG_PTR pulDataLen /* gets p-text size */ -); -#endif - - -/* C_DecryptUpdate continues a multiple-part decryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedPart, /* encrypted data */ - CK_ULONG ulEncryptedPartLen, /* input length */ - CK_BYTE_PTR pPart, /* gets plaintext */ - CK_ULONG_PTR pulPartLen /* p-text size */ -); -#endif - - -/* C_DecryptFinal finishes a multiple-part decryption - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pLastPart, /* gets plaintext */ - CK_ULONG_PTR pulLastPartLen /* p-text size */ -); -#endif - - - -/* Message digesting */ - -/* C_DigestInit initializes a message-digesting operation. */ -CK_PKCS11_FUNCTION_INFO(C_DigestInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ -); -#endif - - -/* C_Digest digests data in a single part. */ -CK_PKCS11_FUNCTION_INFO(C_Digest) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* data to be digested */ - CK_ULONG ulDataLen, /* bytes of data to digest */ - CK_BYTE_PTR pDigest, /* gets the message digest */ - CK_ULONG_PTR pulDigestLen /* gets digest length */ -); -#endif - - -/* C_DigestUpdate continues a multiple-part message-digesting - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* data to be digested */ - CK_ULONG ulPartLen /* bytes of data to be digested */ -); -#endif - - -/* C_DigestKey continues a multi-part message-digesting - * operation, by digesting the value of a secret key as part of - * the data already digested. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_OBJECT_HANDLE hKey /* secret key to digest */ -); -#endif - - -/* C_DigestFinal finishes a multiple-part message-digesting - * operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pDigest, /* gets the message digest */ - CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ -); -#endif - - - -/* Signing and MACing */ - -/* C_SignInit initializes a signature (private key encryption) - * operation, where the signature is (will be) an appendix to - * the data, and plaintext cannot be recovered from the - * signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ - CK_OBJECT_HANDLE hKey /* handle of signature key */ -); -#endif - - -/* C_Sign signs (encrypts with private key) data in a single - * part, where the signature is (will be) an appendix to the - * data, and plaintext cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_Sign) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* the data to sign */ - CK_ULONG ulDataLen, /* count of bytes to sign */ - CK_BYTE_PTR pSignature, /* gets the signature */ - CK_ULONG_PTR pulSignatureLen /* gets signature length */ -); -#endif - - -/* C_SignUpdate continues a multiple-part signature operation, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* the data to sign */ - CK_ULONG ulPartLen /* count of bytes to sign */ -); -#endif - - -/* C_SignFinal finishes a multiple-part signature operation, - * returning the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSignature, /* gets the signature */ - CK_ULONG_PTR pulSignatureLen /* gets signature length */ -); -#endif - - -/* C_SignRecoverInit initializes a signature operation, where - * the data can be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ - CK_OBJECT_HANDLE hKey /* handle of the signature key */ -); -#endif - - -/* C_SignRecover signs data in a single operation, where the - * data can be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_SignRecover) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* the data to sign */ - CK_ULONG ulDataLen, /* count of bytes to sign */ - CK_BYTE_PTR pSignature, /* gets the signature */ - CK_ULONG_PTR pulSignatureLen /* gets signature length */ -); -#endif - - - -/* Verifying signatures and MACs */ - -/* C_VerifyInit initializes a verification operation, where the - * signature is an appendix to the data, and plaintext cannot - * cannot be recovered from the signature (e.g. DSA). - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ - CK_OBJECT_HANDLE hKey /* verification key */ -); -#endif - - -/* C_Verify verifies a signature in a single-part operation, - * where the signature is an appendix to the data, and plaintext - * cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_Verify) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pData, /* signed data */ - CK_ULONG ulDataLen, /* length of signed data */ - CK_BYTE_PTR pSignature, /* signature */ - CK_ULONG ulSignatureLen /* signature length*/ -); -#endif - - -/* C_VerifyUpdate continues a multiple-part verification - * operation, where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pPart, /* signed data */ - CK_ULONG ulPartLen /* length of signed data */ -); -#endif - - -/* C_VerifyFinal finishes a multiple-part verification - * operation, checking the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSignature, /* signature to verify */ - CK_ULONG ulSignatureLen /* signature length */ -); -#endif - - -/* C_VerifyRecoverInit initializes a signature verification - * operation, where the data is recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ - CK_OBJECT_HANDLE hKey /* verification key */ -); -#endif - - -/* C_VerifyRecover verifies a signature in a single-part - * operation, where the data is recovered from the signature. - */ -CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSignature, /* signature to verify */ - CK_ULONG ulSignatureLen, /* signature length */ - CK_BYTE_PTR pData, /* gets signed data */ - CK_ULONG_PTR pulDataLen /* gets signed data len */ -); -#endif - - - -/* Dual-function cryptographic operations */ - -/* C_DigestEncryptUpdate continues a multiple-part digesting - * and encryption operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pPart, /* the plaintext data */ - CK_ULONG ulPartLen, /* plaintext length */ - CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ -); -#endif - - -/* C_DecryptDigestUpdate continues a multiple-part decryption and - * digesting operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedPart, /* ciphertext */ - CK_ULONG ulEncryptedPartLen, /* ciphertext length */ - CK_BYTE_PTR pPart, /* gets plaintext */ - CK_ULONG_PTR pulPartLen /* gets plaintext len */ -); -#endif - - -/* C_SignEncryptUpdate continues a multiple-part signing and - * encryption operation. - */ -CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pPart, /* the plaintext data */ - CK_ULONG ulPartLen, /* plaintext length */ - CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ - CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ -); -#endif - - -/* C_DecryptVerifyUpdate continues a multiple-part decryption and - * verify operation. - */ -CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_BYTE_PTR pEncryptedPart, /* ciphertext */ - CK_ULONG ulEncryptedPartLen, /* ciphertext length */ - CK_BYTE_PTR pPart, /* gets plaintext */ - CK_ULONG_PTR pulPartLen /* gets p-text length */ -); -#endif - - - -/* Key management */ - -/* C_GenerateKey generates a secret key, creating a new key - * object. - */ -CK_PKCS11_FUNCTION_INFO(C_GenerateKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* key generation mech. */ - CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ - CK_ULONG ulCount, /* # of attrs in template */ - CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ -); -#endif - - -/* C_GenerateKeyPair generates a public-key/private-key pair, - * creating new key objects. - */ -CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session handle */ - CK_MECHANISM_PTR pMechanism, /* key-gen mech. */ - CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */ - CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */ - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */ - CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */ - CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */ - CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */ -); -#endif - - -/* C_WrapKey wraps (i.e., encrypts) a key. */ -CK_PKCS11_FUNCTION_INFO(C_WrapKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ - CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ - CK_OBJECT_HANDLE hKey, /* key to be wrapped */ - CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ - CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ -); -#endif - - -/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new - * key object. - */ -CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ - CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ - CK_BYTE_PTR pWrappedKey, /* the wrapped key */ - CK_ULONG ulWrappedKeyLen, /* wrapped key len */ - CK_ATTRIBUTE_PTR pTemplate, /* new key template */ - CK_ULONG ulAttributeCount, /* template length */ - CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ -); -#endif - - -/* C_DeriveKey derives a key from a base key, creating a new key - * object. - */ -CK_PKCS11_FUNCTION_INFO(C_DeriveKey) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* session's handle */ - CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ - CK_OBJECT_HANDLE hBaseKey, /* base key */ - CK_ATTRIBUTE_PTR pTemplate, /* new key template */ - CK_ULONG ulAttributeCount, /* template length */ - CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ -); -#endif - - - -/* Random number generation */ - -/* C_SeedRandom mixes additional seed material into the token's - * random number generator. - */ -CK_PKCS11_FUNCTION_INFO(C_SeedRandom) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR pSeed, /* the seed material */ - CK_ULONG ulSeedLen /* length of seed material */ -); -#endif - - -/* C_GenerateRandom generates random data. */ -CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_BYTE_PTR RandomData, /* receives the random data */ - CK_ULONG ulRandomLen /* # of bytes to generate */ -); -#endif - - - -/* Parallel function management */ - -/* C_GetFunctionStatus is a legacy function; it obtains an - * updated status of a function running in parallel with an - * application. - */ -CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - -/* C_CancelFunction is a legacy function; it cancels a function - * running in parallel. - */ -CK_PKCS11_FUNCTION_INFO(C_CancelFunction) -#ifdef CK_NEED_ARG_LIST -( - CK_SESSION_HANDLE hSession /* the session's handle */ -); -#endif - - -/* C_WaitForSlotEvent waits for a slot event (token insertion, - * removal, etc.) to occur. - */ -CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) -#ifdef CK_NEED_ARG_LIST -( - CK_FLAGS flags, /* blocking/nonblocking flag */ - CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ - CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ -); -#endif - diff --git a/SoftHSMv2/src/lib/pkcs11/pkcs11t.h b/SoftHSMv2/src/lib/pkcs11/pkcs11t.h deleted file mode 100644 index 0cf3acc..0000000 --- a/SoftHSMv2/src/lib/pkcs11/pkcs11t.h +++ /dev/null @@ -1,2003 +0,0 @@ -/* Copyright (c) OASIS Open 2016. All Rights Reserved./ - * /Distributed under the terms of the OASIS IPR Policy, - * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY - * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. - */ - -/* Latest version of the specification: - * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html - */ - -/* See top of pkcs11.h for information about the macros that - * must be defined and the structure-packing conventions that - * must be set before including this file. - */ - -#ifndef _PKCS11T_H_ -#define _PKCS11T_H_ 1 - -#define CRYPTOKI_VERSION_MAJOR 2 -#define CRYPTOKI_VERSION_MINOR 40 -#define CRYPTOKI_VERSION_AMENDMENT 0 - -#define CK_TRUE 1 -#define CK_FALSE 0 - -#ifndef CK_DISABLE_TRUE_FALSE -#ifndef FALSE -#define FALSE CK_FALSE -#endif -#ifndef TRUE -#define TRUE CK_TRUE -#endif -#endif - -/* an unsigned 8-bit value */ -typedef unsigned char CK_BYTE; - -/* an unsigned 8-bit character */ -typedef CK_BYTE CK_CHAR; - -/* an 8-bit UTF-8 character */ -typedef CK_BYTE CK_UTF8CHAR; - -/* a BYTE-sized Boolean flag */ -typedef CK_BYTE CK_BBOOL; - -/* an unsigned value, at least 32 bits long */ -typedef unsigned long int CK_ULONG; - -/* a signed value, the same size as a CK_ULONG */ -typedef long int CK_LONG; - -/* at least 32 bits; each bit is a Boolean flag */ -typedef CK_ULONG CK_FLAGS; - - -/* some special values for certain CK_ULONG variables */ -#define CK_UNAVAILABLE_INFORMATION (~0UL) -#define CK_EFFECTIVELY_INFINITE 0UL - - -typedef CK_BYTE CK_PTR CK_BYTE_PTR; -typedef CK_CHAR CK_PTR CK_CHAR_PTR; -typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; -typedef CK_ULONG CK_PTR CK_ULONG_PTR; -typedef void CK_PTR CK_VOID_PTR; - -/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ -typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; - - -/* The following value is always invalid if used as a session - * handle or object handle - */ -#define CK_INVALID_HANDLE 0UL - - -typedef struct CK_VERSION { - CK_BYTE major; /* integer portion of version number */ - CK_BYTE minor; /* 1/100ths portion of version number */ -} CK_VERSION; - -typedef CK_VERSION CK_PTR CK_VERSION_PTR; - - -typedef struct CK_INFO { - CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_FLAGS flags; /* must be zero */ - CK_UTF8CHAR libraryDescription[32]; /* blank padded */ - CK_VERSION libraryVersion; /* version of library */ -} CK_INFO; - -typedef CK_INFO CK_PTR CK_INFO_PTR; - - -/* CK_NOTIFICATION enumerates the types of notifications that - * Cryptoki provides to an application - */ -typedef CK_ULONG CK_NOTIFICATION; -#define CKN_SURRENDER 0UL -#define CKN_OTP_CHANGED 1UL - -typedef CK_ULONG CK_SLOT_ID; - -typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; - - -/* CK_SLOT_INFO provides information about a slot */ -typedef struct CK_SLOT_INFO { - CK_UTF8CHAR slotDescription[64]; /* blank padded */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_FLAGS flags; - - CK_VERSION hardwareVersion; /* version of hardware */ - CK_VERSION firmwareVersion; /* version of firmware */ -} CK_SLOT_INFO; - -/* flags: bit flags that provide capabilities of the slot - * Bit Flag Mask Meaning - */ -#define CKF_TOKEN_PRESENT 0x00000001UL /* a token is there */ -#define CKF_REMOVABLE_DEVICE 0x00000002UL /* removable devices*/ -#define CKF_HW_SLOT 0x00000004UL /* hardware slot */ - -typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; - - -/* CK_TOKEN_INFO provides information about a token */ -typedef struct CK_TOKEN_INFO { - CK_UTF8CHAR label[32]; /* blank padded */ - CK_UTF8CHAR manufacturerID[32]; /* blank padded */ - CK_UTF8CHAR model[16]; /* blank padded */ - CK_CHAR serialNumber[16]; /* blank padded */ - CK_FLAGS flags; /* see below */ - - CK_ULONG ulMaxSessionCount; /* max open sessions */ - CK_ULONG ulSessionCount; /* sess. now open */ - CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ - CK_ULONG ulRwSessionCount; /* R/W sess. now open */ - CK_ULONG ulMaxPinLen; /* in bytes */ - CK_ULONG ulMinPinLen; /* in bytes */ - CK_ULONG ulTotalPublicMemory; /* in bytes */ - CK_ULONG ulFreePublicMemory; /* in bytes */ - CK_ULONG ulTotalPrivateMemory; /* in bytes */ - CK_ULONG ulFreePrivateMemory; /* in bytes */ - CK_VERSION hardwareVersion; /* version of hardware */ - CK_VERSION firmwareVersion; /* version of firmware */ - CK_CHAR utcTime[16]; /* time */ -} CK_TOKEN_INFO; - -/* The flags parameter is defined as follows: - * Bit Flag Mask Meaning - */ -#define CKF_RNG 0x00000001UL /* has random # generator */ -#define CKF_WRITE_PROTECTED 0x00000002UL /* token is write-protected */ -#define CKF_LOGIN_REQUIRED 0x00000004UL /* user must login */ -#define CKF_USER_PIN_INITIALIZED 0x00000008UL /* normal user's PIN is set */ - -/* CKF_RESTORE_KEY_NOT_NEEDED. If it is set, - * that means that *every* time the state of cryptographic - * operations of a session is successfully saved, all keys - * needed to continue those operations are stored in the state - */ -#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020UL - -/* CKF_CLOCK_ON_TOKEN. If it is set, that means - * that the token has some sort of clock. The time on that - * clock is returned in the token info structure - */ -#define CKF_CLOCK_ON_TOKEN 0x00000040UL - -/* CKF_PROTECTED_AUTHENTICATION_PATH. If it is - * set, that means that there is some way for the user to login - * without sending a PIN through the Cryptoki library itself - */ -#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100UL - -/* CKF_DUAL_CRYPTO_OPERATIONS. If it is true, - * that means that a single session with the token can perform - * dual simultaneous cryptographic operations (digest and - * encrypt; decrypt and digest; sign and encrypt; and decrypt - * and sign) - */ -#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200UL - -/* CKF_TOKEN_INITIALIZED. If it is true, the - * token has been initialized using C_InitializeToken or an - * equivalent mechanism outside the scope of PKCS #11. - * Calling C_InitializeToken when this flag is set will cause - * the token to be reinitialized. - */ -#define CKF_TOKEN_INITIALIZED 0x00000400UL - -/* CKF_SECONDARY_AUTHENTICATION. If it is - * true, the token supports secondary authentication for - * private key objects. - */ -#define CKF_SECONDARY_AUTHENTICATION 0x00000800UL - -/* CKF_USER_PIN_COUNT_LOW. If it is true, an - * incorrect user login PIN has been entered at least once - * since the last successful authentication. - */ -#define CKF_USER_PIN_COUNT_LOW 0x00010000UL - -/* CKF_USER_PIN_FINAL_TRY. If it is true, - * supplying an incorrect user PIN will it to become locked. - */ -#define CKF_USER_PIN_FINAL_TRY 0x00020000UL - -/* CKF_USER_PIN_LOCKED. If it is true, the - * user PIN has been locked. User login to the token is not - * possible. - */ -#define CKF_USER_PIN_LOCKED 0x00040000UL - -/* CKF_USER_PIN_TO_BE_CHANGED. If it is true, - * the user PIN value is the default value set by token - * initialization or manufacturing, or the PIN has been - * expired by the card. - */ -#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000UL - -/* CKF_SO_PIN_COUNT_LOW. If it is true, an - * incorrect SO login PIN has been entered at least once since - * the last successful authentication. - */ -#define CKF_SO_PIN_COUNT_LOW 0x00100000UL - -/* CKF_SO_PIN_FINAL_TRY. If it is true, - * supplying an incorrect SO PIN will it to become locked. - */ -#define CKF_SO_PIN_FINAL_TRY 0x00200000UL - -/* CKF_SO_PIN_LOCKED. If it is true, the SO - * PIN has been locked. SO login to the token is not possible. - */ -#define CKF_SO_PIN_LOCKED 0x00400000UL - -/* CKF_SO_PIN_TO_BE_CHANGED. If it is true, - * the SO PIN value is the default value set by token - * initialization or manufacturing, or the PIN has been - * expired by the card. - */ -#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000UL - -#define CKF_ERROR_STATE 0x01000000UL - -typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; - - -/* CK_SESSION_HANDLE is a Cryptoki-assigned value that - * identifies a session - */ -typedef CK_ULONG CK_SESSION_HANDLE; - -typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; - - -/* CK_USER_TYPE enumerates the types of Cryptoki users */ -typedef CK_ULONG CK_USER_TYPE; -/* Security Officer */ -#define CKU_SO 0UL -/* Normal user */ -#define CKU_USER 1UL -/* Context specific */ -#define CKU_CONTEXT_SPECIFIC 2UL - -/* CK_STATE enumerates the session states */ -typedef CK_ULONG CK_STATE; -#define CKS_RO_PUBLIC_SESSION 0UL -#define CKS_RO_USER_FUNCTIONS 1UL -#define CKS_RW_PUBLIC_SESSION 2UL -#define CKS_RW_USER_FUNCTIONS 3UL -#define CKS_RW_SO_FUNCTIONS 4UL - -/* CK_SESSION_INFO provides information about a session */ -typedef struct CK_SESSION_INFO { - CK_SLOT_ID slotID; - CK_STATE state; - CK_FLAGS flags; /* see below */ - CK_ULONG ulDeviceError; /* device-dependent error code */ -} CK_SESSION_INFO; - -/* The flags are defined in the following table: - * Bit Flag Mask Meaning - */ -#define CKF_RW_SESSION 0x00000002UL /* session is r/w */ -#define CKF_SERIAL_SESSION 0x00000004UL /* no parallel */ - -typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; - - -/* CK_OBJECT_HANDLE is a token-specific identifier for an - * object - */ -typedef CK_ULONG CK_OBJECT_HANDLE; - -typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; - - -/* CK_OBJECT_CLASS is a value that identifies the classes (or - * types) of objects that Cryptoki recognizes. It is defined - * as follows: - */ -typedef CK_ULONG CK_OBJECT_CLASS; - -/* The following classes of objects are defined: */ -#define CKO_DATA 0x00000000UL -#define CKO_CERTIFICATE 0x00000001UL -#define CKO_PUBLIC_KEY 0x00000002UL -#define CKO_PRIVATE_KEY 0x00000003UL -#define CKO_SECRET_KEY 0x00000004UL -#define CKO_HW_FEATURE 0x00000005UL -#define CKO_DOMAIN_PARAMETERS 0x00000006UL -#define CKO_MECHANISM 0x00000007UL -#define CKO_OTP_KEY 0x00000008UL - -#define CKO_VENDOR_DEFINED 0x80000000UL - -typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; - -/* CK_HW_FEATURE_TYPE is a value that identifies the hardware feature type - * of an object with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. - */ -typedef CK_ULONG CK_HW_FEATURE_TYPE; - -/* The following hardware feature types are defined */ -#define CKH_MONOTONIC_COUNTER 0x00000001UL -#define CKH_CLOCK 0x00000002UL -#define CKH_USER_INTERFACE 0x00000003UL -#define CKH_VENDOR_DEFINED 0x80000000UL - -/* CK_KEY_TYPE is a value that identifies a key type */ -typedef CK_ULONG CK_KEY_TYPE; - -/* the following key types are defined: */ -#define CKK_RSA 0x00000000UL -#define CKK_DSA 0x00000001UL -#define CKK_DH 0x00000002UL -#define CKK_ECDSA 0x00000003UL /* Deprecated */ -#define CKK_EC 0x00000003UL -#define CKK_X9_42_DH 0x00000004UL -#define CKK_KEA 0x00000005UL -#define CKK_GENERIC_SECRET 0x00000010UL -#define CKK_RC2 0x00000011UL -#define CKK_RC4 0x00000012UL -#define CKK_DES 0x00000013UL -#define CKK_DES2 0x00000014UL -#define CKK_DES3 0x00000015UL -#define CKK_CAST 0x00000016UL -#define CKK_CAST3 0x00000017UL -#define CKK_CAST5 0x00000018UL /* Deprecated */ -#define CKK_CAST128 0x00000018UL -#define CKK_RC5 0x00000019UL -#define CKK_IDEA 0x0000001AUL -#define CKK_SKIPJACK 0x0000001BUL -#define CKK_BATON 0x0000001CUL -#define CKK_JUNIPER 0x0000001DUL -#define CKK_CDMF 0x0000001EUL -#define CKK_AES 0x0000001FUL -#define CKK_BLOWFISH 0x00000020UL -#define CKK_TWOFISH 0x00000021UL -#define CKK_SECURID 0x00000022UL -#define CKK_HOTP 0x00000023UL -#define CKK_ACTI 0x00000024UL -#define CKK_CAMELLIA 0x00000025UL -#define CKK_ARIA 0x00000026UL - -#define CKK_MD5_HMAC 0x00000027UL -#define CKK_SHA_1_HMAC 0x00000028UL -#define CKK_RIPEMD128_HMAC 0x00000029UL -#define CKK_RIPEMD160_HMAC 0x0000002AUL -#define CKK_SHA256_HMAC 0x0000002BUL -#define CKK_SHA384_HMAC 0x0000002CUL -#define CKK_SHA512_HMAC 0x0000002DUL -#define CKK_SHA224_HMAC 0x0000002EUL - -#define CKK_SEED 0x0000002FUL -#define CKK_GOSTR3410 0x00000030UL -#define CKK_GOSTR3411 0x00000031UL -#define CKK_GOST28147 0x00000032UL - - - -#define CKK_VENDOR_DEFINED 0x80000000UL - - -/* CK_CERTIFICATE_TYPE is a value that identifies a certificate - * type - */ -typedef CK_ULONG CK_CERTIFICATE_TYPE; - -#define CK_CERTIFICATE_CATEGORY_UNSPECIFIED 0UL -#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 1UL -#define CK_CERTIFICATE_CATEGORY_AUTHORITY 2UL -#define CK_CERTIFICATE_CATEGORY_OTHER_ENTITY 3UL - -#define CK_SECURITY_DOMAIN_UNSPECIFIED 0UL -#define CK_SECURITY_DOMAIN_MANUFACTURER 1UL -#define CK_SECURITY_DOMAIN_OPERATOR 2UL -#define CK_SECURITY_DOMAIN_THIRD_PARTY 3UL - - -/* The following certificate types are defined: */ -#define CKC_X_509 0x00000000UL -#define CKC_X_509_ATTR_CERT 0x00000001UL -#define CKC_WTLS 0x00000002UL -#define CKC_VENDOR_DEFINED 0x80000000UL -#define CKC_OPENPGP (CKC_VENDOR_DEFINED|0x00504750) - -/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute - * type - */ -typedef CK_ULONG CK_ATTRIBUTE_TYPE; - -/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which - * consists of an array of values. - */ -#define CKF_ARRAY_ATTRIBUTE 0x40000000UL - -/* The following OTP-related defines relate to the CKA_OTP_FORMAT attribute */ -#define CK_OTP_FORMAT_DECIMAL 0UL -#define CK_OTP_FORMAT_HEXADECIMAL 1UL -#define CK_OTP_FORMAT_ALPHANUMERIC 2UL -#define CK_OTP_FORMAT_BINARY 3UL - -/* The following OTP-related defines relate to the CKA_OTP_..._REQUIREMENT - * attributes - */ -#define CK_OTP_PARAM_IGNORED 0UL -#define CK_OTP_PARAM_OPTIONAL 1UL -#define CK_OTP_PARAM_MANDATORY 2UL - -/* The following attribute types are defined: */ -#define CKA_CLASS 0x00000000UL -#define CKA_TOKEN 0x00000001UL -#define CKA_PRIVATE 0x00000002UL -#define CKA_LABEL 0x00000003UL -#define CKA_APPLICATION 0x00000010UL -#define CKA_VALUE 0x00000011UL -#define CKA_OBJECT_ID 0x00000012UL -#define CKA_CERTIFICATE_TYPE 0x00000080UL -#define CKA_ISSUER 0x00000081UL -#define CKA_SERIAL_NUMBER 0x00000082UL -#define CKA_AC_ISSUER 0x00000083UL -#define CKA_OWNER 0x00000084UL -#define CKA_ATTR_TYPES 0x00000085UL -#define CKA_TRUSTED 0x00000086UL -#define CKA_CERTIFICATE_CATEGORY 0x00000087UL -#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088UL -#define CKA_URL 0x00000089UL -#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008AUL -#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008BUL -#define CKA_NAME_HASH_ALGORITHM 0x0000008CUL -#define CKA_CHECK_VALUE 0x00000090UL - -#define CKA_KEY_TYPE 0x00000100UL -#define CKA_SUBJECT 0x00000101UL -#define CKA_ID 0x00000102UL -#define CKA_SENSITIVE 0x00000103UL -#define CKA_ENCRYPT 0x00000104UL -#define CKA_DECRYPT 0x00000105UL -#define CKA_WRAP 0x00000106UL -#define CKA_UNWRAP 0x00000107UL -#define CKA_SIGN 0x00000108UL -#define CKA_SIGN_RECOVER 0x00000109UL -#define CKA_VERIFY 0x0000010AUL -#define CKA_VERIFY_RECOVER 0x0000010BUL -#define CKA_DERIVE 0x0000010CUL -#define CKA_START_DATE 0x00000110UL -#define CKA_END_DATE 0x00000111UL -#define CKA_MODULUS 0x00000120UL -#define CKA_MODULUS_BITS 0x00000121UL -#define CKA_PUBLIC_EXPONENT 0x00000122UL -#define CKA_PRIVATE_EXPONENT 0x00000123UL -#define CKA_PRIME_1 0x00000124UL -#define CKA_PRIME_2 0x00000125UL -#define CKA_EXPONENT_1 0x00000126UL -#define CKA_EXPONENT_2 0x00000127UL -#define CKA_COEFFICIENT 0x00000128UL -#define CKA_PUBLIC_KEY_INFO 0x00000129UL -#define CKA_PRIME 0x00000130UL -#define CKA_SUBPRIME 0x00000131UL -#define CKA_BASE 0x00000132UL - -#define CKA_PRIME_BITS 0x00000133UL -#define CKA_SUBPRIME_BITS 0x00000134UL -#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS - -#define CKA_VALUE_BITS 0x00000160UL -#define CKA_VALUE_LEN 0x00000161UL -#define CKA_EXTRACTABLE 0x00000162UL -#define CKA_LOCAL 0x00000163UL -#define CKA_NEVER_EXTRACTABLE 0x00000164UL -#define CKA_ALWAYS_SENSITIVE 0x00000165UL -#define CKA_KEY_GEN_MECHANISM 0x00000166UL - -#define CKA_MODIFIABLE 0x00000170UL -#define CKA_COPYABLE 0x00000171UL - -#define CKA_DESTROYABLE 0x00000172UL - -#define CKA_ECDSA_PARAMS 0x00000180UL /* Deprecated */ -#define CKA_EC_PARAMS 0x00000180UL - -#define CKA_EC_POINT 0x00000181UL - -#define CKA_SECONDARY_AUTH 0x00000200UL /* Deprecated */ -#define CKA_AUTH_PIN_FLAGS 0x00000201UL /* Deprecated */ - -#define CKA_ALWAYS_AUTHENTICATE 0x00000202UL - -#define CKA_WRAP_WITH_TRUSTED 0x00000210UL -#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211UL) -#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212UL) -#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213UL) - -#define CKA_OTP_FORMAT 0x00000220UL -#define CKA_OTP_LENGTH 0x00000221UL -#define CKA_OTP_TIME_INTERVAL 0x00000222UL -#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223UL -#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224UL -#define CKA_OTP_TIME_REQUIREMENT 0x00000225UL -#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226UL -#define CKA_OTP_PIN_REQUIREMENT 0x00000227UL -#define CKA_OTP_COUNTER 0x0000022EUL -#define CKA_OTP_TIME 0x0000022FUL -#define CKA_OTP_USER_IDENTIFIER 0x0000022AUL -#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022BUL -#define CKA_OTP_SERVICE_LOGO 0x0000022CUL -#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022DUL - -#define CKA_GOSTR3410_PARAMS 0x00000250UL -#define CKA_GOSTR3411_PARAMS 0x00000251UL -#define CKA_GOST28147_PARAMS 0x00000252UL - -#define CKA_HW_FEATURE_TYPE 0x00000300UL -#define CKA_RESET_ON_INIT 0x00000301UL -#define CKA_HAS_RESET 0x00000302UL - -#define CKA_PIXEL_X 0x00000400UL -#define CKA_PIXEL_Y 0x00000401UL -#define CKA_RESOLUTION 0x00000402UL -#define CKA_CHAR_ROWS 0x00000403UL -#define CKA_CHAR_COLUMNS 0x00000404UL -#define CKA_COLOR 0x00000405UL -#define CKA_BITS_PER_PIXEL 0x00000406UL -#define CKA_CHAR_SETS 0x00000480UL -#define CKA_ENCODING_METHODS 0x00000481UL -#define CKA_MIME_TYPES 0x00000482UL -#define CKA_MECHANISM_TYPE 0x00000500UL -#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501UL -#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502UL -#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503UL -#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600UL) - -#define CKA_VENDOR_DEFINED 0x80000000UL - -/* CK_ATTRIBUTE is a structure that includes the type, length - * and value of an attribute - */ -typedef struct CK_ATTRIBUTE { - CK_ATTRIBUTE_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; /* in bytes */ -} CK_ATTRIBUTE; - -typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; - -/* CK_DATE is a structure that defines a date */ -typedef struct CK_DATE{ - CK_CHAR year[4]; /* the year ("1900" - "9999") */ - CK_CHAR month[2]; /* the month ("01" - "12") */ - CK_CHAR day[2]; /* the day ("01" - "31") */ -} CK_DATE; - - -/* CK_MECHANISM_TYPE is a value that identifies a mechanism - * type - */ -typedef CK_ULONG CK_MECHANISM_TYPE; - -/* the following mechanism types are defined: */ -#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000UL -#define CKM_RSA_PKCS 0x00000001UL -#define CKM_RSA_9796 0x00000002UL -#define CKM_RSA_X_509 0x00000003UL - -#define CKM_MD2_RSA_PKCS 0x00000004UL -#define CKM_MD5_RSA_PKCS 0x00000005UL -#define CKM_SHA1_RSA_PKCS 0x00000006UL - -#define CKM_RIPEMD128_RSA_PKCS 0x00000007UL -#define CKM_RIPEMD160_RSA_PKCS 0x00000008UL -#define CKM_RSA_PKCS_OAEP 0x00000009UL - -#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000AUL -#define CKM_RSA_X9_31 0x0000000BUL -#define CKM_SHA1_RSA_X9_31 0x0000000CUL -#define CKM_RSA_PKCS_PSS 0x0000000DUL -#define CKM_SHA1_RSA_PKCS_PSS 0x0000000EUL - -#define CKM_DSA_KEY_PAIR_GEN 0x00000010UL -#define CKM_DSA 0x00000011UL -#define CKM_DSA_SHA1 0x00000012UL -#define CKM_DSA_SHA224 0x00000013UL -#define CKM_DSA_SHA256 0x00000014UL -#define CKM_DSA_SHA384 0x00000015UL -#define CKM_DSA_SHA512 0x00000016UL - -#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020UL -#define CKM_DH_PKCS_DERIVE 0x00000021UL - -#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030UL -#define CKM_X9_42_DH_DERIVE 0x00000031UL -#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032UL -#define CKM_X9_42_MQV_DERIVE 0x00000033UL - -#define CKM_SHA256_RSA_PKCS 0x00000040UL -#define CKM_SHA384_RSA_PKCS 0x00000041UL -#define CKM_SHA512_RSA_PKCS 0x00000042UL -#define CKM_SHA256_RSA_PKCS_PSS 0x00000043UL -#define CKM_SHA384_RSA_PKCS_PSS 0x00000044UL -#define CKM_SHA512_RSA_PKCS_PSS 0x00000045UL - -#define CKM_SHA224_RSA_PKCS 0x00000046UL -#define CKM_SHA224_RSA_PKCS_PSS 0x00000047UL - -#define CKM_SHA512_224 0x00000048UL -#define CKM_SHA512_224_HMAC 0x00000049UL -#define CKM_SHA512_224_HMAC_GENERAL 0x0000004AUL -#define CKM_SHA512_224_KEY_DERIVATION 0x0000004BUL -#define CKM_SHA512_256 0x0000004CUL -#define CKM_SHA512_256_HMAC 0x0000004DUL -#define CKM_SHA512_256_HMAC_GENERAL 0x0000004EUL -#define CKM_SHA512_256_KEY_DERIVATION 0x0000004FUL - -#define CKM_SHA512_T 0x00000050UL -#define CKM_SHA512_T_HMAC 0x00000051UL -#define CKM_SHA512_T_HMAC_GENERAL 0x00000052UL -#define CKM_SHA512_T_KEY_DERIVATION 0x00000053UL - -#define CKM_RC2_KEY_GEN 0x00000100UL -#define CKM_RC2_ECB 0x00000101UL -#define CKM_RC2_CBC 0x00000102UL -#define CKM_RC2_MAC 0x00000103UL - -#define CKM_RC2_MAC_GENERAL 0x00000104UL -#define CKM_RC2_CBC_PAD 0x00000105UL - -#define CKM_RC4_KEY_GEN 0x00000110UL -#define CKM_RC4 0x00000111UL -#define CKM_DES_KEY_GEN 0x00000120UL -#define CKM_DES_ECB 0x00000121UL -#define CKM_DES_CBC 0x00000122UL -#define CKM_DES_MAC 0x00000123UL - -#define CKM_DES_MAC_GENERAL 0x00000124UL -#define CKM_DES_CBC_PAD 0x00000125UL - -#define CKM_DES2_KEY_GEN 0x00000130UL -#define CKM_DES3_KEY_GEN 0x00000131UL -#define CKM_DES3_ECB 0x00000132UL -#define CKM_DES3_CBC 0x00000133UL -#define CKM_DES3_MAC 0x00000134UL - -#define CKM_DES3_MAC_GENERAL 0x00000135UL -#define CKM_DES3_CBC_PAD 0x00000136UL -#define CKM_DES3_CMAC_GENERAL 0x00000137UL -#define CKM_DES3_CMAC 0x00000138UL -#define CKM_CDMF_KEY_GEN 0x00000140UL -#define CKM_CDMF_ECB 0x00000141UL -#define CKM_CDMF_CBC 0x00000142UL -#define CKM_CDMF_MAC 0x00000143UL -#define CKM_CDMF_MAC_GENERAL 0x00000144UL -#define CKM_CDMF_CBC_PAD 0x00000145UL - -#define CKM_DES_OFB64 0x00000150UL -#define CKM_DES_OFB8 0x00000151UL -#define CKM_DES_CFB64 0x00000152UL -#define CKM_DES_CFB8 0x00000153UL - -#define CKM_MD2 0x00000200UL - -#define CKM_MD2_HMAC 0x00000201UL -#define CKM_MD2_HMAC_GENERAL 0x00000202UL - -#define CKM_MD5 0x00000210UL - -#define CKM_MD5_HMAC 0x00000211UL -#define CKM_MD5_HMAC_GENERAL 0x00000212UL - -#define CKM_SHA_1 0x00000220UL - -#define CKM_SHA_1_HMAC 0x00000221UL -#define CKM_SHA_1_HMAC_GENERAL 0x00000222UL - -#define CKM_RIPEMD128 0x00000230UL -#define CKM_RIPEMD128_HMAC 0x00000231UL -#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232UL -#define CKM_RIPEMD160 0x00000240UL -#define CKM_RIPEMD160_HMAC 0x00000241UL -#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242UL - -#define CKM_SHA256 0x00000250UL -#define CKM_SHA256_HMAC 0x00000251UL -#define CKM_SHA256_HMAC_GENERAL 0x00000252UL -#define CKM_SHA224 0x00000255UL -#define CKM_SHA224_HMAC 0x00000256UL -#define CKM_SHA224_HMAC_GENERAL 0x00000257UL -#define CKM_SHA384 0x00000260UL -#define CKM_SHA384_HMAC 0x00000261UL -#define CKM_SHA384_HMAC_GENERAL 0x00000262UL -#define CKM_SHA512 0x00000270UL -#define CKM_SHA512_HMAC 0x00000271UL -#define CKM_SHA512_HMAC_GENERAL 0x00000272UL -#define CKM_SECURID_KEY_GEN 0x00000280UL -#define CKM_SECURID 0x00000282UL -#define CKM_HOTP_KEY_GEN 0x00000290UL -#define CKM_HOTP 0x00000291UL -#define CKM_ACTI 0x000002A0UL -#define CKM_ACTI_KEY_GEN 0x000002A1UL - -#define CKM_CAST_KEY_GEN 0x00000300UL -#define CKM_CAST_ECB 0x00000301UL -#define CKM_CAST_CBC 0x00000302UL -#define CKM_CAST_MAC 0x00000303UL -#define CKM_CAST_MAC_GENERAL 0x00000304UL -#define CKM_CAST_CBC_PAD 0x00000305UL -#define CKM_CAST3_KEY_GEN 0x00000310UL -#define CKM_CAST3_ECB 0x00000311UL -#define CKM_CAST3_CBC 0x00000312UL -#define CKM_CAST3_MAC 0x00000313UL -#define CKM_CAST3_MAC_GENERAL 0x00000314UL -#define CKM_CAST3_CBC_PAD 0x00000315UL -/* Note that CAST128 and CAST5 are the same algorithm */ -#define CKM_CAST5_KEY_GEN 0x00000320UL -#define CKM_CAST128_KEY_GEN 0x00000320UL -#define CKM_CAST5_ECB 0x00000321UL -#define CKM_CAST128_ECB 0x00000321UL -#define CKM_CAST5_CBC 0x00000322UL /* Deprecated */ -#define CKM_CAST128_CBC 0x00000322UL -#define CKM_CAST5_MAC 0x00000323UL /* Deprecated */ -#define CKM_CAST128_MAC 0x00000323UL -#define CKM_CAST5_MAC_GENERAL 0x00000324UL /* Deprecated */ -#define CKM_CAST128_MAC_GENERAL 0x00000324UL -#define CKM_CAST5_CBC_PAD 0x00000325UL /* Deprecated */ -#define CKM_CAST128_CBC_PAD 0x00000325UL -#define CKM_RC5_KEY_GEN 0x00000330UL -#define CKM_RC5_ECB 0x00000331UL -#define CKM_RC5_CBC 0x00000332UL -#define CKM_RC5_MAC 0x00000333UL -#define CKM_RC5_MAC_GENERAL 0x00000334UL -#define CKM_RC5_CBC_PAD 0x00000335UL -#define CKM_IDEA_KEY_GEN 0x00000340UL -#define CKM_IDEA_ECB 0x00000341UL -#define CKM_IDEA_CBC 0x00000342UL -#define CKM_IDEA_MAC 0x00000343UL -#define CKM_IDEA_MAC_GENERAL 0x00000344UL -#define CKM_IDEA_CBC_PAD 0x00000345UL -#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350UL -#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360UL -#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362UL -#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363UL -#define CKM_XOR_BASE_AND_DATA 0x00000364UL -#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365UL -#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370UL -#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371UL -#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372UL - -#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373UL -#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374UL -#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375UL -#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376UL -#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377UL - -#define CKM_TLS_PRF 0x00000378UL - -#define CKM_SSL3_MD5_MAC 0x00000380UL -#define CKM_SSL3_SHA1_MAC 0x00000381UL -#define CKM_MD5_KEY_DERIVATION 0x00000390UL -#define CKM_MD2_KEY_DERIVATION 0x00000391UL -#define CKM_SHA1_KEY_DERIVATION 0x00000392UL - -#define CKM_SHA256_KEY_DERIVATION 0x00000393UL -#define CKM_SHA384_KEY_DERIVATION 0x00000394UL -#define CKM_SHA512_KEY_DERIVATION 0x00000395UL -#define CKM_SHA224_KEY_DERIVATION 0x00000396UL - -#define CKM_PBE_MD2_DES_CBC 0x000003A0UL -#define CKM_PBE_MD5_DES_CBC 0x000003A1UL -#define CKM_PBE_MD5_CAST_CBC 0x000003A2UL -#define CKM_PBE_MD5_CAST3_CBC 0x000003A3UL -#define CKM_PBE_MD5_CAST5_CBC 0x000003A4UL /* Deprecated */ -#define CKM_PBE_MD5_CAST128_CBC 0x000003A4UL -#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5UL /* Deprecated */ -#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5UL -#define CKM_PBE_SHA1_RC4_128 0x000003A6UL -#define CKM_PBE_SHA1_RC4_40 0x000003A7UL -#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8UL -#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9UL -#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AAUL -#define CKM_PBE_SHA1_RC2_40_CBC 0x000003ABUL - -#define CKM_PKCS5_PBKD2 0x000003B0UL - -#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0UL - -#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0UL -#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1UL -#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2UL -#define CKM_WTLS_PRF 0x000003D3UL -#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4UL -#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5UL - -#define CKM_TLS10_MAC_SERVER 0x000003D6UL -#define CKM_TLS10_MAC_CLIENT 0x000003D7UL -#define CKM_TLS12_MAC 0x000003D8UL -#define CKM_TLS12_KDF 0x000003D9UL -#define CKM_TLS12_MASTER_KEY_DERIVE 0x000003E0UL -#define CKM_TLS12_KEY_AND_MAC_DERIVE 0x000003E1UL -#define CKM_TLS12_MASTER_KEY_DERIVE_DH 0x000003E2UL -#define CKM_TLS12_KEY_SAFE_DERIVE 0x000003E3UL -#define CKM_TLS_MAC 0x000003E4UL -#define CKM_TLS_KDF 0x000003E5UL - -#define CKM_KEY_WRAP_LYNKS 0x00000400UL -#define CKM_KEY_WRAP_SET_OAEP 0x00000401UL - -#define CKM_CMS_SIG 0x00000500UL -#define CKM_KIP_DERIVE 0x00000510UL -#define CKM_KIP_WRAP 0x00000511UL -#define CKM_KIP_MAC 0x00000512UL - -#define CKM_CAMELLIA_KEY_GEN 0x00000550UL -#define CKM_CAMELLIA_ECB 0x00000551UL -#define CKM_CAMELLIA_CBC 0x00000552UL -#define CKM_CAMELLIA_MAC 0x00000553UL -#define CKM_CAMELLIA_MAC_GENERAL 0x00000554UL -#define CKM_CAMELLIA_CBC_PAD 0x00000555UL -#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556UL -#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557UL -#define CKM_CAMELLIA_CTR 0x00000558UL - -#define CKM_ARIA_KEY_GEN 0x00000560UL -#define CKM_ARIA_ECB 0x00000561UL -#define CKM_ARIA_CBC 0x00000562UL -#define CKM_ARIA_MAC 0x00000563UL -#define CKM_ARIA_MAC_GENERAL 0x00000564UL -#define CKM_ARIA_CBC_PAD 0x00000565UL -#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566UL -#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567UL - -#define CKM_SEED_KEY_GEN 0x00000650UL -#define CKM_SEED_ECB 0x00000651UL -#define CKM_SEED_CBC 0x00000652UL -#define CKM_SEED_MAC 0x00000653UL -#define CKM_SEED_MAC_GENERAL 0x00000654UL -#define CKM_SEED_CBC_PAD 0x00000655UL -#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656UL -#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657UL - -#define CKM_SKIPJACK_KEY_GEN 0x00001000UL -#define CKM_SKIPJACK_ECB64 0x00001001UL -#define CKM_SKIPJACK_CBC64 0x00001002UL -#define CKM_SKIPJACK_OFB64 0x00001003UL -#define CKM_SKIPJACK_CFB64 0x00001004UL -#define CKM_SKIPJACK_CFB32 0x00001005UL -#define CKM_SKIPJACK_CFB16 0x00001006UL -#define CKM_SKIPJACK_CFB8 0x00001007UL -#define CKM_SKIPJACK_WRAP 0x00001008UL -#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009UL -#define CKM_SKIPJACK_RELAYX 0x0000100aUL -#define CKM_KEA_KEY_PAIR_GEN 0x00001010UL -#define CKM_KEA_KEY_DERIVE 0x00001011UL -#define CKM_KEA_DERIVE 0x00001012UL -#define CKM_FORTEZZA_TIMESTAMP 0x00001020UL -#define CKM_BATON_KEY_GEN 0x00001030UL -#define CKM_BATON_ECB128 0x00001031UL -#define CKM_BATON_ECB96 0x00001032UL -#define CKM_BATON_CBC128 0x00001033UL -#define CKM_BATON_COUNTER 0x00001034UL -#define CKM_BATON_SHUFFLE 0x00001035UL -#define CKM_BATON_WRAP 0x00001036UL - -#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040UL /* Deprecated */ -#define CKM_EC_KEY_PAIR_GEN 0x00001040UL - -#define CKM_ECDSA 0x00001041UL -#define CKM_ECDSA_SHA1 0x00001042UL -#define CKM_ECDSA_SHA224 0x00001043UL -#define CKM_ECDSA_SHA256 0x00001044UL -#define CKM_ECDSA_SHA384 0x00001045UL -#define CKM_ECDSA_SHA512 0x00001046UL - -#define CKM_ECDH1_DERIVE 0x00001050UL -#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051UL -#define CKM_ECMQV_DERIVE 0x00001052UL - -#define CKM_ECDH_AES_KEY_WRAP 0x00001053UL -#define CKM_RSA_AES_KEY_WRAP 0x00001054UL - -#define CKM_JUNIPER_KEY_GEN 0x00001060UL -#define CKM_JUNIPER_ECB128 0x00001061UL -#define CKM_JUNIPER_CBC128 0x00001062UL -#define CKM_JUNIPER_COUNTER 0x00001063UL -#define CKM_JUNIPER_SHUFFLE 0x00001064UL -#define CKM_JUNIPER_WRAP 0x00001065UL -#define CKM_FASTHASH 0x00001070UL - -#define CKM_AES_KEY_GEN 0x00001080UL -#define CKM_AES_ECB 0x00001081UL -#define CKM_AES_CBC 0x00001082UL -#define CKM_AES_MAC 0x00001083UL -#define CKM_AES_MAC_GENERAL 0x00001084UL -#define CKM_AES_CBC_PAD 0x00001085UL -#define CKM_AES_CTR 0x00001086UL -#define CKM_AES_GCM 0x00001087UL -#define CKM_AES_CCM 0x00001088UL -#define CKM_AES_CTS 0x00001089UL -#define CKM_AES_CMAC 0x0000108AUL -#define CKM_AES_CMAC_GENERAL 0x0000108BUL - -#define CKM_AES_XCBC_MAC 0x0000108CUL -#define CKM_AES_XCBC_MAC_96 0x0000108DUL -#define CKM_AES_GMAC 0x0000108EUL - -#define CKM_BLOWFISH_KEY_GEN 0x00001090UL -#define CKM_BLOWFISH_CBC 0x00001091UL -#define CKM_TWOFISH_KEY_GEN 0x00001092UL -#define CKM_TWOFISH_CBC 0x00001093UL -#define CKM_BLOWFISH_CBC_PAD 0x00001094UL -#define CKM_TWOFISH_CBC_PAD 0x00001095UL - -#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100UL -#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101UL -#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102UL -#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103UL -#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104UL -#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105UL - -#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200UL -#define CKM_GOSTR3410 0x00001201UL -#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202UL -#define CKM_GOSTR3410_KEY_WRAP 0x00001203UL -#define CKM_GOSTR3410_DERIVE 0x00001204UL -#define CKM_GOSTR3411 0x00001210UL -#define CKM_GOSTR3411_HMAC 0x00001211UL -#define CKM_GOST28147_KEY_GEN 0x00001220UL -#define CKM_GOST28147_ECB 0x00001221UL -#define CKM_GOST28147 0x00001222UL -#define CKM_GOST28147_MAC 0x00001223UL -#define CKM_GOST28147_KEY_WRAP 0x00001224UL - -#define CKM_DSA_PARAMETER_GEN 0x00002000UL -#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001UL -#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002UL -#define CKM_DSA_PROBABLISTIC_PARAMETER_GEN 0x00002003UL -#define CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN 0x00002004UL - -#define CKM_AES_OFB 0x00002104UL -#define CKM_AES_CFB64 0x00002105UL -#define CKM_AES_CFB8 0x00002106UL -#define CKM_AES_CFB128 0x00002107UL - -#define CKM_AES_CFB1 0x00002108UL -#define CKM_AES_KEY_WRAP 0x00002109UL /* WAS: 0x00001090 */ -#define CKM_AES_KEY_WRAP_PAD 0x0000210AUL /* WAS: 0x00001091 */ - -#define CKM_RSA_PKCS_TPM_1_1 0x00004001UL -#define CKM_RSA_PKCS_OAEP_TPM_1_1 0x00004002UL - -#define CKM_VENDOR_DEFINED 0x80000000UL - -typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; - - -/* CK_MECHANISM is a structure that specifies a particular - * mechanism - */ -typedef struct CK_MECHANISM { - CK_MECHANISM_TYPE mechanism; - CK_VOID_PTR pParameter; - CK_ULONG ulParameterLen; /* in bytes */ -} CK_MECHANISM; - -typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; - - -/* CK_MECHANISM_INFO provides information about a particular - * mechanism - */ -typedef struct CK_MECHANISM_INFO { - CK_ULONG ulMinKeySize; - CK_ULONG ulMaxKeySize; - CK_FLAGS flags; -} CK_MECHANISM_INFO; - -/* The flags are defined as follows: - * Bit Flag Mask Meaning */ -#define CKF_HW 0x00000001UL /* performed by HW */ - -/* Specify whether or not a mechanism can be used for a particular task */ -#define CKF_ENCRYPT 0x00000100UL -#define CKF_DECRYPT 0x00000200UL -#define CKF_DIGEST 0x00000400UL -#define CKF_SIGN 0x00000800UL -#define CKF_SIGN_RECOVER 0x00001000UL -#define CKF_VERIFY 0x00002000UL -#define CKF_VERIFY_RECOVER 0x00004000UL -#define CKF_GENERATE 0x00008000UL -#define CKF_GENERATE_KEY_PAIR 0x00010000UL -#define CKF_WRAP 0x00020000UL -#define CKF_UNWRAP 0x00040000UL -#define CKF_DERIVE 0x00080000UL - -/* Describe a token's EC capabilities not available in mechanism - * information. - */ -#define CKF_EC_F_P 0x00100000UL -#define CKF_EC_F_2M 0x00200000UL -#define CKF_EC_ECPARAMETERS 0x00400000UL -#define CKF_EC_NAMEDCURVE 0x00800000UL -#define CKF_EC_UNCOMPRESS 0x01000000UL -#define CKF_EC_COMPRESS 0x02000000UL - -#define CKF_EXTENSION 0x80000000UL - -typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; - -/* CK_RV is a value that identifies the return value of a - * Cryptoki function - */ -typedef CK_ULONG CK_RV; - -#define CKR_OK 0x00000000UL -#define CKR_CANCEL 0x00000001UL -#define CKR_HOST_MEMORY 0x00000002UL -#define CKR_SLOT_ID_INVALID 0x00000003UL - -#define CKR_GENERAL_ERROR 0x00000005UL -#define CKR_FUNCTION_FAILED 0x00000006UL - -#define CKR_ARGUMENTS_BAD 0x00000007UL -#define CKR_NO_EVENT 0x00000008UL -#define CKR_NEED_TO_CREATE_THREADS 0x00000009UL -#define CKR_CANT_LOCK 0x0000000AUL - -#define CKR_ATTRIBUTE_READ_ONLY 0x00000010UL -#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL -#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL -#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL - -#define CKR_ACTION_PROHIBITED 0x0000001BUL - -#define CKR_DATA_INVALID 0x00000020UL -#define CKR_DATA_LEN_RANGE 0x00000021UL -#define CKR_DEVICE_ERROR 0x00000030UL -#define CKR_DEVICE_MEMORY 0x00000031UL -#define CKR_DEVICE_REMOVED 0x00000032UL -#define CKR_ENCRYPTED_DATA_INVALID 0x00000040UL -#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041UL -#define CKR_FUNCTION_CANCELED 0x00000050UL -#define CKR_FUNCTION_NOT_PARALLEL 0x00000051UL - -#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054UL - -#define CKR_KEY_HANDLE_INVALID 0x00000060UL - -#define CKR_KEY_SIZE_RANGE 0x00000062UL -#define CKR_KEY_TYPE_INCONSISTENT 0x00000063UL - -#define CKR_KEY_NOT_NEEDED 0x00000064UL -#define CKR_KEY_CHANGED 0x00000065UL -#define CKR_KEY_NEEDED 0x00000066UL -#define CKR_KEY_INDIGESTIBLE 0x00000067UL -#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068UL -#define CKR_KEY_NOT_WRAPPABLE 0x00000069UL -#define CKR_KEY_UNEXTRACTABLE 0x0000006AUL - -#define CKR_MECHANISM_INVALID 0x00000070UL -#define CKR_MECHANISM_PARAM_INVALID 0x00000071UL - -#define CKR_OBJECT_HANDLE_INVALID 0x00000082UL -#define CKR_OPERATION_ACTIVE 0x00000090UL -#define CKR_OPERATION_NOT_INITIALIZED 0x00000091UL -#define CKR_PIN_INCORRECT 0x000000A0UL -#define CKR_PIN_INVALID 0x000000A1UL -#define CKR_PIN_LEN_RANGE 0x000000A2UL - -#define CKR_PIN_EXPIRED 0x000000A3UL -#define CKR_PIN_LOCKED 0x000000A4UL - -#define CKR_SESSION_CLOSED 0x000000B0UL -#define CKR_SESSION_COUNT 0x000000B1UL -#define CKR_SESSION_HANDLE_INVALID 0x000000B3UL -#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4UL -#define CKR_SESSION_READ_ONLY 0x000000B5UL -#define CKR_SESSION_EXISTS 0x000000B6UL - -#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7UL -#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8UL - -#define CKR_SIGNATURE_INVALID 0x000000C0UL -#define CKR_SIGNATURE_LEN_RANGE 0x000000C1UL -#define CKR_TEMPLATE_INCOMPLETE 0x000000D0UL -#define CKR_TEMPLATE_INCONSISTENT 0x000000D1UL -#define CKR_TOKEN_NOT_PRESENT 0x000000E0UL -#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1UL -#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2UL -#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0UL -#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1UL -#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2UL -#define CKR_USER_ALREADY_LOGGED_IN 0x00000100UL -#define CKR_USER_NOT_LOGGED_IN 0x00000101UL -#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102UL -#define CKR_USER_TYPE_INVALID 0x00000103UL - -#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104UL -#define CKR_USER_TOO_MANY_TYPES 0x00000105UL - -#define CKR_WRAPPED_KEY_INVALID 0x00000110UL -#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112UL -#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113UL -#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114UL -#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115UL -#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120UL - -#define CKR_RANDOM_NO_RNG 0x00000121UL - -#define CKR_DOMAIN_PARAMS_INVALID 0x00000130UL - -#define CKR_CURVE_NOT_SUPPORTED 0x00000140UL - -#define CKR_BUFFER_TOO_SMALL 0x00000150UL -#define CKR_SAVED_STATE_INVALID 0x00000160UL -#define CKR_INFORMATION_SENSITIVE 0x00000170UL -#define CKR_STATE_UNSAVEABLE 0x00000180UL - -#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190UL -#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191UL -#define CKR_MUTEX_BAD 0x000001A0UL -#define CKR_MUTEX_NOT_LOCKED 0x000001A1UL - -#define CKR_NEW_PIN_MODE 0x000001B0UL -#define CKR_NEXT_OTP 0x000001B1UL - -#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5UL -#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6UL -#define CKR_LIBRARY_LOAD_FAILED 0x000001B7UL -#define CKR_PIN_TOO_WEAK 0x000001B8UL -#define CKR_PUBLIC_KEY_INVALID 0x000001B9UL - -#define CKR_FUNCTION_REJECTED 0x00000200UL - -#define CKR_VENDOR_DEFINED 0x80000000UL - - -/* CK_NOTIFY is an application callback that processes events */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_NOTIFICATION event, - CK_VOID_PTR pApplication /* passed to C_OpenSession */ -); - - -/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec - * version and pointers of appropriate types to all the - * Cryptoki functions - */ -typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; - -typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; - -typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; - - -/* CK_CREATEMUTEX is an application callback for creating a - * mutex object - */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( - CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ -); - - -/* CK_DESTROYMUTEX is an application callback for destroying a - * mutex object - */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ -); - - -/* CK_LOCKMUTEX is an application callback for locking a mutex */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ -); - - -/* CK_UNLOCKMUTEX is an application callback for unlocking a - * mutex - */ -typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( - CK_VOID_PTR pMutex /* pointer to mutex */ -); - - -/* CK_C_INITIALIZE_ARGS provides the optional arguments to - * C_Initialize - */ -typedef struct CK_C_INITIALIZE_ARGS { - CK_CREATEMUTEX CreateMutex; - CK_DESTROYMUTEX DestroyMutex; - CK_LOCKMUTEX LockMutex; - CK_UNLOCKMUTEX UnlockMutex; - CK_FLAGS flags; - CK_VOID_PTR pReserved; -} CK_C_INITIALIZE_ARGS; - -/* flags: bit flags that provide capabilities of the slot - * Bit Flag Mask Meaning - */ -#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001UL -#define CKF_OS_LOCKING_OK 0x00000002UL - -typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; - - -/* additional flags for parameters to functions */ - -/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ -#define CKF_DONT_BLOCK 1 - -/* CK_RSA_PKCS_MGF_TYPE is used to indicate the Message - * Generation Function (MGF) applied to a message block when - * formatting a message block for the PKCS #1 OAEP encryption - * scheme. - */ -typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; - -typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; - -/* The following MGFs are defined */ -#define CKG_MGF1_SHA1 0x00000001UL -#define CKG_MGF1_SHA256 0x00000002UL -#define CKG_MGF1_SHA384 0x00000003UL -#define CKG_MGF1_SHA512 0x00000004UL -#define CKG_MGF1_SHA224 0x00000005UL - -/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source - * of the encoding parameter when formatting a message block - * for the PKCS #1 OAEP encryption scheme. - */ -typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; - -typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; - -/* The following encoding parameter sources are defined */ -#define CKZ_DATA_SPECIFIED 0x00000001UL - -/* CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the - * CKM_RSA_PKCS_OAEP mechanism. - */ -typedef struct CK_RSA_PKCS_OAEP_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_RSA_PKCS_OAEP_SOURCE_TYPE source; - CK_VOID_PTR pSourceData; - CK_ULONG ulSourceDataLen; -} CK_RSA_PKCS_OAEP_PARAMS; - -typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; - -/* CK_RSA_PKCS_PSS_PARAMS provides the parameters to the - * CKM_RSA_PKCS_PSS mechanism(s). - */ -typedef struct CK_RSA_PKCS_PSS_PARAMS { - CK_MECHANISM_TYPE hashAlg; - CK_RSA_PKCS_MGF_TYPE mgf; - CK_ULONG sLen; -} CK_RSA_PKCS_PSS_PARAMS; - -typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; - -typedef CK_ULONG CK_EC_KDF_TYPE; - -/* The following EC Key Derivation Functions are defined */ -#define CKD_NULL 0x00000001UL -#define CKD_SHA1_KDF 0x00000002UL - -/* The following X9.42 DH key derivation functions are defined */ -#define CKD_SHA1_KDF_ASN1 0x00000003UL -#define CKD_SHA1_KDF_CONCATENATE 0x00000004UL -#define CKD_SHA224_KDF 0x00000005UL -#define CKD_SHA256_KDF 0x00000006UL -#define CKD_SHA384_KDF 0x00000007UL -#define CKD_SHA512_KDF 0x00000008UL -#define CKD_CPDIVERSIFY_KDF 0x00000009UL - - -/* CK_ECDH1_DERIVE_PARAMS provides the parameters to the - * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, - * where each party contributes one key pair. - */ -typedef struct CK_ECDH1_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -} CK_ECDH1_DERIVE_PARAMS; - -typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; - -/* - * CK_ECDH2_DERIVE_PARAMS provides the parameters to the - * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. - */ -typedef struct CK_ECDH2_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; -} CK_ECDH2_DERIVE_PARAMS; - -typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; - -typedef struct CK_ECMQV_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; -} CK_ECMQV_DERIVE_PARAMS; - -typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; - -/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the - * CKM_X9_42_DH_PARAMETER_GEN mechanisms - */ -typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; -typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; - -/* CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the - * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party - * contributes one key pair - */ -typedef struct CK_X9_42_DH1_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -} CK_X9_42_DH1_DERIVE_PARAMS; - -typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; - -/* CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the - * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation - * mechanisms, where each party contributes two key pairs - */ -typedef struct CK_X9_42_DH2_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; -} CK_X9_42_DH2_DERIVE_PARAMS; - -typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; - -typedef struct CK_X9_42_MQV_DERIVE_PARAMS { - CK_X9_42_DH_KDF_TYPE kdf; - CK_ULONG ulOtherInfoLen; - CK_BYTE_PTR pOtherInfo; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPrivateDataLen; - CK_OBJECT_HANDLE hPrivateData; - CK_ULONG ulPublicDataLen2; - CK_BYTE_PTR pPublicData2; - CK_OBJECT_HANDLE publicKey; -} CK_X9_42_MQV_DERIVE_PARAMS; - -typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; - -/* CK_KEA_DERIVE_PARAMS provides the parameters to the - * CKM_KEA_DERIVE mechanism - */ -typedef struct CK_KEA_DERIVE_PARAMS { - CK_BBOOL isSender; - CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pRandomB; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; -} CK_KEA_DERIVE_PARAMS; - -typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; - - -/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and - * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just - * holds the effective keysize - */ -typedef CK_ULONG CK_RC2_PARAMS; - -typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; - - -/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC - * mechanism - */ -typedef struct CK_RC2_CBC_PARAMS { - CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ - CK_BYTE iv[8]; /* IV for CBC mode */ -} CK_RC2_CBC_PARAMS; - -typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; - - -/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the - * CKM_RC2_MAC_GENERAL mechanism - */ -typedef struct CK_RC2_MAC_GENERAL_PARAMS { - CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ - CK_ULONG ulMacLength; /* Length of MAC in bytes */ -} CK_RC2_MAC_GENERAL_PARAMS; - -typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ - CK_RC2_MAC_GENERAL_PARAMS_PTR; - - -/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and - * CKM_RC5_MAC mechanisms - */ -typedef struct CK_RC5_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ -} CK_RC5_PARAMS; - -typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; - - -/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC - * mechanism - */ -typedef struct CK_RC5_CBC_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ - CK_BYTE_PTR pIv; /* pointer to IV */ - CK_ULONG ulIvLen; /* length of IV in bytes */ -} CK_RC5_CBC_PARAMS; - -typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; - - -/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the - * CKM_RC5_MAC_GENERAL mechanism - */ -typedef struct CK_RC5_MAC_GENERAL_PARAMS { - CK_ULONG ulWordsize; /* wordsize in bits */ - CK_ULONG ulRounds; /* number of rounds */ - CK_ULONG ulMacLength; /* Length of MAC in bytes */ -} CK_RC5_MAC_GENERAL_PARAMS; - -typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ - CK_RC5_MAC_GENERAL_PARAMS_PTR; - -/* CK_MAC_GENERAL_PARAMS provides the parameters to most block - * ciphers' MAC_GENERAL mechanisms. Its value is the length of - * the MAC - */ -typedef CK_ULONG CK_MAC_GENERAL_PARAMS; - -typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; - -typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[8]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_DES_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; - -typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_AES_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; - -/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the - * CKM_SKIPJACK_PRIVATE_WRAP mechanism - */ -typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { - CK_ULONG ulPasswordLen; - CK_BYTE_PTR pPassword; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPAndGLen; - CK_ULONG ulQLen; - CK_ULONG ulRandomLen; - CK_BYTE_PTR pRandomA; - CK_BYTE_PTR pPrimeP; - CK_BYTE_PTR pBaseG; - CK_BYTE_PTR pSubprimeQ; -} CK_SKIPJACK_PRIVATE_WRAP_PARAMS; - -typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ - CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR; - - -/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the - * CKM_SKIPJACK_RELAYX mechanism - */ -typedef struct CK_SKIPJACK_RELAYX_PARAMS { - CK_ULONG ulOldWrappedXLen; - CK_BYTE_PTR pOldWrappedX; - CK_ULONG ulOldPasswordLen; - CK_BYTE_PTR pOldPassword; - CK_ULONG ulOldPublicDataLen; - CK_BYTE_PTR pOldPublicData; - CK_ULONG ulOldRandomLen; - CK_BYTE_PTR pOldRandomA; - CK_ULONG ulNewPasswordLen; - CK_BYTE_PTR pNewPassword; - CK_ULONG ulNewPublicDataLen; - CK_BYTE_PTR pNewPublicData; - CK_ULONG ulNewRandomLen; - CK_BYTE_PTR pNewRandomA; -} CK_SKIPJACK_RELAYX_PARAMS; - -typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ - CK_SKIPJACK_RELAYX_PARAMS_PTR; - - -typedef struct CK_PBE_PARAMS { - CK_BYTE_PTR pInitVector; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG ulPasswordLen; - CK_BYTE_PTR pSalt; - CK_ULONG ulSaltLen; - CK_ULONG ulIteration; -} CK_PBE_PARAMS; - -typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; - - -/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the - * CKM_KEY_WRAP_SET_OAEP mechanism - */ -typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { - CK_BYTE bBC; /* block contents byte */ - CK_BYTE_PTR pX; /* extra data */ - CK_ULONG ulXLen; /* length of extra data in bytes */ -} CK_KEY_WRAP_SET_OAEP_PARAMS; - -typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; - -typedef struct CK_SSL3_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; - CK_ULONG ulServerRandomLen; -} CK_SSL3_RANDOM_DATA; - - -typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION_PTR pVersion; -} CK_SSL3_MASTER_KEY_DERIVE_PARAMS; - -typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; - -typedef struct CK_SSL3_KEY_MAT_OUT { - CK_OBJECT_HANDLE hClientMacSecret; - CK_OBJECT_HANDLE hServerMacSecret; - CK_OBJECT_HANDLE hClientKey; - CK_OBJECT_HANDLE hServerKey; - CK_BYTE_PTR pIVClient; - CK_BYTE_PTR pIVServer; -} CK_SSL3_KEY_MAT_OUT; - -typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; - - -typedef struct CK_SSL3_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; -} CK_SSL3_KEY_MAT_PARAMS; - -typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; - -typedef struct CK_TLS_PRF_PARAMS { - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLen; - CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; -} CK_TLS_PRF_PARAMS; - -typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; - -typedef struct CK_WTLS_RANDOM_DATA { - CK_BYTE_PTR pClientRandom; - CK_ULONG ulClientRandomLen; - CK_BYTE_PTR pServerRandom; - CK_ULONG ulServerRandomLen; -} CK_WTLS_RANDOM_DATA; - -typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; - -typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_BYTE_PTR pVersion; -} CK_WTLS_MASTER_KEY_DERIVE_PARAMS; - -typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; - -typedef struct CK_WTLS_PRF_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLen; - CK_BYTE_PTR pOutput; - CK_ULONG_PTR pulOutputLen; -} CK_WTLS_PRF_PARAMS; - -typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; - -typedef struct CK_WTLS_KEY_MAT_OUT { - CK_OBJECT_HANDLE hMacSecret; - CK_OBJECT_HANDLE hKey; - CK_BYTE_PTR pIV; -} CK_WTLS_KEY_MAT_OUT; - -typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; - -typedef struct CK_WTLS_KEY_MAT_PARAMS { - CK_MECHANISM_TYPE DigestMechanism; - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_ULONG ulSequenceNumber; - CK_BBOOL bIsExport; - CK_WTLS_RANDOM_DATA RandomInfo; - CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; -} CK_WTLS_KEY_MAT_PARAMS; - -typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; - -typedef struct CK_CMS_SIG_PARAMS { - CK_OBJECT_HANDLE certificateHandle; - CK_MECHANISM_PTR pSigningMechanism; - CK_MECHANISM_PTR pDigestMechanism; - CK_UTF8CHAR_PTR pContentType; - CK_BYTE_PTR pRequestedAttributes; - CK_ULONG ulRequestedAttributesLen; - CK_BYTE_PTR pRequiredAttributes; - CK_ULONG ulRequiredAttributesLen; -} CK_CMS_SIG_PARAMS; - -typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; - -typedef struct CK_KEY_DERIVATION_STRING_DATA { - CK_BYTE_PTR pData; - CK_ULONG ulLen; -} CK_KEY_DERIVATION_STRING_DATA; - -typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ - CK_KEY_DERIVATION_STRING_DATA_PTR; - - -/* The CK_EXTRACT_PARAMS is used for the - * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit - * of the base key should be used as the first bit of the - * derived key - */ -typedef CK_ULONG CK_EXTRACT_PARAMS; - -typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; - -/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to - * indicate the Pseudo-Random Function (PRF) used to generate - * key bits using PKCS #5 PBKDF2. - */ -typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; - -typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR \ - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; - -#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001UL -#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411 0x00000002UL -#define CKP_PKCS5_PBKD2_HMAC_SHA224 0x00000003UL -#define CKP_PKCS5_PBKD2_HMAC_SHA256 0x00000004UL -#define CKP_PKCS5_PBKD2_HMAC_SHA384 0x00000005UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512 0x00000006UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512_224 0x00000007UL -#define CKP_PKCS5_PBKD2_HMAC_SHA512_256 0x00000008UL - -/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the - * source of the salt value when deriving a key using PKCS #5 - * PBKDF2. - */ -typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; - -typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR \ - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; - -/* The following salt value sources are defined in PKCS #5 v2.0. */ -#define CKZ_SALT_SPECIFIED 0x00000001UL - -/* CK_PKCS5_PBKD2_PARAMS is a structure that provides the - * parameters to the CKM_PKCS5_PBKD2 mechanism. - */ -typedef struct CK_PKCS5_PBKD2_PARAMS { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - CK_VOID_PTR pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - CK_VOID_PTR pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG_PTR ulPasswordLen; -} CK_PKCS5_PBKD2_PARAMS; - -typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; - -/* CK_PKCS5_PBKD2_PARAMS2 is a corrected version of the CK_PKCS5_PBKD2_PARAMS - * structure that provides the parameters to the CKM_PKCS5_PBKD2 mechanism - * noting that the ulPasswordLen field is a CK_ULONG and not a CK_ULONG_PTR. - */ -typedef struct CK_PKCS5_PBKD2_PARAMS2 { - CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; - CK_VOID_PTR pSaltSourceData; - CK_ULONG ulSaltSourceDataLen; - CK_ULONG iterations; - CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; - CK_VOID_PTR pPrfData; - CK_ULONG ulPrfDataLen; - CK_UTF8CHAR_PTR pPassword; - CK_ULONG ulPasswordLen; -} CK_PKCS5_PBKD2_PARAMS2; - -typedef CK_PKCS5_PBKD2_PARAMS2 CK_PTR CK_PKCS5_PBKD2_PARAMS2_PTR; - -typedef CK_ULONG CK_OTP_PARAM_TYPE; -typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ - -typedef struct CK_OTP_PARAM { - CK_OTP_PARAM_TYPE type; - CK_VOID_PTR pValue; - CK_ULONG ulValueLen; -} CK_OTP_PARAM; - -typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; - -typedef struct CK_OTP_PARAMS { - CK_OTP_PARAM_PTR pParams; - CK_ULONG ulCount; -} CK_OTP_PARAMS; - -typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; - -typedef struct CK_OTP_SIGNATURE_INFO { - CK_OTP_PARAM_PTR pParams; - CK_ULONG ulCount; -} CK_OTP_SIGNATURE_INFO; - -typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; - -#define CK_OTP_VALUE 0UL -#define CK_OTP_PIN 1UL -#define CK_OTP_CHALLENGE 2UL -#define CK_OTP_TIME 3UL -#define CK_OTP_COUNTER 4UL -#define CK_OTP_FLAGS 5UL -#define CK_OTP_OUTPUT_LENGTH 6UL -#define CK_OTP_OUTPUT_FORMAT 7UL - -#define CKF_NEXT_OTP 0x00000001UL -#define CKF_EXCLUDE_TIME 0x00000002UL -#define CKF_EXCLUDE_COUNTER 0x00000004UL -#define CKF_EXCLUDE_CHALLENGE 0x00000008UL -#define CKF_EXCLUDE_PIN 0x00000010UL -#define CKF_USER_FRIENDLY_OTP 0x00000020UL - -typedef struct CK_KIP_PARAMS { - CK_MECHANISM_PTR pMechanism; - CK_OBJECT_HANDLE hKey; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; -} CK_KIP_PARAMS; - -typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; - -typedef struct CK_AES_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; -} CK_AES_CTR_PARAMS; - -typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; - -typedef struct CK_GCM_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -} CK_GCM_PARAMS; - -typedef CK_GCM_PARAMS CK_PTR CK_GCM_PARAMS_PTR; - -typedef struct CK_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -} CK_CCM_PARAMS; - -typedef CK_CCM_PARAMS CK_PTR CK_CCM_PARAMS_PTR; - -/* Deprecated. Use CK_GCM_PARAMS */ -typedef struct CK_AES_GCM_PARAMS { - CK_BYTE_PTR pIv; - CK_ULONG ulIvLen; - CK_ULONG ulIvBits; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulTagBits; -} CK_AES_GCM_PARAMS; - -typedef CK_AES_GCM_PARAMS CK_PTR CK_AES_GCM_PARAMS_PTR; - -/* Deprecated. Use CK_CCM_PARAMS */ -typedef struct CK_AES_CCM_PARAMS { - CK_ULONG ulDataLen; - CK_BYTE_PTR pNonce; - CK_ULONG ulNonceLen; - CK_BYTE_PTR pAAD; - CK_ULONG ulAADLen; - CK_ULONG ulMACLen; -} CK_AES_CCM_PARAMS; - -typedef CK_AES_CCM_PARAMS CK_PTR CK_AES_CCM_PARAMS_PTR; - -typedef struct CK_CAMELLIA_CTR_PARAMS { - CK_ULONG ulCounterBits; - CK_BYTE cb[16]; -} CK_CAMELLIA_CTR_PARAMS; - -typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; - -typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; - -typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; - -typedef struct CK_DSA_PARAMETER_GEN_PARAM { - CK_MECHANISM_TYPE hash; - CK_BYTE_PTR pSeed; - CK_ULONG ulSeedLen; - CK_ULONG ulIndex; -} CK_DSA_PARAMETER_GEN_PARAM; - -typedef CK_DSA_PARAMETER_GEN_PARAM CK_PTR CK_DSA_PARAMETER_GEN_PARAM_PTR; - -typedef struct CK_ECDH_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_EC_KDF_TYPE kdf; - CK_ULONG ulSharedDataLen; - CK_BYTE_PTR pSharedData; -} CK_ECDH_AES_KEY_WRAP_PARAMS; - -typedef CK_ECDH_AES_KEY_WRAP_PARAMS CK_PTR CK_ECDH_AES_KEY_WRAP_PARAMS_PTR; - -typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; - -typedef CK_ULONG CK_CERTIFICATE_CATEGORY; - -typedef struct CK_RSA_AES_KEY_WRAP_PARAMS { - CK_ULONG ulAESKeyBits; - CK_RSA_PKCS_OAEP_PARAMS_PTR pOAEPParams; -} CK_RSA_AES_KEY_WRAP_PARAMS; - -typedef CK_RSA_AES_KEY_WRAP_PARAMS CK_PTR CK_RSA_AES_KEY_WRAP_PARAMS_PTR; - -typedef struct CK_TLS12_MASTER_KEY_DERIVE_PARAMS { - CK_SSL3_RANDOM_DATA RandomInfo; - CK_VERSION_PTR pVersion; - CK_MECHANISM_TYPE prfHashMechanism; -} CK_TLS12_MASTER_KEY_DERIVE_PARAMS; - -typedef CK_TLS12_MASTER_KEY_DERIVE_PARAMS CK_PTR \ - CK_TLS12_MASTER_KEY_DERIVE_PARAMS_PTR; - -typedef struct CK_TLS12_KEY_MAT_PARAMS { - CK_ULONG ulMacSizeInBits; - CK_ULONG ulKeySizeInBits; - CK_ULONG ulIVSizeInBits; - CK_BBOOL bIsExport; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; - CK_MECHANISM_TYPE prfHashMechanism; -} CK_TLS12_KEY_MAT_PARAMS; - -typedef CK_TLS12_KEY_MAT_PARAMS CK_PTR CK_TLS12_KEY_MAT_PARAMS_PTR; - -typedef struct CK_TLS_KDF_PARAMS { - CK_MECHANISM_TYPE prfMechanism; - CK_BYTE_PTR pLabel; - CK_ULONG ulLabelLength; - CK_SSL3_RANDOM_DATA RandomInfo; - CK_BYTE_PTR pContextData; - CK_ULONG ulContextDataLength; -} CK_TLS_KDF_PARAMS; - -typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR; - -typedef struct CK_TLS_MAC_PARAMS { - CK_MECHANISM_TYPE prfHashMechanism; - CK_ULONG ulMacLength; - CK_ULONG ulServerOrClient; -} CK_TLS_MAC_PARAMS; - -typedef CK_TLS_MAC_PARAMS CK_PTR CK_TLS_MAC_PARAMS_PTR; - -typedef struct CK_GOSTR3410_DERIVE_PARAMS { - CK_EC_KDF_TYPE kdf; - CK_BYTE_PTR pPublicData; - CK_ULONG ulPublicDataLen; - CK_BYTE_PTR pUKM; - CK_ULONG ulUKMLen; -} CK_GOSTR3410_DERIVE_PARAMS; - -typedef CK_GOSTR3410_DERIVE_PARAMS CK_PTR CK_GOSTR3410_DERIVE_PARAMS_PTR; - -typedef struct CK_GOSTR3410_KEY_WRAP_PARAMS { - CK_BYTE_PTR pWrapOID; - CK_ULONG ulWrapOIDLen; - CK_BYTE_PTR pUKM; - CK_ULONG ulUKMLen; - CK_OBJECT_HANDLE hKey; -} CK_GOSTR3410_KEY_WRAP_PARAMS; - -typedef CK_GOSTR3410_KEY_WRAP_PARAMS CK_PTR CK_GOSTR3410_KEY_WRAP_PARAMS_PTR; - -typedef struct CK_SEED_CBC_ENCRYPT_DATA_PARAMS { - CK_BYTE iv[16]; - CK_BYTE_PTR pData; - CK_ULONG length; -} CK_SEED_CBC_ENCRYPT_DATA_PARAMS; - -typedef CK_SEED_CBC_ENCRYPT_DATA_PARAMS CK_PTR \ - CK_SEED_CBC_ENCRYPT_DATA_PARAMS_PTR; - -#endif /* _PKCS11T_H_ */ - diff --git a/SoftHSMv2/src/lib/session_mgr/Makefile.am b/SoftHSMv2/src/lib/session_mgr/Makefile.am index 5186d33..f696b14 100644 --- a/SoftHSMv2/src/lib/session_mgr/Makefile.am +++ b/SoftHSMv2/src/lib/session_mgr/Makefile.am @@ -14,4 +14,5 @@ libsofthsm_sessionmgr_la_SOURCES = SessionManager.cpp \ SUBDIRS = test -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/session_mgr/test/Makefile.am b/SoftHSMv2/src/lib/session_mgr/test/Makefile.am index 6395038..36233b9 100644 --- a/SoftHSMv2/src/lib/session_mgr/test/Makefile.am +++ b/SoftHSMv2/src/lib/session_mgr/test/Makefile.am @@ -17,10 +17,11 @@ check_PROGRAMS = sessionmgrtest sessionmgrtest_SOURCES = sessionmgrtest.cpp \ SessionManagerTests.cpp -sessionmgrtest_LDADD = ../../libsofthsm_convarch.la +sessionmgrtest_LDADD = ../../libsofthsm_convarch.la sessionmgrtest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install -pthread TESTS = sessionmgrtest -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/slot_mgr/Makefile.am b/SoftHSMv2/src/lib/slot_mgr/Makefile.am index 1e8cf33..db407fa 100644 --- a/SoftHSMv2/src/lib/slot_mgr/Makefile.am +++ b/SoftHSMv2/src/lib/slot_mgr/Makefile.am @@ -15,4 +15,5 @@ libsofthsm_slotmgr_la_SOURCES = SlotManager.cpp \ SUBDIRS = test -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am b/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am index 8e2d161..3793cf9 100644 --- a/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am +++ b/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am @@ -16,10 +16,11 @@ check_PROGRAMS = slotmgrtest slotmgrtest_SOURCES = slotmgrtest.cpp \ SlotManagerTests.cpp -slotmgrtest_LDADD = ../../libsofthsm_convarch.la +slotmgrtest_LDADD = ../../libsofthsm_convarch.la slotmgrtest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install -pthread TESTS = slotmgrtest -EXTRA_DIST = $(srcdir)/*.h +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/test/DeriveTests.cpp b/SoftHSMv2/src/lib/test/DeriveTests.cpp index 588d0b9..eb8aba5 100644 --- a/SoftHSMv2/src/lib/test/DeriveTests.cpp +++ b/SoftHSMv2/src/lib/test/DeriveTests.cpp @@ -145,6 +145,53 @@ CK_RV DeriveTests::generateEcKeyPair(const char* curve, CK_SESSION_HANDLE hSessi } #endif +#ifdef WITH_EDDSA +CK_RV DeriveTests::generateEdKeyPair(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk) +{ + CK_MECHANISM mechanism = { CKM_EC_EDWARDS_KEY_PAIR_GEN, NULL_PTR, 0 }; + CK_KEY_TYPE keyType = CKK_EC_EDWARDS; + CK_BYTE oidX25519[] = { 0x06, 0x03, 0x2B, 0x65, 0x6E }; + CK_BYTE oidX448[] = { 0x06, 0x03, 0x2B, 0x65, 0x6F }; + CK_BBOOL bTrue = CK_TRUE; + CK_ATTRIBUTE pukAttribs[] = { + { CKA_EC_PARAMS, NULL, 0 }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) }, + { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) } + }; + CK_ATTRIBUTE prkAttribs[] = { + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) }, + { CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) }, + { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, + { CKA_DERIVE, &bTrue, sizeof(bTrue) } + }; + + /* Select the curve */ + if (strcmp(curve, "X25519") == 0) + { + pukAttribs[0].pValue = oidX25519; + pukAttribs[0].ulValueLen = sizeof(oidX25519); + } + else if (strcmp(curve, "X448") == 0) + { + pukAttribs[0].pValue = oidX448; + pukAttribs[0].ulValueLen = sizeof(oidX448); + } + else + { + return CKR_GENERAL_ERROR; + } + + hPuk = CK_INVALID_HANDLE; + hPrk = CK_INVALID_HANDLE; + return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, + pukAttribs, sizeof(pukAttribs)/sizeof(CK_ATTRIBUTE), + prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE), + &hPuk, &hPrk) ); +} +#endif + CK_RV DeriveTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey) { CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; @@ -254,7 +301,7 @@ void DeriveTests::dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicK CPPUNIT_ASSERT(rv == CKR_OK); } -#ifdef WITH_ECC +#if defined(WITH_ECC) || defined(WITH_EDDSA) void DeriveTests::ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw) { CK_ATTRIBUTE valAttrib = { CKA_EC_POINT, NULL_PTR, 0 }; @@ -423,7 +470,7 @@ void DeriveTests::testDhDerive() } #ifdef WITH_ECC -void DeriveTests::testEcdhDerive() +void DeriveTests::testEcdsaDerive() { CK_RV rv; CK_SESSION_HANDLE hSessionRO; @@ -497,6 +544,81 @@ void DeriveTests::testEcdhDerive() } #endif +#ifdef WITH_EDDSA +void DeriveTests::testEddsaDerive() +{ + CK_RV rv; + CK_SESSION_HANDLE hSessionRO; + CK_SESSION_HANDLE hSessionRW; + + // Just make sure that we finalize any previous tests + CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) ); + + // Open read-only session on when the token is not initialized should fail + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) ); + CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED); + + // Initialize the library and start the test. + rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-only session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-write session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Login USER into the sessions so we can create a private objects + rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Public Session keys + CK_OBJECT_HANDLE hPuk1 = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPrk1 = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPuk2 = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPrk2 = CK_INVALID_HANDLE; + + rv = generateEdKeyPair("X25519",hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk1,hPrk1); + CPPUNIT_ASSERT(rv == CKR_OK); + rv = generateEdKeyPair("X25519",hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk2,hPrk2); + CPPUNIT_ASSERT(rv == CKR_OK); + CK_OBJECT_HANDLE hKey1 = CK_INVALID_HANDLE; + ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true); + CK_OBJECT_HANDLE hKey2 = CK_INVALID_HANDLE; + ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false); + CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2)); + + // Private Session Keys + rv = generateEdKeyPair("X25519",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk1,hPrk1); + CPPUNIT_ASSERT(rv == CKR_OK); + rv = generateEdKeyPair("X25519",hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk2,hPrk2); + CPPUNIT_ASSERT(rv == CKR_OK); + ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true); + ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false); + CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2)); + + // Public Token Keys + rv = generateEdKeyPair("X25519",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk1,hPrk1); + CPPUNIT_ASSERT(rv == CKR_OK); + rv = generateEdKeyPair("X25519",hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk2,hPrk2); + CPPUNIT_ASSERT(rv == CKR_OK); + ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true); + ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false); + CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2)); + + // Private Token Keys + rv = generateEdKeyPair("X25519",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk1,hPrk1); + CPPUNIT_ASSERT(rv == CKR_OK); + rv = generateEdKeyPair("X25519",hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk2,hPrk2); + CPPUNIT_ASSERT(rv == CKR_OK); + ecdhDerive(hSessionRW,hPuk1,hPrk2,hKey1,true); + ecdhDerive(hSessionRW,hPuk2,hPrk1,hKey2,false); + CPPUNIT_ASSERT(compareSecret(hSessionRW,hKey1,hKey2)); +} +#endif + void DeriveTests::symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE &hDerive, CK_MECHANISM_TYPE mechType, CK_KEY_TYPE keyType) { CK_RV rv; diff --git a/SoftHSMv2/src/lib/test/DeriveTests.h b/SoftHSMv2/src/lib/test/DeriveTests.h index 5b2aef5..a6a94f0 100644 --- a/SoftHSMv2/src/lib/test/DeriveTests.h +++ b/SoftHSMv2/src/lib/test/DeriveTests.h @@ -41,7 +41,10 @@ class DeriveTests : public TestsBase CPPUNIT_TEST_SUITE(DeriveTests); CPPUNIT_TEST(testDhDerive); #ifdef WITH_ECC - CPPUNIT_TEST(testEcdhDerive); + CPPUNIT_TEST(testEcdsaDerive); +#endif +#ifdef WITH_EDDSA + CPPUNIT_TEST(testEddsaDerive); #endif CPPUNIT_TEST(testSymDerive); CPPUNIT_TEST_SUITE_END(); @@ -49,7 +52,10 @@ class DeriveTests : public TestsBase public: void testDhDerive(); #ifdef WITH_ECC - void testEcdhDerive(); + void testEcdsaDerive(); +#endif +#ifdef WITH_EDDSA + void testEddsaDerive(); #endif void testSymDerive(); @@ -64,8 +70,13 @@ protected: void dhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey); #ifdef WITH_ECC CK_RV generateEcKeyPair(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk); +#endif +#if defined(WITH_ECC) || defined(WITH_EDDSA) void ecdhDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_OBJECT_HANDLE &hKey, bool useRaw); #endif +#ifdef WITH_EDDSA + CK_RV generateEdKeyPair(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk); +#endif bool compareSecret(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey1, CK_OBJECT_HANDLE hKey2); void symDerive(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE &hDerive, CK_MECHANISM_TYPE mechType, CK_KEY_TYPE keyType); }; diff --git a/SoftHSMv2/src/lib/test/Makefile.am b/SoftHSMv2/src/lib/test/Makefile.am index 3723399..657f187 100644 --- a/SoftHSMv2/src/lib/test/Makefile.am +++ b/SoftHSMv2/src/lib/test/Makefile.am @@ -5,12 +5,9 @@ AM_CPPFLAGS = -I$(srcdir)/.. \ -I$(srcdir)/../pkcs11 \ @CPPUNIT_CFLAGS@ -check_PROGRAMS = p11test - AUTOMAKE_OPTIONS = subdir-objects -p11test_SOURCES = p11test.cpp \ - SymmetricAlgorithmTests.cpp \ +p11test_SOURCES = SymmetricAlgorithmTests.cpp \ DigestTests.cpp \ InitTests.cpp \ InfoTests.cpp \ @@ -28,11 +25,10 @@ p11test_SOURCES = p11test.cpp \ ../common/log.cpp \ ../common/osmutex.cpp -p11test_LDADD = ../libsofthsm2.la +p11test_LDADD = ../libsofthsm2.la p11test_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install -pthread -static -TESTS = p11test - -EXTRA_DIST = $(srcdir)/*.h \ +EXTRA_DIST = $(srcdir)/CMakeLists.txt \ + $(srcdir)/*.h \ $(srcdir)/tokens/dummy.in diff --git a/SoftHSMv2/src/lib/test/SignVerifyTests.cpp b/SoftHSMv2/src/lib/test/SignVerifyTests.cpp index 06dbf95..c68ed08 100644 --- a/SoftHSMv2/src/lib/test/SignVerifyTests.cpp +++ b/SoftHSMv2/src/lib/test/SignVerifyTests.cpp @@ -165,6 +165,61 @@ CK_RV SignVerifyTests::generateEC(const char* curve, CK_SESSION_HANDLE hSession, } #endif +#ifdef WITH_EDDSA +CK_RV SignVerifyTests::generateED(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk) +{ + CK_MECHANISM mechanism = { CKM_EC_EDWARDS_KEY_PAIR_GEN, NULL_PTR, 0 }; + CK_KEY_TYPE keyType = CKK_EC_EDWARDS; + CK_BYTE oidEd25519[] = { 0x06, 0x03, 0x2B, 0x65, 0x70 }; + CK_BYTE label[] = { 0x12, 0x34 }; // dummy + CK_BYTE id[] = { 123 } ; // dummy + CK_BBOOL bFalse = CK_FALSE; + CK_BBOOL bTrue = CK_TRUE; + + CK_ATTRIBUTE pukAttribs[] = { + { CKA_EC_PARAMS, NULL, 0 }, + { CKA_LABEL, &label[0], sizeof(label) }, + { CKA_ID, &id[0], sizeof(id) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_VERIFY, &bTrue, sizeof(bTrue) }, + { CKA_ENCRYPT, &bFalse, sizeof(bFalse) }, + { CKA_WRAP, &bFalse, sizeof(bFalse) }, + { CKA_TOKEN, &bTokenPuk, sizeof(bTokenPuk) }, + { CKA_PRIVATE, &bPrivatePuk, sizeof(bPrivatePuk) } + }; + CK_ATTRIBUTE prkAttribs[] = { + { CKA_LABEL, &label[0], sizeof(label) }, + { CKA_ID, &id[0], sizeof(id) }, + { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, + { CKA_SIGN, &bTrue, sizeof(bTrue) }, + { CKA_DECRYPT, &bFalse, sizeof(bFalse) }, + { CKA_UNWRAP, &bFalse, sizeof(bFalse) }, + { CKA_SENSITIVE, &bTrue, sizeof(bTrue) }, + { CKA_TOKEN, &bTokenPrk, sizeof(bTokenPrk) }, + { CKA_PRIVATE, &bPrivatePrk, sizeof(bPrivatePrk) }, + { CKA_EXTRACTABLE, &bFalse, sizeof(bFalse) } + }; + + /* Select the curve */ + if (strcmp(curve, "Ed25519") == 0) + { + pukAttribs[0].pValue = oidEd25519; + pukAttribs[0].ulValueLen = sizeof(oidEd25519); + } + else + { + return CKR_GENERAL_ERROR; + } + + hPuk = CK_INVALID_HANDLE; + hPrk = CK_INVALID_HANDLE; + return CRYPTOKI_F_PTR( C_GenerateKeyPair(hSession, &mechanism, + pukAttribs, sizeof(pukAttribs)/sizeof(CK_ATTRIBUTE), + prkAttribs, sizeof(prkAttribs)/sizeof(CK_ATTRIBUTE), + &hPuk, &hPrk) ); +} +#endif + void SignVerifyTests::signVerifySingle(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param /* = NULL_PTR */, CK_ULONG paramLen /* = 0 */) { CK_RV rv; @@ -480,6 +535,61 @@ void SignVerifyTests::testEcSignVerify() } #endif +#ifdef WITH_EDDSA +void SignVerifyTests::testEdSignVerify() +{ + CK_RV rv; + CK_SESSION_HANDLE hSessionRO; + CK_SESSION_HANDLE hSessionRW; + + // Just make sure that we finalize any previous tests + CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) ); + + // Open read-only session on when the token is not initialized should fail + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) ); + CPPUNIT_ASSERT(rv == CKR_CRYPTOKI_NOT_INITIALIZED); + + // Initialize the library and start the test. + rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-only session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, &hSessionRO) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-write session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSessionRW) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Login USER into the sessions so we can create a private objects + rv = CRYPTOKI_F_PTR( C_Login(hSessionRO,CKU_USER,m_userPin1,m_userPin1Length) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + CK_OBJECT_HANDLE hPuk = CK_INVALID_HANDLE; + CK_OBJECT_HANDLE hPrk = CK_INVALID_HANDLE; + + // Public Session keys + rv = generateED("Ed25519", hSessionRW,IN_SESSION,IS_PUBLIC,IN_SESSION,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_EDDSA, hSessionRO, hPuk,hPrk); + + // Private Session Keys + rv = generateED("Ed25519", hSessionRW,IN_SESSION,IS_PRIVATE,IN_SESSION,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_EDDSA, hSessionRO, hPuk,hPrk); + + // Public Token Keys + rv = generateED("Ed25519", hSessionRW,ON_TOKEN,IS_PUBLIC,ON_TOKEN,IS_PUBLIC,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_EDDSA, hSessionRO, hPuk,hPrk); + + // Private Token Keys + rv = generateED("Ed25519", hSessionRW,ON_TOKEN,IS_PRIVATE,ON_TOKEN,IS_PRIVATE,hPuk,hPrk); + CPPUNIT_ASSERT(rv == CKR_OK); + signVerifySingle(CKM_EDDSA, hSessionRO, hPuk,hPrk); +} +#endif + CK_RV SignVerifyTests::generateKey(CK_SESSION_HANDLE hSession, CK_KEY_TYPE keyType, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey) { #ifndef WITH_BOTAN diff --git a/SoftHSMv2/src/lib/test/SignVerifyTests.h b/SoftHSMv2/src/lib/test/SignVerifyTests.h index a251218..6c99564 100644 --- a/SoftHSMv2/src/lib/test/SignVerifyTests.h +++ b/SoftHSMv2/src/lib/test/SignVerifyTests.h @@ -45,6 +45,9 @@ class SignVerifyTests : public TestsBase #ifdef WITH_ECC CPPUNIT_TEST(testEcSignVerify); #endif +#ifdef WITH_EDDSA + CPPUNIT_TEST(testEdSignVerify); +#endif CPPUNIT_TEST(testMacSignVerify); CPPUNIT_TEST_SUITE_END(); @@ -53,6 +56,9 @@ public: #ifdef WITH_ECC void testEcSignVerify(); #endif +#ifdef WITH_EDDSA + void testEdSignVerify(); +#endif void testMacSignVerify(); protected: @@ -60,6 +66,9 @@ protected: #ifdef WITH_ECC CK_RV generateEC(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk); #endif +#ifdef WITH_EDDSA + CK_RV generateED(const char* curve, CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk); +#endif void signVerifySingle(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param = NULL_PTR, CK_ULONG paramLen = 0); void signVerifySingleData(size_t dataSize, CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param = NULL_PTR, CK_ULONG paramLen = 0); void signVerifyMulti(CK_MECHANISM_TYPE mechanismType, CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPublicKey, CK_OBJECT_HANDLE hPrivateKey, CK_VOID_PTR param = NULL_PTR, CK_ULONG paramLen = 0); diff --git a/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.cpp b/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.cpp index bbc340c..1965a35 100644 --- a/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.cpp +++ b/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.cpp @@ -49,6 +49,28 @@ const CK_BBOOL IS_PUBLIC = CK_FALSE; CPPUNIT_TEST_SUITE_REGISTRATION(SymmetricAlgorithmTests); +CK_RV SymmetricAlgorithmTests::generateGenericKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey) +{ + CK_MECHANISM mechanism = { CKM_GENERIC_SECRET_KEY_GEN, NULL_PTR, 0 }; + CK_ULONG bytes = 16; + // CK_BBOOL bFalse = CK_FALSE; + CK_BBOOL bTrue = CK_TRUE; + CK_ATTRIBUTE keyAttribs[] = { + { CKA_TOKEN, &bToken, sizeof(bToken) }, + { CKA_PRIVATE, &bPrivate, sizeof(bPrivate) }, + { CKA_ENCRYPT, &bTrue, sizeof(bTrue) }, + { CKA_DECRYPT, &bTrue, sizeof(bTrue) }, + { CKA_WRAP, &bTrue, sizeof(bTrue) }, + { CKA_UNWRAP, &bTrue, sizeof(bTrue) }, + { CKA_VALUE_LEN, &bytes, sizeof(bytes) }, + }; + + hKey = CK_INVALID_HANDLE; + return CRYPTOKI_F_PTR( C_GenerateKey(hSession, &mechanism, + keyAttribs, sizeof(keyAttribs)/sizeof(CK_ATTRIBUTE), + &hKey) ); +} + CK_RV SymmetricAlgorithmTests::generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey) { CK_MECHANISM mechanism = { CKM_AES_KEY_GEN, NULL_PTR, 0 }; @@ -1145,3 +1167,30 @@ void SymmetricAlgorithmTests::testAesCtrOverflow() rv = CRYPTOKI_F_PTR( C_DecryptUpdate(hSession,&vEncryptedData.front(),1,NULL_PTR,&ulDataPartLen) ); CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_ENCRYPTED_DATA_LEN_RANGE, rv ); } + +void SymmetricAlgorithmTests::testGenericKey() +{ + CK_RV rv; + CK_SESSION_HANDLE hSession; + + // Just make sure that we finalize any previous tests + CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) ); + + // Initialize the library and start the test. + rv = CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Open read-write session + rv = CRYPTOKI_F_PTR( C_OpenSession(m_initializedTokenSlotID, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &hSession) ); + CPPUNIT_ASSERT(rv == CKR_OK); + + // Login USER into the session so we can create a private objects + rv = CRYPTOKI_F_PTR( C_Login(hSession,CKU_USER,m_userPin1,m_userPin1Length) ); + CPPUNIT_ASSERT(rv==CKR_OK); + + CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; + + // Generate a session key. + rv = generateGenericKey(hSession,IN_SESSION,IS_PUBLIC,hKey); + CPPUNIT_ASSERT(rv == CKR_OK); +} diff --git a/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.h b/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.h index 76191d9..19c3529 100644 --- a/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.h +++ b/SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.h @@ -48,6 +48,7 @@ class SymmetricAlgorithmTests : public TestsBase CPPUNIT_TEST(testNonModifiableDesKeyGeneration); CPPUNIT_TEST(testCheckValue); CPPUNIT_TEST(testAesCtrOverflow); + CPPUNIT_TEST(testGenericKey); CPPUNIT_TEST_SUITE_END(); public: @@ -58,8 +59,10 @@ public: void testNonModifiableDesKeyGeneration(); void testCheckValue(); void testAesCtrOverflow(); + void testGenericKey(); protected: + CK_RV generateGenericKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey); CK_RV generateAesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey); #ifndef WITH_FIPS CK_RV generateDesKey(CK_SESSION_HANDLE hSession, CK_BBOOL bToken, CK_BBOOL bPrivate, CK_OBJECT_HANDLE &hKey); diff --git a/SoftHSMv2/src/lib/test/TestsNoPINInitBase.cpp b/SoftHSMv2/src/lib/test/TestsNoPINInitBase.cpp index f5bb066..3ca514b 100644 --- a/SoftHSMv2/src/lib/test/TestsNoPINInitBase.cpp +++ b/SoftHSMv2/src/lib/test/TestsNoPINInitBase.cpp @@ -151,10 +151,6 @@ TestsNoPINInitBase::~TestsNoPINInitBase() { #endif // _WIN32 } -void softHSMLog(const int, const char*, const char*, const int, const char*, ...) -{ - -} #else TestsNoPINInitBase::~TestsNoPINInitBase() {} #endif // P11M diff --git a/SoftHSMv2/src/lib/test/softhsm2-alt.conf.win32 b/SoftHSMv2/src/lib/test/softhsm2-alt.conf.win32 deleted file mode 100644 index 68cb2ec..0000000 --- a/SoftHSMv2/src/lib/test/softhsm2-alt.conf.win32 +++ /dev/null @@ -1,6 +0,0 @@ -# SoftHSM v2 configuration file - -directories.tokendir = .\tokens -objectstore.backend = file -log.level = INFO -slots.removable = true diff --git a/SoftHSMv2/src/lib/test/softhsm2.conf.win32 b/SoftHSMv2/src/lib/test/softhsm2.conf.win32 deleted file mode 100644 index a877d1f..0000000 --- a/SoftHSMv2/src/lib/test/softhsm2.conf.win32 +++ /dev/null @@ -1,6 +0,0 @@ -# SoftHSM v2 configuration file - -directories.tokendir = .\tokens -objectstore.backend = file -log.level = INFO -slots.removable = false diff --git a/SoftHSMv2/testing/appveyor/APPVEYOR-NOTES.MD b/SoftHSMv2/testing/appveyor/APPVEYOR-NOTES.MD new file mode 100644 index 0000000..b2347b0 --- /dev/null +++ b/SoftHSMv2/testing/appveyor/APPVEYOR-NOTES.MD @@ -0,0 +1,27 @@ +# AppVeyor integration with SoftHSMv2 on GitHub + +This document describes the process of integrating AppVeyor with SoftHSMv2 on GitHub. + +## Integration + +### Add project + +To add the project, click on the following: + +1. New Project +2. GitHub +3. opendnssec -> SoftHSMv2 -> Add + +### Settings + +The following settings where changed. + +#### General + +* Custom configuration .yml file name: .appveyor.yml +* Skip branches without appveyor.yml: check + +## Dependencies + +Prebuilt dependencies (OpenSSL and CppUnit) are currently hosted in a dedicated +repository by [disig/SoftHSM2-AppVeyor](https://github.com/disig/SoftHSM2-AppVeyor/) diff --git a/SoftHSMv2/testing/appveyor/appveyor_download_requirements.ps1 b/SoftHSMv2/testing/appveyor/appveyor_download_requirements.ps1 new file mode 100644 index 0000000..56a0d0b --- /dev/null +++ b/SoftHSMv2/testing/appveyor/appveyor_download_requirements.ps1 @@ -0,0 +1,74 @@ +Add-Type -AssemblyName System.IO.Compression.FileSystem +function Unzip +{ + param([string]$zipfile, [string]$outpath) + + [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath) +} + +$CURRENT_DIR_PATH = (Get-Item -Path ".\" -Verbose).FullName +$BUILD_DIR = Join-Path $CURRENT_DIR_PATH build + +#prepare directories +Write-Host "Preparing directories" + +$exists = Test-Path build +if ($exists -eq $false) { + mkdir build +} +cd build + +$exists = Test-Path $env:RELEASE_DIR +if ($exists -eq $false) { + mkdir $env:RELEASE_DIR +} + +$exists = Test-Path python +if ($exists -eq $true) { + Remove-Item python -recurse +} + +$exists = Test-Path "$env:CPPUNIT_PATH" +if ($exists -eq $true) { + Remove-Item "$env:CPPUNIT_PATH" -recurse +} + +$exists = Test-Path "$env:CRYPTO_PACKAGE_PATH" +if ($exists -eq $true) { + Remove-Item "$env:CRYPTO_PACKAGE_PATH" -recurse +} + +mkdir python + +Write-Host "Preparing directories - OK" + +Write-Host "Downloading needed tools and dependencies" + +[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" + +$exists = Test-Path "$env:CRYPTO_PACKAGE_NAME" +if ($exists -eq $false) { + $source = "https://github.com/disig/SoftHSM2-AppVeyor/raw/master/$env:PACKAGE_VERSION_NAME/$env:CRYPTO_PACKAGE" + Invoke-WebRequest $source -OutFile $env:CRYPTO_PACKAGE +} + +$exists = Test-Path "$env:CPPUNIT_PACKAGE" +if ($exists -eq $false) { + $source = "https://github.com/disig/SoftHSM2-AppVeyor/raw/master/$env:CPPUNIT_VERSION_NAME/$env:CPPUNIT_PACKAGE" + Invoke-WebRequest $source -OutFile $env:CPPUNIT_PACKAGE +} + +Write-Host "Downloading needed tools and dependencies - OK" + +Write-Host "Extracting ..." +Unzip "$BUILD_DIR/$env:CRYPTO_PACKAGE" "$BUILD_DIR" + +Unzip "$BUILD_DIR/$env:CPPUNIT_PACKAGE" "$BUILD_DIR" + +dir + +dir "$env:PYTHON_PATH" +dir "$env:CRYPTO_PACKAGE_PATH" +dir "$env:CPPUNIT_PATH" + +cd $CURRENT_DIR_PATH diff --git a/SoftHSMv2/testing/build-botan.sh b/SoftHSMv2/testing/build-botan.sh index fc31217..2f8d10d 100644 --- a/SoftHSMv2/testing/build-botan.sh +++ b/SoftHSMv2/testing/build-botan.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash source `dirname "$0"`/lib.sh && init || exit 1 -BOTAN="Botan-2.4.0" +BOTAN="Botan-2.5.0" BOTAN_URL="https://botan.randombit.net/releases/$BOTAN.tgz" BOTAN_FILENAME="$BOTAN.tgz" BOTAN_HASH_TYPE="sha1" -BOTAN_HASH="212587ae2458d51052c496fbcc79dc4162d33349" +BOTAN_HASH="f422ba87f99c070fdcc3347943cb1a63add2e028" check_if_built botan && exit 0 start_build botan diff --git a/SoftHSMv2/testing/travis/travis.sh b/SoftHSMv2/testing/travis/travis.sh index 6a1ca1f..826fbc4 100644 --- a/SoftHSMv2/testing/travis/travis.sh +++ b/SoftHSMv2/testing/travis/travis.sh @@ -6,11 +6,11 @@ CONF_OBJSTORE="" case $CRYPTO in botan) CONF_CRYPTO="$CONF_CRYPTO --with-crypto-backend=botan --with-botan=/usr" - CONF_CRYPTO="$CONF_CRYPTO --disable-ecc --disable-gost" + CONF_CRYPTO="$CONF_CRYPTO --disable-ecc --disable-eddsa --disable-gost" ;; openssl) CONF_CRYPTO="$CONF_CRYPTO --with-crypto-backend=openssl --with-openssl=/usr" - CONF_CRYPTO="$CONF_CRYPTO --disable-gost" + CONF_CRYPTO="$CONF_CRYPTO --disable-eddsa --disable-gost" openssl version -a ;; *) @@ -37,7 +37,9 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/ echo "Build SoftHSMv2..." cd SoftHSMv2 sh autogen.sh -./configure --disable-gost +./configure --disable-gost --with-openssl=/usr/local/ +make +make check sudo make install cd .. |