// panama.h - originally written and placed in the public domain by Wei Dai /// \file panama.h /// \brief Classes for Panama hash and stream cipher #ifndef CRYPTOPP_PANAMA_H #define CRYPTOPP_PANAMA_H #include "strciphr.h" #include "iterhash.h" #include "secblock.h" // Clang 3.3 integrated assembler crash on Linux. Clang 3.4 due to compiler error with .intel_syntax //#if CRYPTOPP_BOOL_X32 || defined(CRYPTOPP_DISABLE_MIXED_ASM) //# define CRYPTOPP_DISABLE_PANAMA_ASM //#endif // https://github.com/weidai11/cryptopp/issues/758 #define CRYPTOPP_DISABLE_PANAMA_ASM 1 NAMESPACE_BEGIN(CryptoPP) // Base class, do not use directly template class CRYPTOPP_NO_VTABLE Panama { public: virtual ~Panama() {} std::string AlgorithmProvider() const; void Reset(); void Iterate(size_t count, const word32 *p=NULLPTR, byte *output=NULLPTR, const byte *input=NULLPTR, KeystreamOperation operation=WRITE_KEYSTREAM); protected: typedef word32 Stage[8]; CRYPTOPP_CONSTANT(STAGES = 32); FixedSizeAlignedSecBlock m_state; }; namespace Weak { /// \brief Panama hash /// \sa Panama Hash template class PanamaHash : protected Panama, public AlgorithmImpl, PanamaHash > { public: CRYPTOPP_CONSTANT(DIGESTSIZE = 32); virtual ~PanamaHash() {} PanamaHash() {Panama::Reset();} unsigned int DigestSize() const {return DIGESTSIZE;} void TruncatedFinal(byte *hash, size_t size); CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";} std::string AlgorithmProvider() const {return Panama::AlgorithmProvider();} // Fix https://github.com/weidai11/cryptopp/issues/801 protected: void Init() {Panama::Reset();} void HashEndianCorrectedBlock(const word32 *data) {this->Iterate(1, data);} // push size_t HashMultipleBlocks(const word32 *input, size_t length); word32* StateBuf() {return NULLPTR;} FixedSizeSecBlock m_buf; }; } /// \brief MAC construction using a hermetic hash function template class HermeticHashFunctionMAC : public AlgorithmImpl > >, T_Info> { public: void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) { CRYPTOPP_UNUSED(params); m_key.Assign(key, length); Restart(); } void Restart() { m_hash.Restart(); m_keyed = false; } void Update(const byte *input, size_t length) { if (!m_keyed) KeyHash(); m_hash.Update(input, length); } void TruncatedFinal(byte *digest, size_t digestSize) { if (!m_keyed) KeyHash(); m_hash.TruncatedFinal(digest, digestSize); m_keyed = false; } unsigned int DigestSize() const {return m_hash.DigestSize();} unsigned int BlockSize() const {return m_hash.BlockSize();} unsigned int OptimalBlockSize() const {return m_hash.OptimalBlockSize();} unsigned int OptimalDataAlignment() const {return m_hash.OptimalDataAlignment();} protected: void KeyHash() { m_hash.Update(m_key, m_key.size()); m_keyed = true; } T_Hash m_hash; bool m_keyed; SecByteBlock m_key; }; namespace Weak { /// \brief Panama message authentication code template class PanamaMAC : public HermeticHashFunctionMAC > { public: PanamaMAC() {} PanamaMAC(const byte *key, unsigned int length) {this->SetKey(key, length);} }; } /// \brief Panama stream cipher information template struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 32> { CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";} }; /// \brief Panama stream cipher operation template class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, public PanamaCipherInfo, protected Panama { protected: virtual ~PanamaCipherPolicy() {} std::string AlgorithmProvider() const; void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); bool CipherIsRandomAccess() const {return false;} void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length); unsigned int GetAlignment() const; FixedSizeSecBlock m_key; FixedSizeSecBlock m_buf; }; /// \brief Panama stream cipher /// \sa Panama Stream Cipher template struct PanamaCipher : public PanamaCipherInfo, public SymmetricCipherDocumentation { typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, PanamaCipherInfo > Encryption; typedef Encryption Decryption; }; NAMESPACE_END #endif