Botan
1.11.15
|
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 }