Update SoftHSM v2.0 to the latest version 95/75195/9
authorPramod Raghavendra Jayathirth <pramod.raghavendra.jayathirth@intel.com>
Wed, 2 Jan 2019 17:59:48 +0000 (09:59 -0800)
committerPramod Raghavendra Jayathirth <pramod.raghavendra.jayathirth@intel.com>
Fri, 29 Mar 2019 16:59:04 +0000 (09:59 -0700)
Change-Id: Ib3ec2c297f897c82776a66fe2ad55b18984c0337
Issue-ID: AAF-687
Signed-off-by: Pramod Raghavendra Jayathirth <pramod.raghavendra.jayathirth@intel.com>
137 files changed:
SoftHSMv2/.appveyor.yml [new file with mode: 0644]
SoftHSMv2/Makefile.am
SoftHSMv2/NEWS
SoftHSMv2/OSX-NOTES.md [deleted file]
SoftHSMv2/README.md
SoftHSMv2/configure.ac
SoftHSMv2/m4/acx_64bit.m4
SoftHSMv2/m4/acx_botan.m4
SoftHSMv2/m4/acx_botan_aes_gcm.m4
SoftHSMv2/m4/acx_botan_ecc.m4
SoftHSMv2/m4/acx_botan_eddsa.m4 [new file with mode: 0644]
SoftHSMv2/m4/acx_botan_gnump.m4
SoftHSMv2/m4/acx_botan_gost.m4
SoftHSMv2/m4/acx_botan_rawpss.m4
SoftHSMv2/m4/acx_cppunit.m4
SoftHSMv2/m4/acx_crypto_backend.m4
SoftHSMv2/m4/acx_openssl.m4
SoftHSMv2/m4/acx_openssl_ecc.m4
SoftHSMv2/m4/acx_openssl_eddsa.m4 [new file with mode: 0644]
SoftHSMv2/m4/acx_openssl_fips.m4
SoftHSMv2/m4/acx_openssl_gost.m4
SoftHSMv2/m4/acx_p11kit.m4
SoftHSMv2/m4/acx_sqlite3.m4
SoftHSMv2/modules/CompilerOptions.cmake [new file with mode: 0644]
SoftHSMv2/modules/FindBotan.cmake [new file with mode: 0644]
SoftHSMv2/modules/FindCppUnit.cmake [new file with mode: 0644]
SoftHSMv2/modules/FindSQLite3.cmake [new file with mode: 0644]
SoftHSMv2/modules/tests/test_botan_aes_gcm.cpp [new file with mode: 0644]
SoftHSMv2/modules/tests/test_botan_ecc.cpp [new file with mode: 0644]
SoftHSMv2/modules/tests/test_botan_ed25519.cpp [new file with mode: 0644]
SoftHSMv2/modules/tests/test_botan_gost.cpp [new file with mode: 0644]
SoftHSMv2/modules/tests/test_botan_rawpss.cpp [new file with mode: 0644]
SoftHSMv2/modules/tests/test_botan_rfc5649.cpp [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_ecc.c [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_ed25519.c [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_ed448.c [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_fips.c [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_gost.c [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_rfc3394.c [new file with mode: 0644]
SoftHSMv2/modules/tests/test_openssl_rfc5649.c [new file with mode: 0644]
SoftHSMv2/src/Makefile.am
SoftHSMv2/src/bin/Makefile.am
SoftHSMv2/src/bin/dump/Makefile.am
SoftHSMv2/src/bin/dump/tables.h
SoftHSMv2/src/bin/keyconv/Makefile.am [new file with mode: 0644]
SoftHSMv2/src/bin/keyconv/base64.c [new file with mode: 0644]
SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-botan.cpp [new file with mode: 0644]
SoftHSMv2/src/bin/keyconv/softhsm2-keyconv-ossl.cpp [new file with mode: 0644]
SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.1 [new file with mode: 0644]
SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.cpp [new file with mode: 0644]
SoftHSMv2/src/bin/keyconv/softhsm2-keyconv.h [new file with mode: 0644]
SoftHSMv2/src/bin/migrate/Makefile.am
SoftHSMv2/src/bin/migrate/softhsm2-migrate.cpp
SoftHSMv2/src/bin/migrate/softhsm2-migrate.h
SoftHSMv2/src/bin/util/Makefile.am
SoftHSMv2/src/bin/util/softhsm2-util-botan.cpp
SoftHSMv2/src/bin/util/softhsm2-util-botan.h
SoftHSMv2/src/bin/util/softhsm2-util-ossl.cpp
SoftHSMv2/src/bin/util/softhsm2-util-ossl.h
SoftHSMv2/src/lib/HwInfra/README [changed mode: 0755->0644]
SoftHSMv2/src/lib/HwInfra/hwpluginif.h [changed mode: 0755->0644]
SoftHSMv2/src/lib/Makefile.am
SoftHSMv2/src/lib/P11Attributes.cpp
SoftHSMv2/src/lib/P11Attributes.h
SoftHSMv2/src/lib/P11Objects.cpp
SoftHSMv2/src/lib/P11Objects.h
SoftHSMv2/src/lib/SoftHSM.cpp
SoftHSMv2/src/lib/SoftHSM.h
SoftHSMv2/src/lib/common/Makefile.am
SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h
SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp
SoftHSMv2/src/lib/crypto/BotanEDDSA.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDDSA.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDKeyPair.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDKeyPair.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDPrivateKey.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDPublicKey.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanEDPublicKey.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/BotanUtil.cpp
SoftHSMv2/src/lib/crypto/BotanUtil.h
SoftHSMv2/src/lib/crypto/DerUtil.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/DerUtil.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/EDPrivateKey.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/EDPrivateKey.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/EDPublicKey.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/EDPublicKey.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/Makefile.am
SoftHSMv2/src/lib/crypto/OSSLComp.h
SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp
SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h
SoftHSMv2/src/lib/crypto/OSSLEDDSA.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDDSA.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDKeyPair.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDPrivateKey.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLEDPublicKey.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/OSSLUtil.cpp
SoftHSMv2/src/lib/crypto/OSSLUtil.h
SoftHSMv2/src/lib/crypto/test/EDDSATests.cpp [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/test/EDDSATests.h [new file with mode: 0644]
SoftHSMv2/src/lib/crypto/test/Makefile.am
SoftHSMv2/src/lib/data_mgr/Makefile.am
SoftHSMv2/src/lib/data_mgr/test/Makefile.am
SoftHSMv2/src/lib/handle_mgr/Makefile.am
SoftHSMv2/src/lib/handle_mgr/test/Makefile.am
SoftHSMv2/src/lib/object_store/DBObject.cpp
SoftHSMv2/src/lib/object_store/Makefile.am
SoftHSMv2/src/lib/object_store/test/DBObjectTests.cpp
SoftHSMv2/src/lib/object_store/test/DBTests.cpp
SoftHSMv2/src/lib/object_store/test/Makefile.am
SoftHSMv2/src/lib/object_store/test/ObjectFileTests.cpp
SoftHSMv2/src/lib/object_store/test/SessionObjectTests.cpp
SoftHSMv2/src/lib/pkcs11/pkcs11.h
SoftHSMv2/src/lib/pkcs11/pkcs11f.h [deleted file]
SoftHSMv2/src/lib/pkcs11/pkcs11t.h [deleted file]
SoftHSMv2/src/lib/session_mgr/Makefile.am
SoftHSMv2/src/lib/session_mgr/test/Makefile.am
SoftHSMv2/src/lib/slot_mgr/Makefile.am
SoftHSMv2/src/lib/slot_mgr/test/Makefile.am
SoftHSMv2/src/lib/test/DeriveTests.cpp
SoftHSMv2/src/lib/test/DeriveTests.h
SoftHSMv2/src/lib/test/Makefile.am
SoftHSMv2/src/lib/test/SignVerifyTests.cpp
SoftHSMv2/src/lib/test/SignVerifyTests.h
SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.cpp
SoftHSMv2/src/lib/test/SymmetricAlgorithmTests.h
SoftHSMv2/src/lib/test/TestsNoPINInitBase.cpp
SoftHSMv2/src/lib/test/softhsm2-alt.conf.win32 [deleted file]
SoftHSMv2/src/lib/test/softhsm2.conf.win32 [deleted file]
SoftHSMv2/testing/appveyor/APPVEYOR-NOTES.MD [new file with mode: 0644]
SoftHSMv2/testing/appveyor/appveyor_download_requirements.ps1 [new file with mode: 0644]
SoftHSMv2/testing/build-botan.sh
SoftHSMv2/testing/travis/travis.sh
build.sh

diff --git a/SoftHSMv2/.appveyor.yml b/SoftHSMv2/.appveyor.yml
new file mode 100644 (file)
index 0000000..4a46ea5
--- /dev/null
@@ -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)
index cfc0c62..786affe 100644 (file)
@@ -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
index feae4e4..bc32026 100644 (file)
@@ -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 (file)
index f1c7ee2..0000000
+++ /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
index c8230e8..e3b46a3 100644 (file)
@@ -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.
index 48a4bc2..eecd6eb 100644 (file)
@@ -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
 ])
index f610b21..4620184 100644 (file)
@@ -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
 
 ])
index ed93786..346a180 100644 (file)
@@ -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)
 ])
