v41i137: mdigest - message digest library, Part01/03

3 views
Skip to first unread message

Matthew Gream

unread,
Feb 28, 1994, 1:25:53 PM2/28/94
to
Submitted-by: M.G...@uts.edu.au (Matthew Gream)
Posting-number: Volume 41, Issue 137
Archive-name: mdigest/part01
Environment: C

#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.
# Contents: README MANIFEST EXPORT haval.c mtest.c
# Wrapped by alecm@uk-usenet on Thu Feb 24 09:36:44 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 3)."'
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(10157 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
XMESSAGE DIGEST LIBRARY
X
XCopyright,
XMatthew Gream <M.G...@uts.edu.au>,
XFebruary 1994.
X
X
X-- License
X
XPlease read 'license.txt', it is written for my larger project, but
Xapplies to this as well (it doesn't cover the items of sofware that
Xare not under my control, ie. the message digests themselves).
X
X
X-- Acknowledgements
X
XI acknowledge the use and inclusion of the following items of software
Xwithin the library:
X
X MD4, MD5 -- RSA Laboratories Inc.
X SHS -- Peter C. Gutmann, Colin Plumb.
X HAVAL -- Y. Zheng, J. Pieprzyk and J. Seberry.
X
X
X-- Overview
X
XIn working on a larger project, I've had to construct some generic
Xmodular handlers for message digest, encryption and compression methods.
XThe idea is that the one generic interface handler allows selection and
Xuse of any of the particular methods by a common set of interface
Xfunctions, thereby removing the idiosyncrasies of each particular
Xmethod.
X
XSome of the goals when writing this are to ensure it is flexible enough
Xto allow addition of new methods even external to this library, ie so an
Xapplication could selectively add or remove methods due to some other
Xinfluence. At the same, it must be easy to determine what methods are
Xcurrently available, and select them. Therefore, each method is known by
Xa string, ie "md5" for RSAs message-digest #5.
X
XAccess to the module is, similar to how most message digests are
Xstructure at the moment, via a context structure which keeps all the per
Xassociation static data within it. This allows concurrency.
X
XAnyway, the reason for release of this is that I gave it to a friend to
Xuse on something he was working on, he expressed delight at the
X'niftyness' of it, and suggested I make it available. Writing this
Xdocumentation and packaging it up for posting has already taken longer
Xthan writing the thing in the first place :-)
X
X
X-- Startup
X
XMost, just about all actually, functions have an enumerated return type
Xof 'err_code' which are defined in the header file (note: I had to hack
Xaround to move a few things into this header file, because in the larger
Xproject, it is more distributed). To be honest, err_code is a bit of a
Xmisnomer, it should really be ret_code, but anyway ... these give
Xinformation about function execution problems.
X
XBefore you use the module in anyway whatsoever, you want to call the
Xmodule initialisation function, this sets up internal tables and
Xregisters a few common message digests (md4,md5,shs,haval). The syntax
Xfor this is:
X
X md_mod_open ();
X
XEven though it does return an err_code, it is currently redundant. By
Xthe same token, after you've finished with the module, you're expected
Xto call:
X
X md_mod_close ();
X
Xwhich closes down and clears any used internal info. Naturally, a call
Xto /md_mod_open()/ will re-initialise it again.
X
X
X-- Lookup
X
XTo look at what methods are already registered, two functions so you can
X'walk the list' so to speak. To initialise the walk, call:
X
X md_list_init (word* state_var);
X
X/state_var/ is used as an index and used in the subsequent procedure of
Xreturning each registered identifier in turn, the syntax for this is:
X
X md_list_next (word* state_var, string ident);
X
XWhere string is a char array of minimum size /ident_sz/ (defined in the
Xheader -- currently 16). At each iteration, /state_var/ is updated and
Xthe next identifier is copied into /ident/. The return code here will be
X/err_ok/ until the end of list is reached (or you pass an incorrect
X/state_var/). For example, the following bit of code would list all the
Xcurrently registered methods:
X
X void list_methods ()
X {
X word s;
X char ident[ident_sz+1];
X
X md_list_init (&s);
X while (md_list_next (&s, ident) == err_ok)
X printf ("-> %s\n", ident);
X }
X
X-- Registration/Deregistration
X
XIf you wish to add a custom digest to the module, you need to call the
Xregistration process. First, your message digest needs to provide the
Xfollowing functions (examine, say, md4-if.c to see how this works):
X
X create() : this takes as argument the message digest
X context and allocates/initialises the internal
X private data store.
X
X destroy() : takes a context as argument and deallocates the
X the internal private data store.
X
X register() : takes and info structure as it's argument and
X fills out all the function call handlers to
X those just described above.
X
X deregister() : can be NULL, if not this is called when the
X module is deregistered and takes an info struct
X as it's argument.
X
X [the user called functions that actually do work:]
X
X init() : called with the private data structure as
X argument and expected to initialise state
X information ready to start calculating a digest.
X
X update () : takes private data structure, data and it's
X length to be used to update the digest.
X
X final () : takes private data structure and a storage area
X to copy the digest too when all update()s have
X been finished.
X
XTo register, you call the registration function with the ASCII string
Xname of the method and the above registration function, the syntax for
Xthis is:
X
X md_register (string ident, function register);
X
X/md_register()/ will then check that an identifier of the same name
Xdoesn't exist, and if so, allocate new storage for an info structure on
Xthe list and call the register function so it can fill in the details.
XAgain, a much better explanation can be had if you read the source code
X:-).
X
XDeregistration is even easier, just call the deregistration function
Xwith the identifier to remove, the syntax for this is:
X
X md_deregister (string ident);
X
XAs a practical example, say you wanted to register a crc32 message
Xdigest, you'd have code something to the effect of:
X
X extern err_code crc32_register ();
X
X if (md_register ("crc32", crc32_register) != err_ok)
X {
X ...
X }
X
Xand for deregistration:
X
X (void)md_deregister ("crc32");
X
X
X-- Operation
X
XPutting aside the administrative details of initialisation and
Xregistration, using the module from an application is exceeding simple.
XYou first need to call /md_open()/ with an empty context structure, and
Xthe requested digest to use. From then on, you can use successive
Xiterations of /md_init()/ to initialise the digest, /md_update()/ to
Xupdate the digest with new data, and /md_final()/ to return the digest.
XAgain, a practical example is the easiest. Consider the following
Xfunction to take a files as input and determine the digest using md4.
X
X
X /* returns size of digest if ok, or -1 if error occured
X */
X int md_of_file (filename, digest, digest_sz)
X char* filename; /* filename to work on */
X char* digest; /* where to place the digest */
X int digest_sz; /* how much space is avail */
X {
X int f;
X int i, j, k;
X char buf[8192];
X md_ctx ctx;
X
X if (md_mod_open () != err_ok)
X return -1; /* something failed at init */
X
X if (md_open (&ctx, "md4") != err_ok)
X return -1; /* md4 isn't registered */
X
X if (digest_sz < md_hash_sz (&ctx))
X return -1; /* not enough space for the digest */
X
X if ((f = open (filename, O_RDONLY)) < 0)
X return -1; /* can't open file */
X
X md_init (&ctx); /* initialisation */
X
X do /* read and update */
X {
X j = read (f, buf, 8192);
X if (j > 0)
X md_update (&ctx, buf, j);
X }
X while (j == 8192); /* until exhausted input */
X
X close (f);
X
X md_final (&ctx, digest); /* compute and place in buffer */
X j = md_hash_sz (&ctx); /* store size of hash before close */
X
X md_close (&ctx); /* close the context */
X
X md_mod_close (); /* shutdown the module */
X
X return j; /* return size of hash */
X }
X
X
X-- Building
X
XType make. Should work on most architectures as there is little, if no,
Xarchitecture dependent code. I've tested it on linux under gcc and SunOS
Xunder both gcc and cc, no problems at all. I haven't tried it on MSDOS
Xyet though.
X
XIf you want to modify which digests are included and/or which are loaded
Xat module open, the add or remove the object files from the makefile,
Xand edit the lines in mdigest.c in /md_mod_open()/ add or subtract
X/md_register()/s.
X
X
X-- Testing
X
XI've not done exhaustive testing on it, but running test suites and
Xcomparing against vanilla digests, all seems ok. Anyway, it's so damn
Xsmall there isn't really much that can go wrong :-) [famous last
Xwords ...].
X
X
X-- Included software
X
X > mfile.
X
X program which takes as arguments a number of files to calculate message
X digests of. Each digest can be explicitly requested, or if none are,
X then the default is to calculate all of them. This is used to make the
X CHECKSUMS file.
X
X > mtest.
X
X runs test suites relevant to particular message digests.
X
X-- Bugs
X
XNone (so far).
X
X-- Finally
X
XI had to reverse the arguments to some of the message digests. Theres a
Xbit of inconsistency because the init() and update() functions take a
Xcontext as first parameter, but the final() doesn't. I guess it's just
Xmy pedantic genericism that does it, but hey.
X
Xps. I hate writing documentation, so excuse the above if it seems too
Xcryptic.
X
X
END_OF_FILE
if test 10157 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(785 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X File Name Archive # Description
X----------------------------------------------------------
XREADME 1
XMANIFEST 1
XCHECKSUMS 3
XEXPORT 1
XMakefile 3
Xhaval-if.c 3
Xhaval.c 1
Xhaval.h 3
Xlicense.txt 3
Xmd4-if.c 3
Xmd4.c 2
Xmd4.h 3
Xmd5-if.c 3
Xmd5.c 2
Xmd5.h 3
Xmdigest.c 2
Xmdigest.h 3
Xmfile.c 2
Xmtest.c 1
Xshs-if.c 3
Xshs.c 2
Xshs.h 3
Xutility.c 3
END_OF_FILE
if test 785 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'EXPORT' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'EXPORT'\"
else
echo shar: Extracting \"'EXPORT'\" \(97 characters\)
sed "s/^X//" >'EXPORT' <<'END_OF_FILE'
X
XMessage digests are not covered by ITAR. Hence, export of this
Xproduct from the USA is legal.
X
END_OF_FILE
if test 97 -ne `wc -c <'EXPORT'`; then
echo shar: \"'EXPORT'\" unpacked with wrong size!
fi
# end of 'EXPORT'
fi
if test -f 'haval.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'haval.c'\"
else
echo shar: Extracting \"'haval.c'\" \(26139 characters\)
sed "s/^X//" >'haval.c' <<'END_OF_FILE'
X
X/* -- derived from original haval.c, changes are:
X * -- mgream: added run time endian checks, instead of precompiled
X * -- mgream: changed function args from ansi (for compat)
X *
X * haval.c: specifies the routines in the HAVAL (V.1) hashing library.
X *
X * HAVAL is a one-way hashing algorithm with the following
X * collision-resistant property:
X * It is computationally infeasible to find two or more
X * messages that are hashed into the same fingerprint.
X *
X * Reference:
X * Y. Zheng, J. Pieprzyk and J. Seberry:
X * ``HAVAL --- a one-way hashing algorithm with variable
X * length of output'', Advances in Cryptology --- AUSCRYPT'92,
X * Lecture Notes in Computer Science, Springer-Verlag, 1993.
X *
X * Descriptions:
X * - haval_string: hash a string
X * - haval_file: hash a file
X * - haval_stdin: filter -- hash input from the stdin device
X * - haval_hash: hash a string of specified length
X * (Haval_hash is used in conjunction with
X * haval_start & haval_end.)
X * - haval_hash_block: hash a 32-word block
X * - haval_start: initialization
X * - haval_end: finalization
X *
X * Author: Yuliang Zheng
X * Department of Computer Science
X * University of Wollongong
X * Wollongong, NSW 2522, Australia
X * Email: yul...@cs.uow.edu.au
X * Voice: +61 42 21 4331 (office)
X *
X * Date: June 1993
X *
X * Copyright (C) 1993 by C^3SR. All rights reserved.
X * This program may not be sold or used as inducement to
X * buy a product without the written permission of C^3SR.
X */
X
X#include <stdio.h>
X#include <memory.h>
X#include "haval.h"
X
Xstatic int endian = 0; /* 0 = little, 1 = big */
X
X#define VERSION 1 /* current version number */
X
Xvoid haval_start (); /* initialization */
Xvoid haval_hash (); /* updating routine */
Xvoid haval_end (); /* finalization */
Xvoid haval_hash_block (); /* hash a 32-word block */
Xstatic void haval_tailor (); /* folding the last output */
X
Xstatic unsigned char padding[128] = { /* constants for padding */
X0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
X};
X
X#define f_1(x6, x5, x4, x3, x2, x1, x0) \
X ((x1) & ((x0) ^ (x4)) ^ (x2) & (x5) ^ \
X (x3) & (x6) ^ (x0))
X
X#define f_2(x6, x5, x4, x3, x2, x1, x0) \
X ((x2) & ((x1) & ~(x3) ^ (x4) & (x5) ^ (x6) ^ (x0)) ^ \
X (x4) & ((x1) ^ (x5)) ^ (x3) & (x5) ^ (x0))
X
X#define f_3(x6, x5, x4, x3, x2, x1, x0) \
X ((x3) & ((x1) & (x2) ^ (x6) ^ (x0)) ^ \
X (x1) & (x4) ^ (x2) & (x5) ^ (x0))
X
X#define f_4(x6, x5, x4, x3, x2, x1, x0) \
X ((x4) & ((x5) & ~(x2) ^ (x3) & ~(x6) ^ (x1) ^ (x6) ^ (x0)) ^ \
X (x3) & ((x1) & (x2) ^ (x5) ^ (x6)) ^ \
X (x2) & (x6) ^ (x0))
X
X#define f_5(x6, x5, x4, x3, x2, x1, x0) \
X ((x0) & ((x1) & (x2) & (x3) ^ ~(x5)) ^ \
X (x1) & (x4) ^ (x2) & (x5) ^ (x3) & (x6))
X
X/*
X * Permutations phi_{i,j}, i=3,4,5, j=1,...,i.
X *
X * PASS = 3:
X * 6 5 4 3 2 1 0
X * | | | | | | | (replaced by)
X * phi_{3,1}: 1 0 3 5 6 2 4
X * phi_{3,2}: 4 2 1 0 5 3 6
X * phi_{3,3}: 6 1 2 3 4 5 0
X *
X * PASS = 4:
X * 6 5 4 3 2 1 0
X * | | | | | | | (replaced by)
X * phi_{4,1}: 2 6 1 4 5 3 0
X * phi_{4,2}: 3 5 2 0 1 6 4
X * phi_{4,3}: 1 4 3 6 0 2 5
X * phi_{4,4}: 6 4 0 5 2 1 3
X *
X * PASS = 5:
X * 6 5 4 3 2 1 0
X * | | | | | | | (replaced by)
X * phi_{5,1}: 3 4 1 0 5 2 6
X * phi_{5,2}: 6 2 1 0 3 4 5
X * phi_{5,3}: 2 6 0 4 3 1 5
X * phi_{5,4}: 1 5 3 2 0 4 6
X * phi_{5,5}: 2 5 0 6 4 3 1
X */
X
X#if PASS == 3
X#define Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
X f_1(x1, x0, x3, x5, x6, x2, x4)
X#elif PASS == 4
X#define Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
X f_1(x2, x6, x1, x4, x5, x3, x0)
X#else
X#define Fphi_1(x6, x5, x4, x3, x2, x1, x0) \
X f_1(x3, x4, x1, x0, x5, x2, x6)
X#endif
X
X#if PASS == 3
X#define Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
X f_2(x4, x2, x1, x0, x5, x3, x6)
X#elif PASS == 4
X#define Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
X f_2(x3, x5, x2, x0, x1, x6, x4)
X#else
X#define Fphi_2(x6, x5, x4, x3, x2, x1, x0) \
X f_2(x6, x2, x1, x0, x3, x4, x5)
X#endif
X
X#if PASS == 3
X#define Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
X f_3(x6, x1, x2, x3, x4, x5, x0)
X#elif PASS == 4
X#define Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
X f_3(x1, x4, x3, x6, x0, x2, x5)
X#else
X#define Fphi_3(x6, x5, x4, x3, x2, x1, x0) \
X f_3(x2, x6, x0, x4, x3, x1, x5)
X#endif
X
X#if PASS == 4
X#define Fphi_4(x6, x5, x4, x3, x2, x1, x0) \
X f_4(x6, x4, x0, x5, x2, x1, x3)
X#else
X#define Fphi_4(x6, x5, x4, x3, x2, x1, x0) \
X f_4(x1, x5, x3, x2, x0, x4, x6)
X#endif
X
X#define Fphi_5(x6, x5, x4, x3, x2, x1, x0) \
X f_5(x2, x5, x0, x6, x4, x3, x1)
X
X#define rotate_right(x, n) (((x) >> (n)) | ((x) << (32-(n))))
X
X#define FF_1(x7, x6, x5, x4, x3, x2, x1, x0, w) { \
X register haval_word temp = Fphi_1(x6, x5, x4, x3, x2, x1, x0); \
X (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w); \
X }
X
X#define FF_2(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
X register haval_word temp = Fphi_2(x6, x5, x4, x3, x2, x1, x0); \
X (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c); \
X }
X
X#define FF_3(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
X register haval_word temp = Fphi_3(x6, x5, x4, x3, x2, x1, x0); \
X (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c); \
X }
X
X#define FF_4(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
X register haval_word temp = Fphi_4(x6, x5, x4, x3, x2, x1, x0); \
X (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c); \
X }
X
X#define FF_5(x7, x6, x5, x4, x3, x2, x1, x0, w, c) { \
X register haval_word temp = Fphi_5(x6, x5, x4, x3, x2, x1, x0); \
X (x7) = rotate_right(temp, 7) + rotate_right((x7), 11) + (w) + (c); \
X }
X
X/*
X * translate every four characters into a word.
X * assume the number of characters is a multiple of four.
X */
X#define ch2uint(string, word, slen) { \
X unsigned char *sp = string; \
X haval_word *wp = word; \
X while (sp < (string) + (slen)) { \
X *wp++ = (haval_word)*sp | \
X ((haval_word)*(sp+1) << 8) | \
X ((haval_word)*(sp+2) << 16) | \
X ((haval_word)*(sp+3) << 24); \
X sp += 4; \
X } \
X}
X
X/* translate each word into four characters */
X#define uint2ch(word, string, wlen) { \
X haval_word *wp = word; \
X unsigned char *sp = string; \
X while (wp < (word) + (wlen)) { \
X *(sp++) = (unsigned char)( *wp & 0xFF); \
X *(sp++) = (unsigned char)((*wp >> 8) & 0xFF); \
X *(sp++) = (unsigned char)((*wp >> 16) & 0xFF); \
X *(sp++) = (unsigned char)((*wp >> 24) & 0xFF); \
X wp++; \
X } \
X}
X
X/* initialization */
Xvoid haval_start (state)
X haval_state *state;
X{
X state->count[0] = state->count[1] = 0; /* clear count */
X state->fingerprint[0] = 0x243F6A88; /* initial fingerprint */
X state->fingerprint[1] = 0x85A308D3;
X state->fingerprint[2] = 0x13198A2E;
X state->fingerprint[3] = 0x03707344;
X state->fingerprint[4] = 0xA4093822;
X state->fingerprint[5] = 0x299F31D0;
X state->fingerprint[6] = 0x082EFA98;
X state->fingerprint[7] = 0xEC4E6C89;
X
X /* from shs.c
X *
X * Find out what the byte order is on this machine.
X * Big endian is for machines that place the most significant byte
X * first (eg. Sun SPARC). Little endian is for machines that place
X * the least significant byte first (eg. VAX).
X *
X * We figure out the byte order by stuffing a 2 byte string into a
X * short and examining the left byte. '@' = 0x40 and 'P' = 0x50
X * If the left byte is the 'high' byte, then it is 'big endian'.
X * If the left byte is the 'low' byte, then the machine is 'little
X * endian'.
X *
X * -- Shawn A. Clifford (s...@eng.ufl.edu)
X */
X
X if ((*(unsigned short *) ("@P") >> 8) == '@')
X endian = 1;
X else
X endian = 0;
X
X}
X
X/*
X * hash a string of specified length.
X * to be used in conjunction with haval_start and haval_end.
X */
Xvoid haval_hash (state, str, str_len)
X haval_state* state;
X unsigned char *str;
X unsigned int str_len;
X{
X unsigned int i,
X rmd_len,
X fill_len;
X
X /* calculate the number of bytes in the remainder */
X rmd_len = (unsigned int)((state->count[0] >> 3) & 0x7F);
X fill_len = 128 - rmd_len;
X
X /* update the number of bits */
X if ((state->count[0] += (haval_word)str_len << 3)
X < ((haval_word)str_len << 3)) {
X state->count[1]++;
X }
X state->count[1] += (haval_word)str_len >> 29;
X
X/*#ifdef LITTLE_ENDIAN*/
X if (endian == 0) {
X
X /* hash as many blocks as possible */
X if (rmd_len + str_len >= 128) {
X memcpy (((unsigned char *)state->block)+rmd_len, str, fill_len);
X haval_hash_block (state);
X for (i = fill_len; i + 127 < str_len; i += 128){
X memcpy ((unsigned char *)state->block, str+i, 128);
X haval_hash_block (state);
X }
X rmd_len = 0;
X } else {
X i = 0;
X }
X memcpy (((unsigned char *)state->block)+rmd_len, str+i, str_len-i);
X
X/*#else*/
X } else {
X
X /* hash as many blocks as possible */
X if (rmd_len + str_len >= 128) {
X memcpy (&state->remainder[rmd_len], str, fill_len);
X ch2uint(state->remainder, state->block, 128);
X haval_hash_block (state);
X for (i = fill_len; i + 127 < str_len; i += 128){
X memcpy (state->remainder, str+i, 128);
X ch2uint(state->remainder, state->block, 128);
X haval_hash_block (state);
X }
X rmd_len = 0;
X } else {
X i = 0;
X }
X /* save the remaining input chars */
X memcpy (&state->remainder[rmd_len], str+i, str_len-i);
X
X/*#endif*/
X }
X
X}
X
X/* finalization */
Xvoid haval_end (state, final_fpt)
X haval_state * state;
X unsigned char final_fpt[FPTLEN >> 3];
X{
X unsigned char tail[10];
X unsigned int rmd_len, pad_len;
X
X /*
X * save the version number, the number of passes, the fingerprint
X * length and the number of bits in the unpadded message.
X */
X tail[0] = (unsigned char)(((FPTLEN & 0x3) << 6) |
X ((PASS & 0x7) << 3) |
X (VERSION & 0x7));
X tail[1] = (unsigned char)((FPTLEN >> 2) & 0xFF);
X uint2ch (state->count, &tail[2], 2);
X
X /* pad out to 118 mod 128 */
X rmd_len = (unsigned int)((state->count[0] >> 3) & 0x7f);
X pad_len = (rmd_len < 118) ? (118 - rmd_len) : (246 - rmd_len);
X haval_hash (state, padding, pad_len);
X
X /*
X * append the version number, the number of passes,
X * the fingerprint length and the number of bits
X */
X haval_hash (state, tail, 10);
X
X /* tailor the last output */
X haval_tailor(state);
X
X /* translate and save the final fingerprint */
X uint2ch (state->fingerprint, final_fpt, FPTLEN >> 5);
X
X /* clear the state information */
X memset ((unsigned char *)state, 0, sizeof (*state));
X}
X
X/* hash a 32-word block */
Xvoid haval_hash_block (state)
X haval_state* state;
X{
X register haval_word t0 = state->fingerprint[0], /* make use of */
X t1 = state->fingerprint[1], /* internal registers */
X t2 = state->fingerprint[2],
X t3 = state->fingerprint[3],
X t4 = state->fingerprint[4],
X t5 = state->fingerprint[5],
X t6 = state->fingerprint[6],
X t7 = state->fingerprint[7],
X *w = state->block;
X
X /* Pass 1 */
X FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w ));
X FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 1));
X FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 2));
X FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 3));
X FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 4));
X FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 5));
X FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 6));
X FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 7));
X
X FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 8));
X FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9));
X FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+10));
X FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+11));
X FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+12));
X FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+13));
X FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+14));
X FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+15));
X
X FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+16));
X FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+17));
X FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+18));
X FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+19));
X FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+20));
X FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+21));
X FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+22));
X FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+23));
X
X FF_1(t7, t6, t5, t4, t3, t2, t1, t0, *(w+24));
X FF_1(t6, t5, t4, t3, t2, t1, t0, t7, *(w+25));
X FF_1(t5, t4, t3, t2, t1, t0, t7, t6, *(w+26));
X FF_1(t4, t3, t2, t1, t0, t7, t6, t5, *(w+27));
X FF_1(t3, t2, t1, t0, t7, t6, t5, t4, *(w+28));
X FF_1(t2, t1, t0, t7, t6, t5, t4, t3, *(w+29));
X FF_1(t1, t0, t7, t6, t5, t4, t3, t2, *(w+30));
X FF_1(t0, t7, t6, t5, t4, t3, t2, t1, *(w+31));
X
X /* Pass 2 */
X FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 5), 0x452821E6);
X FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+14), 0x38D01377);
X FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+26), 0xBE5466CF);
X FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+18), 0x34E90C6C);
X FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+11), 0xC0AC29B7);
X FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+28), 0xC97C50DD);
X FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 7), 0x3F84D5B5);
X FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+16), 0xB5470917);
X
X FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w ), 0x9216D5D9);
X FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+23), 0x8979FB1B);
X FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+20), 0xD1310BA6);
X FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+22), 0x98DFB5AC);
X FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 1), 0x2FFD72DB);
X FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+10), 0xD01ADFB7);
X FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 4), 0xB8E1AFED);
X FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 8), 0x6A267E96);
X
X FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+30), 0xBA7C9045);
X FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 3), 0xF12C7F99);
X FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0x24A19947);
X FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 9), 0xB3916CF7);
X FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x0801F2E2);
X FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+24), 0x858EFC16);
X FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+29), 0x636920D8);
X FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 6), 0x71574E69);
X
X FF_2(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0xA458FEA3);
X FF_2(t6, t5, t4, t3, t2, t1, t0, t7, *(w+12), 0xF4933D7E);
X FF_2(t5, t4, t3, t2, t1, t0, t7, t6, *(w+15), 0x0D95748F);
X FF_2(t4, t3, t2, t1, t0, t7, t6, t5, *(w+13), 0x728EB658);
X FF_2(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 2), 0x718BCD58);
X FF_2(t2, t1, t0, t7, t6, t5, t4, t3, *(w+25), 0x82154AEE);
X FF_2(t1, t0, t7, t6, t5, t4, t3, t2, *(w+31), 0x7B54A41D);
X FF_2(t0, t7, t6, t5, t4, t3, t2, t1, *(w+27), 0xC25A59B5);
X
X /* Pass 3 */
X FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0x9C30D539);
X FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9), 0x2AF26013);
X FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 4), 0xC5D1B023);
X FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+20), 0x286085F0);
X FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+28), 0xCA417918);
X FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+17), 0xB8DB38EF);
X FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 8), 0x8E79DCB0);
X FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+22), 0x603A180E);
X
X FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+29), 0x6C9E0E8B);
X FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+14), 0xB01E8A3E);
X FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+25), 0xD71577C1);
X FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+12), 0xBD314B27);
X FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+24), 0x78AF2FDA);
X FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+30), 0x55605C60);
X FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+16), 0xE65525F3);
X FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+26), 0xAA55AB94);
X
X FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+31), 0x57489862);
X FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+15), 0x63E81440);
X FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 7), 0x55CA396A);
X FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 3), 0x2AAB10B6);
X FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 1), 0xB4CC5C34);
X FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w ), 0x1141E8CE);
X FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+18), 0xA15486AF);
X FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+27), 0x7C72E993);
X
X FF_3(t7, t6, t5, t4, t3, t2, t1, t0, *(w+13), 0xB3EE1411);
X FF_3(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 6), 0x636FBC2A);
X FF_3(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0x2BA9C55D);
X FF_3(t4, t3, t2, t1, t0, t7, t6, t5, *(w+10), 0x741831F6);
X FF_3(t3, t2, t1, t0, t7, t6, t5, t4, *(w+23), 0xCE5C3E16);
X FF_3(t2, t1, t0, t7, t6, t5, t4, t3, *(w+11), 0x9B87931E);
X FF_3(t1, t0, t7, t6, t5, t4, t3, t2, *(w+ 5), 0xAFD6BA33);
X FF_3(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 2), 0x6C24CF5C);
X
X#if PASS >= 4
X /* Pass 4. executed only when PASS =4 or 5 */
X FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+24), 0x7A325381);
X FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 4), 0x28958677);
X FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w ), 0x3B8F4898);
X FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+14), 0x6B4BB9AF);
X FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 2), 0xC4BFE81B);
X FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 7), 0x66282193);
X FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+28), 0x61D809CC);
X FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+23), 0xFB21A991);
X
X FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+26), 0x487CAC60);
X FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 6), 0x5DEC8032);
X FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+30), 0xEF845D5D);
X FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+20), 0xE98575B1);
X FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+18), 0xDC262302);
X FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+25), 0xEB651B88);
X FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+19), 0x23893E81);
X FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 3), 0xD396ACC5);
X
X FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+22), 0x0F6D6FF3);
X FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+11), 0x83F44239);
X FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+31), 0x2E0B4482);
X FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+21), 0xA4842004);
X FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 8), 0x69C8F04A);
X FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+27), 0x9E1F9B5E);
X FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+12), 0x21C66842);
X FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+ 9), 0xF6E96C9A);
X
X FF_4(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 1), 0x670C9C61);
X FF_4(t6, t5, t4, t3, t2, t1, t0, t7, *(w+29), 0xABD388F0);
X FF_4(t5, t4, t3, t2, t1, t0, t7, t6, *(w+ 5), 0x6A51A0D2);
X FF_4(t4, t3, t2, t1, t0, t7, t6, t5, *(w+15), 0xD8542F68);
X FF_4(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x960FA728);
X FF_4(t2, t1, t0, t7, t6, t5, t4, t3, *(w+10), 0xAB5133A3);
X FF_4(t1, t0, t7, t6, t5, t4, t3, t2, *(w+16), 0x6EEF0B6C);
X FF_4(t0, t7, t6, t5, t4, t3, t2, t1, *(w+13), 0x137A3BE4);
X#endif
X
X#if PASS == 5
X /* Pass 5. executed only when PASS = 5 */
X FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+27), 0xBA3BF050);
X FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 3), 0x7EFB2A98);
X FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+21), 0xA1F1651D);
X FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+26), 0x39AF0176);
X FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+17), 0x66CA593E);
X FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+11), 0x82430E88);
X FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+20), 0x8CEE8619);
X FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+29), 0x456F9FB4);
X
X FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+19), 0x7D84A5C3);
X FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w ), 0x3B8B5EBE);
X FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+12), 0xE06F75D8);
X FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+ 7), 0x85C12073);
X FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+13), 0x401A449F);
X FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 8), 0x56C16AA6);
X FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+31), 0x4ED3AA62);
X FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+10), 0x363F7706);
X
X FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 5), 0x1BFEDF72);
X FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+ 9), 0x429B023D);
X FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+14), 0x37D0D724);
X FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+30), 0xD00A1248);
X FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+18), 0xDB0FEAD3);
X FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 6), 0x49F1C09B);
X FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+28), 0x075372C9);
X FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+24), 0x80991B7B);
X
X FF_5(t7, t6, t5, t4, t3, t2, t1, t0, *(w+ 2), 0x25D479D8);
X FF_5(t6, t5, t4, t3, t2, t1, t0, t7, *(w+23), 0xF6E8DEF7);
X FF_5(t5, t4, t3, t2, t1, t0, t7, t6, *(w+16), 0xE3FE501A);
X FF_5(t4, t3, t2, t1, t0, t7, t6, t5, *(w+22), 0xB6794C3B);
X FF_5(t3, t2, t1, t0, t7, t6, t5, t4, *(w+ 4), 0x976CE0BD);
X FF_5(t2, t1, t0, t7, t6, t5, t4, t3, *(w+ 1), 0x04C006BA);
X FF_5(t1, t0, t7, t6, t5, t4, t3, t2, *(w+25), 0xC1A94FB6);
X FF_5(t0, t7, t6, t5, t4, t3, t2, t1, *(w+15), 0x409F60C4);
X#endif
X
X state->fingerprint[0] += t0;
X state->fingerprint[1] += t1;
X state->fingerprint[2] += t2;
X state->fingerprint[3] += t3;
X state->fingerprint[4] += t4;
X state->fingerprint[5] += t5;
X state->fingerprint[6] += t6;
X state->fingerprint[7] += t7;
X}
X
X/* tailor the last output */
Xstatic void haval_tailor (state)
X haval_state * state;
X{
X haval_word temp;
X
X#if FPTLEN == 128
X temp = (state->fingerprint[7] & 0x000000FF) |
X (state->fingerprint[6] & 0xFF000000) |
X (state->fingerprint[5] & 0x00FF0000) |
X (state->fingerprint[4] & 0x0000FF00);
X state->fingerprint[0] += rotate_right(temp, 8);
X
X temp = (state->fingerprint[7] & 0x0000FF00) |
X (state->fingerprint[6] & 0x000000FF) |
X (state->fingerprint[5] & 0xFF000000) |
X (state->fingerprint[4] & 0x00FF0000);
X state->fingerprint[1] += rotate_right(temp, 16);
X
X temp = (state->fingerprint[7] & 0x00FF0000) |
X (state->fingerprint[6] & 0x0000FF00) |
X (state->fingerprint[5] & 0x000000FF) |
X (state->fingerprint[4] & 0xFF000000);
X state->fingerprint[2] += rotate_right(temp, 24);
X
X temp = (state->fingerprint[7] & 0xFF000000) |
X (state->fingerprint[6] & 0x00FF0000) |
X (state->fingerprint[5] & 0x0000FF00) |
X (state->fingerprint[4] & 0x000000FF);
X state->fingerprint[3] += temp;
X
X#elif FPTLEN == 160
X temp = (state->fingerprint[7] & (haval_word)0x3F) |
X (state->fingerprint[6] & ((haval_word)0x7F << 25)) |
X (state->fingerprint[5] & ((haval_word)0x3F << 19));
X state->fingerprint[0] += rotate_right(temp, 19);
X
X temp = (state->fingerprint[7] & ((haval_word)0x3F << 6)) |
X (state->fingerprint[6] & (haval_word)0x3F) |
X (state->fingerprint[5] & ((haval_word)0x7F << 25));
X state->fingerprint[1] += rotate_right(temp, 25);
X
X temp = (state->fingerprint[7] & ((haval_word)0x7F << 12)) |
X (state->fingerprint[6] & ((haval_word)0x3F << 6)) |
X (state->fingerprint[5] & (haval_word)0x3F);
X state->fingerprint[2] += temp;
X
X temp = (state->fingerprint[7] & ((haval_word)0x3F << 19)) |
X (state->fingerprint[6] & ((haval_word)0x7F << 12)) |
X (state->fingerprint[5] & ((haval_word)0x3F << 6));
X state->fingerprint[3] += temp >> 6;
X
X temp = (state->fingerprint[7] & ((haval_word)0x7F << 25)) |
X (state->fingerprint[6] & ((haval_word)0x3F << 19)) |
X (state->fingerprint[5] & ((haval_word)0x7F << 12));
X state->fingerprint[4] += temp >> 12;
X
X#elif FPTLEN == 192
X temp = (state->fingerprint[7] & (haval_word)0x1F) |
X (state->fingerprint[6] & ((haval_word)0x3F << 26));
X state->fingerprint[0] += rotate_right(temp, 26);
X
X temp = (state->fingerprint[7] & ((haval_word)0x1F << 5)) |
X (state->fingerprint[6] & (haval_word)0x1F);
X state->fingerprint[1] += temp;
X
X temp = (state->fingerprint[7] & ((haval_word)0x3F << 10)) |
X (state->fingerprint[6] & ((haval_word)0x1F << 5));
X state->fingerprint[2] += temp >> 5;
X
X temp = (state->fingerprint[7] & ((haval_word)0x1F << 16)) |
X (state->fingerprint[6] & ((haval_word)0x3F << 10));
X state->fingerprint[3] += temp >> 10;
X
X temp = (state->fingerprint[7] & ((haval_word)0x1F << 21)) |
X (state->fingerprint[6] & ((haval_word)0x1F << 16));
X state->fingerprint[4] += temp >> 16;
X
X temp = (state->fingerprint[7] & ((haval_word)0x3F << 26)) |
X (state->fingerprint[6] & ((haval_word)0x1F << 21));
X state->fingerprint[5] += temp >> 21;
X
X#elif FPTLEN == 224
X state->fingerprint[0] += (state->fingerprint[7] >> 27) & 0x1F;
X state->fingerprint[1] += (state->fingerprint[7] >> 22) & 0x1F;
X state->fingerprint[2] += (state->fingerprint[7] >> 18) & 0x0F;
X state->fingerprint[3] += (state->fingerprint[7] >> 13) & 0x1F;
X state->fingerprint[4] += (state->fingerprint[7] >> 9) & 0x0F;
X state->fingerprint[5] += (state->fingerprint[7] >> 4) & 0x1F;
X state->fingerprint[6] += state->fingerprint[7] & 0x0F;
X#endif
X}
X
X
END_OF_FILE
if test 26139 -ne `wc -c <'haval.c'`; then
echo shar: \"'haval.c'\" unpacked with wrong size!
fi
# end of 'haval.c'
fi
if test -f 'mtest.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mtest.c'\"
else
echo shar: Extracting \"'mtest.c'\" \(11052 characters\)
sed "s/^X//" >'mtest.c' <<'END_OF_FILE'
X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X
X/* $Id: mfile.c%v 0.90 1994/02/22 20:51:46 matt Exp $
X */
X
X/*
X * File: mtest.c
X * Description: test md4, md5, shs and (if added) other digests
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <unistd.h>
X#include <fcntl.h>
X
X#include <mdigest.h>
X
X/* -------------------------------------------------------------------- */
X
Xstatic string digest_to_hex ();
Xstatic word test_md4 ();
Xstatic word test_md5 ();
Xstatic word test_shs ();
Xstatic word test_haval ();
X
X/* -------------------------------------------------------------------- */
X
Xtypedef struct
X {
X string ident;
X word (*test)();
X } test_func;
X
Xtest_func testable_mds[] =
X {
X { "md4", test_md4 },
X { "md5", test_md5 },
X { "shs", test_shs },
X { "haval", test_haval },
X { NULL, NULL },
X };
X
X/* -------------------------------------------------------------------- */
X/* function : main */
X/* -------------------------------------------------------------------- */
Xvoid
Xmain (argc, argv)
X int argc;
X char** argv;
X{
X word c;
X word s;
X md_ctx ctx;
X char ident[ident_sz+1];
X
X /* ---------------------------------------------------------------- */
X /* open the module and try to test whatever is available */
X /* ---------------------------------------------------------------- */
X
X md_mod_open ();
X
X md_list_init (&s);
X while (md_list_next (&s, ident) == err_ok)
X {
X printf ("%-8s : ", ident);
X
X for (c = 0; testable_mds[c].ident != NULL &&
X strcasecmp(ident, testable_mds[c].ident) != 0; c++)
X ;
X
X if (testable_mds[c].ident == NULL)
X {
X printf ("no test suite exists.\n");
X continue;
X }
X
X /* ------------------------------------------------------------ */
X /* create an association for that particular message digest */
X /* ------------------------------------------------------------ */
X
X if (md_open (&ctx, ident) != err_ok)
X {
X printf ("internal error.\n");
X exit (1);
X }
X
X /* ------------------------------------------------------------ */
X /* call it, and then close the association */
X /* ------------------------------------------------------------ */
X
X c = (*(testable_mds[c].test))(&ctx);
X
X if (c == -1)
X printf ("test(s) failed !\n");
X else
X printf ("%d test%s, all successfull.\n", c, (c == 1) ?"":"s");
X
X md_close (&ctx);
X
X }
X
X exit (0);
X}
X
X
X/* -------------------------------------------------------------------- */
X/* function : digest_to_hex */
X/* description : format a digest into a hex string */
X/* -------------------------------------------------------------------- */
Xstatic string
Xdigest_to_hex (digest, sz)
X opaque digest; /* bytes of digest */
X word sz; /* # bytes in digest */
X{
X static char hex_str[81];
X word c;
X
X for (c = 0; c < sz; c++)
X sprintf (&hex_str[c<<1], "%02x", (digest[c] & 0xff));
X
X hex_str[c<<1] = '\0';
X return (hex_str);
X}
X
X/* -------------------------------------------------------------------- */
X/* -------------------------------------------------------------------- */
X/* place test routines/structures/info from here onwards ... */
X/* -------------------------------------------------------------------- */
X/* -------------------------------------------------------------------- */
X
Xtypedef struct
X {
X string test;
X string result;
X } test_set;
X
Xchar digest[64];
Xstring hdigest;
X
X/* -------------------------------------------------------------------- */
X/* function : check_test_set */
X/* description : check all items in a test_set */
X/* -------------------------------------------------------------------- */
XSTATIC word
Xcheck_test_set (ctx, tset)
X md_ctx* ctx;
X test_set tset[];
X{
X word c;
X
X for (c = 0; tset[c].test != NULL; c++)
X {
X md_init (ctx);
X md_update (ctx, tset[c].test, strlen(tset[c].test));
X md_final (ctx, digest);
X
X hdigest = digest_to_hex (digest, md_hash_sz (ctx));
X
X if (strcmp (hdigest, tset[c].result) != 0)
X return -1;
X }
X
X return c;
X}
X
X
X/* -------------------------------------------------------------------- */
X/* message-digest 4 test suite from RFC-1186 */
X/* -------------------------------------------------------------------- */
X
Xstatic test_set md4_tests[] =
X {
X { "",
X "31d6cfe0d16ae931b73c59d7e0c089c0" },
X { "a",
X "bde52cb31de33e46245e05fbdbd6fb24" },
X { "abc",
X "a448017aaf21d8525fc10ae87aa6729d" },
X { "message digest",
X "d9130a8164549fe818874806e1c7014b" },
X { "abcdefghijklmnopqrstuvwxyz",
X "d79e1c308aa5bbcdeea8ed63df412da9" },
X { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
X "043f8582f241db351ce627e153e7f0e4" },
X { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
X "e33b4ddc9c38f2199c3e7b164fcc0536" },
X { NULL,
X NULL },
X };
X
X/* -------------------------------------------------------------------- */
X/* function : test_md4 */
X/* description : run through the md4 test suite */
X/* -------------------------------------------------------------------- */
XSTATIC word
Xtest_md4 (ctx)
X md_ctx* ctx;
X{
X return check_test_set (ctx, md4_tests);
X}
X
X
X/* -------------------------------------------------------------------- */
X/* message-digest 5 test suite from RFC-1321 */
X/* -------------------------------------------------------------------- */
X
Xstatic test_set md5_tests[] =
X {
X { "",
X "d41d8cd98f00b204e9800998ecf8427e" },
X { "a",
X "0cc175b9c0f1b6a831c399e269772661" },
X { "abc",
X "900150983cd24fb0d6963f7d28e17f72" },
X { "message digest",
X "f96b697d7cb7938d525a2f31aaf161d0" },
X { "abcdefghijklmnopqrstuvwxyz",
X "c3fcd3d76192e4007dfb496cca67e13b" },
X { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
X "d174ab98d277d9f5a5611c2c9f419d9f" },
X { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
X "57edf4a22be3c955ac49da2e2107b67a" },
X { NULL,
X NULL },
X };
X
X/* -------------------------------------------------------------------- */
X/* function : test_md5 */
X/* description : run through the md5 test suite */
X/* -------------------------------------------------------------------- */
XSTATIC word
Xtest_md5 (ctx)
X md_ctx* ctx;
X{
X return check_test_set (ctx, md5_tests);
X}
X
X
X/* -------------------------------------------------------------------- */
X/* NIST shs test */
X/* -------------------------------------------------------------------- */
X
Xstatic test_set shs_tests[] =
X {
X { "abc",
X "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880" },
X { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
X "d2516ee1acfa5baf33dfc1c471e438449ef134c8" },
X { NULL,
X NULL },
X };
X
X/* -------------------------------------------------------------------- */
X/* function : test_shs */
X/* description : go through NIST shs tests */
X/* -------------------------------------------------------------------- */
XSTATIC word
Xtest_shs (ctx)
X md_ctx* ctx;
X{
X word c;
X word i;
X char buf[1000];
X
X c = check_test_set (ctx, shs_tests);
X
X if (c == -1)
X return -1;
X
X /* ---------------------------------------------------------------- */
X /* do 1million 'a's. */
X /* ---------------------------------------------------------------- */
X
X memset (buf, 'a', 1000);
X
X md_init (ctx);
X for (i = 0; i < 1000; i++)
X md_update (ctx, buf, 1000);
X md_final (ctx, digest);
X
X hdigest = digest_to_hex (digest, md_hash_sz (ctx));
X
X if (strcmp (hdigest, "3232affa48628a26653b5aaa44541fd90d690603") != 0)
X return -1;
X
X return ++c;
X}
X
X
X/* -------------------------------------------------------------------- */
X/* function : test_haval */
X/* description : do haval test */
X/* -- NOTE -- : this assumes the default pass3=,fptlen=128/160 setup! */
X/* -------------------------------------------------------------------- */
XSTATIC word
Xtest_haval (ctx)
X md_ctx* ctx;
X{
X string test_f128 = "";
X string result_f128 = "1bdc556b29ad02ec09af8c66477f2a87";
X string test_f160 = "a";
X string result_f160 = "5e1610fced1d3adb0bb18e92ac2b11f0bd99d8ed";
X string t, r;
X
X
X if (md_hash_sz (ctx) == (128>>3))
X {
X t = test_f128;
X r = result_f128;
X }
X else if (md_hash_sz (ctx) == (160>>3))
X {
X t = test_f160;
X r = result_f160;
X }
X else
X return -1;
X
X md_init (ctx);
X md_update (ctx, t, strlen (t));
X md_final (ctx, digest);
X
X hdigest = digest_to_hex (digest, md_hash_sz (ctx));
X
X if (strcmp (hdigest, r) != 0)
X return -1;
X
X return 1;
X}
X
X/* -------------------------------------------------------------------- */
X
X
END_OF_FILE
if test 11052 -ne `wc -c <'mtest.c'`; then
echo shar: \"'mtest.c'\" unpacked with wrong size!
fi
# end of 'mtest.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...

