23 #ifndef TAO_CRYPT_HMAC_HPP
24 #define TAO_CRYPT_HMAC_HPP
35 enum { IPAD = 0x36, OPAD = 0x5C };
37 HMAC() : ipad_(reinterpret_cast<byte*>(&ip_)),
38 opad_(reinterpret_cast<byte*>(&op_)),
39 innerHash_(reinterpret_cast<byte*>(&innerH_))
43 void Update(
const byte*, word32);
47 void SetKey(
const byte*, word32);
56 enum { HMAC_BSIZE = T::BLOCK_SIZE /
sizeof(word32),
57 HMAC_DSIZE = T::DIGEST_SIZE /
sizeof(word32) };
59 word32 ip_[HMAC_BSIZE];
60 word32 op_[HMAC_BSIZE];
61 word32 innerH_[HMAC_DSIZE];
75 innerHashKeyed_ =
false;
81 void HMAC<T>::SetKey(
const byte* key, word32 length)
85 if (length <= T::BLOCK_SIZE)
86 memcpy(ipad_, key, length);
88 mac_.Update(key, length);
90 length = T::DIGEST_SIZE;
92 memset(ipad_ + length, 0, T::BLOCK_SIZE - length);
94 for (word32
i = 0;
i < T::BLOCK_SIZE;
i++) {
95 opad_[
i] = ipad_[
i] ^ OPAD;
103 void HMAC<T>::KeyInnerHash()
105 mac_.Update(ipad_, T::BLOCK_SIZE);
106 innerHashKeyed_ =
true;
112 void HMAC<T>::Update(
const byte*
msg, word32 length)
114 if (!innerHashKeyed_)
116 mac_.Update(msg, length);
122 void HMAC<T>::Final(byte* hash)
124 if (!innerHashKeyed_)
126 mac_.Final(innerHash_);
128 mac_.Update(opad_, T::BLOCK_SIZE);
129 mac_.Update(innerHash_, T::DIGEST_SIZE);
132 innerHashKeyed_ =
false;
138 #endif // TAO_CRYPT_HMAC_HPP