index d52c9cb..4873e30 100644 (file)
@@ -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
index 9bce21d..1dd067e 100644 (file)
@@ -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 (file)
index 0000000..88090b7
--- /dev/null
@@ -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
+])
index d15859a..28272ab 100644 (file)
@@ -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++])
index 3720f4a..ba4c334 100644 (file)
@@ -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
index 018e324..92b56ff 100644 (file)
@@ -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
index 2720d81..1e04244 100644 (file)
@@ -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])
 ])
index c860c89..f815bcd 100644 (file)
@@ -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
index e90c78f..2f1adad 100644 (file)
@@ -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
index 612c505..3ecf7a9 100644 (file)
@@ -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 (file)
index 0000000..0b629e2
--- /dev/null
@@ -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
+])
index 0491397..a55c209 100644 (file)
@@ -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
index dca489b..7deaacb 100644 (file)
@@ -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
index 20c7b7e..9545e7e 100644 (file)
@@ -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)
index cf829b7..fd942a7 100644 (file)
@@ -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 (file)
index 0000000..29a0ae5
--- /dev/null
@@ -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 (file)
index 0000000..6cb85a6
--- /dev/null
@@ -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 (file)
index 0000000..0980d1d
--- /dev/null
@@ -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 (file)
index 0000000..dc7a3b3
--- /dev/null
@@ -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 (file)
index 0000000..3769342
--- /dev/null
@@ -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 (file)
index 0000000..cb1be21
--- /dev/null
@@ -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 (file)
index 0000000..8ac4bac
--- /dev/null
@@ -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 (file)
index 0000000..a141e4b
--- /dev/null
@@ -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 (file)
index 0000000..ba7ad01
--- /dev/null
@@ -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 (file)
index 0000000..7f1fae4
--- /dev/null
@@ -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 (file)
index 0000000..d1eb22b
--- /dev/null
@@ -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 (file)
index 0000000..70dd92f
--- /dev/null
@@ -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 (file)
index 0000000..c97b094
--- /dev/null
@@ -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 (file)
index 0000000..51e75cd
--- /dev/null
@@ -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 (file)
index 0000000..33487e1
--- /dev/null
@@ -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 (file)
index 0000000..97343ee
--- /dev/null
@@ -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 (file)
index 0000000..17d63ba
--- /dev/null
@@ -0,0 +1,6 @@
+#include <openssl/evp.h>
+int main()
+{
+        EVP_aes_128_wrap_pad();
+        return 0;
+}
index 7f51142..0985325 100644 (file)
@@ -1,3 +1,5 @@
 MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
 
 SUBDIRS = lib bin
