Coverage Report

Created: 2020-02-14 15:38

/src/botan/src/lib/mac/hmac/hmac.cpp
Line
Count
Source (jump to first uncovered line)
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
229k
   {
18
229k
   verify_key_set(m_ikey.empty() == false);
19
229k
   m_hash->update(input, length);
20
229k
   }
21
22
/*
23
* Finalize a HMAC Calculation
24
*/
25
void HMAC::final_result(uint8_t mac[])
26
141k
   {
27
141k
   verify_key_set(m_okey.empty() == false);
28
141k
   m_hash->final(mac);
29
141k
   m_hash->update(m_okey);
30
141k
   m_hash->update(mac, m_hash_output_length);
31
141k
   m_hash->final(mac);
32
141k
   m_hash->update(m_ikey);
33
141k
   }
34
35
Key_Length_Specification HMAC::key_spec() const
36
39.5k
   {
37
39.5k
   // Support very long lengths for things like PBKDF2 and the TLS PRF
38
39.5k
   return Key_Length_Specification(0, 4096);
39
39.5k
   }
40
41
size_t HMAC::output_length() const
42
141k
   {
43
141k
   return m_hash_output_length;
44
141k
   }
45
46
/*
47
* HMAC Key Schedule
48
*/
49
void HMAC::key_schedule(const uint8_t key[], size_t length)
50
39.5k
   {
51
39.5k
   const uint8_t ipad = 0x36;
52
39.5k
   const uint8_t opad = 0x5C;
53
39.5k
54
39.5k
   m_hash->clear();
55
39.5k
56
39.5k
   m_ikey.resize(m_hash_block_size);
57
39.5k
   set_mem(m_ikey.data(), m_hash_block_size, ipad);
58
39.5k
59
39.5k
   m_okey.resize(m_hash_block_size);
60
39.5k
   set_mem(m_okey.data(), m_hash_block_size, opad);
61
39.5k
62
39.5k
   if(length > m_hash_block_size)
63
8.98k
      {
64
8.98k
      m_hash->update(key, length);
65
8.98k
      m_hash->final(m_ikey.data());
66
8.98k
67
8.98k
      xor_buf(m_okey.data(), m_ikey.data(), m_hash_output_length);
68
8.98k
69
344k
      for(size_t i = 0; i != m_hash_output_length; ++i)
70
335k
         {
71
335k
         m_ikey[i] ^= ipad;
72
335k
         }
73
8.98k
      }
74
30.5k
   else
75
30.5k
      {
76
30.5k
      xor_buf(m_ikey, key, length);
77
30.5k
      xor_buf(m_okey, key, length);
78
30.5k
      }
79
39.5k
80
39.5k
   m_hash->update(m_ikey);
81
39.5k
   }
82
83
/*
84
* Clear memory of sensitive data
85
*/
86
void HMAC::clear()
87
0
   {
88
0
   m_hash->clear();
89
0
   zap(m_ikey);
90
0
   zap(m_okey);
91
0
   }
92
93
/*
94
* Return the name of this type
95
*/
96
std::string HMAC::name() const
97
1.29k
   {
98
1.29k
   return "HMAC(" + m_hash->name() + ")";
99
1.29k
   }
100
101
/*
102
* Return a clone of this object
103
*/
104
MessageAuthenticationCode* HMAC::clone() const
105
0
   {
106
0
   return new HMAC(m_hash->clone());
107
0
   }
108
109
/*
110
* HMAC Constructor
111
*/
112
HMAC::HMAC(HashFunction* hash) :
113
   m_hash(hash),
114
   m_hash_output_length(m_hash->output_length()),
115
   m_hash_block_size(m_hash->hash_block_size())
116
24.6k
   {
117
24.6k
   BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length,
118
24.6k
                   "HMAC is not compatible with this hash function");
119
24.6k
   }
120
121
}