1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * This is derived from material copyright RSA Data Security, Inc.
17 * Their notice is reproduced below in its entirety.
19 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
22 * License to copy and use this software is granted provided that it
23 * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
24 * Algorithm" in all material mentioning or referencing this software
27 * License is also granted to make and use derivative works provided
28 * that such works are identified as "derived from the RSA Data
29 * Security, Inc. MD4 Message-Digest Algorithm" in all material
30 * mentioning or referencing the derived work.
32 * RSA Data Security, Inc. makes no representations concerning either
33 * the merchantability of this software or the suitability of this
34 * software for any particular purpose. It is provided "as is"
35 * without express or implied warranty of any kind.
37 * These notices must be retained in any copies of any part of this
38 * documentation and/or software.
41 #include "apr_strings.h"
52 /* Constants for MD4Transform routine.
68 static void MD4Transform(apr_uint32_t state
[4], const unsigned char block
[64]);
69 static void Encode(unsigned char *output
, const apr_uint32_t
*input
,
71 static void Decode(apr_uint32_t
*output
, const unsigned char *input
,
74 static unsigned char PADDING
[64] =
76 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
81 #if APR_CHARSET_EBCDIC
82 static apr_xlate_t
*xlate_ebcdic_to_ascii
; /* used in apr_md4_encode() */
85 /* F, G and I are basic MD4 functions.
87 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
88 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
89 #define H(x, y, z) ((x) ^ (y) ^ (z))
91 /* ROTATE_LEFT rotates x left n bits.
93 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
95 /* FF, GG and HH are transformations for rounds 1, 2 and 3 */
96 /* Rotation is separate from addition to prevent recomputation */
98 #define FF(a, b, c, d, x, s) { \
99 (a) += F ((b), (c), (d)) + (x); \
100 (a) = ROTATE_LEFT ((a), (s)); \
102 #define GG(a, b, c, d, x, s) { \
103 (a) += G ((b), (c), (d)) + (x) + (apr_uint32_t)0x5a827999; \
104 (a) = ROTATE_LEFT ((a), (s)); \
106 #define HH(a, b, c, d, x, s) { \
107 (a) += H ((b), (c), (d)) + (x) + (apr_uint32_t)0x6ed9eba1; \
108 (a) = ROTATE_LEFT ((a), (s)); \
111 /* MD4 initialization. Begins an MD4 operation, writing a new context.
113 APU_DECLARE(apr_status_t
) apr_md4_init(apr_md4_ctx_t
*context
)
115 context
->count
[0] = context
->count
[1] = 0;
117 /* Load magic initialization constants. */
118 context
->state
[0] = 0x67452301;
119 context
->state
[1] = 0xefcdab89;
120 context
->state
[2] = 0x98badcfe;
121 context
->state
[3] = 0x10325476;
124 context
->xlate
= NULL
;
131 /* MD4 translation setup. Provides the APR translation handle
132 * to be used for translating the content before calculating the
135 APU_DECLARE(apr_status_t
) apr_md4_set_xlate(apr_md4_ctx_t
*context
,
141 /* TODO: remove the single-byte-only restriction from this code
143 rv
= apr_xlate_sb_get(xlate
, &is_sb
);
144 if (rv
!= APR_SUCCESS
) {
150 context
->xlate
= xlate
;
153 #endif /* APR_HAS_XLATE */
155 /* MD4 block update operation. Continues an MD4 message-digest
156 * operation, processing another message block, and updating the
159 APU_DECLARE(apr_status_t
) apr_md4_update(apr_md4_ctx_t
*context
,
160 const unsigned char *input
,
163 unsigned int i
, idx
, partLen
;
165 apr_size_t inbytes_left
, outbytes_left
;
168 /* Compute number of bytes mod 64 */
169 idx
= (unsigned int)((context
->count
[0] >> 3) & 0x3F);
171 /* Update number of bits */
172 if ((context
->count
[0] += ((apr_uint32_t
)inputLen
<< 3))
173 < ((apr_uint32_t
)inputLen
<< 3))
175 context
->count
[1] += (apr_uint32_t
)inputLen
>> 29;
179 /* Transform as many times as possible. */
181 if (inputLen
>= partLen
) {
182 memcpy(&context
->buffer
[idx
], input
, partLen
);
183 MD4Transform(context
->state
, context
->buffer
);
185 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64)
186 MD4Transform(context
->state
, &input
[i
]);
193 /* Buffer remaining input */
194 memcpy(&context
->buffer
[idx
], &input
[i
], inputLen
- i
);
195 #else /*APR_HAS_XLATE*/
196 if (inputLen
>= partLen
) {
197 if (context
->xlate
) {
198 inbytes_left
= outbytes_left
= partLen
;
199 apr_xlate_conv_buffer(context
->xlate
, (const char *)input
,
201 (char *)&context
->buffer
[idx
],
205 memcpy(&context
->buffer
[idx
], input
, partLen
);
207 MD4Transform(context
->state
, context
->buffer
);
209 for (i
= partLen
; i
+ 63 < inputLen
; i
+= 64) {
210 if (context
->xlate
) {
211 unsigned char inp_tmp
[64];
212 inbytes_left
= outbytes_left
= 64;
213 apr_xlate_conv_buffer(context
->xlate
, (const char *)&input
[i
],
215 (char *)inp_tmp
, &outbytes_left
);
216 MD4Transform(context
->state
, inp_tmp
);
219 MD4Transform(context
->state
, &input
[i
]);
228 /* Buffer remaining input */
229 if (context
->xlate
) {
230 inbytes_left
= outbytes_left
= inputLen
- i
;
231 apr_xlate_conv_buffer(context
->xlate
, (const char *)&input
[i
],
232 &inbytes_left
, (char *)&context
->buffer
[idx
],
236 memcpy(&context
->buffer
[idx
], &input
[i
], inputLen
- i
);
238 #endif /*APR_HAS_XLATE*/
242 /* MD4 finalization. Ends an MD4 message-digest operation, writing the
243 * the message digest and zeroizing the context.
245 APU_DECLARE(apr_status_t
) apr_md4_final(
246 unsigned char digest
[APR_MD4_DIGESTSIZE
],
247 apr_md4_ctx_t
*context
)
249 unsigned char bits
[8];
250 unsigned int idx
, padLen
;
252 /* Save number of bits */
253 Encode(bits
, context
->count
, 8);
256 /* apr_md4_update() should not translate for this final round. */
257 context
->xlate
= NULL
;
258 #endif /*APR_HAS_XLATE*/
260 /* Pad out to 56 mod 64. */
261 idx
= (unsigned int) ((context
->count
[0] >> 3) & 0x3f);
262 padLen
= (idx
< 56) ? (56 - idx
) : (120 - idx
);
263 apr_md4_update(context
, PADDING
, padLen
);
265 /* Append length (before padding) */
266 apr_md4_update(context
, bits
, 8);
268 /* Store state in digest */
269 Encode(digest
, context
->state
, APR_MD4_DIGESTSIZE
);
271 /* Zeroize sensitive information. */
272 memset(context
, 0, sizeof(*context
));
277 /* MD4 computation in one step (init, update, final)
279 APU_DECLARE(apr_status_t
) apr_md4(unsigned char digest
[APR_MD4_DIGESTSIZE
],
280 const unsigned char *input
,
288 if ((rv
= apr_md4_update(&ctx
, input
, inputLen
)) != APR_SUCCESS
)
291 return apr_md4_final(digest
, &ctx
);
294 /* MD4 basic transformation. Transforms state based on block. */
295 static void MD4Transform(apr_uint32_t state
[4], const unsigned char block
[64])
297 apr_uint32_t a
= state
[0], b
= state
[1], c
= state
[2], d
= state
[3],
298 x
[APR_MD4_DIGESTSIZE
];
300 Decode(x
, block
, 64);
303 FF (a
, b
, c
, d
, x
[ 0], S11
); /* 1 */
304 FF (d
, a
, b
, c
, x
[ 1], S12
); /* 2 */
305 FF (c
, d
, a
, b
, x
[ 2], S13
); /* 3 */
306 FF (b
, c
, d
, a
, x
[ 3], S14
); /* 4 */
307 FF (a
, b
, c
, d
, x
[ 4], S11
); /* 5 */
308 FF (d
, a
, b
, c
, x
[ 5], S12
); /* 6 */
309 FF (c
, d
, a
, b
, x
[ 6], S13
); /* 7 */
310 FF (b
, c
, d
, a
, x
[ 7], S14
); /* 8 */
311 FF (a
, b
, c
, d
, x
[ 8], S11
); /* 9 */
312 FF (d
, a
, b
, c
, x
[ 9], S12
); /* 10 */
313 FF (c
, d
, a
, b
, x
[10], S13
); /* 11 */
314 FF (b
, c
, d
, a
, x
[11], S14
); /* 12 */
315 FF (a
, b
, c
, d
, x
[12], S11
); /* 13 */
316 FF (d
, a
, b
, c
, x
[13], S12
); /* 14 */
317 FF (c
, d
, a
, b
, x
[14], S13
); /* 15 */
318 FF (b
, c
, d
, a
, x
[15], S14
); /* 16 */
321 GG (a
, b
, c
, d
, x
[ 0], S21
); /* 17 */
322 GG (d
, a
, b
, c
, x
[ 4], S22
); /* 18 */
323 GG (c
, d
, a
, b
, x
[ 8], S23
); /* 19 */
324 GG (b
, c
, d
, a
, x
[12], S24
); /* 20 */
325 GG (a
, b
, c
, d
, x
[ 1], S21
); /* 21 */
326 GG (d
, a
, b
, c
, x
[ 5], S22
); /* 22 */
327 GG (c
, d
, a
, b
, x
[ 9], S23
); /* 23 */
328 GG (b
, c
, d
, a
, x
[13], S24
); /* 24 */
329 GG (a
, b
, c
, d
, x
[ 2], S21
); /* 25 */
330 GG (d
, a
, b
, c
, x
[ 6], S22
); /* 26 */
331 GG (c
, d
, a
, b
, x
[10], S23
); /* 27 */
332 GG (b
, c
, d
, a
, x
[14], S24
); /* 28 */
333 GG (a
, b
, c
, d
, x
[ 3], S21
); /* 29 */
334 GG (d
, a
, b
, c
, x
[ 7], S22
); /* 30 */
335 GG (c
, d
, a
, b
, x
[11], S23
); /* 31 */
336 GG (b
, c
, d
, a
, x
[15], S24
); /* 32 */
339 HH (a
, b
, c
, d
, x
[ 0], S31
); /* 33 */
340 HH (d
, a
, b
, c
, x
[ 8], S32
); /* 34 */
341 HH (c
, d
, a
, b
, x
[ 4], S33
); /* 35 */
342 HH (b
, c
, d
, a
, x
[12], S34
); /* 36 */
343 HH (a
, b
, c
, d
, x
[ 2], S31
); /* 37 */
344 HH (d
, a
, b
, c
, x
[10], S32
); /* 38 */
345 HH (c
, d
, a
, b
, x
[ 6], S33
); /* 39 */
346 HH (b
, c
, d
, a
, x
[14], S34
); /* 40 */
347 HH (a
, b
, c
, d
, x
[ 1], S31
); /* 41 */
348 HH (d
, a
, b
, c
, x
[ 9], S32
); /* 42 */
349 HH (c
, d
, a
, b
, x
[ 5], S33
); /* 43 */
350 HH (b
, c
, d
, a
, x
[13], S34
); /* 44 */
351 HH (a
, b
, c
, d
, x
[ 3], S31
); /* 45 */
352 HH (d
, a
, b
, c
, x
[11], S32
); /* 46 */
353 HH (c
, d
, a
, b
, x
[ 7], S33
); /* 47 */
354 HH (b
, c
, d
, a
, x
[15], S34
); /* 48 */
361 /* Zeroize sensitive information. */
362 memset(x
, 0, sizeof(x
));
365 /* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is
368 static void Encode(unsigned char *output
, const apr_uint32_t
*input
,
374 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
376 output
[j
] = (unsigned char)(k
& 0xff);
377 output
[j
+ 1] = (unsigned char)((k
>> 8) & 0xff);
378 output
[j
+ 2] = (unsigned char)((k
>> 16) & 0xff);
379 output
[j
+ 3] = (unsigned char)((k
>> 24) & 0xff);
383 /* Decodes input (unsigned char) into output (apr_uint32_t). Assumes len is
386 static void Decode(apr_uint32_t
*output
, const unsigned char *input
,
391 for (i
= 0, j
= 0; j
< len
; i
++, j
+= 4)
392 output
[i
] = ((apr_uint32_t
)input
[j
]) |
393 (((apr_uint32_t
)input
[j
+ 1]) << 8) |
394 (((apr_uint32_t
)input
[j
+ 2]) << 16) |
395 (((apr_uint32_t
)input
[j
+ 3]) << 24);
398 #if APR_CHARSET_EBCDIC
399 APU_DECLARE(apr_status_t
) apr_MD4InitEBCDIC(apr_xlate_t
*xlate
)
401 xlate_ebcdic_to_ascii
= xlate
;