changeset 297:79bf1023cf11 agent-client

propagate from branch 'au.asn.ucc.matt.dropbear' (head 0501e6f661b5415eb76f3b312d183c3adfbfb712) to branch 'au.asn.ucc.matt.dropbear.cli-agent' (head 01038174ec27245b51bd43a66c01ad930880f67b)
author Matt Johnston <matt@ucc.asn.au>
date Tue, 21 Mar 2006 16:20:59 +0000
parents ca7e76d981d9 (current diff) 03f65e461915 (diff)
children 08b69964e408
files auth.h cli-runopts.c cli-session.c dbutil.c dbutil.h options.h random.c runopts.h ssh.h
diffstat 541 files changed, 93491 insertions(+), 613 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES	Mon Jul 18 14:32:52 2005 +0000
+++ b/CHANGES	Tue Mar 21 16:20:59 2006 +0000
@@ -1,3 +1,66 @@
+0.48.1 - Sat 11 March 2006
+
+- Compile fix for scp
+
+0.48 - Thurs 9 March 2006
+
+- Check that the circular buffer is properly empty before
+  closing a channel, which could cause truncated transfers
+  (thanks to Tomas Vanek for helping track it down)
+
+- Implement per-IP pre-authentication connection limits 
+  (after some poking from Pablo Fernandez)
+
+- Exit gracefully if trying to connect to as SSH v1 server 
+  (reported by Rushi Lala)
+
+- Only read /dev/random once at startup when in non-inetd mode
+
+- Allow ctrl-c to close a dbclient password prompt (may
+  still have to press enter on some platforms)
+
+- Merged in uClinux patch for inetd mode
+
+- Updated to scp from OpenSSH 4.3p2 - fixes a security issue
+  where use of system() could cause users to execute arbitrary
+  code through malformed filenames, ref CVE-2006-0225
+
+0.47 - Thurs Dec 8 2005
+
+- SECURITY: fix for buffer allocation error in server code, could potentially
+  allow authenticated users to gain elevated privileges. All multi-user systems
+  running the server should upgrade (or apply the patch available on the
+  Dropbear webpage).
+
+- Fix channel handling code so that redirecting to /dev/null doesn't use
+  100% CPU.
+
+- Turn on zlib compression for dbclient.
+
+- Set "low delay" TOS bit, can significantly improve interactivity
+  over some links.
+
+- Added client keyboard-interactive mode support, allows operation with
+  newer OpenSSH servers in default config.
+
+- Log when pubkey auth fails because of bad ~/.ssh/authorized_keys permissions
+
+- Improve logging of assertions
+
+- Added aes-256 cipher and sha1-96 hmac.
+
+- Fix twofish so that it actually works.
+
+- Improve PAM prompt comparison.
+
+- Added -g (dbclient) and -a (dropbear server) options to allow
+  connections to listening forwarded ports from remote machines.
+
+- Various other minor fixes
+
+- Compile fixes for glibc 2.1 (ss_family vs __ss_family) and NetBSD
+  (netinet/in_systm.h needs to be included).
+
 0.46 - Sat July 9 2005
 
 - Fix long-standing bug which caused connections to be closed if an ssh-agent
--- a/INSTALL	Mon Jul 18 14:32:52 2005 +0000
+++ b/INSTALL	Tue Mar 21 16:20:59 2006 +0000
@@ -28,6 +28,11 @@
 
 ============================================================================
 
+If you're compiling for a 386-class CPU, you will probably need to add
+CFLAGS=-DLTC_NO_BSWAP so that libtomcrypt doesn't use 486+ instructions.
+
+============================================================================
+
 Compiling with uClibc:
 
 Firstly, make sure you have at least uclibc 0.9.17, as getusershell() in prior
--- a/Makefile.in	Mon Jul 18 14:32:52 2005 +0000
+++ b/Makefile.in	Tue Mar 21 16:20:59 2006 +0000
@@ -29,7 +29,7 @@
 
 CLIOBJS=cli-algo.o cli-main.o cli-auth.o cli-authpasswd.o cli-kex.o \
 		cli-session.o cli-service.o cli-runopts.o cli-chansession.o \
-		cli-authpubkey.o cli-tcpfwd.o cli-channel.o
+		cli-authpubkey.o cli-tcpfwd.o cli-channel.o cli-authinteract.o
 
 CLISVROBJS=common-session.o packet.o common-algo.o common-kex.o \
 			common-channel.o common-chansession.o termcodes.o loginrec.o \
--- a/README	Mon Jul 18 14:32:52 2005 +0000
+++ b/README	Tue Mar 21 16:20:59 2006 +0000
@@ -25,7 +25,7 @@
 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAwVa6M6cGVmUcLl2cFzkxEoJd06Ub4bVDsYrWvXhvUV+ZAM9uGuewZBDoAqNKJxoIn0Hyd0Nk/yU99UVv6NWV/5YSHtnf35LKds56j7cuzoQpFIdjNwdxAN0PCET/MG8qyskG/2IE2DPNIaJ3Wy+Ws4IZEgdJgPlTYUBWWtCWOGc= [email protected]
 
 You must make sure that ~/.ssh, and the key file, are only writable by the
-user.
+user. Beware of editors that split the key into multiple lines.
 
 NOTE: Dropbear ignores authorized_keys options such as those described in the
 OpenSSH sshd manpage, and will not allow a login for these keys. 
--- a/TODO	Mon Jul 18 14:32:52 2005 +0000
+++ b/TODO	Tue Mar 21 16:20:59 2006 +0000
@@ -6,8 +6,6 @@
 
 - Make options.h generated from configure perhaps?
 
-- Improved queueing of unauthed connections
-
 - handle /etc/environment in AIX
 
 - check that there aren't timing issues with valid/invalid user authentication
@@ -15,7 +13,6 @@
 
 - Binding to different interfaces
 
-- check PRNG
 - CTR mode
 - SSH_MSG_IGNORE sending to improve CBC security
 - DH Group Exchange possibly, or just add group14 (whatever it's called today)
--- a/auth.h	Mon Jul 18 14:32:52 2005 +0000
+++ b/auth.h	Tue Mar 21 16:20:59 2006 +0000
@@ -41,28 +41,37 @@
 /* Client functions */
 void recv_msg_userauth_failure();
 void recv_msg_userauth_success();
+void recv_msg_userauth_specific_60();
 void recv_msg_userauth_pk_ok();
+void recv_msg_userauth_info_request();
 void cli_get_user();
 void cli_auth_getmethods();
 void cli_auth_try();
 void recv_msg_userauth_banner();
 void cli_pubkeyfail();
-int cli_auth_password();
+void cli_auth_password();
 int cli_auth_pubkey();
+void cli_auth_interactive();
+char* getpass_or_cancel();
 
 
 #define MAX_USERNAME_LEN 25 /* arbitrary for the moment */
 
-#define AUTH_TYPE_PUBKEY	1 << 0
-#define AUTH_TYPE_PASSWORD	1 << 1
+#define AUTH_TYPE_NONE      1
+#define AUTH_TYPE_PUBKEY    1 << 1
+#define AUTH_TYPE_PASSWORD  1 << 2
+#define AUTH_TYPE_INTERACT  1 << 3
 
-/* auth types, "none" means we should return list of acceptable types */
-#define AUTH_METHOD_NONE	"none"
+#define AUTH_METHOD_NONE "none"
 #define AUTH_METHOD_NONE_LEN 4
 #define AUTH_METHOD_PUBKEY "publickey"
 #define AUTH_METHOD_PUBKEY_LEN 9
 #define AUTH_METHOD_PASSWORD "password"
 #define AUTH_METHOD_PASSWORD_LEN 8
+#define AUTH_METHOD_INTERACT "keyboard-interactive"
+#define AUTH_METHOD_INTERACT_LEN 20
+
+
 
 /* This structure is shared between server and client - it contains
  * relatively little extraneous bits when used for the client rather than the
@@ -77,6 +86,9 @@
 	unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have. Applies for
 							  client and server (though has differing [obvious]
 							  meanings). */
+	unsigned perm_warn : 1; /* Server only, set if bad permissions on 
+							   ~/.ssh/authorized_keys have already been
+							   logged. */
 
 	/* These are only used for the server */
 	char *printableuser; /* stripped of control chars, used for logs etc */
--- a/buffer.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/buffer.c	Tue Mar 21 16:20:59 2006 +0000
@@ -153,7 +153,7 @@
 unsigned char buf_getbyte(buffer* buf) {
 
 	/* This check is really just ==, but the >= allows us to check for the
-	 * assert()able case of pos > len, which should _never_ happen. */
+	 * bad case of pos > len, which should _never_ happen. */
 	if (buf->pos >= buf->len) {
 		dropbear_exit("bad buf_getbyte");
 	}
@@ -270,7 +270,7 @@
 	unsigned int len, pad = 0;
 	TRACE(("enter buf_putmpint"))
 
-	assert(mp != NULL);
+	dropbear_assert(mp != NULL);
 
 	if (SIGN(mp) == MP_NEG) {
 		dropbear_exit("negative bignum");
--- a/channel.h	Mon Jul 18 14:32:52 2005 +0000
+++ b/channel.h	Tue Mar 21 16:20:59 2006 +0000
@@ -65,9 +65,9 @@
 	unsigned int recvdonelen;
 	unsigned int recvmaxpacket, transmaxpacket;
 	void* typedata; /* a pointer to type specific data */
-	int infd; /* data to send over the wire */
-	int outfd; /* data for consumption, what was in writebuf */
-	int errfd; /* used like infd or errfd, depending if it's client or server.
+	int writefd; /* read from wire, written to insecure side */
+	int readfd; /* read from insecure size, written to wire */
+	int errfd; /* used like writefd or readfd, depending if it's client or server.
 				  Doesn't exactly belong here, but is cleaner here */
 	circbuffer *writebuf; /* data from the wire, for local consumption */
 	circbuffer *extrabuf; /* extended-data for the program - used like writebuf
@@ -81,6 +81,10 @@
 	int initconn; /* used for TCP forwarding, whether the channel has been
 					 fully initialised */
 
+	int await_open; /* flag indicating whether we've sent an open request
+					   for this channel (and are awaiting a confirmation
+					   or failure). */
+
 	const struct ChanType* type;
 
 };
@@ -96,7 +100,7 @@
 
 };
 
-void chaninitialise();
+void chaninitialise(const struct ChanType *chantypes[]);
 void chancleanup();
 void setchannelfds(fd_set *readfd, fd_set *writefd);
 void channelio(fd_set *readfd, fd_set *writefd);
@@ -119,7 +123,7 @@
 		circbuffer * buf);
 
 #ifdef DROPBEAR_CLIENT
-const struct ChanType clichansess;
+extern const struct ChanType clichansess;
 #endif
 
 #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT)
--- a/circbuffer.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/circbuffer.c	Tue Mar 21 16:20:59 2006 +0000
@@ -66,8 +66,8 @@
 
 unsigned int cbuf_readlen(circbuffer *cbuf) {
 
-	assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size);
-	assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size);
+	dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size);
+	dropbear_assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size);
 
 	if (cbuf->used == 0) {
 		TRACE(("cbuf_readlen: unused buffer"))
@@ -83,9 +83,9 @@
 
 unsigned int cbuf_writelen(circbuffer *cbuf) {
 
-	assert(cbuf->used <= cbuf->size);
-	assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size);
-	assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size);
+	dropbear_assert(cbuf->used <= cbuf->size);
+	dropbear_assert(((2*cbuf->size)+cbuf->writepos-cbuf->readpos)%cbuf->size == cbuf->used%cbuf->size);
+	dropbear_assert(((2*cbuf->size)+cbuf->readpos-cbuf->writepos)%cbuf->size == (cbuf->size-cbuf->used)%cbuf->size);
 
 	if (cbuf->used == cbuf->size) {
 		TRACE(("cbuf_writelen: full buffer"))
@@ -122,7 +122,7 @@
 	}
 
 	cbuf->used += len;
-	assert(cbuf->used <= cbuf->size);
+	dropbear_assert(cbuf->used <= cbuf->size);
 	cbuf->writepos = (cbuf->writepos + len) % cbuf->size;
 }
 
@@ -132,7 +132,7 @@
 		dropbear_exit("bad cbuf read");
 	}
 
-	assert(cbuf->used >= len);
+	dropbear_assert(cbuf->used >= len);
 	cbuf->used -= len;
 	cbuf->readpos = (cbuf->readpos + len) % cbuf->size;
 }
--- a/cli-auth.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/cli-auth.c	Tue Mar 21 16:20:59 2006 +0000
@@ -32,7 +32,6 @@
 #include "packet.h"
 #include "runopts.h"
 
-
 void cli_authinitialise() {
 
 	memset(&ses.authstate, 0, sizeof(ses.authstate));
@@ -99,6 +98,40 @@
 	TRACE(("leave recv_msg_userauth_banner"))
 }
 
+/* This handles the message-specific types which
+ * all have a value of 60. These are
+ * SSH_MSG_USERAUTH_PASSWD_CHANGEREQ,
+ * SSH_MSG_USERAUTH_PK_OK, &
+ * SSH_MSG_USERAUTH_INFO_REQUEST. */
+void recv_msg_userauth_specific_60() {
+
+#ifdef ENABLE_CLI_PUBKEY_AUTH
+	if (cli_ses.lastauthtype == AUTH_TYPE_PUBKEY) {
+		recv_msg_userauth_pk_ok();
+		return;
+	}
+#endif
+
+#ifdef ENABLE_CLI_INTERACT_AUTH
+	if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT) {
+		recv_msg_userauth_info_request();
+		return;
+	}
+#endif
+
+#ifdef ENABLE_CLI_PASSWORD_AUTH
+	if (cli_ses.lastauthtype == AUTH_TYPE_PASSWORD) {
+		/* Eventually there could be proper password-changing
+		 * support. However currently few servers seem to
+		 * implement it, and password auth is last-resort
+		 * regardless - keyboard-interactive is more likely
+		 * to be used anyway. */
+		dropbear_close("Your password has expired.");
+	}
+#endif
+
+	dropbear_exit("Unexpected userauth packet");
+}
 
 void recv_msg_userauth_failure() {
 
@@ -113,8 +146,7 @@
 
 	if (cli_ses.state != USERAUTH_REQ_SENT) {
 		/* Perhaps we should be more fatal? */
-		TRACE(("But we didn't send a userauth request!!!!!!"))
-		return;
+		dropbear_exit("Unexpected userauth failure");
 	}
 
 #ifdef ENABLE_CLI_PUBKEY_AUTH
@@ -125,6 +157,19 @@
 	}
 #endif
 
+#ifdef ENABLE_CLI_INTERACT_AUTH
+	/* If we get a failure message for keyboard interactive without
+	 * receiving any request info packet, then we don't bother trying
+	 * keyboard interactive again */
+	if (cli_ses.lastauthtype == AUTH_TYPE_INTERACT
+			&& !cli_ses.interact_request_received) {
+		TRACE(("setting auth_interact_failed = 1"))
+		cli_ses.auth_interact_failed = 1;
+	}
+#endif
+
+	cli_ses.lastauthtype = AUTH_TYPE_NONE;
+
 	methods = buf_getstring(ses.payload, &methlen);
 
 	partial = buf_getbool(ses.payload);
@@ -157,6 +202,12 @@
 				ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
 			}
 #endif
+#ifdef ENABLE_CLI_INTERACT_AUTH
+			if (strncmp(AUTH_METHOD_INTERACT, tok,
+				AUTH_METHOD_INTERACT_LEN) == 0) {
+				ses.authstate.authtypes |= AUTH_TYPE_INTERACT;
+			}
+#endif
 #ifdef ENABLE_CLI_PASSWORD_AUTH
 			if (strncmp(AUTH_METHOD_PASSWORD, tok,
 				AUTH_METHOD_PASSWORD_LEN) == 0) {
@@ -180,6 +231,7 @@
 	TRACE(("received msg_userauth_success"))
 	ses.authstate.authdone = 1;
 	cli_ses.state = USERAUTH_SUCCESS_RCVD;
+	cli_ses.lastauthtype = AUTH_TYPE_NONE;
 }
 
 void cli_auth_try() {
@@ -189,7 +241,8 @@
 
 	CHECKCLEARTOWRITE();
 	
-	/* XXX We hardcode that we try a pubkey first */
+	/* Order to try is pubkey, interactive, password.
+	 * As soon as "finished" is set for one, we don't do any more. */
 #ifdef ENABLE_CLI_PUBKEY_AUTH
 	if (ses.authstate.authtypes & AUTH_TYPE_PUBKEY) {
 		finished = cli_auth_pubkey();
@@ -197,16 +250,46 @@
 	}
 #endif
 
+#ifdef ENABLE_CLI_INTERACT_AUTH
+	if (!finished && ses.authstate.authtypes & AUTH_TYPE_INTERACT) {
+		if (cli_ses.auth_interact_failed) {
+			finished = 0;
+		} else {
+			cli_auth_interactive();
+			cli_ses.lastauthtype = AUTH_TYPE_INTERACT;
+			finished = 1;
+		}
+	}
+#endif
+
 #ifdef ENABLE_CLI_PASSWORD_AUTH
 	if (!finished && ses.authstate.authtypes & AUTH_TYPE_PASSWORD) {
-		finished = cli_auth_password();
+		cli_auth_password();
+		finished = 1;
 		cli_ses.lastauthtype = AUTH_TYPE_PASSWORD;
 	}
 #endif
 
+	TRACE(("cli_auth_try lastauthtype %d", cli_ses.lastauthtype))
+
 	if (!finished) {
 		dropbear_exit("No auth methods could be used.");
 	}
 
 	TRACE(("leave cli_auth_try"))
 }
+
+/* A helper for getpass() that exits if the user cancels. The returned
+ * password is statically allocated by getpass() */
+char* getpass_or_cancel()
+{
+	char* password = NULL;
+
+	password = getpass("Password: ");
+
+	/* 0x03 is a ctrl-c character in the buffer. */
+	if (password == NULL || strchr(password, '\3') != NULL) {
+		dropbear_close("Interrupted.");
+	}
+	return password;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cli-authinteract.c	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,168 @@
+/*
+ * Dropbear SSH
+ * 
+ * Copyright (c) 2005 Matt Johnston
+ * All rights reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
+#include "includes.h"
+#include "buffer.h"
+#include "dbutil.h"
+#include "session.h"
+#include "ssh.h"
+#include "runopts.h"
+
+#ifdef ENABLE_CLI_INTERACT_AUTH
+
+static unsigned char* get_response(unsigned char* prompt)
+{
+	FILE* tty = NULL;
+	unsigned char* response = NULL;
+	/* not a password, but a reasonable limit */
+	char buf[DROPBEAR_MAX_CLI_PASS];
+	char* ret = NULL;
+
+	fprintf(stderr, "%s", prompt);
+
+	tty = fopen(_PATH_TTY, "r");
+	if (tty) {
+		ret = fgets(buf, sizeof(buf), tty);
+		fclose(tty);
+	} else {
+		ret = fgets(buf, sizeof(buf), stdin);
+	}
+
+	if (ret == NULL) {
+		response = (unsigned char*)m_strdup("");
+	} else {
+		unsigned int buflen = strlen(buf);
+		/* fgets includes newlines */
+		if (buflen > 0 && buf[buflen-1] == '\n')
+			buf[buflen-1] = '\0';
+		response = (unsigned char*)m_strdup(buf);
+	}
+
+	m_burn(buf, sizeof(buf));
+
+	return response;
+}
+
+void recv_msg_userauth_info_request() {
+
+	unsigned char *name = NULL;
+	unsigned char *instruction = NULL;
+	unsigned int num_prompts = 0;
+	unsigned int i;
+
+	unsigned char *prompt = NULL;
+	unsigned int echo = 0;
+	unsigned char *response = NULL;
+
+	TRACE(("enter recv_msg_recv_userauth_info_request"))
+
+	cli_ses.interact_request_received = 1;
+
+	name = buf_getstring(ses.payload, NULL);
+	instruction = buf_getstring(ses.payload, NULL);
+
+	/* language tag */
+	buf_eatstring(ses.payload);
+
+	num_prompts = buf_getint(ses.payload);
+	
+	if (num_prompts >= DROPBEAR_MAX_CLI_INTERACT_PROMPTS) {
+		dropbear_exit("Too many prompts received for keyboard-interactive");
+	}
+
+	/* we'll build the response as we go */
+	CHECKCLEARTOWRITE();
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_INFO_RESPONSE);
+	buf_putint(ses.writepayload, num_prompts);
+
+	if (strlen(name) > 0) {
+		cleantext(name);
+		fprintf(stderr, "%s", name);
+		m_free(name);
+	}
+	if (strlen(instruction) > 0) {
+		cleantext(instruction);
+		fprintf(stderr, "%s", instruction);
+		m_free(instruction);
+	}
+
+	for (i = 0; i < num_prompts; i++) {
+		unsigned int response_len = 0;
+		prompt = buf_getstring(ses.payload, NULL);
+		cleantext(prompt);
+
+		echo = buf_getbool(ses.payload);
+
+		if (!echo) {
+			unsigned char* p = getpass_or_cancel(prompt);
+			response = m_strdup(p);
+			m_burn(p, strlen(p));
+		} else {
+			response = get_response(prompt);
+		}
+
+		response_len = strlen(response);
+		buf_putstring(ses.writepayload, response, response_len);
+		m_burn(response, response_len);
+		m_free(response);
+	}
+
+	encrypt_packet();
+
+
+	TRACE(("leave recv_msg_recv_userauth_info_request"))
+}
+
+void cli_auth_interactive() {
+
+	TRACE(("enter cli_auth_interactive"))
+	CHECKCLEARTOWRITE();
+
+	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
+
+	/* username */
+	buf_putstring(ses.writepayload, cli_opts.username,
+			strlen(cli_opts.username));
+
+	/* service name */
+	buf_putstring(ses.writepayload, SSH_SERVICE_CONNECTION, 
+			SSH_SERVICE_CONNECTION_LEN);
+
+	/* method */
+	buf_putstring(ses.writepayload, AUTH_METHOD_INTERACT,
+			AUTH_METHOD_INTERACT_LEN);
+
+	/* empty language tag */
+	buf_putstring(ses.writepayload, "", 0);
+
+	/* empty submethods */
+	buf_putstring(ses.writepayload, "", 0);
+
+	encrypt_packet();
+	cli_ses.interact_request_received = 0;
+
+	TRACE(("leave cli_auth_interactive"))
+
+}
+#endif	/* ENABLE_CLI_INTERACT_AUTH */
--- a/cli-authpasswd.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/cli-authpasswd.c	Tue Mar 21 16:20:59 2006 +0000
@@ -113,7 +113,7 @@
 }
 #endif /* ENABLE_CLI_ASKPASS_HELPER */
 
-int cli_auth_password() {
+void cli_auth_password() {
 
 	char* password = NULL;
 
@@ -125,10 +125,7 @@
 		password = gui_getpass("Password: ");
 	else
 #endif
-		password = getpass("Password: ");
-
-	if (password == NULL)
-		return 0;
+		password = getpass_or_cancel("Password: ");
 
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
 
@@ -149,7 +146,5 @@
 	m_burn(password, strlen(password));
 
 	TRACE(("leave cli_auth_password"))
-	return 1; /* Password auth can always be tried */
-
 }
 #endif	/* ENABLE_CLI_PASSWORD_AUTH */
--- a/cli-chansession.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/cli-chansession.c	Tue Mar 21 16:20:59 2006 +0000
@@ -340,10 +340,10 @@
 static int cli_initchansess(struct Channel *channel) {
 
 
-	channel->infd = STDOUT_FILENO;
+	channel->writefd = STDOUT_FILENO;
 	setnonblocking(STDOUT_FILENO);
 
-	channel->outfd = STDIN_FILENO;
+	channel->readfd = STDIN_FILENO;
 	setnonblocking(STDIN_FILENO);
 
 	channel->errfd = STDERR_FILENO;
--- a/cli-runopts.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/cli-runopts.c	Tue Mar 21 16:20:59 2006 +0000
@@ -47,6 +47,7 @@
 					"Usage: %s [options] [[email protected]]host\n"
 					"Options are:\n"
 					"-p <remoteport>\n"
+					"-l <username>\n"
 					"-t    Allocate a pty\n"
 					"-T    Don't allocate a pty\n"
 #ifdef ENABLE_CLI_PUBKEY_AUTH
@@ -57,11 +58,11 @@
 #endif
 #ifdef ENABLE_CLI_LOCALTCPFWD
 					"-L <listenport:remotehost:remoteport> Local port forwarding\n"
+					"-g    Allow remote hosts to connect to forwarded ports\n"
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
 					"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
 #endif
-					"-l <username>\n"
 #ifdef DEBUG_TRACE
 					"-v    verbose\n"
 #endif
@@ -96,6 +97,7 @@
 #endif
 #ifdef ENABLE_CLI_LOCALTCPFWD
 	cli_opts.localfwds = NULL;
+	opts.listen_fwd_all = 0;
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
 	cli_opts.remotefwds = NULL;
@@ -104,8 +106,6 @@
 	cli_opts.agent_fwd = 0;
 	cli_opts.agent_keys_loaded = 0;
 #endif
-	opts.nolocaltcp = 0;
-	opts.noremotetcp = 0;
 	/* not yet
 	opts.ipv4 = 1;
 	opts.ipv6 = 1;
@@ -174,6 +174,9 @@
 				case 'L':
 					nextislocal = 1;
 					break;
+				case 'g':
+					opts.listen_fwd_all = 1;
+					break;
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
 				case 'R':
--- a/cli-session.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/cli-session.c	Tue Mar 21 16:20:59 2006 +0000
@@ -63,9 +63,7 @@
 	{SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
 	{SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
 	{SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, /* client */
-#ifdef ENABLE_CLI_PUBKEY_AUTH
-	{SSH_MSG_USERAUTH_PK_OK, recv_msg_userauth_pk_ok}, /* client */
-#endif
+	{SSH_MSG_USERAUTH_SPECIFIC_60, recv_msg_userauth_specific_60}, /* client */
 	{0, 0} /* End */
 };
 
@@ -81,12 +79,14 @@
 
 void cli_session(int sock, char* remotehost) {
 
+	seedrandom();
+
 	crypto_init();
+
 	common_session_init(sock, remotehost);
 
 	chaninitialise(cli_chantypes);
 
-
 	/* Set up cli_ses vars */
 	cli_session_init();
 
@@ -96,12 +96,8 @@
 	/* Exchange identification */
 	session_identification();
 
-	seedrandom();
-
 	send_msg_kexinit();
 
-	/* XXX here we do stuff differently */
-
 	session_loop(cli_sessionloop);
 
 	/* Not reached */
@@ -288,7 +284,8 @@
 }
 
 /* Operates in-place turning dirty (untrusted potentially containing control
- * characters) text into clean text. */
+ * characters) text into clean text. 
+ * Note: this is safe only with ascii - other charsets could have problems. */
 void cleantext(unsigned char* dirtytext) {
 
 	unsigned int i, j;
--- a/cli-tcpfwd.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/cli-tcpfwd.c	Tue Mar 21 16:20:59 2006 +0000
@@ -95,10 +95,19 @@
 				remoteport));
 
 	tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
+
 	tcpinfo->sendaddr = m_strdup(remoteaddr);
 	tcpinfo->sendport = remoteport;
+
+	if (opts.listen_fwd_all) {
+		tcpinfo->listenaddr = m_strdup("");
+	} else {
+		tcpinfo->listenaddr = m_strdup("localhost");
+	}
 	tcpinfo->listenport = listenport;
+
 	tcpinfo->chantype = &cli_chan_tcplocal;
+	tcpinfo->tcp_type = direct;
 
 	ret = listen_tcpfwd(tcpinfo);
 
@@ -113,13 +122,20 @@
 #ifdef  ENABLE_CLI_REMOTETCPFWD
 static void send_msg_global_request_remotetcp(int port) {
 
+	char* listenspec = NULL;
 	TRACE(("enter send_msg_global_request_remotetcp"))
 
 	CHECKCLEARTOWRITE();
 	buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
 	buf_putstring(ses.writepayload, "tcpip-forward", 13);
 	buf_putbyte(ses.writepayload, 0);
-	buf_putstring(ses.writepayload, "0.0.0.0", 7); /* TODO: IPv6? */
+	if (opts.listen_fwd_all) {
+		listenspec = "";
+	} else {
+		listenspec = "localhost";
+	}
+	/* TODO: IPv6? */;
+	buf_putstring(ses.writepayload, listenspec, strlen(listenspec));
 	buf_putint(ses.writepayload, port);
 
 	encrypt_packet();
@@ -186,11 +202,9 @@
 
 	ses.maxfd = MAX(ses.maxfd, sock);
 
-	/* Note that infd is actually the "outgoing" direction on the
-	 * tcp connection, vice versa for outfd.
-	 * We don't set outfd, that will get set after the connection's
+	/* We don't set readfd, that will get set after the connection's
 	 * progress succeeds */
-	channel->infd = sock;
+	channel->writefd = sock;
 	channel->initconn = 1;
 	
 	err = SSH_OPEN_IN_PROGRESS;
--- a/common-algo.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/common-algo.c	Tue Mar 21 16:20:59 2006 +0000
@@ -32,20 +32,28 @@
 /* Mappings for ciphers, parameters are
    {&cipher_desc, keysize, blocksize} */
 
+#ifdef DROPBEAR_AES256_CBC
+static const struct dropbear_cipher dropbear_aes256 = 
+	{&aes_desc, 32, 16};
+#endif
 #ifdef DROPBEAR_AES128_CBC
-const struct dropbear_cipher dropbear_aes128 = 
+static const struct dropbear_cipher dropbear_aes128 = 
 	{&aes_desc, 16, 16};
 #endif
 #ifdef DROPBEAR_BLOWFISH_CBC
-const struct dropbear_cipher dropbear_blowfish = 
+static const struct dropbear_cipher dropbear_blowfish = 
 	{&blowfish_desc, 16, 8};
 #endif
+#ifdef DROPBEAR_TWOFISH256_CBC
+static const struct dropbear_cipher dropbear_twofish256 = 
+	{&twofish_desc, 32, 16};
+#endif
 #ifdef DROPBEAR_TWOFISH128_CBC
-const struct dropbear_cipher dropbear_twofish128 = 
+static const struct dropbear_cipher dropbear_twofish128 = 
 	{&twofish_desc, 16, 16};
 #endif
 #ifdef DROPBEAR_3DES_CBC
-const struct dropbear_cipher dropbear_3des = 
+static const struct dropbear_cipher dropbear_3des = 
 	{&des3_desc, 24, 8};
 #endif
 
@@ -57,11 +65,15 @@
    {&hash_desc, keysize, hashsize} */
 
 #ifdef DROPBEAR_SHA1_HMAC
-const struct dropbear_hash dropbear_sha1 = 
+static const struct dropbear_hash dropbear_sha1 = 
 	{&sha1_desc, 20, 20};
 #endif
+#ifdef DROPBEAR_SHA1_96_HMAC
+static const struct dropbear_hash dropbear_sha1_96 = 
+	{&sha1_desc, 20, 12};
+#endif
 #ifdef DROPBEAR_MD5_HMAC
-const struct dropbear_hash dropbear_md5 = 
+static const struct dropbear_hash dropbear_md5 = 
 	{&md5_desc, 16, 16};
 #endif
 
@@ -75,19 +87,29 @@
 #ifdef DROPBEAR_AES128_CBC
 	{"aes128-cbc", 0, (void*)&dropbear_aes128, 1},
 #endif
-#ifdef DROPBEAR_BLOWFISH_CBC
-	{"blowfish-cbc", 0, (void*)&dropbear_blowfish, 1},
+#ifdef DROPBEAR_3DES_CBC
+	{"3des-cbc", 0, (void*)&dropbear_3des, 1},
+#endif
+#ifdef DROPBEAR_AES256_CBC
+	{"aes256-cbc", 0, (void*)&dropbear_aes256, 1},
+#endif
+#ifdef DROPBEAR_TWOFISH256_CBC
+	{"twofish256-cbc", 0, (void*)&dropbear_twofish256, 1},
+	{"twofish-cbc", 0, (void*)&dropbear_twofish256, 1},
 #endif
 #ifdef DROPBEAR_TWOFISH128_CBC
-	{"twofish-cbc", 0, (void*)&dropbear_twofish128, 1},
+	{"twofish128-cbc", 0, (void*)&dropbear_twofish128, 1},
 #endif
-#ifdef DROPBEAR_3DES_CBC
-	{"3des-cbc", 0, (void*)&dropbear_3des, 1},
+#ifdef DROPBEAR_BLOWFISH_CBC
+	{"blowfish-cbc", 0, (void*)&dropbear_blowfish, 1},
 #endif
 	{NULL, 0, NULL, 0}
 };
 
 algo_type sshhashes[] = {
+#ifdef DROPBEAR_SHA1_96_HMAC
+	{"hmac-sha1-96", 0, (void*)&dropbear_sha1_96, 1},
+#endif
 #ifdef DROPBEAR_SHA1_HMAC
 	{"hmac-sha1", 0, (void*)&dropbear_sha1, 1},
 #endif
@@ -98,10 +120,10 @@
 };
 
 algo_type sshcompress[] = {
-	{"none", DROPBEAR_COMP_NONE, NULL, 1},
 #ifndef DISABLE_ZLIB
 	{"zlib", DROPBEAR_COMP_ZLIB, NULL, 1},
 #endif
+	{"none", DROPBEAR_COMP_NONE, NULL, 1},
 	{NULL, 0, NULL, 0}
 };
 
