// mdc.h - originally written and placed in the public domain by Wei Dai #ifndef CRYPTOPP_MDC_H #define CRYPTOPP_MDC_H //! \file mdc.h //! \brief Classes for the MDC message digest #include "seckey.h" #include "secblock.h" #include "misc.h" NAMESPACE_BEGIN(CryptoPP) //! \class MDC_Info //! \tparam B BlockCipher derived class //! \brief MDC_Info cipher information template struct MDC_Info : public FixedBlockSize, public FixedKeyLength { static std::string StaticAlgorithmName() {return std::string("MDC/")+B::StaticAlgorithmName();} }; //! \brief MDC cipher //! \tparam T HashTransformation derived class //! \details MDC() is a construction by Peter Gutmann to turn an iterated hash function into a PRF //! \sa MDC template class MDC : public MDC_Info { //! \class Enc //! \brief MDC cipher encryption operation class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl > { typedef typename H::HashWordType HashWordType; public: void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) { CRYPTOPP_UNUSED(params); this->AssertValidKeyLength(length); ConditionalByteReverse(BIG_ENDIAN_ORDER, Key(), reinterpret_cast(userKey), this->KEYLENGTH); } void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), reinterpret_cast(inBlock), this->BLOCKSIZE); H::Transform(Buffer(), Key()); if (xorBlock) { ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), Buffer(), this->BLOCKSIZE); xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE); } else { ConditionalByteReverse(BIG_ENDIAN_ORDER, reinterpret_cast(outBlock), Buffer(), this->BLOCKSIZE); } } bool IsPermutation() const {return false;} unsigned int OptimalDataAlignment() const {return sizeof(HashWordType);} private: HashWordType *Key() {return reinterpret_cast(m_key.data());} const HashWordType *Key() const {return reinterpret_cast(m_key.data());} HashWordType *Buffer() const {return reinterpret_cast(m_buffer.data());} // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup FixedSizeSecBlock::KEYLENGTH, AllocatorWithCleanup > m_key; mutable FixedSizeSecBlock::BLOCKSIZE, AllocatorWithCleanup > m_buffer; }; public: // use BlockCipher interface typedef BlockCipherFinal Encryption; }; NAMESPACE_END #endif