Update DefaultEncryptor, DefaultEncryptorWithMAC and friends (Issue 345)

This commit is contained in:
Jeffrey Walton 2016-12-11 05:09:42 -05:00
parent c6b529ffd5
commit bfbcfeec7c
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
2 changed files with 232 additions and 116 deletions

View File

@ -18,30 +18,26 @@
NAMESPACE_BEGIN(CryptoPP)
static const unsigned int MASH_ITERATIONS = 200;
static const unsigned int SALTLENGTH = 8;
static const unsigned int BLOCKSIZE = DefaultBlockCipher::Encryption::BLOCKSIZE;
static const unsigned int KEYLENGTH = DefaultBlockCipher::Encryption::DEFAULT_KEYLENGTH;
// The purpose of this function Mash() is to take an arbitrary length input
// string and *deterministicly* produce an arbitrary length output string such
// that (1) it looks random, (2) no information about the input is
// deducible from it, and (3) it contains as much entropy as it can hold, or
// the amount of entropy in the input string, whichever is smaller.
template <class H>
static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations)
{
if (BytePrecision(outLen) > 2)
throw InvalidArgument("Mash: output legnth too large");
size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)DefaultHashModule::DIGESTSIZE);
size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)H::DIGESTSIZE);
byte b[2];
SecByteBlock buf(bufSize);
SecByteBlock outBuf(bufSize);
DefaultHashModule hash;
H hash;
unsigned int i;
for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE)
for(i=0; i<outLen; i+=H::DIGESTSIZE)
{
b[0] = (byte) (i >> 8);
b[1] = (byte) i;
@ -53,7 +49,7 @@ static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int ite
while (iterations-- > 1)
{
memcpy(buf, outBuf, bufSize);
for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE)
for (i=0; i<bufSize; i+=H::DIGESTSIZE)
{
b[0] = (byte) (i >> 8);
b[1] = (byte) i;
@ -66,36 +62,41 @@ static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int ite
memcpy(out, outBuf, outLen);
}
static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, byte *key, byte *IV)
template <class BC, class H, class Info>
static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, unsigned int iterations, byte *key, byte *IV)
{
SecByteBlock temp(passphraseLength+saltLength);
memcpy(temp, passphrase, passphraseLength);
memcpy(temp+passphraseLength, salt, saltLength);
SecByteBlock keyIV(KEYLENGTH+BLOCKSIZE);
Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS);
memcpy(key, keyIV, KEYLENGTH);
memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE);
SecByteBlock keyIV(Info::KEYLENGTH+Info::BLOCKSIZE);
Mash<H>(temp, passphraseLength + saltLength, keyIV, Info::KEYLENGTH+Info::BLOCKSIZE, iterations);
memcpy(key, keyIV, Info::KEYLENGTH);
memcpy(IV, keyIV+Info::KEYLENGTH, Info::BLOCKSIZE);
}
// ********************************************************
DefaultEncryptor::DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment)
template <class BC, class H, class Info>
DataEncryptor<BC,H,Info>::DataEncryptor(const char *passphrase, BufferedTransformation *attachment)
: ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
{
CRYPTOPP_COMPILE_ASSERT(SALTLENGTH <= DIGESTSIZE);
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE <= DIGESTSIZE);
}
DefaultEncryptor::DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
template <class BC, class H, class Info>
DataEncryptor<BC,H,Info>::DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
: ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
{
CRYPTOPP_COMPILE_ASSERT(SALTLENGTH <= DIGESTSIZE);
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE <= DIGESTSIZE);
}
void DefaultEncryptor::FirstPut(const byte *)
template <class BC, class H, class Info>
void DataEncryptor<BC,H,Info>::FirstPut(const byte *)
{
CRYPTOPP_COMPILE_ASSERT(SALTLENGTH <= DefaultHashModule::DIGESTSIZE);
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE);
SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE);
DefaultHashModule hash;
SecByteBlock salt(DIGESTSIZE), keyCheck(DIGESTSIZE);
H hash;
// use hash(passphrase | time | clock) as salt
hash.Update(m_passphrase, m_passphrase.size());
@ -115,7 +116,7 @@ void DefaultEncryptor::FirstPut(const byte *)
// mash passphrase and salt together into key and IV
SecByteBlock key(KEYLENGTH);
SecByteBlock IV(BLOCKSIZE);
GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV);
m_cipher.SetKeyWithIV(key, key.size(), IV);
SetFilter(new StreamTransformationFilter(m_cipher));
@ -123,7 +124,8 @@ void DefaultEncryptor::FirstPut(const byte *)
m_filter->Put(keyCheck, BLOCKSIZE);
}
void DefaultEncryptor::LastPut(const byte *inString, size_t length)
template <class BC, class H, class Info>
void DataEncryptor<BC,H,Info>::LastPut(const byte *inString, size_t length)
{
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
m_filter->MessageEnd();
@ -131,28 +133,36 @@ void DefaultEncryptor::LastPut(const byte *inString, size_t length)
// ********************************************************
DefaultDecryptor::DefaultDecryptor(const char *p, BufferedTransformation *attachment, bool throwException)
template <class BC, class H, class Info>
DataDecryptor<BC,H,Info>::DataDecryptor(const char *p, BufferedTransformation *attachment, bool throwException)
: ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
, m_state(WAITING_FOR_KEYCHECK)
, m_passphrase((const byte *)p, strlen(p))
, m_throwException(throwException)
{
CRYPTOPP_COMPILE_ASSERT(SALTLENGTH <= DIGESTSIZE);
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE <= DIGESTSIZE);
}
DefaultDecryptor::DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
template <class BC, class H, class Info>
DataDecryptor<BC,H,Info>::DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
: ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
, m_state(WAITING_FOR_KEYCHECK)
, m_passphrase(passphrase, passphraseLength)
, m_throwException(throwException)
{
CRYPTOPP_COMPILE_ASSERT(SALTLENGTH <= DIGESTSIZE);
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE <= DIGESTSIZE);
}
void DefaultDecryptor::FirstPut(const byte *inString)
template <class BC, class H, class Info>
void DataDecryptor<BC,H,Info>::FirstPut(const byte *inString)
{
CheckKey(inString, inString+SALTLENGTH);
}
void DefaultDecryptor::LastPut(const byte *inString, size_t length)
template <class BC, class H, class Info>
void DataDecryptor<BC,H,Info>::LastPut(const byte *inString, size_t length)
{
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
if (m_filter.get() == NULL)
@ -168,18 +178,19 @@ void DefaultDecryptor::LastPut(const byte *inString, size_t length)
}
}
void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck)
template <class BC, class H, class Info>
void DataDecryptor<BC,H,Info>::CheckKey(const byte *salt, const byte *keyCheck)
{
SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DefaultHashModule::DIGESTSIZE));
SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DIGESTSIZE));
DefaultHashModule hash;
H hash;
hash.Update(m_passphrase, m_passphrase.size());
hash.Update(salt, SALTLENGTH);
hash.Final(check);
SecByteBlock key(KEYLENGTH);
SecByteBlock IV(BLOCKSIZE);
GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV);
m_cipher.SetKeyWithIV(key, key.size(), IV);
member_ptr<StreamTransformationFilter> decryptor(new StreamTransformationFilter(m_cipher));
@ -202,30 +213,34 @@ void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck)
// ********************************************************
static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, size_t passphraseLength)
template <class H, class MAC>
static MAC* NewDataEncryptorMAC(const byte *passphrase, size_t passphraseLength)
{
size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16);
size_t macKeyLength = MAC::StaticGetValidKeyLength(16);
SecByteBlock macKey(macKeyLength);
// since the MAC is encrypted there is no reason to mash the passphrase for many iterations
Mash(passphrase, passphraseLength, macKey, macKeyLength, 1);
return new DefaultMAC(macKey, macKeyLength);
Mash<H>(passphrase, passphraseLength, macKey, macKeyLength, 1);
return new MAC(macKey, macKeyLength);
}
DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment)
template <class BC, class H, class MAC, class Info>
DataEncryptorWithMAC<BC,H,MAC,Info>::DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment)
: ProxyFilter(NULL, 0, 0, attachment)
, m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
, m_mac(NewDataEncryptorMAC<H,MAC>((const byte *)passphrase, strlen(passphrase)))
{
SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true));
SetFilter(new HashFilter(*m_mac, new DataEncryptor<BC,H,Info>(passphrase), true));
}
DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
template <class BC, class H, class MAC, class Info>
DataEncryptorWithMAC<BC,H,MAC,Info>::DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
: ProxyFilter(NULL, 0, 0, attachment)
, m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
, m_mac(NewDataEncryptorMAC<H,MAC>(passphrase, passphraseLength))
{
SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true));
SetFilter(new HashFilter(*m_mac, new DataEncryptor<BC,H,Info>(passphrase, passphraseLength), true));
}
void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length)
template <class BC, class H, class MAC, class Info>
void DataEncryptorWithMAC<BC,H,MAC,Info>::LastPut(const byte *inString, size_t length)
{
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
m_filter->MessageEnd();
@ -233,33 +248,38 @@ void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length)
// ********************************************************
DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException)
template <class BC, class H, class MAC, class Info>
DataDecryptorWithMAC<BC,H,MAC,Info>::DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException)
: ProxyFilter(NULL, 0, 0, attachment)
, m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
, m_mac(NewDataEncryptorMAC<H,MAC>((const byte *)passphrase, strlen(passphrase)))
, m_throwException(throwException)
{
SetFilter(new DefaultDecryptor(passphrase, m_hashVerifier=new HashVerificationFilter(*m_mac, NULL, HashVerificationFilter::PUT_MESSAGE), throwException));
SetFilter(new DataDecryptor<BC,H,Info>(passphrase, m_hashVerifier=new HashVerificationFilter(*m_mac, NULL, HashVerificationFilter::PUT_MESSAGE), throwException));
}
DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
template <class BC, class H, class MAC, class Info>
DataDecryptorWithMAC<BC,H,MAC,Info>::DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
: ProxyFilter(NULL, 0, 0, attachment)
, m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
, m_mac(NewDataEncryptorMAC<H,MAC>(passphrase, passphraseLength))
, m_throwException(throwException)
{
SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerificationFilter(*m_mac, NULL, HashVerificationFilter::PUT_MESSAGE), throwException));
SetFilter(new DataDecryptor<BC,H,Info>(passphrase, passphraseLength, m_hashVerifier=new HashVerificationFilter(*m_mac, NULL, HashVerificationFilter::PUT_MESSAGE), throwException));
}
DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const
template <class BC, class H, class MAC, class Info>
typename DataDecryptor<BC,H,Info>::State DataDecryptorWithMAC<BC,H,MAC,Info>::CurrentState() const
{
return static_cast<const DefaultDecryptor *>(m_filter.get())->CurrentState();
return static_cast<const DataDecryptor<BC,H,Info> *>(m_filter.get())->CurrentState();
}
bool DefaultDecryptorWithMAC::CheckLastMAC() const
template <class BC, class H, class MAC, class Info>
bool DataDecryptorWithMAC<BC,H,MAC,Info>::CheckLastMAC() const
{
return m_hashVerifier->GetLastResult();
}
void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length)
template <class BC, class H, class MAC, class Info>
void DataDecryptorWithMAC<BC,H,MAC,Info>::LastPut(const byte *inString, size_t length)
{
CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length);
m_filter->MessageEnd();
@ -267,5 +287,15 @@ void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length)
throw MACBadErr();
}
NAMESPACE_END
template class DataParametersInfo<LegacyBlockCipher::BLOCKSIZE, LegacyBlockCipher::DEFAULT_KEYLENGTH, LegacyHashModule::DIGESTSIZE, 8, 200>;
template class DataParametersInfo<DefaultBlockCipher::BLOCKSIZE, DefaultBlockCipher::DEFAULT_KEYLENGTH, DefaultHashModule::DIGESTSIZE, 8, 2500>;
template class DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo>;
template class DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo>;
template class DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo>;
template class DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo>;
template class DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,DefaultMAC,LegacyParametersInfo>;
template class DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,DefaultMAC,LegacyParametersInfo>;
template class DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo>;
template class DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo>;
NAMESPACE_END