Matthew Gream

unread,
Feb 28, 1994, 1:26:06 PM2/28/94
to
Submitted-by: M.G...@uts.edu.au (Matthew Gream)
Posting-number: Volume 41, Issue 138
Archive-name: mdigest/part02
Environment: C

#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.

# Contents: md4.c md5.c mdigest.c mfile.c shs.c


# Wrapped by alecm@uk-usenet on Thu Feb 24 09:36:44 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 2 (of 3)."'
if test -f 'md4.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'md4.c'\"
else
echo shar: Extracting \"'md4.c'\" \(8249 characters\)
sed "s/^X//" >'md4.c' <<'END_OF_FILE'
X
X/* Derived from:
X MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
X Notes: MD4Final has args changed -- mgream
X */
X
X/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
X
X License to copy and use this software is granted provided that it
X is identified as the "RSA Data Security, Inc. MD4 Message-Digest
X Algorithm" in all material mentioning or referencing this software
X or this function.
X
X License is also granted to make and use derivative works provided
X that such works are identified as "derived from the RSA Data
X Security, Inc. MD4 Message-Digest Algorithm" in all material
X mentioning or referencing the derived work.
X
X RSA Data Security, Inc. makes no representations concerning either
X the merchantability of this software or the suitability of this
X software for any particular purpose. It is provided "as is"
X without express or implied warranty of any kind.
X
X These notices must be retained in any copies of any part of this
X documentation and/or software.
X */
X
X#include "md4.h"
X
X/* Constants for MD4Transform routine.
X */
X#define S11 3
X#define S12 7
X#define S13 11
X#define S14 19
X#define S21 3
X#define S22 5
X#define S23 9
X#define S24 13
X#define S31 3
X#define S32 9
X#define S33 11
X#define S34 15
X
Xstatic void MD4Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
Xstatic void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int));
Xstatic void Decode PROTO_LIST ((UINT4 *, unsigned char *, unsigned int));
X
Xstatic unsigned char PADDING[64] = {
X 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
X};
X
X/* F, G and H are basic MD4 functions.
X */
X#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
X#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
X#define H(x, y, z) ((x) ^ (y) ^ (z))
X
X/* ROTATE_LEFT rotates x left n bits.
X */
X#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
X
X/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
X/* Rotation is separate from addition to prevent recomputation */
X
X#define FF(a, b, c, d, x, s) { \
X (a) += F ((b), (c), (d)) + (x); \
X (a) = ROTATE_LEFT ((a), (s)); \
X }
X#define GG(a, b, c, d, x, s) { \
X (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
X (a) = ROTATE_LEFT ((a), (s)); \
X }
X#define HH(a, b, c, d, x, s) { \
X (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
X (a) = ROTATE_LEFT ((a), (s)); \
X }
X
X/* MD4 initialization. Begins an MD4 operation, writing a new context.
X */
Xvoid MD4Init (context)
XMD4_CTX *context; /* context */
X{
X context->count[0] = context->count[1] = 0;
X
X /* Load magic initialization constants.
X */
X context->state[0] = 0x67452301;
X context->state[1] = 0xefcdab89;
X context->state[2] = 0x98badcfe;
X context->state[3] = 0x10325476;
X}
X
X/* MD4 block update operation. Continues an MD4 message-digest
X operation, processing another message block, and updating the
X context.
X */
Xvoid MD4Update (context, input, inputLen)
XMD4_CTX *context; /* context */
Xunsigned char *input; /* input block */
Xunsigned int inputLen; /* length of input block */
X{
X unsigned int i, index, partLen;
X
X /* Compute number of bytes mod 64 */
X index = (unsigned int)((context->count[0] >> 3) & 0x3F);
X /* Update number of bits */
X if ((context->count[0] += ((UINT4)inputLen << 3))
X < ((UINT4)inputLen << 3))
X context->count[1]++;
X context->count[1] += ((UINT4)inputLen >> 29);
X
X partLen = 64 - index;
X
X /* Transform as many times as possible.
X */
X if (inputLen >= partLen) {
X memcpy
X ((POINTER)&context->buffer[index], (POINTER)input, partLen);
X MD4Transform (context->state, context->buffer);
X
X for (i = partLen; i + 63 < inputLen; i += 64)
X MD4Transform (context->state, &input[i]);
X
X index = 0;
X }


X else
X i = 0;
X

X /* Buffer remaining input */
X memcpy
X ((POINTER)&context->buffer[index], (POINTER)&input[i],
X inputLen-i);
X}
X
X/* MD4 finalization. Ends an MD4 message-digest operation, writing the
X the message digest and zeroizing the context.
X */
Xvoid MD4Final (context, digest)
XMD4_CTX *context; /* context */
Xunsigned char digest[16]; /* message digest */
X{
X unsigned char bits[8];
X unsigned int index, padLen;
X
X /* Save number of bits */
X Encode (bits, context->count, 8);
X
X /* Pad out to 56 mod 64.
X */
X index = (unsigned int)((context->count[0] >> 3) & 0x3f);
X padLen = (index < 56) ? (56 - index) : (120 - index);
X MD4Update (context, PADDING, padLen);
X
X /* Append length (before padding) */
X MD4Update (context, bits, 8);
X /* Store state in digest */
X Encode (digest, context->state, 16);
X
X /* Zeroize sensitive information.
X */
X memset ((POINTER)context, 0, sizeof (*context));
X}
X
X/* MD4 basic transformation. Transforms state based on block.
X */
Xstatic void MD4Transform (state, block)
XUINT4 state[4];
Xunsigned char block[64];
X{
X UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
X
X Decode (x, block, 64);
X
X /* Round 1 */
X FF (a, b, c, d, x[ 0], S11); /* 1 */
X FF (d, a, b, c, x[ 1], S12); /* 2 */
X FF (c, d, a, b, x[ 2], S13); /* 3 */
X FF (b, c, d, a, x[ 3], S14); /* 4 */
X FF (a, b, c, d, x[ 4], S11); /* 5 */
X FF (d, a, b, c, x[ 5], S12); /* 6 */
X FF (c, d, a, b, x[ 6], S13); /* 7 */
X FF (b, c, d, a, x[ 7], S14); /* 8 */
X FF (a, b, c, d, x[ 8], S11); /* 9 */
X FF (d, a, b, c, x[ 9], S12); /* 10 */
X FF (c, d, a, b, x[10], S13); /* 11 */
X FF (b, c, d, a, x[11], S14); /* 12 */
X FF (a, b, c, d, x[12], S11); /* 13 */
X FF (d, a, b, c, x[13], S12); /* 14 */
X FF (c, d, a, b, x[14], S13); /* 15 */
X FF (b, c, d, a, x[15], S14); /* 16 */
X
X /* Round 2 */
X GG (a, b, c, d, x[ 0], S21); /* 17 */
X GG (d, a, b, c, x[ 4], S22); /* 18 */
X GG (c, d, a, b, x[ 8], S23); /* 19 */
X GG (b, c, d, a, x[12], S24); /* 20 */
X GG (a, b, c, d, x[ 1], S21); /* 21 */
X GG (d, a, b, c, x[ 5], S22); /* 22 */
X GG (c, d, a, b, x[ 9], S23); /* 23 */
X GG (b, c, d, a, x[13], S24); /* 24 */
X GG (a, b, c, d, x[ 2], S21); /* 25 */
X GG (d, a, b, c, x[ 6], S22); /* 26 */
X GG (c, d, a, b, x[10], S23); /* 27 */
X GG (b, c, d, a, x[14], S24); /* 28 */
X GG (a, b, c, d, x[ 3], S21); /* 29 */
X GG (d, a, b, c, x[ 7], S22); /* 30 */
X GG (c, d, a, b, x[11], S23); /* 31 */
X GG (b, c, d, a, x[15], S24); /* 32 */
X
X /* Round 3 */
X HH (a, b, c, d, x[ 0], S31); /* 33 */
X HH (d, a, b, c, x[ 8], S32); /* 34 */
X HH (c, d, a, b, x[ 4], S33); /* 35 */
X HH (b, c, d, a, x[12], S34); /* 36 */
X HH (a, b, c, d, x[ 2], S31); /* 37 */
X HH (d, a, b, c, x[10], S32); /* 38 */
X HH (c, d, a, b, x[ 6], S33); /* 39 */
X HH (b, c, d, a, x[14], S34); /* 40 */
X HH (a, b, c, d, x[ 1], S31); /* 41 */
X HH (d, a, b, c, x[ 9], S32); /* 42 */
X HH (c, d, a, b, x[ 5], S33); /* 43 */
X HH (b, c, d, a, x[13], S34); /* 44 */
X HH (a, b, c, d, x[ 3], S31); /* 45 */
X HH (d, a, b, c, x[11], S32); /* 46 */
X HH (c, d, a, b, x[ 7], S33); /* 47 */
X HH (b, c, d, a, x[15], S34); /* 48 */
X
X state[0] += a;
X state[1] += b;
X state[2] += c;
X state[3] += d;
X
X /* Zeroize sensitive information.
X */
X memset ((POINTER)x, 0, sizeof (x));
X}
X
X/* Encodes input (UINT4) into output (unsigned char). Assumes len is
X a multiple of 4.
X */
Xstatic void Encode (output, input, len)
Xunsigned char *output;
XUINT4 *input;
Xunsigned int len;
X{
X unsigned int i, j;
X
X for (i = 0, j = 0; j < len; i++, j += 4) {
X output[j] = (unsigned char)(input[i] & 0xff);
X output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
X output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
X output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
X }
X}
X
X/* Decodes input (unsigned char) into output (UINT4). Assumes len is
X a multiple of 4.
X */
Xstatic void Decode (output, input, len)
X
XUINT4 *output;
Xunsigned char *input;
Xunsigned int len;
X{
X unsigned int i, j;
X
X for (i = 0, j = 0; j < len; i++, j += 4)
X output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
X (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
X}
X
END_OF_FILE
if test 8249 -ne `wc -c <'md4.c'`; then
echo shar: \"'md4.c'\" unpacked with wrong size!
fi
# end of 'md4.c'
fi
if test -f 'md5.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'md5.c'\"
else
echo shar: Extracting \"'md5.c'\" \(9847 characters\)
sed "s/^X//" >'md5.c' <<'END_OF_FILE'
X
X/* derived from:
X MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
X Notes: reversed argument order to MD5Final -- mgream
X */
X
X/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
Xrights reserved.
X
XLicense to copy and use this software is granted provided that it
Xis identified as the "RSA Data Security, Inc. MD5 Message-Digest
XAlgorithm" in all material mentioning or referencing this software
Xor this function.
X
XLicense is also granted to make and use derivative works provided
Xthat such works are identified as "derived from the RSA Data
XSecurity, Inc. MD5 Message-Digest Algorithm" in all material
Xmentioning or referencing the derived work.
X
XRSA Data Security, Inc. makes no representations concerning either
Xthe merchantability of this software or the suitability of this
Xsoftware for any particular purpose. It is provided "as is"
Xwithout express or implied warranty of any kind.
X
XThese notices must be retained in any copies of any part of this
Xdocumentation and/or software.
X */
X
X#include "md5.h"
X
X/* Constants for MD5Transform routine.
X */
X
X#define S11 7
X#define S12 12
X#define S13 17
X#define S14 22
X#define S21 5
X#define S22 9
X#define S23 14
X#define S24 20
X#define S31 4
X#define S32 11
X#define S33 16
X#define S34 23
X#define S41 6
X#define S42 10
X#define S43 15
X#define S44 21
X
Xstatic void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
Xstatic void Encode PROTO_LIST ((unsigned char *, UINT4 *, unsigned int));
Xstatic void Decode PROTO_LIST ((UINT4 *, unsigned char *, unsigned int));
X
Xstatic unsigned char PADDING[64] = {
X 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
X};
X
X/* F, G, H and I are basic MD5 functions.
X */
X#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
X#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
X#define H(x, y, z) ((x) ^ (y) ^ (z))
X#define I(x, y, z) ((y) ^ ((x) | (~z)))
X
X/* ROTATE_LEFT rotates x left n bits.
X */
X#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
X
X/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
XRotation is separate from addition to prevent recomputation.
X */
X#define FF(a, b, c, d, x, s, ac) { \
X (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
X (a) = ROTATE_LEFT ((a), (s)); \
X (a) += (b); \
X }
X#define GG(a, b, c, d, x, s, ac) { \
X (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
X (a) = ROTATE_LEFT ((a), (s)); \
X (a) += (b); \
X }
X#define HH(a, b, c, d, x, s, ac) { \
X (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
X (a) = ROTATE_LEFT ((a), (s)); \
X (a) += (b); \
X }
X#define II(a, b, c, d, x, s, ac) { \
X (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
X (a) = ROTATE_LEFT ((a), (s)); \
X (a) += (b); \
X }
X
X/* MD5 initialization. Begins an MD5 operation, writing a new context.
X */
Xvoid MD5Init (context)
XMD5_CTX *context; /* context */
X{
X context->count[0] = context->count[1] = 0;
X /* Load magic initialization constants.
X*/
X context->state[0] = 0x67452301;
X context->state[1] = 0xefcdab89;
X context->state[2] = 0x98badcfe;
X context->state[3] = 0x10325476;
X}
X
X/* MD5 block update operation. Continues an MD5 message-digest
X operation, processing another message block, and updating the
X context.
X */
Xvoid MD5Update (context, input, inputLen)
XMD5_CTX *context; /* context */
Xunsigned char *input; /* input block */
Xunsigned int inputLen; /* length of input block */
X{
X unsigned int i, index, partLen;
X
X /* Compute number of bytes mod 64 */
X index = (unsigned int)((context->count[0] >> 3) & 0x3F);
X
X /* Update number of bits */
X if ((context->count[0] += ((UINT4)inputLen << 3))
X < ((UINT4)inputLen << 3))
X context->count[1]++;
X context->count[1] += ((UINT4)inputLen >> 29);
X
X partLen = 64 - index;
X
X /* Transform as many times as possible.
X*/
X if (inputLen >= partLen) {
X memcpy
X ((POINTER)&context->buffer[index], (POINTER)input, partLen);
X MD5Transform (context->state, context->buffer);
X
X for (i = partLen; i + 63 < inputLen; i += 64)
X MD5Transform (context->state, &input[i]);
X
X index = 0;
X }


X else
X i = 0;
X

X /* Buffer remaining input */
X memcpy
X ((POINTER)&context->buffer[index], (POINTER)&input[i],
X inputLen-i);
X}
X
X/* MD5 finalization. Ends an MD5 message-digest operation, writing the
X the message digest and zeroizing the context.
X */
Xvoid MD5Final (context, digest)
XMD5_CTX *context; /* context */
Xunsigned char digest[16]; /* message digest */
X{
X unsigned char bits[8];
X unsigned int index, padLen;
X
X /* Save number of bits */
X Encode (bits, context->count, 8);
X
X /* Pad out to 56 mod 64.
X*/
X index = (unsigned int)((context->count[0] >> 3) & 0x3f);
X padLen = (index < 56) ? (56 - index) : (120 - index);
X MD5Update (context, PADDING, padLen);
X
X /* Append length (before padding) */
X MD5Update (context, bits, 8);
X
X /* Store state in digest */
X Encode (digest, context->state, 16);
X
X /* Zeroize sensitive information.
X*/
X memset ((POINTER)context, 0, sizeof (*context));
X}
X
X/* MD5 basic transformation. Transforms state based on block.
X */
Xstatic void MD5Transform (state, block)
XUINT4 state[4];
Xunsigned char block[64];
X{
X UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
X
X Decode (x, block, 64);
X
X /* Round 1 */
X FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
X FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
X FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
X FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
X FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
X FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
X FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
X FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
X FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
X FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
X FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
X FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
X FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
X FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
X FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
X FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
X
X /* Round 2 */
X GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
X GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
X GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
X GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
X GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
X GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
X GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
X GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
X GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
X GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
X GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
X GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
X GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
X GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
X GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
X GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
X
X /* Round 3 */
X HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
X HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
X HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
X HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
X HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
X HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
X HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
X HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
X HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
X HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
X HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
X HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
X HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
X HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
X HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
X HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
X
X /* Round 4 */
X II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
X II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
X II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
X II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
X II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
X II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
X II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
X II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
X II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
X II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
X II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
X II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
X II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
X II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
X II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
X II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
X
X state[0] += a;
X state[1] += b;
X state[2] += c;
X state[3] += d;
X
X /* Zeroize sensitive information.
X*/
X memset ((POINTER)x, 0, sizeof (x));
X}
X
X/* Encodes input (UINT4) into output (unsigned char). Assumes len is
X a multiple of 4.
X */
Xstatic void Encode (output, input, len)
Xunsigned char *output;
XUINT4 *input;
Xunsigned int len;
X{
X unsigned int i, j;
X
X for (i = 0, j = 0; j < len; i++, j += 4) {
X output[j] = (unsigned char)(input[i] & 0xff);
X output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
X output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
X output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
X }
X}
X
X/* Decodes input (unsigned char) into output (UINT4). Assumes len is
X a multiple of 4.
X */
Xstatic void Decode (output, input, len)
XUINT4 *output;
Xunsigned char *input;
Xunsigned int len;
X{
X unsigned int i, j;
X
X for (i = 0, j = 0; j < len; i++, j += 4)
X output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
X (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
X}
X
X
END_OF_FILE
if test 9847 -ne `wc -c <'md5.c'`; then
echo shar: \"'md5.c'\" unpacked with wrong size!
fi
# end of 'md5.c'
fi
if test -f 'mdigest.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mdigest.c'\"
else
echo shar: Extracting \"'mdigest.c'\" \(10961 characters\)
sed "s/^X//" >'mdigest.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: mdigest.c%v 0.90 1994/02/22 20:37:24 matt Exp $
X */
X
X/*
X * File: mdigest.c
X * Description: generic interface for message digests
X */
X
X#include <mdigest.h>
X
X
Xextern err_code MD4_REGISTER ();
Xextern err_code MD5_REGISTER ();
Xextern err_code SHS_REGISTER ();
Xextern err_code HAVAL_REGISTER ();
X
Xstatic md_info* md_list[md_max_reg]; /* md info buckets */


X
X
X/* -------------------------------------------------------------------- */

X/* function : md_lookup_id */
X/* description : look for a specific id */
X/* -------------------------------------------------------------------- */
XGLOBAL md_info*
Xmd_lookup_id (ident)
X string ident; /* the string identifier */


X{
X word c;
X

X DEBUG_FUNCTION_ENTER("md_lookup_id");


X
X /* ---------------------------------------------------------------- */

X /* determine length of identifier, and hunt for it. */


X /* ---------------------------------------------------------------- */
X

X for (c = 0; c < md_max_reg; c++)
X if (md_list[c] != NULL &&
X strcasecmp (md_list[c]->ident, ident) == 0)
X return (md_list[c]);
X
X return (NULL);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : md_register */
X/* description : register an instance of an algorithm */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_register (ident, register_func)
X string ident; /* algorithm identifier */
X function register_func; /* function to setup info struct */


X{
X word c;
X

X DEBUG_FUNCTION_ENTER("md_register");


X
X /* ---------------------------------------------------------------- */

X /* check to see if it is registered and we have space */


X /* ---------------------------------------------------------------- */
X

X if (md_lookup_id(ident) != NULL)
X return (err_already_exist);


X
X /* ---------------------------------------------------------------- */

X /* if not, find free slot */


X /* ---------------------------------------------------------------- */
X

X c = 0;
X while (c < md_max_reg && md_list[c] != NULL)
X if (++c == md_max_reg)
X return (err_no_space);


X
X /* ---------------------------------------------------------------- */

X /* create entry, and call initialisation function */


X /* ---------------------------------------------------------------- */
X

X md_list[c] = (md_info*) mem_get (sizeof(md_info), MEMOPT_CLEAR);
X strncpy (md_list[c]->ident, ident, ident_sz);
X
X return (*register_func)(md_list[c]); /* return it's error code */
X}
X
X
X/* -------------------------------------------------------------------- */
X/* function : md_deregister */
X/* description : deregister an instance of an algorithm */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_deregister (ident)
X string ident; /* algorithm identifier */


X{
X word c;
X

X DEBUG_FUNCTION_ENTER("md_deregister");


X
X /* ---------------------------------------------------------------- */

X /* find the relevant slot and free the particular structure */


X /* ---------------------------------------------------------------- */
X

X for (c = 0; c < md_max_reg; c++)
X if (md_list[c] != NULL &&
X strcasecmp (md_list[c]->ident, ident) == 0)
X {
X if (md_list[c]->deregister != NULL)
X (void)(*(md_list[c]->deregister))(md_list[c]); /* ignore */
X
X mem_free (md_list[c]);
X md_list[c] = NULL;
X
X return (err_ok);
X }
X
X return (err_not_found);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : md_mod_open */
X/* description : initialise by registering all the message digests that */
X/* are to be linked in with this module */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_mod_open ()
X{
X
X DEBUG_FUNCTION_ENTER("md_mod_open");


X
X /* ---------------------------------------------------------------- */

X /* clear enter list structure and then call to setup */


X /* ---------------------------------------------------------------- */
X

X memset (md_list, 0, sizeof(md_list));


X
X /* ---------------------------------------------------------------- */

X /* register the already known ones -- insert yours here */
X /* NOTE: they currently ignore return error codes */


X /* ---------------------------------------------------------------- */
X

X md_register ("md4", MD4_REGISTER);
X md_register ("shs", SHS_REGISTER);
X md_register ("md5", MD5_REGISTER);
X md_register ("haval", HAVAL_REGISTER);
X#ifdef MD_INCLUDE_SNEFRU
X md_register ("snefru", SNEFRU_REGISTER);
X#endif
X
X return (err_ok);


X}
X
X/* -------------------------------------------------------------------- */

X/* function : md_mod_close */
X/* description : shutdown the module, and release algorithms */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_mod_close ()


X{
X word c;
X

X DEBUG_FUNCTION_ENTER("md_mod_close");


X
X /* ---------------------------------------------------------------- */

X /* deregister each one in turn */


X /* ---------------------------------------------------------------- */
X

X for (c = 0; c < md_max_reg; c++)
X if (md_list[c] != NULL)
X {
X if (md_list[c]->deregister != NULL)
X (void)(*(md_list[c]->deregister))(md_list[c]); /* ignore */
X
X mem_free (md_list[c]);
X md_list[c] = NULL;
X }
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : md_open */
X/* description : the first instance of creation of any context must */
X/* come here */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_open (req_ctx, ident)
X md_ctx* req_ctx; /* context to be initialised */
X string ident; /* algorithm to use */
X{
X
X DEBUG_FUNCTION_ENTER("md_open");


X
X /* ---------------------------------------------------------------- */

X /* check to make sure the request message digest is valid */
X /* and then setup */


X /* ---------------------------------------------------------------- */
X

X req_ctx->info = md_lookup_id (ident);
X
X if (req_ctx->info == NULL)
X return (err_invalid_alg);


X
X /* ---------------------------------------------------------------- */

X /* call the internal creation routine for the digest */


X /* ---------------------------------------------------------------- */
X

X req_ctx->priv = NULL;
X
X return md_create (req_ctx); /* return err_code from create */
X}
X
X
X/* -------------------------------------------------------------------- */
X/* function : md_close */
X/* description : close down a context by freeing any information */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_close (req_ctx)
X md_ctx* req_ctx; /* context to be close */
X{
X
X DEBUG_FUNCTION_ENTER("md_close");
X
X md_destroy (req_ctx);
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : md_list_init */
X/* description : initialise a state variable for walking the list */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_list_init (state_var)
X word* state_var; /* state variable */
X{
X
X DEBUG_FUNCTION_ENTER("md_list_init");
X
X *state_var = 0;
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : md_list_next */
X/* description : walk down the list */
X/* -------------------------------------------------------------------- */
XGLOBAL err_code
Xmd_list_next (state_var, ident)
X word* state_var; /* state variable */
X string ident; /* where to place ident */
X{
X
X DEBUG_FUNCTION_ENTER("md_list_next");


X
X /* ---------------------------------------------------------------- */

X /* basic strategy is to search from current position to a non empty */
X /* info structure, if the state_variable is out of the allowable */
X /* range, an error is returned, and if nothing is found, an error */
X /* is also returned. err_ok signifies successfull completion */


X /* ---------------------------------------------------------------- */
X

X if (*state_var < 0 || *state_var >= md_max_reg)
X return (err_invalid_params);
X
X while (md_list[*state_var] == NULL && *state_var < md_max_reg)
X (*state_var)++;
X
X if (*state_var == md_max_reg)
X return (err_no_more);
X
X strcpy (ident, md_list[*state_var]->ident);
X
X (*state_var)++;
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */
X

END_OF_FILE
if test 10961 -ne `wc -c <'mdigest.c'`; then
echo shar: \"'mdigest.c'\" unpacked with wrong size!
fi
# end of 'mdigest.c'
fi
if test -f 'mfile.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mfile.c'\"
else
echo shar: Extracting \"'mfile.c'\" \(8644 characters\)
sed "s/^X//" >'mfile.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X
X/* $Id: mfile.c%v 0.90 1994/02/22 20:51:46 matt Exp $
X */
X
X/*

X * File: mfile.c
X * Description: generate message digests for input files using
X * specific digest algs


X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <unistd.h>
X#include <fcntl.h>
X
X#include <mdigest.h>
X

X
X/* -------------------------------------------------------------------- */
X/* variables */
X/* -------------------------------------------------------------------- */
X
Xstatic char md_opt[md_max_reg][ident_sz+1]; /* ident storage */
Xword md_opt_sz = 0; /* number of idents loaded */
Xword md_opt_u = 0; /* bitstring of md's in use */
X
X#define BIT_P(x) (1L<<(x))
X
Xmd_ctx ctx_lst[md_max_reg]; /* contexts to be used */
Xword c; /* temp counter */
X
X#define BUF_LEN (16384) /* input buffer size */
Xopaque read_buf; /* input buffer */
X
Xstatic void file_sig ();
Xstatic string digest_to_hex ();
X
X/* -------------------------------------------------------------------- */
X/* function : show_usage */
X/* description : show command line usage */
X/* -------------------------------------------------------------------- */
Xstatic void
Xshow_usage (fn)
X string fn; /* argv[0] */
X{
X word i;
X
X fprintf (stderr, "Usage: %s ", fn);
X
X for (i = 0; i < md_opt_sz; i++)
X fprintf (stderr, "[-%s] ", md_opt[i]);
X
X fprintf (stderr, "file ...\n" );
X


X exit (1);
X}
X
X

X/* -------------------------------------------------------------------- */
X/* function : main */
X/* -------------------------------------------------------------------- */
Xvoid
Xmain (argc, argv)
X int argc;
X char** argv;
X{

X int ac;
X int file_h;
X word s;


X
X /* ---------------------------------------------------------------- */

X /* walk the list of preregistered message digests and store them */
X /* locally */


X /* ---------------------------------------------------------------- */
X
X md_mod_open ();

X md_list_init (&s);
X while (md_list_next (&s, md_opt[md_opt_sz] ) == err_ok)
X md_opt_sz++;
X


X
X /* ---------------------------------------------------------------- */

X /* parse command line, looking for '-<md>' */


X /* ---------------------------------------------------------------- */
X

X for (ac = 1; ac < argc && argv[ac][0] == '-'; ac++)
X {
X for (c = 0; c < md_opt_sz &&
X strncasecmp (&argv[ac][1], md_opt[c], 3) != 0; c++)
X ;
X
X if (c == md_opt_sz) /* couldn't find the alg */
X show_usage (argv[0]);
X
X md_opt_u |= BIT_P(c);
X }
X


X
X /* ---------------------------------------------------------------- */

X /* if nothing has been specified, then turn them all on */


X /* ---------------------------------------------------------------- */
X

X if (md_opt_u == 0)
X md_opt_u = (BIT_P(md_opt_sz) - 1);
X


X
X /* ---------------------------------------------------------------- */

X /* initialise the context for each requested alg */


X /* ---------------------------------------------------------------- */
X

X for (c = 0; c < md_opt_sz; c++)
X if (md_opt_u & BIT_P(c))
X if (md_open (&ctx_lst[c], md_opt[c]) != err_ok)
X {
X md_opt_u &= ~BIT_P(c);
X fprintf (stderr, " - notice: problem initialising digest '%s'.\n",
X md_opt[c]);
X }
X


X
X /* ---------------------------------------------------------------- */

X /* allocate the file buffer, then process each file or stdin if no */
X /* files were passed on the command line */


X /* ---------------------------------------------------------------- */
X

X read_buf = mem_get(BUF_LEN , MEMOPT_NONE);
X
X if (ac == argc)
X {
X printf ("stdin : ");
X file_sig (fileno(stdin));
X }
X else
X while (ac < argc)
X {
X printf ("%s : ", argv[ac]);
X
X if ((file_h = open(argv[ac], O_RDONLY)) < 0)
X printf ("file not found.\n");
X else
X {
X file_sig (file_h);
X close (file_h);
X }
X
X ac++;
X }


X
X /* ---------------------------------------------------------------- */

X /* destroy buffers, close module and exit */


X /* ---------------------------------------------------------------- */
X

X mem_free (read_buf);
X
X for (c = 0; c < md_opt_sz; c++)
X if (md_opt_u & BIT_P(c))
X (void)md_close (&ctx_lst[c]);


X
X md_mod_close ();
X

X exit (0);
X}
X
X
X/* -------------------------------------------------------------------- */
X/* function : digest_to_hex */
X/* description : format a digest into a hex string */
X/* -------------------------------------------------------------------- */
Xstatic string
Xdigest_to_hex (digest, sz)
X opaque digest; /* bytes of digest */
X word sz; /* # bytes in digest */
X{
X static char hex_str[81];
X word c;
X
X for (c = 0; c < sz; c++)
X sprintf (&hex_str[c<<1], "%02x", (digest[c] & 0xff));
X
X hex_str[c<<1] = '\0';
X return (hex_str);
X}
X

X
X/* -------------------------------------------------------------------- */
X/* function : file_sig */
X/* description : perform signature on the given file */
X/* -------------------------------------------------------------------- */
Xstatic void
Xfile_sig (file_h)
X int file_h; /* file handle */
X{
X int r;
X char digest[48];
X word32 fs = 0;
X
X /* ---------------------------------------------------------------- */
X /* initialise all md contexts */


X /* ---------------------------------------------------------------- */
X

X for (c = 0; c < md_opt_sz; c++)
X if (md_opt_u & BIT_P(c))
X md_init (&ctx_lst[c]);
X


X
X /* ---------------------------------------------------------------- */

X /* pull in buffers from file, updating md on each */


X /* ---------------------------------------------------------------- */
X

X do
X {
X if ((r = read(file_h, read_buf, BUF_LEN)) <= 0)
X break;
X
X for (c = 0; c < md_opt_sz; c++)
X if (md_opt_u & BIT_P(c))
X md_update (&ctx_lst[c], read_buf, r);
X
X fs += r;
X
X } while (r == BUF_LEN);


X
X /* ---------------------------------------------------------------- */

X /* display final tally */


X /* ---------------------------------------------------------------- */
X

X printf ("%lu bytes\n", fs);
X
X for (c = 0; c < md_opt_sz; c++)
X if (md_opt_u & BIT_P(c))
X {
X md_final (&ctx_lst[c], digest);
X
X printf (" %-8s : %s\n", md_opt[c],
X digest_to_hex(digest, md_hash_sz(&ctx_lst[c])));


X }
X}
X
X/* -------------------------------------------------------------------- */

END_OF_FILE
if test 8644 -ne `wc -c <'mfile.c'`; then
echo shar: \"'mfile.c'\" unpacked with wrong size!
fi
# end of 'mfile.c'
fi
if test -f 'shs.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'shs.c'\"
else
echo shar: Extracting \"'shs.c'\" \(12355 characters\)
sed "s/^X//" >'shs.c' <<'END_OF_FILE'
X/* --------------------------------- SHS.C ------------------------------- */
X
X/* NIST proposed Secure Hash Standard.
X
X Written 2 September 1992, Peter C. Gutmann.
X This implementation placed in the public domain.
X
X Modified 1 June 1993, Colin Plumb.
X These modifications placed in the public domain.
X
X mgream: feb/94, changed prototypes/args to be KNR for compat.
X mgream: added runtime endian check
X
X Comments to pg...@cs.aukuni.ac.nz */
X
X#include <string.h>
X#include "shs.h"
X
X/* The SHS f()-functions. The f1 and f3 functions can be optimized to
X save one boolean operation each - thanks to Rich Schroeppel,
X r...@cs.arizona.edu for discovering this */
X
X/*#define f1(x,y,z) ( (x & y) | (~x & z) ) // Rounds 0-19 */
X#define f1(x,y,z) ( z ^ (x & (y ^ z) ) ) /* Rounds 0-19 */
X#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
X/*#define f3(x,y,z) ( (x & y) | (x & z) | (y & z) ) // Rounds 40-59 */
X#define f3(x,y,z) ( (x & y) | (z & (x | y) ) ) /* Rounds 40-59 */
X#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
X
X/* The SHS Mysterious Constants */
X
X#define K1 0x5A827999L /* Rounds 0-19 */
X#define K2 0x6ED9EBA1L /* Rounds 20-39 */
X#define K3 0x8F1BBCDCL /* Rounds 40-59 */
X#define K4 0xCA62C1D6L /* Rounds 60-79 */
X
X/* SHS initial values */
X
X#define h0init 0x67452301L
X#define h1init 0xEFCDAB89L
X#define h2init 0x98BADCFEL
X#define h3init 0x10325476L
X#define h4init 0xC3D2E1F0L
X
X/* Note that it may be necessary to add parentheses to these macros
X if they are to be called with expressions as arguments. */
X
X/* 32-bit rotate left - kludged with shifts */
X
X#define ROTL(n,X) ( (X << n) | ( X >> (32-n) ) )
X
X/* The initial expanding function */
X/* The hash function is defined over an 80-word expanded input array W,
X where the first 16 are copies of the input data, and the remaining 64
X are defined by W[i] = W[i-16] ^ W[i-14] ^ W[i-8] ^ W[i-3]. This
X implementation generates these values on the fly in a circular buffer. */
X
X#define expand(W,i) ( W[i & 15] ^= W[i-14 & 15] ^ W[i-8 & 15] ^ W[i-3 & 15] )
X
X/* The prototype SHS sub-round */
X/* The fundamental sub-round is
X a' = e + ROTL(5,a) + f(b, c, d) + k + data;
X b' = a;
X c' = ROTL(30,b);
X d' = c;
X e' = d;
X ... but this is implemented by unrolling the loop 5 times and renaming
X the variables (e,a,b,c,d) = (a',b',c',d',e') each iteration. */
X
X#define subRound(a, b, c, d, e, f, k, data) \
X ( e += ROTL(5,a) + f(b, c, d) + k + data, b = ROTL(30, b) )
X
X/* The above code is replicated 20 times for each of the 4 functions,
X using the next 20 values from the W[] array each time. */
X
X/* Initialize the SHS values */
X
Xstatic int endian; /* figure out endian-ness while running */
X
Xvoid shsInit( shsInfo )
X SHS_INFO* shsInfo;
X{
X /* Set the h-vars to their initial values */
X shsInfo->digest[ 0 ] = h0init;
X shsInfo->digest[ 1 ] = h1init;
X shsInfo->digest[ 2 ] = h2init;
X shsInfo->digest[ 3 ] = h3init;
X shsInfo->digest[ 4 ] = h4init;
X
X /* Initialise bit count */
X#ifdef HAVE64
X shsInfo->count = 0;
X#else
X shsInfo->countLo = shsInfo->countHi = 0;
X#endif


X
X if ((*(unsigned short *) ("@P") >> 8) == '@')

X endian = 1; /* BIG ENDIAN */
X else
X endian = 0; /* LITTLE ENDIAN */
X}
X
X/* Perform the SHS transformation. Note that this code, like MD5, seems to
X break some optimizing compilers due to the complexity of the expressions
X and the size of the basic block. It may be necessary to split it into
X sections, e.g. based on the four subrounds
X
X Note that this corrupts the shsInfo->data area */
X
Xvoid shsTransform( shsInfo )
X SHS_INFO *shsInfo;
X{
X register WORD32 A, B, C, D, E;
X
X /* Set up first buffer */
X A = shsInfo->digest[ 0 ];
X B = shsInfo->digest[ 1 ];
X C = shsInfo->digest[ 2 ];
X D = shsInfo->digest[ 3 ];
X E = shsInfo->digest[ 4 ];
X
X /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
X subRound( A, B, C, D, E, f1, K1, shsInfo->data[ 0] );
X subRound( E, A, B, C, D, f1, K1, shsInfo->data[ 1] );
X subRound( D, E, A, B, C, f1, K1, shsInfo->data[ 2] );
X subRound( C, D, E, A, B, f1, K1, shsInfo->data[ 3] );
X subRound( B, C, D, E, A, f1, K1, shsInfo->data[ 4] );
X subRound( A, B, C, D, E, f1, K1, shsInfo->data[ 5] );
X subRound( E, A, B, C, D, f1, K1, shsInfo->data[ 6] );
X subRound( D, E, A, B, C, f1, K1, shsInfo->data[ 7] );
X subRound( C, D, E, A, B, f1, K1, shsInfo->data[ 8] );
X subRound( B, C, D, E, A, f1, K1, shsInfo->data[ 9] );
X subRound( A, B, C, D, E, f1, K1, shsInfo->data[10] );
X subRound( E, A, B, C, D, f1, K1, shsInfo->data[11] );
X subRound( D, E, A, B, C, f1, K1, shsInfo->data[12] );
X subRound( C, D, E, A, B, f1, K1, shsInfo->data[13] );
X subRound( B, C, D, E, A, f1, K1, shsInfo->data[14] );
X subRound( A, B, C, D, E, f1, K1, shsInfo->data[15] );
X subRound( E, A, B, C, D, f1, K1, expand(shsInfo->data, 16) );
X subRound( D, E, A, B, C, f1, K1, expand(shsInfo->data, 17) );
X subRound( C, D, E, A, B, f1, K1, expand(shsInfo->data, 18) );
X subRound( B, C, D, E, A, f1, K1, expand(shsInfo->data, 19) );
X
X subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 20) );
X subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 21) );
X subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 22) );
X subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 23) );
X subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 24) );
X subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 25) );
X subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 26) );
X subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 27) );
X subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 28) );
X subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 29) );
X subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 30) );
X subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 31) );
X subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 32) );
X subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 33) );
X subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 34) );
X subRound( A, B, C, D, E, f2, K2, expand(shsInfo->data, 35) );
X subRound( E, A, B, C, D, f2, K2, expand(shsInfo->data, 36) );
X subRound( D, E, A, B, C, f2, K2, expand(shsInfo->data, 37) );
X subRound( C, D, E, A, B, f2, K2, expand(shsInfo->data, 38) );
X subRound( B, C, D, E, A, f2, K2, expand(shsInfo->data, 39) );
X
X subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 40) );
X subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 41) );
X subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 42) );
X subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 43) );
X subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 44) );
X subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 45) );
X subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 46) );
X subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 47) );
X subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 48) );
X subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 49) );
X subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 50) );
X subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 51) );
X subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 52) );
X subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 53) );
X subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 54) );
X subRound( A, B, C, D, E, f3, K3, expand(shsInfo->data, 55) );
X subRound( E, A, B, C, D, f3, K3, expand(shsInfo->data, 56) );
X subRound( D, E, A, B, C, f3, K3, expand(shsInfo->data, 57) );
X subRound( C, D, E, A, B, f3, K3, expand(shsInfo->data, 58) );
X subRound( B, C, D, E, A, f3, K3, expand(shsInfo->data, 59) );
X
X subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 60) );
X subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 61) );
X subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 62) );
X subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 63) );
X subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 64) );
X subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 65) );
X subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 66) );
X subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 67) );
X subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 68) );
X subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 69) );
X subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 70) );
X subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 71) );
X subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 72) );
X subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 73) );
X subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 74) );
X subRound( A, B, C, D, E, f4, K4, expand(shsInfo->data, 75) );
X subRound( E, A, B, C, D, f4, K4, expand(shsInfo->data, 76) );
X subRound( D, E, A, B, C, f4, K4, expand(shsInfo->data, 77) );
X subRound( C, D, E, A, B, f4, K4, expand(shsInfo->data, 78) );
X subRound( B, C, D, E, A, f4, K4, expand(shsInfo->data, 79) );
X
X /* Build message digest */
X shsInfo->digest[ 0 ] += A;
X shsInfo->digest[ 1 ] += B;
X shsInfo->digest[ 2 ] += C;
X shsInfo->digest[ 3 ] += D;
X shsInfo->digest[ 4 ] += E;
X}
X
X/* When run on a little-endian CPU we need to perform byte reversal on an
X array of longwords. It is possible to make the code endianness-
X independant by fiddling around with data at the byte level, but this
X makes for very slow code, so we rely on the user to sort out endianness
X at compile time
X mgream: i've added endian check in init stage, and put the check down
X before byteReverse is called, the overhead should be exceedingly minimal
X */
X
Xstatic void byteReverse( buffer, byteCount )
X WORD32 *buffer;
X unsigned byteCount;
X{
X WORD32 value;
X
X byteCount /= sizeof(WORD32);
X while ( byteCount-- ) {
X value = *buffer;
X value = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 );
X *buffer++ = ( value << 16 ) | ( value >> 16 );
X }
X}
X
X/* Update SHS for a block of data. */
X
Xvoid shsUpdate( shsInfo, buffer, count )
X SHS_INFO *shsInfo;
X BYTE *buffer;
X unsigned count;
X{
X WORD32 t;
X
X /* Update bitcount */
X
X#ifdef HAVE64
X t = ( (WORD32)shsInfo->count >> 3) & 0x3f;
X shsInfo->count += (WORD64)count << 3;
X#else
X t = shsInfo->countLo;
X if ( ( shsInfo->countLo = t + ( (WORD32)count << 3) ) < t )
X shsInfo->countHi++; /* Carry from low to high */
X shsInfo->countHi += count >> 29;
X
X t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
X#endif
X
X /* Handle any leading odd-sized chunks */
X
X if ( t ) {
X BYTE *p = (BYTE *)shsInfo->data + t;
X
X t = 64-t;
X if (count < t) {
X memcpy( p, buffer, count );
X return;
X }
X memcpy( p, buffer, t );
X if (endian == 0) /* little endian */
X byteReverse( shsInfo->data, SHS_BLOCKSIZE );
X shsTransform( shsInfo );
X buffer += t;
X count -= t;
X }
X
X /* Process data in SHS_BLOCKSIZE chunks */
X
X while( count >= SHS_BLOCKSIZE ) {
X memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE );
X if (endian == 0) /* little endian */
X byteReverse( shsInfo->data, SHS_BLOCKSIZE );
X shsTransform( shsInfo );
X buffer += SHS_BLOCKSIZE;
X count -= SHS_BLOCKSIZE;
X }
X
X /* Handle any remaining bytes of data. */
X
X memcpy( shsInfo->data, buffer, count );
X}
X
X/* Final wrapup - pad to 64-byte boundary with the bit pattern
X 1 0* (64-bit count of bits processed, MSB-first) */
X
Xvoid shsFinal( shsInfo )
X SHS_INFO *shsInfo;
X{
X int count;
X BYTE *p;
X
X /* Compute number of bytes mod 64 */
X#ifdef HAVE64
X count = (int)shsInfo->count;
X#else
X count = (int)shsInfo->countLo;
X#endif
X count = ( count >> 3 ) & 0x3F;
X
X /* Set the first char of padding to 0x80. This is safe since there is
X always at least one byte free */
X p = (BYTE *)shsInfo->data + count;
X *p++ = 0x80;
X
X /* Bytes of padding needed to make 64 bytes */
X count = SHS_BLOCKSIZE - 1 - count;
X
X /* Pad out to 56 mod 64 */
X if( count < 8 ) {
X /* Two lots of padding: Pad the first block to 64 bytes */
X memset( p, 0, count );
X if (endian == 0) /* little endian */
X byteReverse( shsInfo->data, SHS_BLOCKSIZE );
X shsTransform( shsInfo );
X
X /* Now fill the next block with 56 bytes */
X memset( shsInfo->data, 0, SHS_BLOCKSIZE - 8 );
X } else {
X /* Pad block to 56 bytes */
X memset( p, 0, count - 8 );
X }
X if (endian == 0) /* little endian */
X byteReverse( shsInfo->data, SHS_BLOCKSIZE-8 );
X
X /* Append length in bits and transform */
X#if HAVE64
X shsInfo->data[ 14 ] = (WORD32)( shsInfo->count >> 32 );
X shsInfo->data[ 15 ] = (WORD32)shsInfo->count;
X#else
X shsInfo->data[ 14 ] = shsInfo->countHi;
X shsInfo->data[ 15 ] = shsInfo->countLo;
X#endif
X
X shsTransform( shsInfo );
X}
X
END_OF_FILE
if test 12355 -ne `wc -c <'shs.c'`; then
echo shar: \"'shs.c'\" unpacked with wrong size!
fi
# end of 'shs.c'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone

