forked from hacspec/hacspec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hmac.rs
48 lines (41 loc) · 2 KB
/
hmac.rs
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
use hacspec_lib::*;
use hacspec_sha256::*;
// HASH_SIZE and K_SIZE are defined in the sha256 crate.
const BLOCK_LEN: usize = K_SIZE;
bytes!(PRK, HASH_SIZE);
bytes!(Block, BLOCK_LEN);
const I_PAD: Block = Block(secret_bytes!([
0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8,
0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8,
0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8,
0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8,
0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8, 0x36u8,
0x36u8, 0x36u8, 0x36u8, 0x36u8
]));
const O_PAD: Block = Block(secret_bytes!([
0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8,
0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8,
0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8,
0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8,
0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8,
0x5cu8, 0x5cu8, 0x5cu8, 0x5cu8
]));
fn k_block(k: &ByteSeq) -> Block {
if k.len() > BLOCK_LEN {
Block::new().update_start(&hash(k))
} else {
Block::new().update_start(k)
}
}
// H(K XOR opad, H(K XOR ipad, text))
pub fn hmac(k: &ByteSeq, txt: &ByteSeq) -> PRK {
// Applications that use keys longer than B bytes will first hash the key
// using H and then use the resultant L byte string as the actual key to HMAC
let k_block = k_block(k);
let mut h_in = ByteSeq::from_seq(&(k_block ^ I_PAD));
h_in = h_in.concat(txt);
let h_inner = hash(&h_in);
let mut h_in = ByteSeq::from_seq(&(k_block ^ O_PAD));
h_in = h_in.concat(&h_inner);
PRK::from_seq(&hash(&h_in))
}