initial commit [141.14.140.180,mike]

This commit is contained in:
2026-08-10 16:12:09 +02:00
commit c534ea1c79
66 changed files with 9244 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
Revision history for Perl extension MD5.
*** 96/06/20 Version 1.7
MD5 is now completely 64-bit clean (I hope). The basic MD5 code uses
32-bit quantities and requires a typedef UINT4 to be defined in
global.h. Perl configuration data (the value of BYTEORDER) is used to
determine if unsigned longs have 4 or 8 bytes. On 64-bit platforms (eg
DEC Alpha) then it assumes that "unsigned int" will be a 32-bit type.
If this is incorrect then adding -DUINT4_IS_LONG to the DEFINES line in
Makefile.PL will override this.
On some machines (at least Cray that I know of) there is no 32-bit
integer type. In this case defining TRUNCATE_UINT4 (which is done
automatically for a Cray) will ensure that 64-bit values are masked
down to 32 bits. I have done my best to test this but without easy
access to a true 64-bit machine I can not totally guarantee it (unless
anyone wants to lend me a spare Cray :-)
There is one remaining limitation for 64-bit enabled processors. The
amount of data passed to any single call to the underlying MD5
routines is limited to (2^32 - 1) bytes -- that's 4 gigabytes. I'm
sorry if that's a real problem for you ...
And finally, a minor complilation warning (unsigned char * used with
function having char * prototype) has also been eliminated.
*** 96/04/09 Version 1.6
Re-generated module framework using h2xs to pick up the latest module
conventions for versions etc. You can now say "use MD5 1.6;" and things
should work correctly. MD5.pod has been integrated into MD5.pm and
CHANGES renamed to Changes. There is a fairly comprehensive test.pl
which can be invoked via "make test". There are no functional changes
to the MD5 routines themselves.
*** 96/03/14 Version 1.5.3
Fixed addfile method to accept type-glob references for the file-handle
(eg \*STDOUT). This is more consistent with other routines and is now the
recommended way of passing file-handles. The documentation now gives more
examples as to how the routines might be used.
*** 96/03/12 Version 1.5.2
Minor fixes from Christopher J Madsen <madsen@computek.net> to provide
support for building on OS/2 (and to work arround a perl -w bug).
Remove warning about possible difference between add('foo', 'bar') and
add('foobar'). This is not true (it may have been true in the earliest
version of the module but is no longer the case).
*** 96/03/08 Version 1.5.1
Add CHANGES file to make it easier for people to figure out what has
been going on. (Meant to do this as part of 1.5)
*** 96/03/05 Version 1.5
Add hash() and hexhash() methods at the suggestion/request of Gary
Howland <gary@kampai.euronet.nl> before inclusion in a wider library
of cryptography modules.
*** 96/02/27 Version 1.4
Finally fixed the pesky Solaris dynamic loading bug. All kudos to Ken
Pizzini <kenp@spry.com>!
*** 95/11/29 Version 1.3.1
Add explanations of current known problems.
*** 95/06/02 Version 1.3
Fix problems with scope resolution in addfile() reported by
Jean-Claude Giese <Jean-Claude.Giese@loria.fr>. Basically ARGV is
always implicitly in package main while other filehandles aren't.
*** 95/05/23 Version 1.2.1
[Changes pre 1.2.1 not recorded]
SCCS ID @(#)Changes 1.5 96/06/28
+13
View File
@@ -0,0 +1,13 @@
README Guess what?
MANIFEST This file
MD5.pm MD5 Perl Module
MD5.xs MD5 Perl 'XS' source file
typemap Supplementary typemap
Makefile.PL Perl Makefile builder
md5c.c MD5 C source from RFC 1321
md5.h Header for above
global.h ditto
test.pl Test suite using standard Perl conventions
Changes Version history
examples/mddriver.pl Example driver script after mddriver.c in RFC 1321
examples/twdigest.pl Example code to format a digest like Tripwire
+263
View File
@@ -0,0 +1,263 @@
# SCCS ID @(#)MD5.pm 1.9 96/06/28
package MD5;
use strict;
use vars qw($VERSION @ISA @EXPORT);
require Exporter;
require DynaLoader;
require AutoLoader;
@ISA = qw(Exporter AutoLoader DynaLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT = qw(
);
$VERSION = '1.7';
bootstrap MD5 $VERSION;
# Preloaded methods go here.
sub addfile
{
no strict 'refs'; # Countermand any strct refs in force so that we
# can still handle file-handle names.
my ($self, $handle) = @_;
my ($package, $file, $line) = caller;
my ($data) = '';
if (!ref($handle))
{
# Old-style passing of filehandle by name. We need to add
# the calling package scope qualifier, if there is not one
# supplied already.
$handle = $package . '::' . $handle unless ($handle =~ /(\:\:|\')/);
}
while (read($handle, $data, 1024))
{
$self->add($data);
}
}
sub hexdigest
{
my ($self) = shift;
unpack("H*", ($self->digest()));
}
sub hash
{
my ($self, $data) = @_;
if (ref($self))
{
# This is an instance method call so reset the current context
$self->reset();
}
else
{
# This is a static method invocation, create a temporary MD5 context
$self = new MD5;
}
# Now do the hash
$self->add($data);
$self->digest();
}
sub hexhash
{
my ($self, $data) = @_;
unpack("H*", ($self->hash($data)));
}
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
=head1 NAME
MD5 - Perl interface to the RSA Data Security Inc. MD5 Message-Digest Algorithm
=head1 SYNOPSIS
use MD5;
$context = new MD5;
$context->reset();
$context->add(LIST);
$context->addfile(HANDLE);
$digest = $context->digest();
$string = $context->hexdigest();
$digest = MD5->hash(SCALAR);
$string = MD5->hexhash(SCALAR);
=head1 DESCRIPTION
The B<MD5> module allows you to use the RSA Data Security Inc. MD5
Message Digest algorithm from within Perl programs.
A new MD5 context object is created with the B<new> operation.
Multiple simultaneous digest contexts can be maintained, if desired.
The context is updated with the B<add> operation which adds the
strings contained in the I<LIST> parameter. Note, however, that
C<add('foo', 'bar')>, C<add('foo')> followed by C<add('bar')> and
C<add('foobar')> should all give the same result.
The final message digest value is returned by the B<digest> operation
as a 16-byte binary string. This operation delivers the result of
B<add> operations since the last B<new> or B<reset> operation. Note
that the B<digest> operation is effectively a destructive, read-once
operation. Once it has been performed, the context must be B<reset>
before being used to calculate another digest value.
Several convenience functions are also provided. The B<addfile>
operation takes an open file-handle and reads it until end-of file in
1024 byte blocks adding the contents to the context. The file-handle
can either be specified by name or passed as a type-glob reference, as
shown in the examples below. The B<hexdigest> operation calls
B<digest> and returns the result as a printable string of hexdecimal
digits. This is exactly the same operation as performed by the
B<unpack> operation in the examples below.
The B<hash> operation can act as either a static member function (ie
you invoke it on the MD5 class as in the synopsis above) or as a
normal virtual function. In both cases it performs the complete MD5
cycle (reset, add, digest) on the supplied scalar value. This is
convenient for handling small quantities of data. When invoked on the
class a temporary context is created. When invoked through an already
created context object, this context is used. The latter form is
slightly more efficient. The B<hexhash> operation is analogous to
B<hexdigest>.
=head1 EXAMPLES
use MD5;
$md5 = new MD5;
$md5->add('foo', 'bar');
$md5->add('baz');
$digest = $md5->digest();
print("Digest is " . unpack("H*", $digest) . "\n");
The above example would print out the message
Digest is 6df23dc03f9b54cc38a0fc1483df6e21
provided that the implementation is working correctly.
Remembering the Perl motto ("There's more than one way to do it"), the
following should all give the same result:
use MD5;
$md5 = new MD5;
die "Can't open /etc/passwd ($!)\n" unless open(P, "/etc/passwd");
seek(P, 0, 0);
$md5->reset;
$md5->addfile(P);
$d = $md5->hexdigest;
print "addfile (handle name) = $d\n";
seek(P, 0, 0);
$md5->reset;
$md5->addfile(\*P);
$d = $md5->hexdigest;
print "addfile (type-glob reference) = $d\n";
seek(P, 0, 0);
$md5->reset;
while (<P>)
{
$md5->add($_);
}
$d = $md5->hexdigest;
print "Line at a time = $d\n";
seek(P, 0, 0);
$md5->reset;
$md5->add(<P>);
$d = $md5->hexdigest;
print "All lines at once = $d\n";
seek(P, 0, 0);
$md5->reset;
while (read(P, $data, (rand % 128) + 1))
{
$md5->add($data);
}
$d = $md5->hexdigest;
print "Random chunks = $d\n";
seek(P, 0, 0);
$md5->reset;
undef $/;
$data = <P>;
$d = $md5->hexhash($data);
print "Single string = $d\n";
close(P);
=head1 NOTE
The MD5 extension may be redistributed under the same terms as Perl.
The MD5 algorithm is defined in RFC1321. The basic C code implementing
the algorithm is derived from that in the RFC and is covered by the
following copyright:
=over 8
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
documentation and/or software.
=back
This copyright does not prohibit distribution of any version of Perl
containing this extension under the terms of the GNU or Artistic
licences.
=head1 AUTHOR
The MD5 interface was written by Neil Winton
(C<N.Winton@axion.bt.co.uk>).
=head1 SEE ALSO
perl(1).
=cut
+101
View File
@@ -0,0 +1,101 @@
/*
** Perl Extension for the
**
** RSA Data Security Inc. MD5 Message-Digest Algorithm
**
** This module by Neil Winton (N.Winton@axion.bt.co.uk)
** SCCS ID @(#)MD5.xs 1.7 96/06/28
**
** This extension may be distributed under the same terms
** as Perl. The MD5 code is covered by separate copyright and
** licence, but this does not prohibit distribution under the
** GNU or Artistic licences. See the file md5c.c or MD5.pm
** for more details.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "global.h"
#include "md5.h"
/*
** The following macro re-definitions added to work around a problem on
** Solaris where the original MD5 routines are already in /lib/libnsl.a.
** This causes dynamic linking of the module to fail.
** Thanks to Ken Pizzini (ken@spry.com) for finally nailing this one!
*/
#define MD5Init MD5Init_perl
#define MD5Update MD5Update_perl
#define MD5Final MD5Final_perl
typedef MD5_CTX *MD5;
#ifdef __cplusplus
}
#endif
MODULE = MD5 PACKAGE = MD5
PROTOTYPES: DISABLE
MD5
new(packname = "MD5")
char * packname
CODE:
{
RETVAL = (MD5_CTX *)safemalloc(sizeof(MD5_CTX));
MD5Init(RETVAL);
}
OUTPUT:
RETVAL
void
DESTROY(context)
MD5 context
CODE:
{
safefree((char *)context);
}
void
reset(context)
MD5 context
CODE:
{
MD5Init(context);
}
void
add(context, ...)
MD5 context
CODE:
{
SV *svdata;
STRLEN len;
unsigned char *data;
int i;
for (i = 1; i < items; i++)
{
data = (unsigned char *)(SvPV(ST(i), len));
MD5Update(context, data, len);
}
}
SV *
digest(context)
MD5 context
CODE:
{
unsigned char digeststr[16];
MD5Final(digeststr, context);
ST(0) = sv_2mortal(newSVpv((char *)digeststr, 16));
}
+13
View File
@@ -0,0 +1,13 @@
# SCCS ID @(#)Makefile.PL 1.10 96/06/28
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'MD5',
'VERSION_FROM' => 'MD5.pm', # finds $VERSION
'LIBS' => [''], # e.g., '-lm'
'CONFIG' => ['byteorder'], # Used to determine 64-bitness
'DEFINE' => '-DPERL_BYTEORDER=$(BYTEORDER)',
'INC' => '', # e.g., '-I/usr/include/other'
'OBJECT' => q[MD5$(OBJ_EXT) md5c$(OBJ_EXT)],
);
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
MD5 Extension Version 1.7
This is a Perl5 extension interface to the RSA Data Security Inc. MD5
Message Digest algorithm. Documentation is in MD5.pod.
To build the extension, unpack this distribution under the ext/
directory of your Perl source distribution, create the Makefile using
'perl Makefile.PL' and do a 'make'.
Note that the MD5.xs file uses the "PROTOTYPES: DISABLE" facility
which only became available in late betas pf perl 5.002. If you are
using a version which does not support this then merely remove
this line.
The mddriver.pl script gives a simple example of how to use the
routines. In particular 'perl mddriver.pl -x' will perform a quick
test of the routines to see if they produce the expected output. The
use of "make test" will perform a more comprehensive test. (WARNING:
You should not run mddriver.pl directly in the MD5 directory when using
dynamic linking as on some systems it will dynamically link to object
files in the current directory which may not give the correct
behaviour. This is believed to affect at least AIX and IRIX. A similar
caveat applies to the direct use of the test.pl script).
The module is known to work (using static or dynamic linking) on at
least AIX, Solaris, HP-UX and IRIX. It should work on other
"reasonable" UNIX-like platforms (for an unspecified definition of the
word "reasonable" :-)
Support is also provided for 64-bit platforms. This should be detected
and handled automatically. See the entry for version 1.7 in the
Changes file for further details.
Bugs, queries, plaudits to
Neil Winton
* Neil Winton Post Point P5 *
* N.Winton@axion.bt.co.uk BT Laboratories *
* Tel +44 1473 646079 Martlesham Heath *
* Fax +44 1473 643306 IPSWICH IP5 7RE, UK *
+69
View File
@@ -0,0 +1,69 @@
#!/usr/local/bin/perl
# SCCS ID @(#)mddriver.pl 1.3 95/05/01
require 'getopts.pl';
use MD5;
sub DoTest;
&Getopts('s:x');
$md5 = new MD5;
if (defined($opt_s))
{
$md5->add($opt_s);
$digest = $md5->digest();
print("MD5(\"$opt_s\") = " . unpack("H*", $digest) . "\n");
}
elsif ($opt_x)
{
DoTest("", "d41d8cd98f00b204e9800998ecf8427e");
DoTest("a", "0cc175b9c0f1b6a831c399e269772661");
DoTest("abc", "900150983cd24fb0d6963f7d28e17f72");
DoTest("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
DoTest("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
DoTest("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"d174ab98d277d9f5a5611c2c9f419d9f");
DoTest("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"57edf4a22be3c955ac49da2e2107b67a");
}
else
{
if ($#ARGV >= 0)
{
foreach $ARGV (@ARGV)
{
die "Can't open file '$ARGV' ($!)\n" unless open(ARGV, $ARGV);
$md5->reset();
$md5->addfile(ARGV);
$hex = $md5->hexdigest();
print "MD5($ARGV) = $hex\n";
close(ARGV);
}
}
else
{
$md5->reset();
$md5->addfile(STDIN);
$hex = $md5->hexdigest();
print "$hex\n";
}
}
exit 0;
sub DoTest
{
my ($str, $expect) = @_;
my ($digest, $hex);
my $md5 = new MD5;
$md5->add($str);
$digest = $md5->digest();
$hex = unpack("H*", $digest);
print "MD5(\"$str\") =>\nEXPECT: $expect\nRESULT: $hex\n"
}
+35
View File
@@ -0,0 +1,35 @@
#!/usr/local/bin/perl
use MD5;
#
# twdigest -- format MD5 digest like TripWire does
#
# This converts the md5->digest binary string to
# 64-radix ascii, given the base-vector:
# 0 - 9, A - Z, a - z, :, .
#
sub twdigest {
my($digest) = @_;
my(@chunks, $bits);
# Convert to ASCII bit-string
$bits = unpack("B*", $digest);
# Round up length to multiple of 6 by prepending zeros
$bits = ("0" x ((6 - (length($bits) % 6)) % 6)) . $bits;
# Split into 6-bit chunks
@chunks = grep {$_ ne ''} (split(/(.{6})/, $bits, -1));
# Convert each 6-bit value to a single character
foreach (@chunks)
{
$_ = pack("B8", "00" . $_);
tr/\000-\011\012-\043\044-\075\076\077/0-9A-Za-z:./;
}
# Join all of the chunks into one string
join('', @chunks);
}
+49
View File
@@ -0,0 +1,49 @@
/* GLOBAL.H - RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 0
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word.
We use the Perl byte-order definition to discover if a long has more than
4 bytes. If so we will try to use an unsigned int. This is OK for DEC
Alpha but may not work everywhere. See the TO32 definition below.
*/
#if (PERL_BYTEORDER <= 4321) || defined(UINT4_IS_LONG)
typedef unsigned long UINT4;
#else
typedef unsigned int UINT4;
#endif
/* TO32 ensures that UINT4 values are truncated to 32 bits.
A Cray has short, int and long all at 64 bits so we need to apply this
macro to reduce UINT4 values to 32 bits at appropriate places. If UINT4
really does have 32 bits then this is a no-op.
*/
#if defined(cray) || defined(TRUNCATE_UINT4)
#define TO32(x) ((x) & 0xffffffff)
#else
#define TO32(x) (x)
#endif
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
+36
View File
@@ -0,0 +1,36 @@
/* MD5.H - header file for MD5C.C
*/
/* 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
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, unsigned char *, unsigned long));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+351
View File
@@ -0,0 +1,351 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* 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
documentation and/or software.
*/
/*
** The following macro re-definitions added to work around a problem on
** Solaris where the original MD5 routines are already in /lib/libnsl.a.
** This causes dynamic linking of the module to fail.
**
** Thanks to Ken Pizzini (ken@spry.com) for finally nailing this one!
*/
#define MD5Init MD5Init_perl
#define MD5Update MD5Update_perl
#define MD5Final MD5Final_perl
#include "global.h"
#include "md5.h"
/* 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
static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned long));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned long));
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned long));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned long));
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
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) TO32((((x) & (y)) | ((~x) & (z))))
#define G(x, y, z) TO32((((x) & (z)) | ((y) & (~z))))
#define H(x, y, z) TO32(((x) ^ (y) ^ (z)))
#define I(x, y, z) TO32(((y) ^ ((x) | (~z))))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) TO32((((x) << (n)) | (TO32((x)) >> (32-(n)))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
TO32((a)); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CTX *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned long inputLen; /* length of input block */
{
unsigned long i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned long)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if (TO32(context->count[0] += (inputLen << 3))
< TO32(inputLen << 3))
context->count[1]++;
context->count[1] += (inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{
unsigned char bits[8];
unsigned long index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned long)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a; TO32(state[0]);
state[1] += b; TO32(state[1]);
state[2] += c; TO32(state[2]);
state[3] += d; TO32(state[3]);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned long len;
{
unsigned long i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned long len;
{
unsigned long i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned long len;
{
unsigned long i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned long len;
{
unsigned long i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
+154
View File
@@ -0,0 +1,154 @@
# SCCS ID @(#)test.pl 1.1 96/04/09
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'
######################### We start with some black magic to print on failure.
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
BEGIN {print "1..14\n";}
END {print "not ok 1\n" unless $loaded;}
use MD5;
$loaded = 1;
print "ok 1\n";
######################### End of black magic.
# Insert your test code below (better if it prints "ok 13"
# (correspondingly "not ok 13") depending on the success of chunk 13
# of the test code):
package MD5Test;
# 2: Constructor
print (($md5 = new MD5) ? "ok 2\n" : "not ok 2\n");
# 3: Basic test data as defined in RFC 1321
%data = (
"" => "d41d8cd98f00b204e9800998ecf8427e",
"a" => "0cc175b9c0f1b6a831c399e269772661",
"abc" => "900150983cd24fb0d6963f7d28e17f72",
"message digest"
=> "f96b697d7cb7938d525a2f31aaf161d0",
"abcdefghijklmnopqrstuvwxyz"
=> "c3fcd3d76192e4007dfb496cca67e13b",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
=> "d174ab98d277d9f5a5611c2c9f419d9f",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
=> "57edf4a22be3c955ac49da2e2107b67a",
);
$failed = 0;
foreach (sort(keys(%data)))
{
$md5->reset;
$md5->add($_);
$digest = $md5->digest;
$hex = unpack("H*", $digest);
if ($hex ne $data{$_})
{
$failed++;
}
}
print ($failed ? "not ok 3\n" : "ok 3\n");
# 4: Various flavours of file-handle to addfile
open(F, "<$0");
$md5->reset;
$md5->addfile(F);
$hex = $md5->hexdigest;
print ($hex ne '' ? "ok 4\n" : "not ok 4\n");
$orig = $hex;
# 5: Fully qualified with ' operator
seek(F, 0, 0);
$md5->reset;
$md5->addfile(MD5Test'F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 5\n" : "not ok 5\n");
# 6: Fully qualified with :: operator
seek(F, 0, 0);
$md5->reset;
$md5->addfile(MD5Test::F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 6\n" : "not ok 6\n");
# 7: Type glob
seek(F, 0, 0);
$md5->reset;
$md5->addfile(*F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 7\n" : "not ok 7\n");
# 8: Type glob reference (the prefered mechanism)
seek(F, 0, 0);
$md5->reset;
$md5->addfile(\*F);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 8\n" : "not ok 8\n");
# 9: File-handle passed by name (really the same as 6)
seek(F, 0, 0);
$md5->reset;
$md5->addfile("MD5Test::F");
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 9\n" : "not ok 9\n");
# 10: Other ways of reading the data -- line at a time
seek(F, 0, 0);
$md5->reset;
while (<F>)
{
$md5->add($_);
}
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 10\n" : "not ok 10\n");
# 11: Input lines as a list to add()
seek(F, 0, 0);
$md5->reset;
$md5->add(<F>);
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 11\n" : "not ok 11\n");
# 12: Random chunks up to 128 bytes
seek(F, 0, 0);
$md5->reset;
while (read(F, $hexata, (rand % 128) + 1))
{
$md5->add($hexata);
}
$hex = $md5->hexdigest;
print ($hex eq $orig ? "ok 12\n" : "not ok 12\n");
# 13: All the data at once
seek(F, 0, 0);
$md5->reset;
undef $/;
$data = <F>;
$hex = $md5->hexhash($data);
print ($hex eq $orig ? "ok 13\n" : "not ok 13\n");
close(F);
# 14: Using static member function
$hex = MD5->hexhash($data);
print ($hex eq $orig ? "ok 14\n" : "not ok 14\n");
+3
View File
@@ -0,0 +1,3 @@
# SCCS ID @(#)typemap 1.2 94/11/07
TYPEMAP
MD5 T_PTROBJ