+
+EXTRA_DIST = $(srcdir)/CMakeLists.txt
index b4a4f57..18d5586 100644 (file)
@@ -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 
index c70d6f6..64bfa8c 100644 (file)
@@ -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
index 76d64fb..e6db516 100644 (file)
@@ -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 (file)
index 0000000..5565017
--- /dev/null
@@ -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 (file)
index 0000000..3eb1201
--- /dev/null
@@ -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 (file)
index 0000000..cb5700f
--- /dev/null
@@ -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 (file)
index 0000000..a5cd8eb
--- /dev/null
@@ -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 (file)
index 0000000..b716bc8
--- /dev/null
@@ -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 (file)
index 0000000..aeb75c3
--- /dev/null
@@ -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 (file)
index 0000000..fdeb719
--- /dev/null
@@ -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 */
index 020c6a7..d903764 100644 (file)
@@ -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
index 0e6dc90..3ce04eb 100644 (file)
@@ -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)
                {
index 1b5a066..a02221c 100644 (file)
@@ -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
 
index a552e14..788ea87 100644 (file)
@@ -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
index cecc0ce..c7b1da3 100644 (file)
@@ -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)
        {
@@ -176,6 +181,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
        {
@@ -200,6 +215,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
        {
@@ -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
index 8cd4a5e..6ad7664 100644 (file)
 #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
index fedfd28..e56dfba 100644 (file)
@@ -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)))
        {
@@ -159,6 +163,15 @@ int crypto_import_key_pair
                case EVP_PKEY_EC:
                        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");
@@ -186,6 +199,13 @@ int crypto_import_key_pair
                result = crypto_save_ecdsa(hSession, label, objID, objIDLen, noPublicKey, ecdsa);
                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
        {
@@ -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
index 7a2a31a..8fac612 100644 (file)
@@ -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
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index eac1704..8c4837e 100644 (file)
@@ -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
index 5a56097..264a0d8 100644 (file)
@@ -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:
index 8c9b98b..d40a9f5 100644 (file)
@@ -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
index 3e663b2..8ba9801 100644 (file)
@@ -885,6 +885,51 @@ bool P11ECPublicKeyObj::init(OSObject *inobject)
        return true;
 }
 
+// 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()
 {
@@ -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;
index 942a8c4..9d223ac 100644 (file)
@@ -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:
index acb90a3..bdf5a90 100644 (file)
@@ -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
@@ -1151,6 +1207,18 @@ CK_RV SoftHSM::C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_
                        pInfo->ulMaxKeySize = 0;
                        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");
@@ -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;
@@ -4114,6 +4187,13 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
                        mechanism = AsymMech::GOST_GOST;
                        bAllowMultiPartOp = true;
                        break;
+#endif
+#ifdef WITH_EDDSA
+               case CKM_EDDSA:
+                       mechanism = AsymMech::EDDSA;
+                       bAllowMultiPartOp = false;
+                       isEDDSA = true;
+                       break;
 #endif
                default:
                        return CKR_MECHANISM_INVALID;
@@ -4179,6 +4259,27 @@ CK_RV SoftHSM::AsymSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechan
                        return CKR_GENERAL_ERROR;
                }
        }
