/src/krb5/src/lib/crypto/builtin/md4/md4.c
Line | Count | Source |
1 | | /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | | /* lib/crypto/builtin/md4/md4.c */ |
3 | | |
4 | | /* |
5 | | * Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. |
6 | | * |
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. |
11 | | * |
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. |
16 | | * |
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. |
21 | | * |
22 | | * These notices must be retained in any copies of any part of this |
23 | | * documentation and/or software. |
24 | | */ |
25 | | |
26 | | /* |
27 | | ********************************************************************** |
28 | | ** md4.c ** |
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 | | ********************************************************************** |
33 | | */ |
34 | | |
35 | | #include "crypto_int.h" |
36 | | #include "rsa-md4.h" |
37 | | |
38 | | #ifdef K5_BUILTIN_MD4 |
39 | | |
40 | | /* forward declaration */ |
41 | | static void Transform (krb5_ui_4 *, krb5_ui_4 *); |
42 | | |
43 | | static const unsigned char PADDING[64] = { |
44 | | 0x80, 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, |
50 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
51 | | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
52 | | }; |
53 | | |
54 | | /* F, G and H are basic MD4 functions: selection, majority, parity */ |
55 | 19.3k | #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) |
56 | 19.3k | #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) |
57 | 19.3k | #define H(x, y, z) ((x) ^ (y) ^ (z)) |
58 | | |
59 | | /* ROTATE_LEFT rotates x left n bits */ |
60 | 57.9k | #define ROTATE_LEFT(x, n) ((((x) << (n)) & 0xffffffff) | ((x) >> (32-(n)))) |
61 | | |
62 | | /* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */ |
63 | | /* Rotation is separate from addition to prevent recomputation */ |
64 | | #define FF(a, b, c, d, x, s) \ |
65 | 19.3k | {(a) += F ((b), (c), (d)) + (x); \ |
66 | 19.3k | (a) &= 0xffffffff; \ |
67 | 19.3k | (a) = ROTATE_LEFT ((a), (s));} |
68 | | #define GG(a, b, c, d, x, s) \ |
69 | 19.3k | {(a) += G ((b), (c), (d)) + (x) + 013240474631UL; \ |
70 | 19.3k | (a) &= 0xffffffff; \ |
71 | 19.3k | (a) = ROTATE_LEFT ((a), (s));} |
72 | | #define HH(a, b, c, d, x, s) \ |
73 | 19.3k | {(a) += H ((b), (c), (d)) + (x) + 015666365641UL; \ |
74 | 19.3k | (a) &= 0xffffffff; \ |
75 | 19.3k | (a) = ROTATE_LEFT ((a), (s));} |
76 | | |
77 | | void |
78 | | krb5int_MD4Init (krb5_MD4_CTX *mdContext) |
79 | 374 | { |
80 | 374 | mdContext->i[0] = mdContext->i[1] = (krb5_ui_4)0; |
81 | | |
82 | | /* Load magic initialization constants. |
83 | | */ |
84 | 374 | mdContext->buf[0] = 0x67452301UL; |
85 | 374 | mdContext->buf[1] = 0xefcdab89UL; |
86 | 374 | mdContext->buf[2] = 0x98badcfeUL; |
87 | 374 | mdContext->buf[3] = 0x10325476UL; |
88 | 374 | } |
89 | | |
90 | | void |
91 | | krb5int_MD4Update (krb5_MD4_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen) |
92 | 748 | { |
93 | 748 | krb5_ui_4 in[16]; |
94 | 748 | int mdi; |
95 | 748 | unsigned int i, ii; |
96 | | |
97 | | /* compute number of bytes mod 64 */ |
98 | 748 | mdi = (int)((mdContext->i[0] >> 3) & 0x3F); |
99 | | |
100 | | /* update number of bits */ |
101 | 748 | if ((mdContext->i[0] + ((krb5_ui_4)inLen << 3)) < mdContext->i[0]) |
102 | 0 | mdContext->i[1]++; |
103 | 748 | mdContext->i[0] += ((krb5_ui_4)inLen << 3); |
104 | 748 | mdContext->i[1] += ((krb5_ui_4)inLen >> 29); |
105 | | |
106 | 75.0k | while (inLen--) { |
107 | | /* add new character to buffer, increment mdi */ |
108 | 74.3k | mdContext->in[mdi++] = *inBuf++; |
109 | | |
110 | | /* transform if necessary */ |
111 | 74.3k | if (mdi == 0x40) { |
112 | 14.1k | for (i = 0, ii = 0; i < 16; i++, ii += 4) { |
113 | 13.3k | in[i] = load_32_le(mdContext->in+ii); |
114 | 13.3k | } |
115 | 834 | Transform (mdContext->buf, in); |
116 | 834 | mdi = 0; |
117 | 834 | } |
118 | 74.3k | } |
119 | 748 | } |
120 | | |
121 | | void |
122 | | krb5int_MD4Final (krb5_MD4_CTX *mdContext) |
123 | 374 | { |
124 | 374 | krb5_ui_4 in[16]; |
125 | 374 | int mdi; |
126 | 374 | unsigned int i, ii; |
127 | 374 | unsigned int padLen; |
128 | | |
129 | | /* save number of bits */ |
130 | 374 | in[14] = mdContext->i[0]; |
131 | 374 | in[15] = mdContext->i[1]; |
132 | | |
133 | | /* compute number of bytes mod 64 */ |
134 | 374 | mdi = (int)((mdContext->i[0] >> 3) & 0x3F); |
135 | | |
136 | | /* pad out to 56 mod 64 */ |
137 | 374 | padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); |
138 | 374 | krb5int_MD4Update (mdContext, PADDING, padLen); |
139 | | |
140 | | /* append length in bits and transform */ |
141 | 5.61k | for (i = 0, ii = 0; i < 14; i++, ii += 4) |
142 | 5.23k | in[i] = load_32_le(mdContext->in+ii); |
143 | 374 | Transform (mdContext->buf, in); |
144 | | |
145 | | |
146 | | /* store buffer in digest */ |
147 | 1.87k | for (i = 0, ii = 0; i < 4; i++, ii += 4) { |
148 | 1.49k | store_32_le(mdContext->buf[i], mdContext->digest+ii); |
149 | 1.49k | } |
150 | 374 | } |
151 | | |
152 | | /* Basic MD4 step. Transform buf based on in. |
153 | | */ |
154 | | static void Transform (krb5_ui_4 *buf, krb5_ui_4 *in) |
155 | 1.20k | { |
156 | 1.20k | krb5_ui_4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; |
157 | | |
158 | | #if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO) |
159 | | int i; |
160 | | #define ROTATE { krb5_ui_4 temp; temp = d, d = c, c = b, b = a, a = temp; } |
161 | | for (i = 0; i < 16; i++) { |
162 | | static const unsigned char round1consts[] = { 3, 7, 11, 19, }; |
163 | | FF (a, b, c, d, in[i], round1consts[i%4]); ROTATE; |
164 | | } |
165 | | for (i = 0; i < 16; i++) { |
166 | | static const unsigned char round2indices[] = { |
167 | | 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 |
168 | | }; |
169 | | static const unsigned char round2consts[] = { 3, 5, 9, 13 }; |
170 | | GG (a, b, c, d, in[round2indices[i]], round2consts[i%4]); ROTATE; |
171 | | } |
172 | | for (i = 0; i < 16; i++) { |
173 | | static const unsigned char round3indices[] = { |
174 | | 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 |
175 | | }; |
176 | | static const unsigned char round3consts[] = { 3, 9, 11, 15 }; |
177 | | HH (a, b, c, d, in[round3indices[i]], round3consts[i%4]); ROTATE; |
178 | | } |
179 | | #else |
180 | | /* Round 1 */ |
181 | 1.20k | FF (a, b, c, d, in[ 0], 3); |
182 | 1.20k | FF (d, a, b, c, in[ 1], 7); |
183 | 1.20k | FF (c, d, a, b, in[ 2], 11); |
184 | 1.20k | FF (b, c, d, a, in[ 3], 19); |
185 | 1.20k | FF (a, b, c, d, in[ 4], 3); |
186 | 1.20k | FF (d, a, b, c, in[ 5], 7); |
187 | 1.20k | FF (c, d, a, b, in[ 6], 11); |
188 | 1.20k | FF (b, c, d, a, in[ 7], 19); |
189 | 1.20k | FF (a, b, c, d, in[ 8], 3); |
190 | 1.20k | FF (d, a, b, c, in[ 9], 7); |
191 | 1.20k | FF (c, d, a, b, in[10], 11); |
192 | 1.20k | FF (b, c, d, a, in[11], 19); |
193 | 1.20k | FF (a, b, c, d, in[12], 3); |
194 | 1.20k | FF (d, a, b, c, in[13], 7); |
195 | 1.20k | FF (c, d, a, b, in[14], 11); |
196 | 1.20k | FF (b, c, d, a, in[15], 19); |
197 | | |
198 | | /* Round 2 */ |
199 | 1.20k | GG (a, b, c, d, in[ 0], 3); |
200 | 1.20k | GG (d, a, b, c, in[ 4], 5); |
201 | 1.20k | GG (c, d, a, b, in[ 8], 9); |
202 | 1.20k | GG (b, c, d, a, in[12], 13); |
203 | 1.20k | GG (a, b, c, d, in[ 1], 3); |
204 | 1.20k | GG (d, a, b, c, in[ 5], 5); |
205 | 1.20k | GG (c, d, a, b, in[ 9], 9); |
206 | 1.20k | GG (b, c, d, a, in[13], 13); |
207 | 1.20k | GG (a, b, c, d, in[ 2], 3); |
208 | 1.20k | GG (d, a, b, c, in[ 6], 5); |
209 | 1.20k | GG (c, d, a, b, in[10], 9); |
210 | 1.20k | GG (b, c, d, a, in[14], 13); |
211 | 1.20k | GG (a, b, c, d, in[ 3], 3); |
212 | 1.20k | GG (d, a, b, c, in[ 7], 5); |
213 | 1.20k | GG (c, d, a, b, in[11], 9); |
214 | 1.20k | GG (b, c, d, a, in[15], 13); |
215 | | |
216 | | /* Round 3 */ |
217 | 1.20k | HH (a, b, c, d, in[ 0], 3); |
218 | 1.20k | HH (d, a, b, c, in[ 8], 9); |
219 | 1.20k | HH (c, d, a, b, in[ 4], 11); |
220 | 1.20k | HH (b, c, d, a, in[12], 15); |
221 | 1.20k | HH (a, b, c, d, in[ 2], 3); |
222 | 1.20k | HH (d, a, b, c, in[10], 9); |
223 | 1.20k | HH (c, d, a, b, in[ 6], 11); |
224 | 1.20k | HH (b, c, d, a, in[14], 15); |
225 | 1.20k | HH (a, b, c, d, in[ 1], 3); |
226 | 1.20k | HH (d, a, b, c, in[ 9], 9); |
227 | 1.20k | HH (c, d, a, b, in[ 5], 11); |
228 | 1.20k | HH (b, c, d, a, in[13], 15); |
229 | 1.20k | HH (a, b, c, d, in[ 3], 3); |
230 | 1.20k | HH (d, a, b, c, in[11], 9); |
231 | 1.20k | HH (c, d, a, b, in[ 7], 11); |
232 | 1.20k | HH (b, c, d, a, in[15], 15); |
233 | 1.20k | #endif |
234 | | |
235 | 1.20k | buf[0] += a; |
236 | 1.20k | buf[1] += b; |
237 | 1.20k | buf[2] += c; |
238 | 1.20k | buf[3] += d; |
239 | 1.20k | } |
240 | | |
241 | | /* |
242 | | ********************************************************************** |
243 | | ** End of md4.c ** |
244 | | ******************************* (cut) ******************************** |
245 | | */ |
246 | | |
247 | | #endif /* K5_BUILTIN_MD4 */ |