Crypto++
|
00001 // hmac.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 00005 #ifndef CRYPTOPP_IMPORTS 00006 00007 #include "hmac.h" 00008 00009 NAMESPACE_BEGIN(CryptoPP) 00010 00011 void HMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) 00012 { 00013 AssertValidKeyLength(keylength); 00014 00015 Restart(); 00016 00017 HashTransformation &hash = AccessHash(); 00018 unsigned int blockSize = hash.BlockSize(); 00019 00020 if (!blockSize) 00021 throw InvalidArgument("HMAC: can only be used with a block-based hash function"); 00022 00023 m_buf.resize(2*AccessHash().BlockSize() + AccessHash().DigestSize()); 00024 00025 if (keylength <= blockSize) 00026 memcpy(AccessIpad(), userKey, keylength); 00027 else 00028 { 00029 AccessHash().CalculateDigest(AccessIpad(), userKey, keylength); 00030 keylength = hash.DigestSize(); 00031 } 00032 00033 assert(keylength <= blockSize); 00034 memset(AccessIpad()+keylength, 0, blockSize-keylength); 00035 00036 for (unsigned int i=0; i<blockSize; i++) 00037 { 00038 AccessOpad()[i] = AccessIpad()[i] ^ 0x5c; 00039 AccessIpad()[i] ^= 0x36; 00040 } 00041 } 00042 00043 void HMAC_Base::KeyInnerHash() 00044 { 00045 assert(!m_innerHashKeyed); 00046 HashTransformation &hash = AccessHash(); 00047 hash.Update(AccessIpad(), hash.BlockSize()); 00048 m_innerHashKeyed = true; 00049 } 00050 00051 void HMAC_Base::Restart() 00052 { 00053 if (m_innerHashKeyed) 00054 { 00055 AccessHash().Restart(); 00056 m_innerHashKeyed = false; 00057 } 00058 } 00059 00060 void HMAC_Base::Update(const byte *input, size_t length) 00061 { 00062 if (!m_innerHashKeyed) 00063 KeyInnerHash(); 00064 AccessHash().Update(input, length); 00065 } 00066 00067 void HMAC_Base::TruncatedFinal(byte *mac, size_t size) 00068 { 00069 ThrowIfInvalidTruncatedSize(size); 00070 00071 HashTransformation &hash = AccessHash(); 00072 00073 if (!m_innerHashKeyed) 00074 KeyInnerHash(); 00075 hash.Final(AccessInnerHash()); 00076 00077 hash.Update(AccessOpad(), hash.BlockSize()); 00078 hash.Update(AccessInnerHash(), hash.DigestSize()); 00079 hash.TruncatedFinal(mac, size); 00080 00081 m_innerHashKeyed = false; 00082 } 00083 00084 NAMESPACE_END 00085 00086 #endif