Matthew Gream

unread,
Feb 28, 1994, 1:26:19 PM2/28/94
to
Submitted-by: M.G...@uts.edu.au (Matthew Gream)
Posting-number: Volume 41, Issue 139
Archive-name: mdigest/part03
Environment: C

#! /bin/sh
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sou...@uunet.uu.net if you want that tool.

# Contents: CHECKSUMS Makefile haval-if.c haval.h license.txt md4-if.c
# md4.h md5-if.c md5.h mdigest.h shs-if.c shs.h utility.c


# Wrapped by alecm@uk-usenet on Thu Feb 24 09:36:44 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:

echo ' "shar: End of archive 3 (of 3)."'
if test -f 'CHECKSUMS' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'CHECKSUMS'\"
else
echo shar: Extracting \"'CHECKSUMS'\" \(4908 characters\)
sed "s/^X//" >'CHECKSUMS' <<'END_OF_FILE'
XEXPORT : 97 bytes
X md4 : 3ac4f1f5f90b8b1f50416125729f1baa
X shs : e4c0e82642034a2e1fb1ea8052ca72fd4243165d
X md5 : 151cbda69cfd23e6120ee4f65fb7dd8d
X haval : be77c00fc6ba285d78d2e2c4918f7358
XMakefile : 598 bytes
X md4 : b7189b9e9dd45996a6eb64e1ff56d487
X shs : b08571682e27ba4a502ad7d556a75af0fd35ceb4
X md5 : d9f729f47f134cad9da76e5757e9fedb
X haval : 5d0f1e5c45462d4e6573e8d917a20813
XREADME : 10157 bytes
X md4 : e3c49ed13ddd7e06c60c54a6b4787366
X shs : 06c1c80b4e18a7512b36eb2c30faf24a7b5eaf48
X md5 : 06dc11c849fadf75b9a279f5fe6582f5
X haval : e3b2445af1096d6d41abfb444d23a917
Xhaval-if.c : 3024 bytes
X md4 : 53cab1c8835daeb44d157e889cae8542
X shs : 6ae9ce9504342fec2298004b77cd1d71210a5d2d
X md5 : 77aea8bc4f32f6e87826957713ee3ec8
X haval : 7722a0f85bff94f7838b33632d30f728
Xhaval.c : 26139 bytes
X md4 : e317891d8b9480b9a1446f779ea6ba7a
X shs : 3051aec69d62d2d912e961d765bc3b2834d0a172
X md5 : 8eed73ca3a388848aad8d713ec37a101
X haval : 411dbdbde75d51143333789f7724cce4
Xhaval.h : 2980 bytes
X md4 : f3b035277bd40d67791c140029f5fca6
X shs : da13bca519d71a25c666f11461c43c5d896dac5a
X md5 : 153c94e7dcbab4660a6ccb916ede4781
X haval : 28b33bf339aefa4543d441c7e217fcb9
Xlicense.txt : 3733 bytes
X md4 : 741462d6ce28e1cd0b9c32a9173fb4e4
X shs : 3de46d78eabeac4c1f87149a5b0085ef2ec11024
X md5 : 33386c167d8f012b437e70c3c0f98a94
X haval : c38ae05ca51511935ae867442f0f8ee7
Xmd4-if.c : 2963 bytes
X md4 : eb51bbba579f6156b33917a5fc812e31
X shs : 53799be5b79bda841fde3bc20582e00fd80b8b1a
X md5 : 0825b96ab0428ccd00d2f976a7b152da
X haval : 6067cc0ea94e504e457da42007d58b72
Xmd4.c : 8249 bytes
X md4 : dcd9c022b19bd3046b8460a2c243491b
X shs : ac634f340ceb8bb3f1323002af85411cc7cb9811
X md5 : 1587b45eb7339f13dec1a5b4ea923746
X haval : 8e05626384ec85374ec7c84849659ff8
Xmd4.h : 1885 bytes
X md4 : 44ac5f61de4ff311b28f2cfcc4dbab99
X shs : dafdf2f0db16aafc1448cc85c72e17ccac95bb23
X md5 : 86cc0bcbd18a73f1b4123437b9769f0f
X haval : 58b4bc1b974069f1030759926b705dfa
Xmd5-if.c : 2964 bytes
X md4 : c06567cc83c254b77e86bd3d7a32fd40
X shs : 92925a403ca84a11654ced4074fee2188a32e458
X md5 : be9119aee609c6375046a3df1d75492e
X haval : e37ca5c533d46dcc7eec78dc2f16f233
Xmd5.c : 9847 bytes
X md4 : d84c616028ea36c08c26441c922ee4e0
X shs : 28c779bf5821d147e4cb43bfd1b52dfed138decd
X md5 : 394d19028b0774e842372ce6cfb971ea
X haval : 330dbb5ff4efc6c92492b1067ba52943
Xmd5.h : 1885 bytes
X md4 : 759872f325c96abce82e408e7f7153f8
X shs : f9978e289707aa2b8fe7d9ef3e5a3227a7db3018
X md5 : d7fa2167486edc450e7a1c73ae1eaada
X haval : 038ecea7854a1d024a55441633b240aa
Xmdigest.c : 10961 bytes
X md4 : 36d674aea8350948bfe1bb8051efd4ff
X shs : 3ed687237403187b77f25e4102fdf4b70cff8862
X md5 : fc43047ad2b642f845acecfdc88975bb
X haval : 4967a23bda802f8acf739dfa2c2bc6cb
Xmdigest.h : 8184 bytes
X md4 : bcde76cbc21787d133f3f255bf07344e
X shs : 6bdb9a733ada0e07d871193992462962c69b9750
X md5 : ffb96e9124d0e69741bd6475d566a51d
X haval : 8326ad6425ab95d13a13836251e70e97
Xmfile.c : 8644 bytes
X md4 : e6000a5b552dda4103679b1fede5690d
X shs : 20cfcd4c1efe86702891d60c2926fce32a5e8e18
X md5 : 8d4ace4e886820e123fd779e9253f66b
X haval : d43cb7cf0172a494d3f7a58e15511464
Xmtest.c : 11052 bytes
X md4 : 972ce79b66abf9b4d762318f9bfb40ce
X shs : c43195c45cb0f79c5cf95d3c6615d94e06e803df
X md5 : 0f7a7e2c5671f000b1d4e6d2b9ecf2b5
X haval : 5db33ece31d35e3526b294f67e5434b1
Xshs-if.c : 3568 bytes
X md4 : ca050edf795ef0a5d6db2f4df6ac2ccd
X shs : 5d05654a1bb62ec8308b815c454fe2e6ac8d8014
X md5 : f817be75acb95e6f06b013cf47f44761
X haval : c11cd17aad8024745957cb55f487f9f0
Xshs-old.c : 8625 bytes
X md4 : d7371df64f71187475ab94ee45a24c1f
X shs : e5c6a9d78f4d137a3cdfada467fa7fe28c6e1c55
X md5 : e69390167a9e3351a8126334a27eaf68
X haval : aabebccdd08e2b7d9e67cf1a069f9648
Xshs-old.h : 1237 bytes
X md4 : b5622e691981b7f2ea5b1fe8aa9c0ef5
X shs : 3004e0f2462db45d5fd2a4b5ff5520644a16f27a
X md5 : 2edf211dd753cedb1c0c9824eaab716d
X haval : 4a59a814c90a8180ce86c0c01a493f9b
Xshs.c : 12355 bytes
X md4 : 51b876be3c89e403877e589a2c1eb4fe
X shs : 86906cc236a78cb35f225b578a44c25ea91b3f57
X md5 : a90364e8128b70875ef5f199528c1025
X haval : 02dcaf11d501af82dbd93163853928a8
Xshs.h : 1619 bytes
X md4 : 7f5331a02c3fe9923901218e198dd691
X shs : 7a4182de7198c93466ed46f56afa229f2cd26e44
X md5 : 4a1d9b2cd015186d0848a52fbda0ed32
X haval : b2ebd0355313ceb85842491f82c2c4ee
Xutility.c : 3574 bytes
X md4 : 9eea7d930f09212c6353de51c5b031c0
X shs : bb100d514f8658b5451109a9b80f6d4a87608d4d
X md5 : 37d0e42deb7a9bccd13ebb3ab8707610
X haval : 5ef3fc0c3940395122754acab320875a
END_OF_FILE
if test 4908 -ne `wc -c <'CHECKSUMS'`; then
echo shar: \"'CHECKSUMS'\" unpacked with wrong size!
fi
# end of 'CHECKSUMS'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(598 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X
XCC = cc
XAR = ar
XRANLIB = ranlib
X
XCFLAGS = -I. -O4 #-Wall
XLDFLAGS = $(CFLAGS) -s
XARFLAGS = rc
X
XLIB = mdigest.a
XLIB_OBJS= mdigest.o utility.o \
X md4.o md4-if.o \
X md5.o md5-if.o \
X shs.o shs-if.o \
X haval.o haval-if.o
X
X# ---
X
Xall: $(LIB) mfile mtest
X
X# ---
X
X$(LIB): $(LIB_OBJS)
X rm -f $(LIB)
X $(AR) $(ARFLAGS) $(LIB) $(LIB_OBJS)
X $(RANLIB) $(LIB)
X
Xmfile: $(LIB) mfile.o
X $(CC) $(LDFLAGS) -o mfile mfile.o $(LIB)
X
Xmtest: $(LIB) mtest.o
X $(CC) $(LDFLAGS) -o mtest mtest.o $(LIB)
X
X# ---
X
Xclean:
X rm -f $(LIB_OBJS) mfile.o mtest.o a.out core
X
Xclobber: clean
X rm -f $(LIB) mfile mtest
X
END_OF_FILE
if test 598 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'haval-if.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'haval-if.c'\"
else
echo shar: Extracting \"'haval-if.c'\" \(3024 characters\)
sed "s/^X//" >'haval-if.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: haval-if.c%v 0.90 1994/02/22 20:37:24 matt Exp $
X */
X
X/*
X * File: haval-if.c
X * Description: interface to haval message digest


X */
X
X#include <mdigest.h>

