diff options
Diffstat (limited to 'lib/crypto')
-rw-r--r-- | lib/crypto/CipherAES.cpp | 201 | ||||
-rw-r--r-- | lib/crypto/CipherAES.h | 88 | ||||
-rw-r--r-- | lib/crypto/CipherBlowfish.cpp | 258 | ||||
-rw-r--r-- | lib/crypto/CipherBlowfish.h | 98 | ||||
-rw-r--r-- | lib/crypto/CipherContext.cpp | 653 | ||||
-rw-r--r-- | lib/crypto/CipherContext.h | 121 | ||||
-rw-r--r-- | lib/crypto/CipherDescription.cpp | 111 | ||||
-rw-r--r-- | lib/crypto/CipherDescription.h | 97 | ||||
-rw-r--r-- | lib/crypto/CipherException.h | 55 | ||||
-rw-r--r-- | lib/crypto/CipherException.txt | 18 | ||||
-rw-r--r-- | lib/crypto/MD5Digest.cpp | 120 | ||||
-rw-r--r-- | lib/crypto/MD5Digest.h | 95 | ||||
-rw-r--r-- | lib/crypto/Makefile.extra | 7 | ||||
-rw-r--r-- | lib/crypto/Random.cpp | 165 | ||||
-rw-r--r-- | lib/crypto/Random.h | 63 | ||||
-rw-r--r-- | lib/crypto/RollingChecksum.cpp | 100 | ||||
-rw-r--r-- | lib/crypto/RollingChecksum.h | 145 |
17 files changed, 2395 insertions, 0 deletions
diff --git a/lib/crypto/CipherAES.cpp b/lib/crypto/CipherAES.cpp new file mode 100644 index 00000000..a8eb63f5 --- /dev/null +++ b/lib/crypto/CipherAES.cpp @@ -0,0 +1,201 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherAES.cpp +// Purpose: AES cipher description +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- + +#include "Box.h" + +// Only available in new versions of openssl +#ifndef HAVE_OLD_SSL + +#include <openssl/evp.h> + +#define BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_TRUE + +#include "CipherAES.h" +#include "CipherException.h" + +#include "MemLeakFindOn.h" + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherAES::CipherAES(CipherDescription::CipherMode, const void *, unsigned int, const void *) +// Purpose: Constructor -- note key material and IV are not copied. KeyLength in bytes. +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +CipherAES::CipherAES(CipherDescription::CipherMode Mode, const void *pKey, unsigned int KeyLength, const void *pInitialisationVector) + : CipherDescription(), + mMode(Mode), + mpKey(pKey), + mKeyLength(KeyLength), + mpInitialisationVector(pInitialisationVector) +{ +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherAES::CipherAES(const CipherAES &) +// Purpose: Copy constructor +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +CipherAES::CipherAES(const CipherAES &rToCopy) + : CipherDescription(rToCopy), + mMode(rToCopy.mMode), + mpKey(rToCopy.mpKey), + mKeyLength(rToCopy.mKeyLength), + mpInitialisationVector(rToCopy.mpInitialisationVector) +{ +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: ~CipherAES::CipherAES() +// Purpose: Destructor +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +CipherAES::~CipherAES() +{ +} + + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherAES::operator=(const CipherAES &) +// Purpose: Assignment operator +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +CipherAES &CipherAES::operator=(const CipherAES &rToCopy) +{ + CipherDescription::operator=(rToCopy); + + mMode = rToCopy.mMode; + mpKey = rToCopy.mpKey; + mKeyLength = rToCopy.mKeyLength; + mpInitialisationVector = rToCopy.mpInitialisationVector; + + return *this; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherAES::GetCipher() +// Purpose: Returns cipher object +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +const EVP_CIPHER *CipherAES::GetCipher() const +{ + switch(mMode) + { + case CipherDescription::Mode_ECB: + switch(mKeyLength) + { + case (128/8): return EVP_aes_128_ecb(); break; + case (192/8): return EVP_aes_192_ecb(); break; + case (256/8): return EVP_aes_256_ecb(); break; + default: + THROW_EXCEPTION(CipherException, EVPBadKeyLength) + break; + } + break; + + case CipherDescription::Mode_CBC: + switch(mKeyLength) + { + case (128/8): return EVP_aes_128_cbc(); break; + case (192/8): return EVP_aes_192_cbc(); break; + case (256/8): return EVP_aes_256_cbc(); break; + default: + THROW_EXCEPTION(CipherException, EVPBadKeyLength) + break; + } + break; + + default: + break; + } + + // Unknown! + THROW_EXCEPTION(CipherException, UnknownCipherMode) +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherAES::SetupParameters(EVP_CIPHER_CTX *) +// Purpose: Set up various parameters for cipher +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +void CipherAES::SetupParameters(EVP_CIPHER_CTX *pCipherContext) const +{ + ASSERT(pCipherContext != 0); + + // Set key (key length is implied) + if(EVP_CipherInit_ex(pCipherContext, NULL, NULL, (unsigned char*)mpKey, (unsigned char*)mpInitialisationVector, -1) != 1) + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + +} + + + +#endif // n HAVE_OLD_SSL + diff --git a/lib/crypto/CipherAES.h b/lib/crypto/CipherAES.h new file mode 100644 index 00000000..3574b86f --- /dev/null +++ b/lib/crypto/CipherAES.h @@ -0,0 +1,88 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherAES.h +// Purpose: AES cipher description +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- + +#ifndef CIPHERAES__H +#define CIPHERAES__H + +// Only available in new versions of openssl +#ifndef HAVE_OLD_SSL + +#include "CipherDescription.h" + +// -------------------------------------------------------------------------- +// +// Class +// Name: CipherAES +// Purpose: AES cipher description +// Created: 27/4/04 +// +// -------------------------------------------------------------------------- +class CipherAES : public CipherDescription +{ +public: + CipherAES(CipherDescription::CipherMode Mode, const void *pKey, unsigned int KeyLength, const void *pInitialisationVector = 0); + CipherAES(const CipherAES &rToCopy); + virtual ~CipherAES(); + CipherAES &operator=(const CipherAES &rToCopy); + + // Return OpenSSL cipher object + virtual const EVP_CIPHER *GetCipher() const; + + // Setup any other parameters + virtual void SetupParameters(EVP_CIPHER_CTX *pCipherContext) const; + +private: + CipherDescription::CipherMode mMode; + const void *mpKey; + unsigned int mKeyLength; + const void *mpInitialisationVector; +}; + +#endif // n HAVE_OLD_SSL + +#endif // CIPHERAES__H + diff --git a/lib/crypto/CipherBlowfish.cpp b/lib/crypto/CipherBlowfish.cpp new file mode 100644 index 00000000..6997560e --- /dev/null +++ b/lib/crypto/CipherBlowfish.cpp @@ -0,0 +1,258 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherBlowfish.cpp +// Purpose: Blowfish cipher description +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- + +#include "Box.h" + +#include <openssl/evp.h> + +#ifdef HAVE_OLD_SSL + #include <string.h> + #include <strings.h> +#endif + +#define BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_TRUE + +#include "CipherBlowfish.h" +#include "CipherException.h" + +#include "MemLeakFindOn.h" + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherBlowfish::CipherBlowfish(CipherDescription::CipherMode, const void *, unsigned int, const void *) +// Purpose: Constructor -- note key material and IV are not copied. KeyLength in bytes. +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherBlowfish::CipherBlowfish(CipherDescription::CipherMode Mode, const void *pKey, unsigned int KeyLength, const void *pInitialisationVector) + : CipherDescription(), + mMode(Mode) +#ifndef HAVE_OLD_SSL + , mpKey(pKey), + mKeyLength(KeyLength), + mpInitialisationVector(pInitialisationVector) +{ +} +#else +{ + mKey.assign((const char *)pKey, KeyLength); + if(pInitialisationVector == 0) + { + bzero(mInitialisationVector, sizeof(mInitialisationVector)); + } + else + { + ::memcpy(mInitialisationVector, pInitialisationVector, sizeof(mInitialisationVector)); + } +} +#endif + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherBlowfish::CipherBlowfish(const CipherBlowfish &) +// Purpose: Copy constructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherBlowfish::CipherBlowfish(const CipherBlowfish &rToCopy) + : CipherDescription(rToCopy), + mMode(rToCopy.mMode), +#ifndef HAVE_OLD_SSL + mpKey(rToCopy.mpKey), + mKeyLength(rToCopy.mKeyLength), + mpInitialisationVector(rToCopy.mpInitialisationVector) +{ +} +#else + mKey(rToCopy.mKey) +{ + ::memcpy(mInitialisationVector, rToCopy.mInitialisationVector, sizeof(mInitialisationVector)); +} +#endif + + +#ifdef HAVE_OLD_SSL +// Hack functions to support old OpenSSL API +CipherDescription *CipherBlowfish::Clone() const +{ + return new CipherBlowfish(*this); +} +void CipherBlowfish::SetIV(const void *pIV) +{ + if(pIV == 0) + { + bzero(mInitialisationVector, sizeof(mInitialisationVector)); + } + else + { + ::memcpy(mInitialisationVector, pIV, sizeof(mInitialisationVector)); + } +} +#endif + + +// -------------------------------------------------------------------------- +// +// Function +// Name: ~CipherBlowfish::CipherBlowfish() +// Purpose: Destructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherBlowfish::~CipherBlowfish() +{ +#ifdef HAVE_OLD_SSL + // Zero copy of key + for(unsigned int l = 0; l < mKey.size(); ++l) + { + mKey[l] = '\0'; + } +#endif +} + + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherBlowfish::operator=(const CipherBlowfish &) +// Purpose: Assignment operator +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherBlowfish &CipherBlowfish::operator=(const CipherBlowfish &rToCopy) +{ + CipherDescription::operator=(rToCopy); + + mMode = rToCopy.mMode; +#ifndef HAVE_OLD_SSL + mpKey = rToCopy.mpKey; + mKeyLength = rToCopy.mKeyLength; + mpInitialisationVector = rToCopy.mpInitialisationVector; +#else + mKey = rToCopy.mKey; + ::memcpy(mInitialisationVector, rToCopy.mInitialisationVector, sizeof(mInitialisationVector)); +#endif + + return *this; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherBlowfish::GetCipher() +// Purpose: Returns cipher object +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +const EVP_CIPHER *CipherBlowfish::GetCipher() const +{ + switch(mMode) + { + case CipherDescription::Mode_ECB: + return EVP_bf_ecb(); + break; + + case CipherDescription::Mode_CBC: + return EVP_bf_cbc(); + break; + + case CipherDescription::Mode_CFB: + return EVP_bf_cfb(); + break; + + case CipherDescription::Mode_OFB: + return EVP_bf_ofb(); + break; + + default: + break; + } + + // Unknown! + THROW_EXCEPTION(CipherException, UnknownCipherMode) +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherBlowfish::SetupParameters(EVP_CIPHER_CTX *) +// Purpose: Set up various parameters for cipher +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +void CipherBlowfish::SetupParameters(EVP_CIPHER_CTX *pCipherContext) const +{ + ASSERT(pCipherContext != 0); + + // Set key length +#ifndef HAVE_OLD_SSL + if(EVP_CIPHER_CTX_set_key_length(pCipherContext, mKeyLength) != 1) +#else + if(EVP_CIPHER_CTX_set_key_length(pCipherContext, mKey.size()) != 1) +#endif + { + THROW_EXCEPTION(CipherException, EVPBadKeyLength) + } + // Set key +#ifndef HAVE_OLD_SSL + if(EVP_CipherInit_ex(pCipherContext, NULL, NULL, (unsigned char*)mpKey, (unsigned char*)mpInitialisationVector, -1) != 1) +#else + if(EVP_CipherInit(pCipherContext, NULL, (unsigned char*)mKey.c_str(), (unsigned char*)mInitialisationVector, -1) != 1) +#endif + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + +} + + + diff --git a/lib/crypto/CipherBlowfish.h b/lib/crypto/CipherBlowfish.h new file mode 100644 index 00000000..6cb862b3 --- /dev/null +++ b/lib/crypto/CipherBlowfish.h @@ -0,0 +1,98 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherBlowfish.h +// Purpose: Blowfish cipher description +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- + +#ifndef CIPHERBLOWFISH__H +#define CIPHERBLOWFISH__H + +#ifdef HAVE_OLD_SSL + #include <string> +#endif + +#include "CipherDescription.h" + +// -------------------------------------------------------------------------- +// +// Class +// Name: CipherBlowfish +// Purpose: Description of Blowfish cipher parameters -- note that copies are not made of key material and IV, careful with object lifetimes. +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +class CipherBlowfish : public CipherDescription +{ +public: + CipherBlowfish(CipherDescription::CipherMode Mode, const void *pKey, unsigned int KeyLength, const void *pInitialisationVector = 0); + CipherBlowfish(const CipherBlowfish &rToCopy); + virtual ~CipherBlowfish(); + CipherBlowfish &operator=(const CipherBlowfish &rToCopy); + + // Return OpenSSL cipher object + virtual const EVP_CIPHER *GetCipher() const; + + // Setup any other parameters + virtual void SetupParameters(EVP_CIPHER_CTX *pCipherContext) const; + +#ifdef HAVE_OLD_SSL + CipherDescription *Clone() const; + void SetIV(const void *pIV); +#endif + +private: + CipherDescription::CipherMode mMode; +#ifndef HAVE_OLD_SSL + const void *mpKey; + unsigned int mKeyLength; + const void *mpInitialisationVector; +#else + std::string mKey; + uint8_t mInitialisationVector[8]; +#endif +}; + + +#endif // CIPHERBLOWFISH__H + diff --git a/lib/crypto/CipherContext.cpp b/lib/crypto/CipherContext.cpp new file mode 100644 index 00000000..c31e613f --- /dev/null +++ b/lib/crypto/CipherContext.cpp @@ -0,0 +1,653 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherContext.cpp +// Purpose: Context for symmetric encryption / descryption +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- + +#include "Box.h" + +#define BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_TRUE +#include "CipherContext.h" +#include "CipherDescription.h" +#include "CipherException.h" +#include "Random.h" + +#include "MemLeakFindOn.h" + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::CipherContext() +// Purpose: Constructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherContext::CipherContext() + : mInitialised(false), + mWithinTransform(false), + mPaddingOn(true) +#ifdef HAVE_OLD_SSL + , mFunction(Decrypt), + mpDescription(0) +#endif +{ +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::~CipherContext() +// Purpose: Destructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherContext::~CipherContext() +{ + if(mInitialised) + { + // Clean up + EVP_CIPHER_CTX_cleanup(&ctx); + mInitialised = false; + } +#ifdef HAVE_OLD_SSL + if(mpDescription != 0) + { + delete mpDescription; + mpDescription = 0; + } +#endif +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::Init(CipherContext::CipherFunction, const CipherDescription &) +// Purpose: Initialises the context, specifying the direction for the encryption, and a +// description of the cipher to use, it's keys, etc +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +void CipherContext::Init(CipherContext::CipherFunction Function, const CipherDescription &rDescription) +{ + // Check for bad usage + if(mInitialised) + { + THROW_EXCEPTION(CipherException, AlreadyInitialised) + } + if(Function != Decrypt && Function != Encrypt) + { + THROW_EXCEPTION(CipherException, BadArguments) + } + + // Initialise the cipher +#ifndef HAVE_OLD_SSL + EVP_CIPHER_CTX_init(&ctx); // no error return code, even though the docs says it does + + if(EVP_CipherInit_ex(&ctx, rDescription.GetCipher(), NULL, NULL, NULL, Function) != 1) +#else + // Store function for later + mFunction = Function; + + // Use old version of init call + if(EVP_CipherInit(&ctx, rDescription.GetCipher(), NULL, NULL, Function) != 1) +#endif + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + + try + { +#ifndef HAVE_OLD_SSL + // Let the description set up everything else + rDescription.SetupParameters(&ctx); +#else + // With the old version, a copy needs to be taken first. + mpDescription = rDescription.Clone(); + // Mark it as not a leak, otherwise static cipher contexts cause supriously memory leaks to be reported + MEMLEAKFINDER_NOT_A_LEAK(mpDescription); + mpDescription->SetupParameters(&ctx); +#endif + } + catch(...) + { + EVP_CIPHER_CTX_cleanup(&ctx); + throw; + } + + // mark as initialised + mInitialised = true; +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::Reset() +// Purpose: Reset the context, so it can be initialised again with a different key +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +void CipherContext::Reset() +{ + if(mInitialised) + { + // Clean up + EVP_CIPHER_CTX_cleanup(&ctx); + mInitialised = false; + } +#ifdef HAVE_OLD_SSL + if(mpDescription != 0) + { + delete mpDescription; + mpDescription = 0; + } +#endif + mWithinTransform = false; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::Begin() +// Purpose: Begin a transformation +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +void CipherContext::Begin() +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + // Warn if in a transformation (not an error, because a context might not have been finalised if an exception occured) + if(mWithinTransform) + { + TRACE0("CipherContext::Begin called when context flagged as within a transform\n"); + } + + // Initialise the cipher context again + if(EVP_CipherInit(&ctx, NULL, NULL, NULL, -1) != 1) + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + + // Mark as being within a transform + mWithinTransform = true; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::Transform(void *, int, const void *, int) +// Purpose: Transforms the data in the in buffer to the out buffer. If pInBuffer == 0 && InLength == 0 +// then Final() is called instead. +// Returns the number of bytes placed in the out buffer. +// There must be room in the out buffer for all the data in the in buffer. +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +int CipherContext::Transform(void *pOutBuffer, int OutLength, const void *pInBuffer, int InLength) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + if(!mWithinTransform) + { + THROW_EXCEPTION(CipherException, BeginNotCalled) + } + + // Check parameters + if(pOutBuffer == 0 || OutLength < 0 || (pInBuffer != 0 && InLength <= 0) || (pInBuffer == 0 && InLength != 0)) + { + THROW_EXCEPTION(CipherException, BadArguments) + } + + // Is this the final call? + if(pInBuffer == 0) + { + return Final(pOutBuffer, OutLength); + } + + // Check output buffer size + if(OutLength < (InLength + EVP_CIPHER_CTX_block_size(&ctx))) + { + THROW_EXCEPTION(CipherException, OutputBufferTooSmall); + } + + // Do the transform + int outLength = OutLength; + if(EVP_CipherUpdate(&ctx, (unsigned char*)pOutBuffer, &outLength, (unsigned char*)pInBuffer, InLength) != 1) + { + THROW_EXCEPTION(CipherException, EVPUpdateFailure) + } + + return outLength; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::Final(void *, int) +// Purpose: Transforms the data as per Transform, and returns the final data in the out buffer. +// Returns the number of bytes written in the out buffer. +// Two main causes of exceptions being thrown: 1) Data is corrupt, and so the end isn't +// padded properly. 2) Padding is off, and the data to be encrypted isn't a multiple +// of a block long. +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +int CipherContext::Final(void *pOutBuffer, int OutLength) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + if(!mWithinTransform) + { + THROW_EXCEPTION(CipherException, BeginNotCalled) + } + + // Check parameters + if(pOutBuffer == 0 || OutLength < 0) + { + THROW_EXCEPTION(CipherException, BadArguments) + } + + // Check output buffer size + if(OutLength < (2 * EVP_CIPHER_CTX_block_size(&ctx))) + { + THROW_EXCEPTION(CipherException, OutputBufferTooSmall); + } + + // Do the transform + int outLength = OutLength; +#ifndef HAVE_OLD_SSL + if(EVP_CipherFinal_ex(&ctx, (unsigned char*)pOutBuffer, &outLength) != 1) + { + THROW_EXCEPTION(CipherException, EVPFinalFailure) + } +#else + OldOpenSSLFinal((unsigned char*)pOutBuffer, outLength); +#endif + + mWithinTransform = false; + + return outLength; +} + + +#ifdef HAVE_OLD_SSL +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::OldOpenSSLFinal(unsigned char *, int &) +// Purpose: The old version of OpenSSL needs more work doing to finalise the cipher, +// and reset it so that it's ready for another go. +// Created: 27/3/04 +// +// -------------------------------------------------------------------------- +void CipherContext::OldOpenSSLFinal(unsigned char *Buffer, int &rOutLengthOut) +{ + // Old version needs to use a different form, and then set up the cipher again for next time around + int outLength = rOutLengthOut; + // Have to emulate padding off... + int blockSize = EVP_CIPHER_CTX_block_size(&ctx); + if(mPaddingOn) + { + // Just use normal final call + if(EVP_CipherFinal(&ctx, Buffer, &outLength) != 1) + { + THROW_EXCEPTION(CipherException, EVPFinalFailure) + } + } + else + { + // Padding is off. OpenSSL < 0.9.7 doesn't support this, so it has to be + // bodged in there. Which isn't nice. + if(mFunction == Decrypt) + { + // NASTY -- fiddling around with internals like this is bad. + // But only way to get this working on old versions of OpenSSL. + if(!EVP_EncryptUpdate(&ctx,Buffer,&outLength,ctx.buf,0) + || outLength != blockSize) + { + THROW_EXCEPTION(CipherException, EVPFinalFailure) + } + // Clean up + EVP_CIPHER_CTX_cleanup(&ctx); + } + else + { + // Check that the length is correct + if((ctx.buf_len % blockSize) != 0) + { + THROW_EXCEPTION(CipherException, EVPFinalFailure) + } + // For encryption, assume that the last block entirely is + // padding, and remove it. + char temp[1024]; + outLength = sizeof(temp); + if(EVP_CipherFinal(&ctx, Buffer, &outLength) != 1) + { + THROW_EXCEPTION(CipherException, EVPFinalFailure) + } + // Remove last block, assuming it's full of padded bytes only. + outLength -= blockSize; + // Copy anything to the main buffer + // (can't just use main buffer, because it might overwrite something important) + if(outLength > 0) + { + ::memcpy(Buffer, temp, outLength); + } + } + } + // Reinitialise the cipher for the next time around + if(EVP_CipherInit(&ctx, mpDescription->GetCipher(), NULL, NULL, mFunction) != 1) + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + mpDescription->SetupParameters(&ctx); + + // Update length for caller + rOutLengthOut = outLength; +} +#endif + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::InSizeForOutBufferSize(int) +// Purpose: Returns the maximum amount of data that can be sent in +// given a output buffer size. +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +int CipherContext::InSizeForOutBufferSize(int OutLength) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + // Strictly speaking, the *2 is unnecessary. However... + // Final() is paranoid, and requires two input blocks of space to work. + return OutLength - (EVP_CIPHER_CTX_block_size(&ctx) * 2); +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::MaxOutSizeForInBufferSize(int) +// Purpose: Returns the maximum output size for an input of a given length. +// Will tend to over estimate, as it needs to allow space for Final() to be called. +// Created: 3/12/03 +// +// -------------------------------------------------------------------------- +int CipherContext::MaxOutSizeForInBufferSize(int InLength) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + // Final() is paranoid, and requires two input blocks of space to work, and so we need to add + // three blocks on to be absolutely sure. + return InLength + (EVP_CIPHER_CTX_block_size(&ctx) * 3); +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::TransformBlock(void *, int, const void *, int) +// Purpose: Transform one block to another all in one go, no Final required. +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +int CipherContext::TransformBlock(void *pOutBuffer, int OutLength, const void *pInBuffer, int InLength) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + // Warn if in a transformation + if(mWithinTransform) + { + TRACE0("CipherContext::TransformBlock called when context flagged as within a transform\n"); + } + + // Check output buffer size + if(OutLength < (InLength + EVP_CIPHER_CTX_block_size(&ctx))) + { + // Check if padding is off, in which case the buffer can be smaller + if(!mPaddingOn && OutLength <= InLength) + { + // This is OK. + } + else + { + THROW_EXCEPTION(CipherException, OutputBufferTooSmall); + } + } + + // Initialise the cipher context again + if(EVP_CipherInit(&ctx, NULL, NULL, NULL, -1) != 1) + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + + // Do the entire block + int outLength = 0; + try + { + // Update + outLength = OutLength; + if(EVP_CipherUpdate(&ctx, (unsigned char*)pOutBuffer, &outLength, (unsigned char*)pInBuffer, InLength) != 1) + { + THROW_EXCEPTION(CipherException, EVPUpdateFailure) + } + // Finalise + int outLength2 = OutLength - outLength; +#ifndef HAVE_OLD_SSL + if(EVP_CipherFinal_ex(&ctx, ((unsigned char*)pOutBuffer) + outLength, &outLength2) != 1) + { + THROW_EXCEPTION(CipherException, EVPFinalFailure) + } +#else + OldOpenSSLFinal(((unsigned char*)pOutBuffer) + outLength, outLength2); +#endif + outLength += outLength2; + } + catch(...) + { + // Finalise the context, so definately ready for the next caller + int outs = OutLength; +#ifndef HAVE_OLD_SSL + EVP_CipherFinal_ex(&ctx, (unsigned char*)pOutBuffer, &outs); +#else + OldOpenSSLFinal((unsigned char*)pOutBuffer, outs); +#endif + throw; + } + + return outLength; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::GetIVLength() +// Purpose: Returns the size of the IV for this context +// Created: 3/12/03 +// +// -------------------------------------------------------------------------- +int CipherContext::GetIVLength() +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + return EVP_CIPHER_CTX_iv_length(&ctx); +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::SetIV(const void *) +// Purpose: Sets the IV for this context (must be correctly sized, use GetIVLength) +// Created: 3/12/03 +// +// -------------------------------------------------------------------------- +void CipherContext::SetIV(const void *pIV) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + // Warn if in a transformation + if(mWithinTransform) + { + TRACE0("CipherContext::SetIV called when context flagged as within a transform\n"); + } + + // Set IV + if(EVP_CipherInit(&ctx, NULL, NULL, (unsigned char *)pIV, -1) != 1) + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + +#ifdef HAVE_OLD_SSL + // Update description + if(mpDescription != 0) + { + mpDescription->SetIV(pIV); + } +#endif +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::SetRandomIV(int &) +// Purpose: Set a random IV for the context, and return a pointer to the IV used, +// and the length of this IV in the rLengthOut arg. +// Created: 3/12/03 +// +// -------------------------------------------------------------------------- +const void *CipherContext::SetRandomIV(int &rLengthOut) +{ + if(!mInitialised) + { + THROW_EXCEPTION(CipherException, NotInitialised) + } + + // Warn if in a transformation + if(mWithinTransform) + { + TRACE0("CipherContext::SetRandomIV called when context flagged as within a transform\n"); + } + + // Get length of IV + unsigned int ivLen = EVP_CIPHER_CTX_iv_length(&ctx); + if(ivLen > sizeof(mGeneratedIV)) + { + THROW_EXCEPTION(CipherException, IVSizeImplementationLimitExceeded) + } + + // Generate some random data + Random::Generate(mGeneratedIV, ivLen); + + // Set IV + if(EVP_CipherInit(&ctx, NULL, NULL, mGeneratedIV, -1) != 1) + { + THROW_EXCEPTION(CipherException, EVPInitFailure) + } + +#ifdef HAVE_OLD_SSL + // Update description + if(mpDescription != 0) + { + mpDescription->SetIV(mGeneratedIV); + } +#endif + + // Return the IV and it's length + rLengthOut = ivLen; + return mGeneratedIV; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherContext::UsePadding(bool) +// Purpose: Set whether or not the context uses padding. +// Created: 12/12/03 +// +// -------------------------------------------------------------------------- +void CipherContext::UsePadding(bool Padding) +{ +#ifndef HAVE_OLD_SSL + if(EVP_CIPHER_CTX_set_padding(&ctx, Padding) != 1) + { + THROW_EXCEPTION(CipherException, EVPSetPaddingFailure) + } +#endif + mPaddingOn = Padding; +} + + + diff --git a/lib/crypto/CipherContext.h b/lib/crypto/CipherContext.h new file mode 100644 index 00000000..427c78d2 --- /dev/null +++ b/lib/crypto/CipherContext.h @@ -0,0 +1,121 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherContext.h +// Purpose: Context for symmetric encryption / descryption +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- + +#ifndef CIPHERCONTEXT__H +#define CIPHERCONTEXT__H + +#ifdef BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_FALSE + always include CipherContext.h first in any .cpp file +#endif +#define BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_TRUE +#include <openssl/evp.h> +class CipherDescription; + +#define CIPHERCONTEXT_MAX_GENERATED_IV_LENGTH 32 + +// -------------------------------------------------------------------------- +// +// Class +// Name: CipherContext +// Purpose: Context for symmetric encryption / descryption +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +class CipherContext +{ +public: + CipherContext(); + ~CipherContext(); +private: + CipherContext(const CipherContext &); // no copying + CipherContext &operator=(const CipherContext &); // no assignment +public: + + typedef enum + { + Decrypt = 0, + Encrypt = 1 + } CipherFunction; + + void Init(CipherContext::CipherFunction Function, const CipherDescription &rDescription); + void Reset(); + + void Begin(); + int Transform(void *pOutBuffer, int OutLength, const void *pInBuffer, int InLength); + int Final(void *pOutBuffer, int OutLength); + int InSizeForOutBufferSize(int OutLength); + int MaxOutSizeForInBufferSize(int InLength); + + int TransformBlock(void *pOutBuffer, int OutLength, const void *pInBuffer, int InLength); + + bool IsInitialised() {return mInitialised;} + + int GetIVLength(); + void SetIV(const void *pIV); + const void *SetRandomIV(int &rLengthOut); + + void UsePadding(bool Padding = true); + +#ifdef HAVE_OLD_SSL + void OldOpenSSLFinal(unsigned char *Buffer, int &rOutLengthOut); +#endif + +private: + EVP_CIPHER_CTX ctx; + bool mInitialised; + bool mWithinTransform; + bool mPaddingOn; + uint8_t mGeneratedIV[CIPHERCONTEXT_MAX_GENERATED_IV_LENGTH]; +#ifdef HAVE_OLD_SSL + CipherFunction mFunction; + CipherDescription *mpDescription; +#endif +}; + + +#endif // CIPHERCONTEXT__H + diff --git a/lib/crypto/CipherDescription.cpp b/lib/crypto/CipherDescription.cpp new file mode 100644 index 00000000..826cfb93 --- /dev/null +++ b/lib/crypto/CipherDescription.cpp @@ -0,0 +1,111 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherDescription.cpp +// Purpose: Pure virtual base class for describing ciphers +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- + +#include "Box.h" + +#include <openssl/evp.h> + +#define BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_TRUE + +#include "CipherDescription.h" + +#include "MemLeakFindOn.h" + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherDescription::CipherDescription() +// Purpose: Constructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherDescription::CipherDescription() +{ +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherDescription::CipherDescription(const CipherDescription &) +// Purpose: Copy constructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherDescription::CipherDescription(const CipherDescription &rToCopy) +{ +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: ~CipherDescription::CipherDescription() +// Purpose: Destructor +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherDescription::~CipherDescription() +{ +} + + + +// -------------------------------------------------------------------------- +// +// Function +// Name: CipherDescription::operator=(const CipherDescription &) +// Purpose: Assignment operator +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +CipherDescription &CipherDescription::operator=(const CipherDescription &rToCopy) +{ + return *this; +} + + diff --git a/lib/crypto/CipherDescription.h b/lib/crypto/CipherDescription.h new file mode 100644 index 00000000..3f90d080 --- /dev/null +++ b/lib/crypto/CipherDescription.h @@ -0,0 +1,97 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherDescription.h +// Purpose: Pure virtual base class for describing ciphers +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- + +#ifndef CIPHERDESCRIPTION__H +#define CIPHERDESCRIPTION__H + +#ifndef BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_TRUE + #define BOX_LIB_CRYPTO_OPENSSL_HEADERS_INCLUDED_FALSE + class EVP_CIPHER; + class EVP_CIPHER_CTX; +#endif + +// -------------------------------------------------------------------------- +// +// Class +// Name: CipherDescription +// Purpose: Describes a cipher +// Created: 1/12/03 +// +// -------------------------------------------------------------------------- +class CipherDescription +{ +public: + CipherDescription(); + CipherDescription(const CipherDescription &rToCopy); + virtual ~CipherDescription(); + CipherDescription &operator=(const CipherDescription &rToCopy); + + // Return OpenSSL cipher object + virtual const EVP_CIPHER *GetCipher() const = 0; + + // Setup any other parameters + virtual void SetupParameters(EVP_CIPHER_CTX *pCipherContext) const = 0; + + // Mode parameter for cipher -- used in derived classes + typedef enum + { + Mode_ECB = 0, + Mode_CBC = 1, + Mode_CFB = 2, + Mode_OFB = 3 + } CipherMode; + +#ifdef HAVE_OLD_SSL + // For the old version of OpenSSL, we need to be able to store cipher descriptions. + virtual CipherDescription *Clone() const = 0; + // And to be able to store new IVs + virtual void SetIV(const void *pIV) = 0; +#endif +}; + +#endif // CIPHERDESCRIPTION__H + diff --git a/lib/crypto/CipherException.h b/lib/crypto/CipherException.h new file mode 100644 index 00000000..4a41bf97 --- /dev/null +++ b/lib/crypto/CipherException.h @@ -0,0 +1,55 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: CipherException.h +// Purpose: Exception +// Created: 2003/07/08 +// +// -------------------------------------------------------------------------- + +#ifndef CIPHEREXCEPTION__H +#define CIPHEREXCEPTION__H + +// Compatibility +#include "autogen_CipherException.h" + +#endif // CIPHEREXCEPTION__H + diff --git a/lib/crypto/CipherException.txt b/lib/crypto/CipherException.txt new file mode 100644 index 00000000..abdbac87 --- /dev/null +++ b/lib/crypto/CipherException.txt @@ -0,0 +1,18 @@ +EXCEPTION Cipher 5 + +Internal 0 +UnknownCipherMode 1 +AlreadyInitialised 2 +BadArguments 3 +EVPInitFailure 4 +EVPUpdateFailure 5 +EVPFinalFailure 6 +NotInitialised 7 +OutputBufferTooSmall 8 +EVPBadKeyLength 9 +BeginNotCalled 10 +IVSizeImplementationLimitExceeded 11 +PseudoRandNotAvailable 12 +EVPSetPaddingFailure 13 +RandomInitFailed 14 Failed to read from random device +LengthRequestedTooLongForRandomHex 15 diff --git a/lib/crypto/MD5Digest.cpp b/lib/crypto/MD5Digest.cpp new file mode 100644 index 00000000..6464182d --- /dev/null +++ b/lib/crypto/MD5Digest.cpp @@ -0,0 +1,120 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: MD5Digest.cpp +// Purpose: Simple interface for creating MD5 digests +// Created: 8/12/03 +// +// -------------------------------------------------------------------------- + + +#include "Box.h" + +#include "MD5Digest.h" + +#include "MemLeakFindOn.h" + + +MD5Digest::MD5Digest() +{ + MD5_Init(&md5); + for(unsigned int l = 0; l < sizeof(mDigest); ++l) + { + mDigest[l] = 0; + } +} + +MD5Digest::~MD5Digest() +{ +} + +void MD5Digest::Add(const std::string &rString) +{ + MD5_Update(&md5, rString.c_str(), rString.size()); +} + +void MD5Digest::Add(const void *pData, int Length) +{ + MD5_Update(&md5, pData, Length); +} + +void MD5Digest::Finish() +{ + MD5_Final(mDigest, &md5); +} + +std::string MD5Digest::DigestAsString() +{ + std::string r; + + static const char *hex = "0123456789abcdef"; + + for(unsigned int l = 0; l < sizeof(mDigest); ++l) + { + r += hex[(mDigest[l] & 0xf0) >> 4]; + r += hex[(mDigest[l] & 0x0f)]; + } + + return r; +} + +int MD5Digest::CopyDigestTo(uint8_t *to) +{ + for(int l = 0; l < MD5_DIGEST_LENGTH; ++l) + { + to[l] = mDigest[l]; + } + + return MD5_DIGEST_LENGTH; +} + + +bool MD5Digest::DigestMatches(uint8_t *pCompareWith) const +{ + for(int l = 0; l < MD5_DIGEST_LENGTH; ++l) + { + if(pCompareWith[l] != mDigest[l]) + return false; + } + + return true; +} + diff --git a/lib/crypto/MD5Digest.h b/lib/crypto/MD5Digest.h new file mode 100644 index 00000000..fc9ebbba --- /dev/null +++ b/lib/crypto/MD5Digest.h @@ -0,0 +1,95 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: MD5Digest.h +// Purpose: Simple interface for creating MD5 digests +// Created: 8/12/03 +// +// -------------------------------------------------------------------------- + +#ifndef MD5DIGEST_H +#define MD5DIGEST_H + +#include <openssl/md5.h> +#include <string> + +// -------------------------------------------------------------------------- +// +// Function +// Name: MD5Digest +// Purpose: Simple interface for creating MD5 digests +// Created: 8/12/03 +// +// -------------------------------------------------------------------------- +class MD5Digest +{ +public: + MD5Digest(); + virtual ~MD5Digest(); + + void Add(const std::string &rString); + void Add(const void *pData, int Length); + + void Finish(); + + std::string DigestAsString(); + uint8_t *DigestAsData(int *pLength = 0) + { + if(pLength) *pLength = sizeof(mDigest); + return mDigest; + } + + enum + { + DigestLength = MD5_DIGEST_LENGTH + }; + + int CopyDigestTo(uint8_t *to); + + bool DigestMatches(uint8_t *pCompareWith) const; + +private: + MD5_CTX md5; + uint8_t mDigest[MD5_DIGEST_LENGTH]; +}; + +#endif // MD5DIGEST_H + diff --git a/lib/crypto/Makefile.extra b/lib/crypto/Makefile.extra new file mode 100644 index 00000000..a7e42000 --- /dev/null +++ b/lib/crypto/Makefile.extra @@ -0,0 +1,7 @@ + +MAKEEXCEPTION = ../../lib/common/makeexception.pl + +# AUTOGEN SEEDING +autogen_CipherException.cpp autogen_CipherException.h: $(MAKEEXCEPTION) CipherException.txt + perl $(MAKEEXCEPTION) CipherException.txt + diff --git a/lib/crypto/Random.cpp b/lib/crypto/Random.cpp new file mode 100644 index 00000000..549a9a91 --- /dev/null +++ b/lib/crypto/Random.cpp @@ -0,0 +1,165 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: Random.cpp +// Purpose: Random numbers +// Created: 31/12/03 +// +// -------------------------------------------------------------------------- + +#include "Box.h" + +#include <openssl/rand.h> +#include <stdio.h> + +#include "Random.h" +#include "CipherException.h" + +#include "MemLeakFindOn.h" + + +// -------------------------------------------------------------------------- +// +// Function +// Name: Random::Initialise() +// Purpose: Add additional randomness to the standard library initialisation +// Created: 18/6/04 +// +// -------------------------------------------------------------------------- +void Random::Initialise() +{ +#ifdef HAVE_RANDOM_DEVICE + if(::RAND_load_file(RANDOM_DEVICE, 1024) != 1024) + { + THROW_EXCEPTION(CipherException, RandomInitFailed) + } +#else + ::fprintf(stderr, "No random device -- additional seeding of random number generator not performed.\n"); +#endif +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: Random::Generate(void *, int) +// Purpose: Generate Length bytes of random data +// Created: 31/12/03 +// +// -------------------------------------------------------------------------- +void Random::Generate(void *pOutput, int Length) +{ + if(RAND_pseudo_bytes((uint8_t*)pOutput, Length) == -1) + { + THROW_EXCEPTION(CipherException, PseudoRandNotAvailable) + } +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: Random::GenerateHex(int) +// Purpose: Generate Length bytes of hex encoded data. Note that the +// maximum length requested is limited. (Returns a string +// 2 x Length characters long.) +// Created: 1/11/04 +// +// -------------------------------------------------------------------------- +std::string Random::GenerateHex(int Length) +{ + uint8_t r[256]; + if(Length > (int)sizeof(r)) + { + THROW_EXCEPTION(CipherException, LengthRequestedTooLongForRandomHex) + } + Random::Generate(r, Length); + + std::string o; + static const char *h = "0123456789abcdef"; + for(int l = 0; l < Length; ++l) + { + o += h[r[l] >> 4]; + o += h[r[l] & 0xf]; + } + + return o; +} + + +// -------------------------------------------------------------------------- +// +// Function +// Name: Random::RandomInt(int) +// Purpose: Return a random integer between 0 and MaxValue inclusive. +// Created: 21/1/04 +// +// -------------------------------------------------------------------------- +uint32_t Random::RandomInt(uint32_t MaxValue) +{ + uint32_t v = 0; + + // Generate a mask + uint32_t mask = 0; + while(mask < MaxValue) + { + mask = (mask << 1) | 1; + } + + do + { + // Generate a random number + uint32_t r = 0; + Random::Generate(&r, sizeof(r)); + + // Mask off relevant bits + v = r & mask; + + // Check that it's in the right range. + } while(v > MaxValue); + + // NOTE: don't do a mod, because this doesn't give a correct random distribution + + return v; +} + + + diff --git a/lib/crypto/Random.h b/lib/crypto/Random.h new file mode 100644 index 00000000..8ecf8a6c --- /dev/null +++ b/lib/crypto/Random.h @@ -0,0 +1,63 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: Random.h +// Purpose: Random numbers +// Created: 31/12/03 +// +// -------------------------------------------------------------------------- + +#ifndef RANDOM__H +#define RANDOM__H + +#include <string> + +namespace Random +{ + void Initialise(); + void Generate(void *pOutput, int Length); + std::string GenerateHex(int Length); + uint32_t RandomInt(uint32_t MaxValue); +}; + + +#endif // RANDOM__H + diff --git a/lib/crypto/RollingChecksum.cpp b/lib/crypto/RollingChecksum.cpp new file mode 100644 index 00000000..73e85319 --- /dev/null +++ b/lib/crypto/RollingChecksum.cpp @@ -0,0 +1,100 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: RollingChecksum.cpp +// Purpose: A simple rolling checksum over a block of data +// Created: 6/12/03 +// +// -------------------------------------------------------------------------- + +#include "Box.h" +#include "RollingChecksum.h" + +#include "MemLeakFindOn.h" + +// -------------------------------------------------------------------------- +// +// Function +// Name: RollingChecksum::RollingChecksum(const void *, unsigned int) +// Purpose: Constructor -- does initial computation of the checksum. +// Created: 6/12/03 +// +// -------------------------------------------------------------------------- +RollingChecksum::RollingChecksum(const void * const data, const unsigned int Length) + : a(0), + b(0) +{ + const uint8_t *block = (const uint8_t *)data; + for(unsigned int x = Length; x >= 1; --x) + { + a += (*block); + b += x * (*block); + + ++block; + } +} + +// -------------------------------------------------------------------------- +// +// Function +// Name: RollingChecksum::RollForwardSeveral(uint8_t*, uint8_t*, unsigned int, unsigned int) +// Purpose: Move the checksum forward a block, given a pointer to the first byte of the current block, +// and a pointer just after the last byte of the current block and the length of the block and of the skip. +// Created: 7/14/05 +// +// -------------------------------------------------------------------------- +void RollingChecksum::RollForwardSeveral(const uint8_t * const StartOfThisBlock, const uint8_t * const LastOfNextBlock, const unsigned int Length, const unsigned int Skip) +{ + // IMPLEMENTATION NOTE: Everything is implicitly mod 2^16 -- uint16_t's will overflow nicely. + unsigned int i; + uint16_t sumBegin=0, j,k; + + for(i=0; i < Skip; i++) + { + j = StartOfThisBlock[i]; + k = LastOfNextBlock[i]; + sumBegin += j; + a += (k - j); + b += a; + } + + b -= Length * sumBegin; +} diff --git a/lib/crypto/RollingChecksum.h b/lib/crypto/RollingChecksum.h new file mode 100644 index 00000000..befc011f --- /dev/null +++ b/lib/crypto/RollingChecksum.h @@ -0,0 +1,145 @@ +// distribution boxbackup-0.10 (svn version: 494) +// +// Copyright (c) 2003 - 2006 +// Ben Summers and contributors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All use of this software and associated advertising materials must +// display the following acknowledgment: +// This product includes software developed by Ben Summers. +// 4. The names of the Authors may not be used to endorse or promote +// products derived from this software without specific prior written +// permission. +// +// [Where legally impermissible the Authors do not disclaim liability for +// direct physical injury or death caused solely by defects in the software +// unless it is modified by a third party.] +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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. +// +// +// +// -------------------------------------------------------------------------- +// +// File +// Name: RollingChecksum.h +// Purpose: A simple rolling checksum over a block of data +// Created: 6/12/03 +// +// -------------------------------------------------------------------------- + +#ifndef ROLLINGCHECKSUM__H +#define ROLLINGCHECKSUM__H + +// -------------------------------------------------------------------------- +// +// Class +// Name: RollingChecksum +// Purpose: A simple rolling checksum over a block of data -- can move the block +// "forwards" in memory and get the next checksum efficiently. +// +// Implementation of http://rsync.samba.org/tech_report/node3.html +// Created: 6/12/03 +// +// -------------------------------------------------------------------------- +class RollingChecksum +{ +public: + RollingChecksum(const void * const data, const unsigned int Length); + + // -------------------------------------------------------------------------- + // + // Function + // Name: RollingChecksum::RollForward(uint8_t, uint8_t, unsigned int) + // Purpose: Move the checksum forward a block, given the first byte of the current block, + // last byte of the next block (it's rolling forward to) and the length of the block. + // Created: 6/12/03 + // + // -------------------------------------------------------------------------- + inline void RollForward(const uint8_t StartOfThisBlock, const uint8_t LastOfNextBlock, const unsigned int Length) + { + // IMPLEMENTATION NOTE: Everything is implicitly mod 2^16 -- uint16_t's will overflow nicely. + a -= StartOfThisBlock; + a += LastOfNextBlock; + b -= Length * StartOfThisBlock; + b += a; + } + + // -------------------------------------------------------------------------- + // + // Function + // Name: RollingChecksum::RollForwardSeveral(uint8_t*, uint8_t*, unsigned int, unsigned int) + // Purpose: Move the checksum forward a block, given a pointer to the first byte of the current block, + // and a pointer just after the last byte of the current block and the length of the block and of the skip. + // Created: 7/14/05 + // + // -------------------------------------------------------------------------- + void RollForwardSeveral(const uint8_t * const StartOfThisBlock, const uint8_t * const LastOfNextBlock, const unsigned int Length, const unsigned int Skip); + + // -------------------------------------------------------------------------- + // + // Function + // Name: RollingChecksum::GetChecksum() + // Purpose: Returns the checksum + // Created: 6/12/03 + // + // -------------------------------------------------------------------------- + inline uint32_t GetChecksum() const + { + return ((uint32_t)a) | (((uint32_t)b) << 16); + } + + // Components, just in case they're handy + inline uint16_t GetComponent1() const {return a;} + inline uint16_t GetComponent2() const {return b;} + + // -------------------------------------------------------------------------- + // + // Function + // Name: RollingChecksum::GetComponentForHashing() + // Purpose: Return the 16 bit component used for hashing and/or quick checks + // Created: 6/12/03 + // + // -------------------------------------------------------------------------- + inline uint16_t GetComponentForHashing() const + { + return b; + } + + // -------------------------------------------------------------------------- + // + // Function + // Name: RollingChecksum::ExtractHashingComponent(uint32_t) + // Purpose: Static. Given a full checksum, extract the component used in the hashing table. + // Created: 14/1/04 + // + // -------------------------------------------------------------------------- + static inline uint16_t ExtractHashingComponent(const uint32_t Checksum) + { + return Checksum >> 16; + } + +private: + uint16_t a; + uint16_t b; +}; + +#endif // ROLLINGCHECKSUM__H + |