~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to srclib/apr-util/crypto/apr_md4.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
 
2
 * applicable.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 *
 
16
 * This is derived from material copyright RSA Data Security, Inc.
 
17
 * Their notice is reproduced below in its entirety.
 
18
 *
 
19
 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
 
20
 * rights reserved.
 
21
 *
 
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
 
25
 * or this function.
 
26
 *
 
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.
 
31
 *
 
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.
 
36
 *
 
37
 * These notices must be retained in any copies of any part of this
 
38
 * documentation and/or software.
 
39
 */
 
40
 
 
41
#include "apr_strings.h"
 
42
#include "apr_md4.h"
 
43
#include "apr_lib.h"
 
44
 
 
45
#if APR_HAVE_STRING_H
 
46
#include <string.h>
 
47
#endif
 
48
#if APR_HAVE_UNISTD_H
 
49
#include <unistd.h>
 
50
#endif
 
51
 
 
52
/* Constants for MD4Transform routine.
 
53
 */
 
54
 
 
55
#define S11 3
 
56
#define S12 7
 
57
#define S13 11
 
58
#define S14 19
 
59
#define S21 3
 
60
#define S22 5
 
61
#define S23 9
 
62
#define S24 13
 
63
#define S31 3
 
64
#define S32 9
 
65
#define S33 11
 
66
#define S34 15
 
67
 
 
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,
 
70
                   unsigned int len);
 
71
static void Decode(apr_uint32_t *output, const unsigned char *input,
 
72
                   unsigned int len);
 
73
 
 
74
static unsigned char PADDING[64] =
 
75
{
 
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
 
79
};
 
80
 
 
81
#if APR_CHARSET_EBCDIC
 
82
static apr_xlate_t *xlate_ebcdic_to_ascii; /* used in apr_md4_encode() */
 
83
#endif
 
84
 
 
85
/* F, G and I are basic MD4 functions.
 
86
 */
 
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))
 
90
 
 
91
/* ROTATE_LEFT rotates x left n bits.
 
92
 */
 
93
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 
94
 
 
95
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
 
96
/* Rotation is separate from addition to prevent recomputation */
 
97
 
 
98
#define FF(a, b, c, d, x, s) { \
 
99
  (a) += F ((b), (c), (d)) + (x); \
 
100
  (a) = ROTATE_LEFT ((a), (s)); \
 
101
  }
 
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)); \
 
105
  }
 
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)); \
 
109
  }
 
110
 
 
111
/* MD4 initialization. Begins an MD4 operation, writing a new context.
 
112
 */
 
113
APU_DECLARE(apr_status_t) apr_md4_init(apr_md4_ctx_t *context)
 
114
{
 
115
    context->count[0] = context->count[1] = 0;
 
116
 
 
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;
 
122
    
 
123
#if APR_HAS_XLATE
 
124
    context->xlate = NULL;
 
125
#endif
 
126
 
 
127
    return APR_SUCCESS;
 
128
}
 
129
 
 
130
#if APR_HAS_XLATE
 
131
/* MD4 translation setup.  Provides the APR translation handle
 
132
 * to be used for translating the content before calculating the
 
133
 * digest.
 
134
 */
 
135
APU_DECLARE(apr_status_t) apr_md4_set_xlate(apr_md4_ctx_t *context, 
 
136
                                            apr_xlate_t *xlate)
 
137
{
 
138
    apr_status_t rv;
 
139
    int is_sb;
 
140
 
 
141
    /* TODO: remove the single-byte-only restriction from this code
 
142
     */
 
143
    rv = apr_xlate_sb_get(xlate, &is_sb);
 
144
    if (rv != APR_SUCCESS) {
 
145
        return rv;
 
146
    }
 
147
    if (!is_sb) {
 
148
        return APR_EINVAL;
 
149
    }
 
150
    context->xlate = xlate;
 
151
    return APR_SUCCESS;
 
152
}
 
153
#endif /* APR_HAS_XLATE */
 
154
 
 
155
/* MD4 block update operation. Continues an MD4 message-digest
 
156
 * operation, processing another message block, and updating the
 
157
 * context.
 
158
 */
 
159
APU_DECLARE(apr_status_t) apr_md4_update(apr_md4_ctx_t *context,
 
160
                                         const unsigned char *input,
 
161
                                         apr_size_t inputLen)
 
162
{
 
163
    unsigned int i, idx, partLen;
 
164
#if APR_HAS_XLATE
 
165
    apr_size_t inbytes_left, outbytes_left;
 
166
#endif
 
167
 
 
168
    /* Compute number of bytes mod 64 */
 
169
    idx = (unsigned int)((context->count[0] >> 3) & 0x3F);
 
170
 
 
171
    /* Update number of bits */
 
172
    if ((context->count[0] += ((apr_uint32_t)inputLen << 3)) 
 
173
            < ((apr_uint32_t)inputLen << 3))
 
174
        context->count[1]++;
 
175
    context->count[1] += (apr_uint32_t)inputLen >> 29;
 
176
 
 
177
    partLen = 64 - idx;
 
178
 
 
179
    /* Transform as many times as possible. */
 
180
#if !APR_HAS_XLATE
 
181
    if (inputLen >= partLen) {
 
182
        memcpy(&context->buffer[idx], input, partLen);
 
183
        MD4Transform(context->state, context->buffer);
 
184
 
 
185
        for (i = partLen; i + 63 < inputLen; i += 64)
 
186
            MD4Transform(context->state, &input[i]);
 
187
 
 
188
        idx = 0;
 
189
    }
 
190
    else
 
191
        i = 0;
 
192
 
 
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, 
 
200
                                  &inbytes_left, 
 
201
                                  (char *)&context->buffer[idx], 
 
202
                                  &outbytes_left);
 
