Merge from vendor branch GCC:
[dragonfly.git] / crypto / heimdal-0.6.3 / lib / otp / otp_md.c
1 /*
2  * Copyright (c) 1995 - 2003 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden).
4  * All rights reserved.
5  * 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 
17  * 3. Neither the name of the Institute nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 RCSID("$Id: otp_md.c,v 1.18 2003/04/16 16:19:33 lha Exp $");
37 #endif
38 #include "otp_locl.h"
39
40 #include "otp_md.h"
41 #include "crypto-headers.h"
42
43 /*
44  * Compress len bytes from md into key
45  */
46
47 static void
48 compressmd (OtpKey key, unsigned char *md, size_t len)
49 {
50   u_char *p = key;
51
52   memset (p, 0, OTPKEYSIZE);
53   while(len) {
54     *p++ ^= *md++;
55     *p++ ^= *md++;
56     *p++ ^= *md++;
57     *p++ ^= *md++;
58     len -= 4;
59     if (p == key + OTPKEYSIZE)
60       p = key;
61   }
62 }
63
64 #ifdef HAVE_OLD_HASH_NAMES
65 static void
66 otp_md4_final (void *res, struct md4 *m)
67 {
68     MD4_Final(res, m);
69 }
70 #undef MD4_Final
71 #define MD4_Final otp_md4_final
72
73 static void
74 otp_md5_final (void *res, struct md5 *m)
75 {
76     MD5_Final(res, m);
77 }
78 #undef MD5_Final
79 #define MD5_Final otp_md5_final
80 #endif
81
82 static int
83 otp_md_init (OtpKey key,
84              const char *pwd,
85              const char *seed,
86              void (*init)(void *),
87              void (*update)(void *, const void *, size_t),
88              void (*final)(void *, void *),
89              void *arg,
90              unsigned char *res,
91              size_t ressz)
92 {
93   char *p;
94   int len;
95
96   len = strlen(pwd) + strlen(seed);
97   p = malloc (len + 1);
98   if (p == NULL)
99     return -1;
100   strlcpy (p, seed, len + 1);
101   strlwr (p);
102   strlcat (p, pwd, len + 1);
103   (*init)(arg);
104   (*update)(arg, p, len);
105   (*final)(res, arg);
106   free (p);
107   compressmd (key, res, ressz);
108   return 0;
109 }
110
111 static int
112 otp_md_next (OtpKey key,
113              void (*init)(void *),
114              void (*update)(void *, const void *, size_t),
115              void (*final)(void *, void *),
116              void *arg,
117              unsigned char *res,
118              size_t ressz)
119 {
120   (*init)(arg);
121   (*update)(arg, key, OTPKEYSIZE);
122   (*final)(res, arg);
123   compressmd (key, res, ressz);
124   return 0;
125 }
126
127 static int
128 otp_md_hash (const char *data,
129              size_t len,
130              void (*init)(void *),
131              void (*update)(void *, const void *, size_t),
132              void (*final)(void *, void *),
133              void *arg,
134              unsigned char *res,
135              size_t ressz)
136 {
137   (*init)(arg);
138   (*update)(arg, data, len);
139   (*final)(res, arg);
140   return 0;
141 }
142
143 int
144 otp_md4_init (OtpKey key, const char *pwd, const char *seed)
145 {
146   unsigned char res[16];
147   MD4_CTX md4;
148
149   return otp_md_init (key, pwd, seed,
150                       (void (*)(void *))MD4_Init,
151                       (void (*)(void *, const void *, size_t))MD4_Update, 
152                       (void (*)(void *, void *))MD4_Final,
153                       &md4, res, sizeof(res));
154 }
155
156 int
157 otp_md4_hash (const char *data,
158               size_t len,
159               unsigned char *res)
160 {
161   MD4_CTX md4;
162
163   return otp_md_hash (data, len,
164                       (void (*)(void *))MD4_Init,
165                       (void (*)(void *, const void *, size_t))MD4_Update, 
166                       (void (*)(void *, void *))MD4_Final,
167                       &md4, res, 16);
168 }
169
170 int
171 otp_md4_next (OtpKey key)
172 {
173   unsigned char res[16];
174   MD4_CTX md4;
175
176   return otp_md_next (key, 
177                       (void (*)(void *))MD4_Init, 
178                       (void (*)(void *, const void *, size_t))MD4_Update, 
179                       (void (*)(void *, void *))MD4_Final,
180                       &md4, res, sizeof(res));
181 }
182
183
184 int
185 otp_md5_init (OtpKey key, const char *pwd, const char *seed)
186 {
187   unsigned char res[16];
188   MD5_CTX md5;
189
190   return otp_md_init (key, pwd, seed, 
191                       (void (*)(void *))MD5_Init, 
192                       (void (*)(void *, const void *, size_t))MD5_Update, 
193                       (void (*)(void *, void *))MD5_Final,
194                       &md5, res, sizeof(res));
195 }
196
197 int
198 otp_md5_hash (const char *data,
199               size_t len,
200               unsigned char *res)
201 {
202   MD5_CTX md5;
203
204   return otp_md_hash (data, len,
205                       (void (*)(void *))MD5_Init,
206                       (void (*)(void *, const void *, size_t))MD5_Update, 
207                       (void (*)(void *, void *))MD5_Final,
208                       &md5, res, 16);
209 }
210
211 int
212 otp_md5_next (OtpKey key)
213 {
214   unsigned char res[16];
215   MD5_CTX md5;
216
217   return otp_md_next (key, 
218                       (void (*)(void *))MD5_Init, 
219                       (void (*)(void *, const void *, size_t))MD5_Update, 
220                       (void (*)(void *, void *))MD5_Final,
221                       &md5, res, sizeof(res));
222 }
223
224 /* 
225  * For histerical reasons, in the OTP definition it's said that the
226  * result from SHA must be stored in little-endian order.  See
227  * draft-ietf-otp-01.txt.
228  */
229
230 static void
231 SHA1_Final_little_endian (void *res, SHA_CTX *m)
232 {
233   unsigned char tmp[20];
234   unsigned char *p = res;
235   int j;
236
237   SHA1_Final (tmp, m);
238   for (j = 0; j < 20; j += 4) {
239     p[j]   = tmp[j+3];
240     p[j+1] = tmp[j+2];
241     p[j+2] = tmp[j+1];
242     p[j+3] = tmp[j];
243   }
244 }
245
246 int
247 otp_sha_init (OtpKey key, const char *pwd, const char *seed)
248 {
249   unsigned char res[20];
250   SHA_CTX sha1;
251
252   return otp_md_init (key, pwd, seed, 
253                       (void (*)(void *))SHA1_Init, 
254                       (void (*)(void *, const void *, size_t))SHA1_Update, 
255                       (void (*)(void *, void *))SHA1_Final_little_endian,
256                       &sha1, res, sizeof(res));
257 }
258
259 int
260 otp_sha_hash (const char *data,
261               size_t len,
262               unsigned char *res)
263 {
264   SHA_CTX sha1;
265
266   return otp_md_hash (data, len,
267                       (void (*)(void *))SHA1_Init,
268                       (void (*)(void *, const void *, size_t))SHA1_Update, 
269                       (void (*)(void *, void *))SHA1_Final_little_endian,
270                       &sha1, res, 20);
271 }
272
273 int
274 otp_sha_next (OtpKey key)
275 {
276   unsigned char res[20];
277   SHA_CTX sha1;
278
279   return otp_md_next (key, 
280                       (void (*)(void *))SHA1_Init,
281                       (void (*)(void *, const void *, size_t))SHA1_Update,
282                       (void (*)(void *, void *))SHA1_Final_little_endian,
283                       &sha1, res, sizeof(res));
284 }