+#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
        {
@@ -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;
@@ -5302,6 +5408,13 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
                        mechanism = AsymMech::GOST_GOST;
                        bAllowMultiPartOp = true;
                        break;
+#endif
+#ifdef WITH_EDDSA
+               case CKM_EDDSA:
+                       mechanism = AsymMech::EDDSA;
+                       bAllowMultiPartOp = false;
+                       isEDDSA = true;
+                       break;
 #endif
                default:
                        return CKR_MECHANISM_INVALID;
@@ -5367,6 +5480,27 @@ CK_RV SoftHSM::AsymVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMech
                        return CKR_GENERAL_ERROR;
                }
        }
+#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
        {
@@ -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;
 }
 
@@ -5956,6 +6103,11 @@ CK_RV SoftHSM::C_GenerateKeyPair
                case CKM_GOSTR3410_KEY_PAIR_GEN:
                        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,
@@ -9482,31 +10075,346 @@ CK_RV SoftHSM::generateGOST
        gost->recycleKeyPair(kp);
        CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
 
-       // Remove keys that may have been created already when the function fails.
+       // 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;
+}
+
+// Derive a DH secret
+CK_RV SoftHSM::deriveDH
+(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) return CKR_MECHANISM_PARAM_INVALID;
+       if (pMechanism->ulParameterLen == 0) 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
+       switch (keyType)
+       {
+               case CKK_GENERIC_SECRET:
+                       if (byteLen == 0)
+                       {
+                               INFO_MSG("CKA_VALUE_LEN must be set");
+                               return CKR_TEMPLATE_INCOMPLETE;
+                       }
+                       break;
+#ifndef WITH_FIPS
+               case CKK_DES:
+                       if (byteLen != 0)
+                       {
+                               INFO_MSG("CKA_VALUE_LEN must not be set");
+                               return CKR_ATTRIBUTE_READ_ONLY;
+                       }
+                       byteLen = 8;
+                       break;
+#endif
+               case CKK_DES2:
+                       if (byteLen != 0)
+                       {
+                               INFO_MSG("CKA_VALUE_LEN must not be set");
+                               return CKR_ATTRIBUTE_READ_ONLY;
+                       }
+                       byteLen = 16;
+                       break;
+               case CKK_DES3:
+                       if (byteLen != 0)
+                       {
+                               INFO_MSG("CKA_VALUE_LEN must not be set");
+                               return CKR_ATTRIBUTE_READ_ONLY;
+                       }
+                       byteLen = 24;
+                       break;
+               case CKK_AES:
+                       if (byteLen != 16 && byteLen != 24 && byteLen != 32)
+                       {
+                               INFO_MSG("CKA_VALUE_LEN must be 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 DH algorithm handler
+       AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
+       if (dh == NULL)
+               return CKR_MECHANISM_INVALID;
+
+       // Get the keys
+       PrivateKey* privateKey = dh->newPrivateKey();
+       if (privateKey == NULL)
+       {
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               return CKR_HOST_MEMORY;
+       }
+       if (getDHPrivateKey((DHPrivateKey*)privateKey, token, baseKey) != CKR_OK)
+       {
+               dh->recyclePrivateKey(privateKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               return CKR_GENERAL_ERROR;
+       }
+
+       ByteString mechParameters;
+       mechParameters.resize(pMechanism->ulParameterLen);
+       memcpy(&mechParameters[0], pMechanism->pParameter, pMechanism->ulParameterLen);
+       PublicKey* publicKey = dh->newPublicKey();
+       if (publicKey == NULL)
+       {
+               dh->recyclePrivateKey(privateKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               return CKR_HOST_MEMORY;
+       }
+       if (getDHPublicKey((DHPublicKey*)publicKey, (DHPrivateKey*)privateKey, mechParameters) != CKR_OK)
+       {
+               dh->recyclePrivateKey(privateKey);
+               dh->recyclePublicKey(publicKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               return CKR_GENERAL_ERROR;
+       }
+
+       // Derive the secret
+       SymmetricKey* secret = NULL;
+       CK_RV rv = CKR_OK;
+       if (!dh->deriveKey(&secret, publicKey, privateKey))
+               rv = CKR_GENERAL_ERROR;
+       dh->recyclePrivateKey(privateKey);
+       dh->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;
+
+                       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
+       dh->recycleSymmetricKey(secret);
+       CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+
+       // Remove secret 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)
+               if (*phKey != CK_INVALID_HANDLE)
                {
-                       OSObject* ospub = (OSObject*)handleManager->getObject(*phPublicKey);
-                       handleManager->destroyObject(*phPublicKey);
-                       if (ospub) ospub->destroyObject();
-                       *phPublicKey = CK_INVALID_HANDLE;
+                       OSObject* ossecret = (OSObject*)handleManager->getObject(*phKey);
+                       handleManager->destroyObject(*phKey);
+                       if (ossecret) ossecret->destroyObject();
+                       *phKey = CK_INVALID_HANDLE;
                }
        }
 
        return rv;
 }
 
-// Derive a DH secret
-CK_RV SoftHSM::deriveDH
+// Derive an ECDH secret
+#ifdef WITH_ECC
+CK_RV SoftHSM::deriveECDH
 (CK_SESSION_HANDLE hSession,
        CK_MECHANISM_PTR pMechanism,
        CK_OBJECT_HANDLE hBaseKey,
@@ -9519,8 +10427,29 @@ CK_RV SoftHSM::deriveDH
 {
        *phKey = CK_INVALID_HANDLE;
 
-       if (pMechanism->pParameter == NULL_PTR) return CKR_MECHANISM_PARAM_INVALID;
-       if (pMechanism->ulParameterLen == 0) return CKR_MECHANISM_PARAM_INVALID;
+       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);
@@ -9564,45 +10493,41 @@ CK_RV SoftHSM::deriveDH
        }
 
        // Check the length
+       // byteLen == 0 impiles return max size the ECC can derive
        switch (keyType)
        {
                case CKK_GENERIC_SECRET:
-                       if (byteLen == 0)
-                       {
-                               INFO_MSG("CKA_VALUE_LEN must be set");
-                               return CKR_TEMPLATE_INCOMPLETE;
-                       }
                        break;
 #ifndef WITH_FIPS
                case CKK_DES:
-                       if (byteLen != 0)
+                       if (byteLen != 0 && byteLen != 8)
                        {
-                               INFO_MSG("CKA_VALUE_LEN must not be set");
-                               return CKR_ATTRIBUTE_READ_ONLY;
+                               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)
+                       if (byteLen != 0 && byteLen != 16)
                        {
-                               INFO_MSG("CKA_VALUE_LEN must not be set");
-                               return CKR_ATTRIBUTE_READ_ONLY;
+                               INFO_MSG("CKA_VALUE_LEN must be 0 or 16");
+                               return CKR_ATTRIBUTE_VALUE_INVALID;
                        }
                        byteLen = 16;
                        break;
                case CKK_DES3:
-                       if (byteLen != 0)
+                       if (byteLen != 0 && byteLen != 24)
                        {
-                               INFO_MSG("CKA_VALUE_LEN must not be set");
-                               return CKR_ATTRIBUTE_READ_ONLY;
+                               INFO_MSG("CKA_VALUE_LEN must be 0 or 24");
+                               return CKR_ATTRIBUTE_VALUE_INVALID;
                        }
                        byteLen = 24;
                        break;
                case CKK_AES:
-                       if (byteLen != 16 && byteLen != 24 && byteLen != 32)
+                       if (byteLen != 0 && byteLen != 16 && byteLen != 24 && byteLen != 32)
                        {
-                               INFO_MSG("CKA_VALUE_LEN must be 16, 24, or 32");
+                               INFO_MSG("CKA_VALUE_LEN must be 0, 16, 24, or 32");
                                return CKR_ATTRIBUTE_VALUE_INVALID;
                        }
                        break;
@@ -9615,50 +10540,52 @@ CK_RV SoftHSM::deriveDH
        if (baseKey == NULL || !baseKey->isValid())
                return CKR_KEY_HANDLE_INVALID;
 
-       // Get the DH algorithm handler
-       AsymmetricAlgorithm* dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
-       if (dh == NULL)
+       // Get the ECDH algorithm handler
+       AsymmetricAlgorithm* ecdh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDH);
+       if (ecdh == NULL)
                return CKR_MECHANISM_INVALID;
 
        // Get the keys
-       PrivateKey* privateKey = dh->newPrivateKey();
+       PrivateKey* privateKey = ecdh->newPrivateKey();
        if (privateKey == NULL)
        {
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
                return CKR_HOST_MEMORY;
        }
-       if (getDHPrivateKey((DHPrivateKey*)privateKey, token, baseKey) != CKR_OK)
+       if (getECPrivateKey((ECPrivateKey*)privateKey, token, baseKey) != CKR_OK)
        {
-               dh->recyclePrivateKey(privateKey);
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               ecdh->recyclePrivateKey(privateKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
                return CKR_GENERAL_ERROR;
        }
 
-       ByteString mechParameters;
-       mechParameters.resize(pMechanism->ulParameterLen);
-       memcpy(&mechParameters[0], pMechanism->pParameter, pMechanism->ulParameterLen);
-       PublicKey* publicKey = dh->newPublicKey();
+       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 = ecdh->newPublicKey();
        if (publicKey == NULL)
        {
-               dh->recyclePrivateKey(privateKey);
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               ecdh->recyclePrivateKey(privateKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
                return CKR_HOST_MEMORY;
        }
-       if (getDHPublicKey((DHPublicKey*)publicKey, (DHPrivateKey*)privateKey, mechParameters) != CKR_OK)
+       if (getECDHPublicKey((ECPublicKey*)publicKey, (ECPrivateKey*)privateKey, publicData) != CKR_OK)
        {
-               dh->recyclePrivateKey(privateKey);
-               dh->recyclePublicKey(publicKey);
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+               ecdh->recyclePrivateKey(privateKey);
+               ecdh->recyclePublicKey(publicKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
                return CKR_GENERAL_ERROR;
        }
 
        // Derive the secret
        SymmetricKey* secret = NULL;
        CK_RV rv = CKR_OK;
-       if (!dh->deriveKey(&secret, publicKey, privateKey))
+       if (!ecdh->deriveKey(&secret, publicKey, privateKey))
                rv = CKR_GENERAL_ERROR;
-       dh->recyclePrivateKey(privateKey);
-       dh->recyclePublicKey(publicKey);
+       ecdh->recyclePrivateKey(privateKey);
+       ecdh->recyclePublicKey(publicKey);
 
        // Create the secret object using C_CreateObject
        const CK_ULONG maxAttribs = 32;
@@ -9730,6 +10657,25 @@ CK_RV SoftHSM::deriveDH
                        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");
@@ -9801,8 +10747,8 @@ CK_RV SoftHSM::deriveDH
        }
 
        // Clean up
-       dh->recycleSymmetricKey(secret);
-       CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+       ecdh->recycleSymmetricKey(secret);
+       CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
 
        // Remove secret that may have been created already when the function fails.
        if (rv != CKR_OK)
@@ -9818,9 +10764,11 @@ CK_RV SoftHSM::deriveDH
 
        return rv;
 }
+#endif
 
-// Derive an ECDH secret
-CK_RV SoftHSM::deriveECDH
+// 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,
@@ -9831,7 +10779,6 @@ CK_RV SoftHSM::deriveECDH
        CK_BBOOL isOnToken,
        CK_BBOOL isPrivate)
 {
-#ifdef WITH_ECC
        *phKey = CK_INVALID_HANDLE;
 
        if ((pMechanism->pParameter == NULL_PTR) ||
@@ -9947,22 +10894,22 @@ CK_RV SoftHSM::deriveECDH
        if (baseKey == NULL || !baseKey->isValid())
                return CKR_KEY_HANDLE_INVALID;
 
-       // Get the ECDH algorithm handler
-       AsymmetricAlgorithm* ecdh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDH);
-       if (ecdh == NULL)
+       // Get the EDDSA algorithm handler
+       AsymmetricAlgorithm* eddsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::EDDSA);
+       if (eddsa == NULL)
                return CKR_MECHANISM_INVALID;
 
        // Get the keys
-       PrivateKey* privateKey = ecdh->newPrivateKey();
+       PrivateKey* privateKey = eddsa->newPrivateKey();
        if (privateKey == NULL)
        {
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
                return CKR_HOST_MEMORY;
        }
-       if (getECPrivateKey((ECPrivateKey*)privateKey, token, baseKey) != CKR_OK)
+       if (getEDPrivateKey((EDPrivateKey*)privateKey, token, baseKey) != CKR_OK)
        {
-               ecdh->recyclePrivateKey(privateKey);
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+               eddsa->recyclePrivateKey(privateKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
                return CKR_GENERAL_ERROR;
        }
 
@@ -9971,28 +10918,28 @@ CK_RV SoftHSM::deriveECDH
        memcpy(&publicData[0],
               CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->pPublicData,
               CK_ECDH1_DERIVE_PARAMS_PTR(pMechanism->pParameter)->ulPublicDataLen);
-       PublicKey* publicKey = ecdh->newPublicKey();
+       PublicKey* publicKey = eddsa->newPublicKey();
        if (publicKey == NULL)
        {
-               ecdh->recyclePrivateKey(privateKey);
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+               eddsa->recyclePrivateKey(privateKey);
+               CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
                return CKR_HOST_MEMORY;
        }
-       if (getECDHPublicKey((ECPublicKey*)publicKey, (ECPrivateKey*)privateKey, publicData) != CKR_OK)
+       if (getEDDHPublicKey((EDPublicKey*)publicKey, (EDPrivateKey*)privateKey, publicData) != CKR_OK)
        {
-               ecdh->recyclePrivateKey(privateKey);
-               ecdh->recyclePublicKey(publicKey);
-               CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+               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 (!ecdh->deriveKey(&secret, publicKey, privateKey))
+       if (!eddsa->deriveKey(&secret, publicKey, privateKey))
                rv = CKR_GENERAL_ERROR;
-       ecdh->recyclePrivateKey(privateKey);
-       ecdh->recyclePublicKey(publicKey);
+       eddsa->recyclePrivateKey(privateKey);
+       eddsa->recyclePublicKey(publicKey);
 
        // Create the secret object using C_CreateObject
        const CK_ULONG maxAttribs = 32;
@@ -10154,8 +11101,8 @@ CK_RV SoftHSM::deriveECDH
        }
 
        // Clean up
-       ecdh->recycleSymmetricKey(secret);
-       CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+       eddsa->recycleSymmetricKey(secret);
+       CryptoFactory::i()->recycleAsymmetricAlgorithm(eddsa);
 
        // Remove secret that may have been created already when the function fails.
        if (rv != CKR_OK)
@@ -10170,10 +11117,8 @@ CK_RV SoftHSM::deriveECDH
        }
 
        return rv;
-#else
-       return CKR_MECHANISM_INVALID;
-#endif
 }
+#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)
index 323f3a5..6456cbe 100644 (file)
@@ -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);
index bf18b1a..29f5c7a 100644 (file)
@@ -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:
index ca0d840..b0f02fd 100644 (file)
@@ -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
        };
 };
 
