d9898ee8 |
1 | /* |
2 | ** Copyright 1998 - 1999 Double Precision, Inc. |
3 | ** See COPYING for distribution information. |
4 | */ |
5 | |
6 | #if HAVE_CONFIG_H |
7 | #include "config.h" |
8 | #endif |
9 | |
10 | #include "hmac.h" |
11 | |
d9898ee8 |
12 | |
13 | struct hmac_hashinfo *hmac_list[]= {HMAC_LIST}; |
14 | |
15 | struct hhki { |
16 | const struct hmac_hashinfo *hh; |
17 | const char *k; |
18 | size_t kl; |
19 | unsigned char *kxopad; |
20 | unsigned char *kxipad; |
21 | |
22 | void *context; |
23 | } ; |
24 | |
25 | static void dohashkey(unsigned char *, void *); |
26 | static void docalcc(void *, void *); |
27 | |
28 | void hmac_hashkey(const struct hmac_hashinfo *hh, const char *k, |
29 | size_t kl, unsigned char *kxopad, unsigned char *kxipad) |
30 | { |
31 | struct hhki i; |
32 | |
33 | i.hh=hh; |
34 | i.k=k; |
35 | i.kl=kl; |
36 | i.kxopad=kxopad; |
37 | i.kxipad=kxipad; |
38 | |
39 | (*hh->hh_allocacontext)( docalcc, (void *)&i ); |
40 | } |
41 | |
42 | static void dokeycalc(struct hhki *); |
43 | |
44 | static void docalcc(void *c, void *v) |
45 | { |
46 | struct hhki *i=(struct hhki *)v; |
47 | |
48 | i->context=c; |
49 | |
50 | if (i->kl > i->hh->hh_B) |
51 | (*i->hh->hh_allocaval)(dohashkey, (void *)i); |
52 | else |
53 | dokeycalc( i ); |
54 | } |
55 | |
56 | static void dohashkey(unsigned char *keybuf, void *v) |
57 | { |
58 | struct hhki *i=(struct hhki *)v; |
59 | |
60 | (*i->hh->hh_init)(i->context); |
61 | (*i->hh->hh_hash)(i->context, i->k, i->kl); |
62 | (*i->hh->hh_endhash)(i->context, i->kl); |
63 | (*i->hh->hh_getdigest)(i->context, keybuf); |
64 | i->k=(char *)keybuf; |
65 | i->kl=i->hh->hh_L; |
66 | dokeycalc(i); |
67 | } |
68 | |
69 | static void dokeycalc(struct hhki *i) |
70 | { |
71 | char buf[64]; /* Random guess :-) */ |
72 | unsigned n; |
73 | unsigned l; |
74 | |
75 | (*i->hh->hh_init)(i->context); |
76 | n=0; |
77 | for (l=0; l<i->hh->hh_B; l++) |
78 | { |
79 | buf[n] = ( l < i->kl ? i->k[l]:0) ^ 0x5C; |
80 | if ( ++n >= sizeof(buf)) |
81 | { |
82 | (*i->hh->hh_hash)(i->context, buf, sizeof(buf)); |
83 | n=0; |
84 | } |
85 | } |
86 | if (n) |
87 | (*i->hh->hh_hash)(i->context, buf, n); |
88 | (*i->hh->hh_getdigest)(i->context, i->kxopad); |
89 | |
90 | (*i->hh->hh_init)(i->context); |
91 | n=0; |
92 | for (l=0; l<i->hh->hh_B; l++) |
93 | { |
94 | buf[n] = ( l < i->kl ? i->k[l]:0) ^ 0x36; |
95 | if ( ++n >= sizeof(buf)) |
96 | { |
97 | (*i->hh->hh_hash)(i->context, buf, sizeof(buf)); |
98 | n=0; |
99 | } |
100 | } |
101 | if (n) |
102 | (*i->hh->hh_hash)(i->context, buf, n); |
103 | (*i->hh->hh_getdigest)(i->context, i->kxipad); |
104 | } |
105 | |
106 | struct hhko { |
107 | const struct hmac_hashinfo *hh; |
108 | const char *t; |
109 | size_t tl; |
110 | const unsigned char *kxopad; |
111 | const unsigned char *kxipad; |
112 | unsigned char *hash; |
113 | } ; |
114 | |
115 | static void docalch(void *, void *); |
116 | |
117 | void hmac_hashtext ( |
118 | const struct hmac_hashinfo *hh, |
119 | const char *t, |
120 | size_t tl, |
121 | const unsigned char *kxopad, |
122 | const unsigned char *kxipad, |
123 | unsigned char *hash) |
124 | { |
125 | struct hhko o; |
126 | |
127 | o.hh=hh; |
128 | o.t=t; |
129 | o.tl=tl; |
130 | o.kxopad=kxopad; |
131 | o.kxipad=kxipad; |
132 | o.hash=hash; |
133 | |
134 | (*hh->hh_allocacontext)( docalch, (void *)&o ); |
135 | } |
136 | |
137 | static void docalch(void *c, void *v) |
138 | { |
139 | struct hhko *o=(struct hhko *)v; |
140 | |
141 | (o->hh->hh_setdigest)(c, o->kxipad); |
142 | (o->hh->hh_hash)(c, o->t, o->tl); |
143 | (o->hh->hh_endhash)(c, o->tl+o->hh->hh_B); |
144 | (o->hh->hh_getdigest)(c, o->hash); |
145 | |
146 | (o->hh->hh_setdigest)(c, o->kxopad); |
147 | (o->hh->hh_hash)(c, o->hash, o->hh->hh_L); |
148 | (o->hh->hh_endhash)(c, o->hh->hh_L + o->hh->hh_B); |
149 | (o->hh->hh_getdigest)(c, o->hash); |
150 | } |