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,2006,2008
4 Free Software Foundation, Inc.
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
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.
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. */
20 /* Adapted by Simon Josefsson from public domain Libtomcrypt 1.06 by
29 #include <sys/types.h>
34 # include "unlocked-io.h"
37 #define BLOCKSIZE 32768
38 #if BLOCKSIZE % 64 != 0
39 # error "invalid BLOCKSIZE"
42 static void md2_update_chksum (struct md2_ctx *md);
43 static void md2_compress (struct md2_ctx *md);
45 /* Initialize structure containing state of computation.
46 (RFC 1319, 3.3: Step 3) */
48 md2_init_ctx (struct md2_ctx *ctx)
50 memset (ctx->X, 0, sizeof (ctx->X));
51 memset (ctx->chksum, 0, sizeof (ctx->chksum));
52 memset (ctx->buf, 0, sizeof (ctx->buf));
56 /* Put result from CTX in first 16 bytes following RESBUF. The result
57 must be in little endian byte order. */
59 md2_read_ctx (const struct md2_ctx *ctx, void *resbuf)
61 memcpy (resbuf, ctx->X, 16);
66 /* Process the remaining bytes in the internal buffer and the usual
67 prolog according to the standard and write the result to RESBUF. */
69 md2_finish_ctx (struct md2_ctx *ctx, void *resbuf)
75 for (i = ctx->curlen; i < 16; i++)
77 ctx->buf[i] = (unsigned char) k;
82 md2_update_chksum (ctx);
85 memcpy (ctx->buf, ctx->chksum, 16);
88 return md2_read_ctx (ctx, resbuf);
91 /* Compute MD2 message digest for bytes read from STREAM. The
92 resulting message digest number will be written into the 16 bytes
93 beginning at RESBLOCK. */
95 md2_stream (FILE *stream, void *resblock)
100 char *buffer = malloc (BLOCKSIZE + 72);
104 /* Initialize the computation context. */
107 /* Iterate over full file contents. */
110 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
111 computation function processes the whole buffer so that with the
112 next round of the loop another block can be read. */
116 /* Read block. Take care for partial reads. */
119 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
123 if (sum == BLOCKSIZE)
128 /* Check for the error flag IFF N == 0, so that we don't
129 exit the loop after a partial read due to e.g., EAGAIN
136 goto process_partial_block;
139 /* We've read at least one byte, so ignore errors. But always
140 check for EOF, since feof may be true even though N > 0.
141 Otherwise, we could end up calling fread after EOF. */
143 goto process_partial_block;
146 /* Process buffer with BLOCKSIZE bytes. Note that
149 md2_process_block (buffer, BLOCKSIZE, &ctx);
152 process_partial_block:;
154 /* Process any remaining bytes. */
156 md2_process_bytes (buffer, sum, &ctx);
158 /* Construct result in desired memory. */
159 md2_finish_ctx (&ctx, resblock);
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
169 md2_buffer (const char *buffer, size_t len, void *resblock)
173 /* Initialize the computation context. */
176 /* Process whole buffer but last len % 64 bytes. */
177 md2_process_block (buffer, len, &ctx);
179 /* Put result in desired memory area. */
180 return md2_finish_ctx (&ctx, resblock);
184 md2_process_bytes (const void *buffer, size_t len, struct md2_ctx *ctx)
186 const char *in = buffer;
191 n = MIN (len, (16 - ctx->curlen));
192 memcpy (ctx->buf + ctx->curlen, in, (size_t) n);
197 /* is 16 bytes full? */
198 if (ctx->curlen == 16)
201 md2_update_chksum (ctx);
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
228 /* adds 16 bytes to the checksum */
230 md2_update_chksum (struct md2_ctx *ctx)
236 for (j = 0; j < 16; j++)
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);
245 md2_compress (struct md2_ctx *ctx)
251 for (j = 0; j < 16; j++)
253 ctx->X[16 + j] = ctx->buf[j];
254 ctx->X[32 + j] = ctx->X[j] ^ ctx->X[16 + j];
257 t = (unsigned char) 0;
260 for (j = 0; j < 18; j++)
262 for (k = 0; k < 48; k++)
264 t = (ctx->X[k] ^= PI_SUBST[(int) (t & 255)]);
266 t = (t + (unsigned char) j) & 255;
270 /* Process LEN bytes of BUFFER, accumulating context into CTX. */
272 md2_process_block (const void *buffer, size_t len, struct md2_ctx *ctx)
274 md2_process_bytes (buffer, len, ctx);