]> jfr.im git - irc/quakenet/newserv.git/blob - lib/hmac.c
Whoops, missed off null terminator.
[irc/quakenet/newserv.git] / lib / hmac.c
1 #include "hmac.h"
2 #include <string.h>
3
4 void hmacsha256_init(hmacsha256 *c, unsigned char *key, int keylen) {
5 unsigned char realkey[64], outerkey[64], innerkey[64];
6 SHA256_CTX keyc;
7 int i;
8
9 memset(realkey, 0, sizeof(realkey));
10 if(keylen > 64) {
11 SHA256_Init(&keyc);
12 SHA256_Update(&keyc, key, keylen);
13 SHA256_Final(realkey, &keyc);
14 keylen = 32;
15 } else {
16 memcpy(realkey, key, keylen);
17 }
18
19 /* abusing the cache here, if we do sha256 in between that'll erase it */
20 for(i=0;i<64;i++) {
21 int r = realkey[i];
22 innerkey[i] = r ^ 0x36;
23 outerkey[i] = r ^ 0x5c;
24 }
25
26 SHA256_Init(&c->outer);
27 SHA256_Init(&c->inner);
28 SHA256_Update(&c->outer, outerkey, 64);
29 SHA256_Update(&c->inner, innerkey, 64);
30 }
31
32 void hmacsha256_update(hmacsha256 *c, unsigned char *message, int messagelen) {
33 SHA256_Update(&c->inner, message, messagelen);
34 }
35
36 void hmacsha256_final(hmacsha256 *c, unsigned char *digest) {
37 SHA256_Final(digest, &c->inner);
38 SHA256_Update(&c->outer, digest, 32);
39 SHA256_Final(digest, &c->outer);
40 }
41
42 void hmacsha1_init(hmacsha1 *c, unsigned char *key, int keylen) {
43 unsigned char realkey[64], outerkey[64], innerkey[64];
44 SHA1_CTX keyc;
45 int i;
46
47 memset(realkey, 0, sizeof(realkey));
48 if(keylen > 64) {
49 SHA1Init(&keyc);
50 SHA1Update(&keyc, key, keylen);
51 SHA1Final(realkey, &keyc);
52 keylen = 20;
53 } else {
54 memcpy(realkey, key, keylen);
55 }
56
57 /* abusing the cache here, if we do sha1 in between that'll erase it */
58 for(i=0;i<64;i++) {
59 int r = realkey[i];
60 innerkey[i] = r ^ 0x36;
61 outerkey[i] = r ^ 0x5c;
62 }
63
64 SHA1Init(&c->outer);
65 SHA1Init(&c->inner);
66 SHA1Update(&c->outer, outerkey, 64);
67 SHA1Update(&c->inner, innerkey, 64);
68 }
69
70 void hmacsha1_update(hmacsha1 *c, unsigned char *message, int messagelen) {
71 SHA1Update(&c->inner, message, messagelen);
72 }
73
74 void hmacsha1_final(hmacsha1 *c, unsigned char *digest) {
75 SHA1Final(digest, &c->inner);
76 SHA1Update(&c->outer, digest, 20);
77 SHA1Final(digest, &c->outer);
78 }
79
80 static const char *hexdigits = "0123456789abcdef";
81
82 char *hmac_printhex(unsigned char *data, char *out, size_t len) {
83 size_t i;
84 char *o = out;
85
86 for(i=0;i<len;i++) {
87 *o++ = hexdigits[(*data & 0xf0) >> 4];
88 *o++ = hexdigits[*data & 0x0f];
89 data++;
90 }
91
92 *o = '\0';
93 return out;
94 }