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