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