- Main Page
- Namespaces
- Classes
- Files

# dmac.h

    00001 #ifndef CRYPTOPP_DMAC_H
    00002 #define CRYPTOPP_DMAC_H
    00003
    00004 #include "cbcmac.h"
    00005
    00006 NAMESPACE_BEGIN(CryptoPP)
    00007
    00008 //! _
    00009 template <class T>
    00010 class CRYPTOPP_NO_VTABLE DMAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode
    00011 {
    00012 public:
    00013         static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";}
    00014
    00015         CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE)
    00016
    00017         DMAC_Base() {}
    00018
    00019         void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params);
    00020         void Update(const byte *input, size_t length);
    00021         void TruncatedFinal(byte *mac, size_t size);
    00022         unsigned int DigestSize() const {return DIGESTSIZE;}
    00023
    00024 private:
    00025         byte *GenerateSubKeys(const byte *key, size_t keylength);
    00026
    00027         size_t m_subkeylength;
    00028         SecByteBlock m_subkeys;
    00029         CBC_MAC<T> m_mac1;
    00030         typename T::Encryption m_f2;
    00031         unsigned int m_counter;
    00032 };
    00033
    00034 //! DMAC
    00035 /*! Based on "CBC MAC for Real-Time Data Sources" by Erez Petrank
    00036         and Charles Rackoff. T should be a class derived from BlockCipherDocumentation.
    00037 */
    00038 template <class T>
    00039 class DMAC : public MessageAuthenticationCodeFinal<DMAC_Base<T> >
    00040 {
    00041 public:
    00042         DMAC() {}
    00043         DMAC(const byte *key, size_t length=DMAC_Base<T>::DEFAULT_KEYLENGTH)
    00044                 {this->SetKey(key, length);}
    00045 };
    00046
    00047 template <class T>
    00048 void DMAC_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
    00049 {
    00050         m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE);
    00051         m_subkeys.resize(2*UnsignedMin((unsigned int)T::BLOCKSIZE, m_subkeylength));
    00052         m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params);
    00053         m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params);
    00054         m_counter = 0;
    00055         m_subkeys.resize(0);
    00056 }
    00057
    00058 template <class T>
    00059 void DMAC_Base<T>::Update(const byte *input, size_t length)
    00060 {
    00061         m_mac1.Update(input, length);
    00062         m_counter = (unsigned int)((m_counter + length) % T::BLOCKSIZE);
    00063 }
    00064
    00065 template <class T>
    00066 void DMAC_Base<T>::TruncatedFinal(byte *mac, size_t size)
    00067 {
    00068         ThrowIfInvalidTruncatedSize(size);
    00069
    00070         byte pad[T::BLOCKSIZE];
    00071         byte padByte = byte(T::BLOCKSIZE-m_counter);
    00072         memset(pad, padByte, padByte);
    00073         m_mac1.Update(pad, padByte);
    00074         m_mac1.TruncatedFinal(mac, size);
    00075         m_f2.ProcessBlock(mac);
    00076
    00077         m_counter = 0;  // reset for next message
    00078 }
    00079
    00080 template <class T>
    00081 byte *DMAC_Base<T>::GenerateSubKeys(const byte *key, size_t keylength)
    00082 {
    00083         typename T::Encryption cipher(key, keylength);
    00084         memset(m_subkeys, 0, m_subkeys.size());
    00085         cipher.ProcessBlock(m_subkeys);
    00086         m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1;
    00087         cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2);
    00088         return m_subkeys;
    00089 }
    00090
    00091 NAMESPACE_END
    00092
    00093 #endif