210
default.h
View File

@ -8,6 +8,7 @@
#include "sha.h"
#include "hmac.h"
#include "aes.h"
#include "des.h"
#include "modes.h"
#include "filters.h"
@ -15,30 +16,89 @@
NAMESPACE_BEGIN(CryptoPP)
//! \brief Legacy block cipher for LegacyEncryptor, LegacyDecryptor, LegacyEncryptorWithMAC and LegacyDecryptorWithMAC
typedef DES_EDE2 LegacyBlockCipher;
//! \brief Legacy hash for use with LegacyEncryptorWithMAC and LegacyDecryptorWithMAC
typedef SHA LegacyHashModule;
//! \brief Legacy HMAC for use withLegacyEncryptorWithMAC and LegacyDecryptorWithMAC
typedef HMAC<LegacyHashModule> LegacyMAC;
//! \brief Default block cipher for DefaultEncryptor, DefaultDecryptor, DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
typedef DES_EDE2 DefaultBlockCipher;
typedef AES DefaultBlockCipher;
//! \brief Default hash for use with DefaultEncryptorWithMAC and DefaultDecryptorWithMAC
typedef SHA DefaultHashModule;
typedef SHA256 DefaultHashModule;
//! \brief Default HMAC for use withDefaultEncryptorWithMAC and DefaultDecryptorWithMAC
typedef HMAC<DefaultHashModule> DefaultMAC;
//! \class DefaultEncryptor
//! \brief Password-Based Encryptor using TripleDES
//! \details The class uses 2-key TripleDES (DES_EDE2) for encryption, which only
//! provides about 80-bits of security.
class DefaultEncryptor : public ProxyFilter
//! \class DataDecryptorErr
//! \brief Exception thrown when LegacyDecryptorWithMAC or DefaultDecryptorWithMAC decryption error is encountered
class DataDecryptorErr : public Exception
{
public:
//! \brief Construct a DefaultEncryptor
DataDecryptorErr(const std::string &s)
: Exception(DATA_INTEGRITY_CHECK_FAILED, s) {}
};
//! \class KeyBadErr
//! \brief Exception thrown when a bad key is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC
class KeyBadErr : public DataDecryptorErr
{
public: KeyBadErr()
: DataDecryptorErr("DataDecryptor: cannot decrypt message with this passphrase") {}
};
//! \class MACBadErr
//! \brief Exception thrown when an incorrect MAC is encountered in DefaultDecryptorWithMAC and LegacyDecryptorWithMAC
class MACBadErr : public DataDecryptorErr
{
public: MACBadErr()
: DataDecryptorErr("DataDecryptorWithMAC: MAC check failed") {}
};
//! \class DataParametersInfo
//! \brief Algorithm information for password-based encryptors and decryptors
template <unsigned int BlockSize, unsigned int KeyLength, unsigned int DigestSize, unsigned int SaltSize, unsigned int Iterations>
struct DataParametersInfo
{
CRYPTOPP_CONSTANT(BLOCKSIZE = BlockSize)
CRYPTOPP_CONSTANT(KEYLENGTH = KeyLength)
CRYPTOPP_CONSTANT(SALTLENGTH = SaltSize)
CRYPTOPP_CONSTANT(DIGESTSIZE = DigestSize)
CRYPTOPP_CONSTANT(ITERATIONS = Iterations)
};
typedef DataParametersInfo<LegacyBlockCipher::BLOCKSIZE, LegacyBlockCipher::DEFAULT_KEYLENGTH, LegacyHashModule::DIGESTSIZE, 8, 200> LegacyParametersInfo;
typedef DataParametersInfo<DefaultBlockCipher::BLOCKSIZE, DefaultBlockCipher::DEFAULT_KEYLENGTH, DefaultHashModule::DIGESTSIZE, 8, 2500> DefaultParametersInfo;
//! \class DataEncryptor
//! \brief Password-Based Encryptor
//! \tparam BC BlockCipher based class used for encryption
//! \tparam H HashTransformation based class used for mashing
//! \tparam Info Constants used by the algorithms
//! \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
//! Crypto++ 5.7 switched to AES and SHA256.
//! \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor
//! \since Crypto++ 2.0
template <class BC, class H, class Info>
class DataEncryptor : public ProxyFilter, public Info
{
public:
CRYPTOPP_CONSTANT(BLOCKSIZE = Info::BLOCKSIZE)
CRYPTOPP_CONSTANT(KEYLENGTH = Info::KEYLENGTH)
CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH)
CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE)
CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS)
//! \brief Construct a DataEncryptor
//! \param passphrase a C-String password
//! \param attachment a BufferedTransformation to attach to this object
DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment = NULL);
DataEncryptor(const char *passphrase, BufferedTransformation *attachment = NULL);
//! \brief Construct a DefaultEncryptor
//! \brief Construct a DataEncryptor
//! \param passphrase a byte string password
//! \param passphraseLength the length of the byte string password
//! \param attachment a BufferedTransformation to attach to this object
DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL);
DataEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL);
protected:
void FirstPut(const byte *);
@ -46,37 +106,40 @@ protected:
private:
SecByteBlock m_passphrase;
CBC_Mode<DefaultBlockCipher>::Encryption m_cipher;
typename CBC_Mode<BC>::Encryption m_cipher;
};
} CRYPTOPP_DEPRECATED ("DefaultEncryptor will be changing in the near future because the algorithms are no longer secure");
//! \class DefaultDecryptor
//! \brief Password-Based Decryptor using TripleDES
//! \details The class uses 2-key TripleDES (DES_EDE2) for encryption, which only
//! provides about 80-bits of security.
class DefaultDecryptor : public ProxyFilter
//! \class DataDecryptor
//! \brief Password-Based Decryptor
//! \tparam BC BlockCipher based class used for encryption
//! \tparam H HashTransformation based class used for mashing
//! \tparam Info Constants used by the algorithms
//! \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
//! Crypto++ 5.7 switched to AES and SHA256.
//! \sa DefaultEncryptor, DefaultDecryptor, LegacyEncryptor, LegacyDecryptor
//! \since Crypto++ 2.0
template <class BC, class H, class Info>
class DataDecryptor : public ProxyFilter, public Info
{
public:
//! \brief Constructs a DefaultDecryptor
CRYPTOPP_CONSTANT(BLOCKSIZE = Info::BLOCKSIZE)
CRYPTOPP_CONSTANT(KEYLENGTH = Info::KEYLENGTH)
CRYPTOPP_CONSTANT(SALTLENGTH = Info::SALTLENGTH)
CRYPTOPP_CONSTANT(DIGESTSIZE = Info::DIGESTSIZE)
CRYPTOPP_CONSTANT(ITERATIONS = Info::ITERATIONS)
//! \brief Constructs a DataDecryptor
//! \param passphrase a C-String password
//! \param attachment a BufferedTransformation to attach to this object
//! \param throwException a flag specifiying whether an Exception should be thrown on error
DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true);
DataDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true);
//! \brief Constructs a DefaultDecryptor
//! \brief Constructs a DataDecryptor
//! \param passphrase a byte string password
//! \param passphraseLength the length of the byte string password
//! \param attachment a BufferedTransformation to attach to this object
//! \param throwException a flag specifiying whether an Exception should be thrown on error
DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true);
class Err : public Exception
{
public:
Err(const std::string &s)
: Exception(DATA_INTEGRITY_CHECK_FAILED, s) {}
};
class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}};
DataDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true);
enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD};
State CurrentState() const {return m_state;}
@ -91,74 +154,86 @@ private:
void CheckKey(const byte *salt, const byte *keyCheck);
SecByteBlock m_passphrase;
CBC_Mode<DefaultBlockCipher>::Decryption m_cipher;
typename CBC_Mode<BC>::Decryption m_cipher;
member_ptr<FilterWithBufferedInput> m_decryptor;
bool m_throwException;
} CRYPTOPP_DEPRECATED ("DefaultDecryptor will be changing in the near future because the algorithms are no longer secure");
};
//! \class DefaultEncryptorWithMAC
//! \brief Password-Based encryptor using TripleDES and HMAC/SHA-1
//! \details DefaultEncryptorWithMAC uses a non-standard mashup function called Mash() to derive key
//! bits from the password. The class also uses 2-key TripleDES (DES_EDE2) for encryption, which only
//! provides about 80-bits of security.
//! \class DataEncryptorWithMAC
//! \brief Password-Based encryptor
//! \tparam BC BlockCipher based class used for encryption
//! \tparam H HashTransformation based class used for mashing
//! \tparam MAC HashTransformation based class used for authentication
//! \tparam Info Constants used by the algorithms
//! \details DataEncryptorWithMAC uses a non-standard mashup function called Mash() to derive key
//! bits from the password.
//! \details The purpose of the function Mash() is to take an arbitrary length input string and
//! *deterministically* produce an arbitrary length output string such that (1) it looks random,
//! (2) no information about the input is deducible from it, and (3) it contains as much entropy
//! as it can hold, or the amount of entropy in the input string, whichever is smaller.
class DefaultEncryptorWithMAC : public ProxyFilter
//! \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
//! Crypto++ 5.7 switched to AES and SHA256.
//! \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC
//! \since Crypto++ 2.0
template <class BC, class H, class MAC, class Info>
class DataEncryptorWithMAC : public ProxyFilter
{
public:
//! \brief Constructs a DefaultEncryptorWithMAC
//! \brief Constructs a DataEncryptorWithMAC
//! \param passphrase a C-String password
//! \param attachment a BufferedTransformation to attach to this object
DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL);
DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL);
//! \brief Constructs a DefaultEncryptorWithMAC
//! \brief Constructs a DataEncryptorWithMAC
//! \param passphrase a byte string password
//! \param passphraseLength the length of the byte string password
//! \param attachment a BufferedTransformation to attach to this object
DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL);
DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL);
protected:
void FirstPut(const byte *inString) {CRYPTOPP_UNUSED(inString);}
void LastPut(const byte *inString, size_t length);
private:
member_ptr<DefaultMAC> m_mac;
member_ptr<MAC> m_mac;
} CRYPTOPP_DEPRECATED ("DefaultEncryptorWithMAC will be changing in the near future because the algorithms are no longer secure");
};
//! \class DefaultDecryptorWithMAC
//! \brief Password-Based decryptor using TripleDES and HMAC/SHA-1
//! \details DefaultDecryptorWithMAC uses a non-standard mashup function called Mash() to derive key
//! bits from the password. The class also uses 2-key TripleDES (DES_EDE2) for encryption, which only
//! provides about 80-bits of security.
//! \class DataDecryptorWithMAC
//! \brief Password-Based decryptor
//! \tparam BC BlockCipher based class used for encryption
//! \tparam H HashTransformation based class used for mashing
//! \tparam MAC HashTransformation based class used for authentication
//! \tparam Info Constants used by the algorithms
//! \details DataDecryptorWithMAC uses a non-standard mashup function called Mash() to derive key
//! bits from the password.
//! \details The purpose of the function Mash() is to take an arbitrary length input string and
//! *deterministically* produce an arbitrary length output string such that (1) it looks random,
//! (2) no information about the input is deducible from it, and (3) it contains as much entropy
//! as it can hold, or the amount of entropy in the input string, whichever is smaller.
class DefaultDecryptorWithMAC : public ProxyFilter
//! \details Crypto++ 5.6.5 and earlier used the legacy algorithms, including DES_EDE2 and SHA1.
//! Crypto++ 5.7 switched to AES and SHA256.
//! \sa DefaultEncryptorWithMAC, DefaultDecryptorWithMAC, LegacyDecryptorWithMAC, LegacyEncryptorWithMAC
//! \since Crypto++ 2.0
template <class BC, class H, class MAC, class Info>
class DataDecryptorWithMAC : public ProxyFilter
{
public:
//! \class MACBadErr
//! \brief Excpetion thrown when an incorrect MAC is encountered
class MACBadErr : public DefaultDecryptor::Err {public: MACBadErr() : DefaultDecryptor::Err("DefaultDecryptorWithMAC: MAC check failed") {}};
//! \brief Constructs a DefaultDecryptor
//! \brief Constructs a DataDecryptor
//! \param passphrase a C-String password
//! \param attachment a BufferedTransformation to attach to this object
//! \param throwException a flag specifiying whether an Exception should be thrown on error
DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true);
DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true);
//! \brief Constructs a DefaultDecryptor
//! \brief Constructs a DataDecryptor
//! \param passphrase a byte string password
//! \param passphraseLength the length of the byte string password
//! \param attachment a BufferedTransformation to attach to this object
//! \param throwException a flag specifiying whether an Exception should be thrown on error
DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true);
DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true);
DefaultDecryptor::State CurrentState() const;
typename DataDecryptor<BC,H,Info>::State CurrentState() const;
bool CheckLastMAC() const;
protected:
@ -166,11 +241,22 @@ protected:
void LastPut(const byte *inString, size_t length);
private:
member_ptr<DefaultMAC> m_mac;
member_ptr<MAC> m_mac;
HashVerificationFilter *m_hashVerifier;
bool m_throwException;
};
} CRYPTOPP_DEPRECATED ("DefaultDecryptorWithMAC will be changing in the near future because the algorithms are no longer secure");
typedef DataEncryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> LegacyEncryptor;
typedef DataDecryptor<LegacyBlockCipher,LegacyHashModule,LegacyParametersInfo> LegacyDecryptor;
typedef DataEncryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> DefaultEncryptor;
typedef DataDecryptor<DefaultBlockCipher,DefaultHashModule,DefaultParametersInfo> DefaultDecryptor;
typedef DataEncryptorWithMAC<LegacyBlockCipher,LegacyHashModule,DefaultMAC,LegacyParametersInfo> LegacyEncryptorWithMAC;
typedef DataDecryptorWithMAC<LegacyBlockCipher,LegacyHashModule,DefaultMAC,LegacyParametersInfo> LegacyDecryptorWithMAC;
typedef DataEncryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> DefaultEncryptorWithMAC;
typedef DataDecryptorWithMAC<DefaultBlockCipher,DefaultHashModule,DefaultMAC,DefaultParametersInfo> DefaultDecryptorWithMAC;
NAMESPACE_END