-
Notifications
You must be signed in to change notification settings - Fork 1
/
hmac.c
64 lines (49 loc) · 1.48 KB
/
hmac.c
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
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "utils.h"
#include "hmac.h"
void hmac_init(struct hmac_state *hmac,
const uint8_t *key, size_t key_len)
{
memset(&hmac->key_exp, 0, SHA256_BLOCK_SIZE);
if (key_len <= SHA256_BLOCK_SIZE)
memcpy(hmac->key_exp, key, key_len);
else
sha256(hmac->key_exp, key, key_len);
uint8_t key_pad[SHA256_BLOCK_SIZE];
for (size_t i = 0; i < SHA256_BLOCK_SIZE; i++)
key_pad[i] = hmac->key_exp[i] ^ 0x36;
sha256_init(&hmac->md);
sha256_process(&hmac->md, key_pad, sizeof(key_pad));
wipe_sized(key_pad);
}
void hmac_process(struct hmac_state *hmac,
const uint8_t *data, size_t data_len)
{
sha256_process(&hmac->md, data, data_len);
}
void hmac_finish(struct hmac_state *hmac, uint8_t *hmac_out)
{
uint8_t hash_inner[SHA256_SIZE];
sha256_finish(&hmac->md, hash_inner);
uint8_t key_pad[SHA256_BLOCK_SIZE];
for (size_t i = 0; i < SHA256_BLOCK_SIZE; i++)
key_pad[i] = hmac->key_exp[i] ^ 0x5c;
sha256_init(&hmac->md);
sha256_process(&hmac->md, key_pad, sizeof(key_pad));
sha256_process(&hmac->md, hash_inner, sizeof(hash_inner));
sha256_finish(&hmac->md, hmac_out);
wipe_sized(hash_inner);
wipe_sized(key_pad);
wipe_ref(hmac);
}
void hmac(uint8_t *hmac_out,
const uint8_t *key, size_t key_len,
const uint8_t *data, size_t data_len)
{
struct hmac_state hmac;
hmac_init(&hmac, key, key_len);
hmac_process(&hmac, data, data_len);
hmac_finish(&hmac, hmac_out); // wipes &hmac
}