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 #ifndef PERL_UNUSED_VAR
47 # define PERL_UNUSED_VAR(x) ((void)x)
50 #ifndef PERL_MAGIC_ext
51 # define PERL_MAGIC_ext '~'
55 # define Newxz(v,n,t) Newz(0,v,n,t)
59 # define SvMAGIC_set(sv, mg) (SvMAGIC(sv) = (mg))
63 # define sv_magicext(sv, obj, type, vtbl, name, namlen) \
64 THX_sv_magicext(aTHX_ sv, obj, type, vtbl, name, namlen)
65 static MAGIC *THX_sv_magicext(pTHX_ SV *sv, SV *obj, int type,
66 MGVTBL const *vtbl, char const *name, I32 namlen)
70 /* exceeded intended usage of this reserve implementation */
73 mg->mg_virtual = (MGVTBL*)vtbl;
75 mg->mg_ptr = (char *)name;
77 (void) SvUPGRADE(sv, SVt_PVMG);
78 mg->mg_moremagic = SvMAGIC(sv);
88 # define SvPVbyte(sv, lp) (sv_utf8_downgrade((sv), 0), SvPV((sv), (lp)))
91 /* Perl does not guarantee that U32 is exactly 32 bits. Some system
92 * has no integral type with exactly 32 bits. For instance, A Cray has
93 * short, int and long all at 64 bits so we need to apply this macro
94 * to reduce U32 values to 32 bits at appropriate places. If U32
95 * really does have 32 bits then this is a no-op.
97 #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32)
98 #define TO32(x) ((x) & 0xFFFFffff)
99 #define TRUNC32(x) ((x) &= 0xFFFFffff)
102 #define TRUNC32(x) /*nothing*/
105 /* The MD5 algorithm is defined in terms of little endian 32-bit
106 * values. The following macros (and functions) allow us to convert
107 * between native integers and such values.
110 #ifndef U32_ALIGNMENT_REQUIRED
111 #if BYTEORDER == 0x1234 /* 32-bit little endian */
112 #define BYTESWAP(x) (x) /* no-op */
114 #elif BYTEORDER == 0x4321 /* 32-bit big endian */
115 #define BYTESWAP(x) ((((x)&0xFF)<<24) \
117 |(((x)&0x0000FF00)<<8) \
118 |(((x)&0x00FF0000)>>8) )
123 static void u2s(U32 u, U8* s)
125 *s++ = (U8)(u & 0xFF);
126 *s++ = (U8)((u >> 8) & 0xFF);
127 *s++ = (U8)((u >> 16) & 0xFF);
128 *s = (U8)((u >> 24) & 0xFF);
131 #define s2u(s,u) ((u) = (U32)(*s) | \
132 ((U32)(*(s+1)) << 8) | \
133 ((U32)(*(s+2)) << 16) | \
134 ((U32)(*(s+3)) << 24))
137 /* This structure keeps the current state of algorithm.
140 U32 A, B, C, D; /* current digest */
141 U32 bytes_low; /* counts bytes in message */
142 U32 bytes_high; /* turn it into a 64-bit counter */
143 U8 buffer[128]; /* collect complete 64 byte blocks */
146 #if defined(USE_ITHREADS) && defined(MGf_DUP)
147 STATIC int dup_md5_ctx(pTHX_ MAGIC *mg, CLONE_PARAMS *params)
150 PERL_UNUSED_VAR(params);
151 New(55, new_ctx, 1, MD5_CTX);
152 memcpy(new_ctx, mg->mg_ptr, sizeof(MD5_CTX));
153 mg->mg_ptr = (char *)new_ctx;
158 STATIC MGVTBL vtbl_md5 = {
180 /* Padding is added at the end of the message in order to fill a
181 * complete 64 byte block (- 8 bytes for the message length). The
182 * padding is also the reason the buffer in MD5_CTX have to be
185 static const unsigned char PADDING[64] = {
186 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
191 /* Constants for MD5Transform routine.
210 /* F, G, H and I are basic MD5 functions.
212 #define F(x, y, z) ((((x) & ((y) ^ (z))) ^ (z)))
213 #define G(x, y, z) F(z, x, y)
214 #define H(x, y, z) ((x) ^ (y) ^ (z))
215 #define I(x, y, z) ((y) ^ ((x) | (~z)))
217 /* ROTATE_LEFT rotates x left n bits.
219 #define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
221 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
222 * Rotation is separate from addition to prevent recomputation.
224 #define FF(a, b, c, d, s, ac) \
225 (a) += F ((b), (c), (d)) + (NEXTx) + (U32)(ac); \
227 (a) = ROTATE_LEFT ((a), (s)); \
231 #define GG(a, b, c, d, x, s, ac) \
232 (a) += G ((b), (c), (d)) + X[x] + (U32)(ac); \
234 (a) = ROTATE_LEFT ((a), (s)); \
238 #define HH(a, b, c, d, x, s, ac) \
239 (a) += H ((b), (c), (d)) + X[x] + (U32)(ac); \
241 (a) = ROTATE_LEFT ((a), (s)); \
245 #define II(a, b, c, d, x, s, ac) \
246 (a) += I ((b), (c), (d)) + X[x] + (U32)(ac); \
248 (a) = ROTATE_LEFT ((a), (s)); \
254 MD5Init(MD5_CTX *ctx)
263 ctx->bytes_low = ctx->bytes_high = 0;
268 MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks)
271 static int tcount = 0;
279 #ifndef U32_ALIGNMENT_REQUIRED
280 const U32 *x = (U32*)buf; /* really just type casting */
289 #if BYTEORDER == 0x1234 && !defined(U32_ALIGNMENT_REQUIRED)
293 U32 X[16]; /* converted values, used in round 2-4 */
297 #define NEXTx (tmp=*x++, *uptr++ = BYTESWAP(tmp))
299 #define NEXTx (s2u(buf,tmp), buf += 4, *uptr++ = tmp)
304 if (buf == ctx->buffer)
305 fprintf(stderr,"%5d: Transform ctx->buffer", ++tcount);
307 fprintf(stderr,"%5d: Transform %p (%d)", ++tcount, buf, blocks);
312 for (i = 0; i < 16; i++) {
313 fprintf(stderr,"%x,", x[i]);
315 fprintf(stderr,"]\n");
320 FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
321 FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
322 FF (c, d, a, b, S13, 0x242070db); /* 3 */
323 FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
324 FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
325 FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
326 FF (c, d, a, b, S13, 0xa8304613); /* 7 */
327 FF (b, c, d, a, S14, 0xfd469501); /* 8 */
328 FF (a, b, c, d, S11, 0x698098d8); /* 9 */
329 FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
330 FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
331 FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
332 FF (a, b, c, d, S11, 0x6b901122); /* 13 */
333 FF (d, a, b, c, S12, 0xfd987193); /* 14 */
334 FF (c, d, a, b, S13, 0xa679438e); /* 15 */
335 FF (b, c, d, a, S14, 0x49b40821); /* 16 */
338 GG (a, b, c, d, 1, S21, 0xf61e2562); /* 17 */
339 GG (d, a, b, c, 6, S22, 0xc040b340); /* 18 */
340 GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
341 GG (b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
342 GG (a, b, c, d, 5, S21, 0xd62f105d); /* 21 */
343 GG (d, a, b, c, 10, S22, 0x2441453); /* 22 */
344 GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
345 GG (b, c, d, a, 4, S24, 0xe7d3fbc8); /* 24 */
346 GG (a, b, c, d, 9, S21, 0x21e1cde6); /* 25 */
347 GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
348 GG (c, d, a, b, 3, S23, 0xf4d50d87); /* 27 */
349 GG (b, c, d, a, 8, S24, 0x455a14ed); /* 28 */
350 GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
351 GG (d, a, b, c, 2, S22, 0xfcefa3f8); /* 30 */
352 GG (c, d, a, b, 7, S23, 0x676f02d9); /* 31 */
353 GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
356 HH (a, b, c, d, 5, S31, 0xfffa3942); /* 33 */
357 HH (d, a, b, c, 8, S32, 0x8771f681); /* 34 */
358 HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
359 HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
360 HH (a, b, c, d, 1, S31, 0xa4beea44); /* 37 */
361 HH (d, a, b, c, 4, S32, 0x4bdecfa9); /* 38 */
362 HH (c, d, a, b, 7, S33, 0xf6bb4b60); /* 39 */
363 HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
364 HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
365 HH (d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
366 HH (c, d, a, b, 3, S33, 0xd4ef3085); /* 43 */
367 HH (b, c, d, a, 6, S34, 0x4881d05); /* 44 */
368 HH (a, b, c, d, 9, S31, 0xd9d4d039); /* 45 */
369 HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
370 HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
371 HH (b, c, d, a, 2, S34, 0xc4ac5665); /* 48 */
374 II (a, b, c, d, 0, S41, 0xf4292244); /* 49 */
375 II (d, a, b, c, 7, S42, 0x432aff97); /* 50 */
376 II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
377 II (b, c, d, a, 5, S44, 0xfc93a039); /* 52 */
378 II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
379 II (d, a, b, c, 3, S42, 0x8f0ccc92); /* 54 */
380 II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
381 II (b, c, d, a, 1, S44, 0x85845dd1); /* 56 */
382 II (a, b, c, d, 8, S41, 0x6fa87e4f); /* 57 */
383 II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
384 II (c, d, a, b, 6, S43, 0xa3014314); /* 59 */
385 II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
386 II (a, b, c, d, 4, S41, 0xf7537e82); /* 61 */
387 II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
388 II (c, d, a, b, 2, S43, 0x2ad7d2bb); /* 63 */
389 II (b, c, d, a, 9, S44, 0xeb86d391); /* 64 */
406 ctx_dump(MD5_CTX* ctx)
408 static char buf[1024];
409 sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",
410 ctx->A, ctx->B, ctx->C, ctx->D,
411 ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));
418 MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len)
421 STRLEN fill = ctx->bytes_low & 0x3F;
424 static int ucount = 0;
425 fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx),
429 ctx->bytes_low += len;
430 if (ctx->bytes_low < len) /* wrap around */
434 STRLEN missing = 64 - fill;
436 Copy(buf, ctx->buffer + fill, len, U8);
439 Copy(buf, ctx->buffer + fill, missing, U8);
440 MD5Transform(ctx, ctx->buffer, 1);
447 MD5Transform(ctx, buf, blocks);
448 if ( (len &= 0x3F)) {
449 Copy(buf + (blocks << 6), ctx->buffer, len, U8);
455 MD5Final(U8* digest, MD5_CTX *ctx)
457 STRLEN fill = ctx->bytes_low & 0x3F;
458 STRLEN padlen = (fill < 56 ? 56 : 120) - fill;
459 U32 bits_low, bits_high;
461 fprintf(stderr," Final: %s\n", ctx_dump(ctx));
463 Copy(PADDING, ctx->buffer + fill, padlen, U8);
466 bits_low = ctx->bytes_low << 3;
467 bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low >> 29);
469 *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_low); fill += 4;
470 *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_high); fill += 4;
472 u2s(bits_low, ctx->buffer + fill); fill += 4;
473 u2s(bits_high, ctx->buffer + fill); fill += 4;
476 MD5Transform(ctx, ctx->buffer, fill >> 6);
478 fprintf(stderr," Result: %s\n", ctx_dump(ctx));
482 *(U32*)digest = BYTESWAP(ctx->A); digest += 4;
483 *(U32*)digest = BYTESWAP(ctx->B); digest += 4;
484 *(U32*)digest = BYTESWAP(ctx->C); digest += 4;
485 *(U32*)digest = BYTESWAP(ctx->D);
488 u2s(ctx->B, digest+4);
489 u2s(ctx->C, digest+8);
490 u2s(ctx->D, digest+12);
495 #define INT2PTR(any,d) (any)(d)
498 static MD5_CTX* get_md5_ctx(pTHX_ SV* sv)
502 if (!sv_derived_from(sv, "Digest::MD5"))
503 croak("Not a reference to a Digest::MD5 object");
505 for (mg = SvMAGIC(SvRV(sv)); mg; mg = mg->mg_moremagic) {
506 if (mg->mg_type == PERL_MAGIC_ext && mg->mg_virtual == &vtbl_md5) {
507 return (MD5_CTX *)mg->mg_ptr;
511 croak("Failed to get MD5_CTX pointer");
512 return (MD5_CTX*)0; /* some compilers insist on a return value */
515 static SV * new_md5_ctx(pTHX_ MD5_CTX *context, const char *klass)
518 SV *obj = newRV_noinc(sv);
523 sv_bless(obj, gv_stashpv(klass, 0));
528 sv_magicext(sv, NULL, PERL_MAGIC_ext, &vtbl_md5, (const char *)context, 0);
530 #if defined(USE_ITHREADS) && defined(MGf_DUP)
531 mg->mg_flags |= MGf_DUP;
538 static char* hex_16(const unsigned char* from, char* to)
540 static const char hexdigits[] = "0123456789abcdef";
541 const unsigned char *end = from + 16;
545 *d++ = hexdigits[(*from >> 4)];
546 *d++ = hexdigits[(*from & 0x0F)];
553 static char* base64_16(const unsigned char* from, char* to)
555 static const char base64[] =
556 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
557 const unsigned char *end = from + 16;
558 unsigned char c1, c2, c3;
563 *d++ = base64[c1>>2];
565 *d++ = base64[(c1 & 0x3) << 4];
570 *d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
571 *d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
572 *d++ = base64[c3 & 0x3F];
583 static SV* make_mortal_sv(pTHX_ const unsigned char *src, int type)
595 ret = hex_16(src, result);
599 ret = base64_16(src, result);
603 croak("Bad conversion type (%d)", type);
606 return sv_2mortal(newSVpv(ret,len));
610 /********************************************************************/
612 typedef PerlIO* InputStream;
614 MODULE = Digest::MD5 PACKAGE = Digest::MD5
624 if (!SvROK(xclass)) {
626 const char *sclass = SvPV(xclass, my_na);
627 New(55, context, 1, MD5_CTX);
628 ST(0) = sv_2mortal(new_md5_ctx(aTHX_ context, sclass));
630 context = get_md5_ctx(aTHX_ xclass);
639 MD5_CTX* cont = get_md5_ctx(aTHX_ self);
640 const char *myname = sv_reftype(SvRV(self),TRUE);
643 New(55, context, 1, MD5_CTX);
644 ST(0) = sv_2mortal(new_md5_ctx(aTHX_ context, myname));
645 memcpy(context,cont,sizeof(MD5_CTX));
658 MD5_CTX* context = get_md5_ctx(aTHX_ self);
663 for (i = 1; i < items; i++) {
664 U32 had_utf8 = SvUTF8(ST(i));
665 data = (unsigned char *)(SvPVbyte(ST(i), len));
666 MD5Update(context, data, len);
667 if (had_utf8) sv_utf8_upgrade(ST(i));
669 XSRETURN(1); /* self */
676 MD5_CTX* context = get_md5_ctx(aTHX_ self);
677 STRLEN fill = context->bytes_low & 0x3F;
678 #ifdef USE_HEAP_INSTEAD_OF_STACK
679 unsigned char* buffer;
681 unsigned char buffer[4096];
686 #ifdef USE_HEAP_INSTEAD_OF_STACK
687 New(0, buffer, 4096, unsigned char);
691 /* The MD5Update() function is faster if it can work with
692 * complete blocks. This will fill up any buffered block
695 STRLEN missing = 64 - fill;
696 if ( (n = PerlIO_read(fh, buffer, missing)) > 0)
697 MD5Update(context, buffer, n);
699 XSRETURN(1); /* self */
702 /* Process blocks until EOF or error */
703 while ( (n = PerlIO_read(fh, buffer, sizeof(buffer))) > 0) {
704 MD5Update(context, buffer, n);
706 #ifdef USE_HEAP_INSTEAD_OF_STACK
709 if (PerlIO_error(fh)) {
710 croak("Reading from filehandle failed");
714 croak("No filehandle passed");
716 XSRETURN(1); /* self */
722 Digest::MD5::digest = F_BIN
723 Digest::MD5::hexdigest = F_HEX
724 Digest::MD5::b64digest = F_B64
726 unsigned char digeststr[16];
728 MD5Final(digeststr, context);
729 MD5Init(context); /* In case it is reused */
730 ST(0) = make_mortal_sv(aTHX_ digeststr, ix);
736 Digest::MD5::md5 = F_BIN
737 Digest::MD5::md5_hex = F_HEX
738 Digest::MD5::md5_base64 = F_B64
744 unsigned char digeststr[16];
748 if (PL_dowarn & G_WARN_ON) {
752 SV* sv = SvRV(ST(0));
753 if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
754 msg = "probably called as method";
756 msg = "called with reference argument";
759 else if (items > 1) {
760 data = (unsigned char *)SvPV(ST(0), len);
761 if (len == 11 && memEQ("Digest::MD5", data, 11)) {
762 msg = "probably called as class method";
764 else if (SvROK(ST(0))) {
765 SV* sv = SvRV(ST(0));
766 if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
767 msg = "probably called as method";
771 const char *f = (ix == F_BIN) ? "md5" :
772 (ix == F_HEX) ? "md5_hex" : "md5_base64";
773 warn("&Digest::MD5::%s function %s", f, msg);
777 for (i = 0; i < items; i++) {
778 U32 had_utf8 = SvUTF8(ST(i));
779 data = (unsigned char *)(SvPVbyte(ST(i), len));
780 MD5Update(&ctx, data, len);
781 if (had_utf8) sv_utf8_upgrade(ST(i));
783 MD5Final(digeststr, &ctx);
784 ST(0) = make_mortal_sv(aTHX_ digeststr, ix);