@@ -126,13 +148,13 @@
 void crypto_init() {
 
 	const struct ltc_cipher_descriptor *regciphers[] = {
-#ifdef DROPBEAR_AES128_CBC
+#ifdef DROPBEAR_AES_CBC
 		&aes_desc,
 #endif
 #ifdef DROPBEAR_BLOWFISH_CBC
 		&blowfish_desc,
 #endif
-#ifdef DROPBEAR_TWOFISH128_CBC
+#ifdef DROPBEAR_TWOFISH_CBC
 		&twofish_desc,
 #endif
 #ifdef DROPBEAR_3DES_CBC
@@ -187,21 +209,20 @@
 /* Output a comma separated list of algorithms to a buffer */
 void buf_put_algolist(buffer * buf, algo_type localalgos[]) {
 
-	unsigned int pos = 0, i, len;
-	char str[50]; /* enough for local algo storage */
+	unsigned int i, len;
+	unsigned int donefirst = 0;
+	buffer *algolist = NULL;
 
+	algolist = buf_new(100);
 	for (i = 0; localalgos[i].name != NULL; i++) {
 		if (localalgos[i].usable) {
-			/* Avoid generating a trailing comma */
-			if (pos)
-			    str[pos++] = ',';
+			if (donefirst)
+				buf_putbyte(algolist, ',');
+			donefirst = 1;
 			len = strlen(localalgos[i].name);
-			memcpy(&str[pos], localalgos[i].name, len);
-			pos += len;
+			buf_putbytes(algolist, localalgos[i].name, len);
 		}
 	}
-	str[pos]=0;
-	/* Debug this */
-	TRACE(("buf_put_algolist: %s", str))
-	buf_putstring(buf, str, pos);
+	buf_putstring(buf, algolist->data, algolist->len);
+	buf_free(algolist);
 }
--- a/common-channel.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/common-channel.c	Tue Mar 21 16:20:59 2006 +0000
@@ -52,8 +52,8 @@
 static void checkinitdone(struct Channel *channel);
 static void checkclose(struct Channel *channel);
 
-static void closeinfd(struct Channel * channel);
-static void closeoutfd(struct Channel * channel, int fd);
+static void closewritefd(struct Channel * channel);
+static void closereadfd(struct Channel * channel, int fd);
 static void closechanfd(struct Channel *channel, int fd, int how);
 
 #define FD_UNINIT (-2)
@@ -143,10 +143,11 @@
 	newchan->transmaxpacket = transmaxpacket;
 	
 	newchan->typedata = NULL;
-	newchan->infd = FD_UNINIT;
-	newchan->outfd = FD_UNINIT;
+	newchan->writefd = FD_UNINIT;
+	newchan->readfd = FD_UNINIT;
 	newchan->errfd = FD_CLOSED; /* this isn't always set to start with */
 	newchan->initconn = 0;
+	newchan->await_open = 0;
 
 	newchan->writebuf = cbuf_new(RECV_MAXWINDOW);
 	newchan->extrabuf = NULL; /* The user code can set it up */
@@ -176,11 +177,10 @@
 }
 
 /* Iterate through the channels, performing IO if available */
-void channelio(fd_set *readfd, fd_set *writefd) {
+void channelio(fd_set *readfds, fd_set *writefds) {
 
 	struct Channel *channel;
 	unsigned int i;
-	int ret;
 
 	/* iterate through all the possible channels */
 	for (i = 0; i < ses.chansize; i++) {
@@ -191,48 +191,30 @@
 			continue;
 		}
 
-		/* read from program/pipe stdout */
-		if (channel->outfd >= 0 && FD_ISSET(channel->outfd, readfd)) {
+		/* read data and send it over the wire */
+		if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
 			send_msg_channel_data(channel, 0, 0);
 		}
 
-		/* read from program/pipe stderr */
+		/* read stderr data and send it over the wire */
 		if (channel->extrabuf == NULL &&
-				channel->errfd >= 0 && FD_ISSET(channel->errfd, readfd)) {
+				channel->errfd >= 0 && FD_ISSET(channel->errfd, readfds)) {
 				send_msg_channel_data(channel, 1, SSH_EXTENDED_DATA_STDERR);
 		}
 
-		/* if we can read from the infd, it might be closed, so we try to
-		 * see if it has errors */
-		if (channel->infd >= 0 && channel->infd != channel->outfd
-				&& FD_ISSET(channel->infd, readfd)) {
-			if (channel->initconn) {
-				/* Handling for "in progress" connection - this is needed
-				 * to avoid spinning 100% CPU when we connect to a server
-				 * which doesn't send anything (tcpfwding) */
-				checkinitdone(channel);
-				continue; /* Important not to use the channel after 
-							 checkinitdone(), as it may be NULL */
-			}
-			ret = write(channel->infd, NULL, 0); /* Fake write */
-			if (ret < 0 && errno != EINTR && errno != EAGAIN) {
-				closeinfd(channel);
-			}
-		}
-
 		/* write to program/pipe stdin */
-		if (channel->infd >= 0 && FD_ISSET(channel->infd, writefd)) {
+		if (channel->writefd >= 0 && FD_ISSET(channel->writefd, writefds)) {
 			if (channel->initconn) {
 				checkinitdone(channel);
 				continue; /* Important not to use the channel after
 							 checkinitdone(), as it may be NULL */
 			}
-			writechannel(channel, channel->infd, channel->writebuf);
+			writechannel(channel, channel->writefd, channel->writebuf);
 		}
 		
 		/* stderr for client mode */
 		if (channel->extrabuf != NULL 
-				&& channel->errfd >= 0 && FD_ISSET(channel->errfd, writefd)) {
+				&& channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
 			writechannel(channel, channel->errfd, channel->extrabuf);
 		}
 	
@@ -243,7 +225,7 @@
 
 	/* Listeners such as TCP, X11, agent-auth */
 #ifdef USING_LISTENERS
-	handle_listeners(readfd);
+	handle_listeners(readfds);
 #endif
 }
 
@@ -251,8 +233,8 @@
 /* do all the EOF/close type stuff checking for a channel */
 static void checkclose(struct Channel *channel) {
 
-	TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d",
-				channel->infd, channel->outfd,
+	TRACE(("checkclose: writefd %d, readfd %d, errfd %d, sentclosed %d, recvclosed %d",
+				channel->writefd, channel->readfd,
 				channel->errfd, channel->sentclosed, channel->recvclosed))
 	TRACE(("writebuf %d extrabuf %s extrabuf %d",
 				cbuf_getused(channel->writebuf),
@@ -265,18 +247,18 @@
 		 * if the shell has exited etc */
 		if (channel->type->checkclose) {
 			if (channel->type->checkclose(channel)) {
-				closeinfd(channel);
+				closewritefd(channel);
 			}
 		}
 
 		if (!channel->senteof
-			&& channel->outfd == FD_CLOSED 
+			&& channel->readfd == FD_CLOSED 
 			&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
 			send_msg_channel_eof(channel);
 		}
 
-		if (channel->infd == FD_CLOSED
-			&& channel->outfd == FD_CLOSED
+		if (channel->writefd == FD_CLOSED
+			&& channel->readfd == FD_CLOSED
 			&& (channel->extrabuf != NULL || channel->errfd == FD_CLOSED)) {
 			send_msg_channel_close(channel);
 		}
@@ -313,17 +295,17 @@
 
 	TRACE(("enter checkinitdone"))
 
-	if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen)
+	if (getsockopt(channel->writefd, SOL_SOCKET, SO_ERROR, &val, &vallen)
 			|| val != 0) {
 		send_msg_channel_open_failure(channel->remotechan,
 				SSH_OPEN_CONNECT_FAILED, "", "");
-		close(channel->infd);
+		close(channel->writefd);
 		deletechannel(channel);
 		TRACE(("leave checkinitdone: fail"))
 	} else {
 		send_msg_channel_open_confirmation(channel, channel->recvwindow,
 				channel->recvmaxpacket);
-		channel->outfd = channel->infd;
+		channel->readfd = channel->writefd;
 		channel->initconn = 0;
 		TRACE(("leave checkinitdone: success"))
 	}
@@ -385,7 +367,7 @@
 		if (len < 0 && errno != EINTR) {
 			/* no more to write - we close it even if the fd was stderr, since
 			 * that's a nasty failure too */
-			closeinfd(channel);
+			closewritefd(channel);
 		}
 		TRACE(("leave writechannel: len <= 0"))
 		return;
@@ -394,9 +376,9 @@
 	cbuf_incrread(cbuf, len);
 	channel->recvdonelen += len;
 
-	if (fd == channel->infd && len == maxlen && channel->recveof) { 
+	if (fd == channel->writefd && cbuf_getused(cbuf) == 0 && channel->recveof) { 
 		/* Check if we're closing up */
-		closeinfd(channel);
+		closewritefd(channel);
 		TRACE(("leave writechannel: recveof set"))
 		return;
 	}
@@ -409,9 +391,9 @@
 		channel->recvdonelen = 0;
 	}
 
-	assert(channel->recvwindow <= RECV_MAXWINDOW);
-	assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
-	assert(channel->extrabuf == NULL ||
+	dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW);
+	dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
+	dropbear_assert(channel->extrabuf == NULL ||
 			channel->recvwindow <= cbuf_getavail(channel->extrabuf));
 	
 	
@@ -420,7 +402,7 @@
 
 /* Set the file descriptors for the main select in session.c
  * This avoid channels which don't have any window available, are closed, etc*/
-void setchannelfds(fd_set *readfd, fd_set *writefd) {
+void setchannelfds(fd_set *readfds, fd_set *writefds) {
 	
 	unsigned int i;
 	struct Channel * channel;
@@ -435,41 +417,31 @@
 		/* Stuff to put over the wire */
 		if (channel->transwindow > 0) {
 
-			if (channel->outfd >= 0) {
-				FD_SET(channel->outfd, readfd);
+			if (channel->readfd >= 0) {
+				FD_SET(channel->readfd, readfds);
 			}
 			
 			if (channel->extrabuf == NULL && channel->errfd >= 0) {
-					FD_SET(channel->errfd, readfd);
+					FD_SET(channel->errfd, readfds);
 			}
 		}
 
-		/* For checking FD status (ie closure etc) - we don't actually
-		 * read data from infd */
-		TRACE(("infd = %d, outfd %d, errfd %d, bufused %d", 
-					channel->infd, channel->outfd,
-					channel->errfd,
-					cbuf_getused(channel->writebuf) ))
-		if (channel->infd >= 0 && channel->infd != channel->outfd) {
-			FD_SET(channel->infd, readfd);
-		}
-
-		/* Stuff from the wire, to local program/shell/user etc */
-		if ((channel->infd >= 0 && cbuf_getused(channel->writebuf) > 0 )
+		/* Stuff from the wire */
+		if ((channel->writefd >= 0 && cbuf_getused(channel->writebuf) > 0 )
 				|| channel->initconn) {
 
-				FD_SET(channel->infd, writefd);
+				FD_SET(channel->writefd, writefds);
 		}
 
 		if (channel->extrabuf != NULL && channel->errfd >= 0 
 				&& cbuf_getused(channel->extrabuf) > 0 ) {
-				FD_SET(channel->errfd, writefd);
+				FD_SET(channel->errfd, writefds);
 		}
 
 	} /* foreach channel */
 
 #ifdef USING_LISTENERS
-	set_listener_fds(readfd);
+	set_listener_fds(readfds);
 #endif
 
 }
@@ -492,7 +464,7 @@
 	if (cbuf_getused(channel->writebuf) == 0
 			&& (channel->extrabuf == NULL 
 					|| cbuf_getused(channel->extrabuf) == 0)) {
-		closeinfd(channel);
+		closewritefd(channel);
 	}
 
 	TRACE(("leave recv_msg_channel_eof"))
@@ -540,8 +512,8 @@
 
 	/* close the FDs in case they haven't been done
 	 * yet (ie they were shutdown etc */
-	close(channel->infd);
-	close(channel->outfd);
+	close(channel->writefd);
+	close(channel->readfd);
 	close(channel->errfd);
 
 	channel->typedata = NULL;
@@ -603,14 +575,14 @@
 
 	CHECKCLEARTOWRITE();
 
-	assert(!channel->sentclosed);
+	dropbear_assert(!channel->sentclosed);
 
 	if (isextended) {
 		fd = channel->errfd;
 	} else {
-		fd = channel->outfd;
+		fd = channel->readfd;
 	}
-	assert(fd >= 0);
+	dropbear_assert(fd >= 0);
 
 	maxlen = MIN(channel->transwindow, channel->transmaxpacket);
 	/* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 
@@ -630,7 +602,7 @@
 	if (len <= 0) {
 		/* on error/eof, send eof */
 		if (len == 0 || errno != EINTR) {
-			closeoutfd(channel, fd);
+			closereadfd(channel, fd);
 		}
 		buf_free(buf);
 		buf = NULL;
@@ -668,7 +640,7 @@
 		dropbear_exit("Unknown channel");
 	}
 
-	common_recv_msg_channel_data(channel, channel->infd, channel->writebuf);
+	common_recv_msg_channel_data(channel, channel->writefd, channel->writebuf);
 }
 
 /* Shared for data and stderr data - when we receive data, put it in a buffer
@@ -688,7 +660,7 @@
 	}
 
  	if (fd < 0) {
-		dropbear_exit("received data with bad infd");
+		dropbear_exit("received data with bad writefd");
 	}
 
 	datalen = buf_getint(ses.payload);
@@ -718,9 +690,9 @@
 		len -= buflen;
 	}
 
-	assert(channel->recvwindow >= datalen);
+	dropbear_assert(channel->recvwindow >= datalen);
 	channel->recvwindow -= datalen;
-	assert(channel->recvwindow <= RECV_MAXWINDOW);
+	dropbear_assert(channel->recvwindow <= RECV_MAXWINDOW);
 
 	TRACE(("leave recv_msg_channel_data"))
 }
@@ -930,9 +902,11 @@
 	/* set fd non-blocking */
 	setnonblocking(fd);
 
-	chan->infd = chan->outfd = fd;
+	chan->writefd = chan->readfd = fd;
 	ses.maxfd = MAX(ses.maxfd, fd);
 
+	chan->await_open = 1;
+
 	/* now open the channel connection */
 	CHECKCLEARTOWRITE();
 
@@ -960,6 +934,11 @@
 		dropbear_exit("Unknown channel");
 	}
 
+	if (!channel->await_open) {
+		dropbear_exit("unexpected channel reply");
+	}
+	channel->await_open = 0;
+
 	channel->remotechan =  buf_getint(ses.payload);
 	channel->transwindow = buf_getint(ses.payload);
 	channel->transmaxpacket = buf_getint(ses.payload);
@@ -990,26 +969,31 @@
 		dropbear_exit("Unknown channel");
 	}
 
+	if (!channel->await_open) {
+		dropbear_exit("unexpected channel reply");
+	}
+	channel->await_open = 0;
+
 	removechannel(channel);
 }
 #endif /* USING_LISTENERS */
 
 /* close a stdout/stderr fd */
-static void closeoutfd(struct Channel * channel, int fd) {
+static void closereadfd(struct Channel * channel, int fd) {
 
-	/* don't close it if it is the same as infd,
-	 * unless infd is already set -1 */
-	TRACE(("enter closeoutfd"))
+	/* don't close it if it is the same as writefd,
+	 * unless writefd is already set -1 */
+	TRACE(("enter closereadfd"))
 	closechanfd(channel, fd, 0);
-	TRACE(("leave closeoutfd"))
+	TRACE(("leave closereadfd"))
 }
 
 /* close a stdin fd */
-static void closeinfd(struct Channel * channel) {
+static void closewritefd(struct Channel * channel) {
 
-	TRACE(("enter closeinfd"))
-	closechanfd(channel, channel->infd, 1);
-	TRACE(("leave closeinfd"))
+	TRACE(("enter closewritefd"))
+	closechanfd(channel, channel->writefd, 1);
+	TRACE(("leave closewritefd"))
 }
 
 /* close a fd, how is 0 for stdout/stderr, 1 for stdin */
@@ -1031,15 +1015,15 @@
 		closein = closeout = 1;
 	}
 
-	if (closeout && fd == channel->outfd) {
-		channel->outfd = FD_CLOSED;
+	if (closeout && fd == channel->readfd) {
+		channel->readfd = FD_CLOSED;
 	}
 	if (closeout && (channel->extrabuf == NULL) && (fd == channel->errfd)) {
 		channel->errfd = FD_CLOSED;
 	}
 
-	if (closein && fd == channel->infd) {
-		channel->infd = FD_CLOSED;
+	if (closein && fd == channel->writefd) {
+		channel->writefd = FD_CLOSED;
 	}
 	if (closein && (channel->extrabuf != NULL) && (fd == channel->errfd)) {
 		channel->errfd = FD_CLOSED;
@@ -1047,8 +1031,8 @@
 
 	/* if we called shutdown on it and all references are gone, then we 
 	 * need to close() it to stop it lingering */
-	if (channel->type->sepfds && channel->outfd == FD_CLOSED 
-		&& channel->infd == FD_CLOSED && channel->errfd == FD_CLOSED) {
+	if (channel->type->sepfds && channel->readfd == FD_CLOSED 
+		&& channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) {
 		close(fd);
 	}
 }
--- a/common-kex.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/common-kex.c	Tue Mar 21 16:20:59 2006 +0000
@@ -35,7 +35,7 @@
 #include "random.h"
 
 /* diffie-hellman-group1-sha1 value for p */
-const unsigned char dh_p_val[] = {
+static const unsigned char dh_p_val[] = {
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
     0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
 	0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
@@ -47,8 +47,9 @@
 	0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
 	0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+#define DH_P_LEN sizeof(dh_p_val)
 
-const int DH_G_VAL = 2;
+static const int DH_G_VAL = 2;
 
 static void kexinitialise();
 void gen_new_keys();
@@ -393,18 +394,28 @@
 /* Belongs in common_kex.c where it should be moved after review */
 void recv_msg_kexinit() {
 	
+	unsigned int kexhashbuf_len = 0;
+	unsigned int remote_ident_len = 0;
+	unsigned int local_ident_len = 0;
+
 	TRACE(("<- KEXINIT"))
 	TRACE(("enter recv_msg_kexinit"))
 	
-	/* start the kex hash */
-	ses.kexhashbuf = buf_new(MAX_KEXHASHBUF);
-
 	if (!ses.kexstate.sentkexinit) {
 		/* we need to send a kex packet */
 		send_msg_kexinit();
 		TRACE(("continue recv_msg_kexinit: sent kexinit"))
 	}
 
+	/* start the kex hash */
+	local_ident_len = strlen(LOCAL_IDENT);
+	remote_ident_len = strlen((char*)ses.remoteident);
+
+	kexhashbuf_len = local_ident_len + remote_ident_len
+		+ ses.transkexinit->len + ses.payload->len
+		+ KEXHASHBUF_MAX_INTS;
+
+	ses.kexhashbuf = buf_new(kexhashbuf_len);
 
 	if (IS_DROPBEAR_CLIENT) {
 
@@ -413,20 +424,16 @@
 
 		/* V_C, the client's version string (CR and NL excluded) */
 	    buf_putstring(ses.kexhashbuf,
-			(unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT));
+			(unsigned char*)LOCAL_IDENT, local_ident_len);
 		/* V_S, the server's version string (CR and NL excluded) */
-	    buf_putstring(ses.kexhashbuf, 
-			ses.remoteident, strlen((char*)ses.remoteident));
+	    buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
 
 		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
 	    buf_putstring(ses.kexhashbuf,
-			buf_getptr(ses.transkexinit, ses.transkexinit->len),
-			ses.transkexinit->len);
+			ses.transkexinit->data, ses.transkexinit->len);
 		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
 	    buf_setpos(ses.payload, 0);
-	    buf_putstring(ses.kexhashbuf,
-			buf_getptr(ses.payload, ses.payload->len),
-			ses.payload->len);
+	    buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
 
 	} else {
 		/* SERVER */
@@ -434,21 +441,19 @@
 		/* read the peer's choice of algos */
 		read_kex_algos();
 		/* V_C, the client's version string (CR and NL excluded) */
-	    buf_putstring(ses.kexhashbuf, 
-			ses.remoteident, strlen((char*)ses.remoteident));
+	    buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
 		/* V_S, the server's version string (CR and NL excluded) */
-	    buf_putstring(ses.kexhashbuf,
-			(unsigned char*)LOCAL_IDENT, strlen(LOCAL_IDENT));
+	    buf_putstring(ses.kexhashbuf, 
+				(unsigned char*)LOCAL_IDENT, local_ident_len);
 
 		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
 	    buf_setpos(ses.payload, 0);
-	    buf_putstring(ses.kexhashbuf,
-			buf_getptr(ses.payload, ses.payload->len),
-			ses.payload->len);
+	    buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
+
 		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
 	    buf_putstring(ses.kexhashbuf,
-			buf_getptr(ses.transkexinit, ses.transkexinit->len),
-			ses.transkexinit->len);
+			ses.transkexinit->data, ses.transkexinit->len);
+
 		ses.requirenext = SSH_MSG_KEXDH_INIT;
 	}
 
@@ -621,7 +626,7 @@
 		erralgo = "enc c->s";
 		goto error;
 	}
-	TRACE(("c2s is  %s", c2s_cipher_algo->name))
+	TRACE(("enc c2s is  %s", c2s_cipher_algo->name))
 
 	/* encryption_algorithms_server_to_client */
 	s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess);
@@ -629,7 +634,7 @@
 		erralgo = "enc s->c";
 		goto error;
 	}
-	TRACE(("s2c is  %s", s2c_cipher_algo->name))
+	TRACE(("enc s2c is  %s", s2c_cipher_algo->name))
 
 	/* mac_algorithms_client_to_server */
 	c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
@@ -637,6 +642,7 @@
 		erralgo = "mac c->s";
 		goto error;
 	}
+	TRACE(("hash c2s is  %s", c2s_hash_algo->name))
 
 	/* mac_algorithms_server_to_client */
 	s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
@@ -644,6 +650,7 @@
 		erralgo = "mac s->c";
 		goto error;
 	}
+	TRACE(("hash s2c is  %s", s2c_hash_algo->name))
 
 	/* compression_algorithms_client_to_server */
 	c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
@@ -651,6 +658,7 @@
 		erralgo = "comp c->s";
 		goto error;
 	}
+	TRACE(("hash c2s is  %s", c2s_comp_algo->name))
 
 	/* compression_algorithms_server_to_client */
 	s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
@@ -658,6 +666,7 @@
 		erralgo = "comp s->c";
 		goto error;
 	}
+	TRACE(("hash s2c is  %s", s2c_comp_algo->name))
 
 	/* languages_client_to_server */
 	buf_eatstring(ses.payload);
@@ -700,13 +709,6 @@
 		ses.newkeys->trans_algo_comp = s2c_comp_algo->val;
 	}
 
-	TRACE(("enc algo recv %s", algo->name))
-	TRACE(("enc algo trans %s", algo->name))
-	TRACE(("mac algo recv %s", algo->name))
-	TRACE(("mac algo trans %s", algo->name))
-	TRACE(("comp algo recv %s", algo->name))
-	TRACE(("comp algo trans %s", algo->name))
-
 	/* reserved for future extensions */
 	buf_getint(ses.payload);
 	return;
--- a/common-session.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/common-session.c	Tue Mar 21 16:20:59 2006 +0000
@@ -62,7 +62,6 @@
 	ses.connecttimeout = 0;
 	
 	kexfirstinitialise(); /* initialise the kex state */
-	chaninitialise(); /* initialise the channel state */
 
 	ses.writepayload = buf_new(MAX_TRANS_PAYLOAD_LEN);
 	ses.transseq = 0;
@@ -126,7 +125,7 @@
 		timeout.tv_usec = 0;
 		FD_ZERO(&writefd);
 		FD_ZERO(&readfd);
-		assert(ses.payload == NULL);
+		dropbear_assert(ses.payload == NULL);
 		if (ses.sock != -1) {
 			FD_SET(ses.sock, &readfd);
 			if (!isempty(&ses.writequeue)) {
@@ -233,10 +232,8 @@
 		dropbear_exit("Error writing ident string");
 	}
 
-	/* We allow up to 9 lines before the actual version string, to
-	 * account for wrappers/cruft etc. According to the spec only the client
-	 * needs to handle this, but no harm in letting the server handle it too */
-	for (i = 0; i < 10; i++) {
+    /* If they send more than 50 lines, something is wrong */
+	for (i = 0; i < 50; i++) {
 		len = ident_readln(ses.sock, linebuf, sizeof(linebuf));
 
 		if (len < 0 && errno != EINTR) {
@@ -260,6 +257,12 @@
 		memcpy(ses.remoteident, linebuf, len);
 	}
 
+    /* Shall assume that 2.x will be backwards compatible. */
+    if (strncmp(ses.remoteident, "SSH-2.", 6) != 0
+            && strncmp(ses.remoteident, "SSH-1.99-", 9) != 0) {
+        dropbear_exit("Incompatible remote version '%s'", ses.remoteident);
+    }
+
 	TRACE(("remoteident: %s", ses.remoteident))
 
 }
--- a/configure.in	Mon Jul 18 14:32:52 2005 +0000
+++ b/configure.in	Tue Mar 21 16:20:59 2006 +0000
@@ -206,7 +206,7 @@
 # Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h pam/pam_appl.h])
+AC_CHECK_HEADERS([fcntl.h limits.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/time.h termios.h unistd.h crypt.h pty.h ioctl.h libutil.h libgen.h inttypes.h stropts.h utmp.h utmpx.h lastlog.h paths.h util.h netdb.h security/pam_appl.h pam/pam_appl.h netinet/in_systm.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -339,8 +339,9 @@
 #endif
 ])
 
-AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_type, struct utmpx.ut_id, struct utmpx.ut_addr, struct utmpx.ut_addr_v6, struct utmpx.ut_time, struct utmpx.ut_tv],,,[
+AC_CHECK_MEMBERS([struct utmpx.ut_host, struct utmpx.ut_syslen, struct utmpx.ut_type, struct utmpx.ut_id, struct utmpx.ut_addr, struct utmpx.ut_addr_v6, struct utmpx.ut_time, struct utmpx.ut_tv, struct sockaddr_storage.ss_family, struct sockadd_storage.__family],,,[
 #include <sys/types.h>
+#include <sys/socket.h>
 #if HAVE_UTMPX_H
 #include <utmpx.h>
 #endif
--- a/dbclient.1	Mon Jul 18 14:32:52 2005 +0000
+++ b/dbclient.1	Tue Mar 21 16:20:59 2006 +0000
@@ -59,6 +59,11 @@
 .TP
 .B \-T
 Don't allocate a pty.
+.TP
+.B \-g
+Allow non-local hosts to connect to forwarded ports. Applies to -L and -R
+forwarded ports, though remote connections to -R forwarded ports may be limited
+by the ssh server.
 .SH AUTHOR
 Matt Johnston ([email protected]).
 .br
--- a/dbutil.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/dbutil.c	Tue Mar 21 16:20:59 2006 +0000
@@ -110,6 +110,10 @@
 	exit(exitcode);
 }
 
+void fail_assert(const char* expr, const char* file, int line) {
+	dropbear_exit("failed assertion (%s:%d): `%s'", file, line, expr);
+}
+
 static void generic_dropbear_log(int UNUSED(priority), const char* format, 
 		va_list param) {
 
@@ -149,8 +153,33 @@
 }
 #endif /* DEBUG_TRACE */
 
-/* Listen on address:port. Unless address is NULL, in which case listen on
- * everything. If called with address == "", we'll listen on localhost/loopback.
+static void set_sock_priority(int sock) {
+
+	int val;
+
+	/* disable nagle */
+	val = 1;
+	setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));
+
+	/* set the TOS bit. note that this will fail for ipv6, I can't find any
+	 * equivalent. */
+#ifdef IPTOS_LOWDELAY
+	val = IPTOS_LOWDELAY;
+	setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&val, sizeof(val));
+#endif
+
+#ifdef SO_PRIORITY
+	/* linux specific, sets QoS class.
+	 * 6 looks to be optimal for interactive traffic (see tc-prio(8) ). */
+	val = 6;
+	setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &val, sizeof(val));
+#endif
+
+}
+
+/* Listen on address:port. 
+ * Special cases are address of "" listening on everything,
+ * and address of NULL listening on localhost only.
  * Returns the number of sockets bound on success, or -1 on failure. On
  * failure, if errstring wasn't NULL, it'll be a newly malloced error
  * string.*/
@@ -170,11 +199,17 @@
 	hints.ai_family = AF_UNSPEC; /* TODO: let them flag v4 only etc */
 	hints.ai_socktype = SOCK_STREAM;
 
-	if (address && address[0] == '\0') {
+	// for calling getaddrinfo:
+	// address == NULL and !AI_PASSIVE: local loopback
+	// address == NULL and AI_PASSIVE: all interfaces
+	// address != NULL: whatever the address says
+	if (!address) {
 		TRACE(("dropbear_listen: local loopback"))
-		address = NULL;
 	} else {
-		TRACE(("dropbear_listen: not local loopback"))
+		if (address[0] == '\0') {
+			TRACE(("dropbear_listen: all interfaces"))
+			address = NULL;
+		}
 		hints.ai_flags = AI_PASSIVE;
 	}
 	err = getaddrinfo(address, port, &hints, &res0);
@@ -186,6 +221,10 @@
 			*errstring = (char*)m_malloc(len);
 			snprintf(*errstring, len, "Error resolving: %s", gai_strerror(err));
 		}
+		if (res0) {
+			freeaddrinfo(res0);
+			res0 = NULL;
+		}
 		TRACE(("leave dropbear_listen: failed resolving"))
 		return -1;
 	}
@@ -215,8 +254,7 @@
 		linger.l_linger = 5;
 		setsockopt(sock, SOL_SOCKET, SO_LINGER, (void*)&linger, sizeof(linger));
 
-		/* disable nagle */
-		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val));
+		set_sock_priority(sock);
 
 		if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
 			err = errno;
@@ -237,6 +275,11 @@
 		nsock++;
 	}
 
+	if (res0) {
+		freeaddrinfo(res0);
+		res0 = NULL;
+	}
+
 	if (nsock == 0) {
 		if (errstring != NULL && *errstring == NULL) {
 			int len;
@@ -343,8 +386,7 @@
 		TRACE(("Error connecting: %s", strerror(err)))
 	} else {
 		/* Success */
-		/* (err is used as a dummy var here) */
-		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&err, sizeof(err));
+		set_sock_priority(sock);
 	}
 
 	freeaddrinfo(res0);
@@ -555,20 +597,17 @@
 }	
 #endif
 
-/* loop until the socket is closed (in case of EINTR) or
- * we get and error.
- * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
-int m_close(int fd) {
+/* make sure that the socket closes */
+void m_close(int fd) {
 
 	int val;
 	do {
 		val = close(fd);
 	} while (val < 0 && errno == EINTR);
 
-	if (val == 0 || errno == EBADF) {
-		return DROPBEAR_SUCCESS;
-	} else {
-		return DROPBEAR_FAILURE;
+	if (val < 0 && errno != EBADF) {
+		/* Linux says EIO can happen */
+		dropbear_exit("Error closing fd %d, %s", fd, strerror(errno));
 	}
 }
 	
--- a/dbutil.h	Mon Jul 18 14:32:52 2005 +0000
+++ b/dbutil.h	Tue Mar 21 16:20:59 2006 +0000
@@ -39,6 +39,7 @@
 void dropbear_exit(const char* format, ...);
 void dropbear_close(const char* format, ...);
 void dropbear_log(int priority, const char* format, ...);
+void fail_assert(const char* expr, const char* file, int line);
 #ifdef DEBUG_TRACE
 void dropbear_trace(const char* format, ...);
 void printhex(const char * label, const unsigned char * buf, int len);
@@ -57,7 +58,7 @@
 int buf_readfile(buffer* buf, const char* filename);
 int buf_getline(buffer * line, FILE * authfile);
 
-int m_close(int fd);
+void m_close(int fd);
 void * m_malloc(size_t size);
 void * m_strdup(const char * str);
 void * m_realloc(void* ptr, size_t size);
@@ -69,4 +70,7 @@
 /* Used to force mp_ints to be initialised */
 #define DEF_MP_INT(X) mp_int X = {0, 0, 0, NULL}
 
+/* Dropbear assertion */
+#define dropbear_assert(X) do { if (!(X)) { fail_assert(#X, __FILE__, __LINE__); } } while (0)
+
 #endif /* _DBUTIL_H_ */
--- a/debian/changelog	Mon Jul 18 14:32:52 2005 +0000
+++ b/debian/changelog	Tue Mar 21 16:20:59 2006 +0000
@@ -1,6 +1,32 @@
-dropbear (0.46-0.1) unstable; urgency=medium
+dropbear (0.48-0.1) unstable; urgency=high
+
+  * New upstream release.
+  * SECURITY: Improve handling of denial of service attempts from a single IP.
+
+ -- Matt Johnston <[email protected]>  Thu, 8 Mar 2006 19:20:21 +0800
+
+dropbear (0.47-0.1) unstable; urgency=high
+
+  * New upstream release.
+  * SECURITY: Fix incorrect buffer sizing.
+
+ -- Matt Johnston <[email protected]>  Thu, 8 Dec 2005 19:20:21 +0800
+
+dropbear (0.46-2) unstable; urgency=low
+
+  * debian/control: Standards-Version: 3.6.2.1; update descriptions to
+    mention included server and client (thx Tino Keitel).
+  * debian/dropbear.init: allow '/etc/init.d/dropbear stop' even though
+    'NO_START is not set to zero.' (closes: #336723).
+
+ -- Gerrit Pape <[email protected]>  Tue,  6 Dec 2005 13:30:49 +0000
+
+dropbear (0.46-1) unstable; urgency=medium
 
   * New upstream release, various fixes.
+  * debian/diff/dbclient-usage-typo.diff, debian/diff/manpages.diff: remove;
+    obsolete.
+  * debian/dbclient.1: move to ./dbclient.1.
 
  -- Matt Johnston <[email protected]>  Fri, 8 July 2005 21:32:55 +0800
 
--- a/debian/control	Mon Jul 18 14:32:52 2005 +0000
+++ b/debian/control	Tue Mar 21 16:20:59 2006 +0000
@@ -3,16 +3,16 @@
 Priority: optional
 Maintainer: Gerrit Pape <[email protected]>
 Build-Depends: libz-dev
-Standards-Version: 3.6.1.0
+Standards-Version: 3.6.2.1
 
 Package: dropbear
 Architecture: any
 Depends: ${shlibs:Depends}
 Suggests: ssh, runit
-Description: lightweight SSH2 server
- dropbear is a SSH 2 server designed to be small enough to be used in small
- memory environments, while still being functional and secure enough for
- general use.
+Description: lightweight SSH2 server and client
+ dropbear is a SSH 2 server and client designed to be small enough to
+ be used in small memory environments, while still being functional and
+ secure enough for general use.
  .
  It implements most required features of the SSH 2 protocol, and other
  features such as X11 and authentication agent forwarding.
--- a/debian/dropbear.init	Mon Jul 18 14:32:52 2005 +0000
+++ b/debian/dropbear.init	Tue Mar 21 16:20:59 2006 +0000
@@ -16,7 +16,6 @@
 
 cancel() { echo "$1" >&2; exit 0; };
 test ! -r /etc/default/dropbear || . /etc/default/dropbear
-test "$NO_START" = "0" || cancel 'NO_START is not set to zero.'
 test -x "$DAEMON" || cancel "$DAEMON does not exist or is not executable."
 test ! -h /var/service/dropbear || \
   cancel '/var/service/dropbear exists, service is controlled through runit.'
@@ -30,6 +29,7 @@
 
 case "$1" in
   start)
+	test "$NO_START" = "0" || cancel 'NO_START is not set to zero.'
 	echo -n "Starting $DESC: "
 	start-stop-daemon --start --quiet --pidfile /var/run/"$NAME".pid \
 	  --exec "$DAEMON" -- -d "$DROPBEAR_DSSKEY" -r "$DROPBEAR_RSAKEY" \
@@ -42,6 +42,7 @@
 	echo "$NAME."
 	;;
   restart|force-reload)
