hmac.cpp

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

Generated on Sat Dec 23 02:07:07 2006 for Crypto++ by  doxygen 1.5.1-p1