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