Botan  2.13.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, m_hash_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 size_t HMAC::output_length() const
42  {
43  return m_hash_output_length;
44  }
45 
46 /*
47 * HMAC Key Schedule
48 */
49 void HMAC::key_schedule(const uint8_t key[], size_t length)
50  {
51  const uint8_t ipad = 0x36;
52  const uint8_t opad = 0x5C;
53 
54  m_hash->clear();
55 
56  m_ikey.resize(m_hash_block_size);
57  set_mem(m_ikey.data(), m_hash_block_size, ipad);
58 
59  m_okey.resize(m_hash_block_size);
60  set_mem(m_okey.data(), m_hash_block_size, opad);
61 
62  if(length > m_hash_block_size)
63  {
64  m_hash->update(key, length);
65  m_hash->final(m_ikey.data());
66 
67  xor_buf(m_okey.data(), m_ikey.data(), m_hash_output_length);
68 
69  for(size_t i = 0; i != m_hash_output_length; ++i)
70  {
71  m_ikey[i] ^= ipad;
72  }
73  }
74  else
75  {
76  xor_buf(m_ikey, key, length);
77  xor_buf(m_okey, key, length);
78  }
79 
80  m_hash->update(m_ikey);
81  }
82 
83 /*
84 * Clear memory of sensitive data
85 */
87  {
88  m_hash->clear();
89  zap(m_ikey);
90  zap(m_okey);
91  }
92 
93 /*
94 * Return the name of this type
95 */
96 std::string HMAC::name() const
97  {
98  return "HMAC(" + m_hash->name() + ")";
99  }
100 
101 /*
102 * Return a clone of this object
103 */
105  {
106  return new HMAC(m_hash->clone());
107  }
108 
109 /*
110 * HMAC Constructor
111 */
113  m_hash(hash),
114  m_hash_output_length(m_hash->output_length()),
115  m_hash_block_size(m_hash->hash_block_size())
116  {
117  BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length,
118  "HMAC is not compatible with this hash function");
119  }
120 
121 }
Key_Length_Specification key_spec() const override
Definition: hmac.cpp:35
MessageAuthenticationCode * clone() const override
Definition: hmac.cpp:104
void zap(std::vector< T, Alloc > &vec)
Definition: secmem.h:170
void set_mem(uint8_t *ptr, size_t n, uint8_t val)
Definition: mem_ops.h:181
size_t output_length() const override
Definition: hmac.cpp:41
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:232
Definition: alg_id.cpp:13
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:37
void verify_key_set(bool cond) const
Definition: sym_algo.h:89
void clear() override
Definition: hmac.cpp:86
HMAC(HashFunction *hash)
Definition: hmac.cpp:112
std::string name() const override
Definition: hmac.cpp:96
std::unique_ptr< HashFunction > m_hash
Definition: tpm.cpp:446
MechanismType hash