Botan  1.11.15
src/lib/mac/hmac/hmac.cpp
Go to the documentation of this file.
00001 /*
00002 * HMAC
00003 * (C) 1999-2007,2014 Jack Lloyd
00004 *     2007 Yves Jerschow
00005 *
00006 * Botan is released under the Simplified BSD License (see license.txt)
00007 */
00008 
00009 #include <botan/internal/mac_utils.h>
00010 #include <botan/hmac.h>
00011 
00012 namespace Botan {
00013 
00014 HMAC* HMAC::make(const Spec& spec)
00015    {
00016    if(spec.arg_count() == 1)
00017       return new HMAC(Algo_Registry<HashFunction>::global_registry().make(spec.arg(0)));
00018    return nullptr;
00019    }
00020 
00021 BOTAN_REGISTER_NAMED_T(MessageAuthenticationCode, "HMAC", HMAC, HMAC::make);
00022 
00023 /*
00024 * Update a HMAC Calculation
00025 */
00026 void HMAC::add_data(const byte input[], size_t length)
00027    {
00028    m_hash->update(input, length);
00029    }
00030 
00031 /*
00032 * Finalize a HMAC Calculation
00033 */
00034 void HMAC::final_result(byte mac[])
00035    {
00036    m_hash->final(mac);
00037    m_hash->update(m_okey);
00038    m_hash->update(mac, output_length());
00039    m_hash->final(mac);
00040    m_hash->update(m_ikey);
00041    }
00042 
00043 /*
00044 * HMAC Key Schedule
00045 */
00046 void HMAC::key_schedule(const byte key[], size_t length)
00047    {
00048    m_hash->clear();
00049 
00050    m_ikey.resize(m_hash->hash_block_size());
00051    m_okey.resize(m_hash->hash_block_size());
00052 
00053    std::fill(m_ikey.begin(), m_ikey.end(), 0x36);
00054    std::fill(m_okey.begin(), m_okey.end(), 0x5C);
00055 
00056    if(length > m_hash->hash_block_size())
00057       {
00058       secure_vector<byte> hmac_key = m_hash->process(key, length);
00059       xor_buf(m_ikey, hmac_key, hmac_key.size());
00060       xor_buf(m_okey, hmac_key, hmac_key.size());
00061       }
00062    else
00063       {
00064       xor_buf(m_ikey, key, length);
00065       xor_buf(m_okey, key, length);
00066       }
00067 
00068    m_hash->update(m_ikey);
00069    }
00070 
00071 /*
00072 * Clear memory of sensitive data
00073 */
00074 void HMAC::clear()
00075    {
00076    m_hash->clear();
00077    zap(m_ikey);
00078    zap(m_okey);
00079    }
00080 
00081 /*
00082 * Return the name of this type
00083 */
00084 std::string HMAC::name() const
00085    {
00086    return "HMAC(" + m_hash->name() + ")";
00087    }
00088 
00089 /*
00090 * Return a clone of this object
00091 */
00092 MessageAuthenticationCode* HMAC::clone() const
00093    {
00094    return new HMAC(m_hash->clone());
00095    }
00096 
00097 /*
00098 * HMAC Constructor
00099 */
00100 HMAC::HMAC(HashFunction* hash) : m_hash(hash)
00101    {
00102    if(m_hash->hash_block_size() == 0)
00103       throw Invalid_Argument("HMAC cannot be used with " + m_hash->name());
00104    }
00105 
00106 }