- Main Page
- Namespaces
- Classes
- Files

# 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