-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhmac.cpp
More file actions
78 lines (67 loc) · 2.2 KB
/
hmac.cpp
File metadata and controls
78 lines (67 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <memory>
#include "hmac.hpp"
#include "util.hpp"
std::shared_ptr<fluks::Hmac_function>
fluks::Hmac_function::create(hash_type type) {
switch (type) {
case hash_type::MD5:
return std::shared_ptr<Hmac_function>(new Hmac_md5);
case hash_type::RMD160:
return std::shared_ptr<Hmac_function>(new Hmac_rmd160);
case hash_type::SHA1:
return std::shared_ptr<Hmac_function>(new Hmac_sha1);
case hash_type::SHA224:
return std::shared_ptr<Hmac_function>(new Hmac_sha224);
case hash_type::SHA256:
return std::shared_ptr<Hmac_function>(new Hmac_sha256);
case hash_type::SHA384:
return std::shared_ptr<Hmac_function>(new Hmac_sha384);
case hash_type::SHA512:
return std::shared_ptr<Hmac_function>(new Hmac_sha512);
default:
return std::shared_ptr<Hmac_function>(new Hmac_impl(
Hash_function::create(type)));
}
}
void
fluks::Hmac_impl::init(const uint8_t *key, size_t sz) {
size_t sz_block = traits()->block_size;
if (sz > sz_block) {
// key too long, so
// K := H(K)
_hashfn->init();
_hashfn->add(key, sz);
_hashfn->end(_key.get());
sz = traits()->digest_size;
} else {
std::copy(key, key + sz, _key.get());
}
if (sz < sz_block)
// (1) fill remainder with zeros
std::fill(_key.get() + sz, _key.get() + sz_block, 0);
// (2) XOR result of (1) with ipad
std::unique_ptr<uint8_t[]> key_ipad{new uint8_t[sz_block]};
xor_buf_byte(_key.get(), sz_block, IPAD, key_ipad.get());
// done below as well as successive calls to add():
// (3) append text to result of (2)
// (4) apply H to result of (3)
_hashfn->init();
_hashfn->add(key_ipad.get(), sz_block);
}
void
fluks::Hmac_impl::end(uint8_t *out) {
size_t sz_block = traits()->block_size;
std::unique_ptr<uint8_t[]> key_opad{new uint8_t[sz_block]};
std::unique_ptr<uint8_t[]> mid_digest{new uint8_t[traits()->digest_size]};
// (5) XOR result of (1) with opad
xor_buf_byte(_key.get(), sz_block, OPAD, key_opad.get());
// (6) append result of (4) to result of (5)
// (7) apply H to result of (6) and output result
// get H1 = H( K^ipad . data )
_hashfn->end(mid_digest.get());
_hashfn->init();
_hashfn->add(key_opad.get(), sz_block);
_hashfn->add(mid_digest.get(), traits()->digest_size);
// get H( K^opad . H1 )
_hashfn->end(out);
}