aboutsummaryrefslogtreecommitdiffstats
path: root/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp')
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp308
1 files changed, 308 insertions, 0 deletions
diff --git a/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp
new file mode 100644
index 0000000..b4df224
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * 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.
+ */
+
+/*****************************************************************************
+ BotanCryptoFactory.cpp
+
+ This is a Botan based cryptographic algorithm factory
+ *****************************************************************************/
+#include "config.h"
+#include "BotanCryptoFactory.h"
+#include "BotanAES.h"
+#include "BotanDES.h"
+#include "BotanDSA.h"
+#include "BotanDH.h"
+#ifdef WITH_ECC
+#include "BotanECDH.h"
+#include "BotanECDSA.h"
+#endif
+#include "BotanMD5.h"
+#include "BotanRNG.h"
+#include "BotanRSA.h"
+#include "BotanSHA1.h"
+#include "BotanSHA224.h"
+#include "BotanSHA256.h"
+#include "BotanSHA384.h"
+#include "BotanSHA512.h"
+#ifdef WITH_GOST
+#include "BotanGOST.h"
+#include "BotanGOSTR3411.h"
+#endif
+#include "BotanMAC.h"
+
+#include <botan/init.h>
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+#include <botan/libstate.h>
+#endif
+
+// Constructor
+BotanCryptoFactory::BotanCryptoFactory()
+{
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ wasInitialized = false;
+
+ // Check if Botan has already been initialized
+ if (Botan::Global_State_Management::global_state_exists())
+ {
+ wasInitialized = true;
+ }
+
+ // Init the Botan crypto library
+ if (!wasInitialized)
+ {
+ Botan::LibraryInitializer::initialize("thread_safe=true");
+ }
+#else
+ Botan::LibraryInitializer::initialize("thread_safe=true");
+#endif
+
+ // Create mutex
+ rngsMutex = MutexFactory::i()->getMutex();
+}
+
+// Destructor
+BotanCryptoFactory::~BotanCryptoFactory()
+{
+ // Delete the RNGs
+#ifdef HAVE_PTHREAD_H
+ std::map<pthread_t,RNG*>::iterator it;
+ for (it=rngs.begin(); it != rngs.end(); it++)
+ {
+ delete (BotanRNG*)it->second;
+ }
+#elif _WIN32
+ std::map<DWORD,RNG*>::iterator it;
+ for (it=rngs.begin(); it != rngs.end(); it++)
+ {
+ delete (BotanRNG*)it->second;
+ }
+#endif
+
+ // Delete the mutex
+ MutexFactory::i()->recycleMutex(rngsMutex);
+
+ // Deinitialize the Botan crypto lib
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ if (!wasInitialized)
+ {
+ Botan::LibraryInitializer::deinitialize();
+ }
+#else
+ Botan::LibraryInitializer::deinitialize();
+#endif
+}
+
+// Return the one-and-only instance
+BotanCryptoFactory* BotanCryptoFactory::i()
+{
+ if (!instance.get())
+ {
+ instance.reset(new BotanCryptoFactory());
+ }
+
+ return instance.get();
+}
+
+// This will destroy the one-and-only instance.
+void BotanCryptoFactory::reset()
+{
+ instance.reset();
+}
+
+// Create a concrete instance of a symmetric algorithm
+SymmetricAlgorithm* BotanCryptoFactory::getSymmetricAlgorithm(SymAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case SymAlgo::AES:
+ return new BotanAES();
+ case SymAlgo::DES:
+ case SymAlgo::DES3:
+ return new BotanDES();
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of an asymmetric algorithm
+AsymmetricAlgorithm* BotanCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case AsymAlgo::RSA:
+ return new BotanRSA();
+ case AsymAlgo::DSA:
+ return new BotanDSA();
+ case AsymAlgo::DH:
+ return new BotanDH();
+#ifdef WITH_ECC
+ case AsymAlgo::ECDH:
+ return new BotanECDH();
+ case AsymAlgo::ECDSA:
+ return new BotanECDSA();
+#endif
+#ifdef WITH_GOST
+ case AsymAlgo::GOST:
+ return new BotanGOST();
+#endif
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of a hash algorithm
+HashAlgorithm* BotanCryptoFactory::getHashAlgorithm(HashAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case HashAlgo::MD5:
+ return new BotanMD5();
+ case HashAlgo::SHA1:
+ return new BotanSHA1();
+ case HashAlgo::SHA224:
+ return new BotanSHA224();
+ case HashAlgo::SHA256:
+ return new BotanSHA256();
+ case HashAlgo::SHA384:
+ return new BotanSHA384();
+ case HashAlgo::SHA512:
+ return new BotanSHA512();
+#ifdef WITH_GOST
+ case HashAlgo::GOST:
+ return new BotanGOSTR3411();
+#endif
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of a MAC algorithm
+MacAlgorithm* BotanCryptoFactory::getMacAlgorithm(MacAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case MacAlgo::HMAC_MD5:
+ return new BotanHMACMD5();
+ case MacAlgo::HMAC_SHA1:
+ return new BotanHMACSHA1();
+ case MacAlgo::HMAC_SHA224:
+ return new BotanHMACSHA224();
+ case MacAlgo::HMAC_SHA256:
+ return new BotanHMACSHA256();
+ case MacAlgo::HMAC_SHA384:
+ return new BotanHMACSHA384();
+ case MacAlgo::HMAC_SHA512:
+ return new BotanHMACSHA512();
+#ifdef WITH_GOST
+ case MacAlgo::HMAC_GOST:
+ return new BotanHMACGOSTR3411();
+#endif
+ case MacAlgo::CMAC_DES:
+ return new BotanCMACDES();
+ case MacAlgo::CMAC_AES:
+ return new BotanCMACAES();
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Get the global RNG (may be an unique RNG per thread)
+RNG* BotanCryptoFactory::getRNG(RNGImpl::Type name /* = RNGImpl::Default */)
+{
+ if (name == RNGImpl::Default)
+ {
+ RNG *threadRNG = NULL;
+
+ // Lock access to the map
+ MutexLocker lock(rngsMutex);
+
+#ifdef HAVE_PTHREAD_H
+ // Get thread ID
+ pthread_t threadID = pthread_self();
+
+ // Find the RNG
+ std::map<pthread_t,RNG*>::iterator findIt;
+ findIt=rngs.find(threadID);
+ if (findIt != rngs.end())
+ {
+ return findIt->second;
+ }
+
+ threadRNG = new BotanRNG();
+ rngs[threadID] = threadRNG;
+#elif _WIN32
+ // Get thread ID
+ DWORD threadID = GetCurrentThreadId();
+
+ // Find the RNG
+ std::map<DWORD,RNG*>::iterator findIt;
+ findIt=rngs.find(threadID);
+ if (findIt != rngs.end())
+ {
+ return findIt->second;
+ }
+
+ threadRNG = new BotanRNG();
+ rngs[threadID] = threadRNG;
+#else
+#error "There are no thread-specific data implementations for your operating system yet"
+#endif
+ return threadRNG;
+ }
+ else
+ {
+ // No RNG implementation is available
+ ERROR_MSG("Unknown RNG '%i'", name);
+
+ return NULL;
+ }
+}