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