7bb31a8e0083450473918b2acc622af72e60b7ad
[libgcrypt.git] / cipher / md4.c
1 /* md4.c - MD4 Message-Digest Algorithm
2  * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  *
20  * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
21  * using a public domain md4 implementation with the following comments:
22  *
23  * Modified by Wei Dai from Andrew M. Kuchling's md4.c
24  * The original code and all modifications are in the public domain.
25  *
26  * This is the original introductory comment:
27  *
28  *  md4.c : MD4 hash algorithm.
29  *
30  * Part of the Python Cryptography Toolkit, version 1.1
31  *
32  * Distribute and use freely; there are no restrictions on further
33  * dissemination and usage except those imposed by the laws of your
34  * country of residence.
35  *
36  */
37
38 /* MD4 test suite:
39  * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
40  * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
41  * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
42  * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
43  * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
44  * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
45  * 043f8582f241db351ce627e153e7f0e4
46  * MD4 ("123456789012345678901234567890123456789012345678901234567890123456
47  * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
48  */
49
50 #include <config.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <assert.h>
55 #include "g10lib.h"
56 #include "memory.h"
57 #include "dynload.h"
58
59 #include "bithelp.h"
60
61
62 typedef struct {
63     u32 A,B,C,D;          /* chaining variables */
64     u32  nblocks;
65     byte buf[64];
66     int  count;
67 } MD4_CONTEXT;
68
69
70 static void
71 md4_init( MD4_CONTEXT *ctx )
72 {
73     ctx->A = 0x67452301;
74     ctx->B = 0xefcdab89;
75     ctx->C = 0x98badcfe;
76     ctx->D = 0x10325476;
77
78     ctx->nblocks = 0;
79     ctx->count = 0;
80 }
81
82 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
83 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
84 #define H(x, y, z) ((x) ^ (y) ^ (z))
85
86
87 /****************
88  * transform 64 bytes
89  */
90 static void
91 transform( MD4_CONTEXT *ctx, byte *data )
92 {
93     u32 in[16];
94     register u32 A = ctx->A;
95     register u32 B = ctx->B;
96     register u32 C = ctx->C;
97     register u32 D = ctx->D;
98
99 #ifdef BIG_ENDIAN_HOST
100     { int i;
101       byte *p2, *p1;
102       for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 ) {
103         p2[3] = *p1++;
104         p2[2] = *p1++;
105         p2[1] = *p1++;
106         p2[0] = *p1++;
107       }
108     }
109 #else
110     memcpy (in, data, 64);
111 #endif
112
113     /* Round 1.  */
114 #define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
115           function(A,B,C,D, 0, 3);
116           function(D,A,B,C, 1, 7);
117           function(C,D,A,B, 2,11);
118           function(B,C,D,A, 3,19);
119           function(A,B,C,D, 4, 3);
120           function(D,A,B,C, 5, 7);
121           function(C,D,A,B, 6,11);
122           function(B,C,D,A, 7,19);
123           function(A,B,C,D, 8, 3);
124           function(D,A,B,C, 9, 7);
125           function(C,D,A,B,10,11);
126           function(B,C,D,A,11,19);
127           function(A,B,C,D,12, 3);
128           function(D,A,B,C,13, 7);
129           function(C,D,A,B,14,11);
130           function(B,C,D,A,15,19);
131
132 #undef function
133
134     /* Round 2.  */
135 #define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
136
137           function(A,B,C,D, 0, 3);
138           function(D,A,B,C, 4, 5);
139           function(C,D,A,B, 8, 9);
140           function(B,C,D,A,12,13);
141           function(A,B,C,D, 1, 3);
142           function(D,A,B,C, 5, 5);
143           function(C,D,A,B, 9, 9);
144           function(B,C,D,A,13,13);
145           function(A,B,C,D, 2, 3);
146           function(D,A,B,C, 6, 5);
147           function(C,D,A,B,10, 9);
148           function(B,C,D,A,14,13);
149           function(A,B,C,D, 3, 3);
150           function(D,A,B,C, 7, 5);
151           function(C,D,A,B,11, 9);
152           function(B,C,D,A,15,13);
153
154 #undef function
155
156     /* Round 3.  */
157 #define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
158
159           function(A,B,C,D, 0, 3);
160           function(D,A,B,C, 8, 9);
161           function(C,D,A,B, 4,11);
162           function(B,C,D,A,12,15);
163           function(A,B,C,D, 2, 3);
164           function(D,A,B,C,10, 9);
165           function(C,D,A,B, 6,11);
166           function(B,C,D,A,14,15);
167           function(A,B,C,D, 1, 3);
168           function(D,A,B,C, 9, 9);
169           function(C,D,A,B, 5,11);
170           function(B,C,D,A,13,15);
171           function(A,B,C,D, 3, 3);
172           function(D,A,B,C,11, 9);
173           function(C,D,A,B, 7,11);
174           function(B,C,D,A,15,15);
175
176
177     /* Put checksum in context given as argument.  */
178     ctx->A += A;
179     ctx->B += B;
180     ctx->C += C;
181     ctx->D += D;
182 }
183
184
185
186 /* The routine updates the message-digest context to
187  * account for the presence of each of the characters inBuf[0..inLen-1]
188  * in the message whose digest is being computed.
189  */
190 static void
191 md4_write( MD4_CONTEXT *hd, byte *inbuf, size_t inlen)
192 {
193     if( hd->count == 64 ) { /* flush the buffer */
194         transform( hd, hd->buf );
195         _gcry_burn_stack (80+6*sizeof(void*));
196         hd->count = 0;
197         hd->nblocks++;
198     }
199     if( !inbuf )
200         return;
201     if( hd->count ) {
202         for( ; inlen && hd->count < 64; inlen-- )
203             hd->buf[hd->count++] = *inbuf++;
204         md4_write( hd, NULL, 0 );
205         if( !inlen )
206             return;
207     }
208     _gcry_burn_stack (80+6*sizeof(void*));
209
210     while( inlen >= 64 ) {
211         transform( hd, inbuf );
212         hd->count = 0;
213         hd->nblocks++;
214         inlen -= 64;
215         inbuf += 64;
216     }
217     for( ; inlen && hd->count < 64; inlen-- )
218         hd->buf[hd->count++] = *inbuf++;
219
220 }
221
222
223
224 /* The routine final terminates the message-digest computation and
225  * ends with the desired message digest in mdContext->digest[0...15].
226  * The handle is prepared for a new MD4 cycle.
227  * Returns 16 bytes representing the digest.
228  */
229
230 static void
231 md4_final( MD4_CONTEXT *hd )
232 {
233     u32 t, msb, lsb;
234     byte *p;
235
236     md4_write(hd, NULL, 0); /* flush */;
237
238     t = hd->nblocks;
239     /* multiply by 64 to make a byte count */
240     lsb = t << 6;
241     msb = t >> 26;
242     /* add the count */
243     t = lsb;
244     if( (lsb += hd->count) < t )
245         msb++;
246     /* multiply by 8 to make a bit count */
247     t = lsb;
248     lsb <<= 3;
249     msb <<= 3;
250     msb |= t >> 29;
251
252     if( hd->count < 56 ) { /* enough room */
253         hd->buf[hd->count++] = 0x80; /* pad */
254         while( hd->count < 56 )
255             hd->buf[hd->count++] = 0;  /* pad */
256     }
257     else { /* need one extra block */
258         hd->buf[hd->count++] = 0x80; /* pad character */
259         while( hd->count < 64 )
260             hd->buf[hd->count++] = 0;
261         md4_write(hd, NULL, 0);  /* flush */;
262         memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
263     }
264     /* append the 64 bit count */
265     hd->buf[56] = lsb      ;
266     hd->buf[57] = lsb >>  8;
267     hd->buf[58] = lsb >> 16;
268     hd->buf[59] = lsb >> 24;
269     hd->buf[60] = msb      ;
270     hd->buf[61] = msb >>  8;
271     hd->buf[62] = msb >> 16;
272     hd->buf[63] = msb >> 24;
273     transform( hd, hd->buf );
274     _gcry_burn_stack (80+6*sizeof(void*));
275
276     p = hd->buf;
277   #ifdef BIG_ENDIAN_HOST
278     #define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
279                       *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
280   #else /* little endian */
281     #define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
282   #endif
283     X(A);
284     X(B);
285     X(C);
286     X(D);
287   #undef X
288
289 }
290
291 static byte *
292 md4_read( MD4_CONTEXT *hd )
293 {
294     return hd->buf;
295 }
296
297 /****************
298  * Return some information about the algorithm.  We need algo here to
299  * distinguish different flavors of the algorithm.
300  * Returns: A pointer to string describing the algorithm or NULL if
301  *          the ALGO is invalid.
302  */
303 static const char *
304 md4_get_info( int algo, size_t *contextsize,
305                byte **r_asnoid, int *r_asnlen, int *r_mdlen,
306                void (**r_init)( void *c ),
307                void (**r_write)( void *c, byte *buf, size_t nbytes ),
308                void (**r_final)( void *c ),
309                byte *(**r_read)( void *c )
310              )
311 {
312     static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
313                     { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
314                       0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
315
316     if( algo != 301 )
317         return NULL;
318
319     *contextsize = sizeof(MD4_CONTEXT);
320     *r_asnoid = asn;
321     *r_asnlen = DIM(asn);
322     *r_mdlen = 16;
323     *(void  (**)(MD4_CONTEXT *))r_init                 = md4_init;
324     *(void  (**)(MD4_CONTEXT *, byte*, size_t))r_write = md4_write;
325     *(void  (**)(MD4_CONTEXT *))r_final                = md4_final;
326     *(byte *(**)(MD4_CONTEXT *))r_read                 = md4_read;
327
328     return "MD4";
329 }
330
331
332 #ifndef IS_MODULE
333 static
334 #endif
335 const char * const gnupgext_version = "MD4 ($Revision$)";
336
337 static struct {
338     int class;
339     int version;
340     int  value;
341     void (*func)(void);
342 } func_table[] = {
343     { 10, 1, 0, (void(*)(void))md4_get_info },
344     { 11, 1, 301 },
345 };
346
347
348 #ifndef IS_MODULE
349 static
350 #endif
351 void *
352 gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
353 {
354     void *ret;
355     int i = *sequence;
356
357     do {
358         if( i >= DIM(func_table) || i < 0 )
359             return NULL;
360         *class = func_table[i].class;
361         *vers  = func_table[i].version;
362         switch( *class ) {
363           case 11: case 21: case 31: ret = &func_table[i].value; break;
364           default:                   ret = func_table[i].func; break;
365         }
366         i++;
367     } while( what && what != *class );
368
369     *sequence = i;
370     return ret;
371 }
372
373
374
375
376 #ifndef IS_MODULE
377 void
378 _gcry_md4_constructor(void)
379 {
380     _gcry_register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
381 }
382 #endif
383
384 /* end of file */