]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/heimdal/lib/otp/otp_md.c
import of heimdal 0.3f
[FreeBSD/FreeBSD.git] / crypto / heimdal / lib / otp / otp_md.c
1 /*
2  * Copyright (c) 1995 - 2001 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.14 2001/01/29 05:55:18 assar Exp $");
37 #endif
38 #include "otp_locl.h"
39
40 #include "otp_md.h"
41 #ifdef HAVE_OPENSSL_MD4_H
42 #include <openssl/md4.h>
43 #else
44 #include <md4.h>
45 #endif
46 #ifdef HAVE_OPENSSL_MD5_H
47 #include <openssl/md5.h>
48 #else
49 #include <md5.h>
50 #endif
51 #ifdef HAVE_OPENSSL_SHA_H
52 #include <openssl/sha.h>
53 #else
54 #include <sha.h>
55 #endif
56
57 /*
58  * Compress len bytes from md into key
59  */
60
61 static void
62 compressmd (OtpKey key, unsigned char *md, size_t len)
63 {
64   u_char *p = key;
65
66   memset (p, 0, OTPKEYSIZE);
67   while(len) {
68     *p++ ^= *md++;
69     *p++ ^= *md++;
70     *p++ ^= *md++;
71     *p++ ^= *md++;
72     len -= 4;
73     if (p == key + OTPKEYSIZE)
74       p = key;
75   }
76 }
77
78 static int
79 otp_md_init (OtpKey key,
80              const char *pwd,
81              const char *seed,
82              void (*init)(void *),
83              void (*update)(void *, const void *, size_t),
84              void (*final)(void *, void *),
85              void *arg,
86              unsigned char *res,
87              size_t ressz)
88 {
89   char *p;
90   int len;
91
92   len = strlen(pwd) + strlen(seed);
93   p = malloc (len + 1);
94   if (p == NULL)
95     return -1;
96   strcpy (p, seed);
97   strlwr (p);
98   strcat (p, pwd);
99   (*init)(arg);
100   (*update)(arg, p, len);
101   (*final)(res, arg);
102   free (p);
103   compressmd (key, res, ressz);
104   return 0;
105 }
106
107 static int
108 otp_md_next (OtpKey key,
109              void (*init)(void *),
110              void (*update)(void *, const void *, size_t),
111              void (*final)(void *, void *),
112              void *arg,
113              unsigned char *res,
114              size_t ressz)
115 {
116   (*init)(arg);
117   (*update)(arg, key, OTPKEYSIZE);
118   (*final)(res, arg);
119   compressmd (key, res, ressz);
120   return 0;
121 }
122
123 static int
124 otp_md_hash (const char *data,
125              size_t len,
126              void (*init)(void *),
127              void (*update)(void *, const void *, size_t),
128              void (*final)(void *, void *),
129              void *arg,
130              unsigned char *res,
131              size_t ressz)
132 {
133   (*init)(arg);
134   (*update)(arg, data, len);
135   (*final)(res, arg);
136   return 0;
137 }
138
139 int
140 otp_md4_init (OtpKey key, const char *pwd, const char *seed)
141 {
142   unsigned char res[16];
143   MD4_CTX md4;
144
145   return otp_md_init (key, pwd, seed,
146                       (void (*)(void *))MD4_Init,
147                       (void (*)(void *, const void *, size_t))MD4_Update, 
148                       (void (*)(void *, void *))MD4_Final,
149                       &md4, res, sizeof(res));
150 }
151
152 int
153 otp_md4_hash (const char *data,
154               size_t len,
155               unsigned char *res)
156 {
157   MD4_CTX md4;
158
159   return otp_md_hash (data, len,
160                       (void (*)(void *))MD4_Init,
161                       (void (*)(void *, const void *, size_t))MD4_Update, 
162                       (void (*)(void *, void *))MD4_Final,
163                       &md4, res, 16);
164 }
165
166 int
167 otp_md4_next (OtpKey key)
168 {
169   unsigned char res[16];
170   MD4_CTX md4;
171
172   return otp_md_next (key, 
173                       (void (*)(void *))MD4_Init, 
174                       (void (*)(void *, const void *, size_t))MD4_Update, 
175                       (void (*)(void *, void *))MD4_Final,
176                       &md4, res, sizeof(res));
177 }
178
179
180 int
181 otp_md5_init (OtpKey key, const char *pwd, const char *seed)
182 {
183   unsigned char res[16];
184   MD5_CTX md5;
185
186   return otp_md_init (key, pwd, seed, 
187                       (void (*)(void *))MD5_Init, 
188                       (void (*)(void *, const void *, size_t))MD5_Update, 
189                       (void (*)(void *, void *))MD5_Final,
190                       &md5, res, sizeof(res));
191 }
192
193 int
194 otp_md5_hash (const char *data,
195               size_t len,
196               unsigned char *res)
197 {
198   MD5_CTX md5;
199
200   return otp_md_hash (data, len,
201                       (void (*)(void *))MD5_Init,
202                       (void (*)(void *, const void *, size_t))MD5_Update, 
203                       (void (*)(void *, void *))MD5_Final,
204                       &md5, res, 16);
205 }
206
207 int
208 otp_md5_next (OtpKey key)
209 {
210   unsigned char res[16];
211   MD5_CTX md5;
212
213   return otp_md_next (key, 
214                       (void (*)(void *))MD5_Init, 
215                       (void (*)(void *, const void *, size_t))MD5_Update, 
216                       (void (*)(void *, void *))MD5_Final,
217                       &md5, res, sizeof(res));
218 }
219
220 /* 
221  * For histerical reasons, in the OTP definition it's said that the
222  * result from SHA must be stored in little-endian order.  See
223  * draft-ietf-otp-01.txt.
224  */
225
226 static void
227 SHA1_Final_little_endian (void *res, SHA_CTX *m)
228 {
229   unsigned char tmp[20];
230   unsigned char *p = res;
231   int j;
232
233   SHA1_Final (tmp, m);
234   for (j = 0; j < 20; j += 4) {
235     p[j]   = tmp[j+3];
236     p[j+1] = tmp[j+2];
237     p[j+2] = tmp[j+1];
238     p[j+3] = tmp[j];
239   }
240 }
241
242 int
243 otp_sha_init (OtpKey key, const char *pwd, const char *seed)
244 {
245   unsigned char res[20];
246   SHA_CTX sha1;
247
248   return otp_md_init (key, pwd, seed, 
249                       (void (*)(void *))SHA1_Init, 
250                       (void (*)(void *, const void *, size_t))SHA1_Update, 
251                       (void (*)(void *, void *))SHA1_Final_little_endian,
252                       &sha1, res, sizeof(res));
253 }
254
255 int
256 otp_sha_hash (const char *data,
257               size_t len,
258               unsigned char *res)
259 {
260   SHA_CTX sha1;
261
262   return otp_md_hash (data, len,
263                       (void (*)(void *))SHA1_Init,
264                       (void (*)(void *, const void *, size_t))SHA1_Update, 
265                       (void (*)(void *, void *))SHA1_Final_little_endian,
266                       &sha1, res, 20);
267 }
268
269 int
270 otp_sha_next (OtpKey key)
271 {
272   unsigned char res[20];
273   SHA_CTX sha1;
274
275   return otp_md_next (key, 
276                       (void (*)(void *))SHA1_Init,
277                       (void (*)(void *, const void *, size_t))SHA1_Update,
278                       (void (*)(void *, void *))SHA1_Final_little_endian,
279                       &sha1, res, sizeof(res));
280 }