1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more
2251876Speter * contributor license agreements.  See the NOTICE file distributed with
3251876Speter * this work for additional information regarding copyright ownership.
4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0
5251876Speter * (the "License"); you may not use this file except in compliance with
6251876Speter * the License.  You may obtain a copy of the License at
7251876Speter *
8251876Speter *     http://www.apache.org/licenses/LICENSE-2.0
9251876Speter *
10251876Speter * Unless required by applicable law or agreed to in writing, software
11251876Speter * distributed under the License is distributed on an "AS IS" BASIS,
12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13251876Speter * See the License for the specific language governing permissions and
14251876Speter * limitations under the License.
15251876Speter *
16251876Speter * This is derived from material copyright RSA Data Security, Inc.
17251876Speter * Their notice is reproduced below in its entirety.
18251876Speter *
19251876Speter * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
20251876Speter * rights reserved.
21251876Speter *
22251876Speter * License to copy and use this software is granted provided that it
23251876Speter * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
24251876Speter * Algorithm" in all material mentioning or referencing this software
25251876Speter * or this function.
26251876Speter *
27251876Speter * License is also granted to make and use derivative works provided
28251876Speter * that such works are identified as "derived from the RSA Data
29251876Speter * Security, Inc. MD4 Message-Digest Algorithm" in all material
30251876Speter * mentioning or referencing the derived work.
31251876Speter *
32251876Speter * RSA Data Security, Inc. makes no representations concerning either
33251876Speter * the merchantability of this software or the suitability of this
34251876Speter * software for any particular purpose. It is provided "as is"
35251876Speter * without express or implied warranty of any kind.
36251876Speter *
37251876Speter * These notices must be retained in any copies of any part of this
38251876Speter * documentation and/or software.
39251876Speter */
40251876Speter
41251876Speter#include "apr_strings.h"
42251876Speter#include "apr_md4.h"
43251876Speter#include "apr_lib.h"
44251876Speter
45251876Speter#if APR_HAVE_STRING_H
46251876Speter#include <string.h>
47251876Speter#endif
48251876Speter#if APR_HAVE_UNISTD_H
49251876Speter#include <unistd.h>
50251876Speter#endif
51251876Speter
52251876Speter/* Constants for MD4Transform routine.
53251876Speter */
54251876Speter
55251876Speter#define S11 3
56251876Speter#define S12 7
57251876Speter#define S13 11
58251876Speter#define S14 19
59251876Speter#define S21 3
60251876Speter#define S22 5
61251876Speter#define S23 9
62251876Speter#define S24 13
63251876Speter#define S31 3
64251876Speter#define S32 9
65251876Speter#define S33 11
66251876Speter#define S34 15
67251876Speter
68251876Speterstatic void MD4Transform(apr_uint32_t state[4], const unsigned char block[64]);
69251876Speterstatic void Encode(unsigned char *output, const apr_uint32_t *input,
70251876Speter                   unsigned int len);
71251876Speterstatic void Decode(apr_uint32_t *output, const unsigned char *input,
72251876Speter                   unsigned int len);
73251876Speter
74251876Speterstatic unsigned char PADDING[64] =
75251876Speter{
76251876Speter    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77251876Speter    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78251876Speter    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
79251876Speter};
80251876Speter
81251876Speter#if APR_CHARSET_EBCDIC
82251876Speterstatic apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md4_encode() */
83251876Speter#endif
84251876Speter
85251876Speter/* F, G and I are basic MD4 functions.
86251876Speter */
87251876Speter#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
88251876Speter#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
89251876Speter#define H(x, y, z) ((x) ^ (y) ^ (z))
90251876Speter
91251876Speter/* ROTATE_LEFT rotates x left n bits.
92251876Speter */
93251876Speter#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
94251876Speter
95251876Speter/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
96251876Speter/* Rotation is separate from addition to prevent recomputation */
97251876Speter
98251876Speter#define FF(a, b, c, d, x, s) { \
99251876Speter  (a) += F ((b), (c), (d)) + (x); \
100251876Speter  (a) = ROTATE_LEFT ((a), (s)); \
101251876Speter  }
102251876Speter#define GG(a, b, c, d, x, s) { \
103251876Speter  (a) += G ((b), (c), (d)) + (x) + (apr_uint32_t)0x5a827999; \
104251876Speter  (a) = ROTATE_LEFT ((a), (s)); \
105251876Speter  }
106251876Speter#define HH(a, b, c, d, x, s) { \
107251876Speter  (a) += H ((b), (c), (d)) + (x) + (apr_uint32_t)0x6ed9eba1; \
108251876Speter  (a) = ROTATE_LEFT ((a), (s)); \
109251876Speter  }
110251876Speter
111251876Speter/* MD4 initialization. Begins an MD4 operation, writing a new context.
112251876Speter */
113251876SpeterAPU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context)
114251876Speter{
115251876Speter    context->count[0] = context->count[1] = 0;
116251876Speter
117251876Speter    /* Load magic initialization constants. */
118251876Speter    context->state[0] = 0x67452301;
119251876Speter    context->state[1] = 0xefcdab89;
120251876Speter    context->state[2] = 0x98badcfe;
121251876Speter    context->state[3] = 0x10325476;
122251876Speter
123251876Speter#if APR_HAS_XLATE
124251876Speter    context->xlate = NULL;
125251876Speter#endif
126251876Speter
127251876Speter    return APR_SUCCESS;
128251876Speter}
129251876Speter
130251876Speter#if APR_HAS_XLATE
131251876Speter/* MD4 translation setup.  Provides the APR translation handle
132251876Speter * to be used for translating the content before calculating the
133251876Speter * digest.
134251876Speter */
135251876SpeterAPU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context,
136251876Speter                                            apr_xlate_t *xlate)
137251876Speter{
138251876Speter    apr_status_t rv;
139251876Speter    int is_sb;
140251876Speter
141251876Speter    /* TODO: remove the single-byte-only restriction from this code
142251876Speter     */
143251876Speter    rv = apr_xlate_sb_get(xlate, &is_sb);
144251876Speter    if (rv != APR_SUCCESS) {
145251876Speter        return rv;
146251876Speter    }
147251876Speter    if (!is_sb) {
148251876Speter        return APR_EINVAL;
149251876Speter    }
150251876Speter    context->xlate = xlate;
151251876Speter    return APR_SUCCESS;
152251876Speter}
153251876Speter#endif /* APR_HAS_XLATE */
154251876Speter
155251876Speter/* MD4 block update operation. Continues an MD4 message-digest
156251876Speter * operation, processing another message block, and updating the
157251876Speter * context.
158251876Speter */
159251876SpeterAPU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context,
160251876Speter                                         const unsigned char *input,
161251876Speter                                         apr_size_t inputLen)
162251876Speter{
163251876Speter    unsigned int i, idx, partLen;
164251876Speter#if APR_HAS_XLATE
165251876Speter    apr_size_t inbytes_left, outbytes_left;
166251876Speter#endif
167251876Speter
168251876Speter    /* Compute number of bytes mod 64 */
169251876Speter    idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
170251876Speter
171251876Speter    /* Update number of bits */
172251876Speter    if ((context->count[0] += ((apr_uint32_t)inputLen << 3))
173251876Speter            < ((apr_uint32_t)inputLen << 3))
174251876Speter        context->count[1]++;
175251876Speter    context->count[1] += (apr_uint32_t)inputLen >> 29;
176251876Speter
177251876Speter    partLen = 64 - idx;
178251876Speter
179251876Speter    /* Transform as many times as possible. */
180251876Speter#if !APR_HAS_XLATE
181251876Speter    if (inputLen >= partLen) {
182251876Speter        memcpy(&context->buffer[idx], input, partLen);
183251876Speter        MD4Transform(context->state, context->buffer);
184251876Speter
185251876Speter        for (i = partLen; i + 63 < inputLen; i += 64)
186251876Speter            MD4Transform(context->state, &input[i]);
187251876Speter
188251876Speter        idx = 0;
189251876Speter    }
190251876Speter    else
191251876Speter        i = 0;
192251876Speter
193251876Speter    /* Buffer remaining input */
194251876Speter    memcpy(&context->buffer[idx], &input[i], inputLen - i);
195251876Speter#else /*APR_HAS_XLATE*/
196251876Speter    if (inputLen >= partLen) {
197251876Speter        if (context->xlate) {
198251876Speter            inbytes_left = outbytes_left = partLen;
199251876Speter            apr_xlate_conv_buffer(context->xlate, (const char *)input,
200251876Speter                                  &inbytes_left,
201251876Speter                                  (char *)&context->buffer[idx],
202251876Speter                                  &outbytes_left);
203251876Speter        }
204251876Speter        else {
205251876Speter            memcpy(&context->buffer[idx], input, partLen);
206251876Speter        }
207251876Speter        MD4Transform(context->state, context->buffer);
208251876Speter
209251876Speter        for (i = partLen; i + 63 < inputLen; i += 64) {
210251876Speter            if (context->xlate) {
211251876Speter                unsigned char inp_tmp[64];
212251876Speter                inbytes_left = outbytes_left = 64;
213251876Speter                apr_xlate_conv_buffer(context->xlate, (const char *)&input[i],
214251876Speter                                      &inbytes_left,
215251876Speter                                      (char *)inp_tmp, &outbytes_left);
216251876Speter                MD4Transform(context->state, inp_tmp);
217251876Speter            }
218251876Speter            else {
219251876Speter                MD4Transform(context->state, &input[i]);
220251876Speter            }
221251876Speter        }
222251876Speter
223251876Speter        idx = 0;
224251876Speter    }
225251876Speter    else
226251876Speter        i = 0;
227251876Speter
228251876Speter    /* Buffer remaining input */
229251876Speter    if (context->xlate) {
230251876Speter        inbytes_left = outbytes_left = inputLen - i;
231251876Speter        apr_xlate_conv_buffer(context->xlate, (const char *)&input[i],
232251876Speter                              &inbytes_left, (char *)&context->buffer[idx],
233251876Speter                              &outbytes_left);
234251876Speter    }
235251876Speter    else {
236251876Speter        memcpy(&context->buffer[idx], &input[i], inputLen - i);
237251876Speter    }
238251876Speter#endif /*APR_HAS_XLATE*/
239251876Speter    return APR_SUCCESS;
240251876Speter}
241251876Speter
242251876Speter/* MD4 finalization. Ends an MD4 message-digest operation, writing the
243251876Speter * the message digest and zeroizing the context.
244251876Speter */
245251876SpeterAPU_DECLARE(apr_status_t) apr_md4_final(
246251876Speter                                    unsigned char digest[APR_MD4_DIGESTSIZE],
247251876Speter                                    apr_md4_ctx_t *context)
248251876Speter{
249251876Speter    unsigned char bits[8];
250251876Speter    unsigned int idx, padLen;
251251876Speter
252251876Speter    /* Save number of bits */
253251876Speter    Encode(bits, context->count, 8);
254251876Speter
255251876Speter#if APR_HAS_XLATE
256251876Speter    /* apr_md4_update() should not translate for this final round. */
257251876Speter    context->xlate = NULL;
258251876Speter#endif /*APR_HAS_XLATE*/
259251876Speter
260251876Speter    /* Pad out to 56 mod 64. */
261251876Speter    idx = (unsigned int) ((context->count[0] >> 3) & 0x3f);
262251876Speter    padLen = (idx < 56) ? (56 - idx) : (120 - idx);
263251876Speter    apr_md4_update(context, PADDING, padLen);
264251876Speter
265251876Speter    /* Append length (before padding) */
266251876Speter    apr_md4_update(context, bits, 8);
267251876Speter
268251876Speter    /* Store state in digest */
269251876Speter    Encode(digest, context->state, APR_MD4_DIGESTSIZE);
270251876Speter
271251876Speter    /* Zeroize sensitive information. */
272251876Speter    memset(context, 0, sizeof(*context));
273251876Speter
274251876Speter    return APR_SUCCESS;
275251876Speter}
276251876Speter
277251876Speter/* MD4 computation in one step (init, update, final)
278251876Speter */
279251876SpeterAPU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE],
280251876Speter                                  const unsigned char *input,
281251876Speter                                  apr_size_t inputLen)
282251876Speter{
283251876Speter    apr_md4_ctx_t ctx;
284251876Speter    apr_status_t rv;
285251876Speter
286251876Speter    apr_md4_init(&ctx);
287251876Speter
288251876Speter    if ((rv = apr_md4_update(&ctx, input, inputLen)) != APR_SUCCESS)
289251876Speter        return rv;
290251876Speter
291251876Speter    return apr_md4_final(digest, &ctx);
292251876Speter}
293251876Speter
294251876Speter/* MD4 basic transformation. Transforms state based on block. */
295251876Speterstatic void MD4Transform(apr_uint32_t state[4], const unsigned char block[64])
296251876Speter{
297251876Speter    apr_uint32_t a = state[0], b = state[1], c = state[2], d = state[3],
298251876Speter                 x[APR_MD4_DIGESTSIZE];
299251876Speter
300251876Speter    Decode(x, block, 64);
301251876Speter
302251876Speter    /* Round 1 */
303251876Speter    FF (a, b, c, d, x[ 0], S11); /* 1 */
304251876Speter    FF (d, a, b, c, x[ 1], S12); /* 2 */
305251876Speter    FF (c, d, a, b, x[ 2], S13); /* 3 */
306251876Speter    FF (b, c, d, a, x[ 3], S14); /* 4 */
307251876Speter    FF (a, b, c, d, x[ 4], S11); /* 5 */
308251876Speter    FF (d, a, b, c, x[ 5], S12); /* 6 */
309251876Speter    FF (c, d, a, b, x[ 6], S13); /* 7 */
310251876Speter    FF (b, c, d, a, x[ 7], S14); /* 8 */
311251876Speter    FF (a, b, c, d, x[ 8], S11); /* 9 */
312251876Speter    FF (d, a, b, c, x[ 9], S12); /* 10 */
313251876Speter    FF (c, d, a, b, x[10], S13); /* 11 */
314251876Speter    FF (b, c, d, a, x[11], S14); /* 12 */
315251876Speter    FF (a, b, c, d, x[12], S11); /* 13 */
316251876Speter    FF (d, a, b, c, x[13], S12); /* 14 */
317251876Speter    FF (c, d, a, b, x[14], S13); /* 15 */
318251876Speter    FF (b, c, d, a, x[15], S14); /* 16 */
319251876Speter
320251876Speter    /* Round 2 */
321251876Speter    GG (a, b, c, d, x[ 0], S21); /* 17 */
322251876Speter    GG (d, a, b, c, x[ 4], S22); /* 18 */
323251876Speter    GG (c, d, a, b, x[ 8], S23); /* 19 */
324251876Speter    GG (b, c, d, a, x[12], S24); /* 20 */
325251876Speter    GG (a, b, c, d, x[ 1], S21); /* 21 */
326251876Speter    GG (d, a, b, c, x[ 5], S22); /* 22 */
327251876Speter    GG (c, d, a, b, x[ 9], S23); /* 23 */
328251876Speter    GG (b, c, d, a, x[13], S24); /* 24 */
329251876Speter    GG (a, b, c, d, x[ 2], S21); /* 25 */
330251876Speter    GG (d, a, b, c, x[ 6], S22); /* 26 */
331251876Speter    GG (c, d, a, b, x[10], S23); /* 27 */
332251876Speter    GG (b, c, d, a, x[14], S24); /* 28 */
333251876Speter    GG (a, b, c, d, x[ 3], S21); /* 29 */
334251876Speter    GG (d, a, b, c, x[ 7], S22); /* 30 */
335251876Speter    GG (c, d, a, b, x[11], S23); /* 31 */
336251876Speter    GG (b, c, d, a, x[15], S24); /* 32 */
337251876Speter
338251876Speter    /* Round 3 */
339251876Speter    HH (a, b, c, d, x[ 0], S31); /* 33 */
340251876Speter    HH (d, a, b, c, x[ 8], S32); /* 34 */
341251876Speter    HH (c, d, a, b, x[ 4], S33); /* 35 */
342251876Speter    HH (b, c, d, a, x[12], S34); /* 36 */
343251876Speter    HH (a, b, c, d, x[ 2], S31); /* 37 */
344251876Speter    HH (d, a, b, c, x[10], S32); /* 38 */
345251876Speter    HH (c, d, a, b, x[ 6], S33); /* 39 */
346251876Speter    HH (b, c, d, a, x[14], S34); /* 40 */
347251876Speter    HH (a, b, c, d, x[ 1], S31); /* 41 */
348251876Speter    HH (d, a, b, c, x[ 9], S32); /* 42 */
349251876Speter    HH (c, d, a, b, x[ 5], S33); /* 43 */
350251876Speter    HH (b, c, d, a, x[13], S34); /* 44 */
351251876Speter    HH (a, b, c, d, x[ 3], S31); /* 45 */
352251876Speter    HH (d, a, b, c, x[11], S32); /* 46 */
353251876Speter    HH (c, d, a, b, x[ 7], S33); /* 47 */
354251876Speter    HH (b, c, d, a, x[15], S34); /* 48 */
355251876Speter
356251876Speter    state[0] += a;
357251876Speter    state[1] += b;
358251876Speter    state[2] += c;
359251876Speter    state[3] += d;
360251876Speter
361251876Speter    /* Zeroize sensitive information. */
362251876Speter    memset(x, 0, sizeof(x));
363251876Speter}
364251876Speter
365251876Speter/* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is
366251876Speter * a multiple of 4.
367251876Speter */
368251876Speterstatic void Encode(unsigned char *output, const apr_uint32_t *input,
369251876Speter                   unsigned int len)
370251876Speter{
371251876Speter    unsigned int i, j;
372251876Speter    apr_uint32_t k;
373251876Speter
374251876Speter    for (i = 0, j = 0; j < len; i++, j += 4) {
375251876Speter        k = input[i];
376251876Speter        output[j]     = (unsigned char)(k & 0xff);
377251876Speter        output[j + 1] = (unsigned char)((k >> 8)  & 0xff);
378251876Speter        output[j + 2] = (unsigned char)((k >> 16) & 0xff);
379251876Speter        output[j + 3] = (unsigned char)((k >> 24) & 0xff);
380251876Speter    }
381251876Speter}
382251876Speter
383251876Speter/* Decodes input (unsigned char) into output (apr_uint32_t). Assumes len is
384251876Speter * a multiple of 4.
385251876Speter */
386251876Speterstatic void Decode(apr_uint32_t *output, const unsigned char *input,
387251876Speter                   unsigned int len)
388251876Speter{
389251876Speter    unsigned int i, j;
390251876Speter
391251876Speter    for (i = 0, j = 0; j < len; i++, j += 4)
392251876Speter        output[i] = ((apr_uint32_t)input[j])             |
393251876Speter                    (((apr_uint32_t)input[j + 1]) << 8)  |
394251876Speter                    (((apr_uint32_t)input[j + 2]) << 16) |
395251876Speter                    (((apr_uint32_t)input[j + 3]) << 24);
396251876Speter}
397251876Speter
398251876Speter#if APR_CHARSET_EBCDIC
399251876SpeterAPU_DECLARE(apr_status_t) apr_MD4InitEBCDIC(apr_xlate_t *xlate)
400251876Speter{
401251876Speter    xlate_ebcdic_to_ascii = xlate;
402251876Speter    return APR_SUCCESS;
403251876Speter}
404251876Speter#endif
405