+	test "$NO_START" = "0" || cancel 'NO_START is not set to zero.'
 	echo -n "Restarting $DESC: "
 	start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/"$NAME".pid
 	sleep 1
--- a/dropbear.8	Mon Jul 18 14:32:52 2005 +0000
+++ b/dropbear.8	Tue Mar 21 16:20:59 2006 +0000
@@ -71,6 +71,9 @@
 .B dropbear
 under TCP/IP servers like inetd, tcpsvd, or tcpserver.
 In program mode the \-F option is implied, and \-p options are ignored.
+.TP
+.B \-a
+Allow remote hosts to connect to forwarded ports.
 .SH AUTHOR
 Matt Johnston ([email protected]).
 .br
--- a/dss.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/dss.c	Tue Mar 21 16:20:59 2006 +0000
@@ -46,7 +46,7 @@
 int buf_get_dss_pub_key(buffer* buf, dss_key *key) {
 
 	TRACE(("enter buf_get_dss_pub_key"))
-	assert(key != NULL);
+	dropbear_assert(key != NULL);
 	key->p = m_malloc(sizeof(mp_int));
 	key->q = m_malloc(sizeof(mp_int));
 	key->g = m_malloc(sizeof(mp_int));
@@ -80,7 +80,7 @@
 
 	int ret = DROPBEAR_FAILURE;
 
-	assert(key != NULL);
+	dropbear_assert(key != NULL);
 
 	ret = buf_get_dss_pub_key(buf, key);
 	if (ret == DROPBEAR_FAILURE) {
@@ -137,7 +137,7 @@
  */
 void buf_put_dss_pub_key(buffer* buf, dss_key *key) {
 
-	assert(key != NULL);
+	dropbear_assert(key != NULL);
 	buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN);
 	buf_putmpint(buf, key->p);
 	buf_putmpint(buf, key->q);
@@ -149,7 +149,7 @@
 /* Same as buf_put_dss_pub_key, but with the private "x" key appended */
 void buf_put_dss_priv_key(buffer* buf, dss_key *key) {
 
-	assert(key != NULL);
+	dropbear_assert(key != NULL);
 	buf_put_dss_pub_key(buf, key);
 	buf_putmpint(buf, key->x);
 
@@ -172,7 +172,7 @@
 	int stringlen;
 
 	TRACE(("enter buf_dss_verify"))
-	assert(key != NULL);
+	dropbear_assert(key != NULL);
 
 	m_mp_init_multi(&val1, &val2, &val3, &val4, NULL);
 
@@ -310,7 +310,7 @@
 	hash_state hs;
 	
 	TRACE(("enter buf_put_dss_sign"))
-	assert(key != NULL);
+	dropbear_assert(key != NULL);
 	
 	/* hash the data */
 	sha1_init(&hs);
@@ -380,7 +380,7 @@
 	buf_putint(buf, 2*SHA1_HASH_SIZE);
 
 	writelen = mp_unsigned_bin_size(&dss_r);
-	assert(writelen <= SHA1_HASH_SIZE);
+	dropbear_assert(writelen <= SHA1_HASH_SIZE);
 	/* need to pad to 160 bits with leading zeros */
 	for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) {
 		buf_putbyte(buf, 0);
@@ -393,7 +393,7 @@
 	buf_incrwritepos(buf, writelen);
 
 	writelen = mp_unsigned_bin_size(&dss_s);
-	assert(writelen <= SHA1_HASH_SIZE);
+	dropbear_assert(writelen <= SHA1_HASH_SIZE);
 	/* need to pad to 160 bits with leading zeros */
 	for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) {
 		buf_putbyte(buf, 0);
--- a/includes.h	Mon Jul 18 14:32:52 2005 +0000
+++ b/includes.h	Tue Mar 21 16:20:59 2006 +0000
@@ -44,7 +44,6 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <limits.h>
-#include <netinet/in.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdlib.h>
@@ -57,8 +56,6 @@
 #include <stdarg.h>
 #include <dirent.h>
 
-#include <arpa/inet.h>
-
 #ifdef HAVE_UTMP_H
 #include <utmp.h>
 #endif
@@ -75,10 +72,20 @@
 #include <lastlog.h>
 #endif
 
+#include <arpa/inet.h>
+
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
 
+/* netbsd 1.6 needs this to be included before netinet/ip.h for some
+ * undocumented reason */
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+
+#include <netinet/ip.h>
+
 #ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
 #endif
@@ -128,6 +135,13 @@
 #define LOG_AUTHPRIV LOG_AUTH
 #endif
 
+/* glibc 2.1.3 systems have sockaddr_storage.__ss_family rather than
+ * sockaddr_storage.ss_family */
+#if !defined(HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY) \
+    && defined(HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY)
+#define ss_family __ss_family
+#endif
+
 /* so we can avoid warnings about unused params (ie in signal handlers etc) */
 #ifdef UNUSED 
 #elif defined(__GNUC__) 
--- a/kex.h	Mon Jul 18 14:32:52 2005 +0000
+++ b/kex.h	Tue Mar 21 16:20:59 2006 +0000
@@ -42,11 +42,6 @@
 void send_msg_kexdh_init(); /* client */
 void recv_msg_kexdh_reply(); /* client */
 
-extern const unsigned char dh_p_val[];
-#define DH_P_LEN 128 /* The length of the dh_p_val array */
-
-extern const int DH_G_VAL; /* == 2 */
-
 struct KEXState {
 
 	unsigned sentkexinit : 1; /*set when we've sent/recv kexinit packet */
--- a/keyimport.c	Mon Jul 18 14:32:52 2005 +0000
+++ b/keyimport.c	Tue Mar 21 16:20:59 2006 +0000
@@ -173,6 +173,8 @@
 		buf_incrpos(buf, len);
 	} while (len > 0 && buf->len != buf->pos);
 
+	fclose(fp);
+
 	if (buf->pos != buf->len) {
 		ret = 0;
 	} else {
@@ -203,7 +205,7 @@
 	unsigned long outlen;
 	int rawcpl;
 	rawcpl = cpl * 3 / 4;
-	assert((unsigned int)cpl < sizeof(out));
+	dropbear_assert((unsigned int)cpl < sizeof(out));
 
     while (datalen > 0) {
 		n = (datalen < rawcpl ? datalen : rawcpl);
@@ -714,7 +716,7 @@
 	}
 #endif
 
-	assert(keytype != -1);
+	dropbear_assert(keytype != -1);
 
 	/*
 	 * Fetch the key blobs.
@@ -913,7 +915,7 @@
 	 * with the same value. Those are all removed and the rest is
 	 * returned.
 	 */
-	assert(pos == len);
+	dropbear_assert(pos == len);
 	while (pos < outlen) {
 		outblob[pos++] = outlen - len;
 	}
@@ -1491,7 +1493,7 @@
 		privlen = pos - publen;
 	}
 
-	assert(privlen > 0);			   /* should have bombed by now if not */
+	dropbear_assert(privlen > 0);			   /* should have bombed by now if not */
 
 	retkey = snew(struct ssh2_userkey);
 	retkey->alg = alg;
@@ -1557,7 +1559,7 @@
 		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
 		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
 
-		assert(e.start && iqmp.start); /* can't go wrong */
+		dropbear_assert(e.start && iqmp.start); /* can't go wrong */
 
 		numbers[0] = e;
 		numbers[1] = d;
@@ -1581,7 +1583,7 @@
 		pos = 0;
 		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
 
-		assert(y.start && x.start); /* can't go wrong */
+		dropbear_assert(y.start && x.start); /* can't go wrong */
 
 		numbers[0] = p;
 		numbers[1] = g;
@@ -1593,7 +1595,7 @@
 		initial_zero = 1;
 		type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}";
 	} else {
-		assert(0);					 /* zoinks! */
+		dropbear_assert(0);					 /* zoinks! */
 	}
 
 	/*
@@ -1637,13 +1639,13 @@
 	}
 	ciphertext = (char *)outblob+lenpos+4;
 	cipherlen = pos - (lenpos+4);
-	assert(!passphrase || cipherlen % 8 == 0);
+	dropbear_assert(!passphrase || cipherlen % 8 == 0);
 	/* Wrap up the encrypted blob string. */
 	PUT_32BIT(outblob+lenpos, cipherlen);
 	/* And finally fill in the total length field. */
 	PUT_32BIT(outblob+4, pos);
 
-	assert(pos < outlen);
+	dropbear_assert(pos < outlen);
 
 	/*
 	 * Encrypt the key.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/Doxyfile	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,1155 @@
+# Doxyfile 1.3.9.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = LibTomCrypt
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 1.05
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc/doxygen
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of source 
+# files, where putting all generated files in the same directory would otherwise 
+# cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is used 
+# as the annotated text. Otherwise, the brief description is used as-is. If left 
+# blank, the following values are used ("$name" is automatically replaced with the 
+# name of the entity): "The $name class" "The $name widget" "The $name file" 
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = src
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = src/headers
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = src
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 1
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = src/headers
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/LICENSE	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,5 @@
+LibTomCrypt is public domain.  As should all quality software be.
+
+Tom St Denis
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/Makefile.in	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,282 @@
+# MAKEFILE for linux GCC
+#
+# Tom St Denis
+# Modified by Clay Culver
+
+# The version
+VERSION=1.05
+
[email protected]@
[email protected]@
+
+# Compiler and Linker Names
+#CC=gcc
+#LD=ld
+
+# Archiver [makes .a files]
+#AR=ar
+#ARFLAGS=r
+
+# Compilation flags. Note the += does not write over the user's CFLAGS!
+# The rest of the flags come from the parent Dropbear makefile
+CFLAGS += -c -I$(srcdir)/src/headers/ -I$(srcdir)/../
+
+# additional warnings (newer GCC 3.4 and higher)
+#CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
+#		  -Wmissing-declarations -Wpointer-arith 
+
+# optimize for SPEED
+#CFLAGS += -O3 -funroll-loops
+
+# add -fomit-frame-pointer.  hinders debugging!
+#CFLAGS += -fomit-frame-pointer
+
+# optimize for SIZE
+#CFLAGS += -Os -DLTC_SMALL_CODE
+
+# older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros
+# define this to help
+#CFLAGS += -DLTC_NO_ROLC
+
+# compile for DEBUGING (required for ccmalloc checking!!!)
+#CFLAGS += -g3 -DLTC_NO_ASM
+
+#Output filenames for various targets.
+LIBNAME=libtomcrypt.a
+LIBTEST=testprof/libtomcrypt_prof.a
+HASH=hashsum
+CRYPT=encrypt
+SMALL=small
+PROF=x86_prof
+TV=tv_gen
+MULTI=multi
+TIMING=timing
+TEST=test
+
+#LIBPATH-The directory for libtomcrypt to be installed to.
+#INCPATH-The directory to install the header files for libtomcrypt.
+#DATAPATH-The directory to install the pdf docs.
+DESTDIR=
+LIBPATH=/usr/lib
+INCPATH=/usr/include
+DATAPATH=/usr/share/doc/libtomcrypt/pdf
+
+#Who do we install as?
+ifdef INSTALL_USER
+USER=$(INSTALL_USER)
+else
+USER=root
+endif
+
+ifdef INSTALL_GROUP
+GROUP=$(INSTALL_GROUP)
+else
+GROUP=wheel
+endif
+
+#List of objects to compile.
+
+#Leave MPI built-in or force developer to link against libtommath?
+#MPIOBJECT=src/misc/mpi/mpi.o
+#Dropbear uses libtommath
+MPIOBJECT=
+
+OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o src/ciphers/anubis.o \
+src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o \
+src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o \
+src/ciphers/safer/safer_tab.o src/ciphers/safer/saferp.o src/ciphers/skipjack.o \
+src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \
+src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \
+src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \
+src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \
+src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \
+src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \
+src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o \
+src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \
+src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \
+src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \
+src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \
+src/hashes/chc/chc.o src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o \
+src/hashes/helper/hash_memory.o src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \
+src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/sha1.o src/hashes/sha2/sha256.o \
+src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o src/mac/hmac/hmac_done.o \
+src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \
+src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \
+src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \
+src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \
+src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \
+src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
+src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \
+src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/misc/base64/base64_decode.o \
+src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt.o \
+src/misc/crypt/crypt_argchk.o src/misc/crypt/crypt_cipher_descriptor.o \
+src/misc/crypt/crypt_cipher_is_valid.o src/misc/crypt/crypt_find_cipher.o \
+src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher_id.o \
+src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_any.o \
+src/misc/crypt/crypt_find_hash_id.o src/misc/crypt/crypt_find_prng.o \
+src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \
+src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \
+src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \
+src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_unregister_cipher.o \
+src/misc/crypt/crypt_unregister_hash.o src/misc/crypt/crypt_unregister_prng.o \
+src/misc/error_to_string.o src/misc/mpi/is_prime.o src/misc/mpi/mpi_to_ltc_error.o \
+src/misc/mpi/rand_prime.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \
+src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \
+src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \
+src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \
+src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \
+src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \
+src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \
+src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
+src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
+src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
+src/modes/ofb/ofb_start.o 
+
+HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \
+src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \
+src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h src/headers/tommath_class.h \
+src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_misc.h \
+src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+
+TESTOBJECTS=demos/test.o
+HASHOBJECTS=demos/hashsum.o
+CRYPTOBJECTS=demos/encrypt.o
+SMALLOBJECTS=demos/small.o
+TVS=demos/tv_gen.o
+MULTIS=demos/multi.o
+TIMINGS=demos/timing.o
+TESTS=demos/test.o
+
+#Files left over from making the crypt.pdf.
+LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out
+
+#Compressed filenames
+COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
+
+#The default rule for make builds the libtomcrypt library.
+default:library
+
+#ciphers come in two flavours... enc+dec and enc 
+src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
+
+#These are the rules to make certain object files.
+src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
+src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
+src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
+src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
+src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
+src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
+src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
+
+#This rule makes the libtomcrypt library.
+library: $(LIBNAME)
+
+$(LIBTEST): 
+	cd testprof ; CFLAGS="$(CFLAGS)" make 
+
+$(LIBNAME): $(OBJECTS)
+	$(AR) $(ARFLAGS) [email protected] $(OBJECTS) 
+	$(RANLIB) $(LIBNAME)
+
+#This rule makes the hash program included with libtomcrypt
+hashsum: library $(HASHOBJECTS)
+	$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
+
+#makes the crypt program
+crypt: library $(CRYPTOBJECTS)
+	$(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN)
+
+#makes the small program
+small: library $(SMALLOBJECTS)
+	$(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN)
+	
+tv_gen: library $(TVS)
+	$(CC) $(TVS) $(LIBNAME) -o $(TV)
+
+multi: library $(MULTIS)
+	$(CC) $(MULTIS) $(LIBNAME) -o $(MULTI)
+
+timing: library $(LIBTEST) $(TIMINGS)
+	$(CC) $(TIMINGS) $(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING)
+
+test: library $(LIBTEST) $(TESTS)
+	$(CC) $(TESTS) $(LIBTEST) $(LIBNAME) -o $(TEST)
+
+
+#This rule installs the library and the header files. This must be run
+#as root in order to have a high enough permission to write to the correct
+#directories and to set the owner and group to root.
+install: library docs
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
+	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
+	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
+	install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH)
+
+install_test: $(LIBTEST)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH)
+
+profile:
+	CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov
+	./timing
+	rm -f timing `find . -type f | grep [.][ao] | xargs`
+	CFLAGS="$(CFLAGS) -fprofile-use" make timing EXTRALIBS=-lgcov
+
+
+#This rule cleans the source tree of all compiled code, not including the pdf
+#documentation.
+clean:
+	-rm -f $(OBJECTS)
+	-rm -f libtomcrypt.a
+
+#build the doxy files (requires Doxygen, tetex and patience)
+doxy:
+	doxygen
+	cd doc/doxygen/latex ; make ; mv -f refman.pdf ../../.
+	echo The huge doxygen PDF should be available as doc/refman.pdf
+	
+#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
+#from the clean command! This is because most people would like to keep the
+#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
+#delete it if we are rebuilding it.
+docs: crypt.tex
+	rm -f doc/crypt.pdf $(LEFTOVERS)
+	echo "hello" > crypt.ind
+	latex crypt > /dev/null
+	latex crypt > /dev/null
+	makeindex crypt.idx > /dev/null
+	latex crypt > /dev/null
+	dvipdf crypt
+	mv -ivf crypt.pdf doc/crypt.pdf
+	rm -f $(LEFTOVERS)
+
+docdvi: crypt.tex
+	echo hello > crypt.ind
+	latex crypt > /dev/null
+	latex crypt > /dev/null
+	makeindex crypt.idx
+	latex crypt > /dev/null
+
+#zipup the project (take that!)
+no_oops: clean
+	cd .. ; cvs commit 
+	echo Scanning for scratch/dirty files
+	find . -type f | grep -v CVS | xargs -n 1 bash mess.sh
+
+zipup: no_oops docs
+	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
+	cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; \
+	cd libtomcrypt-$(VERSION) ; rm -rf `find . -type d | grep CVS | xargs` ; cd .. ; \
+	tar -cjvf crypt-$(VERSION).tar.bz2 libtomcrypt-$(VERSION) ; \
+	zip -9r crypt-$(VERSION).zip libtomcrypt-$(VERSION) ; \
+	gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip ; \
+	mv -fv crypt* ~ ; rm -rf libtomcrypt-$(VERSION)
+
+
+# $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
+# $Revision: 1.70 $ 
+# $Date: 2005/06/19 18:03:24 $ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/TODO	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,10 @@
+For 1.06
+
+1. export ECC functions globally [e.g. mulmod and the sets]
+   - goal is tv_gen module and test vectors
+2. ASN.1 SET and T61String
+3. phase out DH code [RSA/ECC/DSA is enough]
+4. Some ASN.1 demo programs [for now read the source code!]
+5. Start working towards making the bignum code plugable
+6. Look into other ECC point muls and consider a "precomp" interface 
+7. Add OID for ciphers and PRNGs to their descriptors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/build.sh	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,20 @@
+#!/bin/bash
+echo "$1 ($2, $3)..."
+make clean 1>/dev/null 2>/dev/null
+echo -n "building..."
+CFLAGS="$2 $CFLAGS" make -j3 -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1)
+echo -n "testing..."
+if [ -a test ] && [ -f test ] && [ -x test ]; then
+   ((./test >test_std.txt 2>test_err.txt && ./tv_gen > tv.txt) && echo "$1 test passed." && echo "y" > testok.txt) || (echo "$1 test failed" && cat test_err.txt && exit 1)
+   if find *_tv.txt -type f 1>/dev/null 2>/dev/null ; then
+      for f in *_tv.txt; do if (diff $f notes/$f) then true; else (echo "tv_gen $f failed" && rm -f testok.txt && exit 1); fi; done
+   fi
+fi
+if [ -a testok.txt ] && [ -f testok.txt ]; then
+   exit 0
+fi
+exit 1
+
+# $Source: /cvs/libtom/libtomcrypt/build.sh,v $   
+# $Revision: 1.5 $   
+# $Date: 2005/06/27 13:04:05 $ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/changes	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,1326 @@
+June 27th, 2005
+v1.05
+      -- Added Technote #6 which covers the current PK compliance.  
+      -- Fixed buffer overflow in OAEP decoder
+      -- Added CHOICE to the list of ASN.1 types
+      -- Added UTCTIME to the list of ASN.1 types
+      -- Added MUTEX locks around descriptor table functions [but not on the functions that are dependent on them]
+         All functions call *_is_valid() before using a descriptor index which means the respective table must be unlocked before 
+         it can be accessed.  However, during the operation [e.g. CCM] if the descriptor has been altered the results will be 
+         undefined.  
+      -- Minor updates to the manual to reflect recent changes
+      -- Added a catch to for an error that should never come up in rsa_exptmod().  Just being thorough.
+
+June 15th, 2005
+v1.04
+      -- Fixed off by one [bit] error in dsa_make_key() it was too high by one bit [not a security problem just inconsistent]
+      -- ECC-224 curve was wrong [it was an ok curve just not NIST, so no security flaw just interoperability].
+      -- Removed point compression since it slows down ECC ops to save a measly couple bytes.
+         This makes the ecc export format incompatible with 1.03 [it shouldn't change in the future]
+      -- Removed ECC-160 from timing and added the other curves
+
+June 9th, 2005
+v1.03
+      -- Users may want to note that on a P4/GCC3.4 platform "-fno-regmove" greatly accelerates the ciphers/hashes.
+      --------------------------------------------------------------------------------------------------------------
+      -- Made it install the testing library in the icc/static makefiles
+      -- Found bug in ccm_memory.c which would fail to compile when LTC_CLEAN_STACK was enabled
+      -- Simon Johnson proposed I do a fully automated test suite.  Hence "testme.sh" was born
+      -- Added LTC_NO_TEST which forces test vectors off (regardless of what tomcrypt_custom.h has)
+      -- Added LTC_NO_TABLES which disables large tables (where possible, regardless of what tomcrypt_custom.h has)
+      -- New test script found a bug in twofish.c when TABLES was disabled.  Yeah testing!
+      -- Added a LTC_FAST specific test to the testing software.
+      -- Updated test driver to actually halt on errors and just print them out (useful for say... automated testing...)
+      -- Added bounds checking to Pelican MAC
+      -- Added BIT and OCTET STRING to the ASN.1 side of things.  
+      -- Pekka Riikonen pointed out that my ctr_start() function should accept the counter mode. 
+      -- Cleaned up warnings in testprof
+      -- Removed redundant mu and point mapping in ecc_verify_hash() so it should be a bit faster now
+      -- Pekka pointed out that the AES key structure was using 32 bytes more than it ought to.
+      -- Added quick defines to remove entire classes of algorithms.  This makes it easier if you want to build with just 
+         one algorithm (say AES or SHA-256).  Defines are LTC_NO_CIPHERS, LTC_NO_MODES, LTC_NO_HASHES, LTC_NO_MACS,
+         LTC_NO_PRNGS, LTC_NO_PK, LTC_NO_PKCS
+      -- As part of the move for ECC to X9.62 I've changed the signature algorithm to EC DSA.  No API changes.
+      -- Pekka helped me clean up the PKCS #1 v2.1 [OAEP/PSS] code
+      -- Wrote new DER SEQUENCE coder/decoder
+      -- RSA, DSA and ECDSA now use the DER SEQUENCE code (saves a lot of code!)
+      -- DSA output is now a DER SEQUENCE (so not compatible with previous releases).  
+      -- Added Technote #5 which shows how to build LTC on an AMD64 to have a variety of algorithms in only ~80KB of code.
+      -- Changed temp variable in LOAD/STORE macros to "ulong32" for 32-bit ops.  Makes it safer on Big endian platforms
+      -- Added INSTALL_GROUP and INSTALL_USER which you can specify on the build to override the default USER/GROUP the library 
+         is to be installed as
+      -- Removed "testprof" from the default build.  
+      -- Added IA5, NULL and Object Identifier to the list of ASN.1 DER supported types
+      -- The "no_oops" target (part of zipup) now scans for non-cvs files.  This helps prevent temp/scratch files from appearing in releases ;-)
+      -- Added DERs for missing hashes, but just the OID not the PKCS #1 v1.5 additions. 
+      -- Removed PKCS #1 v1.5 from the tree since it's taking up space and you ought to use v2.1 anyways
+      -- Kevin Kenny pointed out a few stray // comments
+      -- INTEGER code properly supports negatives and zero padding [Pekka!]
+      -- Sorted asn1/der/ directory ... less of a mess now ;-)
+      -- Added PRINTABLE STRING type
+      -- Removed ECC-160 as it wasn't a standard curve
+      -- Made ecc_shared_secret() ANSI X9.63 compliant
+      -- Changed "printf" to "fprintf(stderr, " in the testbench... ;-)
+      -- Optimized the GCM table creation.  On 1KB packets [with key switching] the new GCM is 12.7x faster than before.
+      -- Changed OID representation for hashes to be just a list of unsigned longs (so you can compare against them nicely after decoding a sequence)
+      -- ECC code now uses Montgomery reduction ... it's even faster [ECC-256 make key down from 37.4M to 4.6M cycles on an Athlon64]
+      -- Added SHORT_INTEGER so users can easily store DER encoded INTEGER types without using the bignum math library
+      -- Fixed OMAC code so that with LTC_FAST it doesn't require that LTC_FAST_TYPE divides 16 [it has to divide the block size instead]
+      -- ECC key export is now a simple [and documented] SEQUENCE, the "encrypt_key" also uses a new SEQUENCE format.
+      -- Thanks goes to the following testers
+            Michael Brown             - Solaris 10/uSPARCII
+            Richard Outerbridge       - MacOS
+            Martin Carpenter          - Solaris 8/uSPARCII [Thanks for cleaning up the scripts]
+            Greg Rose                 -  ... SunOS 5.8/SPARC [... what's with the SPARCS?]
+            Matt Johnston             - MacOS X  [Thanks for pointing out GCC 4 problems with -Os]
+
+April 19th, 2005
+v1.02
+      -- Added LTC_TEST support to gcm_test()
+      -- "pt/ct" can now be NULL in gcm_process() if you are processing zero bytes
+      -- Optimized GCM by removing the "double copy" handling of the plaintext/aad
+      -- Richard Outerbridge pointed out that x86_prof won't build on MACOS and that the manual 
+         erroneously refers to "mycrypt" all over the place.  Fixed.
+
+April 17th, 2005
+v1.01
+       ** Secure Science Corporation has supported this release cycle by sponsoring the development time taken.  Their 
+          continuing support of this project has helped me maintain a steady pace in order to keep LibTomCrypt up to date,
+          stable and more efficient.
+       -----------------------------------------------------------------------------------------------------
+       -- Updated base64_decode.c so if there are more than 3 '=' signs it would stop parsing
+       -- Merged in latest mpi that fixed a few bugs here and there
+       -- Updated OAEP encoder/decoder to catch when the hash output is too large
+          Cleaned up PSS code too
+       -- Andy Bontoft fixed a bug in my demos/tests/makefile.msvc ... seems "dsa_test.c" isn't an object
+          afterall.  Thanks.
+       -- Made invalid ECC key sizes (configuration) not hard fault the program (it returns an error code now)
+       -- SAFER has been re-enabled after I was pointed to http://www.ciphersbyritter.com/NEWS2/95032301.HTM
+          [Mark Kotiaho]
+       -- Added CCM mode to the encauth list (now has EAX, OCB and CCM, c'est un treo magnifique!)
+       -- Added missing ASN.1 header to the RSA keys ... oops... now the rsa_export/import are FULLY compatible
+          with other libs like OpenSSL (comment:  Test vectors would go a long way RSA...)
+       -- Manually merged in fix to the prime_random_ex() LTM function that ensures the 2nd MSB is set properly.  Now
+          When you say "I want a 1024/8 byte RSA key" the MSB bit of the modulus is set as expected.  Note I generally 
+          don't view this as a "huge issue" but it's just one less nit to worry about. [Bryan Klisch]
+       -- A new CVS has been setup on my Athlon64 box... if you want developer access send me an email (and at this point the email would have to be awesome).
+       -- Updated API for ECB and CBC shell code.  Now can process N whole blocks in one call (like $DEITY intended)
+       -- Introduced a new "hardware accel" framework that can be used to speed up cipher ECB, CBC and CTR mode
+          calls.  Later on dependent code (e.g. OMAC, CCM) will be re-written to use the generic cbc/ctr functions.  But now
+          if you [say] call ctr_encrypt() with a cipher descriptor that has hardware CTR it will automatically
+          be used (e.g. no code rewrites)
+       -- Now ships with 20% more love.
+       -- x86_prof now uses ECB shell code (hint: accelerators) and outputs cycles per BLOCK not byte.  This will make it a bit 
+          easier to compare hardware vs. software cipher implementations.  It also emits timings for CBC and CTR modes
+       -- [Peter LaDow] fixed a typo w.r.t. XREALLOC macro (spelling counts kids!)
+       -- Fixed bug with __x86_64__ where ROL64/ROR64 with LTC_NO_ROLC would be the 32-bit versions instead...
+       -- Shipping with preliminary GCM code (disabled).  It's buggy (stack overflow hidden somewhere).  If anyone can spot it let me know.
+       -- Added Pelican MAC [it's an AES based fast MAC] to the list of supported MACs
+       -- Added LTC_FAST [and you can disable by defining LTC_NO_FAST] so that CBC and CTR mode XOR whole words [e.g. 32 or 64 bits] at a time
+          instead of one byte.  On my AMD64 this reduced the overhead for AES-128-CBC from 4.56 cycles/byte to around 1 cycle/byte.  This requires
+          that you either allow unaligned read/writes [e.g. x86_32/x86_64] or align all your data.  It won't go out of it's way to ensure 
+          aligned access.  Only enabled for x86_* platforms by default since they allow unaligned read/writes.
+       -- Added LTC_FAST support to PMAC (drops the cycle/byte by about 9 cycles on my AMD64) [note: I later rewrote this prior to release]
+       -- Updated "profiled" target to work with the new directory layout
+       -- Added [demo only] optimized RC5-CTR code to x86_prof demo to show off how to make an accelerator
+          [This has been removed prior to release... It may re-appear later]
+       -- Added CCM acelerator callbacks to the list [now supports ECB, CTR, CBC and now CCM].
+       -- Added chapter to manual about accelerators (you know you want it)
+       -- Added "bswap" optimizations to x86 LOAD/STORE with big endian.  Can be disabled by defining LTC_NO_BSWAP
+       -- LTC_NO_ASM is now the official "disable all non-portable stuff" macro.  When defined it will make the code endian-neutral,
+          disable any form of ASM and disable LTC_FAST load/stores.  Essentially build the library with this defined if you're having
+          trouble building the library (old GCCs for instance dislike the ROLc macro)
+       -- Added tomcrypt_mac.h and moved MAC/encMAC functions from tomcrypt_hash.h into it
+       -- Added "done" function to ciphers and the five chaining modes [and things like omac/pmac/etc]
+       -- Changed install group to "wheel" from "root".
+       -- Replaced // comments with /**/ so it will build on older UNIX-like platforms
+       -- x86_prof builds and runs with IntelCC fine now 
+       -- Added "stest" build to intel CC to test static linked from within the dir (so you don't have to install to test)
+       -- Moved testing/benchmark into testprof directory and build it as part of the build.  Now you can link against libtomcrypt_prof.a to get 
+          testing info (hint: hardware developers ;-) )
+       -- Added CCM to tv_gen 
+       -- Added demos to MSVC makefile
+       -- Removed -funroll-all-loops from GCC makefile and replaced with -funroll-loops which is a bit more sane (P4 ain't got much cache for the IDATA)
+       -- Fixed GCM prior to release and re-enabled it.  It has not been optimized but it does conform when compiled with optimizations.
+       -- I've since optimized GCM and CCM.  They're close in speed but GCM is more flexible imho (though EAX is more flexible than both)
+       -- For kicks I optimized the ECC code to use projective points.  Gets between 3.21x (Prescott P4) to 4.53x (AMD64) times faster than before at 160-bit keys and the
+          speedup grows as the keysize grows.  Basically removing most practical reasons to "not use the ECC code".  Enjoy.
+       -- Added LTC_FAST support to OMAC/PMAC and doubled it's speed on my amd64 [faster on the P4 too I guess]
+       -- Added GCM to tv_gen
+       -- Removed "makefile.cygwin_dll" as it's not really used by anyone and not worth the effort (hell I hardly maintain the MSVC makefiles ...)
+       -- Updated a few files in the "misc" directory to have correct @file comments for doxygen
+       -- Removed "profile" target since it was slower anyways (go figure...)
+
+December 31st, 2004
+v1.00  
+       -- Added "r,s == 0" check to dsa_verify_hash()
+       -- Added "multi block" helpers for hash, hmac, pmac and omac routines so you can process multiple non-adjacent
+          blocks of data with one call (added demos/multi.c to make sure they work)
+          -- Note these are not documented but they do have doxygen comments inside them
+          -- Also I don't use them in other functions (like pkcs_5_2()) because I didn't have the time.  Job for the new LTC maintainer ;-)
+       -- Added tweaked Anubis test vectors and made it default (undefined ANUBIS_TWEAK to get original Anubis)
+       -- Merged in fix for mp_prime_random_ex() to deal with MSB and LSB "bugs"
+       -- Removed tim_exptmod() completely, updated several RSA functions (notably v15 and the decrypt/verify) so they 
+          don't require a prng now
+       -- This release brought to you by the fine tunes of Macy Gray.  We miss you.
+
+December 23rd, 2004
+v1.00rc1
+       -- Renamed "mycrypt_*" to "tomcrypt_*" to be more specific and professional
+          Now just include "tomcrypt.h" instead of "mycrypt.h" to get LTC ;-)
+       -- Cleaned up makefiles to ensure all headers are correctly installed
+       -- Added "rotate by constant" macros for portable, x86-32 and x86-64
+          You can disable this new code with LTC_NO_ROLC which is useful for older GCCs
+       -- Cleaned up detection of x86-64 so it works for ROL/ROR macros
+       -- Fixed rsa_import() so that it would detect multi-prime RSA keys and error appropriately
+       -- Sorted the source files by category and updated the makefiles appropriately
+       -- Added LTC_DER define so you can trim out DER code if not required
+       -- Fixed up RSA's decrypt functions changing "res" to "stat" to be more in sync
+          with the signature variables nomenclature. (no code change just renamed the arguments)
+       -- Removed all labels starting with __ and replaced with LBL_ to avoid namespace conflicts (Randy Howard)
+       -- Merged in LTM fix to mp_prime_random_ex() which zap'ed the most significant byte if the bit size
+          requested was a multiple of eight.
+       -- Made RSA_TIMING off by default as it's not terribly useful [and likely to be deprecated]
+       -- Renamed SMALL_CODE, CLEAN_STACK and NO_FILE to have a LTC_ prefix to avoid namespace collisions
+          with other programs.  e.g. SMALL_CODE => LTC_SMALL_CODE
+       -- Zed Shaw pointed out that on certain systems installing libs as "root" isn't possible as the super-user
+          is not root.  Now the makefiles allow this to be changed easily.
+       -- Renamed "struct _*_descriptor" to "struct ltc_*_descriptor" to avoid using a leading _
+          Also renamed _ARGCHK to LTC_ARGCHK
+       -- Zed Shaw pointed out that I still defined the prng structs in tomcrypt_prng.h even if they 
+          weren't defined.  This made undef'ing FORTUNA break the build.
+       -- Added LTC_NO_ASM to disable inline asm macros [ROL/ROR/etc]
+       -- Changed RSA decrypt functions to change the output length variable name from "keylen" to "outlen" to make 
+          it more consistent.
+       -- Added the 64-bit Khazad block cipher [NESSIE]
+       -- Added the 128-bit Anubis block cipher [with key support for 128...320 bit keys] [NESSIE]
+       -- Changes to several MAC functions to rename input arguments to more sensible names
+       -- Removed FAST_PK support from dh_sys.c
+       -- Declared deskey() from des.c as static instead of a global
+       -- Added pretty much all practical GCC warning tests to the GCC [related] makefiles.  These additional
+          warnings can easily be disabled for those with older copies of GCC [or even non GNU cc's]
+       -- Added doxygen @ tags to the code...  phew that was a hell of a lot of [repetitive] work
+       -- Also added pre-configured Doxygen script.
+       -- Cleaned up quite a few functions [ciphers, pk, etc] to make the parameters naming style consistent
+          E.g. ciphers keys are called "skey" consistently now.  The input to PK encryption is called "in", etc.
+          These changes require no code changes on the behalf of developers fortunately
+       -- Started a SAFER+ optimizer [does encrypt only] which shaves a good 30 or so cycles/byte on my AMD64
+          at an expense of huge code.  It's in notes/etc/saferp_optimizer.c
+       -- DSA sign/verify now uses DER encoded output/inputs and no LTC style headers.  
+       -- Matt Johnston found a missing semi-colon in mp_exptmod().  Fix has been merged in.  
+
+October 29th, 2004
+v0.99  -- Merged in the latest version of LTM which includes all of the recent bug fixes
+       -- Deprecated LTMSSE and removed it (to be replaced with TFM later on)
+       -- Stefan Arentz pointed out that mp_s_rmap should be extern
+       -- Kristian Gjøsteen pointed out that there are typos in the 
+          "test" makefile and minor issues in Yarrow and Sober [just cosmetics really]
+       -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword 
+          so changed the PRNG api to use "pexport" and "pimport"
+       -- Updated "hashsum" demo so it builds ;-)
+       -- Added automatic support for x86-64 (will configure for 64-bit little endian automagically)
+       -- Zhi Chen pointed out a bug in rsa_exptmod which would leak memory on error. 
+       -- Made hash functions "init" return an int.  slight change to API ;-(
+       -- Added "CHC" mode which turns any cipher into a hash the other LTC functions can use
+       -- Added CHC mode stuff to demos such as tv_gen and hashsum
+       -- Added "makefile.shared" which builds and installs shared/static object copies
+          of the library.
+       -- Added DER for bignum support 
+       -- RSA is now fully joy.  rsa_export/rsa_import use PKCS #1 encodings and should be 
+          compatible with other crypto libs that use the format.
+       -- Added support for x86-64 for the ROL/ROR macros 
+       -- Changed the DLL and SO makefiles to optimize for speed, commented SMALL_CODE in
+          mycrypt_custom.h and added -DSMALL_CODE to the default makefile
+       -- Updated primality testing code so it does a minimum of 5 tests [of Miller-Rabin]
+          (AFAIK not a security fix, just warm fuzzies)
+       -- Minor updates to the OMAC code (additional __ARGCHK and removed printf from omac_test... oops!)
+       -- Update build and configuration info which was really really really out of date.  (Chapter 14)
+       ++ Minor update, switch RSA to use the PKCS style CRT
+
+August 6th, 2004
+v0.98  -- Update to hmac_init to free all allocated memory on error
+       -- Update to PRNG API to fix import/export functions of Fortuna and Yarrow
+       -- Added test functions to PRNG api, RC4 now conforms ;-) [was a minor issue]
+       -- Added the SOBER-128 PRNG based off of code donated by Greg Rose.
+       -- Added Tech Note #4 [notes/tech0004.txt] 
+       -- Changed RC4 back [due to request].  It will now XOR the output so you can use it like 
+          a stream cipher easily.
+       -- Update Fortuna's export() to emit a hash of each pool.  This means that the accumulated 
+          entropy that was spread over all the pools isn't entirely lost when you export/import.
+       -- Zhi Chen suggested a comment for rsa_encrypt_key() to let users know [easily] that it was
+          PKCS #1 v2.0 padding.  (updated other rsa_* functions)
+       -- Cleaned up Noekeon to remove unrolling [wasn't required, was messy and actually slower with GCC/ICC]
+       -- Updated RC4 so that when you feed it >256 bytes of entropy it quietly ignores additional
+          bytes.  Also removed the % from the key setup to speed it up a bit.
+       -- Added cipher/hash/prng tests to x86_prof to help catch bugs while testing
+       -- Made the PRNG "done" return int, fixed sprng_done to not require prng* to be non-null
+       -- Spruced up mycrypt_custom.h to trap more errors and also help prevent LTMSSE from being defined
+          on non-i386 platforms by accident.
+       -- Added RSA/ECC/DH speed tests to x86_prof and cleaned it up to build with zero warnings
+       -- Changed Fortuna to count only entropy [not the 2 byte header] added to pool[0] into the 
+          reseed mechanism.  
+       -- Added "export_size" member to prng_descriptor tables so you can know in advance the size of 
+          the exported state for any given PRNG.  
+       -- Ported over patch on LTM 0.30 [not ready to release LTM 0.31] that fixes bug in mp_mul()/mp_div()
+          that used to result in negative zeroes when you multiplied zero by a negative integer.  
+          (patch due to "Wolfgang Ehrhardt" <[email protected]>)
+       -- Fixed rsa_*decrypt_key() and rsa_*verify_hash() to default to invalid "stat" or "res".  This way
+          if any of the higher level functions fail [before you get to the padding] the result will be in
+          a known state].  Applied to both v2 and v1.5 padding helpers.
+       -- Added MACs to x86_prof
+       -- Fixed up "warnings" in x86_prof and tv_gen
+       -- Added a "profiled" target back [for GCC 3.4 and ICC v8].  Doesn't seem to help but might be worth
+          tinkering with.
+       -- Beefed up load/store test in demos/test
+
+       ++ New note, in order to use the optimized LOAD/STORE macros your platform
+          must support unaligned 32/64 bit load/stores.  The x86s support this
+          but some [ARM for instance] do not.  If your platform cannot perform
+          unaligned operations you must use the endian neutral code which is safe for 
+          any sort of platform.
+
+July 23rd, 2004
+v0.97b -- Added PKCS #1 v1.5 RSA encrypt/sign helpers (like rsa_sign_hash, etc...)
+       -- Added missing prng check to rsa_decrypt_key() [not critical as I don't use 
+          descriptors directly in that function]
+       -- Merged in LTM-SSE, define LTMSSE before you build and you will get SSE2 optimized math ;-)
+          (roughly 3x faster on a P4 Northwood).  By default it will compile as ISO C portable
+          code (when LTMSSE is undefined).
+       -- Fixed bug in ltc_tommath.h where I had the kara/toom cutoffs not marked as ``extern''
+          Thanks to "Stefan Arentz" <stefan at organicnetwork.net>
+       -- Steven Dake <[email protected]> and Richard Amacker <[email protected]> submitted patches to 
+          fix pkcs_5_2().  It now matches the output of another crypto library.  Whoops... hehehe
+       -- Updated PRNG api.  Added Fortuna PRNG to the list of supported PRNGs
+       -- Fixed up the descriptor tables since globals are automatically zero'ed on startup.
+       -- Changed RC4 to store it's output.  If you want to encrypt with RC4
+          you'll have to do the XOR yourself.
+       -- Fixed buffer overflows/overruns in the HMAC code.  
+
+       ++ API change for the PRNGs there now is a done() function per PRNG.  You
+          should call it when you are done with a prng state.  So far it's
+          not absolutely required (won't cause problems) but is a good idea to
+          start.  
+
+
+June 23rd, 2004
+v0.97a ++ Fixed several potentially crippling bugs... [read on]
+       -- Fixed bug in OAEP decoder that would incorrectly report 
+          buffer overflows. [Zhi Chen]
+       -- Fixed headers which had various C++ missing [extern "C"]'s
+       -- Added "extern" to sha384_desc descriptor which I removed by mistake
+       -- Fixed bugs in ENDIAN_BIG macros using the wrong byte order [Matt Johnston]
+       -- Updated tiger.c and des.c to not shadow "round" which is intrinsic on
+          some C compilers.
+       -- Updated demos/test/rsa_test.c to test the RSA functionality better
+       ++ This update has been tested with GCC [v3.3.3], ICC [v8] and MSVC [v6+SP6] 
+          all on a x86 P4  [GCC/ICC tested in Gentoo Linux, MSVC in WinXP]
+       ++ Outcome: The bug Zhi Chen pointed out has been fixed.  So have the bugs
+          that Matt Johnston found.  
+
+June 19th, 2004
+v0.97  -- Removed spurious unused files [arrg!]
+       -- Patched buffer overflow in tim_exptmod()
+       -- Fixed buffer overrun bug in pkcs_1_v15_es_decode()
+       -- Reduced stack usage in PKCS #1 v2.0 padding functions (by several KBs)
+       -- Removed useless extern's that were an artifact from the project start... ;-)
+       -- Replaced memcpy/memset with XMEMCPY and XMEMSET for greater flexibility
+       -- fixed bugs in hmac_done()/hmac_init()/[various others()] where I didn't trap errors 
+       -- Reduced stack usage in OMAC/PMAC/HMAC/EAX/OCB/PKCS#5 by mallocing any significant sized
+          arrays (e.g. > 100 bytes or so).  Only in non-critical functions (e.g. eax_init())
+       -- "Zhi Chen" <[email protected]> pointed out that rsa_decrypt_key() requires
+          an incorrect output size (too large).  Fixed.
+       -- Added a "pretty" target to the GCC makefile.  Requires PERL.  It is NEAT!
+       -- Minor updates to ch1 of the manual.
+       -- Cleaned up the indentation and added comments to rsa_make_key(), rsa_exptmod() and 
+          rsa_verify_hash()
+       -- Updated makefile.icc so the "install" target would work ;-)
+       -- Removed demos/test.c [deprecated from demos/test/test.c]
+       -- Changed MAXBLOCKSIZE from 128 to 64 to reflect the true size...
+
+May 30th, 2004
+v0.96  -- Removed GF and Keyring code
+       -- Extended OAEP decoder to distinguish better [and use a more uniform API]
+       -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments)
+       -- rsa_exptmod() now pads with leading zeroes as per I2OSP.
+       -- added error checking to yarrow code
+       --  pointed out that tommath.h from this distro will overwrite tommath.h
+          from libtommath.  I changed this to ltc_tommath.h to avoid any such problems.
+       -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly
+       -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space.
+       -- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-)
+       -- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used.
+       -- replaced old RSA code with new code that uses PKCS #1 v2.0 padding
+       -- replaced old test harness with new over-engineer'ed one in /demos/test/
+       -- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying.
+       -- Added PKCS #1 v1.5 RSA encryption and signature padding routines
+       -- Added DER OID's to most hash descriptors (as many as I could find) 
+       -- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations 
+          added #define RSA_TIMING which can turn on/off this feature.
+       -- No more config.pl so please just read mycrypt_custom.h for build-time tweaks
+       -- Small update to rand_prime()
+       -- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined.  If you want speed though,
+          you're going to have to undefine SMALL_CODE ;-)
+       -- Worked over AES so that it's even smaller now [in both modes].
+       
+May 12th, 2004
+v0.95  -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact
+          the transforms are circulant.  AES dropped 5KB and WHIRLPOOL dropped 13KB
+          using the default build options on the x86.
+       -- Updated eax so the eax_done() would clear the state [like hmac,pmac,ocb] when
+          CLEAN_STACK has been defined.
+       -- added LTC_TEST support to rmd160
+       -- updates to mycrypt_pk.h
+       -- updated rand_prime() to faciliate making RSA composites 
+       -- DSA/RSA now makes composites of the exact size desired.
+       -- Refactored quite a bit of the code, fewer functions per C file
+       -- cleaned up the makefiles to organize the objects logically
+       -- added ICC makefile along with "profiled" targets for both GNU and ICC compilers
+       -- Marked functions for removal before v1.00 see PLAN for more information
+       -- GCC 3.4.0 tested and seems to work
+       -- Added PKCS #5 support
+       -- Fixed typo in comment header of .C files  ;-)
+       -- Added PKCS #1 OAEP and PSS support.  
+       
+Feb 20th, 2004
+v0.94  -- removed unused variables from ocb.c and fixed it to match known test vectors.
+       -- Added PMAC support, minor changes to OMAC/EAX code [I think....]
+       -- Teamed up with Brian Gladman.  His code verifies against my vectors and my code
+          verifies against his test vectors.  Hazaa for co-operation!
+       -- Various small changes (added missing ARGCHKs and cleaned up indentation)
+       -- Optimization to base64, removed unused variable "c"
+       -- Added base64 gen to demos/tv_gen.c
+       -- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird...
+       -- Fixed up all of the PK code by adding missing error checking, removed "res" variables,
+          shrunk some stack variables, removed non-required stack variables and added proper
+          error conversion from MPI to LTC codes.  I also spotted a few "off by one" error
+          checking which could have been used to force the code to read past the end of
+          the buffer (in theory, haven't checked if it would work) by a few bytes.
+       -- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I 
+          also modded it so it stores in the output provided to the function (that is not on
+          the local stack) which saves memory and time.
+       -- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later)
+       -- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my
+          Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte].  This code uses the 
+          teams new sbox design (not the original NESSIE one).
+      
+
+Jan 25th, 2004
+v0.93  -- [note: deleted v0.93 changes by accident... recreating from memory...]
+       -- Fix to RC2 to not deference pointer before ARGCHK
+       -- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit
+       -- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish
+       -- Fix to OMAC to test cipher block size first [prevents wasting any time]
+       -- Added more OMAC test vectors
+       -- Added EAX Encrypt+Authenticate support
+       -- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin]
+       -- Added common headers to all C files
+       -- CTR mode supports big and little [default] endian counters now.  
+       -- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table.
+       -- added find_hash_any() akin to find_cipher_any().
+       -- Added EAX code to demos/tv_gen.c  Hazaa! 
+       -- Removed SONY defines and files from codebase.
+       -- Added OCB support [patents be damned] and to demos/tv_gen.c
+       -- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h
+       -- Made appropriate changes to the debug string in crypt.c
+
+Dec 24th, 2003
+v0.92  -- Updated the config.pl script so the options have more details.
+       -- Updated demos/tv_gen to include RIPEMD hashes
+       -- Updated Twofish so when TWOFISH_ALL_TABLES is defined a pre-computed RS table
+          is included [speedup: slight, about 4k cycles on my Athlon].
+       -- Re-wrote the twofish large key generation [the four 8x32 key dependent tables].  Now about twice as fast.
+          With both optimizations [e.g. TWOFISH_ALL_TABLES defined] a 128-bit Twofish key can now be scheduled
+          in 26,000 cycles on my Athlon XP [as opposed to 49,000 before] when optimized for size.
+       -- config.pl has been updated so rmd128.o and rmd160.o are objects included in the build [oops]
+       -- Andrew Mann found a bug in rsa_exptmod() which wouldn't indicate if the wrong type of key was specified
+          (e.g. not PK_PRIVATE or PK_PUBLIC)
+       -- Fixed up demos/x86_prof so it sorts the output now :-)  
+       -- The project is now powered by radioactive rubber pants.
+       -- Fixed dh_encrypt_key() so if you pass it a hash with a smaller output than the input key it 
+          will return CRYPT_INVALID_HASH [to match what ecc_encrypt_key() will do]
+       -- Merge the store/encrypt key part of ecc_encrypt_key() as per dh_encrypt_key() [can you guess what I'm upto?]
+       -- Massive updates to the prime generation code.  I use the LTM random prime functions [and provide a nice 
+          interface between the LTC PRNG's and the LTM generic prng prototype].  I also use a variable number of tests
+          depending on the input size.  This nicely speeds up most prime generation/testing within the library.
+       -- Added SHA-224 to the list of hashes.
+       -- Made HMAC test vectors constant and static [takes ROM space instead of RAM]
+       -- This release was brought to you by the letter P which stands for Patent Infringement.
+       -- Added generic HASH_PROCESS macro to mycrypt_hash.h which simplifies the hash "process" functions
+          I also optimized the compression functions of all but MD2 to not perform input copies when avoidable.
+       -- Removed the division from the Blowfish setup function [dropped 3k cycles on my Athlon]
+       -- Added stack cleaning to rijndael, cast5 so now all ciphers have CLEAN_STACK code.  
+       -- Added Skipjack to the list of ciphers [made appropriate changes to demos/test.c, demos/tv_gen.c and 
+          demos/x86_prof.c]
+       -- Added mechanical testing to cipher test vector routines.  Now it encrypts 1000 times, then decrypts and
+          compares.  Any fault (e.g. bug in code, compiler) in the routines is likely to show through.  Doesn't
+          stress test the key gen though...
+       -- Matt Johnson found a bug in the blowfish.c  apparently I was out of my mind and put twofish defines in there 
+          The code now builds with any config.  Thanks.
+       -- Added OMAC1 Message Authentication Code support to the library.
+       -- Re-prototyped the hash "process" and "done" to prevent buffer overflows [which don't seem easy to exploit].  
+          Updated HMAC code to use them too.  Hazaa!
+       -- Fixed bug in ECC code which wouldn't do an _ARGCHK on stat in ecc_verify_hash().
+       -- Fixed [temp fix] bug in all PK where the OUTPUT_BIGNUM macros would not trap errors on the to_unsigned_bin 
+          conversion [now returns CRYPT_MEM, will fix it up better later]
+       -- Added DSA to the list of supported PK algorithms.  
+       -- Fixed up various ciphers to &255 the input key bytes where required [e.g. where used to index a table] to prevent
+          problems on platforms where CHAR_BIT != 8 
+       -- Merged in LibTomMath v0.28
+       -- Updated demos/x86_prof.c to use Yarrow during the key sched testing [was horribly slow on platforms with blockable
+          /dev/random]. 
+       -- Added OMAC/HMAC tests to demos/tv_gen and I now store the output of this in notes/ 
+       -- Fixed a bug in config.pl that wouldn't have TWOFISH_TABLES defined by default (too many commas on the line)
+       -- Fixed bug in hmac_done().  Apparently FIPS-198 [HMAC] specifies that the output can be truncated.  My code
+          would not support that (does now just like the new OMAC code).
+       -- Removed "hashsize" from hmac_state as it wasn't being used.
+       -- Made demos/test.c stop if OMAC or HMAC tests fail (instead of just printing a failed message and keep going).
+       -- Updated notes/tech0003.txt to take into account the existence of Skipjack [also I fixed a few typos].
+       -- Slight changes to Noekeon, with SMALL_CODE undefined it uses a fully unrolled version.  Dropped +10 cycles/byte
+          on my Athlon (35 cycles per byte or 410.4Mbit/sec at 1795Mhz)
+       -- Added _ARGCHK() calls to is_prime() for the two input pointers.
+
+Sept 25th, 2003
+v0.91  -- HMAC fix of 0.90 was incorrect for keys larger than the block size of the hash.
+       -- Added error CRYPT_FILE_NOTFOUND for the file [hmac/hash] routines.
+       -- Added RIPEMD hashes to the hashsum demo.
+       -- Added hashsum demo to MSVC makefile.
+       -- Added RMD160 to the x86_prof demo [oops]
+       -- Merged in LibTomMath-0.27 with a patch to mp_shrink() that will be in LibTomMath-0.28
+          Fixes another potential memory leak.
+
+Sept 7th, 2003
+v0.90  -- new ROL/ROR for x86 GCC
+       -- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library
+          when not required.
+       == By default the KR code is not enabled [it's only a demo anyways!]
+       -- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes]
+       -- hmac_done() now requires you pass it the size of the destination buffer to prevent
+          buffer overflows.  (API CHANGE)
+       -- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined.
+       -- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default
+          configuration of LibTomMath.  Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size,
+
+768-bit,     4 vs.  10
+1024-bit,    8 vs.  18
+1280-bit,   12 vs.  34
+1536-bit,   20 vs.  56
+1792-bit    28 vs.  88
+2048-bit,   40 vs. 124
+2560-bit,   71 vs. 234
+3072-bit,  113 vs. 386
+4096-bit,  283 vs. 916
+
+          Times are all in milliseconds for key generation.  New primes times on the left.  This makes the code binary
+          incompatible with previous releases.  However, this addition is long overdue as LibTomMath has supported DR
+          reductions for quite some time.
+       -- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total].
+       -- The project has been released as public domain.  TDCAL no longer applies.
+
+July 15th, 2003
+v0.89  -- Fix a bug in bits.c which would prevent it from building with msvc
+       -- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!]
+       -- Removed the LTC version of next_prime() and replaced it with a call to the
+          mp_prime_next_prime() from LibTomMath
+       -- reverted bits.c to the 0.86 copy since the new one doesn't build in MSVC
+          or cygwin.
+
+Jul 10th, 2003
+v0.88  -- Sped up CAST5 key schedule for MSVC
+       -- added "ulong32" which allows people on 64-bit platforms to force the 32-bit tables in
+          ciphers like blowfish and AES to be 32-bits.  E.g. when unsigned long is 64-bits.
+       -- Optimized the SAFER-SK64, SAFER-SK128, SAFER+, RC5 and RC6 key schedule [big time!]
+       -- Optimized SHA-1 and SHA-256 quite a bit too.
+       -- Fixed up the makefile to use -fomit-frame-pointer more liberally
+       -- Added tv_gen program which makes test vectors for ciphers/hashes
+       -- Merged in LibTomMath v0.22
+       
+Jun 19th, 2003
+v0.87  -- Many MSVC optimizations to the code base
+       -- Improved the AES and Twofish key schedule [faster, more constant time]
+       -- Tons of optimizations here and there.  
+       
+Jun 15th, 2003
+v0.86  -- Fixed up AES to workaround MSVC optimizer bug
+       -- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC
+       -- Wrote x86_prof which will time the hashes and ciphers downto cycles per byte.
+       -- Fixed up demos/encrypt to remove serpent_desc from the list
+       -- Re-enabled MSVC optimizations w00t w00t
+       -- Replaced "errno" with "err" in all functions that had it so it wouldn't clash
+          with the global "errno"
+       -- Removed a set of unused variables from certain functions
+       -- Removed {#line 0 "..."} stuff from mpi.c to comply with ISO C  :-)
+       
+Jun 11th, 2003
+v0.85  -- Swapped in a new AES routine
+       -- Removed Serpent
+       -- Added TDCAL policy document
+       
+Jun 1st, 2003
+v0.84  -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
+       -- Fixed another potential buffer problem.  Not an overflow but could cause the 
+          PK import routines to read past the end of the buffer.
+       -- Optimized the ECC mulmod more by removing a if condition that will always be false
+       -- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime
+          test from LibTomMath now
+       -- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h]
+       -- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now].
+        
+
+Mar 29th, 2003
+v0.83  -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space
+       -- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL
+       -- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy
+          buffer overflow.
+       -- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return
+          errors now.
+       
+Mar 15th, 2003
+v0.82  -- Manual updated
+       -- Added MSVC makefile [back, actually its written from scratch to work with NMAKE]
+       -- Change to HMAC helper functions API to avoid buffer overflow [source changes]
+       -- the rsa_encrypt_key was supposed to reject key sizes out of bounds ... 
+          same fix to the rsa_sign_hash 
+       -- Added code to ensure that that chaining mode code (cfb/ofb/ctr/cbc) have valid
+          structures when being called.  E.g. the indexes to the pad/ivs are not out of bounds
+       -- Cleaned up the DES code and simplified the core desfunc routine.
+       -- Simplified one of the boolean functions in MD4
+       
+Jan 16th, 2003
+v0.81  -- Merged in new makefile from Clay Culver and Mike Frysinger
+       -- Sped up the ECC mulmod() routine by making the word size adapt to the input.  Saves a whopping 9 point
+          operations on 521-bit keys now (translates to about 8ms on my Athlon XP).  I also now use barrett reduction
+          as much as possible.  This sped the routine up quite a bit.
+       -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
+       -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
+          (fix due to Mika Boström)
+       -- Merged in LibTomMath for kicks
+       -- Changed the build process so that by default "mycrypt_custom.h" is included and provided
+          The makefile doesn't include any build options anymore
+       -- Removed the PS2 and VC makefiles.
+       
+Dec 16th, 2002
+v0.80  -- Found a change I made to the MPI that is questionable.  Not quite a bug but definately not desired.  Had todo
+          with the digit shifting.  In v0.79 I simply truncated without zeroing.  It didn't cause problems during my
+          testing but I fixed it up none the less.
+       -- Optimized s_mp_mul_dig() from MPI to do a minimal number of passes.
+       -- Fixed in rsa_exptmod() where I was getting the size of the result.  Basically it accomplishes the same thing
+          but the fixed code is more readable.
+       -- Fixed slight bug in dh_sign_hash() where the random "k" value was 1 byte shorter than it should have been.  I've
+          also made the #define FAST_PK speed up signatures as well.  Essentially FAST_PK tells the DH sub-system to 
+          limit any private exponent to 256-bits.   Note that when FAST_PK is defined does not make the library
+          binary or source incompatible with a copy of the library with it undefined.
+       -- Removed the DSA code.  If you want fast diffie-hellman just define FAST_PK :-)
+       -- Updated dh_sign_hash()/dh_verify_hash() to export "unsigned" bignums.  Saves two bytes but is not binary
+          compatible with the previous release... sorry!  I've performed the same fix to the ecc code as well.
+       -- Fixed up the PK code to remove all use of mp_toraw() and mp_read_raw() [get all the changes out of the way now]
+       -- Fixed a bug in the DH code where it missed trapping a few errors if they occurred.
+       -- Fixed a slight "its-not-a-bug-but-could-be-done-better" bug in the next_prime() function.  Essentially it was
+          testing to ensure that in the loop that searches for the next candidate that the step never grows beyond
+          65000.  Should have been testing for MP_DIGIT_MAX
+       -- Spruced up the config.pl script.  It now makes a header file "mycrypt_custom.h" which can be included *before*
+          you include mycrypt.h.  This allows you to add libtomcrypt to a project without completely changing your make
+          system around.  Note that you should use the makefile it writes to at least build the library initially.
+       -- Used splint to check alot of the code out.  Tons of minor fixes and explicit casts added.
+       -- Also made all the internal functions of MPI are now static to avoid poluting the namespace
+       -- **Notice**:  There are no planned future releases for at least a month from the this release date.
+       
+Dec 14th, 2002
+v0.79  -- Change to PK code [binary and source].  I made it so you have to pass the buffer size to the *_decrypt_key and
+          *_verify_hash functions.  This prevents malformed packets from performing buffer overflows.  I've also trimmed
+          the packet header size [by 4 bytes].
+       -- Made the test program halt on the first error it occurs.  Also made it trap more errors than before.
+       -- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website!
+       -- Included a perl script "config.pl" that will make "makefile.out" according to the users needs.  
+       -- Added shell script to look for latest release
+       -- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles
+       -- updated the makefile to use BSD friendly archiving invokations
+       -- Changed the DH and ECC code to use base64 static key settings [e.g. the primes].  Dropped the code size by 3KB
+          and is ever-so-slightly faster than before.
+       -- added "mp_shrink" function to shrink the size of bignums.  Specially useful for PK code :-)
+       -- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto
+          sized numbers].  Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of
+          heap todo the calculation.  Both are #define'able controlled
+       -- Added XREALLOC macro to provide realloc() functionality.
+       -- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's
+          not being used.
+       -- Fixed potential bug in the ECC code.  Only would occur on platforms where char is not eight bits [which isn't
+          often!]
+       -- Fixed up the ECC point multiplication, its about 15% faster now
+       -- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines
+          so they export as "unsigned" types saving 1 byte per bignum outputted.  Not a lot but heck why not.
+          
+Nov 28th, 2002
+v0.78  -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB.
+       -- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly.
+       -- Added Noekeon block cipher at 2,800 bytes of object code and 345Mbit/sec it is a welcome addition.
+       -- Made the KR code check if the other PK systems are included [provides error when building otherwise].
+       -- Made "aes" an alias for Rijndael via a pre-processor macro.  Now you can use "aes_ecb_encrypt", etc... :-)
+          Thanks to Jean-Luc Cooke for the "buzzword conformance" suggestion.
+       -- Removed the old PK code entirely (e.g. rsa_sign, dh_encrypt).  The *_sign_hash and *_encrypt_key functions
+          are all that is to remain.
+       -- **NOTE** Changed the PK *_import (including the keyring) routine to accept a "inlen" parameter.  This fixes a
+          bug where improperly made key packets could result in reading passed the end of the buffer.  This means
+          the code is no longer source compatible but still binary compatible.
+       -- Fixed a few other minor bugs in the PK import code while I was at it.
+       
+Nov 26th, 2002
+v0.77  -- Updated the XTEA code to use pre-computed keys.  With optimizations for speed it achieves 222Mbit/sec
+          compared to the 121Mbit/sec before.  It is 288 bytes bigger than before.
+       -- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes)
+       -- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys]
+       -- Removed most test cases from Blowfish, left three of them there.  Makes it smaller and faster to test.
+       -- Changed the primality routines around.  I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve
+          step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work.
+       -- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity.  This means
+          that a invalid value could have caused segfaults, etc...
+       -- **NOTE** Changed the way the ECC/DH export/import functions work.  They are source but not binary compatible
+          with v0.76.  Essentially insteading of exporting the setting index like before I export the key size.  Now
+          if you ever re-configure which key settings are supported the lib will still be able to make use of your 
+          keys.
+       -- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the 
+          rest.  It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before.  The new blowfish 
+          object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller.  So the code is both smaller and 
+          faster!
+       -- Optimized Twofish as well by inlining the round function.  Gets ~400Mbit/sec compared to 280Mbit/sec before
+          and the code is only 78 bytes larger than the previous copy.
+       -- Removed SMALL_PRIME_TAB build option.  I use the smaller table always.
+       -- Fixed some mistakes concerning prime generation in the manual.
+       -- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz]
+
+Nov 25th, 2002
+v0.76  -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size.  Got the lib
+          downto 265KB using GCC 3.2 on my x86 box.
+       -- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design.
+       -- Updated all other test vector routines to return as soon as an error is found
+       -- fixed a bug in the test program where errors in the hash test routines would not be reported
+          correctly.  I found this by temporarily changing one of the bytes of the test vectors.  All the
+          hashes check out [the demos/test.c would still have reported an error, just the wrong one].
+          
+
+Nov 24th, 2002
+v0.75  -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL
+       -- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would 
+          not be closed.
+       -- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code
+          In the next release "-Wconversion" will be enabled which will deal with all implicit casts.
+
+Nov 22nd, 2002 [later in the day]
+v0.74  -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms
+       -- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions]
+       -- Wrote a small variant of Rijndael (trimmed 13KB)
+       -- Trimmed the TIGER/192 hash function a bit
+       -- Overall the entire lib compiled is 295KB [down from 400KB before]
+       -- Fixed a few minor oversights in the MSVC makefile
+
+Nov 22nd, 2002
+v0.73  -- Fixed bug in RC4 code where it could only use 255 byte keys.
+       -- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it...
+       -- Removed the ecc compress/expand points from the global scope.  Reduces namespace polution
+       -- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be
+          able todo since the SPRNG has no state...
+       -- Corrected some oversights in the manual and the examples...
+       -- By default the GF(2^W) math library is excluded from the build.  The source is maintained because I wrote it
+          and like it :-).  This way the built library is a tad smaller
+       -- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized.
+
+Nov 21th, 2002
+v0.72  -- Fixed bug in the prime testing.  In the Miller-Rabin test I was raising the base to "N-1" not "r".
+          The math still worked out fine because in effect it was performing a Fermat test.  Tested the new code and it 
+          works properly
+       -- Fixed some of the code where it was still using the old error syntax
+       -- Sped up the RSA decrypt/sign routines
+       -- Optimized the ecc_shared_secret routine to not use so much stack
+       -- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip
+          to
+
+Nov 19th, 2002
+v0.71  -- HELP TOM.  I need tuition for the January semester.  Now I don't want to force donations [nor will I ever]
+          but I really need the help!  See my website http://tom.iahu.ca/help_tom.html for more details.  Please help
+          if you can! 
+       --------------------------------------------------------------------------------------------------------------
+       -- Officially the library is no longer supported in GCC 3.2 in windows [cygwin].
+          In windows you can either use GCC 2.95.3 or try your luck with 3.2  It seems that
+          "-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???]
+          If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2"
+       -- Started new error handling API.  Similar to the previous except there are more error codes than just
+          CRYPT_ERROR
+       -- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!]
+       -- Merged in more changes from Sky Schulz.  I have to make mention here that he has been a tremendous help in 
+          getting me motivated to make some much needed updates to the library!
+       -- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards
+       -- Fixed a bug in the RC4 code [wasn't setting up the key correctly]
+       -- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...)
+       -- Fixed numerous bugs in the PK code.  Essentially I was "freeing" keys when the import failed.  This is neither
+          required nor a good a idea [double free].  
+       -- Tom needs a job.
+       -- Fixed up the test harness as requested by Sky Schulz.  Also modifed the timing routines to run for X seconds
+          and count # of ops performed.  This is more suitable than say encrypting 10 million blocks on a slow processor
+          where it could take minutes!
+       -- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax
+       -- Removed the PKCS code since it was incomplete.  In the future I plan on writing a "add-on" library that
+          provides PKCS support... 
+       -- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h  
+       -- Willing to work on an hourly basis for 15$ CDN per hour.
+       -- updated the test program to not test ciphers not included
+       -- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...]
+       -- fixed numerous failures to detect buffer overflows [minor] in the PK code.
+       -- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup
+          function
+       -- check out my CV at http://tom.iahu.ca/cv.html
+       -- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...]
+       -- merged in rudimentary [for testing] PS2 RNG from Sky Schulz
+       -- merged in PS2 timer code [only shell included due to NDA reasons...]
+       -- updated HMAC code to return errors where possible
+       -- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt]
+
+Nov 12th, 2002
+v0.70  -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz)
+       -- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h
+       -- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?]
+       -- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz....
+       -- Added support for substituting out the clock() function (Sky Schulz)
+       -- Fixed up makefile to include new headers in the HEADERS variable
+       -- Removed "coin.c" as its not really useful anyways
+       -- Removed many "debug" printfs that would show up on failures.  Basically I wanted to ensure the only output
+          would be from the developer themselves.
+       -- Added "rc4.c" a RC4 implementation with a PRNG interface.  Since RC4 isn't a block cipher it wouldn't work
+          too well as a block cipher.
+       -- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code
+       -- updated makefile to make subdirectory properly (Sku Schulz)
+       -- Started towards new API setup.  Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK"
+          In future releases functions will return things other than CRYPT_ERROR on error to give more useful
+          thread safe error reporting.  The manual will be updated to reflect this.  For this release all
+          errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change.         
+       -- Removed the zlib branch since its not really required anyways.  Makes the package smaller
+
+Nov 11th, 2002
+v0.69  -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers
+       -- Note I forgot to change the CRYPT version tag in v0.68... fixed now.
+
+Nov 8th, 2002
+v0.68  -- Fixed flaw in kr_import/kr_export that wasted 4 bytes.  Source but not binary compatible with v0.67
+       -- Fixed bug in kr_find_name that used memcmp to match strings.  Uses strncmp now.
+       -- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing]
+       -- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt.
+       -- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the
+          respective ciphers can use.  
+       -- Fixed a bug in hashsum demo that would report the hash for files that don't exist!
+
+Oct 16th, 2002
+v0.67  -- Moved the function prototypes into files mycrypt_*.h.  To "install" the lib just copy all the 
+          header files "*.h" from the base of this project into your global include path.
+       -- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int"
+       -- Added keyring support for the PK functions
+       -- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key.  Basically
+          move the first argument to the next to last.
+       -- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group
+       -- replaced the primes in the DH code with new ones that are larger than the size they are 
+          associated with.  That is a 1024-bit DH key will have a 1025-bit prime as the modulus
+       -- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66]
+       -- major editing of the manual, started Docer program
+       -- added 160 and 224 bit key settings for ECC.  This makes the DH and ECC binary wise incompatible with v0.66
+       -- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit
+       -- Removed ID_TAG from all files [meh, not a big fan...]
+       -- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo
+       -- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start()
+       -- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls
+          Returns int now instead of void.
+
+Sept 24th, 2002
+v0.66  -- Updated the /demos/test.c program to time the hashes correctly.  Also it uses the yarrow PRNG for all of the 
+          tests meaning its possible to run on RNG less platforms 
+       -- Updated the /demos/hashsum.c program to hash from the standard input
+       -- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same
+          time.
+       -- Dan Kaminsky suggested some cleanups for the code and the MPI config
+          Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want
+          to read the stuff you'll have to convert it 
+       -- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed
+
+Sept 20th, 2002
+v0.65  -- Wayne Scott ([email protected]) made a few of suggestions to improve the library.  Most 
+          importantly he pointed out the math lib is not really required.  He's also tested the lib on 18 
+          different platforms.  According to him with only a few troubles [lack of /dev/random, etc] the 
+          library worked as it was supposed to.  You can find the list at 
+          http://www.bitkeeper.com/Products.BitKeeper.Platforms.html
+       -- Updated the hash_file and hash_memory functions to keep track of the size of the output
+       -- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more
+       -- Modified the mycrypt_cfg.h to autodetect x86-32 machines
+
+Sept 19th, 2002
+v0.64  -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally]
+       -- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages
+       -- fixed more typos in the manual
+       -- removed all unused variables from the core library (ignore the ID_TAG stuff)
+       -- added "const char *crypt_build_settings" string which is a build time constant that gives a listing
+          of all the build time options.  Useful for debugging since you can send that to me and I will know what 
+          exactly you had set for the mycrypt_cfg.h file.
+       -- Added control over endianess.  Out of the box it defaults to endianess neutral but you can trivially 
+          configure the library for your platform.  Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my 
+          Athlon box.  See "mycrypt_cfg.h" for more information.
+
+Sept 11th, 2002
+v0.63  -- Made hashsum demo output like the original md5sum program 
+       -- Made additions to the examples in the manual (fixed them up a bunch)
+       -- Merged in the base64 code from Wayne Scott ([email protected])
+
+Aug 29th, 2002
+v0.62  -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update.
+
+Aug 9th, 2002
+v0.61  -- Fixed a bug in the DES code [oops I read something wrong].
+
+Aug 8th, 2002
+v0.60  -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V.
+
+Aug 7th, 2002
+v0.59  -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC.
+       -- Cleaned up a little in the makefile
+       -- added code that times the hash functions too in the test program
+
+Aug 3rd, 2002
+v0.58  -- Added more stack cleaning conditionals throughout the code.  
+       -- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK
+       -- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message
+          now they only make one call to ctr_encrypt()/ctr_decrypt().
+
+Aug 2nd, 2002
+v0.57  -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name.
+       -- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a
+          key size.  By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that 
+          down if required.
+       -- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus).
+       -- The padding method for RSA is more clearly documented.  Namely if you want to encrypt/sign something of length
+          N then your modulus must be of length 1+3N.  So to sign a message with say SHA-384 [48 bytes] you need a 
+          145 byte (1160 bits) modulus.  This is all in the manual now.
+       -- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every
+          cipher/hash call
+       -- Sped up the hash "process()" functions by not copying one byte at a time.
+       ++ (added just after I uploaded...)
+          MD4 process() now handles input buffers > 64 bytes
+
+Aug 1st, 2002
+v0.56  -- Cleaned up the comments in the Blowfish code.
+       -- Oh yeah, in v0.55 I made all of the descriptor elements constant.  I just forgot to mention it.
+       -- fixed a couple of places where descriptor indexes were tested wrong.  Not a huge bug but now its harder
+          to mess up.
+       -- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library.
+       -- Added the RC2 block cipher to the library.
+       -- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers
+          can use them with less confusion.
+
+July 29th, 2002
+v0.55  -- My god stupid Blowfish has yet again been fixed.  I swear I hate that cipher.  Next bug in it and boom its out of the
+          library.  Use AES or something else cuz I really hate Blowfish at this stage....
+       -- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!]
+
+July 19th, 2002
+v0.54  -- Blowfish now conforms to known test vectors.  Silly bad coding tom!
+       -- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before]
+
+July 18th, 2002
+v0.53  -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)]
+       -- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code
+          with an invalid index ever now.
+       -- Simplified the Yarrow code once again :-)
+
+July 12th, 2002
+v0.52  -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512.  Now MD4 will work with
+          all the routines...
+       -- Fixed the comments in SHA-512 to be a bit more meaningful
+       -- In md4 I made the PADDING array const [again to store it in ROM]
+       -- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer
+       -- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1
+       -- Fixed a logical error in the CTR code which would make it skip the first IV value.  This means
+          the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more
+          sense this way.
+       -- Added {} braces for as many if/for/blocks of code I could find.  My rule is that every for/if/while/do block
+          must have {} braces around it.
+       -- made the rounds table in saferp_setup const [again for the ROM think about the ROM!]
+       -- fixed RC5 since it no longer requires rc5 to be registered in the lib.  It used to since the descriptors used to 
+          be part of the table...
+       -- the packet.c code now makes crypt_error literal string errors when an error occurs
+       -- cleaned up the SAFER+ key schedule to be a bit easier to read.
+       -- fixed a huge bug in Twofish with the TWOFISH_SMALL define.  Because I clean the stack now I had
+          changed the "g_func()" to be called indirectly.  I forgot to actually return the return of the Twofish
+          g_func() function which caused it not to work... [does now :-)]
+
+July 11th, 2002
+v0.51  -- Fixed a bug in SHA512/384 code for multi-block messages.
+       -- Added more test vectors to the SHA384/512 and TIGER hash functions
+       -- cleaned up the hash done routines to make more sense
+ 
+July 10th, 2002
+v0.50  -- Fixed yarrow.c so that the cipher/hash used would be registered.  Also fixed
+          a bug where the SAFER+ name was "safer" but should have been "safer+".
+       -- Added an element to the hash descriptors that gives the size of a block [sent into the compressor]
+       -- Cleaned up the support for HMAC's
+       -- Cleaned up the test vector routines to make the test vector data const.  This means on some platforms it will be
+          placed in ROM not RAM now.
+       -- Added MD4 code submited by Dobes Vandermeer ([email protected])
+       -- Added "burn_stack" function [idea taken from another source of crypto code].  The idea is if a function has
+          alot of variables it will clean up better.  Functions like the ecb serpent and twofish code will now have their
+          stacks cleaned and the rest of the code is getting much more straightforward.
+       -- Added a hashing demo by Daniel Richards ([email protected])
+       -- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style.
+          For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec.
+       -- Fixed the register/unregister functions to properly report errors in crypt_error
+       -- Correctly updated yarrow code to remove a few unused variables.
+       -- Updated manual to fix a few erroneous examples.
+       -- Added section on Hash based Message Authentication Codes (HMAC) to the manual
+
+June 19th, 2002
+v0.46  -- Added in HMAC code from Dobes Vandermeer ([email protected])
+
+June 8th, 2002
+v0.45  -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause
+          undefined behaviour.
+       -- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key.
+       -- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h
+
+Apr 4th, 2002
+v0.44  -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it.
+
+Mar 22nd, 2002
+v0.43  -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug.  
+       -- Updated the GCC makefile not to use -O3 or -funroll-loops
+       -- Version tag in mycrypt.h has been updated :-)
+
+Mar 10th, 2002
+v0.42  -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste)
+
+Mar 3rd, 2002
+v0.41  -- Added support to link and use ciphers at compile time.  This can greatly reduce the code size!
+       -- Added a demo to show off how small an application can get... 46kb!
+       -- Disastry pointed out that Blowfish is supposed to be high endian.
+       -- Made registry code for the PRNGs as well [now the smallest useable link is 43kb]
+
+Feb 11th, 2002
+v0.40  -- RSA signatures use [and check for] fixed padding scheme.
+       -- I'm developing in Linux now :-)
+       -- No more warnings from GCC 2.96
+
+Feb 5th, 2002
+v0.39  -- Updated the XTEA code to work in accordance with the XTEA design
+
+January 24th, 2002
+v0.38  -- CFB and OFB modes can now handle blocks of variable size like the CTR code
+       -- Wrote a wrapper around the memory compress functions in Zlib that act like the functions
+          in the rest of my crypto lib
+
+January 23rd, 2002
+v0.37  -- Added support code so that if a hash size and key size for a cipher don't match up they will
+          use the next lower key supported.  (mainly for the PK code).  So you can now use SHA-1 with
+          Twofish, etc...
+       -- Added more options for Twofish.  You can now tell it to use precomputed sboxes and MDS multiplications
+          This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes.
+       -- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB
+       -- Fixed all of the PK packet code to use the same header format [see packet.c].  This makes the PK code
+          binary wise incompatible with previous releases while the API has not changed at all.
+
+January 22nd, 2002
+v0.36  -- Corrections to the manual
+       -- Made a modification to Twofish which lets you build a "small ram" variant.  It requires
+          about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal 
+          variant requires.
+       -- Reduced the stack space used in all of the PK routines.
+
+January 19th, 2002
+v0.35  -- If you removed the first hash or cipher from the library it wouldn't return an error if 
+          you used an ID=0 [i.e blowfish or sha256] in any routine.  Now it checks for that and will
+          return an error like it should
+       -- Merged in new routines from Clay Culver.  These routines are for the PK code so you can easily 
+          encode a symmetric key for multiple recipients.
+       -- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed.
+          Originally I wanted to ensure that the keys were smaller than the order of the field used
+          However, the bias is so insignifcant using full sizes.  For example, with a ECC-192 key the order
+          is about 2^191.99, so instead I rounded down and used a 184-bit secret key.  Now I simply use a full 192-bit
+          key the code will work just the same except that some 192-bit keys will be duplicates which is not a big
+          deal since 1/2^192 is a very small bias!
+       -- Made the configuration a bit simpler and more exacting.  You can for example now select which DH or ECC
+          key settings you wish to support without including the data for all other key settings.  I put the #defines
+          in a new file called "mycrypt_cfg.h"
+       -- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used
+       -- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues.  The yarrow code will now
+          use what ever remaining hash/cipher combo is left [after you #undef them] at build time.   He also suggested
+          a fix to remove unused structures from the symmetric_key and hash_state unions.
+       -- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can
+          encrypt messages any size block at a time.
+       -- Simplified the yarrow code to take advantage of the new CTR code.
+       -- Added a 4096-bit DH key setting.  That took me about 36 hours to find!
+       -- Changed the base64 routines to use a real base64 encoding scheme.
+       -- Added in DH and ECC "encrypt_key()" functions.  They are still rather "beta"ish.
+       -- Added **Twofish** to the list of ciphers!
+
+January 18th, 2002
+v0.34  -- Added "sha512" to the list of hashes.  Produces a 512-bit message digest.  Note that with the current
+          padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures.
+       -- Cleaned up the other hash functions to use the LOAD and STORE macros...
+
+January 17th, 2002
+v0.33  -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't
+          work with the padding scheme and large symmetric keys.
+       -- Added information concerning the Zlib license to the manual
+       -- Added a 3072-bit key setting for the DH code.
+       -- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion.
+       -- Fixed an embarassing typo in the manual concerning the hashes.  Thank's Clay for finding it!
+       -- Fixed rand_prime() so that it makes primes bigger than the setting you give.  For example,
+          if you want a 1024-bit prime it would make a 1023-bit one.  Now it ensures that the prime
+          it makes is always greater than 2^(8n) (n == bytes in prime).  This doesn't have a huge
+          impact on security but I corrected it just the same.
+       -- Fixed the CTR routine to work on platforms where char != 8-bits 
+       -- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries
+          I "AND" with 0xFFFFFFFF.  That forces only the lower 32-bits to have information in it.  On x86 platforms
+          most compilers optimize out the AND operation since its a nop.
+
+January 16th, 2002
+v0.32  -- Made Rijndael's setup function fully static so it is thread safe
+       -- Svante Seleborg suggested a cosmetic style fixup for aes.c, 
+          basically to remove some of the #defines to clean it up
+       -- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes
+          the PK message formats *incompatible* with previous releases.
+       -- Merge in Zlib :-)
+ 
+  
+January 15th, 2002
+v0.31  -- The RSA routines can now use CRT to speed up decryption/signatures.  The routines are backwards 
+          compatible with previous releases.
+       -- Fixed another bug that Svante Seleborg found.  Basically you could buffer-overrun the 
+          rsa_exptmod() function itself if you're not careful.  That's fixed now.  Fixed another bug in
+          rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used 
+          memory.       
+       -- improved the readability of the PK import/export functions
+       -- Added a fix to RSA.C by Clay Culver
+       -- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64".
+
+January 14th, 2002
+v0.30  -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found.
+          Basically if you added entropy to the pool in small increments it could in fact
+          cancel out.  Now I hash the pool with the new data which is way smarter.
+
+January 12th, 2002
+v0.29  -- Added MPI code written by Svante Seleborg to the library.  This will make the PK code much
+          easier to follow and debug.  Actually I've already fixed a memory leak in dh_shared_secret().
+       -- Memory leaks found and correct in all three PK routines.  The leaks would occur when a bignum
+          operation fails so it wouldn't normally turn up in the course of a program
+       -- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es
+
+January 11th, 2002
+v0.28  -- Cleaned up some code so that it doesn't assume "char == 8bits".  Mainly SAFER+ has been 
+          changed.
+       -- ***HUGE*** changes in the PK code.  I check all return values in the bignum code so if there
+          are errors [insufficient memory, etc..] it will be reported.  This makes the code fairly more
+          robust and likely to catch any errors.
+       -- Updated the is_prime() function to use a new prototype [it can return errors now] and it also
+          does trial divisions against more primes before the Rabin Miller steps
+       -- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations.
+       -- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation.
+          I should note that there is not alot of concrete information about the cipher.  "Ansi C" versions
+          I found did not address endianess and were not even portable!.  This code is portable and to the
+          best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper.
+       -- Reformated the manual to include the **FULL** source code optimized to be pritable.
+
+January 9th, 2002
+v0.27  -- Changed the char constants to numerical values.  It is backwards compatible and should work on
+          platforms where 'd' != 100 [for example].
+       -- Made a change to rand_prime() which takes the input length as a signed type so you can pass
+          a negative len to get a "3 mod 4" style prime... oops
+       -- changed the MSVC makefile to build with a warning level of three, no warnings!
+
+January 8th, 2002
+v0.26  -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt
+          the output
+       -- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions.
+       -- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int()
+          I added a work around that catches the error and continues normally.
+
+January 8th, 2002
+v0.25  -- Added a stupid define so MSVC 6.00 can build the library.
+       -- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC
+
+January 7th, 2002
+v0.24  -- Sped up Blowfish by unrolling and removing the swaps.
+       -- Made the code comply with more traditional ANSI C standards
+          Should compile with MSVC with less errors
+       -- moved the demos and documentation into their own directories
+          so you can easily build the library with other tool chains
+          by compiling the files in the root
+       -- converted functions with length of outputs to use 
+          "unsigned long" so 16-bit platforms will like this library more.
+
+January 5th, 2002
+v0.23  -- Fixed a small error in the MPI config it should build fine anywhere.
+
+January 4th, 2002
+v0.22  -- faster gf_mul() code
+       -- gf_shl() and gf_shr() are safe on 64-bit platforms now
+       -- Fixed an error in the hashes that Brian Gladman found.  
+          Basically if the message has exactly 56 bytes left to be 
+          compressed I handled them incorrectly.
+
+January 4th, 2002
+v0.21  -- sped up the ECC code by removing redundant divisions in the 
+          point add and double routines.  I also extract the bits more
+          efficiently in "ecc_mulmod()" now.
+       -- sped up [and documented] the rand_prime() function.  Now it just
+          makes a random integer and increments by two until a prime is found
+          This is faster since it doesn't require alot of calls to the PRNG and
+          it doesn't require loading huge integers over and over.  rand_prime()
+          can also make primes congruent to 3 mod 4 [i.e for a blum integer]
+       -- added a gf_sqrt() function that finds square roots in a GF(2^w) field
+       -- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator
+          divisor than the dividend.
+
+January 4th, 2002
+v0.20  -- Added the fixed MPI back in so RSA and DH are much faster again
+
+v0.19  -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code.
+       -- DH, ECC and RSA signature/decryption functions check if the key is private
+       -- new DH signature/verification code works just like the RSA/ECC versions
+
+January 3rd, 2002
+v0.18  -- Added way more comments to each .C file 
+       -- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer]
+       -- fixed RC5 so it reads the default rounds out of the cipher_descriptor table
+       -- cleaned up ecc_export()
+       -- Cleaned up dh_import() and ecc_import() which also perform more 
+          error checking now
+       -- Fixed a serious flaw in rsa_import() with private keys.
+
+January 2nd, 2002
+v0.17  -- Fixed a bug in the random prime generator that fixes the wrong bits to one
+       -- ECC and DH code verify that the moduli and orders are in fact prime.  That 
+          slows down the test routines alot but what are you gonna do? 
+       -- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some
+          values of p.  I replaced it with a slow function.  Once the author of MPI fixes his faster routine
+          I will switch back.
+  
+January 1st, 2002 [whoa new year!]
+v0.16  -- Improved GF division code that is faster.
+       -- documented the GF code
+
+December 31st, 2001
+v0.15  -- A 1792-bit and 2048-bit DH setting was added.  Took me all night to 
+          find a 1792 and 2048-bit strong prime but what the heck
+       -- Library now has polynomial-basis GF(2^w) routines I wrote myself.  Can be used to perform
+          ECC over GF(2^w) later on....
+       -- Fixed a bug with the defines that allows it to build in windows
+       
+December 30th, 2001
+v0.14  -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size 
+          for the cipher used.  It was defaulting to making a 256-bit IV...
+       -- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed...
+       -- spell checked the manual again... :-)
+
+December 30th, 2001
+v0.13  -- Switching back to older copy of MPI since it works! arrg..
+       -- Added sign/verify functions for ECC
+       -- all signature verification routines default to invalid signatures.
+       -- Changed all calls to memset to zeromem.  Fixed up some buffer problems 
+          in other routines.  All calls to zeromem let the compiler determine the size
+          of the data to wipe.
+
+December 29th, 2001
+v0.12  -- Imported a new version of MPI [the bignum library] that should
+          be a bit more stable [if you want to write your own bignum
+          routines with the library that is...]
+       -- Manual has way more info
+       -- hash_file() clears stack now [like it should]
+       -- The artificial cap on the hash input size of 2^32 bits has been
+          removed.  Basically I was too lazy todo 64-bit math before
+          [don't ask why... I can't remember].  Anyways the hashes
+          support the size of 2^64 bits [if you ever use that many bits in a message
+          that's just wierd...]
+       -- The hashes now wipe the "hash_state" after the digest is computed.  This helps
+          prevent the internal state of the hash being leaked accidently [i.e stack problems]
+
+December 29th, 2001
+v0.11  -- Made #define's so you can trim the library down by removing
+          ciphers, hashs, modes of operation, prngs, and even PK algorithms
+          For example, the library with rijndael+ctr+sha1+ECC is 91KB compared
+          to the 246kb the full library takes.
+       -- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to
+          the RSA packet routines.
+       -- ECC now compresses the public key, a ECC-192 public key takes 33 bytes 
+          for example....
+
+December 28th, 2001
+v0.10  -- going to restart the manual from scratch to make it more 
+          clear and professional
+       -- Added ECC over Z/pZ.  Basically provides as much as DH
+          except its faster since the numbers are smaller.  For example,
+          A comparable 256-bit ECC key provides as much security as expected
+          from a DH key over 1024-bits.
+       -- Cleaned up the DH code to not export the symbol "sets[]"
+       -- Fixed a bug in the DH code that would not make the correct size 
+          random string if you made the key short.  For instance if you wanted 
+          a 512-bit DH key it would make a 768-bit one but only make up 512-bits 
+          for the exponent... now it makes the full 768 bits [or whatever the case 
+          is]
+       -- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit
+          keys by mistake.
+
+December 25th, 2001
+v0.09  -- Includes a demo program called file_crypt which shows off
+          how to use the library to make a command line tool which
+          allows the user to encode/decode a file with any
+          hash (on the passphrase) and cipher in CTR mode.
+       -- Switched everything to use typedef's now to clear up the code.
+       -- Added AES (128/192 and 256 bit key modes)
+
+December 24th, 2001
+v0.08  -- fixed a typo in the manual. MPI stores its bignums in
+          BIG endian not little.
+       -- Started adding a RNG to the library.  Right now it tries
+          to open /dev/random and if that fails it uses either the 
+          MS CSP or the clock drift RNG.  It also allows callbacks 
+          since the drift RNG is slow (about 3.5 bytes/sec)
+       -- the RNG can also automatically setup a PRNG as well now
+
+v0.07  -- Added basic DH routines sufficient to 
+          negotiate shared secrets 
+          [see the manual for a complete example!]
+       -- Fixed rsa_import to detect when the input
+          could be corrupt.  
+       -- added more to the manual.
+
+December 22nd, 2001
+v0.06  -- Fixed some formatting errors in 
+          the hash functions [just source code cleaning]
+       -- Fixed a typo in the error message for sha256 :-)
+       -- Fixed an error in base64_encode() that 
+          would fail to catch all buffer overruns
+       -- Test program times the RSA and symmetric cipher 
+          routines for kicks...
+       -- Added the "const" modifier to alot of routines to 
+          clear up the purpose of each function.
+       -- Changed the name of the library to "TomCrypt" 
+          following a suggestion from a sci.crypt reader....
+
+v0.05  -- Fixed the ROL/ROR macro to be safe on platforms 
+          where unsigned long is not 32-bits
+       -- I have added a bit more to the documentation 
+          manual "crypt.pdf" provided.
+       -- I have added a makefile for LCC-Win32.  It should be 
+          easy to port to other LCC platforms by changing a few lines.
+       -- Ran a spell checker over the manual.
+       -- Changed the header and library from "crypt" to "mycrypt" to not
+          clash with the *nix package "crypt".
+
+v0.04  -- Fixed a bug in the RC5,RC6,Blowfish key schedules
+          where if the key was not a multiple of 4 bytes it would
+          not get loaded correctly.
+
+December 21st, 2001
+
+v0.03  -- Added Serpent to the list of ciphers.
+
+v0.02  -- Changed RC5 to only allow 12 to 24 rounds
+       -- Added more to the manual.
+
+v0.01  -- We will call this the first version.
+
+/* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
+/* $Revision: 1.106 $ */
+/* $Date: 2005/06/27 12:37:06 $ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/crypt.tex	Tue Mar 21 16:20:59 2006 +0000
@@ -0,0 +1,4563 @@
+\documentclass[a4paper]{book}
+\usepackage{hyperref}
+\usepackage{makeidx}
+\usepackage{amssymb}
+\usepackage{color}
+\usepackage{alltt}
+\usepackage{graphicx}
+\usepackage{layout}
+\def\union{\cup}
+\def\intersect{\cap}
+\def\getsrandom{\stackrel{\rm R}{\gets}}
+\def\cross{\times}
+\def\cat{\hspace{0.5em} \| \hspace{0.5em}}
+\def\catn{$\|$}
+\def\divides{\hspace{0.3em} | \hspace{0.3em}}
+\def\nequiv{\not\equiv}
+\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
+\def\lcm{{\rm lcm}}
+\def\gcd{{\rm gcd}}
+\def\log{{\rm log}}
+\def\ord{{\rm ord}}
+\def\abs{{\mathit abs}}
+\def\rep{{\mathit rep}}
+\def\mod{{\mathit\ mod\ }}
+\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
+\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
+\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
+\def\Or{{\rm\ or\ }}
+\def\And{{\rm\ and\ }}
+\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
+\def\implies{\Rightarrow}
+\def\undefined{{\rm ``undefined"}}
+\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
+\let\oldphi\phi
+\def\phi{\varphi}
+\def\Pr{{\rm Pr}}
+\newcommand{\str}[1]{{\mathbf{#1}}}
+\def\F{{\mathbb F}}
+\def\N{{\mathbb N}}
+\def\Z{{\mathbb Z}}
+\def\R{{\mathbb R}}
+\def\C{{\mathbb C}}
+\def\Q{{\mathbb Q}}
+
+\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
+
+\def\gap{\vspace{0.5ex}}
+\makeindex
+\begin{document}
+\title{LibTomCrypt \\ Version 1.05}
+\author{Tom St Denis \\
+\\
[email protected] \\
+http://libtomcrypt.org
+}
+\maketitle
+This text and source code library are both hereby placed in the public domain.  This book has been 
+formatted for A4 paper using the \LaTeX{} {\em book} macro package.
+
+\vspace{15cm}
+
+\begin{flushright}Open Source.  Open Academia.  Open Minds.
+
+\mbox{ }
+
+Tom St Denis,
+
+Phone: 1-613-836-3160
+
+111 Banning Rd 
+
+Kanata, Ontario 
+
+K2L 1C3 
+
+Canada
+\end{flushright}
+\newpage
+\tableofcontents
+\chapter{Introduction}
+\section{What is the LibTomCrypt?}
+LibTomCrypt is a portable ISO C cryptographic library that is meant to be a toolset for cryptographers who are 
+designing a cryptosystem.  It supports symmetric ciphers, one-way hashes, pseudo-random number generators, 
+public key cryptography (via PKCS \#1 RSA, DH or ECCDH) and a plethora of support 
+routines.  
+
+The library was designed such that new ciphers/hashes/PRNGs can be added at runtime and the existing API 
+(and helper API functions) are able to use the new designs automatically.  There exists self-check functions for each 
+block cipher and hash function to ensure that they compile and execute to the published design specifications.  The library 
+also performs extensive parameter error checking to prevent any number of runtime exploits or errors.
+
+\subsection{What the library IS for?}
+
+The library serves as a toolkit for developers who have to solve cryptographic problems.  Out of the box LibTomCrypt
+does not process SSL or OpenPGP messages, it doesn't read x.591 certificates or write PEM encoded data.  It does, however,
+provide all of the tools required to build such functionality.  LibTomCrypt was designed to be a flexible library that 
+was not tied to any particular cryptographic problem.  
+
+\section{Why did I write it?}
+You may be wondering, ``Tom, why did you write a crypto library.  I already have one.''.  Well the reason falls into
+two categories:
+\begin{enumerate}
+    \item I am too lazy to figure out someone else's API.  I'd rather invent my own simpler API and use that.
+    \item It was (still is) good coding practice.
+\end{enumerate}
+
+The idea is that I am not striving to replace OpenSSL or Crypto++ or Cryptlib or etc.  I'm trying to write my 
+{\bf own} crypto library and hopefully along the way others will appreciate the work.
+
+With this library all core functions (ciphers, hashes, prngs) have the {\bf exact} same prototype definition.  They all load
+and store data in a format independent of the platform.  This means if you encrypt with Blowfish on a PPC it should decrypt
+on an x86 with zero problems.  The consistent API also means that if you learn how to use Blowfish with my library you 
+know how to use Safer+ or RC6 or Serpent or ... as well.  With all of the core functions there are central descriptor tables 
+that can be used to make a program automatically pick between ciphers, hashes and PRNGs at runtime.  That means your 
+application can support all ciphers/hashes/prngs without changing the source code.
+
+Not only did I strive to make a consistent and simple API to work with but I also strived to make the library
+configurable in terms of its build options.  Out of the box the library will build with any modern version of GCC
+without having to use configure scripts.  This means that the library will work with platforms where development
+tools may be limited (e.g. no autoconf).
+
+On top of making the build simple and the API approachable I've also strived for a reasonably high level of
+robustness and efficiency.  LibTomCrypt traps and returns a series of errors ranging from invalid
+arguments to buffer overflows/overruns.  It is mostly thread safe and has been clocked on various platforms
+with ``cycles per byte'' timings that are comparable (and often favourable) to other libraries such as OpenSSL and
+Crypto++.
+
+\subsection{Modular}
+The LibTomCrypt package has also been written to be very modular.  The block ciphers, one--way hashes and
+pseudo--random number generators (PRNG) are all used within the API through ``descriptor'' tables which 
+are essentially structures with pointers to functions.  While you can still call particular functions
+directly (\textit{e.g. sha256\_process()}) this descriptor interface allows the developer to customize their
+usage of the library.
+
+For example, consider a hardware platform with a specialized RNG device.  Obviously one would like to tap
+that for the PRNG needs within the library (\textit{e.g. making a RSA key}).  All the developer has to do
+is write a descriptor and the few support routines required for the device.  After that the rest of the 
+API can make use of it without change.  Similiarly imagine a few years down the road when AES2 
+(\textit{or whatever they call it}) has been invented.  It can be added to the library and used within applications 
+with zero modifications to the end applications provided they are written properly.
+
+This flexibility within the library means it can be used with any combination of primitive algorithms and 
+unlike libraries like OpenSSL is not tied to direct routines.  For instance, in OpenSSL there are CBC block
+mode routines for every single cipher.  That means every time you add or remove a cipher from the library
+you have to update the associated support code as well.  In LibTomCrypt the associated code (\textit{chaining modes in this case})
+are not directly tied to the ciphers.  That is a new cipher can be added to the library by simply providing 
+the key setup, ECB decrypt and encrypt and test vector routines.  After that all five chaining mode routines
+can make use of the cipher right away.
+
+\section{License}
+
+All of the source code except for the following files have been written by the author or donated to the project
+under a public domain license:
+
+\begin{enumerate}
+   \item rc2.c
+\end{enumerate}
+
+`mpi.c'' was originally written by Michael Fromberger ([email protected]) but has since been replaced with 
+my LibTomMath library which is public domain.
+
+``rc2.c'' is based on publicly available code that is not attributed to a person from the given source.  
+
+The project is hereby released as public domain.
+
+\section{Patent Disclosure}
+
+The author (Tom St Denis) is not a patent lawyer so this section is not to be treated as legal advice.  To the best
+of the authors knowledge the only patent related issues within the library are the RC5 and RC6 symmetric block ciphers.  
+They can be removed from a build by simply commenting out the two appropriate lines in ``tomcrypt\_custom.h''.  The rest
+of the ciphers and hashes are patent free or under patents that have since expired.
+
+The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations.  This means you can use 
+the ciphers you just can't advertise that you are doing so.  
+
+\section{Thanks}
+I would like to give thanks to the following people (in no particular order) for helping me develop this project from
+early on:
+\begin{enumerate}
+   \item Richard van de Laarschot
+   \item Richard Heathfield
+   \item Ajay K. Agrawal
+   \item Brian Gladman
+   \item Svante Seleborg
+   \item Clay Culver
+   \item Jason Klapste
+   \item Dobes Vandermeer
+   \item Daniel Richards
+   \item Wayne Scott
+   \item Andrew Tyler
+   \item Sky Schulz
+   \item Christopher Imes
+\end{enumerate}
+
+There have been quite a few other people as well.  Please check the change log to see who else has contributed from
+time to time.
+
+\chapter{The Application Programming Interface (API)}
+\section{Introduction}
+\index{CRYPT\_ERROR} \index{CRYPT\_OK}
+
+In general the API is very simple to memorize and use.  Most of the functions return either {\bf void} or {\bf int}.  Functions
+that return {\bf int} will return {\bf CRYPT\_OK} if the function was successful or one of the many error codes 
+if it failed.  Certain functions that return int will return $-1$ to indicate an error.  These functions will be explicitly
+commented upon.  When a function does return a CRYPT error code it can be translated into a string with
+
+\index{error\_to\_string()}
+\begin{verbatim}
+const char *error_to_string(int err);
+\end{verbatim}
+
+An example of handling an error is:
+\begin{verbatim}
+void somefunc(void)
+{
+   int err;
+   
+   /* call a cryptographic function */
+   if ((err = some_crypto_function(...)) != CRYPT_OK) {
+      printf("A crypto error occured, %s\n", error_to_string(err));
+      /* perform error handling */
+   }
+   /* continue on if no error occured */
+}
+\end{verbatim}
+
+There is no initialization routine for the library and for the most part the code is thread safe.  The only thread
+related issue is if you use the same symmetric cipher, hash or public key state data in multiple threads.  Normally
+that is not an issue.
+
+To include the prototypes for ``LibTomCrypt.a'' into your own program simply include ``tomcrypt.h'' like so:
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void) {
+    return 0;
+}
+\end{verbatim}
+
+The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and 
+``ltc\_tommath.h'' (the bignum library routines).
+
+\section{Macros}
+
+There are a few helper macros to make the coding process a bit easier.  The first set are related to loading and storing
+32/64-bit words in little/big endian format.  The macros are:
+
+\index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP}
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+     \hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\
+     \hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\
+     \hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\
+     \hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\
+     \hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\
+     \hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\
+     \hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\
+     \hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\
+     \hline BSWAP(x) & {\bf unsigned long} x & Swaps byte order (32--bits only) \\
+     \hline
+\end{tabular}
+\end{center}
+\end{small}
+
+There are 32 and 64-bit cyclic rotations as well:
+\index{ROL} \index{ROR} \index{ROL64} \index{ROR64} \index{ROLc} \index{RORc} \index{ROL64c} \index{ROR64c} 
+\begin{center}
+\begin{tabular}{|c|c|c|}
+     \hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\
+     \hline ROLc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 31$ \\
+     \hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 31$ \\
+     \hline RORc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 31$ \\
+     \hline && \\
+     \hline ROL64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 63$ \\
+     \hline ROL64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 63$ \\
+     \hline ROR64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 63$ \\
+     \hline ROR64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 63$ \\
+     \hline
+\end{tabular}
+\end{center}
+
+\section{Functions with Variable Length Output}
+Certain functions such as (for example) ``rsa\_export()'' give an output that is variable length.  To prevent buffer overflows you
+must pass it the length of the buffer\footnote{Extensive error checking is not in place but it will be in future releases so it is a good idea to follow through with these guidelines.} where
+the output will be stored.  For example:
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void) {
+    rsa_key key;
+    unsigned char buffer[1024];
+    unsigned long x;
+    int err;
+
+    /* ... Make up the RSA key somehow ... */
+
+    /* lets export the key, set x to the size of the output buffer */
+    x = sizeof(buffer);
+    if ((err = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
+       printf("Export error: %s\n", error_to_string(err));
+       return -1;
+    }
+    
+    /* if rsa_export() was successful then x will have the size of the output */
+    printf("RSA exported key takes %d bytes\n", x);
+
+    /* ... do something with the buffer */
+
+    return 0;
+}
+\end{verbatim}
+\end{small}
+In the above example if the size of the RSA public key was more than 1024 bytes this function would return an error code
+indicating a buffer overflow would have occurred.  If the function succeeds it stores the length of the output
+back into ``x'' so that the calling application will know how many bytes were used.
+
+\section{Functions that need a PRNG}
+\index{Pseudo Random Number Generator} \index{PRNG}
+Certain functions such as ``rsa\_make\_key()'' require a Pseudo Random Number Generator (PRNG).  These functions do not setup 
+the PRNG themselves so it is the responsibility of the calling function to initialize the PRNG before calling them.
+
+Certain PRNG algorithms do not require a ``prng\_state'' argument (sprng for example).  The ``prng\_state'' argument
+may be passed as \textbf{NULL} in such situations.
+
+\section{Functions that use Arrays of Octets}
+Most functions require inputs that are arrays of the data type ``unsigned char''.  Whether it is a symmetric key, IV
+for a chaining mode or public key packet it is assumed that regardless of the actual size of ``unsigned char'' only the
+lower eight bits contain data.  For example, if you want to pass a 256 bit key to a symmetric ciphers setup routine
+you must pass it in (a pointer to) an array of 32 ``unsigned char'' variables.  Certain routines 
+(such as SAFER+) take special care to work properly on platforms where an ``unsigned char'' is not eight bits.
+
+For the purposes of this library the term ``byte'' will refer to an octet or eight bit word.  Typically an array of
+type ``byte'' will be synonymous with an array of type ``unsigned char''.
+
+\chapter{Symmetric Block Ciphers}
+\section{Core Functions}
+
+LibTomCrypt provides several block ciphers with an ECB block mode interface.  It's important to first note that you 
+should never use the ECB modes directly to encrypt data.  Instead you should use the ECB functions to make a chaining mode
+or use one of the provided chaining modes.  All of the ciphers are written as ECB interfaces since it allows the rest of
+the API to grow in a modular fashion.
+
+\subsection{Key Scheduling}
+All ciphers store their scheduled keys in a single data type called ``symmetric\_key''.  This allows all ciphers to 
+have the same prototype and store their keys as naturally as possible.  This also removes the need for dynamic memory
+allocation and allows you to allocate a fixed sized buffer for storing scheduled keys.  All ciphers provide five visible 
+functions which are (given that XXX is the name of the cipher):
+\index{Cipher Setup}
+\begin{verbatim}
+int XXX_setup(const unsigned char *key, int keylen, int rounds,
+              symmetric_key *skey);
+\end{verbatim}
+
+The XXX\_setup() routine will setup the cipher to be used with a given number of rounds and a given key length (in bytes).
+The number of rounds can be set to zero to use the default, which is generally a good idea.
+
+If the function returns successfully the variable ``skey'' will have a scheduled key stored in it.  It's important to note
+that you should only used this scheduled key with the intended cipher.  For example, if you call ``blowfish\_setup()'' do not 
+pass the scheduled key onto ``rc5\_ecb\_encrypt()''.  All setup functions do not allocate memory off the heap so when you are 
+done with a key you can simply discard it (e.g. they can be on the stack).
+
+\subsection{ECB Encryption and Decryption}
+To encrypt or decrypt a block in ECB mode there are these two function classes
+\index{Cipher Encrypt} \index{Cipher Decrypt}
+\begin{verbatim}
+void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
+                     symmetric_key *skey);
+
+void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
+                     symmetric_key *skey);
+\end{verbatim}
+These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
+which cipher you are using.} and store the result where you want it.  It is possible that the input and output buffer are 
+the same buffer.  For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and 
+``ct''\footnote{ct stands for ciphertext.} is the output.  For the decryption function it's the opposite.  To test a particular 
+cipher against test vectors\footnote{As published in their design papers.} call the self-test function
+ 
+\subsection{Self--Testing}
+\index{Cipher Testing}
+\begin{verbatim}
+int XXX_test(void);
+\end{verbatim}
+This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is 
+based upon.  
+
+\subsection{Key Sizing}
+For each cipher there is a function which will help find a desired key size:
+\begin{verbatim}
+int XXX_keysize(int *keysize);
+\end{verbatim}
+Essentially it will round the input keysize in ``keysize'' down to the next appropriate key size.  This function
+return {\bf CRYPT\_OK} if the key size specified is acceptable.  For example:
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int keysize, err;
+
+   /* now given a 20 byte key what keysize does Twofish want to use? */
+   keysize = 20;
+   if ((err = twofish_keysize(&keysize)) != CRYPT_OK) {
+      printf("Error getting key size: %s\n", error_to_string(err));
+      return -1;
+   }
+   printf("Twofish suggested a key size of %d\n", keysize);
+   return 0;
+}
+\end{verbatim}
+\end{small}
+This should indicate a keysize of sixteen bytes is suggested.  
+
+\subsection{Cipher Termination}
+When you are finished with a cipher you can de--initialize it with the done function.
+\begin{verbatim}
+void XXX_done(symmetric_key *skey);
+\end{verbatim}
+For the software based ciphers within LibTomCrypt this function will not do anything.  However, user supplied
+cipher descriptors may require calls to it for resource management.  To be compliant all functions which call a cipher
+setup function must also call the respective cipher done function when finished.
+
+\subsection{Simple Encryption Demonstration}
+An example snippet that encodes a block with Blowfish in ECB mode is below.
+
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{ 
+   unsigned char pt[8], ct[8], key[8];
+   symmetric_key skey;
+   int err;
+
+   /* ... key is loaded appropriately in ``key'' ... */
+   /* ... load a block of plaintext in ``pt'' ... */
+
+   /* schedule the key */
+   if ((err = blowfish_setup(key,     /* the key we will use */
+                               8,     /* key is 8 bytes (64-bits) long */
+                               0,     /* 0 == use default # of rounds */
+                           &skey)     /* where to put the scheduled key */
+       ) != CRYPT_OK) {
+      printf("Setup error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* encrypt the block */
+   blowfish_ecb_encrypt(pt,             /* encrypt this 8-byte array */
+                        ct,             /* store encrypted data here */ 
+                        &skey);         /* our previously scheduled key */
+                        
+   /* now ct holds the encrypted version of pt */                        
+
+   /* decrypt the block */
+   blowfish_ecb_decrypt(ct,             /* decrypt this 8-byte array */
+                        pt,             /* store decrypted data here */
+                        &skey);         /* our previously scheduled key */
+
+   /* now we have decrypted ct to the original plaintext in pt */                        
+
+   /* Terminate the cipher context */
+   blowfish_done(&skey);
+
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+\section{Key Sizes and Number of Rounds}
+\index{Symmetric Keys}
+As a general rule of thumb do not use symmetric keys under 80 bits if you can.  Only a few of the ciphers support smaller
+keys (mainly for test vectors anyways).  Ideally your application should be making at least 256 bit keys.  This is not
+because you're supposed to be paranoid.  It's because if your PRNG has a bias of any sort the more bits the better.  For
+example, if you have $\mbox{Pr}\left[X = 1\right] = {1 \over 2} \pm \gamma$ where $\vert \gamma \vert > 0$ then the
+total amount of entropy in N bits is $N \cdot -log_2\left ({1 \over 2} + \vert \gamma \vert \right)$.  So if $\gamma$
+were $0.25$ (a severe bias) a 256-bit string would have about 106 bits of entropy whereas a 128-bit string would have
+only 53 bits of entropy.
+
+The number of rounds of most ciphers is not an option you can change.  Only RC5 allows you to change the number of
+rounds.  By passing zero as the number of rounds all ciphers will use their default number of rounds.  Generally the
+ciphers are configured such that the default number of rounds provide adequate security for the given block and key 
+size.
+
+\section{The Cipher Descriptors}
+\index{Cipher Descriptor}
+To facilitate automatic routines an array of cipher descriptors is provided in the array ``cipher\_descriptor''.  An element
+of this array has the following format:
+
+\begin{small}
+\begin{verbatim}
+struct _cipher_descriptor {
+   char *name;
+   unsigned char ID;
+   int  min_key_length, 
+        max_key_length, 
+        block_length, 
+        default_rounds;
+   int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+   void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+   void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+   int (*test)(void);
+   void (*done)(symmetric_key *skey);      
+   int  (*keysize)(int *keysize);
+
+   void (*accel_ecb_encrypt)(const unsigned char *pt, 
+                                   unsigned char *ct, 
+                                   unsigned long blocks, symmetric_key *skey);
+   void (*accel_ecb_decrypt)(const unsigned char *ct, 
+                                   unsigned char *pt, 
+                                   unsigned long blocks, symmetric_key *skey);
+   void (*accel_cbc_encrypt)(const unsigned char *pt, 
+                                   unsigned char *ct, 
+                                   unsigned long blocks, unsigned char *IV, 
+                                   symmetric_key *skey);
+   void (*accel_cbc_decrypt)(const unsigned char *ct, 
+                                   unsigned char *pt, 
+                                   unsigned long blocks, unsigned char *IV, 
+                                   symmetric_key *skey);
+   void (*accel_ctr_encrypt)(const unsigned char *pt, 
+                                   unsigned char *ct, 
+                                   unsigned long blocks, unsigned char *IV, 
+                                   int mode, symmetric_key *skey);
+   void (*accel_ccm_memory)(
+       const unsigned char *key,    unsigned long keylen,
+       const unsigned char *nonce,  unsigned long noncelen,
+       const unsigned char *header, unsigned long headerlen,
+             unsigned char *pt,     unsigned long ptlen,
+             unsigned char *ct,
+             unsigned char *tag,    unsigned long *taglen,
+                       int  direction);
+
+};
+\end{verbatim}
+\end{small}
+
+Where ``name'' is the lower case ASCII version of the name.  The fields ``min\_key\_length'' and ``max\_key\_length'' 
+are the minimum and maximum key sizes in bytes.  The ``block\_length'' member is the block size of the cipher
+in bytes.  As a good rule of thumb it is assumed that the cipher supports
+the min and max key lengths but not always everything in between.  The ``default\_rounds'' field is the default number
+of rounds that will be used.
+
+The remaining fields are all pointers to the core functions for each cipher.  The end of the cipher\_descriptor array is
+marked when ``name'' equals {\bf NULL}.
+
+As of this release the current cipher\_descriptors elements are
+
+\index{Cipher descriptor table}
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|c|}
+     \hline Name & Descriptor Name & Block Size & Key Range & Rounds \\
+     \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\
+     \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\
+     \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\
+     \hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\
+     \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\
+     \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\
+     \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
+                & aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
+     \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\
+     \hline DES & des\_desc & 8 & 7 & 16 \\
+     \hline 3DES (EDE mode) & des3\_desc & 8 & 21 & 16 \\
+     \hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\
+     \hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\
+     \hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\
+     \hline Anubis & anubis\_desc & 16 & 16 $\ldots$ 40 & 12 $\ldots$ 18 \\
+     \hline Khazad & khazad\_desc & 8 & 16 & 8 \\
+     \hline
+\end{tabular}
+\end{center}
+\end{small}
+
+\subsection{Notes}
+\begin{small}
+\begin{enumerate}
+\item
+For AES (also known as Rijndael) there are four descriptors which complicate issues a little.  The descriptors 
+rijndael\_desc and rijndael\_enc\_desc provide the cipher named ``rijndael''.  The descriptors aes\_desc and 
+aes\_enc\_desc provide the cipher name ``aes''.  Functionally both ``rijndael'' and ``aes'' are the same cipher.  The
+only difference is when you call find\_cipher() you have to pass the correct name.  The cipher descriptors with ``enc'' 
+in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine
+and tables.  The decryption and self--test function pointers of both ``encrypt only'' descriptors are set to \textbf{NULL} and 
+should not be called.
+
+The ``encrypt only'' descriptors are useful for applications that only use the encryption function of the cipher.  Algorithms such
+as EAX, PMAC and OMAC only require the encryption function.  So far this ``encrypt only'' functionality has only been implemented for
+Rijndael as it makes the most sense for this cipher.
+
+\item
+Note that for ``DES'' and ``3DES'' they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in
+fact used for the purposes of encryption.  My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24
+byte string from the real 7/21 byte key.
+
+\item
+Note that ``Twofish'' has additional configuration options that take place at build time.  These options are found in
+the file ``tomcrypt\_cfg.h''.  The first option is ``TWOFISH\_SMALL'' which when defined will force the Twofish code
+to not pre-compute the Twofish ``$g(X)$'' function as a set of four $8 \times 32$ s-boxes.  This means that a scheduled
+key will require less ram but the resulting cipher will be slower.  The second option is ``TWOFISH\_TABLES'' which when
+defined will force the Twofish code to use pre-computed tables for the two s-boxes $q_0, q_1$ as well as the multiplication
+by the polynomials 5B and EF used in the MDS multiplication.  As a result the code is faster and slightly larger.  The
+speed increase is useful when ``TWOFISH\_SMALL'' is defined since the s-boxes and MDS multiply form the heart of the
+Twofish round function.
+
+\index{Twofish build options}
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|l|l|}
+\hline TWOFISH\_SMALL & TWOFISH\_TABLES & Speed and Memory (per key) \\
+\hline undefined & undefined & Very fast, 4.2KB of ram. \\
+\hline undefined & defined & Faster keysetup, larger code. \\
+\hline defined & undefined & Very slow, 0.2KB of ram. \\
+\hline defined & defined & Faster, 0.2KB of ram, larger code. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+
+\end{enumerate}
+\end{small}
+
+To work with the cipher\_descriptor array there is a function:
+\index{find\_cipher()}
+\begin{verbatim}
+int find_cipher(char *name)
+\end{verbatim}
+Which will search for a given name in the array.  It returns negative one if the cipher is not found, otherwise it returns
+the location in the array where the cipher was found.  For example, to indirectly setup Blowfish you can also use:
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   unsigned char key[8];
+   symmetric_key skey;
+   int err;
+
+   /* you must register a cipher before you use it */
+   if (register_cipher(&blowfish_desc)) == -1) {
+      printf("Unable to register Blowfish cipher.");
+      return -1;
+   }
+
+   /* generic call to function (assuming the key in key[] was already setup) */
+   if ((err = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != 
+       CRYPT_OK) {
+      printf("Error setting up Blowfish: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* ... use cipher ... */
+}
+\end{verbatim}
+\end{small}
+
+A good safety would be to check the return value of ``find\_cipher()'' before accessing the desired function.  In order
+to use a cipher with the descriptor table you must register it first using:
+\index{register\_cipher()}
+\begin{verbatim}
+int register_cipher(const struct _cipher_descriptor *cipher);
+\end{verbatim}
+Which accepts a pointer to a descriptor and returns the index into the global descriptor table.  If an error occurs such
+as there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}.  If you try to add the same cipher more
+than once it will just return the index of the first copy.  To remove a cipher call:
+\index{unregister\_cipher()}
+\begin{verbatim}
+int unregister_cipher(const struct _cipher_descriptor *cipher);
+\end{verbatim}
+Which returns {\bf CRYPT\_OK} if it removes it otherwise it returns {\bf CRYPT\_ERROR}.  Consider:
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int err;
+   
+   /* register the cipher */
+   if (register_cipher(&rijndael_desc) == -1) {
+      printf("Error registering Rijndael\n");
+      return -1;
+   }
+
+   /* use Rijndael */
+
+   /* remove it */
+   if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {
+      printf("Error removing Rijndael: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   return 0;
+}
+\end{verbatim}
+\end{small}
+This snippet is a small program that registers only Rijndael only.  
+
+\section{Symmetric Modes of Operations}
+\subsection{Background}
+A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the block
+size of the cipher.  Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block
+$P$ under the key $k$ as $E_k(P)$.  In some modes there exists an initial vector denoted as $C_{-1}$.
+
+\subsubsection{ECB Mode}
+\index{ECB mode}
+ECB or Electronic Codebook Mode is the simplest method to use.  It is given as:
+\begin{equation}
+C_i = E_k(P_i)
+\end{equation}
+This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used more
+than once.
+
+\subsubsection{CBC Mode}
+\index{CBC mode}
+CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers.
+It is given as:
+\begin{equation}
+C_i = E_k(P_i \oplus C_{i - 1})
+\end{equation}
+It is important that the initial vector be unique and preferably random for each message encrypted under the same key.
+
+\subsubsection{CTR Mode}
+\index{CTR mode}
+CTR or Counter Mode is a mode which only uses the encryption function of the cipher.  Given a initial vector which is
+treated as a large binary counter the CTR mode is given as:
+\begin{eqnarray}
+C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\
+C_i = P_i \oplus E_k(C_{-1})
+\end{eqnarray}
+Where $W$ is the size of a block in bits (e.g. 64 for Blowfish).  As long as the initial vector is random for each message
+encrypted under the same key replay and swap attacks are infeasible.  CTR mode may look simple but it is as secure
+as the block cipher is under a chosen plaintext attack (provided the initial vector is unique).
+
+\subsubsection{CFB Mode}
+\index{CFB mode}
+CFB or Ciphertext Feedback Mode is a mode akin to CBC.  It is given as:
+\begin{eqnarray}
+C_i = P_i \oplus C_{-1} \nonumber \\
+C_{-1} = E_k(C_i)
+\end{eqnarray}
+Note that in this library the output feedback width is equal to the size of the block cipher.  That is this mode is used
+to encrypt whole blocks at a time.  However, the library will buffer data allowing the user to encrypt or decrypt partial
+blocks without a delay.  When this mode is first setup it will initially encrypt the initial vector as required.
+
+\subsubsection{OFB Mode}
+\index{OFB mode}
+OFB or Output Feedback Mode is a mode akin to CBC as well.  It is given as:
+\begin{eqnarray}
+C_{-1} = E_k(C_{-1}) \nonumber \\
+C_i = P_i \oplus C_{-1}
+\end{eqnarray}
+Like the CFB mode the output width in CFB mode is the same as the width of the block cipher.  OFB mode will also
+buffer the output which will allow you to encrypt or decrypt partial blocks without delay.
+
+\subsection{Choice of Mode}
+My personal preference is for the CTR mode since it has several key benefits:
+\begin{enumerate}
+   \item No short cycles which is possible in the OFB and CFB modes.
+   \item Provably as secure as the block cipher being used under a chosen plaintext attack.
+   \item Technically does not require the decryption routine of the cipher.
+   \item Allows random access to the plaintext.
+   \item Allows the encryption of block sizes that are not equal to the size of the block cipher.
+\end{enumerate}
+The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size.  They 
+accomplish this by buffering the data required to complete a block.  This allows you to encrypt or decrypt any size 
+block of memory with either of the three modes.
+
+The ECB and CBC modes process blocks of the same size as the cipher at a time.  Therefore they are less flexible than the
+other modes.
+
+\subsection{Initialization}
+\index{CBC Mode} \index{CTR Mode}
+\index{OFB Mode} \index{CFB Mode}
+The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages.  Assuming the mode 
+you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required to
+use that mode.  They have identical setup routines (except CTR and ECB mode):
+\index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()}
+\begin{verbatim}
+int XXX_start(int cipher, const unsigned char *IV, 
+              const unsigned char *key, int keylen, 
+              int num_rounds, symmetric_XXX *XXX);
+
+int ctr_start(               int   cipher,
+              const unsigned char *IV,
+              const unsigned char *key,       int keylen,
+                             int  num_rounds, int ctr_mode,
+                   symmetric_CTR *ctr);
+
+int ecb_start(int cipher, const unsigned char *key, int keylen, 
+              int num_rounds, symmetric_ECB *ecb);
+\end{verbatim}
+
+In each case ``cipher'' is the index into the cipher\_descriptor array of the cipher you want to use.  The ``IV'' value is 
+the initialization vector to be used with the cipher.  You must fill the IV yourself and it is assumed they are the same 
+length as the block size\footnote{In otherwords the size of a block of plaintext for the cipher, e.g. 8 for DES, 16 for AES, etc.} 
+of the cipher you choose.  It is important that the IV  be random for each unique message you want to encrypt.  The 
+parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call.  The final parameter 
+is a pointer to the structure you want to hold the information for the mode of operation.
+
+
+In the case of CTR mode there is an additional parameter ``ctr\_mode'' which specifies the mode that the counter is to be used in.
+If \textbf{CTR\_COUNTER\_LITTLE\_ENDIAN} was specified then the counter will be treated as a little endian value.  Otherwise, if 
+\textbf{CTR\_COUNTER\_BIG\_ENDIAN} was specified the counter will be treated as a big endian value.
+
+The routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code.  
+
+\subsection{Encryption and Decryption}
+To actually encrypt or decrypt the following routines are provided:
+\index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} 
+\index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()}
+\begin{verbatim}
+int XXX_encrypt(const unsigned char *pt, unsigned char *ct, 
+                unsigned long len, symmetric_YYY *YYY);
+int XXX_decrypt(const unsigned char *ct, unsigned char *pt, 
+                unsigned long len, symmetric_YYY *YYY);
+\end{verbatim}
+Where ``XXX'' is one of $\lbrace ecb, cbc, ctr, cfb, ofb \rbrace$.  
+
+In all cases ``len'' is the size of the buffer (as number of octets) to encrypt or decrypt.  The CTR, OFB and CFB modes are order sensitive but not
+chunk sensitive.  That is you can encrypt ``ABCDEF'' in three calls like ``AB'', ``CD'', ``EF'' or two like ``ABCDE'' and ``F''
+and end up with the same ciphertext.  However, encrypting ``ABC'' and ``DABC'' will result in different ciphertexts.  All
+five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions.
+
+In the ECB and CBC cases ``len'' must be a multiple of the ciphers block size.  In the CBC case you must manually pad the end of your message (either with
+zeroes or with whatever your protocol requires).
+
+To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used)
+and use the decrypt routine on all of the blocks.
+
+\subsection{IV Manipulation}
+To change or read the IV of a previously initialized chaining mode use the following two functions.
+
+\index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()}
+\index{ctr\_setiv()} \index{ctr\_getiv()}
+\begin{verbatim}
+int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX);
+int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX);
+\end{verbatim}
+
+The XXX\_getiv() functions will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV 
+stored in ``len''.  The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified.  The length
+of the IV passed in must be the size of the ciphers block size.
+
+The XXX\_setiv() functions are handy if you wish to change the IV without re--keying the cipher.  
+
+\subsection{Stream Termination}
+To terminate an open stream call the done function.
+
+\index{ecb\_done()} \index{cbc\_done()}\index{cfb\_done()}\index{ofb\_done()} \index{ctr\_done()}
+\begin{verbatim}
+int XXX_done(symmetric_XXX *XXX);
+\end{verbatim}
+
+This will terminate the stream (by terminating the cipher) and return \textbf{CRYPT\_OK} if successful.
+
+\subsection{Examples}
+
+\newpage
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   unsigned char key[16], IV[16], buffer[512];
+   symmetric_CTR ctr;
+   int x, err;
+
+   /* register twofish first */
+   if (register_cipher(&twofish_desc) == -1) {
+      printf("Error registering cipher.\n");
+      return -1;
+   }
+
+   /* somehow fill out key and IV */
+
+   /* start up CTR mode */
+   if ((err = ctr_start(
+        find_cipher("twofish"), /* index of desired cipher */
+                            IV, /* the initial vector */
+                           key, /* the secret key */
+                            16, /* length of secret key (16 bytes, 128 bits) */
+                             0, /* 0 == default # of rounds */
+     CTR_COUNTER_LITTLE_ENDIAN, /* Little endian counter */
+                         &ctr)  /* where to store initialized CTR state */
+      ) != CRYPT_OK) {
+      printf("ctr_start error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* somehow fill buffer than encrypt it */
+   if ((err = ctr_encrypt(        buffer, /* plaintext */
+                                  buffer, /* ciphertext */
+                          sizeof(buffer), /* length of data to encrypt */
+                                   &ctr)  /* previously initialized CTR state */
+      ) != CRYPT_OK) {
+      printf("ctr_encrypt error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* make use of ciphertext... */
+
+   /* now we want to decrypt so let's use ctr_setiv */
+   if ((err = ctr_setiv(  IV, /* the initial IV we gave to ctr_start */
+                          16, /* the IV is 16 bytes long */
+                        &ctr) /* the ctr state we wish to modify */
+       ) != CRYPT_OK) {
+      printf("ctr_setiv error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   if ((err = ctr_decrypt(        buffer, /* ciphertext */
+                                  buffer, /* plaintext */
+                          sizeof(buffer), /* length of data to encrypt */
+                                   &ctr)  /* previously initialized CTR state */
+      ) != CRYPT_OK) {
+      printf("ctr_decrypt error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* terminate the stream */
+   if ((err = ctr_done(&ctr)) != CRYPT_OK) {
+      printf("ctr_done error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* clear up and return */
+   zeromem(key, sizeof(key));
+   zeromem(&ctr, sizeof(ctr));
+
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+\section{Encrypt and Authenticate Modes}
+
+\subsection{EAX Mode}
+LibTomCrypt provides support for a mode called EAX\footnote{See 
+M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the
+way it was intended to be used by the designers.  First a short description of what EAX mode is before I explain how to use it.  
+EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication\footnote{Note that since EAX only requires OMAC and CTR you may use ``encrypt only'' cipher descriptors with this mode.}.  
+It is initialized with a random ``nonce'' that can be shared publicly as well as a ``header'' which can be fixed and public as well as a random 
+secret symmetric key.
+
+The ``header'' data is meant to be meta-data associated with a stream that isn't private (e.g. protocol messages).  It can
+be added at anytime during an EAX stream and is part of the authentication tag.  That is, changes in the meta-data can
+be detected by changes in the output tag.
+
+The mode can then process plaintext producing ciphertext as well as compute a partial checksum.  The actual checksum
+called a ``tag'' is only emitted when the message is finished.  In the interim though the user can process any arbitrary
+sized message block to send to the recipient as ciphertext.  This makes the EAX mode especially suited for streaming modes
+of operation.
+
+The mode is initialized with the following function.
+\index{eax\_init()}
+\begin{verbatim}
+int eax_init(eax_state *eax, int cipher, 
+             const unsigned char *key, unsigned long keylen,
+             const unsigned char *nonce, unsigned long noncelen,
+             const unsigned char *header, unsigned long headerlen);
+\end{verbatim}
+
+Where ``eax'' is the EAX state.  ``cipher'' is the index of the desired cipher in the descriptor table.  
+``key'' is the shared secret symmetric key of length ``keylen''.  ``nonce'' is the random public string of
+length ``noncelen''.  ``header'' is the random (or fixed or \textbf{NULL}) header for the message of length
+``headerlen''.
+
+When this function completes ``eax'' will be initialized such that you can now either have data decrypted or 
+encrypted in EAX mode.  Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL} to indicate
+there is no initial header data.
+
+To encrypt or decrypt data in a streaming mode use the following.
+\index{eax\_encrypt()} \index{eax\_decrypt()}
+\begin{verbatim}
+int eax_encrypt(eax_state *eax, const unsigned char *pt, 
+                unsigned char *ct, unsigned long length);
+
+int eax_decrypt(eax_state *eax, const unsigned char *ct, 
+                unsigned char *pt, unsigned long length);
+\end{verbatim}
+The function ``eax\_encrypt'' will encrypt the bytes in ``pt'' of ``length'' bytes and store the ciphertext in
+``ct''.  Note that ``ct'' and ``pt'' may be the same region in memory.   This function will also send the ciphertext
+through the OMAC function.  The function ``eax\_decrypt'' decrypts ``ct'' and stores it in ``pt''.  This also allows 
+``pt'' and ``ct'' to be the same region in memory.  
+
+You cannot both encrypt or decrypt with the same ``eax'' context.  For bi-directional communication you
+will need to initialize two EAX contexts (preferably with different headers and nonces).  
+
+Note that both of these functions allow you to send the data in any granularity but the order is important.  While
+the eax\_init() function allows you to add initial header data to the stream you can also add header data during the
+EAX stream with the following.
+
+\index{eax\_addheader()}
+\begin{verbatim}
+int eax_addheader(eax_state *eax, 
+                  const unsigned char *header, unsigned long length);
+\end{verbatim}
+
+This will add the ``length'' bytes from ``header'' to the given ``eax'' stream.  Once the message is finished the 
+``tag'' (checksum) may be computed with the following function.
+
+\index{eax\_done()}
+\begin{verbatim}
+int eax_done(eax_state *eax, 
+             unsigned char *tag, unsigned long *taglen);
+\end{verbatim}
+This will terminate the EAX state ``eax'' and store upto ``taglen'' bytes of the message tag in ``tag''.  The function
+then stores how many bytes of the tag were written out back into ``taglen''.
+
+The EAX mode code can be tested to ensure it matches the test vectors by calling the following function.
+\index{eax\_test()}
+\begin{verbatim}
+int eax_test(void);
+\end{verbatim}
+This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first.
+
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int           err;
+   eax_state     eax;
+   unsigned char pt[64], ct[64], nonce[16], key[16], tag[16];
+   unsigned long taglen;
+
+   if (register_cipher(&rijndael_desc) == -1) {
+      printf("Error registering Rijndael");
+      return EXIT_FAILURE;
+   }
+
+   /* ... make up random nonce and key ... */
+
+   /* initialize context */
+   if ((err = eax_init(            &eax,  /* the context */
+                find_cipher("rijndael"),  /* cipher we want to use */
+                                  nonce,  /* our state nonce */
+                                     16,  /* none is 16 bytes */
+                              "TestApp",  /* example header, identifies this program */
+                                      7)  /* length of the header */
+       ) != CRYPT_OK) {
+      printf("Error eax_init: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* now encrypt data, say in a loop or whatever */
+   if ((err = eax_encrypt(     &eax,      /* eax context */
+                                 pt,      /* plaintext  (source) */
+                                 ct,      /* ciphertext (destination) */
+                          sizeof(pt)      /* size of plaintext */
+      ) != CRYPT_OK) {
+      printf("Error eax_encrypt: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* finish message and get authentication tag */
+   taglen = sizeof(tag);
+   if ((err = eax_done(   &eax,           /* eax context */
+                           tag,           /* where to put tag */
+                       &taglen            /* length of tag space */
+      ) != CRYPT_OK) {
+      printf("Error eax_done: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* now we have the authentication tag in "tag" and it's taglen bytes long */
+
+}
+\end{verbatim}
+                       
+You can also perform an entire EAX state on a block of memory in a single function call with the 
+following functions.
+
+
+\index{eax\_encrypt\_authenticate\_memory} \index{eax\_decrypt\_verify\_memory}
+\begin{verbatim}
+int eax_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen);
+
+int eax_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+          unsigned char *tag,    unsigned long taglen,
+          int           *res);
+\end{verbatim}
+
+Both essentially just call eax\_init() followed by eax\_encrypt() (or eax\_decrypt() respectively) and eax\_done().  The parameters
+have the same meaning as with those respective functions.  
+
+The only difference is eax\_decrypt\_verify\_memory() does not emit a tag.  Instead you pass it a tag as input and it compares it against
+the tag it computed while decrypting the message.  If the tags match then it stores a $1$ in ``res'', otherwise it stores a $0$.
+
+\subsection{OCB Mode}
+LibTomCrypt provides support for a mode called OCB\footnote{See 
+P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.}
+.  OCB is an encryption protocol that simultaneously provides authentication.  It is slightly faster to use than EAX mode
+but is less flexible.  Let's review how to initialize an OCB context.
+
+\index{ocb\_init()}
+\begin{verbatim}
+int ocb_init(ocb_state *ocb, int cipher, 
+             const unsigned char *key, unsigned long keylen, 
+             const unsigned char *nonce);
+\end{verbatim}
+
+This will initialize the ``ocb'' context using cipher descriptor ``cipher''.  It will use a ``key'' of length ``keylen''
+and the random ``nonce''.  Note that ``nonce'' must be a random (public) string the same length as the block ciphers
+block size (e.g. 16 bytes for AES).
+
+This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream.
+To encrypt or decrypt data use the following.
+
+\index{ocb\_encrypt()} \index{ocb\_decrypt()}
+\begin{verbatim}
+int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
+int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
+\end{verbatim}
+
+This will encrypt (or decrypt for the latter) a fixed length of data from ``pt'' to ``ct'' (vice versa for the latter).  
+They assume that ``pt'' and ``ct'' are the same size as the block cipher's block size.  Note that you cannot call 
+both functions given a single ``ocb'' state.  For bi-directional communication you will have to initialize two ``ocb''
+states (with different nonces).  Also ``pt'' and ``ct'' may point to the same location in memory.
+
+\subsubsection{State Termination}
+
+When you are finished encrypting the message you call the following function to compute the tag.
+
+\index{ocb\_done\_encrypt()}
+\begin{verbatim}
+int ocb_done_encrypt(ocb_state *ocb, 
+                     const unsigned char *pt, unsigned long ptlen,
+                           unsigned char *ct, 
+                           unsigned char *tag, unsigned long *taglen);
+\end{verbatim}
+
+This will terminate an encrypt stream ``ocb''.  If you have trailing bytes of plaintext that will not complete a block 
+you can pass them here.  This will also encrypt the ``ptlen'' bytes in ``pt'' and store them in ``ct''.  It will also
+store upto ``taglen'' bytes of the tag into ``tag''.
+
+Note that ``ptlen'' must be less than or equal to the block size of block cipher chosen.  Also note that if you have 
+an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only.  
+
+To terminate a decrypt stream and compared the tag you call the following.
+
+\index{ocb\_done\_decrypt()}
+\begin{verbatim}
+int ocb_done_decrypt(ocb_state *ocb, 
+                     const unsigned char *ct,  unsigned long ctlen,
+                           unsigned char *pt, 
+                     const unsigned char *tag, unsigned long taglen, 
+                           int *res);
+\end{verbatim}
+
+Similarly to the previous function you can pass trailing message bytes into this function.  This will compute the 
+tag of the message (internally) and then compare it against the ``taglen'' bytes of ``tag'' provided.  By default
+``res'' is set to zero.  If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticated
+message).
+
+\subsubsection{Packet Functions}
+To make life simpler the following two functions are provided for memory bound OCB.
+
+\index{ocb\_encrypt\_authenticate\_memory()}
+\begin{verbatim}
+int ocb_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen);
+\end{verbatim}
+
+This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''.  The length ``ptlen''
+can be any arbitrary length.  
+
+\index{ocb\_decrypt\_verify\_memory()}
+\begin{verbatim}
+int ocb_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+    const unsigned char *tag,    unsigned long taglen,
+          int           *res);
+\end{verbatim}
+
+Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set 
+appropriately.
+
+\subsection{CCM Mode}
+CCM is a NIST proposal for Encrypt+Authenticate that is centered around using AES (or any 16--byte cipher) as a primitive.  Unlike EAX and OCB mode
+it is only meant for ``packet'' mode where the length of the input is known in advance.  Since it is a packet mode function CCM only has one 
+function that performs the protocol.
+
+\index{ccm\_memory()}
+\begin{verbatim}
+int ccm_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+          unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen,
+                    int  direction);
+\end{verbatim}
+
+This performs the ``CCM'' operation on the data.  The ``cipher'' variable indicates which cipher in the descriptor table to use.  It must have a 
+16--byte block size for CCM.  The key is ``key'' with a length of ``keylen'' octets.  The nonce or salt is ``nonce'' of
+length ``noncelen'' octets.  The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header''
+of length ``headerlen'' octets.  The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}).  
+
+The plaintext is stored in ``pt'' and the ciphertext in ``ct''.  The length of both are expected to be equal and is passed in as ``ptlen''.  It is
+allowable that $pt = ct$.  The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or 
+decryption (direction $=$ \textbf{CCM\_DECRYPT}) is to be performed.
+
+As implemented this copy of CCM cannot handle a header or plaintext longer than $2^{32} - 1$ octets long.  
+
+You can test the implementation of CCM with the following function.
+
+\index{ccm\_test()}
+\begin{verbatim}
+int ccm_test(void);
+\end{verbatim}
+
+This will return \textbf{CRYPT\_OK} if the CCM routine passes known test vectors.
+
+\subsection{GCM Mode}
+Galois counter mode is an IEEE proposal for authenticated encryption.  Like EAX and OCB it can be used in a streaming capacity however, unlike EAX it cannot
+accept ``additional authentication data'' (meta--data) after plaintext has been processed.  This mode also only works with block ciphers with a sixteen
+byte block.
+
+A GCM stream is meant to be processed in three modes each one sequential serial.  First the initial vector (per session) data is processed.  This should be 
+unique to every session.  Next the the optional additional authentication data is processed and finally the plaintext.  
+
+\subsubsection{Initialization}
+To initialize the GCM context with a secret key call the following function.
+
+\index{gcm\_init()}
+\begin{verbatim}
+int gcm_init(gcm_state *gcm, int cipher,
+             const unsigned char *key, int keylen);
+\end{verbatim}
+This initializes the GCM state ``gcm'' for the given cipher indexed by ``cipher'' with a secret key ``key'' of length ``keylen'' octets.  The cipher chosen
+must have a 16--byte block size (e.g. AES).  
+
+\subsubsection{Initial Vector}
+After the state has been initialized (or reset) the next step is to add the session (or packet) initial vector.  It should be unique per packet encrypted.
+
+\index{gcm\_add\_iv()}
+\begin{verbatim}
+int gcm_add_iv(gcm_state *gcm, 
+               const unsigned char *IV,     unsigned long IVlen);
+\end{verbatim}
+
+This adds the initial vector octets from ``IV'' of length ``IVlen'' to the GCM state ``gcm''.  You can call this function as many times as required
+to process the entire IV.  
+
+Note that the GCM protocols provides a ``shortcut'' for 12--byte IVs where no preprocessing is to be done.  If you want to minimize per packet latency it's ideal
+to only use 12--byte IVs.  You can just increment it like a counter for each packet and the CTR [privacy] will be ensured.
+
+\subsubsection{Additional Authentication Data}
+After the entire IV has been processed the additional authentication data can be processed.  Unlike the IV a packet/session does not require additional
+authentication data (AAD) for security.  The AAD is meant to be used as side--channel data you want to be authenticated with the packet.  Note that once
+you begin adding AAD to the GCM state you cannot return to adding IV data until the state is reset.
+
+\index{gcm\_add\_aad()}
+\begin{verbatim}
+int gcm_add_aad(gcm_state *gcm, 
+               const unsigned char *adata,     unsigned long adatalen);
+\end{verbatim}
+This adds the additional authentication data ``adata'' of length ``adatalen'' to the GCM state ``gcm''.
+
+\subsubsection{Plaintext Processing}
+After the AAD has been processed the plaintext (or ciphertext depending on the direction) can be processed.  
+
+\index{gcm\_process()}
+\begin{verbatim}
+int gcm_process(gcm_state *gcm,
+                     unsigned char *pt,     unsigned long ptlen,
+                     unsigned char *ct,
+                     int direction);
+\end{verbatim}
+This processes message data where ``pt'' is the plaintext and ``ct'' is the ciphertext.  The length of both are equal and stored in ``ptlen''.  Depending on the 
+mode ``pt'' is the input and ``ct'' is the output (or vice versa).  When ``direction'' equals \textbf{GCM\_ENCRYPT} the plaintext is read, encrypted and stored
+in the ciphertext buffer.  When ``direction'' equals \textbf{GCM\_DECRYPT} the opposite occurs.
+
+\subsubsection{State Termination}
+To terminate a GCM state and retrieve the message authentication tag call the following function.
+
+\index{gcm\_done()}
+\begin{verbatim}
+int gcm_done(gcm_state *gcm, 
+                     unsigned char *tag,    unsigned long *taglen);
+\end{verbatim}
+This terminates the GCM state ``gcm'' and stores the tag in ``tag'' of length ``taglen'' octets.
+
+\subsubsection{State Reset}
+The call to gcm\_init() will perform considerable pre--computation (when \textbf{GCM\_TABLES} is defined) and if you're going to be dealing with a lot of packets
+it is very costly to have to call it repeatedly.  To aid in this endeavour the reset function has been provided.
+
+\index{gcm\_reset()}
+\begin{verbatim}
+int gcm_reset(gcm_state *gcm);
+\end{verbatim}
+
+This will reset the GCM state ``gcm'' to the state that gcm\_init() left it.  The user would then call gcm\_add\_iv(), gcm\_add\_aad(), etc.
+
+\subsubsection{One--Shot Packet}
+To process a single packet under any given key the following helper function can be used.
+
+\index{gcm\_memory()}
+\begin{verbatim}
+int gcm_memory(      int           cipher,
+               const unsigned char *key,    unsigned long keylen,
+               const unsigned char *IV,     unsigned long IVlen,
+               const unsigned char *adata,  unsigned long adatalen,
+                     unsigned char *pt,     unsigned long ptlen,
+                     unsigned char *ct, 
+                     unsigned char *tag,    unsigned long *taglen,
+                               int direction);
+\end{verbatim}
+
+This will initialize the GCM state with the given key, IV and AAD value then proceed to encrypt or decrypt the message text and store the final
+message tag.  The definition of the variables is the same as it is for all the manual functions.
+
+If you are processing many packets under the same key you shouldn't use this function as it invokes the pre--computation with each call.
+
+\subsubsection{Example Usage}
+The following is an example usage of how to use GCM over multiple packets with a shared secret key.
+
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+
+int send_packet(const unsigned char *pt,  unsigned long ptlen,
+                const unsigned char *iv,  unsigned long ivlen,
+                const unsigned char *aad, unsigned long aadlen,
+                      gcm_state     *gcm)
+{
+   int           err;
+   unsigned long taglen;
+   unsigned char tag[16];
+
+   /* reset the state */
+   if ((err = gcm_reset(gcm)) != CRYPT_OK) {
+      return err;
+   }
+ 
+   /* Add the IV */
+   if ((err = gcm_add_iv(gcm, iv, ivlen)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* Add the AAD (note: aad can be NULL if aadlen == 0) */
+   if ((err = gcm_add_aad(gcm, aad, aadlen)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* process the plaintext */
+   if ((err = gcm_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* Finish up and get the MAC tag */
+   taglen = sizeof(tag);
+   if ((err = gcm_done(gcm, tag, &taglen)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* ... send a header describing the lengths ... */
+
+   /* depending on the protocol and how IV is generated you may have to send it too... */
+   send(socket, iv, ivlen, 0);
+
+   /* send the aad */
+   send(socket, aad, aadlen, 0);
+
+   /* send the ciphertext */
+   send(socket, pt, ptlen, 0);
+
+   /* send the tag */
+   send(socket, tag, taglen, 0);
+
+   return CRYPT_OK;
+}
+
+int main(void)
+{
+   gcm_state     gcm;
+   unsigned char key[16], IV[12], pt[PACKET_SIZE];
+   int           err, x;
+   unsigned long ptlen; 
+ 
+   /* somehow fill key/IV with random values */
+   
+   /* register AES */
+   register_cipher(&aes_desc);
+
+   /* init the GCM state */
+   if ((err = gcm_init(&gcm, find_cipher("aes"), key, 16)) != CRYPT_OK) {
+      whine_and_pout(err);
+   }
+
+   /* handle us some packets */
+   for (;;) {
+       ptlen = make_packet_we_want_to_send(pt);
+
+       /* use IV as counter (12 byte counter) */
+       for (x = 11; x >= 0; x--) {
+           if (++IV[x]) {
+              break;
+           }
+       }
+
+       if ((err = send_packet(pt, ptlen, iv, 12, NULL, 0, &gcm)) != CRYPT_OK) {
+           whine_and_pout(err);
+       }
+   }
+   return EXIT_SUCCESS;
+}
+\end{verbatim}
+\end{small}
+
+\chapter{One-Way Cryptographic Hash Functions}
+\section{Core Functions}
+
+Like the ciphers there are hash core functions and a universal data type to hold the hash state called ``hash\_state''.  
+To initialize hash XXX (where XXX is the name) call:
+\index{Hash Functions}
+\begin{verbatim}
+void XXX_init(hash_state *md);
+\end{verbatim}
+
+This simply sets up the hash to the default state governed by the specifications of the hash.  To add data to the 
+message being hashed call:
+\begin{verbatim}
+int XXX_process(hash_state *md, const unsigned char *in, unsigned long inlen);
+\end{verbatim}
+
+Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which 
+are buffered.  The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest
+(hash output) will be the same.  For example, this means that:
+\begin{verbatim}
+md5_process(&md, "hello ", 6);
+md5_process(&md, "world", 5);
+\end{verbatim}
+Will produce the same message digest as the single call:
+\index{Message Digest}
+\begin{verbatim}
+md5_process(&md, "hello world", 11);
+\end{verbatim}
+
+To finally get the message digest (the hash) call:
+\begin{verbatim}
+int XXX_done(hash_state *md, 
+              unsigned char *out);
+\end{verbatim}
+
+This function will finish up the hash and store the result in the ``out'' array.  You must ensure that ``out'' is long
+enough for the hash in question.  Often hashes are used to get keys for symmetric ciphers so the ``XXX\_done()'' functions
+will wipe the ``md'' variable before returning automatically.
+
+To test a hash function call:
+\begin{verbatim}
+int XXX_test(void);
+\end{verbatim}
+
+This will return {\bf CRYPTO\_OK} if the hash matches the test vectors, otherwise it returns an error code.  An
+example snippet that hashes a message with md5 is given below.
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+    hash_state md;
+    unsigned char *in = "hello world", out[16];
+
+    /* setup the hash */
+    md5_init(&md);
+
+    /* add the message */
+    md5_process(&md, in, strlen(in));
+
+    /* get the hash in out[0..15] */
+    md5_done(&md, out);
+
+    return 0;
+}
+\end{verbatim}
+\end{small}
+
+\section{Hash Descriptors}
+Like the set of ciphers the set of hashes have descriptors too.  They are stored in an array called ``hash\_descriptor'' and
+are defined by:
+\begin{verbatim}
+struct _hash_descriptor {
+    char *name;
+    unsigned long hashsize;    /* digest output size in bytes  */
+    unsigned long blocksize;   /* the block size the hash uses */
+    void (*init)   (hash_state *hash);
+    int  (*process)(hash_state *hash, 
+                    const unsigned char *in, unsigned long inlen);
+    int  (*done)   (hash_state *hash, unsigned char *out);
+    int  (*test)   (void);
+};
+\end{verbatim}
+
+Similarly ``name'' is the name of the hash function in ASCII (all lowercase).  ``hashsize'' is the size of the digest output
+in bytes.  The remaining fields are pointers to the functions that do the respective tasks.  There is a function to
+search the array as well called ``int find\_hash(char *name)''.  It returns -1 if the hash is not found, otherwise the
+position in the descriptor table of the hash.
+
+You can use the table to indirectly call a hash function that is chosen at runtime.  For example:
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   unsigned char buffer[100], hash[MAXBLOCKSIZE];
+   int idx, x;
+   hash_state md;
+
+   /* register hashes .... */
+   if (register_hash(&md5_desc) == -1) {
+      printf("Error registering MD5.\n");
+      return -1;
+   }
+
+   /* register other hashes ... */
+
+   /* prompt for name and strip newline */
+   printf("Enter hash name: \n");
+   fgets(buffer, sizeof(buffer), stdin);
+   buffer[strlen(buffer) - 1] = 0;
+
+   /* get hash index */
+   idx = find_hash(buffer);
+   if (idx == -1) {
+      printf("Invalid hash name!\n");
+      return -1;
+   }
+
+   /* hash input until blank line */
+   hash_descriptor[idx].init(&md);
+   while (fgets(buffer, sizeof(buffer), stdin) != NULL)
+         hash_descriptor[idx].process(&md, buffer, strlen(buffer));
+   hash_descriptor[idx].done(&md, hash);
+
+   /* dump to screen */
+   for (x = 0; x < hash_descriptor[idx].hashsize; x++)
+       printf("%02x ", hash[x]);
+   printf("\n");
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+Note the usage of ``MAXBLOCKSIZE''.  In Libtomcrypt no symmetric block, key or hash digest is larger than MAXBLOCKSIZE in
+length.  This provides a simple size you can set your automatic arrays to that will not get overrun.
+
+There are three helper functions as well:
+\index{hash\_memory()} \index{hash\_file()}
+\begin{verbatim}
+int hash_memory(int hash, 
+                const unsigned char *in,   unsigned long inlen, 
+                      unsigned char *out,  unsigned long *outlen);
+
+int hash_file(int hash, const char *fname, 
+              unsigned char *out, unsigned long *outlen);
+
+int hash_filehandle(int hash, FILE *in, 
+                    unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+
+The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}).  
+The ``*outlen'' variable is used to keep track of the output size.  You must set it to the size of your output buffer before 
+calling the functions.  When they complete succesfully they store the length of the message digest back in it.  The functions 
+are otherwise straightforward.  The ``hash\_filehandle'' function assumes that ``in'' is an file handle opened in binary mode.  
+It will hash to the end of file and not reset the file position when finished.
+
+To perform the above hash with md5 the following code could be used:
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int idx, err;
+   unsigned long len;
+   unsigned char out[MAXBLOCKSIZE];
+
+   /* register the hash */
+   if (register_hash(&md5_desc) == -1) {
+      printf("Error registering MD5.\n");
+      return -1;
+   }
+
+   /* get the index of the hash  */
+   idx = find_hash("md5");
+
+   /* call the hash */
+   len = sizeof(out);
+   if ((err = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) {
+      printf("Error hashing data: %s\n", error_to_string(err));
+      return -1;
+   }
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+The following hashes are provided as of this release:
+\index{Hash descriptor table}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+      \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
+      \hline WHIRLPOOL & whirlpool\_desc & 64 \\
+      \hline SHA-512 & sha512\_desc & 64 \\
+      \hline SHA-384 & sha384\_desc & 48 \\
+      \hline SHA-256 & sha256\_desc & 32 \\
+      \hline SHA-224 & sha224\_desc & 28 \\
+      \hline TIGER-192 & tiger\_desc & 24 \\
+      \hline SHA-1 & sha1\_desc & 20 \\
+      \hline RIPEMD-160 & rmd160\_desc & 20 \\
+      \hline RIPEMD-128 & rmd128\_desc & 16 \\
+      \hline MD5 & md5\_desc & 16 \\
+      \hline MD4 & md4\_desc & 16 \\
+      \hline MD2 & md2\_desc & 16 \\
+      \hline
+\end{tabular}
+\end{center}
+
+Similar to the cipher descriptor table you must register your hash algorithms before you can use them.  These functions
+work exactly like those of the cipher registration code.  The functions are:
+\index{register\_hash()} \index{unregister\_hash()}
+\begin{verbatim}
+int register_hash(const struct _hash_descriptor *hash);
+int unregister_hash(const struct _hash_descriptor *hash);
+\end{verbatim}
+
+\section{Cipher Hash Construction}
+\index{Cipher Hash Construction}
+An addition to the suite of hash functions is the ``Cipher Hash Construction'' or ``CHC'' mode.  In this mode
+applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use.  In 
+particular this allows a cryptosystem to be designed using very few moving parts.
+
+In order to use the CHC system the developer will have to take a few extra steps.  First the ``chc\_desc'' hash
+descriptor must be registered with register\_hash().  At this point the CHC hash cannot be used to hash
+data.  While it is in the hash system you still have to tell the CHC code which cipher to use.  This is accomplished
+via the chc\_register() function.
+
+\index{chc\_register()}
+\begin{verbatim}
+int chc_register(int cipher);
+\end{verbatim}
+
+A cipher has to be registered with CHC (and also in the cipher descriptor tables with 
+register\_cipher()).  The chc\_register() function will bind a cipher to the CHC system.  Only one cipher can 
+be bound to the CHC hash at a time.  There are additional requirements for the system to work.
+
+\begin{enumerate}
+   \item The cipher must have a block size greater than 64--bits.  
+   \item The cipher must allow an input key the size of the block size.
+\end{enumerate}
+
+Example of using CHC with the AES block cipher.
+
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int err; 
+
+   /* register cipher and hash */
+   if (register_cipher(&aes_enc_desc) == -1) {
+      printf("Could not register cipher\n");
+      return EXIT_FAILURE;
+   }
+   if (register_hash(&chc_desc) == -1) {
+      printf("Could not register hash\n");
+      return EXIT_FAILURE;
+   }
+
+   /* start chc with AES */
+   if ((err = chc_register(find_cipher("aes"))) != CRYPT_OK) {
+      printf("Error binding AES to CHC: %s\n", error_to_string(err));
+   }
+
+   /* now you can use chc_hash in any LTC function [aside from pkcs...] */
+   /* ... */
+\end{verbatim}
+
+
+\section{Notice}
+It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.  
+These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
+(e.g. Yarrow).
+
+The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure
+for all purposes you would normally use a hash for.
+
+\chapter{Message Authentication Codes}
+\section{HMAC Protocol}
+Thanks to Dobes Vandermeer the library now includes support for hash based message authenication codes or HMAC for short.  An HMAC
+of a message is a keyed authenication code that only the owner of a private symmetric key will be able to verify.  The purpose is
+to allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct.  Any impostor or
+eavesdropper will not be able to verify the authenticity of a message.  
+
+The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key 
+and its length.  The key is much like a key you would pass to a cipher.  That is, it is simply an array of octets stored in
+chars.  The initialization routine is:
+\index{hmac\_init()}
+\begin{verbatim}
+int hmac_init(hmac_state *hmac, int hash, 
+              const unsigned char *key, unsigned long keylen);
+\end{verbatim}
+The ``hmac'' parameter is the state for the HMAC code.  ``hash'' is the index into the descriptor table of the hash you want
+to use to authenticate the message.  ``key'' is the pointer to the array of chars that make up the key.  ``keylen'' is the
+length (in octets) of the key you want to use to authenticate the message.  To send octets of a message through the HMAC system you must use the following function:
+\index{hmac\_process()}
+\begin{verbatim}
+int hmac_process(hmac_state *hmac, 
+                 const unsigned char *in, unsigned long inlen);
+\end{verbatim}
+``hmac'' is the HMAC state you are working with. ``buf'' is the array of octets to send into the HMAC process.  ``len'' is the
+number of octets to process.  Like the hash process routines you can send the data in arbitrarly sized chunks. When you 
+are finished with the HMAC process you must call the following function to get the HMAC code:
+\index{hmac\_done()}
+\begin{verbatim}
+int hmac_done(hmac_state *hmac, 
+              unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+``hmac'' is the HMAC state you are working with.  ``out'' is the array of octets where the HMAC code should be stored.  You must
+set ``outlen'' to the size of the destination buffer before calling this function.  It is updated with the length of the HMAC code
+produced (depending on which hash was picked).  If ``outlen'' is less than the size of the message digest (and ultimately
+the HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first ``outlen'' bytes).
+
+There are two  utility functions provided to make using HMACs easier todo.  They accept the key and information about the
+message (file pointer, address in memory) and produce the HMAC result in one shot.  These are useful if you want to avoid
+calling the three step process yourself.
+
+\index{hmac\_memory()}
+\begin{verbatim}
+int hmac_memory(int hash, 
+                const unsigned char *key, unsigned long  keylen,
+                const unsigned char *in,  unsigned long  inlen, 
+                      unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+This will produce an HMAC code for the array of octets in ``in'' of length ``inlen''.  The index into the hash descriptor 
+table must be provided in ``hash''.  It uses the key from ``key'' with a key length of ``keylen''.  
+The result is stored in the array of octets ``out'' and the length in ``outlen''.  The value of ``outlen'' must be set
+to the size of the destination buffer before calling this function.  Similarly for files there is the  following function:
+\index{hmac\_file()}
+\begin{verbatim}
+int hmac_file(int hash, const char *fname, 
+              const unsigned char *key, unsigned long  keylen, 
+                    unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+``hash'' is the index into the hash descriptor table of the hash you want to use.  ``fname'' is the filename to process.  
+``key'' is the array of octets to use as the key of length ``keylen''.  ``out'' is the array of octets where the 
+result should be stored.
+
+To test if the HMAC code is working there is the following function:
+\index{hmac\_test()}
+\begin{verbatim}
+int hmac_test(void);
+\end{verbatim}
+Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code.  Some example code for using the 
+HMAC system is given below.
+
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int idx, err;
+   hmac_state hmac;
+   unsigned char key[16], dst[MAXBLOCKSIZE];
+   unsigned long dstlen;
+
+   /* register SHA-1 */
+   if (register_hash(&sha1_desc) == -1) {
+      printf("Error registering SHA1\n");
+      return -1;
+   }
+
+   /* get index of SHA1 in hash descriptor table */
+   idx = find_hash("sha1");
+
+   /* we would make up our symmetric key in "key[]" here */
+
+   /* start the HMAC */
+   if ((err = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) {
+      printf("Error setting up hmac: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* process a few octets */
+   if((err = hmac_process(&hmac, "hello", 5) != CRYPT_OK) {
+      printf("Error processing hmac: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* get result (presumably to use it somehow...) */
+   dstlen = sizeof(dst);
+   if ((err = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) {
+      printf("Error finishing hmac: %s\n", error_to_string(err));
+      return -1;
+   }
+   printf("The hmac is %lu bytes long\n", dstlen);
+  
+   /* return */
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+\section{OMAC Support}
+OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an 
+algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES.  From an API 
+standpoint the OMAC routines work much like the HMAC routines do.  Instead in this case a cipher is used instead of a hash.  
+
+To start an OMAC state you call
+\index{omac\_init()}
+\begin{verbatim}
+int omac_init(omac_state *omac, int cipher, 
+              const unsigned char *key, unsigned long keylen);
+\end{verbatim}
+The ``omac'' variable is the state for the OMAC algorithm.  ``cipher'' is the index into the cipher\_descriptor table
+of the cipher\footnote{The cipher must have a 64 or 128 bit block size.  Such as CAST5, Blowfish, DES, AES, Twofish, etc.} you
+wish to use.  ``key'' and ``keylen'' are the keys used to authenticate the data.
+
+To send data through the algorithm call
+\index{omac\_process()}
+\begin{verbatim}
+int omac_process(omac_state *state, 
+                 const unsigned char *in, unsigned long inlen);
+\end{verbatim}
+This will send ``inlen'' bytes from ``in'' through the active OMAC state ``state''.  Returns \textbf{CRYPT\_OK} if the 
+function succeeds.  The function is not sensitive to the granularity of the data.  For example,
+
+\begin{verbatim}
+omac_process(&mystate, "hello",  5);
+omac_process(&mystate, " world", 6);
+\end{verbatim}
+
+Would produce the same result as,
+
+\begin{verbatim}
+omac_process(&mystate, "hello world",  11);
+\end{verbatim}
+
+When you are done processing the message you can call the following to compute the message tag.
+
+\index{omac\_done()}
+\begin{verbatim}
+int omac_done(omac_state *state, 
+              unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+Which will terminate the OMAC and output the \textit{tag} (MAC) to ``out''.  Note that unlike the HMAC and other code 
+``outlen'' can be smaller than the default MAC size (for instance AES would make a 16-byte tag).  Part of the OMAC 
+specification states that the output may be truncated.  So if you pass in $outlen = 5$ and use AES as your cipher than
+the output MAC code will only be five bytes long.  If ``outlen'' is larger than the default size it is set to the default
+size to show how many bytes were actually used.
+
+Similar to the HMAC code the file and memory functions are also provided.  To OMAC a buffer of memory in one shot use the 
+following function.
+
+\index{omac\_memory()}
+\begin{verbatim}
+int omac_memory(int cipher, 
+                const unsigned char *key, unsigned long keylen,
+                const unsigned char *in,  unsigned long inlen,
+                      unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+This will compute the OMAC of ``inlen'' bytes of ``in'' using the key ``key'' of length ``keylen'' bytes and the cipher
+specified by the ``cipher'''th entry in the cipher\_descriptor table.  It will store the MAC in ``out'' with the same
+rules as omac\_done.
+
+To OMAC a file use
+\index{omac\_file()}
+\begin{verbatim}
+int omac_file(int cipher, 
+              const unsigned char *key, unsigned long keylen,
+              const char *filename, 
+                    unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+
+Which will OMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes
+and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table.  It will store the MAC in ``out'' with 
+the same rules as omac\_done.
+
+To test if the OMAC code is working there is the following function:
+\index{omac\_test()}
+\begin{verbatim}
+int omac_test(void);
+\end{verbatim}
+Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code.  Some example code for using the 
+OMAC system is given below.
+
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int idx, err;
+   omac_state omac;
+   unsigned char key[16], dst[MAXBLOCKSIZE];
+   unsigned long dstlen;
+
+   /* register Rijndael */
+   if (register_cipher(&rijndael_desc) == -1) {
+      printf("Error registering Rijndael\n");
+      return -1;
+   }
+
+   /* get index of Rijndael in cipher descriptor table */
+   idx = find_cipher("rijndael");
+
+   /* we would make up our symmetric key in "key[]" here */
+
+   /* start the OMAC */
+   if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) {
+      printf("Error setting up omac: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* process a few octets */
+   if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) {
+      printf("Error processing omac: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* get result (presumably to use it somehow...) */
+   dstlen = sizeof(dst);
+   if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) {
+      printf("Error finishing omac: %s\n", error_to_string(err));
+      return -1;
+   }
+   printf("The omac is %lu bytes long\n", dstlen);
+  
+   /* return */
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+\section{PMAC Support}
+The PMAC\footnote{J.Black, P.Rogaway, ``A Block--Cipher Mode of Operation for Parallelizable Message Authentication''} 
+protocol is another MAC algorithm that relies solely on a symmetric-key block cipher.  It uses essentially the same
+API as the provided OMAC code.  
+
+A PMAC state is initialized with the following.
+
+\index{pmac\_init()}
+\begin{verbatim}
+int pmac_init(pmac_state *pmac, int cipher, 
+              const unsigned char *key, unsigned long keylen);
+\end{verbatim}
+Which initializes the ``pmac'' state with the given ``cipher'' and ``key'' of length ``keylen'' bytes.  The chosen cipher
+must have a 64 or 128 bit block size (e.x. AES).
+
+To MAC data simply send it through the process function.
+
+\index{pmac\_process()}
+\begin{verbatim}
+int pmac_process(pmac_state *state, 
+                 const unsigned char *in, unsigned long inlen);
+\end{verbatim}
+This will process ``inlen'' bytes of ``in'' in the given ``state''.  The function is not sensitive to the granularity of the
+data.  For example,
+
+\begin{verbatim}
+pmac_process(&mystate, "hello",  5);
+pmac_process(&mystate, " world", 6);
+\end{verbatim}
+
+Would produce the same result as,
+
+\begin{verbatim}
+pmac_process(&mystate, "hello world",  11);
+\end{verbatim}
+
+When a complete message has been processed the following function can be called to compute the message tag.
+
+\index{pmac\_done()}
+\begin{verbatim}
+int pmac_done(pmac_state *state, 
+              unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+This will store upto ``outlen'' bytes of the tag for the given ``state'' into ``out''.  Note that if ``outlen'' is larger
+than the size of the tag it is set to the amount of bytes stored in ``out''.
+
+Similar to the PMAC code the file and memory functions are also provided.  To PMAC a buffer of memory in one shot use the 
+following function.
+
+\index{pmac\_memory()}
+\begin{verbatim}
+int pmac_memory(int cipher, 
+                const unsigned char *key, unsigned long  keylen,
+                const unsigned char *in,  unsigned long  inlen,
+                      unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+This will compute the PMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher
+specified by the ``cipher'''th entry in the cipher\_descriptor table.  It will store the MAC in ``out'' with the same
+rules as omac\_done.
+
+To PMAC a file use
+\index{pmac\_file()}
+\begin{verbatim}
+int pmac_file(int cipher, 
+              const unsigned char *key, unsigned long keylen,
+              const char *filename, 
+              unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+
+Which will PMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes
+and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table.  It will store the MAC in ``out'' with 
+the same rules as omac\_done.
+
+To test if the PMAC code is working there is the following function:
+\index{pmac\_test()}
+\begin{verbatim}
+int pmac_test(void);
+\end{verbatim}
+Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code.
+
+\section{Pelican MAC}
+Pelican MAC is a new (experimental) MAC by the AES team that uses four rounds of AES as a ``mixing function''.  It achieves a very high 
+rate of processing and is potentially very secure.  It requires AES to be enabled to function.  You do not have to register\_cipher() AES first though
+as it calls AES directly.
+
+\index{pelican\_init()}
+\begin{verbatim}
+int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen);
+\end{verbatim}
+This will initialize the Pelican state with the given AES key.  Once this has been done you can begin processing data.
+
+\index{pelican\_process()}
+\begin{verbatim}
+int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen);
+\end{verbatim}
+This will process ``inlen'' bytes of ``in'' through the Pelican MAC.  It's best that you pass in multiples of 16 bytes as it makes the
+routine more efficient but you may pass in any length of text.  You can call this function as many times as required to process
+an entire message.
+
+\index{pelican\_done()}
+\begin{verbatim}
+int pelican_done(pelican_state *pelmac, unsigned char *out);
+\end{verbatim}
+This terminates a Pelican MAC and writes the 16--octet tag to ``out''.
+
+\subsection{Example}
+
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   pelican_state pelstate;
+   unsigned char key[32], tag[16];
+   int           err;
+
+   /* somehow initialize a key */
+
+   /* initialize pelican mac */
+   if ((err = pelican_init(&pelstate,          /* the state */
+                           key,                /* user key */
+                           32                  /* key length in octets */
+                          )) != CRYPT_OK) {
+      printf("Error initializing Pelican: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* MAC some data */
+   if ((err = pelican_process(&pelstate,       /* the state */
+                              "hello world",   /* data to mac */        
+                              11               /* length of data */
+                              )) != CRYPT_OK) {
+      printf("Error processing Pelican: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* Terminate the MAC */
+   if ((err = pelican_done(&pelstate,       /* the state */
+                           tag              /* where to store the tag */
+                           )) != CRYPT_OK) {
+      printf("Error terminating Pelican: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* tag[0..15] has the MAC output now */
+
+   return EXIT_SUCCESS;
+}
+\end{verbatim}
+
+
+\chapter{Pseudo-Random Number Generators}
+\section{Core Functions}
+The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well.  A cryptographic PRNG is
+used to expand a shorter bit string into a longer bit string.  PRNGs are used wherever random data is required such as Public Key (PK)
+key generation.  There is a universal structure called ``prng\_state''.  To initialize a PRNG call:
+\index{PRNG start}
+\begin{verbatim}
+int XXX_start(prng_state *prng);
+\end{verbatim}
+
+This will setup the PRNG for future use and not seed it.  In order for the PRNG to be cryptographically useful you must give it 
+entropy.  Ideally you'd have some OS level source to tap like in UNIX.  To add entropy to the PRNG call:
+\index{PRNG add\_entropy}
+\begin{verbatim}
+int XXX_add_entropy(const unsigned char *in, unsigned long inlen, 
+                    prng_state *prng);
+\end{verbatim}
+
+Which returns {\bf CRYPTO\_OK} if the entropy was accepted.  Once you think you have enough entropy you call another
+function to put the entropy into action.
+\index{PRNG ready}
+\begin{verbatim}
+int XXX_ready(prng_state *prng);
+\end{verbatim}
+
+Which returns {\bf CRYPTO\_OK} if it is ready.  Finally to actually read bytes call:
+\index{PRNG read}
+\begin{verbatim}
+unsigned long XXX_read(unsigned char *out, unsigned long outlen,
+                       prng_state *prng);
+\end{verbatim}
+
+Which returns the number of bytes read from the PRNG.  When you are finished with a PRNG state you call
+the following.
+
+\index{PRNG done}
+\begin{verbatim}
+void XXX_done(prng_state *prng);
+\end{verbatim}
+
+This will terminate a PRNG state and free any memory (if any) allocated.  To export a PRNG state
+so that you can later resume the PRNG call the following.
+
+\index{PRNG export}
+\begin{verbatim}
+int XXX_export(unsigned char *out, unsigned long *outlen, 
+               prng_state    *prng);
+\end{verbatim}
+
+This will write a ``PRNG state'' to the buffer ``out'' of length ``outlen'' bytes.  The idea of 
+the export is meant to be used as a ``seed file''.  That is, when the program starts up there will not likely
+be that much entropy available.   To import a state to seed a PRNG call the following function.
+
+\index{PRNG import}
+\begin{verbatim}
+int XXX_import(const unsigned char *in, unsigned long inlen, 
+                     prng_state     *prng);
+\end{verbatim}
+
+This will call the start and add\_entropy functions of the given PRNG.  It will use the state in
+``in'' of length ``inlen'' as the initial seed.  You must pass the same seed length as was exported
+by the corresponding export function.
+
+Note that importing a state will not ``resume'' the PRNG from where it left off.  That is, if you export
+a state, emit (say) 8 bytes and then import the previously exported state the next 8 bytes will not 
+specifically equal the 8 bytes you generated previously.
+
+When a program is first executed the normal course of operation is 
+
+\begin{enumerate}
+   \item Gather entropy from your sources for a given period of time or number of events.
+   \item Start, use your entropy via add\_entropy and ready the PRNG yourself.
+\end{enumerate}
+
+When your program is finished you simply call the export function and save the state to a medium (disk,
+flash memory, etc).  The next time your application starts up you can detect the state, feed it to the 
+import function and go on your way.  It is ideal that (as soon as possible) after startup you export a
+fresh state.  This helps in the case that the program aborts or the machine is powered down without
+being given a chance to exit properly.  
+
+Note that even if you have a state to import it is important to add new entropy to the state.  However,
+there is less pressure to do so.  
+
+To test a PRNG for operational conformity call the following functions.
+
+\index{PRNG test}
+\begin{verbatim}
+int XXX_test(void);
+\end{verbatim}
+
+This will return \textbf{CRYPT\_OK} if PRNG is operating properly.
+
+\subsection{Remarks}
+
+It is possible to be adding entropy and reading from a PRNG at the same time.  For example, if you first seed the PRNG
+and call ready() you can now read from it.  You can also keep adding new entropy to it.  The new entropy will not be used
+in the PRNG until ready() is called again.  This allows the PRNG to be used and re-seeded at the same time.  No real error 
+checking is guaranteed to see if the entropy is sufficient or if the PRNG is even in a ready state before reading.
+
+\subsection{Example}
+
+Below is a simple snippet to read 10 bytes from yarrow.  Its important to note that this snippet is 
+{\bf NOT} secure since the entropy added is not random.
+
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   prng_state prng;
+   unsigned char buf[10];
+   int err;
+   
+   /* start it */
+   if ((err = yarrow_start(&prng)) != CRYPT_OK) {
+      printf("Start error: %s\n", error_to_string(err));
+   }
+   /* add entropy */
+   if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) {
+      printf("Add_entropy error: %s\n", error_to_string(err));
+   }
+   /* ready and read */
+   if ((err = yarrow_ready(&prng)) != CRYPT_OK) {
+      printf("Ready error: %s\n", error_to_string(err));
+   }
+   printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng));
+   return 0;
+}
+\end{verbatim}
+
+\section{PRNG Descriptors}
+\index{PRNG Descriptor}
+PRNGs have descriptors too (surprised?). Stored in the structure ``prng\_descriptor''.  The format of an element is:
+\begin{verbatim}
+struct _prng_descriptor {
+    char *name;
+    int  export_size;    /* size in bytes of exported state */
+    int (*start)      (prng_state *);
+    int (*add_entropy)(const unsigned char *, unsigned long, prng_state *);
+    int (*ready)      (prng_state *);
+    unsigned long (*read)(unsigned char *, unsigned long len, prng_state *);
+    void (*done)(prng_state *);
+    int (*export)(unsigned char *, unsigned long *, prng_state *);
+    int (*import)(const unsigned char *, unsigned long, prng_state *);
+    int (*test)(void);
+};
+\end{verbatim}
+
+There is a ``int find\_prng(char *name)'' function as well.  Returns -1 if the PRNG is not found, otherwise it returns
+the position in the prng\_descriptor array.
+
+Just like the ciphers and hashes you must register your prng before you can use it.  The two functions provided work
+exactly as those for the cipher registry functions.  They are:
+\begin{verbatim}
+int register_prng(const struct _prng_descriptor *prng);
+int unregister_prng(const struct _prng_descriptor *prng);
+\end{verbatim}
+
+\subsection{PRNGs Provided}
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|l|}
+\hline \textbf{Name} & \textbf{Descriptor} & \textbf{Usage} \\
+\hline Yarrow & yarrow\_desc & Fast short-term PRNG \\
+\hline Fortuna & fortuna\_desc & Fast long-term PRNG (recommended) \\
+\hline RC4 & rc4\_desc & Stream Cipher \\
+\hline SOBER-128 & sober128\_desc & Stream Cipher (also very fast PRNG) \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{List of Provided PRNGs}
+\end{figure}
+
+\subsubsection{Yarrow}
+Yarrow is fast PRNG meant to collect an unspecified amount of entropy from sources 
+(keyboard, mouse, interrupts, etc) and produce an unbounded string of random bytes.  
+
+\textit{Note:} This PRNG is still secure for most taskings but is no longer recommended.  Users
+should use Fortuna instead.
+
+\subsubsection{Fortuna}
+
+Fortuna is a fast attack tolerant and more thoroughly designed PRNG suitable for long term
+usage.  It is faster than the default implementation of Yarrow\footnote{Yarrow has been implemented
+to work with most cipher and hash combos based on which you have chosen to build into the library.} while
+providing more security.  
+
+Fortuna is slightly less flexible than Yarrow in the sense that it only works with the AES block cipher 
+and SHA--256 hash function.  Technically Fortuna will work with any block cipher that accepts a 256--bit
+key and any hash that produces at least a 256--bit output.  However, to make the implementation simpler
+it has been fixed to those choices.
+
+Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being 
+added to the PRNG learn far less about the state than that of Yarrow.  Without getting into to many
+details Fortuna has the ability to recover from state determination attacks where the attacker starts
+to learn information from the PRNGs output about the internal state.  Yarrow on the other hand cannot 
+recover from that problem until new entropy is added to the pool and put to use through the ready() function.
+
+\subsubsection{RC4}
+
+RC4 is an old stream cipher that can also double duty as a PRNG in a pinch.  You ``key'' it by
+calling add\_entropy() and setup the key by calling ready().  You can only add upto 256 bytes via
+add\_entropy().  
+
+When you read from RC4 the output of the RC4 algorithm is XOR'd against your buffer you provide.  In this
+manner you can use rc4\_read() as an encrypt (and decrypt) function.  
+
+You really shouldn't use RC4 anymore.  This isn't because RC4 is weak (though biases are known to exist) just
+simply that faster alternatives exist.
+
+\subsubsection{SOBER-128}
+
+SOBER-128 is a stream cipher designed by the QUALCOMM Australia team.  Like RC4 you ``key'' it by 
+calling add\_entropy().  There is no need to call ready() for this PRNG as it does not do anything.  
+
+Note that this cipher has several oddities about how it operates.  The first time you call 
+add\_entropy() that sets the cipher's key.  Every other time you call the same function it sets
+the cipher's IV variable.  The IV mechanism allows you to encrypt several messages with the same
+key and not re--use the same key material.
+
+Unlike Yarrow and Fortuna all of the entropy (and hence security) of this algorithm rests in the data
+you pass it on the first call to add\_entropy().  All buffers sent to add\_entropy() must have a length
+that is a multiple of four bytes.
+
+Like RC4 the output of SOBER--128 is XOR'ed against the buffer you provide it.  In this manner you can use
+sober128\_read() as an encrypt (and decrypt) function.
+
+Since SOBER-128 has a fixed keying scheme and is very fast (faster than RC4) the ideal usage of SOBER-128 is to 
+key it from the output of Fortuna (or Yarrow) and use it to encrypt messages.  It is also ideal for
+simulations which need a high quality (and fast) stream of bytes.  
+
+\subsubsection{Example Usage}
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   prng_state prng;
+   unsigned char buf[32];
+   int err;
+
+   if ((err = rc4_start(&prng)) != CRYPT_OK) {
+      printf("RC4 init error: %s\n", error_to_string(err));
+      exit(-1);
+   }
+
+   /* use ``key'' as the key */
+   if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) {
+      printf("RC4 add entropy error: %s\n", error_to_string(err));
+      exit(-1);
+   }
+
+   /* setup RC4 for use */
+   if ((err = rc4_ready(&prng)) != CRYPT_OK) {
+      printf("RC4 ready error: %s\n", error_to_string(err));
+      exit(-1);
+   }
+
+   /* encrypt buffer */
+   strcpy(buf,"hello world");
+   if (rc4_read(buf, 11, &prng) != 11) {
+      printf("RC4 read error\n");
+      exit(-1);
+   }
+   return 0;
+}   
+\end{verbatim}
+\end{small}
+To decrypt you have to do the exact same steps.  
+
+\section{The Secure RNG}
+\index{Secure RNG}
+An RNG is related to a PRNG except that it doesn't expand a smaller seed to get the data.  They generate their random bits
+by performing some computation on fresh input bits.  Possibly the hardest thing to get correctly in a cryptosystem is the 
+PRNG.  Computers are deterministic beasts that try hard not to stray from pre-determined paths.  That makes gathering 
+entropy needed to seed the PRNG a hard task.  
+
+There is one small function that may help on certain platforms:
+\index{rng\_get\_bytes()}
+\begin{verbatim}
+unsigned long rng_get_bytes(unsigned char *buf, unsigned long len, 
+                  void (*callback)(void));
+\end{verbatim}
+
+Which will try one of three methods of getting random data.  The first is to open the popular ``/dev/random'' device which 
+on most *NIX platforms provides cryptographic random bits\footnote{This device is available in Windows through the Cygwin compiler suite.  It emulates ``/dev/random'' via the Microsoft CSP.}.  
+The second method is to try the Microsoft Cryptographic Service Provider and read the RNG.  The third method is an ANSI C 
+clock drift method that is also somewhat popular but gives bits of lower entropy.  The ``callback'' parameter is a pointer to a function that returns void.  Its used when the slower ANSI C RNG must be 
+used so the calling application can still work.  This is useful since the ANSI C RNG has a throughput of three 
+bytes a second.  The callback pointer may be set to {\bf NULL} to avoid using it if you don't want to.  The function 
+returns the number of bytes actually read from any RNG source.  There is a function to help setup a PRNG as well:
+\index{rng\_make\_prng()}
+\begin{verbatim}
+int rng_make_prng(int bits, int wprng, prng_state *prng, 
+                  void (*callback)(void));
+\end{verbatim}
+This will try to setup the prng with a state of at least ``bits'' of entropy.  The ``callback'' parameter works much like
+the callback in ``rng\_get\_bytes()''.  It is highly recommended that you use this function to setup your PRNGs unless you have a
+platform where the RNG doesn't work well.  Example usage of this function is given below.
+
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   ecc_key mykey;
+   prng_state prng;
+   int err;
+
+   /* register yarrow */
+   if (register_prng(&yarrow_desc) == -1) {
+      printf("Error registering Yarrow\n");
+      return -1;
+   }
+
+   /* setup the PRNG */
+   if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
+      printf("Error setting up PRNG, %s\n", error_to_string(err));
+      return -1;
+   }
+
+   /* make a 192-bit ECC key */
+   if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) {
+      printf("Error making key: %s\n", error_to_string(err));
+      return -1;
+   }
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+\subsection{The Secure PRNG Interface}
+It is possible to access the secure RNG through the PRNG interface and in turn use it within dependent functions such
+as the PK API.  This simplifies the cryptosystem on platforms where the secure RNG is fast.  The secure PRNG never 
+requires to be started, that is you need not call the start, add\_entropy or ready functions.  For example, consider
+the previous example using this PRNG.
+
+\begin{small}
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   ecc_key mykey;
+   int err;
+
+   /* register SPRNG */
+   if (register_prng(&sprng_desc) == -1) {
+      printf("Error registering SPRNG\n");
+      return -1;
+   }
+
+   /* make a 192-bit ECC key */
+   if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) {
+      printf("Error making key: %s\n", error_to_string(err));
+      return -1;
+   }
+   return 0;
+}
+\end{verbatim}
+\end{small}
+
+
+
+\chapter{RSA Public Key Cryptography}
+
+\section{Introduction}
+RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography.  In the specifications are
+padding algorithms for encryption and signatures.  The standard includes the ``v2.1'' algorithms.
+To simplify matters a little the v2.1 encryption and signature padding algorithms are called OAEP and PSS 
+respectively.  
+
+\section{PKCS \#1 Encryption}
+
+PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation.  As far as this portion of
+the library is concerned we are only dealing with th OAEP padding of the message.
+
+\subsection{OAEP Encoding}
+
+\index{pkcs\_1\_oaep\_encode()}
+\begin{alltt}
+int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
+                       const unsigned char *lparam, unsigned long lparamlen,
+                             unsigned long modulus_bitlen, prng_state *prng,
+                             int           prng_idx,         int  hash_idx,
+                             unsigned char *out,    unsigned long *outlen);
+\end{alltt}
+
+This accepts ``msg'' as input of length ``msglen'' which will be OAEP padded.  The ``lparam'' variable is an additional system specific
+tag that can be applied to the encoding.  This is useful to identify which system encoded the message.  If no variance is desired then
+``lparam'' can be set to \textbf{NULL}.  
+
+OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output.  This is passed as the parameter
+``modulus\_bitlen''.  ``hash\_idx'' is the index into the hash descriptor table of the hash desired.  PKCS \#1 allows any hash to be 
+used but both the encoder and decoder must use the same hash in order for this to succeed.  The size of hash output affects the maximum
+ sized input message.  ``prng\_idx'' and ``prng'' are the random number generator arguments required to randomize the padding process.  
+The padded message is stored in ``out'' along with the length in ``outlen''.
+
+If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for ``msg'' is 
+$m - 2h - 2$.  For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes.  
+
+Note that when the message is padded it still has not been RSA encrypted.  You must pass the output of this function to 
+rsa\_exptmod() to encrypt it. 
+
+\subsection{OAEP Decoding}
+
+\index{pkcs\_1\_oaep\_decode()}
+\begin{alltt}
+int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
+                       const unsigned char *lparam, unsigned long lparamlen,
+                             unsigned long modulus_bitlen, int hash_idx,
+                             unsigned char *out,    unsigned long *outlen,
+                             int           *res);
+\end{alltt}
+
+This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder.  ``msg'' is the 
+output of pkcs\_1\_oaep\_encode() of length ``msglen''.  ``lparam'' is the same system variable passed to the OAEP encoder.  If it does not
+match what was used during encoding this function will not decode the packet.  ``modulus\_bitlen'' is the size of the RSA modulus in bits
+and must match what was used during encoding.  Similarly the ``hash\_idx'' index into the hash descriptor table must match what was used
+during encoding.
+
+If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen'' and stores a 
+$1$ in ``res''.  If the packet is invalid it stores $0$ in ``res'' and if the function fails for another reason
+it returns an error code.  
+
+\section{PKCS \#1 Digital Signatures}
+
+\subsection{PSS Encoding}
+PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed.  
+
+\index{pkcs\_1\_pss\_encode()}
+\begin{alltt}
+int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
+                            unsigned long saltlen,  prng_state   *prng,     
+                            int           prng_idx, int           hash_idx,
+                            unsigned long modulus_bitlen,
+                            unsigned char *out,     unsigned long *outlen);
+\end{alltt}
+
+This function assumes the message to be PSS encoded has previously been hashed.  The input hash ``msghash'' is of length 
+``msghashlen''.  PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process.  
+``hash\_idx'' is the index into the hash descriptor table of the hash to use.  ``prng\_idx'' and ``prng'' are the random
+number generator information required for the salt.
+
+Similar to OAEP encoding ``modulus\_bitlen'' is the size of the RSA modulus (in bits).  It limits the size of the salt.  If $m$ is the length
+of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt.  
+
+This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod().
+
+\subsection{PSS Decoding}
+
+To decode a PSS encoded signature block you have to use the following.
+
+\index{pkcs\_1\_pss\_decode()}
+\begin{alltt}
+int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
+                      const unsigned char *sig,     unsigned long siglen,
+                            unsigned long saltlen,  int           hash_idx,
+                            unsigned long modulus_bitlen, int    *res);
+\end{alltt}
+This will decode the PSS encoded message in ``sig'' of length ``siglen'' and compare it to values in ``msghash'' of length
+``msghashlen''.  If the block is a valid PSS block and the decoded hash equals the hash supplied ``res'' is set to non--zero.  Otherwise, 
+it is set to zero.  The rest of the parameters are as in the PSS encode call.
+
+It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work.
+
+\section{RSA Operations}
+\subsection{Background}
+
+RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown 
+factorization.  Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are
+not strictly equivalent.
+
+The system begins with with two primes $p$ and $q$ and their product $N = pq$.  The order or ``Euler totient'' of the
+multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to 
+$\mbox{lcm}(p - 1, q - 1)$.  The public key consists of the composite $N$ and some integer $e$ such that 
+$\mbox{gcd}(e, \phi(N)) = 1$.  The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$ 
+often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$.
+
+A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that 
+$1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$.  Since finding the inverse exponent $d$
+given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute
+$C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$.  Similarly the owner of the private key 
+can sign a message by ``decrypting'' it.  Others can verify it by ``encrypting'' it.  
+
+Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other.  
+Ideally $e$ should be larger than $100$ to prevent direct analysis.  For example, if $e$ is three and you do not pad
+the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial.  
+The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well 
+designed for fast exponentiation (requires 16 squarings and one multiplication).
+
+It is important to pad the input to RSA since it has particular mathematical structure.  For instance  
+$M_1^dM_2^d = (M_1M_2)^d$ which can be used to forge a signature.  Suppose $M_3 = M_1M_2$ is a message you want
+to have a forged signature for.  Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result
+together.  Similar tricks can be used to deduce plaintexts from ciphertexts.  It is important not only to sign 
+the hash of documents only but also to pad the inputs with data to remove such structure.  
+
+\subsection{RSA Key Generation}
+
+For RSA routines a single ``rsa\_key'' structure is used.  To make a new RSA key call:
+\index{rsa\_make\_key()}
+\begin{verbatim}
+int rsa_make_key(prng_state *prng, 
+                 int wprng, int size, 
+                 long e, rsa_key *key);
+\end{verbatim}
+
+Where ``wprng'' is the index into the PRNG descriptor array.  ``size'' is the size in bytes of the RSA modulus desired.
+``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537.  I suggest you stick with 65537 since its big
+enough to prevent trivial math attacks and not super slow.  ``key'' is where the key is placed.  All keys must be at 
+least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
+
+Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key.  Make sure to call 
+``rsa\_free()'' (see below) when you are finished with the key.  If ``rsa\_make\_key()'' fails it will automatically 
+free the ram allocated itself.
+
+\index{PK\_PRIVATE} \index{PK\_PUBLIC}
+There are two types of RSA keys.  The types are {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}.  The first type is a private 
+RSA key which includes the CRT parameters\footnote{As of v0.99 the PK\_PRIVATE\_OPTIMIZED type has been deprecated
+and has been replaced by the PK\_PRIVATE type.} in the form of a RSAPrivateKey.  The second type is a public RSA key
+which only includes the modulus and public exponent.  It takes the form of a RSAPublicKey.
+
+\subsection{RSA Exponentiation}
+
+To do raw work with the RSA function call:
+\index{rsa\_exptmod()}
+\begin{verbatim}
+int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long *outlen, 
+                      int which, prng_state *prng, int prng_idx,
+                      rsa_key *key);
+\end{verbatim}
+This loads the bignum from ``in'' as a big endian word in the format PKCS specifies, raises it to either ``e'' or ``d'' and stores the result
+in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e'' 
+(i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing).
+
+Note that the output of his function is zero-padded as per PKCS \#1 specifications.  This allows this routine to 
+interoprate with PKCS \#1 padding functions properly.
+
+\subsection{RSA Key Encryption}
+Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message.
+To facilitate encrypting short keys the following functions have been provided.
+
+\index{rsa\_encrypt\_key()}
+\begin{verbatim}
+int rsa_encrypt_key(const unsigned char *in,  unsigned long inlen,
+                          unsigned char *out, unsigned long *outlen,
+                    const unsigned char *lparam, unsigned long lparamlen,
+                    prng_state *prng, int prng_idx, int hash_idx, rsa_key *key);
+\end{verbatim}
+This function will OAEP pad ``in'' of length inlen bytes then RSA encrypt it and store the ciphertext
+in ``out'' of length ``outlen''.  The ``lparam'' and ``lparamlen'' are the same parameters you would pass
+to pkcs\_1\_oaep\_encode().
+
+\index{rsa\_decrypt\_key()}
+\begin{verbatim}
+int rsa_decrypt_key(const unsigned char *in,  unsigned long inlen,
+                          unsigned char *out, unsigned long *outlen, 
+                    const unsigned char *lparam, unsigned long lparamlen,
+                          int            hash_idx, int *stat,
+                          rsa_key       *key);
+\end{verbatim}
+This function will RSA decrypt ``in'' of length ``inlen'' then OAEP depad the resulting data and store it in
+``out'' of length ``outlen''.  The ``lparam'' and ``lparamlen'' are the same parameters you would pass
+to pkcs\_1\_oaep\_decode().
+
+If the RSA decrypted data isn't a valid OAEP packet then ``stat'' is set to $0$.  Otherwise, it is set to $1$.
+
+\subsection{RSA Hash Signatures}
+Similar to RSA key encryption RSA is also used to ``digitally sign'' message digests (hashes).  To facilitate this
+process the following functions have been provided.
+
+\index{rsa\_sign\_hash()}
+\begin{verbatim}
+int rsa_sign_hash(const unsigned char *in,   unsigned long  inlen, 
+                        unsigned char *out,  unsigned long *outlen, 
+                        prng_state    *prng,     int            prng_idx,
+                        int            hash_idx, unsigned long  saltlen,
+                        rsa_key *key);
+\end{verbatim}
+
+This will PSS encode the message hash ``in'' of length ``inlen''.  Next the PSS encoded message will be RSA ``signed'' and 
+the output is stored in ``out'' of length ``outlen''.  
+
+
+\index{rsa\_verify\_hash()}
+\begin{verbatim}
+int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
+                    const unsigned char *msghash,  unsigned long msghashlen,
+                          int            hash_idx, unsigned long saltlen,
+                          int           *stat,     rsa_key      *key);
+\end{verbatim}
+
+This will RSA ``verify'' the signature in ``sig'' of length ``siglen''.  Next the RSA decoded data is PSS decoded
+and the extracted hash is compared against the message hash ``msghash'' of length ``msghashlen''.
+
+If the RSA decoded data is not a valid PSS message or if the PSS decoded hash does not match the ``msghash'' 
+the value ``res'' is set to $0$.  Otherwise, if the function succeeds and signature is valid ``res'' is set
+to $1$.
+
+\begin{verbatim}
+#include <tomcrypt.h>
+int main(void)
+{
+   int           err, hash_idx, prng_idx, res;
+   unsigned long l1, l2;
+   unsigned char pt[16], pt2[16], out[1024];
+   rsa_key       key;
+
+   /* register prng/hash */
+   if (register_prng(&sprng_desc) == -1) {
+      printf("Error registering sprng");
+      return EXIT_FAILURE;
+   }
+
+   if (register_hash(&sha1_desc) == -1) {
+      printf("Error registering sha1");
+      return EXIT_FAILURE;
+   }
+   hash_idx = find_hash("sha1");
+   prng_idx = find_prng("sprng");
+
+   /* make an RSA-1024 key */
+   if ((err = rsa_make_key(NULL,     /* PRNG state */
+                           prng_idx, /* PRNG idx */
+                           1024/8,   /* 1024-bit key */
+                           65537,    /* we like e=65537 */
+                           &key)     /* where to store the key */
+       ) != CRYPT_OK) {
+       printf("rsa_make_key %s", error_to_string(err));
+       return EXIT_FAILURE;
+   }
+
+   /* fill in pt[] with a key we want to send ... */
+   l1 = sizeof(out);
+   if ((err = rsa_encrypt_key(pt,    /* data we wish to encrypt */
+                              16,    /* data is 16 bytes long */
+                             out,    /* where to store ciphertext */
+                             &l1,    /* length of ciphertext */
+                       "TestApp",    /* our lparam for this program */
+                               7,    /* lparam is 7 bytes long */
+                            NULL,    /* PRNG state */
+                        prng_idx,    /* prng idx */
+                        hash_idx,    /* hash idx */
+                            &key)    /* our RSA key */
+       ) != CRYPT_OK) {
+       printf("rsa_encrypt_key %s", error_to_string(err));
+       return EXIT_FAILURE;
+   }
+
+   /* now let's decrypt the encrypted key */
+   l2 = sizeof(pt2);
+   if ((err = rsa_decrypt_key(out, /* encrypted data */
+                               l1, /* length of ciphertext */
+                              pt2, /* where to put plaintext */
+                              &l2, /* plaintext length */
+                        "TestApp", /* lparam for this program */
+                                7, /* lparam is 7 bytes long */
+                         hash_idx, /* hash idx */
+                             &res, /* validity of data */
+                             &key) /* our RSA key */ 
+        ) != CRYPT_OK) {
+       printf("rsa_decrypt_key %s", error_to_string(err));
+       return EXIT_FAILURE;
+   }
+   /* if all went well pt == pt2, l2 == 16, res == 1 */
+}
+\end{verbatim}
+
+
+\chapter{Diffie-Hellman Key Exchange}
+
+\section{Background}
+
+Diffie-Hellman was the original public key system proposed.  The system is based upon the group structure
+of finite fields.  For Diffie-Hellman a prime $p$ is chosen and a ``base'' $b$ such that $b^x\mbox{ }(\mbox{mod }p)$ 
+generates a large sub-group of prime order (for unique values of $x$).
+
+A secret key is an exponent $x$ and a public key is the value of $y \equiv g^x\mbox{ }(\mbox{mod }p)$.  The term
+``discrete logarithm'' denotes the action of finding $x$ given only $y$, $g$ and $p$.  The key exchange part of
+Diffie-Hellman arises from the fact that two users A and B with keys $(A_x, A_y)$ and $(B_x, B_y)$ can exchange 
+a shared key $K \equiv B_y^{A_x} \equiv A_y^{B_x} \equiv g^{A_xB_x}\mbox{ }(\mbox{mod }p)$.
+
+From this public encryption and signatures can be developed.  The trivial way to encrypt (for example) using a public key 
+$y$ is to perform the key exchange offline.  The sender invents a key $k$ and its public copy 
+$k' \equiv g^k\mbox{ }(\mbox{mod }p)$ and uses $K \equiv k'^{A_x}\mbox{ }(\mbox{mod }p)$ as a key to encrypt
+the message with.  Typically $K$ would be sent to a one-way hash and the message digested used as a key in a 
+symmetric cipher.
+
+It is important that the order of the sub-group that $g$ generates not only be large but also prime.  There are
+discrete logarithm algorithms that take $\sqrt r$ time given the order $r$.  The discrete logarithm can be computed
+modulo each prime factor of $r$ and the results combined using the Chinese Remainder Theorem.  In the cases where