diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
commit | b21162cf8e06f40baa1f58be6a8c17435cebc34d (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /cbcmac.h | |
download | cryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz |
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'cbcmac.h')
-rw-r--r-- | cbcmac.h | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/cbcmac.h b/cbcmac.h new file mode 100644 index 0000000..0297f9d --- /dev/null +++ b/cbcmac.h @@ -0,0 +1,99 @@ +#ifndef CRYPTOPP_CBCMAC_H +#define CRYPTOPP_CBCMAC_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +template <class T> +class CBC_MAC_Base : public SameKeyLengthAs<T>, 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; +}; + +//! <a href="http://www.weidai.com/scan-mirror/mac.html#CBC-MAC">CBC-MAC</a> +/*! Compatible with FIPS 113. T should be an encryption class. + Secure only for fixed length messages. For variable length + messages use DMAC. +*/ +template <class T> +class CBC_MAC : public MessageAuthenticationCodeTemplate<CBC_MAC_Base<T> > +{ +public: + CBC_MAC() {} + CBC_MAC(const byte *key, unsigned int length=CBC_MAC_Base<T>::DEFAULT_KEYLENGTH) + {SetKey(key, length);} +}; + +template <class T> +void CBC_MAC_Base<T>::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 <class T> +void CBC_MAC_Base<T>::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 <class T> +void CBC_MAC_Base<T>::TruncatedFinal(byte *mac, unsigned int size) +{ + ThrowIfInvalidTruncatedSize(size); + + if (m_counter) + ProcessBuf(); + + memcpy(mac, m_reg, size); + memset(m_reg, 0, T::BLOCKSIZE); +} + +template <class T> +void CBC_MAC_Base<T>::ProcessBuf() +{ + m_cipher.ProcessBlock(m_reg); + m_counter = 0; +} + +NAMESPACE_END + +#endif |