~ubuntu-branches/ubuntu/precise/pdns/precise

« back to all changes in this revision

Viewing changes to pdns/ext/polarssl/library/md4.c

  • Committer: Package Import Robot
  • Author(s): Jean-Louis Dupond
  • Date: 2012-02-14 01:36:30 UTC
  • mfrom: (1.1.8) (12.1.12 sid)
  • Revision ID: package-import@ubuntu.com-20120214013630-z26d5ugoxnau5ok3
Tags: 3.0-1.1ubuntu1
* Merge from Debian testing. (LP: #931133)  Remaining changes:
  - debian/rules: Fix FTBFS with multiarch libmysqlclient.
  - debian/control: Build-depend on libtdb-dev rather than tdb-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  RFC 1186/1320 compliant MD4 implementation
 
3
 *
 
4
 *  Copyright (C) 2006-2010, Paul Bakker <polarssl_maintainer at polarssl.org>
 
5
 *  All rights reserved.
 
6
 *
 
7
 *  This program is free software; you can redistribute it and/or modify
 
8
 *  it under the terms of the GNU General Public License as published by
 
9
 *  the Free Software Foundation; either version 2 of the License, or
 
10
 *  (at your option) any later version.
 
11
 *
 
12
 *  This program is distributed in the hope that it will be useful,
 
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 *  GNU General Public License for more details.
 
16
 *
 
17
 *  You should have received a copy of the GNU General Public License along
 
18
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 
19
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
/*
 
22
 *  The MD4 algorithm was designed by Ron Rivest in 1990.
 
23
 *
 
24
 *  http://www.ietf.org/rfc/rfc1186.txt
 
25
 *  http://www.ietf.org/rfc/rfc1320.txt
 
26
 */
 
27
 
 
28
#include "polarssl/config.h"
 
29
 
 
30
#if defined(POLARSSL_MD4_C)
 
31
 
 
32
#include "polarssl/md4.h"
 
33
 
 
34
#include <string.h>
 
35
#include <stdio.h>
 
36
 
 
37
/*
 
38
 * 32-bit integer manipulation macros (little endian)
 
39
 */
 
40
#ifndef GET_ULONG_LE
 
41
#define GET_ULONG_LE(n,b,i)                             \
 
42
{                                                       \
 
43
    (n) = ( (unsigned long) (b)[(i)    ]       )        \
 
44
        | ( (unsigned long) (b)[(i) + 1] <<  8 )        \
 
45
        | ( (unsigned long) (b)[(i) + 2] << 16 )        \
 
46
        | ( (unsigned long) (b)[(i) + 3] << 24 );       \
 
47
}
 
48
#endif
 
49
 
 
50
#ifndef PUT_ULONG_LE
 
51
#define PUT_ULONG_LE(n,b,i)                             \
 
52
{                                                       \
 
53
    (b)[(i)    ] = (unsigned char) ( (n)       );       \
 
54
    (b)[(i) + 1] = (unsigned char) ( (n) >>  8 );       \
 
55
    (b)[(i) + 2] = (unsigned char) ( (n) >> 16 );       \
 
56
    (b)[(i) + 3] = (unsigned char) ( (n) >> 24 );       \
 
57
}
 
58
#endif
 
59
 
 
60
/*
 
61
 * MD4 context setup
 
62
 */
 
63
void md4_starts( md4_context *ctx )
 
64
{
 
65
    ctx->total[0] = 0;
 
66
    ctx->total[1] = 0;
 
67
 
 
68
    ctx->state[0] = 0x67452301;
 
69
    ctx->state[1] = 0xEFCDAB89;
 
70
    ctx->state[2] = 0x98BADCFE;
 
71
    ctx->state[3] = 0x10325476;
 
72
}
 
73
 
 
74
static void md4_process( md4_context *ctx, const unsigned char data[64] )
 
75
{
 
76
    unsigned long X[16], A, B, C, D;
 
77
 
 
78
    GET_ULONG_LE( X[ 0], data,  0 );
 
79
    GET_ULONG_LE( X[ 1], data,  4 );
 
80
    GET_ULONG_LE( X[ 2], data,  8 );
 
81
    GET_ULONG_LE( X[ 3], data, 12 );
 
82
    GET_ULONG_LE( X[ 4], data, 16 );
 
83
    GET_ULONG_LE( X[ 5], data, 20 );
 
84
    GET_ULONG_LE( X[ 6], data, 24 );
 
85
    GET_ULONG_LE( X[ 7], data, 28 );
 
86
    GET_ULONG_LE( X[ 8], data, 32 );
 
87
    GET_ULONG_LE( X[ 9], data, 36 );
 
88
    GET_ULONG_LE( X[10], data, 40 );
 
89
    GET_ULONG_LE( X[11], data, 44 );
 
90
    GET_ULONG_LE( X[12], data, 48 );
 
91
    GET_ULONG_LE( X[13], data, 52 );
 
92
    GET_ULONG_LE( X[14], data, 56 );
 
93
    GET_ULONG_LE( X[15], data, 60 );
 
94
 
 
95
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
 
96
 
 
97
    A = ctx->state[0];
 
98
    B = ctx->state[1];
 
99
    C = ctx->state[2];
 
100
    D = ctx->state[3];
 
101
 
 
102
#define F(x, y, z) ((x & y) | ((~x) & z))
 
103
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
 
104
 
 
105
    P( A, B, C, D, X[ 0],  3 );
 
106
    P( D, A, B, C, X[ 1],  7 );
 
107
    P( C, D, A, B, X[ 2], 11 );
 
108
    P( B, C, D, A, X[ 3], 19 );
 
109
    P( A, B, C, D, X[ 4],  3 );
 
110
    P( D, A, B, C, X[ 5],  7 );
 
111
    P( C, D, A, B, X[ 6], 11 );
 
112
    P( B, C, D, A, X[ 7], 19 );
 
113
    P( A, B, C, D, X[ 8],  3 );
 
114
    P( D, A, B, C, X[ 9],  7 );
 
115
    P( C, D, A, B, X[10], 11 );
 
116
    P( B, C, D, A, X[11], 19 );
 
117
    P( A, B, C, D, X[12],  3 );
 
118
    P( D, A, B, C, X[13],  7 );
 
119
    P( C, D, A, B, X[14], 11 );
 
120
    P( B, C, D, A, X[15], 19 );
 
121
 
 
122
#undef P
 
123
#undef F
 
124
 
 
125
#define F(x,y,z) ((x & y) | (x & z) | (y & z))
 
126
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
 
127
 
 
128
    P( A, B, C, D, X[ 0],  3 );
 
129
    P( D, A, B, C, X[ 4],  5 );
 
130
    P( C, D, A, B, X[ 8],  9 );
 
131
    P( B, C, D, A, X[12], 13 );
 
132
    P( A, B, C, D, X[ 1],  3 );
 
133
    P( D, A, B, C, X[ 5],  5 );
 
134
    P( C, D, A, B, X[ 9],  9 );
 
135
    P( B, C, D, A, X[13], 13 );
 
136
    P( A, B, C, D, X[ 2],  3 );
 
137
    P( D, A, B, C, X[ 6],  5 );
 
138
    P( C, D, A, B, X[10],  9 );
 
139
    P( B, C, D, A, X[14], 13 );
 
140
    P( A, B, C, D, X[ 3],  3 );
 
141
    P( D, A, B, C, X[ 7],  5 );
 
142
    P( C, D, A, B, X[11],  9 );
 
143
    P( B, C, D, A, X[15], 13 );
 
144
 
 
145
#undef P
 
146
#undef F
 
147
 
 
148
#define F(x,y,z) (x ^ y ^ z)
 
149
#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
 
150
 
 
151
    P( A, B, C, D, X[ 0],  3 );
 
152
    P( D, A, B, C, X[ 8],  9 );
 
153
    P( C, D, A, B, X[ 4], 11 );
 
154
    P( B, C, D, A, X[12], 15 );
 
155
    P( A, B, C, D, X[ 2],  3 );
 
156
    P( D, A, B, C, X[10],  9 );
 
157
    P( C, D, A, B, X[ 6], 11 );
 
158
    P( B, C, D, A, X[14], 15 );
 
159
    P( A, B, C, D, X[ 1],  3 );
 
160
    P( D, A, B, C, X[ 9],  9 );
 
161
    P( C, D, A, B, X[ 5], 11 );
 
162
    P( B, C, D, A, X[13], 15 );
 
163
    P( A, B, C, D, X[ 3],  3 );
 
164
    P( D, A, B, C, X[11],  9 );
 
165
    P( C, D, A, B, X[ 7], 11 );
 
166
    P( B, C, D, A, X[15], 15 );
 
167
 
 
168
#undef F
 
169
#undef P
 
170
 
 
171
    ctx->state[0] += A;
 
172
    ctx->state[1] += B;
 
173
    ctx->state[2] += C;
 
174
    ctx->state[3] += D;
 
175
}
 
176
 
 
177
/*
 
178
 * MD4 process buffer
 
179
 */
 
180
void md4_update( md4_context *ctx, const unsigned char *input, int ilen )
 
181
{
 
182
    int fill;
 
183
    unsigned long left;
 
184
 
 
185
    if( ilen <= 0 )
 
186
        return;
 
187
 
 
188
    left = ctx->total[0] & 0x3F;
 
189
    fill = 64 - left;
 
190
 
 
191
    ctx->total[0] += ilen;
 
192
    ctx->total[0] &= 0xFFFFFFFF;
 
193
 
 
194
    if( ctx->total[0] < (unsigned long) ilen )
 
195
        ctx->total[1]++;
 
196
 
 
197
    if( left && ilen >= fill )
 
198
    {
 
199
        memcpy( (void *) (ctx->buffer + left),
 
200
                (void *) input, fill );
 
201
        md4_process( ctx, ctx->buffer );
 
202
        input += fill;
 
203
        ilen  -= fill;
 
204
        left = 0;
 
205
    }
 
206
 
 
207
    while( ilen >= 64 )
 
208
    {
 
209
        md4_process( ctx, input );
 
210
        input += 64;
 
211
        ilen  -= 64;
 
212
    }
 
213
 
 
214
    if( ilen > 0 )
 
215
    {
 
216
        memcpy( (void *) (ctx->buffer + left),
 
217
                (void *) input, ilen );
 
218
    }
 
219
}
 
220
 
 
221
static const unsigned char md4_padding[64] =
 
222
{
 
223
 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
224
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
225
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 
226
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 
227
};
 
228
 
 
229
/*
 
230
 * MD4 final digest
 
231
 */
 
232
void md4_finish( md4_context *ctx, unsigned char output[16] )
 
233
{
 
234
    unsigned long last, padn;
 
235
    unsigned long high, low;
 
236
    unsigned char msglen[8];
 
237
 
 
238
    high = ( ctx->total[0] >> 29 )
 
239
         | ( ctx->total[1] <<  3 );
 
240
    low  = ( ctx->total[0] <<  3 );
 
241
 
 
242
    PUT_ULONG_LE( low,  msglen, 0 );
 
243
    PUT_ULONG_LE( high, msglen, 4 );
 
244
 
 
245
    last = ctx->total[0] & 0x3F;
 
246
    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
 
247
 
 
248
    md4_update( ctx, (unsigned char *) md4_padding, padn );
 
249
    md4_update( ctx, msglen, 8 );
 
250
 
 
251
    PUT_ULONG_LE( ctx->state[0], output,  0 );
 
252
    PUT_ULONG_LE( ctx->state[1], output,  4 );
 
253
    PUT_ULONG_LE( ctx->state[2], output,  8 );
 
254
    PUT_ULONG_LE( ctx->state[3], output, 12 );
 
255
}
 
256
 
 
257
/*
 
258
 * output = MD4( input buffer )
 
259
 */
 
260
void md4( const unsigned char *input, int ilen, unsigned char output[16] )
 
261
{
 
262
    md4_context ctx;
 
263
 
 
264
    md4_starts( &ctx );
 
265
    md4_update( &ctx, input, ilen );
 
266
    md4_finish( &ctx, output );
 
267
 
 
268
    memset( &ctx, 0, sizeof( md4_context ) );
 
269
}
 
270
 
 
271
/*
 
272
 * output = MD4( file contents )
 
273
 */
 
274
int md4_file( const char *path, unsigned char output[16] )
 
275
{
 
276
    FILE *f;
 
277
    size_t n;
 
278
    md4_context ctx;
 
279
    unsigned char buf[1024];
 
280
 
 
281
    if( ( f = fopen( path, "rb" ) ) == NULL )
 
282
        return( 1 );
 
283
 
 
284
    md4_starts( &ctx );
 
285
 
 
286
    while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
 
287
        md4_update( &ctx, buf, (int) n );
 
288
 
 
289
    md4_finish( &ctx, output );
 
290
 
 
291
    memset( &ctx, 0, sizeof( md4_context ) );
 
292
 
 
293
    if( ferror( f ) != 0 )
 
294
    {
 
295
        fclose( f );
 
296
        return( 2 );
 
297
    }
 
298
 
 
299
    fclose( f );
 
300
    return( 0 );
 
301
}
 
302
 
 
303
/*
 
304
 * MD4 HMAC context setup
 
305
 */
 
306
void md4_hmac_starts( md4_context *ctx, const unsigned char *key, int keylen )
 
307
{
 
308
    int i;
 
309
    unsigned char sum[16];
 
310
 
 
311
    if( keylen > 64 )
 
312
    {
 
313
        md4( key, keylen, sum );
 
314
        keylen = 16;
 
315
        key = sum;
 
316
    }
 
317
 
 
318
    memset( ctx->ipad, 0x36, 64 );
 
319
    memset( ctx->opad, 0x5C, 64 );
 
320
 
 
321
    for( i = 0; i < keylen; i++ )
 
322
    {
 
323
        ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
 
324
        ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
 
325
    }
 
326
 
 
327
    md4_starts( ctx );
 
328
    md4_update( ctx, ctx->ipad, 64 );
 
329
 
 
330
    memset( sum, 0, sizeof( sum ) );
 
331
}
 
332
 
 
333
/*
 
334
 * MD4 HMAC process buffer
 
335
 */
 
336
void md4_hmac_update( md4_context *ctx, const unsigned char *input, int ilen )
 
337
{
 
338
    md4_update( ctx, input, ilen );
 
339
}
 
340
 
 
341
/*
 
342
 * MD4 HMAC final digest
 
343
 */
 
344
void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
 
345
{
 
346
    unsigned char tmpbuf[16];
 
347
 
 
348
    md4_finish( ctx, tmpbuf );
 
349
    md4_starts( ctx );
 
350
    md4_update( ctx, ctx->opad, 64 );
 
351
    md4_update( ctx, tmpbuf, 16 );
 
352
    md4_finish( ctx, output );
 
353
 
 
354
    memset( tmpbuf, 0, sizeof( tmpbuf ) );
 
355
}
 
356
 
 
357
/*
 
358
 * MD4 HMAC context reset
 
359
 */
 
360
void md4_hmac_reset( md4_context *ctx )
 
361
{
 
362
    md4_starts( ctx );
 
363
    md4_update( ctx, ctx->ipad, 64 );
 
364
}
 
365
 
 
366
/*
 
367
 * output = HMAC-MD4( hmac key, input buffer )
 
368
 */
 
369
void md4_hmac( const unsigned char *key, int keylen,
 
370
               const unsigned char *input, int ilen,
 
371
               unsigned char output[16] )
 
372
{
 
373
    md4_context ctx;
 
374
 
 
375
    md4_hmac_starts( &ctx, key, keylen );
 
376
    md4_hmac_update( &ctx, input, ilen );
 
377
    md4_hmac_finish( &ctx, output );
 
378
 
 
379
    memset( &ctx, 0, sizeof( md4_context ) );
 
380
}
 
381
 
 
382
#if defined(POLARSSL_SELF_TEST)
 
383
 
 
384
/*
 
385
 * RFC 1320 test vectors
 
386
 */
 
387
static const char md4_test_str[7][81] =
 
388
{
 
389
    { "" }, 
 
390
    { "a" },
 
391
    { "abc" },
 
392
    { "message digest" },
 
393
    { "abcdefghijklmnopqrstuvwxyz" },
 
394
    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
 
395
    { "12345678901234567890123456789012345678901234567890123456789012" \
 
396
      "345678901234567890" }
 
397
};
 
398
 
 
399
static const unsigned char md4_test_sum[7][16] =
 
400
{
 
401
    { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
 
402
      0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
 
403
    { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
 
404
      0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
 
405
    { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
 
406
      0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
 
407
    { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
 
408
      0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
 
409
    { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
 
410
      0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
 
411
    { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
 
412
      0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
 
413
    { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
 
414
      0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
 
415
};
 
416
 
 
417
/*
 
418
 * Checkup routine
 
419
 */
 
420
int md4_self_test( int verbose )
 
421
{
 
422
    int i;
 
423
    unsigned char md4sum[16];
 
424
 
 
425
    for( i = 0; i < 7; i++ )
 
426
    {
 
427
        if( verbose != 0 )
 
428
            printf( "  MD4 test #%d: ", i + 1 );
 
429
 
 
430
        md4( (unsigned char *) md4_test_str[i],
 
431
             strlen( md4_test_str[i] ), md4sum );
 
432
 
 
433
        if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
 
434
        {
 
435
            if( verbose != 0 )
 
436
                printf( "failed\n" );
 
437
 
 
438
            return( 1 );
 
439
        }
 
440
 
 
441
        if( verbose != 0 )
 
442
            printf( "passed\n" );
 
443
    }
 
444
 
 
445
    if( verbose != 0 )
 
446
        printf( "\n" );
 
447
 
 
448
    return( 0 );
 
449
}
 
450
 
 
451
#endif
 
452
 
 
453
#endif