1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/crypto/builtin/md4/md4.c */
5 * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
7 * License to copy and use this software is granted provided that
8 * it is identified as the "RSA Data Security, Inc. MD4 Message
9 * Digest Algorithm" in all material mentioning or referencing this
10 * software or this function.
12 * License is also granted to make and use derivative works
13 * provided that such works are identified as "derived from the RSA
14 * Data Security, Inc. MD4 Message Digest Algorithm" in all
15 * material mentioning or referencing the derived work.
17 * RSA Data Security, Inc. makes no representations concerning
18 * either the merchantability of this software or the suitability
19 * of this software for any particular purpose. It is provided "as
20 * is" without express or implied warranty of any kind.
22 * These notices must be retained in any copies of any part of this
23 * documentation and/or software.
27 **********************************************************************
29 ** RSA Data Security, Inc. MD4 Message Digest Algorithm **
30 ** Created: 2/17/90 RLR **
31 ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version **
32 **********************************************************************
38 /* forward declaration */
39 static void Transform (krb5_ui_4 *, krb5_ui_4 *);
41 static const unsigned char PADDING[64] = {
42 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
52 /* F, G and H are basic MD4 functions: selection, majority, parity */
53 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
54 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
55 #define H(x, y, z) ((x) ^ (y) ^ (z))
57 /* ROTATE_LEFT rotates x left n bits */
58 #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n))))
60 /* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */
61 /* Rotation is separate from addition to prevent recomputation */
62 #define FF(a, b, c, d, x, s) \
63 {(a) += F ((b), (c), (d)) + (x); \
65 (a) = ROTATE_LEFT ((a), (s));}
66 #define GG(a, b, c, d, x, s) \
67 {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \
69 (a) = ROTATE_LEFT ((a), (s));}
70 #define HH(a, b, c, d, x, s) \
71 {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \
73 (a) = ROTATE_LEFT ((a), (s));}
76 krb5int_MD4Init (krb5_MD4_CTX *mdContext)
78 mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0;
80 /* Load magic initialization constants.
82 mdContext->buf[0] = 0x67452301UL;
83 mdContext->buf[1] = 0xefcdab89UL;
84 mdContext->buf[2] = 0x98badcfeUL;
85 mdContext->buf[3] = 0x10325476UL;
89 krb5int_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)
95 /* compute number of bytes mod 64 */
96 mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
98 /* update number of bits */
99 if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0])
101 mdContext->i[0] += ((krb5_ui_4)inLen << 3);
102 mdContext->i[1] += ((krb5_ui_4)inLen >> 29);
105 /* add new character to buffer, increment mdi */
106 mdContext->in[mdi++] = *inBuf++;
108 /* transform if necessary */
110 for (i = 0, ii = 0; i < 16; i++, ii += 4) {
111 in[i] = load_32_le(mdContext->in+ii);
113 Transform (mdContext->buf, in);
120 krb5int_MD4Final (krb5_MD4_CTX *mdContext)
127 /* save number of bits */
128 in[14] = mdContext->i[0];
129 in[15] = mdContext->i[1];
131 /* compute number of bytes mod 64 */
132 mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
134 /* pad out to 56 mod 64 */
135 padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
136 krb5int_MD4Update (mdContext, PADDING, padLen);
138 /* append length in bits and transform */
139 for (i = 0, ii = 0; i < 14; i++, ii += 4)
140 in[i] = load_32_le(mdContext->in+ii);
141 Transform (mdContext->buf, in);
144 /* store buffer in digest */
145 for (i = 0, ii = 0; i < 4; i++, ii += 4) {
146 store_32_le(mdContext->buf[i], mdContext->digest+ii);
150 /* Basic MD4 step. Transform buf based on in.
152 static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in)
154 krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
156 #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
158 #define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; }
159 for (i = 0; i < 16; i++) {
160 static const unsigned char round1consts[] = { 3, 7, 11, 19, };
161 FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE;
163 for (i = 0; i < 16; i++) {
164 static const unsigned char round2indices[] = {
165 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
167 static const unsigned char round2consts[] = { 3, 5, 9, 13 };
168 GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE;
170 for (i = 0; i < 16; i++) {
171 static const unsigned char round3indices[] = {
172 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15
174 static const unsigned char round3consts[] = { 3, 9, 11, 15 };
175 HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE;
179 FF (a, b, c, d, in[ 0], 3);
180 FF (d, a, b, c, in[ 1], 7);
181 FF (c, d, a, b, in[ 2], 11);
182 FF (b, c, d, a, in[ 3], 19);
183 FF (a, b, c, d, in[ 4], 3);
184 FF (d, a, b, c, in[ 5], 7);
185 FF (c, d, a, b, in[ 6], 11);
186 FF (b, c, d, a, in[ 7], 19);
187 FF (a, b, c, d, in[ 8], 3);
188 FF (d, a, b, c, in[ 9], 7);
189 FF (c, d, a, b, in[10], 11);
190 FF (b, c, d, a, in[11], 19);
191 FF (a, b, c, d, in[12], 3);
192 FF (d, a, b, c, in[13], 7);
193 FF (c, d, a, b, in[14], 11);
194 FF (b, c, d, a, in[15], 19);
197 GG (a, b, c, d, in[ 0], 3);
198 GG (d, a, b, c, in[ 4], 5);
199 GG (c, d, a, b, in[ 8], 9);
200 GG (b, c, d, a, in[12], 13);
201 GG (a, b, c, d, in[ 1], 3);
202 GG (d, a, b, c, in[ 5], 5);
203 GG (c, d, a, b, in[ 9], 9);
204 GG (b, c, d, a, in[13], 13);
205 GG (a, b, c, d, in[ 2], 3);
206 GG (d, a, b, c, in[ 6], 5);
207 GG (c, d, a, b, in[10], 9);
208 GG (b, c, d, a, in[14], 13);
209 GG (a, b, c, d, in[ 3], 3);
210 GG (d, a, b, c, in[ 7], 5);
211 GG (c, d, a, b, in[11], 9);
212 GG (b, c, d, a, in[15], 13);
215 HH (a, b, c, d, in[ 0], 3);
216 HH (d, a, b, c, in[ 8], 9);
217 HH (c, d, a, b, in[ 4], 11);
218 HH (b, c, d, a, in[12], 15);
219 HH (a, b, c, d, in[ 2], 3);
220 HH (d, a, b, c, in[10], 9);
221 HH (c, d, a, b, in[ 6], 11);
222 HH (b, c, d, a, in[14], 15);
223 HH (a, b, c, d, in[ 1], 3);
224 HH (d, a, b, c, in[ 9], 9);
225 HH (c, d, a, b, in[ 5], 11);
226 HH (b, c, d, a, in[13], 15);
227 HH (a, b, c, d, in[ 3], 3);
228 HH (d, a, b, c, in[11], 9);
229 HH (c, d, a, b, in[ 7], 11);
230 HH (b, c, d, a, in[15], 15);
240 **********************************************************************
242 ******************************* (cut) ********************************