index b4df224..405570c 100644 (file)
@@ -53,6 +53,9 @@
 #include "BotanGOSTR3411.h"
 #endif
 #include "BotanMAC.h"
+#ifdef WITH_EDDSA
+#include "BotanEDDSA.h"
+#endif
 
 #include <botan/init.h>
 
@@ -175,6 +178,10 @@ AsymmetricAlgorithm* BotanCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type a
 #ifdef WITH_GOST
                case AsymAlgo::GOST:
                        return new BotanGOST();
+#endif
+#ifdef WITH_EDDSA
+               case AsymAlgo::EDDSA:
+                       return new BotanEDDSA();
 #endif
                default:
                        // No algorithm implementation is available
diff --git a/SoftHSMv2/src/lib/crypto/BotanEDDSA.cpp b/SoftHSMv2/src/lib/crypto/BotanEDDSA.cpp
new file mode 100644 (file)
index 0000000..f5c7bd5
--- /dev/null
@@ -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 (file)
index 0000000..552bca4
--- /dev/null
@@ -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 (file)
index 0000000..3e967e5
--- /dev/null
@@ -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 (file)
index 0000000..4f2cffe
--- /dev/null
@@ -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 (file)
index 0000000..bef9e7b
--- /dev/null
@@ -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 (file)
index 0000000..ac236bb
--- /dev/null
@@ -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 (file)
index 0000000..3cf8474
--- /dev/null
@@ -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 (file)
index 0000000..15e6d45
--- /dev/null
@@ -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
index e5da460..c623fed 100644 (file)
@@ -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
index 67f6ca6..ca86041 100644 (file)
@@ -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 (file)
index 0000000..1117b2e
--- /dev/null
@@ -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 (file)
index 0000000..d4df5fb
--- /dev/null
@@ -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 (file)
index 0000000..23f9f71
--- /dev/null
@@ -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 (file)
index 0000000..778cf34
--- /dev/null
@@ -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 (file)
index 0000000..cd7033e
--- /dev/null
@@ -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 (file)
index 0000000..0d60634
--- /dev/null
@@ -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
+
index f65e0a4..e23848f 100644 (file)
@@ -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 \
index 4bced32..5b2a424 100644 (file)
@@ -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);
index ad27482..04d383d 100644 (file)
@@ -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
 
