Coverage Report

Created: 2020-05-23 13:54

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