PerlIO_read() can return negative.
[p5sagit/p5-mst-13.2.git] / ext / Digest / MD5 / MD5.xs
1 /* $Id: MD5.xs,v 1.39 2003/07/05 05:25:37 gisle Exp $ */
2
3 /* 
4  * This library is free software; you can redistribute it and/or
5  * modify it under the same terms as Perl itself.
6  * 
7  *  Copyright 1998-2000 Gisle Aas.
8  *  Copyright 1995-1996 Neil Winton.
9  *  Copyright 1991-1992 RSA Data Security, Inc.
10  *
11  * This code is derived from Neil Winton's MD5-1.7 Perl module, which in
12  * turn is derived from the reference implementation in RFC 1321 which
13  * comes with this message:
14  *
15  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
16  * rights reserved.
17  *
18  * License to copy and use this software is granted provided that it
19  * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
20  * Algorithm" in all material mentioning or referencing this software
21  * or this function.
22  *
23  * License is also granted to make and use derivative works provided
24  * that such works are identified as "derived from the RSA Data
25  * Security, Inc. MD5 Message-Digest Algorithm" in all material
26  * mentioning or referencing the derived work.
27  *
28  * RSA Data Security, Inc. makes no representations concerning either
29  * the merchantability of this software or the suitability of this
30  * software for any particular purpose. It is provided "as is"
31  * without express or implied warranty of any kind.
32  *
33  * These notices must be retained in any copies of any part of this
34  * documentation and/or software.
35  */
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 #include "EXTERN.h"
41 #include "perl.h"
42 #include "XSUB.h"
43 #ifdef __cplusplus
44 }
45 #endif
46
47 #ifndef PERL_VERSION
48 #    include <patchlevel.h>
49 #    if !(defined(PERL_VERSION) || (SUBVERSION > 0 && defined(PATCHLEVEL)))
50 #        include <could_not_find_Perl_patchlevel.h>
51 #    endif
52 #    define PERL_REVISION       5
53 #    define PERL_VERSION        PATCHLEVEL
54 #    define PERL_SUBVERSION     SUBVERSION
55 #endif
56
57 #if PERL_VERSION <= 4 && !defined(PL_dowarn)
58    #define PL_dowarn dowarn
59 #endif
60
61 #ifdef G_WARN_ON
62    #define DOWARN (PL_dowarn & G_WARN_ON)
63 #else
64    #define DOWARN PL_dowarn
65 #endif
66
67 #ifdef SvPVbyte
68    #if PERL_REVISION == 5 && PERL_VERSION < 7
69        /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
70        #undef SvPVbyte
71        #define SvPVbyte(sv, lp) \
72           ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
73            ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp))
74
75        static char *
76        my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp)
77        {
78            sv_utf8_downgrade(sv,0);
79            return SvPV(sv,*lp);
80        }
81    #endif
82 #else
83    #define SvPVbyte SvPV
84 #endif
85
86 /* Perl does not guarantee that U32 is exactly 32 bits.  Some system
87  * has no integral type with exactly 32 bits.  For instance, A Cray has
88  * short, int and long all at 64 bits so we need to apply this macro
89  * to reduce U32 values to 32 bits at appropriate places. If U32
90  * really does have 32 bits then this is a no-op.
91  */
92 #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32)
93   #define TO32(x)    ((x) &  0xFFFFffff)
94   #define TRUNC32(x) ((x) &= 0xFFFFffff)
95 #else
96   #define TO32(x)    (x)
97   #define TRUNC32(x) /*nothing*/
98 #endif
99
100 /* The MD5 algorithm is defined in terms of little endian 32-bit
101  * values.  The following macros (and functions) allow us to convert
102  * between native integers and such values.
103  */
104 #undef BYTESWAP
105 #ifndef U32_ALIGNMENT_REQUIRED
106  #if BYTEORDER == 0x1234      /* 32-bit little endian */
107   #define BYTESWAP(x) (x)     /* no-op */
108
109  #elif BYTEORDER == 0x4321    /* 32-bit big endian */
110   #define BYTESWAP(x)   ((((x)&0xFF)<<24)       \
111                         |(((x)>>24)&0xFF)       \
112                         |(((x)&0x0000FF00)<<8)  \
113                         |(((x)&0x00FF0000)>>8)  )
114  #endif
115 #endif
116
117 #ifndef BYTESWAP
118 static void u2s(U32 u, U8* s)
119 {
120     *s++ = (U8)(u         & 0xFF);
121     *s++ = (U8)((u >>  8) & 0xFF);
122     *s++ = (U8)((u >> 16) & 0xFF);
123     *s   = (U8)((u >> 24) & 0xFF);
124 }
125
126 #define s2u(s,u) ((u) =  (U32)(*s)            |  \
127                         ((U32)(*(s+1)) << 8)  |  \
128                         ((U32)(*(s+2)) << 16) |  \
129                         ((U32)(*(s+3)) << 24))
130 #endif
131
132 #define MD5_CTX_SIGNATURE 200003165
133
134 /* This stucture keeps the current state of algorithm.
135  */
136 typedef struct {
137   U32 signature;   /* safer cast in get_md5_ctx() */
138   U32 A, B, C, D;  /* current digest */
139   U32 bytes_low;   /* counts bytes in message */
140   U32 bytes_high;  /* turn it into a 64-bit counter */
141   U8 buffer[128];  /* collect complete 64 byte blocks */
142 } MD5_CTX;
143
144
145 /* Padding is added at the end of the message in order to fill a
146  * complete 64 byte block (- 8 bytes for the message length).  The
147  * padding is also the reason the buffer in MD5_CTX have to be
148  * 128 bytes.
149  */
150 static unsigned char PADDING[64] = {
151   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
154 };
155
156 /* Constants for MD5Transform routine.
157  */
158 #define S11 7
159 #define S12 12
160 #define S13 17
161 #define S14 22
162 #define S21 5
163 #define S22 9
164 #define S23 14
165 #define S24 20
166 #define S31 4
167 #define S32 11
168 #define S33 16
169 #define S34 23
170 #define S41 6
171 #define S42 10
172 #define S43 15
173 #define S44 21
174
175 /* F, G, H and I are basic MD5 functions.
176  */
177 #define F(x, y, z) ((((x) & ((y) ^ (z))) ^ (z)))
178 #define G(x, y, z) F(z, x, y)
179 #define H(x, y, z) ((x) ^ (y) ^ (z))
180 #define I(x, y, z) ((y) ^ ((x) | (~z)))
181
182 /* ROTATE_LEFT rotates x left n bits.
183  */
184 #define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
185
186 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
187  * Rotation is separate from addition to prevent recomputation.
188  */
189 #define FF(a, b, c, d, s, ac)                    \
190  (a) += F ((b), (c), (d)) + (NEXTx) + (U32)(ac); \
191  TRUNC32((a));                                   \
192  (a) = ROTATE_LEFT ((a), (s));                   \
193  (a) += (b);                                     \
194  TRUNC32((a));
195
196 #define GG(a, b, c, d, x, s, ac)                 \
197  (a) += G ((b), (c), (d)) + X[x] + (U32)(ac);    \
198  TRUNC32((a));                                   \
199  (a) = ROTATE_LEFT ((a), (s));                   \
200  (a) += (b);                                     \
201  TRUNC32((a));
202
203 #define HH(a, b, c, d, x, s, ac)                 \
204  (a) += H ((b), (c), (d)) + X[x] + (U32)(ac);    \
205  TRUNC32((a));                                   \
206  (a) = ROTATE_LEFT ((a), (s));                   \
207  (a) += (b);                                     \
208  TRUNC32((a));
209
210 #define II(a, b, c, d, x, s, ac)                 \
211  (a) += I ((b), (c), (d)) + X[x] + (U32)(ac);    \
212  TRUNC32((a));                                   \
213  (a) = ROTATE_LEFT ((a), (s));                   \
214  (a) += (b);                                     \
215  TRUNC32((a));
216
217
218 static void
219 MD5Init(MD5_CTX *ctx)
220 {
221   /* Start state */
222   ctx->A = 0x67452301;
223   ctx->B = 0xefcdab89;
224   ctx->C = 0x98badcfe;
225   ctx->D = 0x10325476;
226
227   /* message length */
228   ctx->bytes_low = ctx->bytes_high = 0;
229 }
230
231
232 static void
233 MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks)
234 {
235 #ifdef MD5_DEBUG
236     static int tcount = 0;
237 #endif
238
239     U32 A = ctx->A;
240     U32 B = ctx->B;
241     U32 C = ctx->C;
242     U32 D = ctx->D;
243
244 #ifndef U32_ALIGNMENT_REQUIRED
245     const U32 *x = (U32*)buf;  /* really just type casting */
246 #endif
247
248     do {
249         U32 a = A;
250         U32 b = B;
251         U32 c = C;
252         U32 d = D;
253
254 #if BYTEORDER == 0x1234 && !defined(U32_ALIGNMENT_REQUIRED)
255         const U32 *X = x;
256         #define NEXTx  (*x++)
257 #else
258         U32 X[16];      /* converted values, used in round 2-4 */
259         U32 *uptr = X;
260         U32 tmp;
261  #ifdef BYTESWAP
262         #define NEXTx  (tmp=*x++, *uptr++ = BYTESWAP(tmp))
263  #else
264         #define NEXTx  (s2u(buf,tmp), buf += 4, *uptr++ = tmp)
265  #endif
266 #endif
267
268 #ifdef MD5_DEBUG
269         if (buf == ctx->buffer)
270             fprintf(stderr,"%5d: Transform ctx->buffer", ++tcount);
271         else 
272             fprintf(stderr,"%5d: Transform %p (%d)", ++tcount, buf, blocks);
273
274         {
275             int i;
276             fprintf(stderr,"[");
277             for (i = 0; i < 16; i++) {
278                 fprintf(stderr,"%x,", x[i]);
279             }
280             fprintf(stderr,"]\n");
281         }
282 #endif
283
284         /* Round 1 */
285         FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
286         FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
287         FF (c, d, a, b, S13, 0x242070db); /* 3 */
288         FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
289         FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
290         FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
291         FF (c, d, a, b, S13, 0xa8304613); /* 7 */
292         FF (b, c, d, a, S14, 0xfd469501); /* 8 */
293         FF (a, b, c, d, S11, 0x698098d8); /* 9 */
294         FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
295         FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
296         FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
297         FF (a, b, c, d, S11, 0x6b901122); /* 13 */
298         FF (d, a, b, c, S12, 0xfd987193); /* 14 */
299         FF (c, d, a, b, S13, 0xa679438e); /* 15 */
300         FF (b, c, d, a, S14, 0x49b40821); /* 16 */
301
302         /* Round 2 */
303         GG (a, b, c, d,  1, S21, 0xf61e2562); /* 17 */
304         GG (d, a, b, c,  6, S22, 0xc040b340); /* 18 */
305         GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
306         GG (b, c, d, a,  0, S24, 0xe9b6c7aa); /* 20 */
307         GG (a, b, c, d,  5, S21, 0xd62f105d); /* 21 */
308         GG (d, a, b, c, 10, S22,  0x2441453); /* 22 */
309         GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
310         GG (b, c, d, a,  4, S24, 0xe7d3fbc8); /* 24 */
311         GG (a, b, c, d,  9, S21, 0x21e1cde6); /* 25 */
312         GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
313         GG (c, d, a, b,  3, S23, 0xf4d50d87); /* 27 */
314         GG (b, c, d, a,  8, S24, 0x455a14ed); /* 28 */
315         GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
316         GG (d, a, b, c,  2, S22, 0xfcefa3f8); /* 30 */
317         GG (c, d, a, b,  7, S23, 0x676f02d9); /* 31 */
318         GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
319
320         /* Round 3 */
321         HH (a, b, c, d,  5, S31, 0xfffa3942); /* 33 */
322         HH (d, a, b, c,  8, S32, 0x8771f681); /* 34 */
323         HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
324         HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
325         HH (a, b, c, d,  1, S31, 0xa4beea44); /* 37 */
326         HH (d, a, b, c,  4, S32, 0x4bdecfa9); /* 38 */
327         HH (c, d, a, b,  7, S33, 0xf6bb4b60); /* 39 */
328         HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
329         HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
330         HH (d, a, b, c,  0, S32, 0xeaa127fa); /* 42 */
331         HH (c, d, a, b,  3, S33, 0xd4ef3085); /* 43 */
332         HH (b, c, d, a,  6, S34,  0x4881d05); /* 44 */
333         HH (a, b, c, d,  9, S31, 0xd9d4d039); /* 45 */
334         HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
335         HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
336         HH (b, c, d, a,  2, S34, 0xc4ac5665); /* 48 */
337
338         /* Round 4 */
339         II (a, b, c, d,  0, S41, 0xf4292244); /* 49 */
340         II (d, a, b, c,  7, S42, 0x432aff97); /* 50 */
341         II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
342         II (b, c, d, a,  5, S44, 0xfc93a039); /* 52 */
343         II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
344         II (d, a, b, c,  3, S42, 0x8f0ccc92); /* 54 */
345         II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
346         II (b, c, d, a,  1, S44, 0x85845dd1); /* 56 */
347         II (a, b, c, d,  8, S41, 0x6fa87e4f); /* 57 */
348         II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
349         II (c, d, a, b,  6, S43, 0xa3014314); /* 59 */
350         II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
351         II (a, b, c, d,  4, S41, 0xf7537e82); /* 61 */
352         II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
353         II (c, d, a, b,  2, S43, 0x2ad7d2bb); /* 63 */
354         II (b, c, d, a,  9, S44, 0xeb86d391); /* 64 */
355
356         A += a;  TRUNC32(A);
357         B += b;  TRUNC32(B);
358         C += c;  TRUNC32(C);
359         D += d;  TRUNC32(D);
360
361     } while (--blocks);
362     ctx->A = A;
363     ctx->B = B;
364     ctx->C = C;
365     ctx->D = D;
366 }
367
368
369 #ifdef MD5_DEBUG
370 static char*
371 ctx_dump(MD5_CTX* ctx)
372 {
373     static char buf[1024];
374     sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",
375             ctx->A, ctx->B, ctx->C, ctx->D,
376             ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));
377     return buf;
378 }
379 #endif
380
381
382 static void
383 MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len)
384 {
385     STRLEN blocks;
386     STRLEN fill = ctx->bytes_low & 0x3F;
387
388 #ifdef MD5_DEBUG  
389     static int ucount = 0;
390     fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx),
391                                                 buf, len);
392 #endif
393
394     ctx->bytes_low += len;
395     if (ctx->bytes_low < len) /* wrap around */
396         ctx->bytes_high++;
397
398     if (fill) {
399         STRLEN missing = 64 - fill;
400         if (len < missing) {
401             Copy(buf, ctx->buffer + fill, len, U8);
402             return;
403         }
404         Copy(buf, ctx->buffer + fill, missing, U8);
405         MD5Transform(ctx, ctx->buffer, 1);
406         buf += missing;
407         len -= missing;
408     }
409
410     blocks = len >> 6;
411     if (blocks)
412         MD5Transform(ctx, buf, blocks);
413     if ( (len &= 0x3F)) {
414         Copy(buf + (blocks << 6), ctx->buffer, len, U8);
415     }
416 }
417
418
419 static void
420 MD5Final(U8* digest, MD5_CTX *ctx)
421 {
422     STRLEN fill = ctx->bytes_low & 0x3F;
423     STRLEN padlen = (fill < 56 ? 56 : 120) - fill;
424     U32 bits_low, bits_high;
425 #ifdef MD5_DEBUG
426     fprintf(stderr,"       Final:  %s\n", ctx_dump(ctx));
427 #endif
428     Copy(PADDING, ctx->buffer + fill, padlen, U8);
429     fill += padlen;
430
431     bits_low = ctx->bytes_low << 3;
432     bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low  >> 29);
433 #ifdef BYTESWAP
434     *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_low);    fill += 4;
435     *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_high);   fill += 4;
436 #else
437     u2s(bits_low,  ctx->buffer + fill);   fill += 4;
438     u2s(bits_high, ctx->buffer + fill);   fill += 4;
439 #endif
440
441     MD5Transform(ctx, ctx->buffer, fill >> 6);
442 #ifdef MD5_DEBUG
443     fprintf(stderr,"       Result: %s\n", ctx_dump(ctx));
444 #endif
445
446 #ifdef BYTESWAP
447     *(U32*)digest = BYTESWAP(ctx->A);  digest += 4;
448     *(U32*)digest = BYTESWAP(ctx->B);  digest += 4;
449     *(U32*)digest = BYTESWAP(ctx->C);  digest += 4;
450     *(U32*)digest = BYTESWAP(ctx->D);
451 #else
452     u2s(ctx->A, digest);
453     u2s(ctx->B, digest+4);
454     u2s(ctx->C, digest+8);
455     u2s(ctx->D, digest+12);
456 #endif
457 }
458
459 #ifndef INT2PTR
460 #define INT2PTR(any,d)  (any)(d)
461 #endif
462
463 static MD5_CTX* get_md5_ctx(SV* sv)
464 {
465     if (SvROK(sv)) {
466         sv = SvRV(sv);
467         if (SvIOK(sv)) {
468             MD5_CTX* ctx = INT2PTR(MD5_CTX*, SvIV(sv));
469             if (ctx && ctx->signature == MD5_CTX_SIGNATURE) {
470                 return ctx;
471             }
472         }
473     }
474     croak("Not a reference to a Digest::MD5 object");
475     return (MD5_CTX*)0; /* some compilers insist on a return value */
476 }
477
478
479 static char* hex_16(const unsigned char* from, char* to)
480 {
481     static char *hexdigits = "0123456789abcdef";
482     const unsigned char *end = from + 16;
483     char *d = to;
484
485     while (from < end) {
486         *d++ = hexdigits[(*from >> 4)];
487         *d++ = hexdigits[(*from & 0x0F)];
488         from++;
489     }
490     *d = '\0';
491     return to;
492 }
493
494 static char* base64_16(const unsigned char* from, char* to)
495 {
496     static char* base64 =
497         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
498     const unsigned char *end = from + 16;
499     unsigned char c1, c2, c3;
500     char *d = to;
501
502     while (1) {
503         c1 = *from++;
504         *d++ = base64[c1>>2];
505         if (from == end) {
506             *d++ = base64[(c1 & 0x3) << 4];
507             break;
508         }
509         c2 = *from++;
510         c3 = *from++;
511         *d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
512         *d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
513         *d++ = base64[c3 & 0x3F];
514     }
515     *d = '\0';
516     return to;
517 }
518
519 /* Formats */
520 #define F_BIN 0
521 #define F_HEX 1
522 #define F_B64 2
523
524 static SV* make_mortal_sv(const unsigned char *src, int type)
525 {
526     STRLEN len;
527     char result[33];
528     char *ret;
529     
530     switch (type) {
531     case F_BIN:
532         ret = (char*)src;
533         len = 16;
534         break;
535     case F_HEX:
536         ret = hex_16(src, result);
537         len = 32;
538         break;
539     case F_B64:
540         ret = base64_16(src, result);
541         len = 22;
542         break;
543     default:
544         croak("Bad convertion type (%d)", type);
545         break;
546     }
547     return sv_2mortal(newSVpv(ret,len));
548 }
549
550
551 /********************************************************************/
552
553 typedef PerlIO* InputStream;
554
555 MODULE = Digest::MD5            PACKAGE = Digest::MD5
556
557 PROTOTYPES: DISABLE
558
559 void
560 new(xclass)
561         SV* xclass
562     PREINIT:
563         MD5_CTX* context;
564     PPCODE:
565         if (!SvROK(xclass)) {
566             STRLEN my_na;
567             char *sclass = SvPV(xclass, my_na);
568             New(55, context, 1, MD5_CTX);
569             context->signature = MD5_CTX_SIGNATURE;
570             ST(0) = sv_newmortal();
571             sv_setref_pv(ST(0), sclass, (void*)context);
572             SvREADONLY_on(SvRV(ST(0)));
573         } else {
574             context = get_md5_ctx(xclass);
575         }
576         MD5Init(context);
577         XSRETURN(1);
578
579 void
580 clone(self)
581         SV* self
582     PREINIT:
583         MD5_CTX* cont = get_md5_ctx(self);
584         char *myname = sv_reftype(SvRV(self),TRUE);
585         MD5_CTX* context;
586     PPCODE:
587         STRLEN my_na;
588         New(55, context, 1, MD5_CTX);
589         ST(0) = sv_newmortal();
590         sv_setref_pv(ST(0), myname , (void*)context);
591         SvREADONLY_on(SvRV(ST(0)));
592         memcpy(context,cont,sizeof(MD5_CTX));
593         XSRETURN(1);
594
595 void
596 DESTROY(context)
597         MD5_CTX* context
598     CODE:
599         Safefree(context);
600
601 void
602 add(self, ...)
603         SV* self
604     PREINIT:
605         MD5_CTX* context = get_md5_ctx(self);
606         int i;
607         unsigned char *data;
608         STRLEN len;
609     PPCODE:
610         for (i = 1; i < items; i++) {
611             data = (unsigned char *)(SvPVbyte(ST(i), len));
612             MD5Update(context, data, len);
613         }
614         XSRETURN(1);  /* self */
615
616 void
617 addfile(self, fh)
618         SV* self
619         InputStream fh
620     PREINIT:
621         MD5_CTX* context = get_md5_ctx(self);
622         STRLEN fill = context->bytes_low & 0x3F;
623         unsigned char buffer[4096];
624         SSize_t n;
625     CODE:
626         if (fh) {
627             if (fill) {
628                 /* The MD5Update() function is faster if it can work with
629                  * complete blocks.  This will fill up any buffered block
630                  * first.
631                  */
632                 STRLEN missing = 64 - fill;
633                 n = PerlIO_read(fh, buffer, missing);
634                 if (n >= 0)
635                     MD5Update(context, buffer, n);
636                 else {
637                     if (PerlIO_error(fh)) {
638                         croak("Reading from filehandle failed");
639                     }
640                     XSRETURN(1);  /* self */
641                 }
642             }
643
644             /* Process blocks until EOF or error */
645             while ( (n = PerlIO_read(fh, buffer, sizeof(buffer))) > 0 ) {
646                 MD5Update(context, buffer, n);
647             }
648
649             if (PerlIO_error(fh)) {
650                 croak("Reading from filehandle failed");
651             }
652         }
653         else {
654             croak("No filehandle passed");
655         }
656         XSRETURN(1);  /* self */
657
658 void
659 digest(context)
660         MD5_CTX* context
661     ALIAS:
662         Digest::MD5::digest    = F_BIN
663         Digest::MD5::hexdigest = F_HEX
664         Digest::MD5::b64digest = F_B64
665     PREINIT:
666         unsigned char digeststr[16];
667     PPCODE:
668         MD5Final(digeststr, context);
669         MD5Init(context);  /* In case it is reused */
670         ST(0) = make_mortal_sv(digeststr, ix);
671         XSRETURN(1);
672
673 void
674 md5(...)
675     ALIAS:
676         Digest::MD5::md5        = F_BIN
677         Digest::MD5::md5_hex    = F_HEX
678         Digest::MD5::md5_base64 = F_B64
679     PREINIT:
680         MD5_CTX ctx;
681         int i;
682         unsigned char *data;
683         STRLEN len;
684         unsigned char digeststr[16];
685     PPCODE:
686         MD5Init(&ctx);
687
688         if (DOWARN) {
689             char *msg = 0;
690             if (items == 1) {
691                 if (SvROK(ST(0))) {
692                     SV* sv = SvRV(ST(0));
693                     if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
694                         msg = "probably called as method";
695                     else
696                         msg = "called with reference argument";
697                 }
698             }
699             else if (items > 1) {
700                 data = (unsigned char *)SvPVbyte(ST(0), len);
701                 if (len == 11 && memEQ("Digest::MD5", data, 11)) {
702                     msg = "probably called as class method";
703                 }
704             }
705             if (msg) {
706                 char *f = (ix == F_BIN) ? "md5" :
707                           (ix == F_HEX) ? "md5_hex" : "md5_base64";
708                 warn("&Digest::MD5::%s function %s", f, msg);
709             }
710         }
711
712         for (i = 0; i < items; i++) {
713             data = (unsigned char *)(SvPVbyte(ST(i), len));
714             MD5Update(&ctx, data, len);
715         }
716         MD5Final(digeststr, &ctx);
717         ST(0) = make_mortal_sv(digeststr, ix);
718         XSRETURN(1);