Botan  2.7.0
Crypto and TLS for C++11
hmac.cpp
Go to the documentation of this file.
1 /*
2 * HMAC
3 * (C) 1999-2007,2014 Jack Lloyd
4 * 2007 Yves Jerschow
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #include <botan/hmac.h>
10 
11 namespace Botan {
12 
13 /*
14 * Update a HMAC Calculation
15 */
16 void HMAC::add_data(const uint8_t input[], size_t length)
17  {
18  verify_key_set(m_ikey.empty() == false);
19  m_hash->update(input, length);
20  }
21 
22 /*
23 * Finalize a HMAC Calculation
24 */
25 void HMAC::final_result(uint8_t mac[])
26  {
27  verify_key_set(m_okey.empty() == false);
28  m_hash->final(mac);
29  m_hash->update(m_okey);
30  m_hash->update(mac, output_length());
31  m_hash->final(mac);
32  m_hash->update(m_ikey);
33  }
34 
36  {
37  // Support very long lengths for things like PBKDF2 and the TLS PRF
38  return Key_Length_Specification(0, 4096);
39  }
40 
41 /*
42 * HMAC Key Schedule
43 */
44 void HMAC::key_schedule(const uint8_t key[], size_t length)
45  {
46  m_hash->clear();
47 
48  m_ikey.resize(m_hash->hash_block_size());
49  m_okey.resize(m_hash->hash_block_size());
50 
51  const uint8_t ipad = 0x36;
52  const uint8_t opad = 0x5C;
53 
54  std::fill(m_ikey.begin(), m_ikey.end(), ipad);
55  std::fill(m_okey.begin(), m_okey.end(), opad);
56 
57  if(length > m_hash->hash_block_size())
58  {
59  secure_vector<uint8_t> hmac_key = m_hash->process(key, length);
60  xor_buf(m_ikey, hmac_key, hmac_key.size());
61  xor_buf(m_okey, hmac_key, hmac_key.size());
62  }
63  else
64  {
65  xor_buf(m_ikey, key, length);
66  xor_buf(m_okey, key, length);
67  }
68 
69  m_hash->update(m_ikey);
70  }
71 
72 /*
73 * Clear memory of sensitive data
74 */
76  {
77  m_hash->clear();
78  zap(m_ikey);
79  zap(m_okey);
80  }
81 
82 /*
83 * Return the name of this type
84 */
85 std::string HMAC::name() const
86  {
87  return "HMAC(" + m_hash->name() + ")";
88  }
89 
90 /*
91 * Return a clone of this object
92 */
94  {
95  return new HMAC(m_hash->clone());
96  }
97 
98 /*
99 * HMAC Constructor
100 */
102  {
103  BOTAN_ARG_CHECK(m_hash->hash_block_size() > 0,
104  "HMAC is not compatible with this hash function");
105  }
106 
107 }
Key_Length_Specification key_spec() const override
Definition: hmac.cpp:35
MessageAuthenticationCode * clone() const override
Definition: hmac.cpp:93
void verify_key_set(bool cond) const
Definition: sym_algo.h:89
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:193
size_t output_length() const override
Definition: hmac.h:26
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:174
Definition: alg_id.cpp:13
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:37
void clear() override
Definition: hmac.cpp:75
HMAC(HashFunction *hash)
Definition: hmac.cpp:101
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
std::string name() const override
Definition: hmac.cpp:85
MechanismType hash