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 }