1 /* 2 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/crypto/md4/md4.c 10 */ 11 12 /* 13 ********************************************************************** 14 ** md4.c ** 15 ** RSA Data Security, Inc. MD4 Message Digest Algorithm ** 16 ** Created: 2/17/90 RLR ** 17 ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** 18 ********************************************************************** 19 */ 20 21 /* 22 ********************************************************************** 23 ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** 24 ** ** 25 ** License to copy and use this software is granted provided that ** 26 ** it is identified as the "RSA Data Security, Inc. MD4 Message ** 27 ** Digest Algorithm" in all material mentioning or referencing this ** 28 ** software or this function. ** 29 ** ** 30 ** License is also granted to make and use derivative works ** 31 ** provided that such works are identified as "derived from the RSA ** 32 ** Data Security, Inc. MD4 Message Digest Algorithm" in all ** 33 ** material mentioning or referencing the derived work. ** 34 ** ** 35 ** RSA Data Security, Inc. makes no representations concerning ** 36 ** either the merchantability of this software or the suitability ** 37 ** of this software for any particular purpose. It is provided "as ** 38 ** is" without express or implied warranty of any kind. ** 39 ** ** 40 ** These notices must be retained in any copies of any part of this ** 41 ** documentation and/or software. ** 42 ********************************************************************** 43 */ 44 45 #include <k5-int.h> 46 #include <rsa-md4.h> 47 48 /* forward declaration */ 49 static void Transform (krb5_ui_4 *, krb5_ui_4 *); 50 51 static const unsigned char PADDING[64] = { 52 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 60 }; 61 62 /* F, G and H are basic MD4 functions: selection, majority, parity */ 63 #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) 64 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 65 #define H(x, y, z) ((x) ^ (y) ^ (z)) 66 67 /* ROTATE_LEFT rotates x left n bits */ 68 #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n)))) 69 70 /* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */ 71 /* Rotation is separate from addition to prevent recomputation */ 72 #define FF(a, b, c, d, x, s) \ 73 {(a) += F ((b), (c), (d)) + (x); \ 74 (a) &= 0xffffffff; \ 75 (a) = ROTATE_LEFT ((a), (s));} 76 #define GG(a, b, c, d, x, s) \ 77 {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \ 78 (a) &= 0xffffffff; \ 79 (a) = ROTATE_LEFT ((a), (s));} 80 #define HH(a, b, c, d, x, s) \ 81 {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \ 82 (a) &= 0xffffffff; \ 83 (a) = ROTATE_LEFT ((a), (s));} 84 85 void 86 krb5_MD4Init (mdContext) 87 krb5_MD4_CTX *mdContext; 88 { 89 mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0; 90 91 /* Load magic initialization constants. 92 */ 93 mdContext->buf[0] = 0x67452301UL; 94 mdContext->buf[1] = 0xefcdab89UL; 95 mdContext->buf[2] = 0x98badcfeUL; 96 mdContext->buf[3] = 0x10325476UL; 97 } 98 99 void 100 krb5_MD4Update (mdContext, inBuf, inLen) 101 krb5_MD4_CTX *mdContext; 102 const unsigned char *inBuf; 103 unsigned int inLen; 104 { 105 krb5_ui_4 in[16]; 106 int mdi; 107 unsigned int i, ii; 108 109 /* compute number of bytes mod 64 */ 110 mdi = (int)((mdContext->i[0] >> 3) & 0x3F); 111 112 /* update number of bits */ 113 if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0]) 114 mdContext->i[1]++; 115 mdContext->i[0] += ((krb5_ui_4)inLen << 3); 116 mdContext->i[1] += ((krb5_ui_4)inLen >> 29); 117 118 while (inLen--) { 119 /* add new character to buffer, increment mdi */ 120 mdContext->in[mdi++] = *inBuf++; 121 122 /* transform if necessary */ 123 if (mdi == 0x40) { 124 for (i = 0, ii = 0; i < 16; i++, ii += 4) 125 in[i] = (((krb5_ui_4)mdContext->in[ii+3]) << 24) | 126 (((krb5_ui_4)mdContext->in[ii+2]) << 16) | 127 (((krb5_ui_4)mdContext->in[ii+1]) << 8) | 128 ((krb5_ui_4)mdContext->in[ii]); 129 Transform (mdContext->buf, in); 130 mdi = 0; 131 } 132 } 133 } 134 135 void 136 krb5_MD4Final (mdContext) 137 krb5_MD4_CTX *mdContext; 138 { 139 krb5_ui_4 in[16]; 140 int mdi; 141 unsigned int i, ii; 142 unsigned int padLen; 143 144 /* save number of bits */ 145 in[14] = mdContext->i[0]; 146 in[15] = mdContext->i[1]; 147 148 /* compute number of bytes mod 64 */ 149 mdi = (int)((mdContext->i[0] >> 3) & 0x3F); 150 151 /* pad out to 56 mod 64 */ 152 padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); 153 krb5_MD4Update (mdContext, PADDING, padLen); 154 155 /* append length in bits and transform */ 156 for (i = 0, ii = 0; i < 14; i++, ii += 4) 157 in[i] = (((krb5_ui_4)mdContext->in[ii+3]) << 24) | 158 (((krb5_ui_4)mdContext->in[ii+2]) << 16) | 159 (((krb5_ui_4)mdContext->in[ii+1]) << 8) | 160 ((krb5_ui_4)mdContext->in[ii]); 161 Transform (mdContext->buf, in); 162 163 164 /* store buffer in digest */ 165 for (i = 0, ii = 0; i < 4; i++, ii += 4) { 166 mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); 167 mdContext->digest[ii+1] = 168 (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); 169 mdContext->digest[ii+2] = 170 (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); 171 mdContext->digest[ii+3] = 172 (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); 173 } 174 } 175 176 /* Basic MD4 step. Transform buf based on in. 177 */ 178 static void Transform (buf, in) 179 krb5_ui_4 *buf; 180 krb5_ui_4 *in; 181 { 182 register krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; 183 184 /* Round 1 */ 185 FF (a, b, c, d, in[ 0], 3); 186 FF (d, a, b, c, in[ 1], 7); 187 FF (c, d, a, b, in[ 2], 11); 188 FF (b, c, d, a, in[ 3], 19); 189 FF (a, b, c, d, in[ 4], 3); 190 FF (d, a, b, c, in[ 5], 7); 191 FF (c, d, a, b, in[ 6], 11); 192 FF (b, c, d, a, in[ 7], 19); 193 FF (a, b, c, d, in[ 8], 3); 194 FF (d, a, b, c, in[ 9], 7); 195 FF (c, d, a, b, in[10], 11); 196 FF (b, c, d, a, in[11], 19); 197 FF (a, b, c, d, in[12], 3); 198 FF (d, a, b, c, in[13], 7); 199 FF (c, d, a, b, in[14], 11); 200 FF (b, c, d, a, in[15], 19); 201 202 /* Round 2 */ 203 GG (a, b, c, d, in[ 0], 3); 204 GG (d, a, b, c, in[ 4], 5); 205 GG (c, d, a, b, in[ 8], 9); 206 GG (b, c, d, a, in[12], 13); 207 GG (a, b, c, d, in[ 1], 3); 208 GG (d, a, b, c, in[ 5], 5); 209 GG (c, d, a, b, in[ 9], 9); 210 GG (b, c, d, a, in[13], 13); 211 GG (a, b, c, d, in[ 2], 3); 212 GG (d, a, b, c, in[ 6], 5); 213 GG (c, d, a, b, in[10], 9); 214 GG (b, c, d, a, in[14], 13); 215 GG (a, b, c, d, in[ 3], 3); 216 GG (d, a, b, c, in[ 7], 5); 217 GG (c, d, a, b, in[11], 9); 218 GG (b, c, d, a, in[15], 13); 219 220 /* Round 3 */ 221 HH (a, b, c, d, in[ 0], 3); 222 HH (d, a, b, c, in[ 8], 9); 223 HH (c, d, a, b, in[ 4], 11); 224 HH (b, c, d, a, in[12], 15); 225 HH (a, b, c, d, in[ 2], 3); 226 HH (d, a, b, c, in[10], 9); 227 HH (c, d, a, b, in[ 6], 11); 228 HH (b, c, d, a, in[14], 15); 229 HH (a, b, c, d, in[ 1], 3); 230 HH (d, a, b, c, in[ 9], 9); 231 HH (c, d, a, b, in[ 5], 11); 232 HH (b, c, d, a, in[13], 15); 233 HH (a, b, c, d, in[ 3], 3); 234 HH (d, a, b, c, in[11], 9); 235 HH (c, d, a, b, in[ 7], 11); 236 HH (b, c, d, a, in[15], 15); 237 238 buf[0] += a; 239 buf[1] += b; 240 buf[2] += c; 241 buf[3] += d; 242 } 243 244 /* 245 ********************************************************************** 246 ** End of md4.c ** 247 ******************************* (cut) ******************************** 248 */ 249