1 /* $Id: MD5.xs,v 1.26 2000/09/18 14:27:44 gisle Exp $ */
4 * This library is free software; you can redistribute it and/or
5 * modify it under the same terms as Perl itself.
7 * Copyright 1998-2000 Gisle Aas.
8 * Copyright 1995-1996 Neil Winton.
9 * Copyright 1991-1992 RSA Data Security, Inc.
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 1231 which
13 * comes with this message:
15 * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
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
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.
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.
33 * These notices must be retained in any copies of any part of this
34 * documentation and/or software.
47 /*#define MD5_DEBUG /**/
49 /* Perl does not guarantee that U32 is exactly 32 bits. Some system
50 * has no integral type with exactly 32 bits. For instance, A Cray has
51 * short, int and long all at 64 bits so we need to apply this macro
52 * to reduce U32 values to 32 bits at appropriate places. If U32
53 * really does have 32 bits then this is a no-op.
55 #if BYTEORDER > 0x4321 || defined(TRUNCATE_U32)
56 #define TO32(x) ((x) & 0xFFFFffff)
57 #define TRUNC32(x) ((x) &= 0xFFFFffff)
60 #define TRUNC32(x) /*nothing*/
63 /* The MD5 algorithm is defined in terms of little endian 32-bit
64 * values. The following macros (and functions) allow us to convert
65 * between native integers and such values.
68 #ifndef U32_ALIGNMENT_REQUIRED
69 #if BYTEORDER == 0x1234 /* 32-bit little endian */
70 #define BYTESWAP(x) (x) /* no-op */
72 #elif BYTEORDER == 0x4321 /* 32-bit big endian */
73 #define BYTESWAP(x) ((((x)&0xFF)<<24) \
75 |(((x)&0x0000FF00)<<8) \
76 |(((x)&0x00FF0000)>>8) )
81 static void u2s(U32 u, U8* s)
84 *s++ = (u >> 8) & 0xFF;
85 *s++ = (u >> 16) & 0xFF;
86 *s = (u >> 24) & 0xFF;
89 #define s2u(s,u) ((u) = (U32)(*s) | \
90 ((U32)(*(s+1)) << 8) | \
91 ((U32)(*(s+2)) << 16) | \
92 ((U32)(*(s+3)) << 24))
95 #define MD5_CTX_SIGNATURE 200003165
97 /* This stucture keeps the current state of algorithm.
100 U32 signature; /* safer cast in get_md5_ctx() */
101 U32 A, B, C, D; /* current digest */
102 U32 bytes_low; /* counts bytes in message */
103 U32 bytes_high; /* turn it into a 64-bit counter */
104 U8 buffer[128]; /* collect complete 64 byte blocks */
108 /* Padding is added at the end of the message in order to fill a
109 * complete 64 byte block (- 8 bytes for the message length). The
110 * padding is also the reason the buffer in MD5_CTX have to be
113 static unsigned char PADDING[64] = {
114 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
119 /* Constants for MD5Transform routine.
138 /* F, G, H and I are basic MD5 functions.
140 #define F(x, y, z) (((x) & ((y) ^ (z)) ^ (z)))
141 #define G(x, y, z) F(z, x, y)
142 #define H(x, y, z) ((x) ^ (y) ^ (z))
143 #define I(x, y, z) ((y) ^ ((x) | (~z)))
145 /* ROTATE_LEFT rotates x left n bits.
147 #define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
149 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
150 * Rotation is separate from addition to prevent recomputation.
152 #define FF(a, b, c, d, s, ac) \
153 (a) += F ((b), (c), (d)) + (NEXTx) + (U32)(ac); \
155 (a) = ROTATE_LEFT ((a), (s)); \
159 #define GG(a, b, c, d, x, s, ac) \
160 (a) += G ((b), (c), (d)) + X[x] + (U32)(ac); \
162 (a) = ROTATE_LEFT ((a), (s)); \
166 #define HH(a, b, c, d, x, s, ac) \
167 (a) += H ((b), (c), (d)) + X[x] + (U32)(ac); \
169 (a) = ROTATE_LEFT ((a), (s)); \
173 #define II(a, b, c, d, x, s, ac) \
174 (a) += I ((b), (c), (d)) + X[x] + (U32)(ac); \
176 (a) = ROTATE_LEFT ((a), (s)); \
182 MD5Init(MD5_CTX *ctx)
191 ctx->bytes_low = ctx->bytes_high = 0;
196 MD5Transform(MD5_CTX* ctx, const U8* buf, STRLEN blocks)
198 static int tcount = 0;
205 #ifndef U32_ALIGNMENT_REQUIRED
206 const U32 *x = (U32*)buf; /* really just type casting */
215 #if BYTEORDER == 0x1234 && !defined(U32_ALIGNMENT_REQUIRED)
219 U32 X[16]; /* converted values, used in round 2-4 */
223 #define NEXTx (tmp=*x++, *uptr++ = BYTESWAP(tmp))
225 #define NEXTx (s2u(buf,tmp), buf += 4, *uptr++ = tmp)
230 if (buf == ctx->buffer)
231 fprintf(stderr,"%5d: Transform ctx->buffer", ++tcount);
233 fprintf(stderr,"%5d: Transform %p (%d)", ++tcount, buf, blocks);
238 for (i = 0; i < 16; i++) {
239 fprintf(stderr,"%x,", x[i]);
241 fprintf(stderr,"]\n");
246 FF (a, b, c, d, S11, 0xd76aa478); /* 1 */
247 FF (d, a, b, c, S12, 0xe8c7b756); /* 2 */
248 FF (c, d, a, b, S13, 0x242070db); /* 3 */
249 FF (b, c, d, a, S14, 0xc1bdceee); /* 4 */
250 FF (a, b, c, d, S11, 0xf57c0faf); /* 5 */
251 FF (d, a, b, c, S12, 0x4787c62a); /* 6 */
252 FF (c, d, a, b, S13, 0xa8304613); /* 7 */
253 FF (b, c, d, a, S14, 0xfd469501); /* 8 */
254 FF (a, b, c, d, S11, 0x698098d8); /* 9 */
255 FF (d, a, b, c, S12, 0x8b44f7af); /* 10 */
256 FF (c, d, a, b, S13, 0xffff5bb1); /* 11 */
257 FF (b, c, d, a, S14, 0x895cd7be); /* 12 */
258 FF (a, b, c, d, S11, 0x6b901122); /* 13 */
259 FF (d, a, b, c, S12, 0xfd987193); /* 14 */
260 FF (c, d, a, b, S13, 0xa679438e); /* 15 */
261 FF (b, c, d, a, S14, 0x49b40821); /* 16 */
264 GG (a, b, c, d, 1, S21, 0xf61e2562); /* 17 */
265 GG (d, a, b, c, 6, S22, 0xc040b340); /* 18 */
266 GG (c, d, a, b, 11, S23, 0x265e5a51); /* 19 */
267 GG (b, c, d, a, 0, S24, 0xe9b6c7aa); /* 20 */
268 GG (a, b, c, d, 5, S21, 0xd62f105d); /* 21 */
269 GG (d, a, b, c, 10, S22, 0x2441453); /* 22 */
270 GG (c, d, a, b, 15, S23, 0xd8a1e681); /* 23 */
271 GG (b, c, d, a, 4, S24, 0xe7d3fbc8); /* 24 */
272 GG (a, b, c, d, 9, S21, 0x21e1cde6); /* 25 */
273 GG (d, a, b, c, 14, S22, 0xc33707d6); /* 26 */
274 GG (c, d, a, b, 3, S23, 0xf4d50d87); /* 27 */
275 GG (b, c, d, a, 8, S24, 0x455a14ed); /* 28 */
276 GG (a, b, c, d, 13, S21, 0xa9e3e905); /* 29 */
277 GG (d, a, b, c, 2, S22, 0xfcefa3f8); /* 30 */
278 GG (c, d, a, b, 7, S23, 0x676f02d9); /* 31 */
279 GG (b, c, d, a, 12, S24, 0x8d2a4c8a); /* 32 */
282 HH (a, b, c, d, 5, S31, 0xfffa3942); /* 33 */
283 HH (d, a, b, c, 8, S32, 0x8771f681); /* 34 */
284 HH (c, d, a, b, 11, S33, 0x6d9d6122); /* 35 */
285 HH (b, c, d, a, 14, S34, 0xfde5380c); /* 36 */
286 HH (a, b, c, d, 1, S31, 0xa4beea44); /* 37 */
287 HH (d, a, b, c, 4, S32, 0x4bdecfa9); /* 38 */
288 HH (c, d, a, b, 7, S33, 0xf6bb4b60); /* 39 */
289 HH (b, c, d, a, 10, S34, 0xbebfbc70); /* 40 */
290 HH (a, b, c, d, 13, S31, 0x289b7ec6); /* 41 */
291 HH (d, a, b, c, 0, S32, 0xeaa127fa); /* 42 */
292 HH (c, d, a, b, 3, S33, 0xd4ef3085); /* 43 */
293 HH (b, c, d, a, 6, S34, 0x4881d05); /* 44 */
294 HH (a, b, c, d, 9, S31, 0xd9d4d039); /* 45 */
295 HH (d, a, b, c, 12, S32, 0xe6db99e5); /* 46 */
296 HH (c, d, a, b, 15, S33, 0x1fa27cf8); /* 47 */
297 HH (b, c, d, a, 2, S34, 0xc4ac5665); /* 48 */
300 II (a, b, c, d, 0, S41, 0xf4292244); /* 49 */
301 II (d, a, b, c, 7, S42, 0x432aff97); /* 50 */
302 II (c, d, a, b, 14, S43, 0xab9423a7); /* 51 */
303 II (b, c, d, a, 5, S44, 0xfc93a039); /* 52 */
304 II (a, b, c, d, 12, S41, 0x655b59c3); /* 53 */
305 II (d, a, b, c, 3, S42, 0x8f0ccc92); /* 54 */
306 II (c, d, a, b, 10, S43, 0xffeff47d); /* 55 */
307 II (b, c, d, a, 1, S44, 0x85845dd1); /* 56 */
308 II (a, b, c, d, 8, S41, 0x6fa87e4f); /* 57 */
309 II (d, a, b, c, 15, S42, 0xfe2ce6e0); /* 58 */
310 II (c, d, a, b, 6, S43, 0xa3014314); /* 59 */
311 II (b, c, d, a, 13, S44, 0x4e0811a1); /* 60 */
312 II (a, b, c, d, 4, S41, 0xf7537e82); /* 61 */
313 II (d, a, b, c, 11, S42, 0xbd3af235); /* 62 */
314 II (c, d, a, b, 2, S43, 0x2ad7d2bb); /* 63 */
315 II (b, c, d, a, 9, S44, 0xeb86d391); /* 64 */
332 ctx_dump(MD5_CTX* ctx)
334 static char buf[1024];
335 sprintf(buf, "{A=%x,B=%x,C=%x,D=%x,%d,%d(%d)}",
336 ctx->A, ctx->B, ctx->C, ctx->D,
337 ctx->bytes_low, ctx->bytes_high, (ctx->bytes_low&0x3F));
344 MD5Update(MD5_CTX* ctx, const U8* buf, STRLEN len)
347 STRLEN fill = ctx->bytes_low & 0x3F;
350 static int ucount = 0;
351 fprintf(stderr,"%5i: Update(%s, %p, %d)\n", ++ucount, ctx_dump(ctx),
355 ctx->bytes_low += len;
356 if (ctx->bytes_low < len) /* wrap around */
360 STRLEN missing = 64 - fill;
362 Copy(buf, ctx->buffer + fill, len, U8);
365 Copy(buf, ctx->buffer + fill, missing, U8);
366 MD5Transform(ctx, ctx->buffer, 1);
373 MD5Transform(ctx, buf, blocks);
374 if ( (len &= 0x3F)) {
375 Copy(buf + (blocks << 6), ctx->buffer, len, U8);
381 MD5Final(U8* digest, MD5_CTX *ctx)
383 STRLEN fill = ctx->bytes_low & 0x3F;
384 STRLEN padlen = (fill < 56 ? 56 : 120) - fill;
385 U32 bits_low, bits_high;
387 fprintf(stderr," Final: %s\n", ctx_dump(ctx));
389 Copy(PADDING, ctx->buffer + fill, padlen, U8);
392 bits_low = ctx->bytes_low << 3;
393 bits_high = (ctx->bytes_high << 3) | (ctx->bytes_low >> 29);
395 *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_low); fill += 4;
396 *(U32*)(ctx->buffer + fill) = BYTESWAP(bits_high); fill += 4;
398 u2s(bits_low, ctx->buffer + fill); fill += 4;
399 u2s(bits_high, ctx->buffer + fill); fill += 4;
402 MD5Transform(ctx, ctx->buffer, fill >> 6);
404 fprintf(stderr," Result: %s\n", ctx_dump(ctx));
408 *(U32*)digest = BYTESWAP(ctx->A); digest += 4;
409 *(U32*)digest = BYTESWAP(ctx->B); digest += 4;
410 *(U32*)digest = BYTESWAP(ctx->C); digest += 4;
411 *(U32*)digest = BYTESWAP(ctx->D);
414 u2s(ctx->B, digest+4);
415 u2s(ctx->C, digest+8);
416 u2s(ctx->D, digest+12);
421 #define INT2PTR(any,d) (any)(d)
424 static MD5_CTX* get_md5_ctx(SV* sv)
429 MD5_CTX* ctx = INT2PTR(MD5_CTX*, SvIV(sv));
430 if (ctx && ctx->signature == MD5_CTX_SIGNATURE) {
435 croak("Not a reference to a Digest::MD5 object");
436 return (MD5_CTX*)0; /* some compilers insist on a return value */
440 static char* hex_16(const unsigned char* from, char* to)
442 static char *hexdigits = "0123456789abcdef";
443 const unsigned char *end = from + 16;
447 *d++ = hexdigits[(*from >> 4)];
448 *d++ = hexdigits[(*from & 0x0F)];
455 static char* base64_16(const unsigned char* from, char* to)
457 static char* base64 =
458 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
459 const unsigned char *end = from + 16;
460 unsigned char c1, c2, c3;
465 *d++ = base64[c1>>2];
467 *d++ = base64[(c1 & 0x3) << 4];
472 *d++ = base64[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
473 *d++ = base64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
474 *d++ = base64[c3 & 0x3F];
485 static SV* make_mortal_sv(const unsigned char *src, int type)
497 ret = hex_16(src, result);
501 ret = base64_16(src, result);
505 croak("Bad convertion type (%d)", type);
508 return sv_2mortal(newSVpv(ret,len));
512 /********************************************************************/
514 typedef PerlIO* InputStream;
516 MODULE = Digest::MD5 PACKAGE = Digest::MD5
526 if (!SvROK(xclass)) {
528 char *sclass = SvPV(xclass, my_na);
529 New(55, context, 1, MD5_CTX);
530 context->signature = MD5_CTX_SIGNATURE;
531 ST(0) = sv_newmortal();
532 sv_setref_pv(ST(0), sclass, (void*)context);
533 SvREADONLY_on(SvRV(ST(0)));
535 context = get_md5_ctx(xclass);
550 MD5_CTX* context = get_md5_ctx(self);
555 for (i = 1; i < items; i++) {
556 data = (unsigned char *)(SvPV(ST(i), len));
557 MD5Update(context, data, len);
559 XSRETURN(1); /* self */
566 MD5_CTX* context = get_md5_ctx(self);
567 STRLEN fill = context->bytes_low & 0x3F;
568 unsigned char buffer[4096];
573 /* The MD5Update() function is faster if it can work with
574 * complete blocks. This will fill up any buffered block
577 STRLEN missing = 64 - fill;
578 if ( (n = PerlIO_read(fh, buffer, missing)))
579 MD5Update(context, buffer, n);
581 XSRETURN(1); /* self */
584 /* Process blocks until EOF */
585 while ( (n = PerlIO_read(fh, buffer, sizeof(buffer)))) {
586 MD5Update(context, buffer, n);
589 XSRETURN(1); /* self */
595 Digest::MD5::digest = F_BIN
596 Digest::MD5::hexdigest = F_HEX
597 Digest::MD5::b64digest = F_B64
599 unsigned char digeststr[16];
601 MD5Final(digeststr, context);
602 MD5Init(context); /* In case it is reused */
603 ST(0) = make_mortal_sv(digeststr, ix);
609 Digest::MD5::md5 = F_BIN
610 Digest::MD5::md5_hex = F_HEX
611 Digest::MD5::md5_base64 = F_B64
617 unsigned char digeststr[16];
620 for (i = 0; i < items; i++) {
621 data = (unsigned char *)(SvPV(ST(i), len));
622 MD5Update(&ctx, data, len);
624 MD5Final(digeststr, &ctx);
625 ST(0) = make_mortal_sv(digeststr, ix);