@@ -290,6 +318,10 @@ AsymmetricAlgorithm* OSSLCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type al
 #ifdef WITH_GOST
                case AsymAlgo::GOST:
                        return new OSSLGOST();
+#endif
+#ifdef WITH_EDDSA
+               case AsymAlgo::EDDSA:
+                       return new OSSLEDDSA();
 #endif
                default:
                        // No algorithm implementation is available
index e8bfa2c..d718b69 100644 (file)
 #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 (file)
index 0000000..8fde7e2
--- /dev/null
@@ -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 (file)
index 0000000..02b8a11
--- /dev/null
@@ -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 (file)
index 0000000..c452785
--- /dev/null
@@ -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 (file)
index 0000000..3efe9f4
--- /dev/null
@@ -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 (file)
index 0000000..7c91b54
--- /dev/null
@@ -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 (file)
index 0000000..f097718
--- /dev/null
@@ -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 (file)
index 0000000..e4515ff
--- /dev/null
@@ -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 (file)
index 0000000..6951a2b
--- /dev/null
@@ -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
+
index 981bb98..3a9c742 100644 (file)
@@ -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
index f353cc6..7b86c50 100644 (file)
@@ -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 (file)
index 0000000..ecb6078
--- /dev/null
@@ -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 (file)
index 0000000..1f9da74
--- /dev/null
@@ -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
+
index bf63ae6..4065ef9 100644 (file)
@@ -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
index 85aa4d7..0c21bdb 100644 (file)
@@ -14,4 +14,5 @@ libsofthsm_datamgr_la_SOURCES =       ByteString.cpp \
 
 SUBDIRS =                      test
 
