Add MD2 and hash fixes.
[gnulib.git] / lib / md2.c
1 /* Functions to compute MD2 message digest of files or memory blocks.
2    according to the definition of MD2 in RFC 1319 from April 1992.
3    Copyright (C) 1995,1996,1997,1999,2000,2001,2002,2003,2005
4    Free Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10
11    This program 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 General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software Foundation,
18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 /* Adapted by Simon Josefsson from public domain Libtomcrypt 1.06 by
21    Tom St Denis. */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include "md2.h"
28
29 #include <string.h>
30 #include <sys/types.h>
31
32 #include <minmax.h>
33
34 #if USE_UNLOCKED_IO
35 # include "unlocked-io.h"
36 #endif
37
38 #define BLOCKSIZE 4096
39 #if BLOCKSIZE % 64 != 0
40 # error "invalid BLOCKSIZE"
41 #endif
42
43 static void md2_update_chksum (struct md2_ctx *md);
44 static void md2_compress (struct md2_ctx *md);
45
46 /* Initialize structure containing state of computation.
47    (RFC 1319, 3.3: Step 3)  */
48 void
49 md2_init_ctx (struct md2_ctx *ctx)
50 {
51   memset (ctx->X, 0, sizeof (ctx->X));
52   memset (ctx->chksum, 0, sizeof (ctx->chksum));
53   memset (ctx->buf, 0, sizeof (ctx->buf));
54   ctx->curlen = 0;
55 }
56
57 /* Put result from CTX in first 16 bytes following RESBUF.  The result
58    must be in little endian byte order.
59
60    IMPORTANT: On some systems it is required that RESBUF is correctly
61    aligned for a 32 bits value.  */
62 void *
63 md2_read_ctx (const struct md2_ctx *ctx, void *resbuf)
64 {
65   memcpy (resbuf, ctx->X, 16);
66
67   return resbuf;
68 }
69
70 /* Process the remaining bytes in the internal buffer and the usual
71    prolog according to the standard and write the result to RESBUF.
72
73    IMPORTANT: On some systems it is required that RESBUF is correctly
74    aligned for a 32 bits value.  */
75 void *
76 md2_finish_ctx (struct md2_ctx *ctx, void *resbuf)
77 {
78   unsigned long i, k;
79
80   /* pad the message */
81   k = 16 - ctx->curlen;
82   for (i = ctx->curlen; i < 16; i++)
83     {
84       ctx->buf[i] = (unsigned char) k;
85     }
86
87   /* hash and update */
88   md2_compress (ctx);
89   md2_update_chksum (ctx);
90
91   /* hash checksum */
92   memcpy (ctx->buf, ctx->chksum, 16);
93   md2_compress (ctx);
94
95   return md2_read_ctx (ctx, resbuf);
96 }
97
98 /* Compute MD2 message digest for bytes read from STREAM.  The
99    resulting message digest number will be written into the 16 bytes
100    beginning at RESBLOCK.  */
101 int
102 md2_stream (FILE *stream, void *resblock)
103 {
104   struct md2_ctx ctx;
105   char buffer[BLOCKSIZE + 72];
106   size_t sum;
107
108   /* Initialize the computation context.  */
109   md2_init_ctx (&ctx);
110
111   /* Iterate over full file contents.  */
112   while (1)
113     {
114       /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
115          computation function processes the whole buffer so that with the
116          next round of the loop another block can be read.  */
117       size_t n;
118       sum = 0;
119
120       /* Read block.  Take care for partial reads.  */
121       while (1)
122         {
123           n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
124
125           sum += n;
126
127           if (sum == BLOCKSIZE)
128             break;
129
130           if (n == 0)
131             {
132               /* Check for the error flag IFF N == 0, so that we don't
133                  exit the loop after a partial read due to e.g., EAGAIN
134                  or EWOULDBLOCK.  */
135               if (ferror (stream))
136                 return 1;
137               goto process_partial_block;
138             }
139
140           /* We've read at least one byte, so ignore errors.  But always
141              check for EOF, since feof may be true even though N > 0.
142              Otherwise, we could end up calling fread after EOF.  */
143           if (feof (stream))
144             goto process_partial_block;
145         }
146
147       /* Process buffer with BLOCKSIZE bytes.  Note that
148          BLOCKSIZE % 64 == 0
149        */
150       md2_process_block (buffer, BLOCKSIZE, &ctx);
151     }
152
153 process_partial_block:;
154
155   /* Process any remaining bytes.  */
156   if (sum > 0)
157     md2_process_bytes (buffer, sum, &ctx);
158
159   /* Construct result in desired memory.  */
160   md2_finish_ctx (&ctx, resblock);
161   return 0;
162 }
163
164 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
165    result is always in little endian byte order, so that a byte-wise
166    output yields to the wanted ASCII representation of the message
167    digest.  */
168 void *
169 md2_buffer (const char *buffer, size_t len, void *resblock)
170 {
171   struct md2_ctx ctx;
172
173   /* Initialize the computation context.  */
174   md2_init_ctx (&ctx);
175
176   /* Process whole buffer but last len % 64 bytes.  */
177   md2_process_block (buffer, len, &ctx);
178
179   /* Put result in desired memory area.  */
180   return md2_finish_ctx (&ctx, resblock);
181 }
182
183 void
184 md2_process_bytes (const void *buffer, size_t len, struct md2_ctx *ctx)
185 {
186   const char *in = buffer;
187   unsigned long n;
188
189   while (len > 0)
190     {
191       n = MIN (len, (16 - ctx->curlen));
192       memcpy (ctx->buf + ctx->curlen, in, (size_t) n);
193       ctx->curlen += n;
194       in += n;
195       len -= n;
196
197       /* is 16 bytes full? */
198       if (ctx->curlen == 16)
199         {
200           md2_compress (ctx);
201           md2_update_chksum (ctx);
202           ctx->curlen = 0;
203         }
204     }
205 }
206
207 static const unsigned char PI_SUBST[256] = {
208   41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
209   19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
210   76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
211   138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
212   245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
213   148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
214   39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
215   181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
216   150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
217   112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
218   96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
219   85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
220   234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
221   129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
222   8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
223   203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
224   166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
225   31, 26, 219, 153, 141, 51, 159, 17, 131, 20
226 };
227
228 /* adds 16 bytes to the checksum */
229 static void
230 md2_update_chksum (struct md2_ctx *ctx)
231 {
232   int j;
233   unsigned char L;
234
235   L = ctx->chksum[15];
236   for (j = 0; j < 16; j++)
237     {
238       /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the
239          reference source code [and test vectors] say otherwise. */
240       L = (ctx->chksum[j] ^= PI_SUBST[(int) (ctx->buf[j] ^ L)] & 255);
241     }
242 }
243
244 static void
245 md2_compress (struct md2_ctx *ctx)
246 {
247   size_t j, k;
248   unsigned char t;
249
250   /* copy block */
251   for (j = 0; j < 16; j++)
252     {
253       ctx->X[16 + j] = ctx->buf[j];
254       ctx->X[32 + j] = ctx->X[j] ^ ctx->X[16 + j];
255     }
256
257   t = (unsigned char) 0;
258
259   /* do 18 rounds */
260   for (j = 0; j < 18; j++)
261     {
262       for (k = 0; k < 48; k++)
263         {
264           t = (ctx->X[k] ^= PI_SUBST[(int) (t & 255)]);
265         }
266       t = (t + (unsigned char) j) & 255;
267     }
268 }
269
270 /* Process LEN bytes of BUFFER, accumulating context into CTX.  */
271 void
272 md2_process_block (const void *buffer, size_t len, struct md2_ctx *ctx)
273 {
274   md2_process_bytes (buffer, len, ctx);
275 }