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