Coverage Report

Created: 2020-03-26 13:53

/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
226k
   {
18
226k
   verify_key_set(m_ikey.empty() == false);
19
226k
   m_hash->update(input, length);
20
226k
   }
21
22
/*
23
* Finalize a HMAC Calculation
24
*/
25
void HMAC::final_result(uint8_t mac[])
26
139k
   {
27
139k
   verify_key_set(m_okey.empty() == false);
28
139k
   m_hash->final(mac);
29
139k
   m_hash->update(m_okey);
30
139k
   m_hash->update(mac, m_hash_output_length);
31
139k
   m_hash->final(mac);
32
139k
   m_hash->update(m_ikey);
33
139k
   }
34
35
Key_Length_Specification HMAC::key_spec() const
36
39.0k
   {
37
39.0k
   // Support very long lengths for things like PBKDF2 and the TLS PRF
38
39.0k
   return Key_Length_Specification(0, 4096);
39
39.0k
   }
40
41
size_t HMAC::output_length() const
42
139k
   {
43
139k
   return m_hash_output_length;
44
139k
   }
45
46
/*
47
* HMAC Key Schedule
48
*/
49
void HMAC::key_schedule(const uint8_t key[], size_t length)
50
39.0k
   {
51
39.0k
   const uint8_t ipad = 0x36;
52
39.0k
   const uint8_t opad = 0x5C;
53
39.0k
54
39.0k
   m_hash->clear();
55
39.0k
56
39.0k
   m_ikey.resize(m_hash_block_size);
57
39.0k
   set_mem(m_ikey.data(), m_hash_block_size, ipad);
58
39.0k
59
39.0k
   m_okey.resize(m_hash_block_size);
60
39.0k
   set_mem(m_okey.data(), m_hash_block_size, opad);
61
39.0k
62
39.0k
   if(length > m_hash_block_size)
63
9.01k
      {
64
9.01k
      m_hash->update(key, length);
65
9.01k
      m_hash->final(m_ikey.data());
66
9.01k
67
9.01k
      xor_buf(m_okey.data(), m_ikey.data(), m_hash_output_length);
68
9.01k
69
349k
      for(size_t i = 0; i != m_hash_output_length; ++i)
70
340k
         {
71
340k
         m_ikey[i] ^= ipad;
72
340k
         }
73
9.01k
      }
74
30.0k
   else
75
30.0k
      {
76
30.0k
      xor_buf(m_ikey, key, length);
77
30.0k
      xor_buf(m_okey, key, length);
78
30.0k
      }
79
39.0k
80
39.0k
   m_hash->update(m_ikey);
81
39.0k
   }
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.33k
   {
98
1.33k
   return "HMAC(" + m_hash->name() + ")";
99
1.33k
   }
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.5k
   {
117
24.5k
   BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length,
118
24.5k
                   "HMAC is not compatible with this hash function");
119
24.5k
   }
120
121
}