MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hmac.hpp
1 /*
2  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to the
15  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16  MA 02110-1301 USA.
17 */
18 
19 /* hamc.hpp implements HMAC, see RFC 2104
20 */
21 
22 
23 #ifndef TAO_CRYPT_HMAC_HPP
24 #define TAO_CRYPT_HMAC_HPP
25 
26 #include "hash.hpp"
27 
28 namespace TaoCrypt {
29 
30 
31 // HMAC class template
32 template <class T>
33 class HMAC {
34 public:
35  enum { IPAD = 0x36, OPAD = 0x5C };
36 
37  HMAC() : ipad_(reinterpret_cast<byte*>(&ip_)),
38  opad_(reinterpret_cast<byte*>(&op_)),
39  innerHash_(reinterpret_cast<byte*>(&innerH_))
40  {
41  Init();
42  }
43  void Update(const byte*, word32);
44  void Final(byte*);
45  void Init();
46 
47  void SetKey(const byte*, word32);
48 private:
49  byte* ipad_;
50  byte* opad_;
51  byte* innerHash_;
52  bool innerHashKeyed_;
53  T mac_;
54 
55  // MSVC 6 HACK, gives compiler error if calculated in array
56  enum { HMAC_BSIZE = T::BLOCK_SIZE / sizeof(word32),
57  HMAC_DSIZE = T::DIGEST_SIZE / sizeof(word32) };
58 
59  word32 ip_[HMAC_BSIZE]; // align ipad_ on word32
60  word32 op_[HMAC_BSIZE]; // align opad_ on word32
61  word32 innerH_[HMAC_DSIZE]; // align innerHash_ on word32
62 
63  void KeyInnerHash();
64 
65  HMAC(const HMAC&);
66  HMAC& operator= (const HMAC&);
67 };
68 
69 
70 // Setup
71 template <class T>
72 void HMAC<T>::Init()
73 {
74  mac_.Init();
75  innerHashKeyed_ = false;
76 }
77 
78 
79 // Key generation
80 template <class T>
81 void HMAC<T>::SetKey(const byte* key, word32 length)
82 {
83  Init();
84 
85  if (length <= T::BLOCK_SIZE)
86  memcpy(ipad_, key, length);
87  else {
88  mac_.Update(key, length);
89  mac_.Final(ipad_);
90  length = T::DIGEST_SIZE;
91  }
92  memset(ipad_ + length, 0, T::BLOCK_SIZE - length);
93 
94  for (word32 i = 0; i < T::BLOCK_SIZE; i++) {
95  opad_[i] = ipad_[i] ^ OPAD;
96  ipad_[i] ^= IPAD;
97  }
98 }
99 
100 
101 // Inner Key Hash
102 template <class T>
103 void HMAC<T>::KeyInnerHash()
104 {
105  mac_.Update(ipad_, T::BLOCK_SIZE);
106  innerHashKeyed_ = true;
107 }
108 
109 
110 // Update
111 template <class T>
112 void HMAC<T>::Update(const byte* msg, word32 length)
113 {
114  if (!innerHashKeyed_)
115  KeyInnerHash();
116  mac_.Update(msg, length);
117 }
118 
119 
120 // Final
121 template <class T>
122 void HMAC<T>::Final(byte* hash)
123 {
124  if (!innerHashKeyed_)
125  KeyInnerHash();
126  mac_.Final(innerHash_);
127 
128  mac_.Update(opad_, T::BLOCK_SIZE);
129  mac_.Update(innerHash_, T::DIGEST_SIZE);
130  mac_.Final(hash);
131 
132  innerHashKeyed_ = false;
133 }
134 
135 
136 } // namespace
137 
138 #endif // TAO_CRYPT_HMAC_HPP