#ifndef CRYPTOPP_CBCMAC_H #define CRYPTOPP_CBCMAC_H #include "seckey.h" #include "secblock.h" NAMESPACE_BEGIN(CryptoPP) template class CRYPTOPP_NO_VTABLE CBC_MAC_Base : public SameKeyLengthAs, public MessageAuthenticationCode { public: static std::string StaticAlgorithmName() {return std::string("CBC-MAC(") + T::StaticAlgorithmName() + ")";} CBC_MAC_Base() {} void CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms); void Update(const byte *input, unsigned int length); void TruncatedFinal(byte *mac, unsigned int size); unsigned int DigestSize() const {return m_cipher.BlockSize();} private: void ProcessBuf(); typename T::Encryption m_cipher; SecByteBlock m_reg; unsigned int m_counter; }; //! CBC-MAC /*! Compatible with FIPS 113. T should be an encryption class. Secure only for fixed length messages. For variable length messages use DMAC. */ template class CBC_MAC : public MessageAuthenticationCodeTemplate > { public: CBC_MAC() {} CBC_MAC(const byte *key, unsigned int length=CBC_MAC_Base::DEFAULT_KEYLENGTH) {SetKey(key, length);} }; template void CBC_MAC_Base::CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms) { m_cipher.SetKey(key, length, params); m_reg.CleanNew(m_cipher.BlockSize()); m_counter = 0; } template void CBC_MAC_Base::Update(const byte *input, unsigned int length) { while (m_counter && length) { m_reg[m_counter++] ^= *input++; if (m_counter == T::BLOCKSIZE) ProcessBuf(); length--; } while (length >= T::BLOCKSIZE) { xorbuf(m_reg, input, T::BLOCKSIZE); ProcessBuf(); input += T::BLOCKSIZE; length -= T::BLOCKSIZE; } while (length--) { m_reg[m_counter++] ^= *input++; if (m_counter == T::BLOCKSIZE) ProcessBuf(); } } template void CBC_MAC_Base::TruncatedFinal(byte *mac, unsigned int size) { ThrowIfInvalidTruncatedSize(size); if (m_counter) ProcessBuf(); memcpy(mac, m_reg, size); memset(m_reg, 0, T::BLOCKSIZE); } template void CBC_MAC_Base::ProcessBuf() { m_cipher.ProcessBlock(m_reg); m_counter = 0; } NAMESPACE_END #endif