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 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 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 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 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 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 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 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 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 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 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 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 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 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 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