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
|
/* This file is part of Eclat
Copyright (C) 2012 Sergey Poznyakoff
Eclat is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Eclat is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Eclat. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include "libeclat.h"
#include "sha1.h"
#include <string.h>
#define IPAD 0x36
#define OPAD 0x5c
void
hmac_sha1(const void *text, size_t textlen,
const void *key, size_t keylen,
void *digest)
{
size_t i;
struct sha1_ctx ctx;
char innerhash[20];
char keybuf[20];
unsigned char ipad[64]; /* inner padding - key ^ ipad[64] */
unsigned char opad[64]; /* outer padding - key ^ opad[64] */
unsigned char *kp = (unsigned char *)key;
/* if key is longer than 64 bytes reset it to key=SHA1(key) */
if (keylen > 64) {
struct sha1_ctx keyhash;
sha1_init_ctx(&keyhash);
sha1_process_bytes(key, keylen, &keyhash);
sha1_finish_ctx(&keyhash, keybuf);
key = keybuf;
keylen = sizeof(keybuf);
}
/* Compute SHA1(K XOR opad, SHA1(K XOR ipad, text)),
where
K is an key, padded to 64 bytes with zeros,
ipad and opad are the respective defines above repeated 64 times
text is the text argument (textlen bytes long)
*/
memset(ipad, IPAD, sizeof(ipad));
memset(opad, OPAD, sizeof(opad));
for (i = 0; i < keylen; i++, kp++) {
ipad[i] ^= *kp;
opad[i] ^= *kp;
}
/* Compute inner hash */
sha1_init_ctx(&ctx);
sha1_process_block(ipad, sizeof(ipad), &ctx);
sha1_process_bytes(text, textlen, &ctx);
sha1_finish_ctx(&ctx, innerhash);
/* Compute outer hash */
sha1_init_ctx(&ctx);
sha1_process_block(opad, sizeof(opad), &ctx);
sha1_process_bytes(innerhash, sizeof(innerhash), &ctx);
sha1_finish_ctx(&ctx, digest);
}
|