1// hmac.h - written and placed in the public domain by Wei Dai 2 3#ifndef CRYPTOPP_HMAC_H 4#define CRYPTOPP_HMAC_H 5 6#include "seckey.h" 7#include "secblock.h" 8 9NAMESPACE_BEGIN(CryptoPP) 10 11//! _ 12class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HMAC_Base : public VariableKeyLength<16, 0, INT_MAX>, public MessageAuthenticationCode 13{ 14public: 15 HMAC_Base() : m_innerHashKeyed(false) {} 16 void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); 17 18 void Restart(); 19 void Update(const byte *input, size_t length); 20 void TruncatedFinal(byte *mac, size_t size); 21 unsigned int OptimalBlockSize() const {return const_cast<HMAC_Base*>(this)->AccessHash().OptimalBlockSize();} 22 unsigned int DigestSize() const {return const_cast<HMAC_Base*>(this)->AccessHash().DigestSize();} 23 24protected: 25 virtual HashTransformation & AccessHash() =0; 26 byte * AccessIpad() {return m_buf;} 27 byte * AccessOpad() {return m_buf + AccessHash().BlockSize();} 28 byte * AccessInnerHash() {return m_buf + 2*AccessHash().BlockSize();} 29 30private: 31 void KeyInnerHash(); 32 33 SecByteBlock m_buf; 34 bool m_innerHashKeyed; 35}; 36 37//! <a href="http://www.weidai.com/scan-mirror/mac.html#HMAC">HMAC</a> 38/*! HMAC(K, text) = H(K XOR opad, H(K XOR ipad, text)) */ 39template <class T> 40class HMAC : public MessageAuthenticationCodeImpl<HMAC_Base, HMAC<T> > 41{ 42public: 43 CRYPTOPP_CONSTANT(DIGESTSIZE=T::DIGESTSIZE) 44 CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE) 45 46 HMAC() {} 47 HMAC(const byte *key, size_t length=HMAC_Base::DEFAULT_KEYLENGTH) 48 {this->SetKey(key, length);} 49 50 static std::string StaticAlgorithmName() {return std::string("HMAC(") + T::StaticAlgorithmName() + ")";} 51 std::string AlgorithmName() const {return std::string("HMAC(") + m_hash.AlgorithmName() + ")";} 52 53private: 54 HashTransformation & AccessHash() {return m_hash;} 55 56 T m_hash; 57}; 58 59NAMESPACE_END 60 61#endif 62