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
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
int
libsha2_hmac_init(struct libsha2_hmac_state *restrict state, enum libsha2_algorithm algorithm,
const void *restrict key_, size_t keylen)
{
const unsigned char *restrict key = key_;
size_t i;
state->sha2_state.algorithm = algorithm;
state->outsize = libsha2_algorithm_output_size(algorithm) * 8;
if (!state->outsize) {
errno = EINVAL;
return -1;
}
state->inited = 0;
if (keylen <= (algorithm <= LIBSHA2_256 ? 64 * 8 : 128 * 8)) {
memset(state->ipad, 0x36, sizeof(state->ipad));
memset(state->opad, 0x5C, sizeof(state->opad));
for (i = 0; i < keylen / 8; i++) {
state->ipad[i] ^= key[i];
state->opad[i] ^= key[i];
}
if (keylen & 7) {
state->ipad[i] ^= (unsigned char)(key[i] << (8 - (keylen & 7)));
state->opad[i] ^= (unsigned char)(key[i] << (8 - (keylen & 7)));
}
} else {
memset(state->ipad, 0, sizeof(state->ipad));
if (libsha2_init(&state->sha2_state, algorithm))
return -1;
libsha2_digest(&state->sha2_state, key, keylen, state->ipad);
memcpy(state->opad, state->ipad, sizeof(state->ipad));
for (i = 0; i < sizeof(state->ipad); i++) {
state->ipad[i] ^= 0x36;
state->opad[i] ^= 0x5C;
}
}
return 0;
}
|