203
        }
 
204
        else {
 
205
            memcpy(&context->buffer[idx], input, partLen);
 
206
        }
 
207
        MD4Transform(context->state, context->buffer);
 
208
 
 
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], 
 
214
                                      &inbytes_left,
 
215
                                      (char *)inp_tmp, &outbytes_left);
 
216
                MD4Transform(context->state, inp_tmp);
 
217
            }
 
218
            else {
 
219
                MD4Transform(context->state, &input[i]);
 
220
            }
 
221
        }
 
222
 
 
223
        idx = 0;
 
224
    }
 
225
    else
 
226
        i = 0;
 
227
 
 
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], 
 
233
                              &outbytes_left);
 
234
    }
 
235
    else {
 
236
        memcpy(&context->buffer[idx], &input[i], inputLen - i);
 
237
    }
 
238
#endif /*APR_HAS_XLATE*/
 
239
    return APR_SUCCESS;
 
240
}
 
241
 
 
242
/* MD4 finalization. Ends an MD4 message-digest operation, writing the
 
243
 * the message digest and zeroizing the context.
 
244
 */
 
245
APU_DECLARE(apr_status_t) apr_md4_final(
 
246
                                    unsigned char digest[APR_MD4_DIGESTSIZE],
 
247
                                    apr_md4_ctx_t *context)
 
248
{
 
249
    unsigned char bits[8];
 
250
    unsigned int idx, padLen;
 
251
 
 
252
    /* Save number of bits */
 
253
    Encode(bits, context->count, 8);
 
254
 
 
255
#if APR_HAS_XLATE
 
256
    /* apr_md4_update() should not translate for this final round. */
 
257
    context->xlate = NULL;
 
258
#endif /*APR_HAS_XLATE*/
 
259
 
 
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);
 
264
 
 
265
    /* Append length (before padding) */
 
266
    apr_md4_update(context, bits, 8);
 
267
 
 
268
    /* Store state in digest */
 
269
    Encode(digest, context->state, APR_MD4_DIGESTSIZE);
 
270
 
 
271
    /* Zeroize sensitive information. */
 
272
    memset(context, 0, sizeof(*context));
 
273
    
 
274
    return APR_SUCCESS;
 
275
}
 
276
 
 
277
/* MD4 computation in one step (init, update, final)
 
278
 */
 
279
APU_DECLARE(apr_status_t) apr_md4(unsigned char digest[APR_MD4_DIGESTSIZE],
 
280
                                  const unsigned char *input,
 
281
                                  apr_size_t inputLen)
 
282
{
 
283
    apr_md4_ctx_t ctx;
 
284
    apr_status_t rv;
 
285
 
 
286
    apr_md4_init(&ctx);
 
287
 
 
288
    if ((rv = apr_md4_update(&ctx, input, inputLen)) != APR_SUCCESS)
 
289
        return rv;
 
290
 
 
291
    return apr_md4_final(digest, &ctx);
 
292
}
 
293
 
 
294
/* MD4 basic transformation. Transforms state based on block. */
 
295
static void MD4Transform(apr_uint32_t state[4], const unsigned char block[64])
 
296
{
 
297
    apr_uint32_t a = state[0], b = state[1], c = state[2], d = state[3],
 
298
                 x[APR_MD4_DIGESTSIZE];
 
299
 
 
300
    Decode(x, block, 64);
 
301
 
 
302
    /* Round 1 */
 
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 */
 
319
 
 
320
    /* Round 2 */
 
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 */
 
337
 
 
338
    /* Round 3 */
 
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 */
 
355
 
 
356
    state[0] += a;
 
357
    state[1] += b;
 
358
    state[2] += c;
 
359
    state[3] += d;
 
360
    
 
361
    /* Zeroize sensitive information. */
 
362
    memset(x, 0, sizeof(x));
 
363
}
 
364
 
 
365
/* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is
 
366
 * a multiple of 4.
 
367
 */
 
368
static void Encode(unsigned char *output, const apr_uint32_t *input,
 
369
                   unsigned int len)
 
370
{
 
371
    unsigned int i, j;
 
372
    apr_uint32_t k;
 
373
 
 
374
    for (i = 0, j = 0; j < len; i++, j += 4) {
 
375
        k = input[i];
 
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);
 
380
    }
 
381
}
 
382
 
 
383
/* Decodes input (unsigned char) into output (apr_uint32_t). Assumes len is
 
384
 * a multiple of 4.
 
385
 */
 
386
static void Decode(apr_uint32_t *output, const unsigned char *input,
 
387
                   unsigned int len)
 
388
{
 
389
    unsigned int i, j;
 
390
 
 
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);
 
396
}
 
397
 
 
398
#if APR_CHARSET_EBCDIC
 
399
APU_DECLARE(apr_status_t) apr_MD4InitEBCDIC(apr_xlate_t *xlate)
 
400
{
 
401
    xlate_ebcdic_to_ascii = xlate;
 
402
    return APR_SUCCESS;
 
403
}
 
404
#endif