From b21162cf8e06f40baa1f58be6a8c17435cebc34d Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 Oct 2002 17:31:41 +0000 Subject: Initial revision git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- dmac.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 dmac.h (limited to 'dmac.h') diff --git a/dmac.h b/dmac.h new file mode 100644 index 0000000..dd5d3cb --- /dev/null +++ b/dmac.h @@ -0,0 +1,90 @@ +#ifndef CRYPTOPP_DMAC_H +#define CRYPTOPP_DMAC_H + +#include "cbcmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +class DMAC_Base : public SameKeyLengthAs, 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 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 DMAC : public MessageAuthenticationCodeTemplate > +{ +public: + DMAC() {} + DMAC(const byte *key, unsigned int length=DMAC_Base::DEFAULT_KEYLENGTH) + {SetKey(key, length);} +}; + +template +void DMAC_Base::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 +void DMAC_Base::Update(const byte *input, unsigned int length) +{ + m_mac1.Update(input, length); + m_counter = (m_counter + length) % T::BLOCKSIZE; +} + +template +void DMAC_Base::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 +byte *DMAC_Base::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 -- cgit v1.2.1