Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

cbcmac.h

00001 #ifndef CRYPTOPP_CBCMAC_H
00002 #define CRYPTOPP_CBCMAC_H
00003 
00004 #include "seckey.h"
00005 #include "secblock.h"
00006 
00007 NAMESPACE_BEGIN(CryptoPP)
00008 
00009 template <class T>
00010 class CBC_MAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode
00011 {
00012 public:
00013         static std::string StaticAlgorithmName() {return std::string("CBC-MAC(") + T::StaticAlgorithmName() + ")";}
00014 
00015         CBC_MAC_Base() {}
00016 
00017         void CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs &params);
00018         void Update(const byte *input, unsigned int length);
00019         void TruncatedFinal(byte *mac, unsigned int size);
00020         unsigned int DigestSize() const {return m_cipher.BlockSize();}
00021 
00022 private:
00023         void ProcessBuf();
00024         typename T::Encryption m_cipher;
00025         SecByteBlock m_reg;
00026         unsigned int m_counter;
00027 };
00028 
00029 //! <a href="http://www.weidai.com/scan-mirror/mac.html#CBC-MAC">CBC-MAC</a>
00030 /*! Compatible with FIPS 113. T should be an encryption class.
00031         Secure only for fixed length messages. For variable length
00032         messages use DMAC.
00033 */
00034 template <class T>
00035 class CBC_MAC : public MessageAuthenticationCodeTemplate<CBC_MAC_Base<T> >
00036 {
00037 public:
00038         CBC_MAC() {}
00039         CBC_MAC(const byte *key, unsigned int length=CBC_MAC_Base<T>::DEFAULT_KEYLENGTH)
00040                 {SetKey(key, length);}
00041 };
00042 
00043 template <class T>
00044 void CBC_MAC_Base<T>::CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs &params)
00045 {
00046         m_cipher.SetKey(key, length, params);
00047         m_reg.CleanNew(m_cipher.BlockSize());
00048         m_counter = 0;
00049 }
00050 
00051 template <class T>
00052 void CBC_MAC_Base<T>::Update(const byte *input, unsigned int length)
00053 {
00054         while (m_counter && length)
00055         {
00056                 m_reg[m_counter++] ^= *input++;
00057                 if (m_counter == T::BLOCKSIZE)
00058                         ProcessBuf();
00059                 length--;
00060         }
00061 
00062         while (length >= T::BLOCKSIZE)
00063         {
00064                 xorbuf(m_reg, input, T::BLOCKSIZE);
00065                 ProcessBuf();
00066                 input += T::BLOCKSIZE;
00067                 length -= T::BLOCKSIZE;
00068         }
00069 
00070         while (length--)
00071         {
00072                 m_reg[m_counter++] ^= *input++;
00073                 if (m_counter == T::BLOCKSIZE)
00074                         ProcessBuf();
00075         }
00076 }
00077 
00078 template <class T>
00079 void CBC_MAC_Base<T>::TruncatedFinal(byte *mac, unsigned int size)
00080 {
00081         ThrowIfInvalidTruncatedSize(size);
00082 
00083         if (m_counter)
00084                 ProcessBuf();
00085 
00086         memcpy(mac, m_reg, size);
00087         memset(m_reg, 0, T::BLOCKSIZE);
00088 }
00089 
00090 template <class T>
00091 void CBC_MAC_Base<T>::ProcessBuf()
00092 {
00093         m_cipher.ProcessBlock(m_reg);
00094         m_counter = 0;
00095 }
00096 
00097 NAMESPACE_END
00098 
00099 #endif

Generated on Sun Mar 14 20:44:24 2004 for Crypto++ by doxygen 1.3.6-20040222