00001
00002
00003 #ifndef CRYPTOPP_HMAC_H
00004 #define CRYPTOPP_HMAC_H
00005
00006 #include "seckey.h"
00007 #include "secblock.h"
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011 class CRYPTOPP_DLL HMAC_Base : public VariableKeyLength<16, 0, UINT_MAX>, public MessageAuthenticationCode
00012 {
00013 public:
00014 HMAC_Base() : m_innerHashKeyed(false) {}
00015 void UncheckedSetKey(const byte *userKey, unsigned int keylength);
00016
00017 void Restart();
00018 void Update(const byte *input, unsigned int length);
00019 void TruncatedFinal(byte *mac, unsigned int size);
00020 unsigned int OptimalBlockSize() const {return const_cast<HMAC_Base*>(this)->AccessHash().OptimalBlockSize();}
00021 unsigned int DigestSize() const {return const_cast<HMAC_Base*>(this)->AccessHash().DigestSize();}
00022
00023 protected:
00024 virtual HashTransformation & AccessHash() =0;
00025 virtual byte * AccessIpad() =0;
00026 virtual byte * AccessOpad() =0;
00027 virtual byte * AccessInnerHash() =0;
00028
00029 private:
00030 void KeyInnerHash();
00031
00032 enum {IPAD=0x36, OPAD=0x5c};
00033
00034 bool m_innerHashKeyed;
00035 };
00036
00037
00038
00039 template <class T>
00040 class HMAC : public MessageAuthenticationCodeFinalTemplate<HMAC_Base, HMAC<T> >
00041 {
00042 public:
00043 enum {DIGESTSIZE=T::DIGESTSIZE, BLOCKSIZE=T::BLOCKSIZE};
00044
00045 HMAC() {}
00046 HMAC(const byte *key, unsigned int length=HMAC_Base::DEFAULT_KEYLENGTH)
00047 {SetKey(key, length);}
00048
00049 static std::string StaticAlgorithmName() {return std::string("HMAC(") + T::StaticAlgorithmName() + ")";}
00050
00051 private:
00052 HashTransformation & AccessHash() {return m_hash;}
00053 byte * AccessIpad() {return m_ipad;}
00054 byte * AccessOpad() {return m_opad;}
00055 byte * AccessInnerHash() {return m_innerHash;}
00056
00057 FixedSizeSecBlock<byte, BLOCKSIZE> m_ipad, m_opad;
00058 FixedSizeSecBlock<byte, DIGESTSIZE> m_innerHash;
00059 T m_hash;
00060 };
00061
00062 NAMESPACE_END
00063
00064 #endif