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 ¶ms);
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
00030
00031
00032
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 ¶ms)
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