diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2002-10-04 17:31:41 +0000 |
commit | b21162cf8e06f40baa1f58be6a8c17435cebc34d (patch) | |
tree | 8b045309c238226c32a563b1df6b9c30a2f0e0b3 /dmac.h | |
download | cryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz |
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'dmac.h')
-rw-r--r-- | dmac.h | 90 |
1 files changed, 90 insertions, 0 deletions
@@ -0,0 +1,90 @@ +#ifndef CRYPTOPP_DMAC_H +#define CRYPTOPP_DMAC_H + +#include "cbcmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +template <class T> +class DMAC_Base : public SameKeyLengthAs<T>, public MessageAuthenticationCode +{ +public: + static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";} + + enum {DIGESTSIZE=T::BLOCKSIZE}; + + DMAC_Base() {} + + void CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, unsigned int length); + void TruncatedFinal(byte *mac, unsigned int size); + unsigned int DigestSize() const {return DIGESTSIZE;} + +private: + byte *GenerateSubKeys(const byte *key, unsigned int keylength); + + unsigned int m_subkeylength; + SecByteBlock m_subkeys; + CBC_MAC<T> m_mac1; + typename T::Encryption m_f2; + unsigned int m_counter; +}; + +//! DMAC +/*! Based on "CBC MAC for Real-Time Data Sources" by Erez Petrank + and Charles Rackoff. T should be BlockTransformation class. +*/ +template <class T> +class DMAC : public MessageAuthenticationCodeTemplate<DMAC_Base<T> > +{ +public: + DMAC() {} + DMAC(const byte *key, unsigned int length=DMAC_Base<T>::DEFAULT_KEYLENGTH) + {SetKey(key, length);} +}; + +template <class T> +void DMAC_Base<T>::CheckedSetKey(void *, Empty empty, const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE); + m_subkeys.resize(2*STDMAX((unsigned int)T::BLOCKSIZE, m_subkeylength)); + m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params); + m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params); + m_counter = 0; + m_subkeys.resize(0); +} + +template <class T> +void DMAC_Base<T>::Update(const byte *input, unsigned int length) +{ + m_mac1.Update(input, length); + m_counter = (m_counter + length) % T::BLOCKSIZE; +} + +template <class T> +void DMAC_Base<T>::TruncatedFinal(byte *mac, unsigned int size) +{ + ThrowIfInvalidTruncatedSize(size); + + byte pad[T::BLOCKSIZE]; + byte padByte = byte(T::BLOCKSIZE-m_counter); + memset(pad, padByte, padByte); + m_mac1.Update(pad, padByte); + m_mac1.TruncatedFinal(mac, size); + m_f2.ProcessBlock(mac); +} + +template <class T> +byte *DMAC_Base<T>::GenerateSubKeys(const byte *key, unsigned int keylength) +{ + typename T::Encryption cipher(key, keylength); + memset(m_subkeys, 0, m_subkeys.size()); + cipher.ProcessBlock(m_subkeys); + m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1; + cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2); + return m_subkeys; +} + +NAMESPACE_END + +#endif |