md4c.c revision 1.1 1 1.1 christos /* $NetBSD: md4c.c,v 1.1 2005/12/20 19:28:51 christos Exp $ */
2 1.1 christos
3 1.1 christos /*
4 1.1 christos * This file is derived from the RSA Data Security, Inc. MD4 Message-Digest
5 1.1 christos * Algorithm and has been modified by Jason R. Thorpe <thorpej (at) NetBSD.org>
6 1.1 christos * for portability and formatting.
7 1.1 christos */
8 1.1 christos
9 1.1 christos /*
10 1.1 christos * Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
11 1.1 christos *
12 1.1 christos * License to copy and use this software is granted provided that it
13 1.1 christos * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
14 1.1 christos * Algorithm" in all material mentioning or referencing this software
15 1.1 christos * or this function.
16 1.1 christos *
17 1.1 christos * License is also granted to make and use derivative works provided
18 1.1 christos * that such works are identified as "derived from the RSA Data
19 1.1 christos * Security, Inc. MD4 Message-Digest Algorithm" in all material
20 1.1 christos * mentioning or referencing the derived work.
21 1.1 christos *
22 1.1 christos * RSA Data Security, Inc. makes no representations concerning either
23 1.1 christos * the merchantability of this software or the suitability of this
24 1.1 christos * software for any particular purpose. It is provided "as is"
25 1.1 christos * without express or implied warranty of any kind.
26 1.1 christos *
27 1.1 christos * These notices must be retained in any copies of any part of this
28 1.1 christos * documentation and/or software.
29 1.1 christos */
30 1.1 christos
31 1.1 christos #if !defined(_KERNEL) && !defined(_STANDALONE)
32 1.1 christos #include <sys/cdefs.h>
33 1.1 christos #if defined(LIBC_SCCS) && !defined(lint)
34 1.1 christos __RCSID("$NetBSD: md4c.c,v 1.1 2005/12/20 19:28:51 christos Exp $");
35 1.1 christos #endif /* LIBC_SCCS and not lint */
36 1.1 christos
37 1.1 christos #include "namespace.h"
38 1.1 christos
39 1.1 christos #include <sys/types.h>
40 1.1 christos
41 1.1 christos #include <assert.h>
42 1.1 christos #include <md4.h>
43 1.1 christos #include <string.h>
44 1.1 christos
45 1.1 christos #if HAVE_NBTOOL_CONFIG_H
46 1.1 christos #include "nbtool_config.h"
47 1.1 christos #endif
48 1.1 christos
49 1.1 christos #else
50 1.1 christos
51 1.1 christos #include <sys/md4.h>
52 1.1 christos #include <lib/libkern/libkern.h>
53 1.1 christos
54 1.1 christos #endif /* !_KERNEL && !_STANDALONE */
55 1.1 christos
56 1.1 christos #if !HAVE_MD4_H
57 1.1 christos
58 1.1 christos typedef unsigned char *POINTER;
59 1.1 christos typedef u_int16_t UINT2;
60 1.1 christos typedef u_int32_t UINT4;
61 1.1 christos
62 1.1 christos /*
63 1.1 christos * Constants for MD4Transform routine.
64 1.1 christos */
65 1.1 christos #define S11 3
66 1.1 christos #define S12 7
67 1.1 christos #define S13 11
68 1.1 christos #define S14 19
69 1.1 christos #define S21 3
70 1.1 christos #define S22 5
71 1.1 christos #define S23 9
72 1.1 christos #define S24 13
73 1.1 christos #define S31 3
74 1.1 christos #define S32 9
75 1.1 christos #define S33 11
76 1.1 christos #define S34 15
77 1.1 christos
78 1.1 christos static void MD4Transform __P((UINT4 [4], const unsigned char [64]));
79 1.1 christos
80 1.1 christos static void Encode __P((unsigned char *, UINT4 *, unsigned int));
81 1.1 christos static void Decode __P((UINT4 *, const unsigned char *, unsigned int));
82 1.1 christos
83 1.1 christos static const unsigned char PADDING[64] = {
84 1.1 christos 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 1.1 christos 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 1.1 christos 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
87 1.1 christos };
88 1.1 christos
89 1.1 christos /*
90 1.1 christos * F, G and H are basic MD4 functions.
91 1.1 christos */
92 1.1 christos #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
93 1.1 christos #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
94 1.1 christos #define H(x, y, z) ((x) ^ (y) ^ (z))
95 1.1 christos
96 1.1 christos /*
97 1.1 christos * ROTATE_LEFT rotates x left n bits.
98 1.1 christos */
99 1.1 christos #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
100 1.1 christos
101 1.1 christos /*
102 1.1 christos * FF, GG and HH are transformations for rounds 1, 2 and 3.
103 1.1 christos * Rotation is separate from addition to prevent recomputation.
104 1.1 christos */
105 1.1 christos #define FF(a, b, c, d, x, s) { \
106 1.1 christos (a) += F ((b), (c), (d)) + (x); \
107 1.1 christos (a) = ROTATE_LEFT ((a), (s)); \
108 1.1 christos }
109 1.1 christos
110 1.1 christos #define GG(a, b, c, d, x, s) { \
111 1.1 christos (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
112 1.1 christos (a) = ROTATE_LEFT ((a), (s)); \
113 1.1 christos }
114 1.1 christos
115 1.1 christos #define HH(a, b, c, d, x, s) { \
116 1.1 christos (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
117 1.1 christos (a) = ROTATE_LEFT ((a), (s)); \
118 1.1 christos }
119 1.1 christos
120 1.1 christos #if !defined(_KERNEL) && !defined(_STANDALONE) && defined(__weak_alias)
121 1.1 christos __weak_alias(MD4Init,_MD4Init)
122 1.1 christos __weak_alias(MD4Update,_MD4Update)
123 1.1 christos __weak_alias(MD4Final,_MD4Final)
124 1.1 christos __weak_alias(MD4Transform,_MD4Transform)
125 1.1 christos #endif
126 1.1 christos
127 1.1 christos /*
128 1.1 christos * MD4 initialization. Begins an MD4 operation, writing a new context.
129 1.1 christos */
130 1.1 christos void
131 1.1 christos MD4Init(context)
132 1.1 christos MD4_CTX *context; /* context */
133 1.1 christos {
134 1.1 christos
135 1.1 christos _DIAGASSERT(context != 0);
136 1.1 christos
137 1.1 christos context->count[0] = context->count[1] = 0;
138 1.1 christos
139 1.1 christos /* Load magic initialization constants. */
140 1.1 christos context->state[0] = 0x67452301;
141 1.1 christos context->state[1] = 0xefcdab89;
142 1.1 christos context->state[2] = 0x98badcfe;
143 1.1 christos context->state[3] = 0x10325476;
144 1.1 christos }
145 1.1 christos
146 1.1 christos /*
147 1.1 christos * MD4 block update operation. Continues an MD4 message-digest
148 1.1 christos * operation, processing another message block, and updating the
149 1.1 christos * context.
150 1.1 christos */
151 1.1 christos void
152 1.1 christos MD4Update (context, input, inputLen)
153 1.1 christos MD4_CTX *context; /* context */
154 1.1 christos const unsigned char *input; /* input block */
155 1.1 christos unsigned int inputLen; /* length of input block */
156 1.1 christos {
157 1.1 christos unsigned int i, idx, partLen;
158 1.1 christos
159 1.1 christos _DIAGASSERT(context != 0);
160 1.1 christos _DIAGASSERT(input != 0);
161 1.1 christos
162 1.1 christos /* Compute number of bytes mod 64 */
163 1.1 christos idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
164 1.1 christos
165 1.1 christos /* Update number of bits */
166 1.1 christos if ((context->count[0] += ((UINT4)inputLen << 3))
167 1.1 christos < ((UINT4)inputLen << 3))
168 1.1 christos context->count[1]++;
169 1.1 christos context->count[1] += ((UINT4)inputLen >> 29);
170 1.1 christos
171 1.1 christos partLen = 64 - idx;
172 1.1 christos
173 1.1 christos /* Transform as many times as possible. */
174 1.1 christos if (inputLen >= partLen) {
175 1.1 christos memcpy(&context->buffer[idx], input, partLen);
176 1.1 christos MD4Transform(context->state, context->buffer);
177 1.1 christos
178 1.1 christos for (i = partLen; i + 63 < inputLen; i += 64)
179 1.1 christos MD4Transform(context->state, &input[i]);
180 1.1 christos
181 1.1 christos idx = 0;
182 1.1 christos } else
183 1.1 christos i = 0;
184 1.1 christos
185 1.1 christos /* Buffer remaining input */
186 1.1 christos memcpy(&context->buffer[idx], &input[i], inputLen - i);
187 1.1 christos }
188 1.1 christos
189 1.1 christos /*
190 1.1 christos * MD4 finalization. Ends an MD4 message-digest operation, writing the
191 1.1 christos * message digest and zeroing the context.
192 1.1 christos */
193 1.1 christos void
194 1.1 christos MD4Final (digest, context)
195 1.1 christos unsigned char digest[16]; /* message digest */
196 1.1 christos MD4_CTX *context; /* context */
197 1.1 christos {
198 1.1 christos unsigned char bits[8];
199 1.1 christos unsigned int idx, padLen;
200 1.1 christos
201 1.1 christos _DIAGASSERT(digest != 0);
202 1.1 christos _DIAGASSERT(context != 0);
203 1.1 christos
204 1.1 christos /* Save number of bits */
205 1.1 christos Encode(bits, context->count, 8);
206 1.1 christos
207 1.1 christos /* Pad out to 56 mod 64. */
208 1.1 christos idx = (unsigned int)((context->count[0] >> 3) & 0x3f);
209 1.1 christos padLen = (idx < 56) ? (56 - idx) : (120 - idx);
210 1.1 christos MD4Update(context, PADDING, padLen);
211 1.1 christos
212 1.1 christos /* Append length (before padding) */
213 1.1 christos MD4Update(context, bits, 8);
214 1.1 christos
215 1.1 christos /* Store state in digest */
216 1.1 christos Encode(digest, context->state, 16);
217 1.1 christos
218 1.1 christos /* Zeroize sensitive information. */
219 1.1 christos memset(context, 0, sizeof(*context));
220 1.1 christos }
221 1.1 christos
222 1.1 christos /*
223 1.1 christos * MD4 basic transformation. Transforms state based on block.
224 1.1 christos */
225 1.1 christos static void
226 1.1 christos MD4Transform (state, block)
227 1.1 christos UINT4 state[4];
228 1.1 christos const unsigned char block[64];
229 1.1 christos {
230 1.1 christos UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
231 1.1 christos
232 1.1 christos Decode(x, block, 64);
233 1.1 christos
234 1.1 christos /* Round 1 */
235 1.1 christos FF (a, b, c, d, x[ 0], S11); /* 1 */
236 1.1 christos FF (d, a, b, c, x[ 1], S12); /* 2 */
237 1.1 christos FF (c, d, a, b, x[ 2], S13); /* 3 */
238 1.1 christos FF (b, c, d, a, x[ 3], S14); /* 4 */
239 1.1 christos FF (a, b, c, d, x[ 4], S11); /* 5 */
240 1.1 christos FF (d, a, b, c, x[ 5], S12); /* 6 */
241 1.1 christos FF (c, d, a, b, x[ 6], S13); /* 7 */
242 1.1 christos FF (b, c, d, a, x[ 7], S14); /* 8 */
243 1.1 christos FF (a, b, c, d, x[ 8], S11); /* 9 */
244 1.1 christos FF (d, a, b, c, x[ 9], S12); /* 10 */
245 1.1 christos FF (c, d, a, b, x[10], S13); /* 11 */
246 1.1 christos FF (b, c, d, a, x[11], S14); /* 12 */
247 1.1 christos FF (a, b, c, d, x[12], S11); /* 13 */
248 1.1 christos FF (d, a, b, c, x[13], S12); /* 14 */
249 1.1 christos FF (c, d, a, b, x[14], S13); /* 15 */
250 1.1 christos FF (b, c, d, a, x[15], S14); /* 16 */
251 1.1 christos
252 1.1 christos /* Round 2 */
253 1.1 christos GG (a, b, c, d, x[ 0], S21); /* 17 */
254 1.1 christos GG (d, a, b, c, x[ 4], S22); /* 18 */
255 1.1 christos GG (c, d, a, b, x[ 8], S23); /* 19 */
256 1.1 christos GG (b, c, d, a, x[12], S24); /* 20 */
257 1.1 christos GG (a, b, c, d, x[ 1], S21); /* 21 */
258 1.1 christos GG (d, a, b, c, x[ 5], S22); /* 22 */
259 1.1 christos GG (c, d, a, b, x[ 9], S23); /* 23 */
260 1.1 christos GG (b, c, d, a, x[13], S24); /* 24 */
261 1.1 christos GG (a, b, c, d, x[ 2], S21); /* 25 */
262 1.1 christos GG (d, a, b, c, x[ 6], S22); /* 26 */
263 1.1 christos GG (c, d, a, b, x[10], S23); /* 27 */
264 1.1 christos GG (b, c, d, a, x[14], S24); /* 28 */
265 1.1 christos GG (a, b, c, d, x[ 3], S21); /* 29 */
266 1.1 christos GG (d, a, b, c, x[ 7], S22); /* 30 */
267 1.1 christos GG (c, d, a, b, x[11], S23); /* 31 */
268 1.1 christos GG (b, c, d, a, x[15], S24); /* 32 */
269 1.1 christos
270 1.1 christos /* Round 3 */
271 1.1 christos HH (a, b, c, d, x[ 0], S31); /* 33 */
272 1.1 christos HH (d, a, b, c, x[ 8], S32); /* 34 */
273 1.1 christos HH (c, d, a, b, x[ 4], S33); /* 35 */
274 1.1 christos HH (b, c, d, a, x[12], S34); /* 36 */
275 1.1 christos HH (a, b, c, d, x[ 2], S31); /* 37 */
276 1.1 christos HH (d, a, b, c, x[10], S32); /* 38 */
277 1.1 christos HH (c, d, a, b, x[ 6], S33); /* 39 */
278 1.1 christos HH (b, c, d, a, x[14], S34); /* 40 */
279 1.1 christos HH (a, b, c, d, x[ 1], S31); /* 41 */
280 1.1 christos HH (d, a, b, c, x[ 9], S32); /* 42 */
281 1.1 christos HH (c, d, a, b, x[ 5], S33); /* 43 */
282 1.1 christos HH (b, c, d, a, x[13], S34); /* 44 */
283 1.1 christos HH (a, b, c, d, x[ 3], S31); /* 45 */
284 1.1 christos HH (d, a, b, c, x[11], S32); /* 46 */
285 1.1 christos HH (c, d, a, b, x[ 7], S33); /* 47 */
286 1.1 christos HH (b, c, d, a, x[15], S34); /* 48 */
287 1.1 christos
288 1.1 christos state[0] += a;
289 1.1 christos state[1] += b;
290 1.1 christos state[2] += c;
291 1.1 christos state[3] += d;
292 1.1 christos
293 1.1 christos /* Zeroize sensitive information. */
294 1.1 christos memset(x, 0, sizeof (x));
295 1.1 christos }
296 1.1 christos
297 1.1 christos /*
298 1.1 christos * Encodes input (UINT4) into output (unsigned char). Assumes len is
299 1.1 christos * a multiple of 4.
300 1.1 christos */
301 1.1 christos static void
302 1.1 christos Encode(output, input, len)
303 1.1 christos unsigned char *output;
304 1.1 christos UINT4 *input;
305 1.1 christos unsigned int len;
306 1.1 christos {
307 1.1 christos unsigned int i, j;
308 1.1 christos
309 1.1 christos for (i = 0, j = 0; j < len; i++, j += 4) {
310 1.1 christos output[j] = (unsigned char)(input[i] & 0xff);
311 1.1 christos output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
312 1.1 christos output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
313 1.1 christos output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
314 1.1 christos }
315 1.1 christos }
316 1.1 christos
317 1.1 christos /*
318 1.1 christos * Decodes input (unsigned char) into output (UINT4). Assumes len is
319 1.1 christos * a multiple of 4.
320 1.1 christos */
321 1.1 christos static void
322 1.1 christos Decode(output, input, len)
323 1.1 christos UINT4 *output;
324 1.1 christos const unsigned char *input;
325 1.1 christos unsigned int len;
326 1.1 christos {
327 1.1 christos unsigned int i, j;
328 1.1 christos
329 1.1 christos for (i = 0, j = 0; j < len; i++, j += 4)
330 1.1 christos output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
331 1.1 christos (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
332 1.1 christos }
333 1.1 christos
334 1.1 christos #endif /* HAVE_MD4_H */
335