/* $Id: MD5.xs,v 1.42 2003/12/06 22:35:16 gisle Exp $ */
/*
* modify it under the same terms as Perl itself.
*
* Copyright 1998-2000 Gisle Aas.
* Copyright 1995-1996 Neil Winton.
* Copyright 1991-1992 RSA Data Security, Inc.
*
* This code is derived from Neil Winton's MD5-1.7 Perl module, which in
* turn is derived from the reference implementation in RFC 1321 which
* comes with this message:
*
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
* rights reserved.
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD5 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD5 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
*/
#ifdef __cplusplus
extern "C" {
#endif
#define PERL_NO_GET_CONTEXT /* we want efficiency */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus
}
#endif
#ifndef PERL_VERSION
# include <patchlevel.h>
# include <could_not_find_Perl_patchlevel.h>
# endif
# define PERL_REVISION 5
# define PERL_VERSION PATCHLEVEL
# define PERL_SUBVERSION SUBVERSION
#endif
#endif
#ifdef G_WARN_ON
#else
#endif
#ifdef SvPVbyte
/* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
static char *
{
sv_utf8_downgrade(sv,0);
}
#endif
#else
#endif
#ifndef dTHX
#define pTHX_
#define aTHX_
#endif
/* Perl does not guarantee that U32 is exactly 32 bits. Some system
* has no integral type with exactly 32 bits. For instance, A Cray has
* short, int and long all at 64 bits so we need to apply this macro
* to reduce U32 values to 32 bits at appropriate places. If U32
* really does have 32 bits then this is a no-op.
*/
#define TO32(x) ((x) & 0xFFFFffff)
#define TRUNC32(x) ((x) &= 0xFFFFffff)
#else
#define TO32(x) (x)
#define TRUNC32(x) /*nothing*/
#endif
/* The MD5 algorithm is defined in terms of little endian 32-bit
* values. The following macros (and functions) allow us to convert
* between native integers and such values.
*/
#ifndef U32_ALIGNMENT_REQUIRED
#define BYTESWAP(x) (x) /* no-op */
|(((x)>>24)&0xFF) \
|(((x)&0x0000FF00)<<8) \
|(((x)&0x00FF0000)>>8) )
#endif
#endif
#ifndef BYTESWAP
{
*s++ = (U8)(u & 0xFF);
}
#endif
#define MD5_CTX_SIGNATURE 200003165
/* This stucture keeps the current state of algorithm.
*/
typedef struct {
U32 A, B, C, D; /* current digest */
} MD5_CTX;
/* Padding is added at the end of the message in order to fill a
* complete 64 byte block (- 8 bytes for the message length). The
* padding is also the reason the buffer in MD5_CTX have to be
* 128 bytes.
*/
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) ((((x) & ((y) ^ (z))) ^ (z)))
#define G(x, y, z) F(z, x, y)
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n) | ((x) >> (32-(n)))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
* Rotation is separate from addition to prevent recomputation.
*/
TRUNC32((a)); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TRUNC32((a));
TRUNC32((a)); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TRUNC32((a));
TRUNC32((a)); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TRUNC32((a));
TRUNC32((a)); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TRUNC32((a));
static void
{
/* Start state */
ctx->A = 0x67452301;
ctx->B = 0xefcdab89;
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
/* message length */
}
static void
{
#ifdef MD5_DEBUG
static int tcount = 0;
#endif
#ifndef U32_ALIGNMENT_REQUIRED
#endif
do {
U32 a = A;
U32 b = B;
U32 c = C;
U32 d = D;
const U32 *X = x;
#define NEXTx (*x++)
#else
#ifdef BYTESWAP
#else
#endif
#endif
#ifdef MD5_DEBUG
else
{
int i;
for (i = 0; i < 16; i++) {
}
}
#endif
/* Round 1 */
/* Round 2 */
/* Round 3 */
/* Round 4 */
A += a; TRUNC32(A);
B += b; TRUNC32(B);
C += c; TRUNC32(C);
D += d; TRUNC32(D);
} while (--blocks);
ctx->A = A;
ctx->B = B;
ctx->C = C;
ctx->D = D;
}
#ifdef MD5_DEBUG
static char*
{
static char buf[1024];
return buf;
}
#endif
static void
{
#ifdef MD5_DEBUG
static int ucount = 0;
#endif
ctx->bytes_high++;
if (fill) {
return;
}
}
if (blocks)
if ( (len &= 0x3F)) {
}
}
static void
{
#ifdef MD5_DEBUG
#endif
#ifdef BYTESWAP
#else
#endif
#ifdef MD5_DEBUG
#endif
#ifdef BYTESWAP
#else
#endif
}
#ifndef INT2PTR
#endif
{
return ctx;
}
}
}
croak("Not a reference to a Digest::MD5 object");
return (MD5_CTX*)0; /* some compilers insist on a return value */
}
{
static char *hexdigits = "0123456789abcdef";
char *d = to;
from++;
}
*d = '\0';
return to;
}
{
static char* base64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *d = to;
while (1) {
break;
}
}
*d = '\0';
return to;
}
/* Formats */
#define F_BIN 0
#define F_HEX 1
#define F_B64 2
{
char result[33];
char *ret;
switch (type) {
case F_BIN:
len = 16;
break;
case F_HEX:
len = 32;
break;
case F_B64:
len = 22;
break;
default:
break;
}
}
/********************************************************************/
typedef PerlIO* InputStream;
void
ST(0) = sv_newmortal();
} else {
}
XSRETURN(1);
void
ST(0) = sv_newmortal();
XSRETURN(1);
void
CODE:
void
int i;
unsigned char *data;
for (i = 1; i < items; i++) {
}
void
unsigned char buffer[4096];
int n;
CODE:
if (fh) {
if (fill) {
/* The MD5Update() function is faster if it can work with
* complete blocks. This will fill up any buffered block
* first.
*/
else
}
/* Process blocks until EOF or error */
}
if (PerlIO_error(fh)) {
croak("Reading from filehandle failed");
}
}
else {
croak("No filehandle passed");
}
void
unsigned char digeststr[16];
XSRETURN(1);
void
md5(...)
int i;
unsigned char *data;
unsigned char digeststr[16];
if (DOWARN) {
char *msg = 0;
if (items == 1) {
msg = "probably called as method";
else
msg = "called with reference argument";
}
}
else if (items > 1) {
msg = "probably called as class method";
}
}
if (msg) {
}
}
for (i = 0; i < items; i++) {
}
XSRETURN(1);