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
79
80
81
82
83
84
#![no_std]
extern crate generic_array;
extern crate digest;
extern crate crypto_mac;
pub use crypto_mac::{Mac, MacResult};
use digest::{Input, FixedOutput};
use generic_array::{ArrayLength, GenericArray};
const IPAD: u8 = 0x36;
const OPAD: u8 = 0x5c;
pub struct Hmac<D>
where D: Input + FixedOutput + Default,
<D as Input>::BlockSize: ArrayLength<u8>
{
digest: D,
key: GenericArray<u8, D::BlockSize>,
}
fn expand_key<D>(key: &[u8]) -> GenericArray<u8, D::BlockSize>
where D: Input + FixedOutput + Default,
<D as Input>::BlockSize: ArrayLength<u8>
{
let mut exp_key = GenericArray::default();
if key.len() <= exp_key.len() {
exp_key[..key.len()].copy_from_slice(key);
} else {
let mut digest = D::default();
digest.digest(key);
let output = digest.fixed_result();
exp_key[..output.len()].copy_from_slice(output.as_slice());
}
exp_key
}
impl <D> Hmac<D>
where D: Input + FixedOutput + Default,
<D as Input>::BlockSize: ArrayLength<u8>
{
fn derive_key(&self, mask: u8) -> GenericArray<u8, D::BlockSize> {
let mut key = self.key.clone();
for elem in key.iter_mut() {
*elem ^= mask;
}
key
}
}
impl <D> Mac for Hmac<D>
where D: Input + FixedOutput + Default,
<D as Input>::BlockSize: ArrayLength<u8>,
<D as FixedOutput>::OutputSize: ArrayLength<u8>
{
type OutputSize = D::OutputSize;
fn new(key: &[u8]) -> Hmac<D> {
let mut hmac = Hmac {
digest: D::default(),
key: expand_key::<D>(key),
};
let i_key_pad = hmac.derive_key(IPAD);
hmac.digest.digest(&i_key_pad);
hmac
}
fn input(&mut self, data: &[u8]) {
self.digest.digest(data);
}
fn result(self) -> MacResult<D::OutputSize> {
let o_key_pad = self.derive_key(OPAD);
let output = self.digest.fixed_result();
let mut digest = D::default();
digest.digest(&o_key_pad);
digest.digest(&output);
MacResult::new(digest.fixed_result())
}
}