From bfbcfeec7ca7a0487978391803496a1d4aada37c Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sun, 11 Dec 2016 05:09:42 -0500 Subject: [PATCH] Update DefaultEncryptor, DefaultEncryptorWithMAC and friends (Issue 345) --- default.cpp | 138 ++++++++++++++++++++-------------- default.h | 210 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 232 insertions(+), 116 deletions(-) diff --git a/default.cpp b/default.cpp index f9b42085..dc781bbf 100644 --- a/default.cpp +++ b/default.cpp @@ -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 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> 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> 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 +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(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 +DataEncryptor::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 +DataEncryptor::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 +void DataEncryptor::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(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 +void DataEncryptor::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 +DataDecryptor::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 +DataDecryptor::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 +void DataDecryptor::FirstPut(const byte *inString) { CheckKey(inString, inString+SALTLENGTH); } -void DefaultDecryptor::LastPut(const byte *inString, size_t length) +template +void DataDecryptor::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 +void DataDecryptor::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(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV); m_cipher.SetKeyWithIV(key, key.size(), IV); member_ptr 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 +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(passphrase, passphraseLength, macKey, macKeyLength, 1); + return new MAC(macKey, macKeyLength); } -DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment) +template +DataEncryptorWithMAC::DataEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment) : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase))) + , m_mac(NewDataEncryptorMAC((const byte *)passphrase, strlen(passphrase))) { - SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true)); + SetFilter(new HashFilter(*m_mac, new DataEncryptor(passphrase), true)); } -DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) +template +DataEncryptorWithMAC::DataEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength)) + , m_mac(NewDataEncryptorMAC(passphrase, passphraseLength)) { - SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true)); + SetFilter(new HashFilter(*m_mac, new DataEncryptor(passphrase, passphraseLength), true)); } -void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length) +template +void DataEncryptorWithMAC::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 +DataDecryptorWithMAC::DataDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException) : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase))) + , m_mac(NewDataEncryptorMAC((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(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 +DataDecryptorWithMAC::DataDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) : ProxyFilter(NULL, 0, 0, attachment) - , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength)) + , m_mac(NewDataEncryptorMAC(passphrase, passphraseLength)) , m_throwException(throwException) { - SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerificationFilter(*m_mac, NULL, HashVerificationFilter::PUT_MESSAGE), throwException)); + SetFilter(new DataDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerificationFilter(*m_mac, NULL, HashVerificationFilter::PUT_MESSAGE), throwException)); } -DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const +template +typename DataDecryptor::State DataDecryptorWithMAC::CurrentState() const { - return static_cast(m_filter.get())->CurrentState(); + return static_cast *>(m_filter.get())->CurrentState(); } -bool DefaultDecryptorWithMAC::CheckLastMAC() const +template +bool DataDecryptorWithMAC::CheckLastMAC() const { return m_hashVerifier->GetLastResult(); } -void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length) +template +void DataDecryptorWithMAC::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; +template class DataParametersInfo; +template class DataEncryptor; +template class DataDecryptor; +template class DataEncryptor; +template class DataDecryptor; +template class DataEncryptorWithMAC; +template class DataDecryptorWithMAC; +template class DataEncryptorWithMAC; +template class DataDecryptorWithMAC; +NAMESPACE_END diff --git a/default.h b/default.h index e2e82449..5f33a3c8 100644 --- a/default.h +++ b/default.h @@ -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 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 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 +struct DataParametersInfo +{ + CRYPTOPP_CONSTANT(BLOCKSIZE = BlockSize) + CRYPTOPP_CONSTANT(KEYLENGTH = KeyLength) + CRYPTOPP_CONSTANT(SALTLENGTH = SaltSize) + CRYPTOPP_CONSTANT(DIGESTSIZE = DigestSize) + CRYPTOPP_CONSTANT(ITERATIONS = Iterations) +}; + +typedef DataParametersInfo LegacyParametersInfo; +typedef DataParametersInfo 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 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::Encryption m_cipher; + typename CBC_Mode::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 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::Decryption m_cipher; + typename CBC_Mode::Decryption m_cipher; member_ptr 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 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 m_mac; + member_ptr 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 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::State CurrentState() const; bool CheckLastMAC() const; protected: @@ -166,11 +241,22 @@ protected: void LastPut(const byte *inString, size_t length); private: - member_ptr m_mac; + member_ptr 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 LegacyEncryptor; +typedef DataDecryptor LegacyDecryptor; + +typedef DataEncryptor DefaultEncryptor; +typedef DataDecryptor DefaultDecryptor; + +typedef DataEncryptorWithMAC LegacyEncryptorWithMAC; +typedef DataDecryptorWithMAC LegacyDecryptorWithMAC; + +typedef DataEncryptorWithMAC DefaultEncryptorWithMAC; +typedef DataDecryptorWithMAC DefaultDecryptorWithMAC; NAMESPACE_END