Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# 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)
    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         if (keylength <= blockSize)
    00024                 memcpy(AccessIpad(), userKey, keylength);
    00025         else
    00026         {
    00027                 AccessHash().CalculateDigest(AccessIpad(), userKey, keylength);
    00028                 keylength = hash.DigestSize();
    00029         }
    00030
    00031         assert(keylength <= blockSize);
    00032         memset(AccessIpad()+keylength, 0, blockSize-keylength);
    00033
    00034         for (unsigned int i=0; i<blockSize; i++)
    00035         {
    00036                 AccessOpad()[i] = AccessIpad()[i] ^ OPAD;
    00037                 AccessIpad()[i] ^= IPAD;
    00038         }
    00039 }
    00040
    00041 void HMAC_Base::KeyInnerHash()
    00042 {
    00043         assert(!m_innerHashKeyed);
    00044         HashTransformation &hash = AccessHash();
    00045         hash.Update(AccessIpad(), hash.BlockSize());
    00046         m_innerHashKeyed = true;
    00047 }
    00048
    00049 void HMAC_Base::Restart()
    00050 {
    00051         if (m_innerHashKeyed)
    00052         {
    00053                 AccessHash().Restart();
    00054                 m_innerHashKeyed = false;
    00055         }
    00056 }
    00057
    00058 void HMAC_Base::Update(const byte *input, unsigned int length)
    00059 {
    00060         if (!m_innerHashKeyed)
    00061                 KeyInnerHash();
    00062         AccessHash().Update(input, length);
    00063 }
    00064
    00065 void HMAC_Base::TruncatedFinal(byte *mac, unsigned int size)
    00066 {
    00067         ThrowIfInvalidTruncatedSize(size);
    00068
    00069         HashTransformation &hash = AccessHash();
    00070
    00071         if (!m_innerHashKeyed)
    00072                 KeyInnerHash();
    00073         hash.Final(AccessInnerHash());
    00074
    00075         hash.Update(AccessOpad(), hash.BlockSize());
    00076         hash.Update(AccessInnerHash(), hash.DigestSize());
    00077         hash.TruncatedFinal(mac, size);
    00078
    00079         m_innerHashKeyed = false;
    00080 }
    00081
    00082 NAMESPACE_END
    00083
    00084 #endif