X#include "haval.h"


X
X
X/* -------------------------------------------------------------------- */

X/* function : HAVAL_CREATE */
X/* description : individually setup a haval context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XHAVAL_CREATE (ctx)
X md_ctx* ctx; /* context to setup */
X{
X if (ctx->priv == NULL)
X ((haval_state*)ctx->priv) = (haval_state*)mem_get (sizeof(haval_state), MEMOPT_CLEAR);
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : HAVAL_DESTROY */
X/* description : shutdown a previously allocated context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XHAVAL_DESTROY (ctx)
X md_ctx* ctx; /* context to deallocate */
X{
X if (ctx->priv != NULL)
X mem_free (ctx->priv);
X
X ctx->priv = NULL;
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : HAVAL_REGISTER */
X/* description : register and setup haval info structure */


X/* -------------------------------------------------------------------- */
XGLOBAL err_code

XHAVAL_REGISTER (m)
X md_info* m; /* info structure to fill out */
X{
X m->block_sz = 128;
X m->hash_sz = FPTLEN >> 3;
X
X m->create = HAVAL_CREATE;
X m->destroy = HAVAL_DESTROY;
X m->deregister = NULL;
X
X m->init = haval_start;
X m->update = haval_hash;
X m->final = haval_end;
X
X return (err_ok);


X}
X
X/* -------------------------------------------------------------------- */
X

END_OF_FILE
if test 3024 -ne `wc -c <'haval-if.c'`; then
echo shar: \"'haval-if.c'\" unpacked with wrong size!
fi
# end of 'haval-if.c'
fi
if test -f 'haval.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'haval.h'\"
else
echo shar: Extracting \"'haval.h'\" \(2980 characters\)
sed "s/^X//" >'haval.h' <<'END_OF_FILE'
X
X/* -- derived from original havalapp.h and haval.h
X * -- mgream: endian definitions not needed, they are computed run time
X * -- mgream: changed prototypes from ansi (for compat)
X *
X * havalapp.h: specifies the following three constants needed to
X * compile the HAVAL hashing library:
X * LITTLE_ENDIAN, PASS and FPTLEN


X *
X * Descriptions:
X *

X * LITTLE_ENDIAN define this only if your machine is little-endian
X * (such as 80X86 family).
X *
X * Note:
X * 1. In general, HAVAL is faster on a little endian
X * machine than on a big endian one.
X *
X * 2. The test program "havaltest.c" provides an option
X * for testing the endianity of your machine.
X *
X * 3. The speed of HAVAL is even more remarkable on a
X * machine that has a large number of internal registers.
X *
X * PASS define the number of passes (3, 4, or 5)
X * FPTLEN define the length of a fingerprint (128, 160, 192, 224 or 256)
X */
X
X/*#define LITTLE_ENDIAN*/
X
X#ifndef PASS
X#define PASS 3 /* 3, 4, or 5 */
X#endif
X
X#ifndef FPTLEN
X#define FPTLEN 128 /* 128, 160, 192, 224 or 256 */
X#endif
X
X/*
X * haval.h: specifies the interface to the HAVAL (V.1) hashing library.


X *
X * HAVAL is a one-way hashing algorithm with the following
X * collision-resistant property:
X * It is computationally infeasible to find two or more
X * messages that are hashed into the same fingerprint.
X *
X * Reference:
X * Y. Zheng, J. Pieprzyk and J. Seberry:
X * ``HAVAL --- a one-way hashing algorithm with variable
X * length of output'', Advances in Cryptology --- AUSCRYPT'92,
X * Lecture Notes in Computer Science, Springer-Verlag, 1993.
X *

X * This library provides routines to hash
X * - a string,
X * - a file,
X * - input from the standard input device,
X * - a 32-word block, and
X * - a string of specified length.
X *


X * Author: Yuliang Zheng
X * Department of Computer Science
X * University of Wollongong
X * Wollongong, NSW 2522, Australia
X * Email: yul...@cs.uow.edu.au
X * Voice: +61 42 21 4331 (office)
X *
X * Date: June 1993
X *
X * Copyright (C) 1993 by C^3SR. All rights reserved.
X * This program may not be sold or used as inducement to
X * buy a product without the written permission of C^3SR.
X */
X

Xtypedef unsigned long int haval_word; /* a HAVAL word = 32 bits */
X
Xtypedef struct {
X haval_word count[2]; /* number of bits in a message */
X haval_word fingerprint[8]; /* current state of fingerprint */
X haval_word block[32]; /* buffer for a 32-word block */
X unsigned char remainder[32*4]; /* unhashed chars (No.<128) */
X} haval_state;
X
Xvoid haval_start ();
Xvoid haval_hash ();
Xvoid haval_end ();
X
END_OF_FILE
if test 2980 -ne `wc -c <'haval.h'`; then
echo shar: \"'haval.h'\" unpacked with wrong size!
fi
# end of 'haval.h'
fi
if test -f 'license.txt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'license.txt'\"
else
echo shar: Extracting \"'license.txt'\" \(3733 characters\)
sed "s/^X//" >'license.txt' <<'END_OF_FILE'
X
XSACS LIBRARY SOFTWARE LICENSE
X
X
XMatthew Gream
XM.G...@uts.edu.au
X+61-2-821-2043
XMarch 1994
X
X
X-- BEGIN LICENCE --
X
XUnless specifically authorized in writing by the author of this
Xlibrary, you are given a limited license to use and distributed
Xthis library and software incorporating elements of this library
Xin accordance with the following conditions:
X
X 1. WARRANTIES AND SUITABILITY TO TASK
X
X This library comes with no warranties at all, either expressed
X or implied. This includes such warranties as merchantability
X or fitness for a particular purpose. There is no guarantee
X whatsoever that this library will perform as per expected and
X described operation.
X
X 2. COST RECOVERY
X
X Except to recover reasonable costs for media and distribution
X purposes, monies or payment in any form whatsoever for this
X library or creations incorporating any element of this library
X may not be made.
X
X 3. MODIFICATION AND/OR DISTRIBUTION
X
X You many not modify and/or distribute modified copies of this
X library or provide mechanisms for creating modified versions
X of this library without prior consent of the author. You may,
X however, for the purposes of integration and development of
X software using elements of this library make minimal and
X reasonable changes to ensure this library will compile on an
X otherwise incompatible operating system. These modifications
X must not change the functionality of the library and must
X interoperate with existing unmodified versions of this
X library.
X
X 4. COPYRIGHT AND CREATION NOTICES
X
X Any software incorporating or using elements of this library
X must ensure that notice is placed in such software or
X accompanying documentation so as to give credit to the
X authorship, copyright ownership and current version of this
X library.
X
X 5. NOTIFICATION OF USE
X
X Reasonable attempts must be made to notify the author of this
X library of the existence and generation of any software that
X incorporates elements of this library. Further, reasonable
X attempts must be made to provide the author with a copy of
X such software.
X
X
X-- END LICENSE --
X
X
XA rough english-speak translation of the above is as such (this
Xdoes not constitute part of the license, but merely attempts to
Xexplain it):
X
X Unless I specifically say so, all the following holds. Which
X means I may of course relax any or all of the following
X restrictions or modify them on request.
X
X This library is free, and you are allowed to use it for free
X providing you or someone isn't going to make any money out of
X it. Shareware or commercial use maybe considered upon
X application to the author. At the same time, this library is
X centrally controlled in terms of modifications and future
X revisions. This means that only I as the author can release
X new versions of any form, though you are welcome to submit
X patches or improvements to me. This means you are not allowed
X to distribute modified copies of this library or software to
X generate modified copies of this library.
X
X I do this to prevent splinters in the source tree, and to
X maintain compatibility. I do allow the distribution of patches
X that fix existing bugs or incompatibilities with particular
X operating systems, provided the patches don't change the way
X the library operates and don't stop it interoperating with
X unmodified versions of the library.
X
X I also ask that you make best efforts to send me, or notify me
X about how to retrieve a copy of any software which uses this
X library. The reason I ask this is that feedback of this sort
X is important in determining modifications and future
X directions of the library. By the same token, I welcome any
X _constructive_ criticisms, comments and suggestions.
X
X
X
END_OF_FILE
if test 3733 -ne `wc -c <'license.txt'`; then
echo shar: \"'license.txt'\" unpacked with wrong size!
fi
# end of 'license.txt'
fi
if test -f 'md4-if.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'md4-if.c'\"
else
echo shar: Extracting \"'md4-if.c'\" \(2963 characters\)
sed "s/^X//" >'md4-if.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: md4-if.c%v 0.90 1994/02/22 20:37:24 matt Exp $
X */
X
X/*
X * File: md4-if.c
X * Description: interface to md4


X */
X
X#include <mdigest.h>

X#include "md4.h"


X
X
X/* -------------------------------------------------------------------- */

X/* function : MD4_CREATE */
X/* description : individually setup a md4 context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XMD4_CREATE (ctx)
X md_ctx* ctx; /* context to setup */
X{
X if (ctx->priv == NULL)
X ((MD4_CTX*)ctx->priv) = (MD4_CTX*)mem_get (sizeof(MD4_CTX), MEMOPT_CLEAR);
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : MD4_DESTROY */
X/* description : shutdown a previously allocated context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XMD4_DESTROY (ctx)
X md_ctx* ctx; /* context to deallocate */
X{
X if (ctx->priv != NULL)
X mem_free (ctx->priv);
X
X ctx->priv = NULL;
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : MD4_REGISTER */
X/* description : register and setup md4 info structure */


X/* -------------------------------------------------------------------- */
XGLOBAL err_code

XMD4_REGISTER (m)
X md_info* m; /* info structure to fill out */
X{
X m->block_sz = 64;
X m->hash_sz = 16;
X
X m->create = MD4_CREATE;
X m->destroy = MD4_DESTROY;
X m->deregister = NULL;
X
X m->init = MD4Init;
X m->update = MD4Update;
X m->final = MD4Final;
X
X return (err_ok);


X}
X
X/* -------------------------------------------------------------------- */
X

END_OF_FILE
if test 2963 -ne `wc -c <'md4-if.c'`; then
echo shar: \"'md4-if.c'\" unpacked with wrong size!
fi
# end of 'md4-if.c'
fi
if test -f 'md4.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'md4.h'\"
else
echo shar: Extracting \"'md4.h'\" \(1885 characters\)
sed "s/^X//" >'md4.h' <<'END_OF_FILE'


X
X/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All

X rights reserved.


X
X License to copy and use this software is granted provided that it
X is identified as the "RSA Data Security, Inc. MD4 Message-Digest
X Algorithm" in all material mentioning or referencing this software
X or this function.
X
X License is also granted to make and use derivative works provided
X that such works are identified as "derived from the RSA Data
X Security, Inc. MD4 Message-Digest Algorithm" in all material
X mentioning or referencing the derived work.
X
X RSA Data Security, Inc. makes no representations concerning either
X the merchantability of this software or the suitability of this
X software for any particular purpose. It is provided "as is"
X without express or implied warranty of any kind.
X
X These notices must be retained in any copies of any part of this
X documentation and/or software.
X */
X

X#ifndef PROTOTYPES
X#define PROTOTYPES 0
X#endif
X
X/* POINTER defines a generic pointer type */
Xtypedef unsigned char *POINTER;
X
X/* UINT2 defines a two byte word */
Xtypedef unsigned short int UINT2;
X
X/* UINT4 defines a four byte word */
Xtypedef unsigned long int UINT4;
X
X/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
X If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
X returns an empty list.
X */
X
X#if PROTOTYPES
X#define PROTO_LIST(list) list
X#else
X#define PROTO_LIST(list) ()
X#endif
X
X/* MD4 context. */
Xtypedef struct {
X UINT4 state[4]; /* state (ABCD) */
X UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
X unsigned char buffer[64]; /* input buffer */
X} MD4_CTX;
X
Xvoid MD4Init PROTO_LIST ((MD4_CTX *));
Xvoid MD4Update PROTO_LIST ((MD4_CTX *, unsigned char *, unsigned int));
Xvoid MD4Final PROTO_LIST ((MD4_CTX*, unsigned char [16]));
X
END_OF_FILE
if test 1885 -ne `wc -c <'md4.h'`; then
echo shar: \"'md4.h'\" unpacked with wrong size!
fi
# end of 'md4.h'
fi
if test -f 'md5-if.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'md5-if.c'\"
else
echo shar: Extracting \"'md5-if.c'\" \(2964 characters\)
sed "s/^X//" >'md5-if.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: md5-if.c%v 0.90 1994/02/22 20:37:24 matt Exp $
X */
X
X/*
X * File: md5-if.c
X * Description: interface to md5


X */
X
X#include <mdigest.h>

X#include "md5.h"


X
X
X/* -------------------------------------------------------------------- */

X/* function : MD5_CREATE */
X/* description : individually setup a md5 context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XMD5_CREATE (ctx)
X md_ctx* ctx; /* context to setup */
X{
X if (ctx->priv == NULL)
X ((MD5_CTX*)ctx->priv) = (MD5_CTX*)mem_get (sizeof(MD5_CTX), MEMOPT_CLEAR);
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : MD5_DESTROY */
X/* description : shutdown a previously allocated context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XMD5_DESTROY (ctx)
X md_ctx* ctx; /* context to deallocate */
X{
X if (ctx->priv != NULL)
X mem_free (ctx->priv);
X
X ctx->priv = NULL;
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : MD5_REGISTER */
X/* description : register and setup md5 info structure */


X/* -------------------------------------------------------------------- */
XGLOBAL err_code

XMD5_REGISTER (m)
X md_info* m; /* info structure to fill out */
X{
X m->block_sz = 64;
X m->hash_sz = 16;
X
X m->create = MD5_CREATE;
X m->destroy = MD5_DESTROY;
X m->deregister = NULL;
X
X m->init = MD5Init;
X m->update = MD5Update;
X m->final = MD5Final;
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */
X

END_OF_FILE
if test 2964 -ne `wc -c <'md5-if.c'`; then
echo shar: \"'md5-if.c'\" unpacked with wrong size!
fi
# end of 'md5-if.c'
fi
if test -f 'md5.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'md5.h'\"
else
echo shar: Extracting \"'md5.h'\" \(1885 characters\)
sed "s/^X//" >'md5.h' <<'END_OF_FILE'
X
X/* derived from: MD5.H - header file for MD5C.C


X */
X
X/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
Xrights reserved.
X
XLicense to copy and use this software is granted provided that it
Xis identified as the "RSA Data Security, Inc. MD5 Message-Digest
XAlgorithm" in all material mentioning or referencing this software
Xor this function.
X
XLicense is also granted to make and use derivative works provided
Xthat such works are identified as "derived from the RSA Data
XSecurity, Inc. MD5 Message-Digest Algorithm" in all material
Xmentioning or referencing the derived work.
X
XRSA Data Security, Inc. makes no representations concerning either
Xthe merchantability of this software or the suitability of this
Xsoftware for any particular purpose. It is provided "as is"
Xwithout express or implied warranty of any kind.

XThese notices must be retained in any copies of any part of this
Xdocumentation and/or software.
X */
X

X#ifndef PROTOTYPES
X#define PROTOTYPES 0
X#endif
X
X/* POINTER defines a generic pointer type */
Xtypedef unsigned char *POINTER;
X
X/* UINT2 defines a two byte word */
Xtypedef unsigned short int UINT2;
X
X/* UINT4 defines a four byte word */
Xtypedef unsigned long int UINT4;
X
X/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
XIf using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
X returns an empty list.
X */
X#if PROTOTYPES
X#define PROTO_LIST(list) list
X#else
X#define PROTO_LIST(list) ()
X#endif
X
X/* MD5 context. */
Xtypedef struct {
X UINT4 state[4]; /* state (ABCD) */
X UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
X unsigned char buffer[64]; /* input buffer */
X} MD5_CTX;
X
Xvoid MD5Init PROTO_LIST ((MD5_CTX *));
Xvoid MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int));
Xvoid MD5Final PROTO_LIST ((MD5_CTX*, unsigned char [16]));
X
END_OF_FILE
if test 1885 -ne `wc -c <'md5.h'`; then
echo shar: \"'md5.h'\" unpacked with wrong size!
fi
# end of 'md5.h'
fi
if test -f 'mdigest.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'mdigest.h'\"
else
echo shar: Extracting \"'mdigest.h'\" \(8184 characters\)
sed "s/^X//" >'mdigest.h' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: mdigest.h%v 0.90 1994/02/22 20:37:24 matt Exp $
X */
X
X/*
X * File: mdigest.h
X * Description: Message digest header file
X */
X
X#ifndef _MDIGEST_H_
X#define _MDIGEST_H_
X
X/* -------------------------------------------------------------------- */
X/* header files */
X/* -------------------------------------------------------------------- */
X
X#include <stdio.h>
X#include <strings.h>
X#include <stdlib.h>
X#include <unistd.h>
X
X/* -------------------------------------------------------------------- */
X/* usual low level type castings */
X/* -------------------------------------------------------------------- */
X
Xtypedef unsigned char word8; /* defined as per bit size */
Xtypedef unsigned short word16;
Xtypedef unsigned long word32;
X
Xtypedef int word; /* ''generic'' integer */
X
Xtypedef unsigned char* opaque; /* arbitrary data segments */
Xtypedef char* string; /* character strings */
X
Xtypedef void (*handler)(); /* void function handler */
X
X/* -------------------------------------------------------------------- */
X/* nearly all functions return error codes as defined below */
X/* -------------------------------------------------------------------- */
X
Xtypedef enum
X {
X err_ok = 0, /* no error occured */
X err_no_memory = 1, /* memory allocation failed */
X err_invalid_params = 2, /* invalid parameters passed */
X err_file_not_found = 3, /* can't find a requested filename */
X err_cant_open_file = 4, /* can't open a requested filename */
X err_invalid_alg = 5, /* unknown algorithm from somewhere */
X err_already_exist = 6, /* something already exists */
X err_no_space = 7, /* internal table/etc is full */
X err_not_found = 8, /* something was not found */
X err_no_more = 9, /* no more is available */
X err_not_init = 10, /* not initialised */
X err_unknown = 255, /* unknown error */
X } err_code;
X
Xtypedef err_code (*function)(); /* general function handler */


X
X
X/* -------------------------------------------------------------------- */

X/* macros for general purpose use */
X/* -------------------------------------------------------------------- */
X
X#ifndef min
X# define min(a, b) ( ((a) <= (b)) ? (a) : (b) )
X# define max(a, b) ( ((a) >= (b)) ? (a) : (b) )
X#endif
X
X#ifndef TRUE
X# define TRUE (1)
X# define FALSE (0)
X#endif
X
X#define BIT_POS(x) (1L<<(x)) /* specific bit position */
X#define ident_sz (16) /* identifer sizes in the system */
X
X#define GLOBAL /* functions for rest of the world */
X#define STATIC static /* local to specific file */
X#define reg register /* quick defn for register vars */


X
X
X/* -------------------------------------------------------------------- */

X/* simple bitstring class and operators */
X/* -------------------------------------------------------------------- */
X
Xtypedef word32 bitstring;
X
X#define bit_max (sizeof(bitstring)<<3)
X#define bit_set(s, b) ((s) |= (1L<<(b))
X#define bit_clr(s, b) ((s) &= ~(1L<<(b))
X#define bit_zero(s) (s) = ((bitstring)0L)
X#define bit_inv(s) (s) ^= ((bitstring)0xffffffff)
X#define bit_chk(s, b) ((((s) &= ~(1L<<(b))) == 0) ? FALSE : TRUE)
X
X#define bit_pos(b) (1L<<(b))
X#define bit_empty (0L)


X
X
X/* -------------------------------------------------------------------- */

X/* debug facilities */
X/* -------------------------------------------------------------------- */
X
X#define DEBUG_FUNCTION_ENTER(f)


X
X
X/* -------------------------------------------------------------------- */

X/* memory.c requirements */
X/* -------------------------------------------------------------------- */
X
X#define MEMOPT_NONE bit_empty /* no options */
X#define MEMOPT_CLEAR bit_pos(0) /* clear segment before use */


X
X
X/* -------------------------------------------------------------------- */

X/* max number of registerable hash functions */
X/* -------------------------------------------------------------------- */
X
X#define md_max_reg (8)


X
X
X/* -------------------------------------------------------------------- */

X/* at registration, each algorithm provides function handlers and other */
X/* information */


X/* -------------------------------------------------------------------- */
X
Xtypedef struct
X {

X char ident[ident_sz+1]; /* id string */
X
X word block_sz; /* input block size in bytes */
X word hash_sz; /* output has size in bytes */
X
X function create; /* creation handler */
X function destroy; /* destruction */
X function deregister; /* deregistration */
X
X handler init; /* init for start of hash */
X handler update; /* update for hash */
X handler final; /* final and calc digest */
X
X } md_info;
X
X/* -------------------------------------------------------------------- */
X/* each association with the module uses its own context: */


X/* -------------------------------------------------------------------- */
X
Xtypedef struct
X {

X md_info *info; /* ptr to above info block */
X opaque priv; /* private structure */
X
X } md_ctx;
X
X
X#define md_create(c) (*((c)->info->create))(c) /* not for user */
X#define md_destroy(c) (*((c)->info->destroy))(c) /* not for user */
X
X#define md_init(c) (*((c)->info->init))((c)->priv) /* u */
X#define md_update(c,d,l) (*((c)->info->update))((c)->priv,d,l) /* u */
X#define md_final(c,o) (*((c)->info->final))((c)->priv,o) /* u */
X
X#define md_hash_sz(c) ((c)->info->hash_sz)
X#define md_block_sz(c) ((c)->info->block_sz)
X#define md_id(c) ((c)->info->ident)


X
X
X/* -------------------------------------------------------------------- */

X/* prototypes -- k'n'r */
X
Xopaque mem_get ();
Xvoid mem_free ();
Xstring sacs_err_msg ();
Xmd_info* md_lookup_id ();
Xerr_code md_register ();
Xerr_code md_deregister ();
Xerr_code md_mod_open ();
Xerr_code md_mod_close ();
Xerr_code md_open ();
Xerr_code md_close ();
Xerr_code md_list_init ();
Xerr_code md_list_next ();
X
X/* -------------------------------------------------------------------- */
X#endif /*_MDIGEST_H_*/
X
END_OF_FILE
if test 8184 -ne `wc -c <'mdigest.h'`; then
echo shar: \"'mdigest.h'\" unpacked with wrong size!
fi
# end of 'mdigest.h'
fi
if test -f 'shs-if.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'shs-if.c'\"
else
echo shar: Extracting \"'shs-if.c'\" \(3568 characters\)
sed "s/^X//" >'shs-if.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: shs-if.c%v 0.90 1994/02/22 20:37:24 matt Exp $
X */
X
X/*
X * File: shs-if.c
X * Description: interface to nist shs


X */
X
X#include <mdigest.h>

X#include "shs.h"


X
X
X/* -------------------------------------------------------------------- */

X/* function : SHS_FINAL */
X/* description : perform the final operation, so as to copy in digest */
X/* -------------------------------------------------------------------- */
XSTATIC void
XSHS_FINAL (shsInfo, digest)
X SHS_INFO* shsInfo; /* private shsinfo structure */
X opaque digest; /* where to place digest */
X{
X shsFinal (shsInfo);
X memcpy (digest, shsInfo->digest, SHS_DIGESTSIZE);


X}
X
X/* -------------------------------------------------------------------- */

X/* function : SHS_CREATE */
X/* description : individually setup a SHS context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XSHS_CREATE (ctx)
X md_ctx* ctx; /* context to setup */
X{
X if (ctx->priv == NULL)
X ((SHS_INFO*)ctx->priv) = (SHS_INFO*)mem_get (sizeof(SHS_INFO), MEMOPT_CLEAR);
X
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : SHS_DESTROY */
X/* description : shutdown a previously allocated context */
X/* -------------------------------------------------------------------- */
XSTATIC err_code
XSHS_DESTROY (ctx)
X md_ctx* ctx; /* context to deallocate */
X{
X if (ctx->priv != NULL)
X mem_free (ctx->priv);
X
X ctx->priv = NULL;
X return (err_ok);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : SHS_REGISTER */
X/* description : register and setup SHS info structure */


X/* -------------------------------------------------------------------- */
XGLOBAL err_code

XSHS_REGISTER (m)
X md_info* m; /* info structure to fill out */
X{
X m->block_sz = SHS_BLOCKSIZE;
X m->hash_sz = SHS_DIGESTSIZE;
X
X m->create = SHS_CREATE;
X m->destroy = SHS_DESTROY;
X m->deregister = NULL;
X
X m->init = shsInit;
X m->update = shsUpdate;
X m->final = SHS_FINAL;
X
X return (err_ok);


X}
X
X/* -------------------------------------------------------------------- */
X

END_OF_FILE
if test 3568 -ne `wc -c <'shs-if.c'`; then
echo shar: \"'shs-if.c'\" unpacked with wrong size!
fi
# end of 'shs-if.c'
fi
if test -f 'shs.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'shs.h'\"
else
echo shar: Extracting \"'shs.h'\" \(1619 characters\)
sed "s/^X//" >'shs.h' <<'END_OF_FILE'
X
X/* --------------------------------- SHS.H ------------------------------- */


X
X/* NIST proposed Secure Hash Standard.
X
X Written 2 September 1992, Peter C. Gutmann.
X This implementation placed in the public domain.
X
X Modified 1 June 1993, Colin Plumb.
X These modifications placed in the public domain.
X

X mgream: feb/94, changed from ANSI to KNR args/protos for compat.


X mgream: added runtime endian check
X
X Comments to pg...@cs.aukuni.ac.nz */
X

X/* Useful defines/typedefs */
X
Xtypedef unsigned char BYTE;
X
X/* Since 64-bit machines are the wave of the future, we may as well
X support them directly. */
X
X#ifdef FORCE32
X
X#undef HAVE64
X
X#else /* !FORCE32 */
X
X#if __alpha /* Or other machines? */
X#define HAVE64 1
Xtypedef unsigned long WORD64;
X#endif
X
X#if __GNUC__
X#define HAVE64 1
Xtypedef unsigned long long WORD64;
X#endif
X
X#endif /* !FORCE32 */
X
X#ifdef HAVE64
Xtypedef unsigned int WORD32;
X#else
Xtypedef unsigned long WORD32;
X#endif
X
X/* The SHS block size and message digest sizes, in bytes */
X
X#define SHS_BLOCKSIZE 64
X#define SHS_DIGESTSIZE 20
X
X/* The structure for storing SHS info
X data[] is placed first in case offsets of 0 are faster
X for some reason; it's the most often accessed field. */
X
Xtypedef struct {
X WORD32 data[ 16 ]; /* SHS data buffer */
X WORD32 digest[ 5 ]; /* Message digest */
X#ifdef HAVE64
X WORD64 count;
X#else
X WORD32 countHi, countLo; /* 64-bit bit count */
X#endif
X} SHS_INFO;
X
X/* Whether the machine is little-endian or not */
X
X/*#define LITTLE_ENDIAN -- obselete (mgream) */
X
X/* shs.c */
Xvoid shsInit();
Xvoid shsTransform();
Xvoid shsUpdate();
Xvoid shsFinal();
X
END_OF_FILE
if test 1619 -ne `wc -c <'shs.h'`; then
echo shar: \"'shs.h'\" unpacked with wrong size!
fi
# end of 'shs.h'
fi
if test -f 'utility.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'utility.c'\"
else
echo shar: Extracting \"'utility.c'\" \(3574 characters\)
sed "s/^X//" >'utility.c' <<'END_OF_FILE'


X
X/* -------------------------------------------------------------------- */
X/* */
X/* Secure Asyncronous Communications Subsystem (SACS) */
X/* (C) 1994 Matthew Gream <M.G...@uts.edu.au> */
X/* */
X/* You have been given a limited license to use and distribute this */
X/* library. You should have received this license with the original */
X/* release package of this library, named "license.txt" and entitled */
X/* "SACS SOFTWARE LICENSE". In the event that you have not read or */
X/* understood this license, regardless of reason, you may do nothing */
X/* with this library other than read it for self-awareness. */
X/* */
X/* -------------------------------------------------------------------- */
X

X/* $Id: memory.c%v 0.81 1994/02/12 10:08:43 matt Exp $
X */
X
X/*
X * File: utility.c
X * Description: misc utility stuff


X */
X
X#include <mdigest.h>

X
X
X/* -------------------------------------------------------------------- */

X/* function : mem_get */
X/* description : allocate and return 'req_size' bytes of memory, clear */
X/* if MEMOPT_CLEAR flag is present. Failures are hard. */
X/* -------------------------------------------------------------------- */
XGLOBAL opaque
Xmem_get (req_size, req_options)
X word req_size; /* size of memory requested */
X bitstring req_options; /* options for allocated mem */
X{
X opaque seg_addr;
X
X DEBUG_FUNCTION_ENTER("mem_get");


X
X /* ---------------------------------------------------------------- */

X /* code should never request zero size segments -- deal with it by */
X /* returning NULL pointer. */


X /* ---------------------------------------------------------------- */
X

X if (req_size == 0)
X return ((opaque)NULL);


X
X /* ---------------------------------------------------------------- */

X /* if allocation request fails, call error handler and indicate a */
X /* fatal error with appropriate error code */


X /* ---------------------------------------------------------------- */
X

X seg_addr = (opaque)malloc (req_size);
X if (seg_addr == NULL)
X {
X /*sacs_hard_error (err_no_memory);*/
X fprintf (stderr, "malloc failed.\n");
X exit (1);
X /* not reached */
X }


X
X /* ---------------------------------------------------------------- */

X /* clear segment if we were specifically asked to do so */


X /* ---------------------------------------------------------------- */
X

X if (bit_chk (req_options, MEMOPT_CLEAR) == TRUE)
X memset (seg_addr, '\0', req_size);
X
X return (seg_addr);


X}
X
X
X/* -------------------------------------------------------------------- */

X/* function : mem_free */
X/* description : release memory segment previously allocated */
X/* -------------------------------------------------------------------- */
XGLOBAL void
Xmem_free (seg_addr)
X opaque seg_addr; /* address of mem segment */
X{
X DEBUG_FUNCTION_ENTER("mem_free");
X
X if (seg_addr != NULL)
X free (seg_addr);


X}
X
X/* -------------------------------------------------------------------- */
X

END_OF_FILE
if test 3574 -ne `wc -c <'utility.c'`; then
echo shar: \"'utility.c'\" unpacked with wrong size!
fi
# end of 'utility.c'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone

Reply all
Reply to author
Forward
0 new messages