Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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