-EXTRA_DIST =                   $(srcdir)/*.h
+EXTRA_DIST =                   $(srcdir)/CMakeLists.txt \
+                               $(srcdir)/*.h
index e1ebcdd..59039cb 100644 (file)
@@ -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
index 108f74d..b588009 100644 (file)
@@ -14,4 +14,5 @@ libsofthsm_handlemgr_la_SOURCES =     HandleManager.cpp \
 
 SUBDIRS =                              test
 
-EXTRA_DIST =                           $(srcdir)/*.h
+EXTRA_DIST =                           $(srcdir)/CMakeLists.txt \
+                                       $(srcdir)/*.h
index 8d110b0..536a7b5 100644 (file)
@@ -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
 
index a55a32a..bf40bc8 100644 (file)
@@ -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;
index d3e89d3..6af0d2c 100644 (file)
@@ -31,4 +31,5 @@ libsofthsm_objectstore_la_LDFLAGS =   @SQLITE3_LIBS@
 
 SUBDIRS =                              test
 
-EXTRA_DIST =                           $(srcdir)/*.h
+EXTRA_DIST =                           $(srcdir)/CMakeLists.txt \
+                                       $(srcdir)/*.h
index d856b06..22d252c 100644 (file)
@@ -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;
index d787a83..0e68358 100644 (file)
@@ -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);
index 71de7dd..0ba05c1 100644 (file)
@@ -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
index 9f0f5bd..f3c3ae5 100644 (file)
@@ -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;
index 6183ec6..20d9052 100644 (file)
@@ -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;
index 0d78dd7..9d31ce8 100644 (file)
-/* 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 */
+
+\f
+/* 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 (file)
index ed90aff..0000000
+++ /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 (file)
index 0cf3acc..0000000
+++ /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_ */
-
index 5186d33..f696b14 100644 (file)
@@ -14,4 +14,5 @@ libsofthsm_sessionmgr_la_SOURCES =    SessionManager.cpp \
 
 SUBDIRS =                              test
 
