Enable AMD64 SHA512 implementations for WIN64
[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   _gcry_md_block_write(hd, NULL, 0); /* flush */;
217
218   t = hd->bctx.nblocks;
219   if (sizeof t == sizeof hd->bctx.nblocks)
220     th = hd->bctx.nblocks_high;
221   else
222     th = hd->bctx.nblocks >> 32;
223
224   /* multiply by 64 to make a byte count */
225   lsb = t << 6;
226   msb = (th << 6) | (t >> 26);
227   /* add the count */
228   t = lsb;
229   if( (lsb += hd->bctx.count) < t )
230     msb++;
231   /* multiply by 8 to make a bit count */
232   t = lsb;
233   lsb <<= 3;
234   msb <<= 3;
235   msb |= t >> 29;
236
237   if( hd->bctx.count < 56 )  /* enough room */
238     {
239       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
240       while( hd->bctx.count < 56 )
241         hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
242     }
243   else /* need one extra block */
244     {
245       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
246       while( hd->bctx.count < 64 )
247         hd->bctx.buf[hd->bctx.count++] = 0;
248       _gcry_md_block_write(hd, NULL, 0);  /* flush */;
249       memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
250     }
251   /* append the 64 bit count */
252   buf_put_le32(hd->bctx.buf + 56, lsb);
253   buf_put_le32(hd->bctx.buf + 60, msb);
254   burn = transform ( hd, hd->bctx.buf, 1 );
255   _gcry_burn_stack (burn);
256
257   p = hd->bctx.buf;
258 #define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
259   X(A);
260   X(B);
261   X(C);
262   X(D);
263 #undef X
264
265 }
266
267 static byte *
268 md4_read (void *context)
269 {
270   MD4_CONTEXT *hd = context;
271   return hd->bctx.buf;
272 }
273
274 static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
275   { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
276     0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
277
278 static gcry_md_oid_spec_t oid_spec_md4[] =
279   {
280     /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
281     { "1.2.840.113549.2.4" },
282     { NULL },
283   };
284
285 gcry_md_spec_t _gcry_digest_spec_md4 =
286   {
287     GCRY_MD_MD4, {0, 0},
288     "MD4", asn, DIM (asn), oid_spec_md4,16,
289     md4_init, _gcry_md_block_write, md4_final, md4_read,
290     sizeof (MD4_CONTEXT)
291   };