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