pkgconfig: Fix libgcrypt.pc.
[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
55 #include "g10lib.h"
56 #include "cipher.h"
57
58 #include "bithelp.h"
59 #include "bufhelp.h"
60 #include "hash-common.h"
61
62
63 typedef struct {
64     gcry_md_block_ctx_t bctx;
65     u32 A,B,C,D;          /* chaining variables */
66 } MD4_CONTEXT;
67
68 static unsigned int
69 transform ( void *c, const unsigned char *data, size_t nblks );
70
71 static void
72 md4_init (void *context, unsigned int flags)
73 {
74   MD4_CONTEXT *ctx = context;
75
76   (void)flags;
77
78   ctx->A = 0x67452301;
79   ctx->B = 0xefcdab89;
80   ctx->C = 0x98badcfe;
81   ctx->D = 0x10325476;
82
83   ctx->bctx.nblocks = 0;
84   ctx->bctx.nblocks_high = 0;
85   ctx->bctx.count = 0;
86   ctx->bctx.blocksize = 64;
87   ctx->bctx.bwrite = transform;
88 }
89
90 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
91 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
92 #define H(x, y, z) ((x) ^ (y) ^ (z))
93
94
95 /****************
96  * transform 64 bytes
97  */
98 static unsigned int
99 transform_blk ( void *c, const unsigned char *data )
100 {
101   MD4_CONTEXT *ctx = c;
102   u32 in[16];
103   register u32 A = ctx->A;
104   register u32 B = ctx->B;
105   register u32 C = ctx->C;
106   register u32 D = ctx->D;
107   int i;
108
109   for ( i = 0; i < 16; i++ )
110     in[i] = buf_get_le32(data + i * 4);
111
112   /* Round 1.  */
113 #define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
114   function(A,B,C,D, 0, 3);
115   function(D,A,B,C, 1, 7);
116   function(C,D,A,B, 2,11);
117   function(B,C,D,A, 3,19);
118   function(A,B,C,D, 4, 3);
119   function(D,A,B,C, 5, 7);
120   function(C,D,A,B, 6,11);
121   function(B,C,D,A, 7,19);
122   function(A,B,C,D, 8, 3);
123   function(D,A,B,C, 9, 7);
124   function(C,D,A,B,10,11);
125   function(B,C,D,A,11,19);
126   function(A,B,C,D,12, 3);
127   function(D,A,B,C,13, 7);
128   function(C,D,A,B,14,11);
129   function(B,C,D,A,15,19);
130
131 #undef function
132
133   /* Round 2.  */
134 #define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
135
136   function(A,B,C,D, 0, 3);
137   function(D,A,B,C, 4, 5);
138   function(C,D,A,B, 8, 9);
139   function(B,C,D,A,12,13);
140   function(A,B,C,D, 1, 3);
141   function(D,A,B,C, 5, 5);
142   function(C,D,A,B, 9, 9);
143   function(B,C,D,A,13,13);
144   function(A,B,C,D, 2, 3);
145   function(D,A,B,C, 6, 5);
146   function(C,D,A,B,10, 9);
147   function(B,C,D,A,14,13);
148   function(A,B,C,D, 3, 3);
149   function(D,A,B,C, 7, 5);
150   function(C,D,A,B,11, 9);
151   function(B,C,D,A,15,13);
152
153 #undef function
154
155   /* Round 3.  */
156 #define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
157
158   function(A,B,C,D, 0, 3);
159   function(D,A,B,C, 8, 9);
160   function(C,D,A,B, 4,11);
161   function(B,C,D,A,12,15);
162   function(A,B,C,D, 2, 3);
163   function(D,A,B,C,10, 9);
164   function(C,D,A,B, 6,11);
165   function(B,C,D,A,14,15);
166   function(A,B,C,D, 1, 3);
167   function(D,A,B,C, 9, 9);
168   function(C,D,A,B, 5,11);
169   function(B,C,D,A,13,15);
170   function(A,B,C,D, 3, 3);
171   function(D,A,B,C,11, 9);
172   function(C,D,A,B, 7,11);
173   function(B,C,D,A,15,15);
174
175
176   /* Put checksum in context given as argument.  */
177   ctx->A += A;
178   ctx->B += B;
179   ctx->C += C;
180   ctx->D += D;
181
182   return /*burn_stack*/ 80+6*sizeof(void*);
183 }
184
185
186 static unsigned int
187 transform ( void *c, const unsigned char *data, size_t nblks )
188 {
189   unsigned int burn;
190
191   do
192     {
193       burn = transform_blk (c, data);
194       data += 64;
195     }
196   while (--nblks);
197
198   return burn;
199 }
200
201
202 /* The routine final terminates the message-digest computation and
203  * ends with the desired message digest in mdContext->digest[0...15].
204  * The handle is prepared for a new MD4 cycle.
205  * Returns 16 bytes representing the digest.
206  */
207
208 static void
209 md4_final( void *context )
210 {
211   MD4_CONTEXT *hd = context;
212   u32 t, th, msb, lsb;
213   byte *p;
214   unsigned int burn;
215
216   t = hd->bctx.nblocks;
217   if (sizeof t == sizeof hd->bctx.nblocks)
218     th = hd->bctx.nblocks_high;
219   else
220     th = hd->bctx.nblocks >> 32;
221
222   /* multiply by 64 to make a byte count */
223   lsb = t << 6;
224   msb = (th << 6) | (t >> 26);
225   /* add the count */
226   t = lsb;
227   if( (lsb += hd->bctx.count) < t )
228     msb++;
229   /* multiply by 8 to make a bit count */
230   t = lsb;
231   lsb <<= 3;
232   msb <<= 3;
233   msb |= t >> 29;
234
235   if (hd->bctx.count < 56)  /* enough room */
236     {
237       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
238       if (hd->bctx.count < 56)
239         memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
240       hd->bctx.count = 56;
241
242       /* append the 64 bit count */
243       buf_put_le32(hd->bctx.buf + 56, lsb);
244       buf_put_le32(hd->bctx.buf + 60, msb);
245       burn = transform (hd, hd->bctx.buf, 1);
246     }
247   else /* need one extra block */
248     {
249       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
250       /* fill pad and next block with zeroes */
251       memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
252       hd->bctx.count = 64 + 56;
253
254       /* append the 64 bit count */
255       buf_put_le32(hd->bctx.buf + 64 + 56, lsb);
256       buf_put_le32(hd->bctx.buf + 64 + 60, msb);
257       burn = transform (hd, hd->bctx.buf, 2);
258     }
259
260   p = hd->bctx.buf;
261 #define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
262   X(A);
263   X(B);
264   X(C);
265   X(D);
266 #undef X
267
268   _gcry_burn_stack (burn);
269 }
270
271 static byte *
272 md4_read (void *context)
273 {
274   MD4_CONTEXT *hd = context;
275   return hd->bctx.buf;
276 }
277
278 static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
279   { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
280     0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
281
282 static gcry_md_oid_spec_t oid_spec_md4[] =
283   {
284     /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
285     { "1.2.840.113549.2.4" },
286     { NULL },
287   };
288
289 gcry_md_spec_t _gcry_digest_spec_md4 =
290   {
291     GCRY_MD_MD4, {0, 0},
292     "MD4", asn, DIM (asn), oid_spec_md4,16,
293     md4_init, _gcry_md_block_write, md4_final, md4_read, NULL,
294     NULL, NULL,
295     sizeof (MD4_CONTEXT)
296   };