-EXTRA_DIST =                           $(srcdir)/*.h
+EXTRA_DIST =                           $(srcdir)/CMakeLists.txt \
+                                       $(srcdir)/*.h
index 6395038..36233b9 100644 (file)
@@ -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
index 1e8cf33..db407fa 100644 (file)
@@ -15,4 +15,5 @@ libsofthsm_slotmgr_la_SOURCES =       SlotManager.cpp \
 
 SUBDIRS =                      test
 
-EXTRA_DIST =                   $(srcdir)/*.h
+EXTRA_DIST =                   $(srcdir)/CMakeLists.txt \
+                               $(srcdir)/*.h
index 8e2d161..3793cf9 100644 (file)
@@ -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
index 588d0b9..eb8aba5 100644 (file)
@@ -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;
index 5b2aef5..a6a94f0 100644 (file)
@@ -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,7 +70,12 @@ 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);
index 3723399..657f187 100644 (file)
@@ -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
index 06dbf95..c68ed08 100644 (file)
@@ -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
index a251218..6c99564 100644 (file)
@@ -44,6 +44,9 @@ class SignVerifyTests : public TestsBase
        CPPUNIT_TEST(testRsaSignVerify);
 #ifdef WITH_ECC
        CPPUNIT_TEST(testEcSignVerify);
+#endif
+#ifdef WITH_EDDSA
+       CPPUNIT_TEST(testEdSignVerify);
 #endif
        CPPUNIT_TEST(testMacSignVerify);
        CPPUNIT_TEST_SUITE_END();
@@ -52,6 +55,9 @@ public:
        void testRsaSignVerify();
 #ifdef WITH_ECC
        void testEcSignVerify();
+#endif
+#ifdef WITH_EDDSA
+       void testEdSignVerify();
 #endif
        void testMacSignVerify();
 
@@ -59,6 +65,9 @@ protected:
        CK_RV generateRSA(CK_SESSION_HANDLE hSession, CK_BBOOL bTokenPuk, CK_BBOOL bPrivatePuk, CK_BBOOL bTokenPrk, CK_BBOOL bPrivatePrk, CK_OBJECT_HANDLE &hPuk, CK_OBJECT_HANDLE &hPrk);
 #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);
index bbc340c..1965a35 100644 (file)
@@ -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);
+}
index 76191d9..19c3529 100644 (file)
@@ -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);
index f5bb066..3ca514b 100644 (file)
@@ -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 (file)
index 68cb2ec..0000000
+++ /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 (file)
index a877d1f..0000000
+++ /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 (file)
index 0000000..b2347b0
--- /dev/null
@@ -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 (file)
index 0000000..56a0d0b
--- /dev/null
@@ -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
index fc31217..2f8d10d 100644 (file)
@@ -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
index 6a1ca1f..826fbc4 100644 (file)
@@ -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
        ;;
 *)
index bb2a06e..6365435 100644 (file)
--- a/build.sh
+++ b/build.sh
@@ -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 ..