1 // mdc.h - originally written and placed in the public domain by Wei Dai 2 3 /// \file mdc.h 4 /// \brief Classes for the MDC message digest 5 6 #ifndef CRYPTOPP_MDC_H 7 #define CRYPTOPP_MDC_H 8 9 #include "seckey.h" 10 #include "secblock.h" 11 #include "misc.h" 12 13 // GCC cast warning 14 #define HashWordPtr(x) ((HashWordType*)(void*)(x)) 15 #define ConstHashWordPtr(x) ((const HashWordType*)(const void*)(x)) 16 17 NAMESPACE_BEGIN(CryptoPP) 18 19 /// \tparam B BlockCipher derived class 20 /// \brief MDC_Info cipher information 21 template <class B> 22 struct MDC_Info : public FixedBlockSize<B::DIGESTSIZE>, public FixedKeyLength<B::BLOCKSIZE> 23 { StaticAlgorithmNameMDC_Info24 static std::string StaticAlgorithmName() {return std::string("MDC/")+B::StaticAlgorithmName();} 25 }; 26 27 /// \brief MDC cipher 28 /// \tparam H HashTransformation derived class 29 /// \details MDC() is a construction by Peter Gutmann to turn an iterated hash function into a PRF 30 /// \sa <a href="http://www.cryptopp.com/wiki/MDC">MDC</a> 31 template <class H> 32 class MDC : public MDC_Info<H> 33 { 34 /// \brief MDC cipher encryption operation 35 class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl<MDC_Info<H> > 36 { 37 typedef typename H::HashWordType HashWordType; 38 39 public: UncheckedSetKey(const byte * userKey,unsigned int length,const NameValuePairs & params)40 void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) 41 { 42 CRYPTOPP_UNUSED(params); 43 this->AssertValidKeyLength(length); 44 ConditionalByteReverse(BIG_ENDIAN_ORDER, Key(), ConstHashWordPtr(userKey), this->KEYLENGTH); 45 } 46 ProcessAndXorBlock(const byte * inBlock,const byte * xorBlock,byte * outBlock)47 void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 48 { 49 ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), ConstHashWordPtr(inBlock), this->BLOCKSIZE); 50 H::Transform(Buffer(), Key()); 51 52 if (xorBlock) 53 { 54 ConditionalByteReverse(BIG_ENDIAN_ORDER, Buffer(), Buffer(), this->BLOCKSIZE); 55 xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE); 56 } 57 else 58 { 59 ConditionalByteReverse(BIG_ENDIAN_ORDER, HashWordPtr(outBlock), Buffer(), this->BLOCKSIZE); 60 } 61 } 62 IsPermutation()63 bool IsPermutation() const {return false;} 64 OptimalDataAlignment()65 unsigned int OptimalDataAlignment() const {return sizeof(HashWordType);} 66 67 private: Key()68 HashWordType *Key() {return HashWordPtr(m_key.data());} Key()69 const HashWordType *Key() const {return ConstHashWordPtr(m_key.data());} Buffer()70 HashWordType *Buffer() const {return HashWordPtr(m_buffer.data());} 71 72 // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup 73 FixedSizeSecBlock<byte, MDC_Info<H>::KEYLENGTH, AllocatorWithCleanup<byte> > m_key; 74 mutable FixedSizeSecBlock<byte, MDC_Info<H>::BLOCKSIZE, AllocatorWithCleanup<byte> > m_buffer; 75 }; 76 77 public: 78 // use BlockCipher interface 79 typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption; 80 }; 81 82 NAMESPACE_END 83 84 #endif 85