From 0c89b3ccba7c9b7332ab67ae1936aff51ca62367 Mon Sep 17 00:00:00 2001 From: NingSun Date: Thu, 8 Feb 2018 08:34:03 -0800 Subject: Initial sshsm project structure Issue-ID: AAF-94 Change-Id: I5e82fff418e7567b161acf9b98013a9b85ffc5b4 Signed-off-by: NingSun --- SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp | 388 +++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp (limited to 'SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp') diff --git a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp new file mode 100644 index 0000000..ad27482 --- /dev/null +++ b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp @@ -0,0 +1,388 @@ +/* + * 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. + */ + +/***************************************************************************** + OSSLCryptoFactory.cpp + + This is an OpenSSL based cryptographic algorithm factory + *****************************************************************************/ + +#include "config.h" +#include "MutexFactory.h" +#include "OSSLCryptoFactory.h" +#include "OSSLRNG.h" +#include "OSSLAES.h" +#include "OSSLDES.h" +#include "OSSLMD5.h" +#include "OSSLSHA1.h" +#include "OSSLSHA224.h" +#include "OSSLSHA256.h" +#include "OSSLSHA384.h" +#include "OSSLSHA512.h" +#include "OSSLCMAC.h" +#include "OSSLHMAC.h" +#include "OSSLRSA.h" +#include "OSSLDSA.h" +#include "OSSLDH.h" +#ifdef WITH_ECC +#include "OSSLECDH.h" +#include "OSSLECDSA.h" +#endif +#ifdef WITH_GOST +#include "OSSLGOSTR3411.h" +#include "OSSLGOST.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_GOST +#include +#endif + +#ifdef WITH_FIPS +// Initialise the FIPS 140-2 selftest status +bool OSSLCryptoFactory::FipsSelfTestStatus = false; +#endif + +static unsigned nlocks; +static Mutex** locks; + +// Mutex callback +void lock_callback(int mode, int n, const char* file, int line) +{ + if ((unsigned) n >= nlocks) + { + ERROR_MSG("out of range [0..%u[ lock %d at %s:%d", + nlocks, n, file, line); + + return; + } + + Mutex* mtx = locks[(unsigned) n]; + + if (mode & CRYPTO_LOCK) + { + mtx->lock(); + } + else + { + mtx->unlock(); + } +} + +// Constructor +OSSLCryptoFactory::OSSLCryptoFactory() +{ + // Multi-thread support + nlocks = CRYPTO_num_locks(); + locks = new Mutex*[nlocks]; + for (unsigned i = 0; i < nlocks; i++) + { + locks[i] = MutexFactory::i()->getMutex(); + } + +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + setLockingCallback = false; + if (CRYPTO_get_locking_callback() == NULL) + { + CRYPTO_set_locking_callback(lock_callback); + setLockingCallback = true; + } +#endif + +#ifdef WITH_FIPS + // Already in FIPS mode on reenter (avoiding selftests) + if (!FIPS_mode()) + { + FipsSelfTestStatus = false; + if (!FIPS_mode_set(1)) + { + ERROR_MSG("can't enter into FIPS mode"); + return; + } + } else { + // Undo RAND_cleanup() + RAND_init_fips(); + } + FipsSelfTestStatus = true; +#endif + + // Initialise OpenSSL + OpenSSL_add_all_algorithms(); + + // Initialise the one-and-only RNG + rng = new OSSLRNG(); + +#ifdef WITH_GOST + // 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) + { + ERROR_MSG("can't get the GOST engine"); + return; + } + if (ENGINE_init(eg) <= 0) + { + ENGINE_free(eg); + eg = NULL; + ERROR_MSG("can't initialize the GOST engine"); + return; + } + // better than digest_gost + EVP_GOST_34_11 = ENGINE_get_digest(eg, NID_id_GostR3411_94); + if (EVP_GOST_34_11 == NULL) + { + ERROR_MSG("can't get the GOST digest"); + goto err; + } + // from the openssl.cnf + if (ENGINE_register_pkey_asn1_meths(eg) <= 0) + { + ERROR_MSG("can't register ASN.1 for the GOST engine"); + goto err; + } + if (ENGINE_ctrl_cmd_string(eg, + "CRYPT_PARAMS", + "id-Gost28147-89-CryptoPro-A-ParamSet", + 0) <= 0) + { + ERROR_MSG("can't set params of the GOST engine"); + goto err; + } + return; + +err: + ENGINE_finish(eg); + ENGINE_free(eg); + eg = NULL; + return; +#endif +} + +// Destructor +OSSLCryptoFactory::~OSSLCryptoFactory() +{ +#ifdef WITH_GOST + // Finish the GOST engine + if (eg != NULL) + { + ENGINE_finish(eg); + ENGINE_free(eg); + eg = NULL; + } +#endif + + // Destroy the one-and-only RNG + delete rng; + + // Recycle locks +#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + if (setLockingCallback) + { + CRYPTO_set_locking_callback(NULL); + } +#endif + for (unsigned i = 0; i < nlocks; i++) + { + MutexFactory::i()->recycleMutex(locks[i]); + } + delete[] locks; +} + +// Return the one-and-only instance +OSSLCryptoFactory* OSSLCryptoFactory::i() +{ + if (!instance.get()) + { + instance.reset(new OSSLCryptoFactory()); + } + + return instance.get(); +} + +// This will destroy the one-and-only instance. +void OSSLCryptoFactory::reset() +{ + instance.reset(); +} + +#ifdef WITH_FIPS +bool OSSLCryptoFactory::getFipsSelfTestStatus() const +{ + return FipsSelfTestStatus; +} +#endif + +// Create a concrete instance of a symmetric algorithm +SymmetricAlgorithm* OSSLCryptoFactory::getSymmetricAlgorithm(SymAlgo::Type algorithm) +{ + switch (algorithm) + { + case SymAlgo::AES: + return new OSSLAES(); + case SymAlgo::DES: + case SymAlgo::DES3: + return new OSSLDES(); + 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* OSSLCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type algorithm) +{ + switch (algorithm) + { + case AsymAlgo::RSA: + return new OSSLRSA(); + case AsymAlgo::DSA: + return new OSSLDSA(); + case AsymAlgo::DH: + return new OSSLDH(); +#ifdef WITH_ECC + case AsymAlgo::ECDH: + return new OSSLECDH(); + case AsymAlgo::ECDSA: + return new OSSLECDSA(); +#endif +#ifdef WITH_GOST + case AsymAlgo::GOST: + return new OSSLGOST(); +#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* OSSLCryptoFactory::getHashAlgorithm(HashAlgo::Type algorithm) +{ + switch (algorithm) + { + case HashAlgo::MD5: + return new OSSLMD5(); + case HashAlgo::SHA1: + return new OSSLSHA1(); + case HashAlgo::SHA224: + return new OSSLSHA224(); + case HashAlgo::SHA256: + return new OSSLSHA256(); + case HashAlgo::SHA384: + return new OSSLSHA384(); + case HashAlgo::SHA512: + return new OSSLSHA512(); +#ifdef WITH_GOST + case HashAlgo::GOST: + return new OSSLGOSTR3411(); +#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* OSSLCryptoFactory::getMacAlgorithm(MacAlgo::Type algorithm) +{ + switch (algorithm) + { + case MacAlgo::HMAC_MD5: + return new OSSLHMACMD5(); + case MacAlgo::HMAC_SHA1: + return new OSSLHMACSHA1(); + case MacAlgo::HMAC_SHA224: + return new OSSLHMACSHA224(); + case MacAlgo::HMAC_SHA256: + return new OSSLHMACSHA256(); + case MacAlgo::HMAC_SHA384: + return new OSSLHMACSHA384(); + case MacAlgo::HMAC_SHA512: + return new OSSLHMACSHA512(); +#ifdef WITH_GOST + case MacAlgo::HMAC_GOST: + return new OSSLHMACGOSTR3411(); +#endif + case MacAlgo::CMAC_DES: + return new OSSLCMACDES(); + case MacAlgo::CMAC_AES: + return new OSSLCMACAES(); + 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* OSSLCryptoFactory::getRNG(RNGImpl::Type name /* = RNGImpl::Default */) +{ + if (name == RNGImpl::Default) + { + return rng; + } + else + { + // No RNG implementation is available + ERROR_MSG("Unknown RNG '%i'", name); + + return NULL; + } +} + -- cgit 1.2.3-korg