]> jfr.im git - irc/quakenet/newserv.git/blob - lib/hmac.c
A4STATS: remove E style escapes and switch to createtable for indices
[irc/quakenet/newserv.git] / lib / hmac.c
1 #include "hmac.h"
2 #include <string.h>
3 #include <ctype.h>
4
5 void hmacsha256_init(hmacsha256 *c, unsigned char *key, int keylen) {
6 unsigned char realkey[64], outerkey[64], innerkey[64];
7 SHA256_CTX keyc;
8 int i;
9
10 memset(realkey, 0, sizeof(realkey));
11 if(keylen > 64) {
12 SHA256_Init(&keyc);
13 SHA256_Update(&keyc, key, keylen);
14 SHA256_Final(realkey, &keyc);
15 keylen = 32;
16 } else {
17 memcpy(realkey, key, keylen);
18 }
19
20 /* abusing the cache here, if we do sha256 in between that'll erase it */
21 for(i=0;i<64;i++) {
22 int r = realkey[i];
23 innerkey[i] = r ^ 0x36;
24 outerkey[i] = r ^ 0x5c;
25 }
26
27 SHA256_Init(&c->outer);
28 SHA256_Init(&c->inner);
29 SHA256_Update(&c->outer, outerkey, 64);
30 SHA256_Update(&c->inner, innerkey, 64);
31 }
32
33 void hmacsha256_update(hmacsha256 *c, unsigned char *message, int messagelen) {
34 SHA256_Update(&c->inner, message, messagelen);
35 }
36
37 void hmacsha256_final(hmacsha256 *c, unsigned char *digest) {
38 SHA256_Final(digest, &c->inner);
39 SHA256_Update(&c->outer, digest, 32);
40 SHA256_Final(digest, &c->outer);
41 }
42
43 void hmacsha1_init(hmacsha1 *c, unsigned char *key, int keylen) {
44 unsigned char realkey[64], outerkey[64], innerkey[64];
45 SHA1_CTX keyc;
46 int i;
47
48 memset(realkey, 0, sizeof(realkey));
49 if(keylen > 64) {
50 SHA1Init(&keyc);
51 SHA1Update(&keyc, key, keylen);
52 SHA1Final(realkey, &keyc);
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 void hmacmd5_init(hmacmd5 *c, unsigned char *key, int keylen) {
81 unsigned char realkey[64], outerkey[64], innerkey[64];
82 MD5Context keyc;
83 int i;
84
85 memset(realkey, 0, sizeof(realkey));
86 if(keylen > 64) {
87 MD5Init(&keyc);
88 MD5Update(&keyc, key, keylen);
89 MD5Final(realkey, &keyc);
90 } else {
91 memcpy(realkey, key, keylen);
92 }
93
94 /* abusing the cache here, if we do sha1 in between that'll erase it */
95 for(i=0;i<64;i++) {
96 int r = realkey[i];
97 innerkey[i] = r ^ 0x36;
98 outerkey[i] = r ^ 0x5c;
99 }
100
101 MD5Init(&c->outer);
102 MD5Init(&c->inner);
103 MD5Update(&c->outer, outerkey, 64);
104 MD5Update(&c->inner, innerkey, 64);
105 }
106
107 void hmacmd5_update(hmacmd5 *c, unsigned char *message, int messagelen) {
108 MD5Update(&c->inner, message, messagelen);
109 }
110
111 void hmacmd5_final(hmacmd5 *c, unsigned char *digest) {
112 MD5Final(digest, &c->inner);
113 MD5Update(&c->outer, digest, 16);
114 MD5Final(digest, &c->outer);
115 }
116
117 static const char *hexdigits = "0123456789abcdef";
118
119 char *hmac_printhex(unsigned char *data, char *out, size_t len) {
120 size_t i;
121 unsigned char *o = (unsigned char *)out;
122
123 for(i=0;i<len;i++) {
124 *o++ = hexdigits[(*data & 0xf0) >> 4];
125 *o++ = hexdigits[*data & 0x0f];
126 data++;
127 }
128
129 *o = '\0';
130 return out;
131 }
132
133 int hmac_strcmp(const char *a, const char *b) {
134 int result = 1;
135
136 if(!a || !b)
137 return 1;
138
139 if(strlen(a) != strlen(b))
140 return 1;
141
142 while(*a)
143 result&=(tolower(*a++) == tolower(*b++));
144
145 return !result;
146 }
147