mdc.h 2.6 KB

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