2 * This library is free software; you can redistribute it and/or
3 * modify it under the same terms as Perl itself.
5 * Copyright 1998-2000 Gisle Aas.
6 * Copyright 1995-1996 Neil Winton.
7 * Copyright 1991-1992 RSA Data Security, Inc.
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:
13 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
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
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.
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.
31 * These notices must be retained in any copies of any part of this
32 * documentation and/or software.
38 #define PERL_NO_GET_CONTEXT /* we want efficiency */
46 /* Perl does not guarantee that U32 is exactly 32 bits. Some system
47 * has no integral type with exactly 32 bits. For instance, A Cray has
48 * short, int and long all at 64 bits so we need to apply this macro
49 * to reduce U32 values to 32 bits at appropriate places. If U32
50 * really does have 32 bits then this is a no-op.
52 #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32)
53 #define TO32(x) ((x) & 0xFFFFffff)
54 #define TRUNC32(x) ((x) &= 0xFFFFffff)
57 #define TRUNC32(x) /*nothing*/
60 /* The MD5 algorithm is defined in terms of little endian 32-bit
61 * values. The following macros (and functions) allow us to convert
62 * between native integers and such values.
65 #ifndef U32_ALIGNMENT_REQUIRED
66 #if BYTEORDER == 0x1234 /* 32-bit little endian */
67 #define BYTESWAP(x) (x) /* no-op */
69 #elif BYTEORDER == 0x4321 /* 32-bit big endian */
70 #define BYTESWAP(x) ((((x)&0xFF)<<24) \
72 |(((x)&0x0000FF00)<<8) \
73 |(((x)&0x00FF0000)>>8) )
78 static void u2s(U32 u, U8* s)
80 *s++ = (U8)(u & 0xFF);
81 *s++ = (U8)((u >> 8) & 0xFF);
82 *s++ = (U8)((u >> 16) & 0xFF);
83 *s = (U8)((u >> 24) & 0xFF);
86 #define s2u(s,u) ((u) = (U32)(*s) | \
87 ((U32)(*(s+1)) << 8) | \
88 ((U32)(*(s+2)) << 16) | \
89 ((U32)(*(s+3)) << 24))
92 /* This stucture keeps the current state of algorithm.
95 U32 A, B, C, D; /* current digest */
96 U32 bytes_low; /* counts bytes in message */
97 U32 bytes_high; /* turn it into a 64-bit counter */
98 U8 buffer[128]; /* collect complete 64 byte blocks */
102 STATIC int dup_md5_ctx(pTHX_ MAGIC *mg, CLONE_PARAMS *params)
105 PERL_UNUSED_VAR(params);
106 New(55, new_ctx, 1, MD5_CTX);
107 memcpy(new_ctx, mg->mg_ptr, sizeof(MD5_CTX));
108 mg->mg_ptr = (char *)new_ctx;
113 STATIC MGVTBL vtbl_md5 = {
135 /* Padding is added at the end of the message in order to fill a
136 * complete 64 byte block (- 8 bytes for the message length). The
137 * padding is also the reason the buffer in MD5_CTX have to be
140 static const unsigned char PADDING[64] = {
141 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
146 /* Constants for MD5Transform routine.
165 /* F, G, H and I are basic MD5 functions.
167 #define F(x, y, z) ((((x) & ((y) ^ (z))) ^ (z)))
168 #define G(x, y, z) F(z, x, y)
169 #define H(x, y, z) ((x) ^ (y) ^ (z))
170 #define I(x, y, z) ((y) ^ ((x) | (~z)))
172 /* ROTATE_LEFT rotates x left n bits.
174 #define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
176 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
177 * Rotation is separate from addition to prevent recomputation.
179 #define FF(a, b, c, d, s, ac) \
180 (a) += F ((b), (c), (d)) + (NEXTx) + (U32)(ac); \
182 (a) = ROTATE_LEFT ((a), (s)); \
186 #define GG(a, b, c, d, x, s, ac) \
187 (a) += G ((b), (c), (d)) + X[x] + (U32)(ac); \
189 (a) = ROTATE_LEFT ((a), (s)); \
193 #define HH(a, b, c, d, x, s, ac) \
194 (a) += H ((b), (c), (d)) + X[x] + (U32)(ac); \
196 (a) = ROTATE_LEFT ((a), (s)); \
200 #define II(a, b, c, d, x, s, ac) \
201 (a) += I ((b), (c), (d)) + X[x] + (U32)(ac); \
203 (a) = ROTATE_LEFT ((a), (s)); \
209 MD5Init(MD5_CTX *ctx)
218 ctx->bytes_low = ctx->bytes_high = 0;
223 MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks)
226 static int tcount = 0;
234 #ifndef U32_ALIGNMENT_REQUIRED
235 const U32 *x = (U32*)buf; /* really just type casting */
244 #if BYTEORDER == 0x1234 && !defined(U32_ALIGNMENT_REQUIRED)
248 U32 X[16]; /* converted values, used in round 2-4 */
252 #define NEXTx (tmp=*x++, *uptr++ = BYTESWAP(tmp))
254 #define NEXTx (s2u(buf,tmp), buf += 4, *uptr++ = tmp)
259 if (buf == ctx->buffer)
260 fprintf(stderr,"%5d: Transform ctx->buffer", ++tcount);
262 fprintf(stderr,"%5d: Transform %p (%d)", ++tcount, buf, blocks);
267 for (i = 0; i < 16; i++) {
268 fprintf(stderr,"%x,", x[i]);
270 fprintf(stderr,"]\n");
275 FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
276 FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
277 FF (c, d, a, b, S13, 0x242070db); /* 3 */
278 FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
279 FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
280 FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
281 FF (c, d, a, b, S13, 0xa8304613); /* 7 */
282 FF (b, c, d, a, S14, 0xfd469501); /* 8 */
283 FF (a, b, c, d, S11, 0x698098d8); /* 9 */
284 FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
285 FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
286 FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
287 FF (a, b, c, d, S11, 0x6b901122); /* 13 */
288 FF (d, a, b, c, S12, 0xfd987193); /* 14 */
289 FF (c, d, a, b, S13, 0xa679438e); /* 15 */
290 FF (b, c, d, a, S14, 0x49b40821); /* 16 */
293 GG (a, b, c, d, 1, S21, 0xf61e2562); /* 17 */
294 GG (d, a, b, c, 6, S22, 0xc040b340); /* 18 */
295 GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
296 GG (b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
297 GG (a, b, c, d, 5, S21, 0xd62f105d); /* 21 */
298 GG (d, a, b, c, 10, S22, 0x2441453); /* 22 */
299 GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
300 GG (b, c, d, a, 4, S24, 0xe7d3fbc8); /* 24 */
301 GG (a, b, c, d, 9, S21, 0x21e1cde6); /* 25 */
302 GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
303 GG (c, d, a, b, 3, S23, 0xf4d50d87); /* 27 */
304 GG (b, c, d, a, 8, S24, 0x455a14ed); /* 28 */
305 GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
306 GG (d, a, b, c, 2, S22, 0xfcefa3f8); /* 30 */
307 GG (c, d, a, b, 7, S23, 0x676f02d9); /* 31 */
308 GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
311 HH (a, b, c, d, 5, S31, 0xfffa3942); /* 33 */
312 HH (d, a, b, c, 8, S32, 0x8771f681); /* 34 */
313 HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
314 HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
315 HH (a, b, c, d, 1, S31, 0xa4beea44); /* 37 */
316 HH (d, a, b, c, 4, S32, 0x4bdecfa9); /* 38 */
317 HH (c, d, a, b, 7, S33, 0xf6bb4b60); /* 39 */
318 HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
319 HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
320 HH (d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
321 HH (c, d, a, b, 3, S33, 0xd4ef3085); /* 43 */
322 HH (b, c, d, a, 6, S34, 0x4881d05); /* 44 */
323 HH (a, b, c, d, 9, S31, 0xd9d4d039); /* 45 */
324 HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
325 HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
326 HH (b, c, d, a, 2, S34, 0xc4ac5665); /* 48 */
329 II (a, b, c, d, 0, S41, 0xf4292244); /* 49 */
330 II (d, a, b, c, 7, S42, 0x432aff97); /* 50 */
331 II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
332 II (b, c, d, a, 5, S44, 0xfc93a039); /* 52 */
333 II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
334 II (d, a, b, c, 3, S42, 0x8f0ccc92); /* 54 */
335 II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
336 II (b, c, d, a, 1, S44, 0x85845dd1); /* 56 */
337 II (a, b, c, d, 8, S41, 0x6fa87e4f); /* 57 */
338 II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
339 II (c, d, a, b, 6, S43, 0xa3014314); /* 59 */
340 II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
341 II (a, b, c, d, 4, S41, 0xf7537e82); /* 61 */
342 II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
343 II (c, d, a, b, 2, S43, 0x2ad7d2bb); /* 63 */
344 II (b, c, d, a, 9, S44, 0xeb86d391); /* 64 */
361 ctx_dump(MD5_CTX* ctx)
363 static char buf[1024];
364 sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",
365 ctx->A, ctx->B, ctx->C, ctx->D,
366 ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));
373 MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len)
376 STRLEN fill = ctx->bytes_low & 0x3F;
379 static int ucount = 0;
380 fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx),
384 ctx->bytes_low += len;
385 if (ctx->bytes_low < len) /* wrap around */
389 STRLEN missing = 64 - fill;
391 Copy(buf, ctx->buffer + fill, len, U8);
394 Copy(buf, ctx->buffer + fill, missing, U8);
395 MD5Transform(ctx, ctx->buffer, 1);
402 MD5Transform(ctx, buf, blocks);
403 if ( (len &= 0x3F)) {
404 Copy(buf + (blocks << 6), ctx->buffer, len, U8);
410 MD5Final(U8* digest, MD5_CTX *ctx)
412 STRLEN fill = ctx->bytes_low & 0x3F;
413 STRLEN padlen = (fill < 56 ? 56 : 120) - fill;
414 U32 bits_low, bits_high;
416 fprintf(stderr," Final: %s\n", ctx_dump(ctx));
418 Copy(PADDING, ctx->buffer + fill, padlen, U8);
421 bits_low = ctx->bytes_low << 3;
422 bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low >> 29);
424 *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_low); fill += 4;
425 *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_high); fill += 4;
427 u2s(bits_low, ctx->buffer + fill); fill += 4;
428 u2s(bits_high, ctx->buffer + fill); fill += 4;
431 MD5Transform(ctx, ctx->buffer, fill >> 6);
433 fprintf(stderr," Result: %s\n", ctx_dump(ctx));
437 *(U32*)digest = BYTESWAP(ctx->A); digest += 4;
438 *(U32*)digest = BYTESWAP(ctx->B); digest += 4;
439 *(U32*)digest = BYTESWAP(ctx->C); digest += 4;
440 *(U32*)digest = BYTESWAP(ctx->D);
443 u2s(ctx->B, digest+4);
444 u2s(ctx->C, digest+8);
445 u2s(ctx->D, digest+12);
450 #define INT2PTR(any,d) (any)(d)
453 static MD5_CTX* get_md5_ctx(pTHX_ SV* sv)
457 if (!sv_derived_from(sv, "Digest::MD5"))
458 croak("Not a reference to a Digest::MD5 object");
460 for (mg = SvMAGIC(SvRV(sv)); mg; mg = mg->mg_moremagic) {
461 if (mg->mg_type == PERL_MAGIC_ext && mg->mg_virtual == &vtbl_md5) {
462 return (MD5_CTX *)mg->mg_ptr;
466 croak("Failed to get MD5_CTX pointer");
467 return (MD5_CTX*)0; /* some compilers insist on a return value */
470 static SV * new_md5_ctx(pTHX_ MD5_CTX *context, const char *klass)
473 SV *obj = newRV_noinc(sv);
478 sv_bless(obj, gv_stashpv(klass, 0));
483 sv_magicext(sv, NULL, PERL_MAGIC_ext, &vtbl_md5, (const char *)context, 0);
486 mg->mg_flags |= MGf_DUP;
493 static char* hex_16(const unsigned char* from, char* to)
495 static const char hexdigits[] = "0123456789abcdef";
496 const unsigned char *end = from + 16;
500 *d++ = hexdigits[(*from >> 4)];
501 *d++ = hexdigits[(*from & 0x0F)];
508 static char* base64_16(const unsigned char* from, char* to)
510 static const char base64[] =
511 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
512 const unsigned char *end = from + 16;
513 unsigned char c1, c2, c3;
518 *d++ = base64[c1>>2];
520 *d++ = base64[(c1 & 0x3) << 4];
525 *d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
526 *d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
527 *d++ = base64[c3 & 0x3F];
538 static SV* make_mortal_sv(pTHX_ const unsigned char *src, int type)
550 ret = hex_16(src, result);
554 ret = base64_16(src, result);
558 croak("Bad convertion type (%d)", type);
561 return sv_2mortal(newSVpv(ret,len));
565 /********************************************************************/
567 typedef PerlIO* InputStream;
569 MODULE = Digest::MD5 PACKAGE = Digest::MD5
579 if (!SvROK(xclass)) {
581 const char *sclass = SvPV(xclass, my_na);
582 New(55, context, 1, MD5_CTX);
583 ST(0) = sv_2mortal(new_md5_ctx(aTHX_ context, sclass));
585 context = get_md5_ctx(aTHX_ xclass);
594 MD5_CTX* cont = get_md5_ctx(aTHX_ self);
595 const char *myname = sv_reftype(SvRV(self),TRUE);
598 New(55, context, 1, MD5_CTX);
599 ST(0) = sv_2mortal(new_md5_ctx(aTHX_ context, myname));
600 memcpy(context,cont,sizeof(MD5_CTX));
613 MD5_CTX* context = get_md5_ctx(aTHX_ self);
618 for (i = 1; i < items; i++) {
619 U32 had_utf8 = SvUTF8(ST(i));
620 data = (unsigned char *)(SvPVbyte(ST(i), len));
621 MD5Update(context, data, len);
622 if (had_utf8) sv_utf8_upgrade(ST(i));
624 XSRETURN(1); /* self */
631 MD5_CTX* context = get_md5_ctx(aTHX_ self);
632 STRLEN fill = context->bytes_low & 0x3F;
633 #ifdef USE_HEAP_INSTEAD_OF_STACK
634 unsigned char* buffer;
636 unsigned char buffer[4096];
641 #ifdef USE_HEAP_INSTEAD_OF_STACK
642 New(0, buffer, 4096, unsigned char);
646 /* The MD5Update() function is faster if it can work with
647 * complete blocks. This will fill up any buffered block
650 STRLEN missing = 64 - fill;
651 if ( (n = PerlIO_read(fh, buffer, missing)) > 0)
652 MD5Update(context, buffer, n);
654 XSRETURN(1); /* self */
657 /* Process blocks until EOF or error */
658 while ( (n = PerlIO_read(fh, buffer, sizeof(buffer))) > 0) {
659 MD5Update(context, buffer, n);
661 #ifdef USE_HEAP_INSTEAD_OF_STACK
664 if (PerlIO_error(fh)) {
665 croak("Reading from filehandle failed");
669 croak("No filehandle passed");
671 XSRETURN(1); /* self */
677 Digest::MD5::digest = F_BIN
678 Digest::MD5::hexdigest = F_HEX
679 Digest::MD5::b64digest = F_B64
681 unsigned char digeststr[16];
683 MD5Final(digeststr, context);
684 MD5Init(context); /* In case it is reused */
685 ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
691 Digest::MD5::md5 = F_BIN
692 Digest::MD5::md5_hex = F_HEX
693 Digest::MD5::md5_base64 = F_B64
699 unsigned char digeststr[16];
703 if (PL_dowarn & G_WARN_ON) {
707 SV* sv = SvRV(ST(0));
708 if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
709 msg = "probably called as method";
711 msg = "called with reference argument";
714 else if (items > 1) {
715 data = (unsigned char *)SvPV(ST(0), len);
716 if (len == 11 && memEQ("Digest::MD5", data, 11)) {
717 msg = "probably called as class method";
719 else if (SvROK(ST(0))) {
720 SV* sv = SvRV(ST(0));
721 if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
722 msg = "probably called as method";
726 const char *f = (ix == F_BIN) ? "md5" :
727 (ix == F_HEX) ? "md5_hex" : "md5_base64";
728 warn("&Digest::MD5::%s function %s", f, msg);
732 for (i = 0; i < items; i++) {
733 U32 had_utf8 = SvUTF8(ST(i));
734 data = (unsigned char *)(SvPVbyte(ST(i), len));
735 MD5Update(&ctx, data, len);
736 if (had_utf8) sv_utf8_upgrade(ST(i));
738 MD5Final(digeststr, &ctx);
739 ST(0) = make_mortal_sv(aTHX_ digeststr, ix);