/ lib / otp / otp_md.c
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  #define HC_DEPRECATED_CRYPTO
 35  
 36  #include "config.h"
 37  
 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  /*
 65   * For histerical reasons, in the OTP definition it's said that
 66   * the result from SHA must be stored in little-endian order.  See
 67   * draft-ietf-otp-01.txt.
 68   */
 69  
 70  static void
 71  little_endian(unsigned char *res, size_t len)
 72  {
 73      unsigned char t;
 74      size_t i;
 75  
 76      for (i = 0; i < len; i += 4) {
 77  	t = res[i + 0]; res[i + 0] = res[i + 3]; res[i + 3] = t;
 78  	t = res[i + 1]; res[i + 1] = res[i + 2]; res[i + 2] = t;
 79      }
 80  }
 81  
 82  static int
 83  otp_md_init (OtpKey key,
 84  	     const char *pwd,
 85  	     const char *seed,
 86  	     const EVP_MD *md,
 87  	     int le,
 88  	     unsigned char *res,
 89  	     size_t ressz)
 90  {
 91      EVP_MD_CTX *ctx;
 92      char *p;
 93      int len;
 94  
 95      ctx = EVP_MD_CTX_create();
 96  
 97      len = strlen(pwd) + strlen(seed);
 98      p = malloc (len + 1);
 99      if (p == NULL)
100  	return -1;
101      strlcpy (p, seed, len + 1);
102      strlwr (p);
103      strlcat (p, pwd, len + 1);
104  
105      EVP_DigestInit_ex(ctx, md, NULL);
106      EVP_DigestUpdate(ctx, p, len);
107      EVP_DigestFinal_ex(ctx, res, NULL);
108  
109      EVP_MD_CTX_destroy(ctx);
110  
111      if (le)
112      	little_endian(res, ressz);
113  
114      free (p);
115      compressmd (key, res, ressz);
116      return 0;
117  }
118  
119  static int
120  otp_md_next (OtpKey key,
121  	     const EVP_MD *md,
122  	     int le,
123  	     unsigned char *res,
124  	     size_t ressz)
125  {
126      EVP_MD_CTX *ctx;
127  
128      ctx = EVP_MD_CTX_create();
129  
130      EVP_DigestInit_ex(ctx, md, NULL);
131      EVP_DigestUpdate(ctx, key, OTPKEYSIZE);
132      EVP_DigestFinal_ex(ctx, res, NULL);
133  
134      EVP_MD_CTX_destroy(ctx);
135  
136      if (le)
137  	little_endian(res, ressz);
138  
139      compressmd (key, res, ressz);
140      return 0;
141  }
142  
143  static int
144  otp_md_hash (const char *data,
145  	     size_t len,
146  	     const EVP_MD *md,
147  	     int le,
148  	     unsigned char *res,
149  	     size_t ressz)
150  {
151      EVP_MD_CTX *ctx;
152      ctx = EVP_MD_CTX_create();
153  
154      EVP_DigestInit_ex(ctx, md, NULL);
155      EVP_DigestUpdate(ctx, data, len);
156      EVP_DigestFinal_ex(ctx, res, NULL);
157  
158      EVP_MD_CTX_destroy(ctx);
159  
160      if (le)
161  	little_endian(res, ressz);
162  
163      return 0;
164  }
165  
166  int
167  otp_md4_init (OtpKey key, const char *pwd, const char *seed)
168  {
169    unsigned char res[16];
170    return otp_md_init (key, pwd, seed, EVP_md4(), 0, res, sizeof(res));
171  }
172  
173  int
174  otp_md4_hash (const char *data,
175  	      size_t len,
176  	      unsigned char *res)
177  {
178    return otp_md_hash (data, len, EVP_md4(), 0, res, 16);
179  }
180  
181  int
182  otp_md4_next (OtpKey key)
183  {
184    unsigned char res[16];
185    return otp_md_next (key, EVP_md4(), 0, res, sizeof(res));
186  }
187  
188  
189  int
190  otp_md5_init (OtpKey key, const char *pwd, const char *seed)
191  {
192    unsigned char res[16];
193    return otp_md_init (key, pwd, seed, EVP_md5(), 0, res, sizeof(res));
194  }
195  
196  int
197  otp_md5_hash (const char *data,
198  	      size_t len,
199  	      unsigned char *res)
200  {
201    return otp_md_hash (data, len, EVP_md5(), 0, res, 16);
202  }
203  
204  int
205  otp_md5_next (OtpKey key)
206  {
207    unsigned char res[16];
208    return otp_md_next (key, EVP_md5(), 0, res, sizeof(res));
209  }
210  
211  int
212  otp_sha_init (OtpKey key, const char *pwd, const char *seed)
213  {
214    unsigned char res[20];
215    return otp_md_init (key, pwd, seed, EVP_sha1(), 1, res, sizeof(res));
216  }
217  
218  int
219  otp_sha_hash (const char *data,
220  	      size_t len,
221  	      unsigned char *res)
222  {
223    return otp_md_hash (data, len, EVP_sha1(), 1, res, 20);
224  }
225  
226  int
227  otp_sha_next (OtpKey key)
228  {
229    unsigned char res[20];
230    return otp_md_next (key, EVP_sha1(), 1, res, sizeof(res));
231  }