panama.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // panama.h - originally written and placed in the public domain by Wei Dai
  2. /// \file panama.h
  3. /// \brief Classes for Panama hash and stream cipher
  4. #ifndef CRYPTOPP_PANAMA_H
  5. #define CRYPTOPP_PANAMA_H
  6. #include "strciphr.h"
  7. #include "iterhash.h"
  8. #include "secblock.h"
  9. // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler error with .intel_syntax
  10. //#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM)
  11. //# define CRYPTOPP_DISABLE_PANAMA_ASM
  12. //#endif
  13. // https://github.com/weidai11/cryptopp/issues/758
  14. #define CRYPTOPP_DISABLE_PANAMA_ASM 1
  15. NAMESPACE_BEGIN(CryptoPP)
  16. // Base class, do not use directly
  17. template <class B>
  18. class CRYPTOPP_NO_VTABLE Panama
  19. {
  20. public:
  21. virtual ~Panama() {}
  22. std::string AlgorithmProvider() const;
  23. void Reset();
  24. void Iterate(size_t count, const word32 *p=NULLPTR, byte *output=NULLPTR, const byte *input=NULLPTR, KeystreamOperation operation=WRITE_KEYSTREAM);
  25. protected:
  26. typedef word32 Stage[8];
  27. CRYPTOPP_CONSTANT(STAGES = 32);
  28. FixedSizeAlignedSecBlock<word32, 20 + 8*32> m_state;
  29. };
  30. namespace Weak {
  31. /// \brief Panama hash
  32. /// \sa <a href="http://www.weidai.com/scan-mirror/md.html#Panama">Panama Hash</a>
  33. template <class B = LittleEndian>
  34. class PanamaHash : protected Panama<B>, public AlgorithmImpl<IteratedHash<word32, NativeByteOrder, 32>, PanamaHash<B> >
  35. {
  36. public:
  37. CRYPTOPP_CONSTANT(DIGESTSIZE = 32);
  38. virtual ~PanamaHash() {}
  39. PanamaHash() {Panama<B>::Reset();}
  40. unsigned int DigestSize() const {return DIGESTSIZE;}
  41. void TruncatedFinal(byte *hash, size_t size);
  42. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";}
  43. std::string AlgorithmProvider() const {return Panama<B>::AlgorithmProvider();} // Fix https://github.com/weidai11/cryptopp/issues/801
  44. protected:
  45. void Init() {Panama<B>::Reset();}
  46. void HashEndianCorrectedBlock(const word32 *data) {this->Iterate(1, data);} // push
  47. size_t HashMultipleBlocks(const word32 *input, size_t length);
  48. word32* StateBuf() {return NULLPTR;}
  49. FixedSizeSecBlock<word32, 8> m_buf;
  50. };
  51. }
  52. /// \brief MAC construction using a hermetic hash function
  53. template <class T_Hash, class T_Info = T_Hash>
  54. class HermeticHashFunctionMAC : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<MessageAuthenticationCode, VariableKeyLength<32, 0, INT_MAX> > >, T_Info>
  55. {
  56. public:
  57. void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  58. {
  59. CRYPTOPP_UNUSED(params);
  60. m_key.Assign(key, length);
  61. Restart();
  62. }
  63. void Restart()
  64. {
  65. m_hash.Restart();
  66. m_keyed = false;
  67. }
  68. void Update(const byte *input, size_t length)
  69. {
  70. if (!m_keyed)
  71. KeyHash();
  72. m_hash.Update(input, length);
  73. }
  74. void TruncatedFinal(byte *digest, size_t digestSize)
  75. {
  76. if (!m_keyed)
  77. KeyHash();
  78. m_hash.TruncatedFinal(digest, digestSize);
  79. m_keyed = false;
  80. }
  81. unsigned int DigestSize() const
  82. {return m_hash.DigestSize();}
  83. unsigned int BlockSize() const
  84. {return m_hash.BlockSize();}
  85. unsigned int OptimalBlockSize() const
  86. {return m_hash.OptimalBlockSize();}
  87. unsigned int OptimalDataAlignment() const
  88. {return m_hash.OptimalDataAlignment();}
  89. protected:
  90. void KeyHash()
  91. {
  92. m_hash.Update(m_key, m_key.size());
  93. m_keyed = true;
  94. }
  95. T_Hash m_hash;
  96. bool m_keyed;
  97. SecByteBlock m_key;
  98. };
  99. namespace Weak {
  100. /// \brief Panama message authentication code
  101. template <class B = LittleEndian>
  102. class PanamaMAC : public HermeticHashFunctionMAC<PanamaHash<B> >
  103. {
  104. public:
  105. PanamaMAC() {}
  106. PanamaMAC(const byte *key, unsigned int length)
  107. {this->SetKey(key, length);}
  108. };
  109. }
  110. /// \brief Panama stream cipher information
  111. template <class B>
  112. struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 32>
  113. {
  114. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";}
  115. };
  116. /// \brief Panama stream cipher operation
  117. template <class B>
  118. class PanamaCipherPolicy : public AdditiveCipherConcretePolicy<word32, 8>,
  119. public PanamaCipherInfo<B>,
  120. protected Panama<B>
  121. {
  122. protected:
  123. virtual ~PanamaCipherPolicy() {}
  124. std::string AlgorithmProvider() const;
  125. void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length);
  126. void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount);
  127. bool CipherIsRandomAccess() const {return false;}
  128. void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length);
  129. unsigned int GetAlignment() const;
  130. FixedSizeSecBlock<word32, 8> m_key;
  131. FixedSizeSecBlock<word32, 8> m_buf;
  132. };
  133. /// \brief Panama stream cipher
  134. /// \sa <a href="http://www.cryptolounge.org/wiki/PANAMA">Panama Stream Cipher</a>
  135. template <class B = LittleEndian>
  136. struct PanamaCipher : public PanamaCipherInfo<B>, public SymmetricCipherDocumentation
  137. {
  138. typedef SymmetricCipherFinal<ConcretePolicyHolder<PanamaCipherPolicy<B>, AdditiveCipherTemplate<> >, PanamaCipherInfo<B> > Encryption;
  139. typedef Encryption Decryption;
  140. };
  141. NAMESPACE_END
  142. #endif