changeset 210:4768b55c5240 libtomcrypt

propagate from branch 'au.asn.ucc.matt.ltc-orig' (head 33c416b902f1a44913d825bae7ad9a160f703ed3) to branch 'au.asn.ucc.matt.dropbear.ltc' (head 4d6aec6e6121e13f68c11c149b6579c41cb63e74)
author Matt Johnston <matt@ucc.asn.au>
date Wed, 06 Jul 2005 12:10:23 +0000
parents 8be64e2c86f4 (current diff) 39d5d58461d6 (diff)
children a3e31d3983cb
files demos/small.c doc/crypt.pdf makefile makefile.msvc src/ciphers/aes/aes.c src/ciphers/des.c src/ciphers/twofish/twofish.c src/hashes/md5.c src/hashes/sha1.c src/headers/tomcrypt.h src/headers/tomcrypt_custom.h src/misc/crypt/crypt.c src/misc/mpi/mpi.c src/pk/asn1/der/der_decode_integer.c src/pk/asn1/der/der_encode_integer.c src/pk/asn1/der/der_get_multi_integer.c src/pk/asn1/der/der_length_integer.c src/pk/asn1/der/der_put_multi_integer.c src/pk/pkcs1/pkcs_1_v15_es_decode.c src/pk/pkcs1/pkcs_1_v15_es_encode.c src/pk/pkcs1/pkcs_1_v15_sa_decode.c src/pk/pkcs1/pkcs_1_v15_sa_encode.c src/pk/rsa/rsa_v15_decrypt_key.c src/pk/rsa/rsa_v15_encrypt_key.c src/pk/rsa/rsa_v15_sign_hash.c src/pk/rsa/rsa_v15_verify_hash.c
diffstat 290 files changed, 6934 insertions(+), 2583 deletions(-) [+]
line wrap: on
line diff
--- a/Doxyfile	Tue May 10 17:02:59 2005 +0000
+++ b/Doxyfile	Wed Jul 06 12:10:23 2005 +0000
@@ -23,7 +23,7 @@
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.02
+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. 
--- a/TODO	Tue May 10 17:02:59 2005 +0000
+++ b/TODO	Wed Jul 06 12:10:23 2005 +0000
@@ -1,1 +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/build.sh	Wed Jul 06 12:10:23 2005 +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 $ 
--- a/changes	Tue May 10 17:02:59 2005 +0000
+++ b/changes	Wed Jul 06 12:10:23 2005 +0000
@@ -1,3 +1,79 @@
+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()
@@ -1243,3 +1319,8 @@
        -- 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 $ */
+
--- a/crypt.tex	Tue May 10 17:02:59 2005 +0000
+++ b/crypt.tex	Wed Jul 06 12:10:23 2005 +0000
@@ -47,7 +47,7 @@
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \begin{document}
-\title{LibTomCrypt \\ Version 1.02}
+\title{LibTomCrypt \\ Version 1.05}
 \author{Tom St Denis \\
 \\
 [email protected] \\
@@ -57,7 +57,7 @@
 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{10cm}
+\vspace{15cm}
 
 \begin{flushright}Open Source.  Open Academia.  Open Minds.
 
@@ -771,13 +771,19 @@
 \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 ECB mode for obvious reasons):
+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}
@@ -789,7 +795,12 @@
 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.
 
-Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code.  
+
+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:
@@ -867,6 +878,7 @@
                            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));
@@ -1349,7 +1361,7 @@
    }
 
    /* process the plaintext */
-   if ((err = gcm_add_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) {
+   if ((err = gcm_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) {
       return err;
    }
 
@@ -1359,6 +1371,8 @@
       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);
 
@@ -2452,8 +2466,8 @@
 
 \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 ``v1.5'' and ``v2.0'' algorithms.
-To simplify matters a little the v2.0 encryption and signature padding algorithms are called OAEP and PSS 
+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}
@@ -2509,33 +2523,6 @@
 $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.  
 
-\subsection{PKCS \#1 v1.5 Encoding}
-
-\index{pkcs\_1\_v15\_es\_encode()}
-\begin{verbatim}
-int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
-                               unsigned long  modulus_bitlen, 
-                               prng_state    *prng,   int           prng_idx,
-                               unsigned char *out,    unsigned long *outlen);
-\end{verbatim}
-
-This will PKCS v1.5 encode the data in ``msg'' of length ``msglen''.  Pass the length (in bits) of your
-RSA modulus in ``modulus\_bitlen''.  The encoded data will be stored in ``out'' of length ``outlen''.
-
-\subsection{PKCS \#1 v1.5 Decoding}
-\index{pkcs\_1\_v15\_es\_decode()}
-\begin{verbatim}
-int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
-                               unsigned long modulus_bitlen,
-                               unsigned char *out,  unsigned long outlen,
-                               int           *res);
-\end{verbatim}
-
-This will PKCS v1.5 decode the message in ``msg'' of length ``msglen''.  It will store the output in ``out''. Note
-that the length of the output ``outlen'' is a constant.  This decoder cannot determine the original message 
-length.  If the data in ``msg'' is a valid packet then a $1$ is stored in ``res'', otherwise a $0$ is 
-stored.
-
 \section{PKCS \#1 Digital Signatures}
 
 \subsection{PSS Encoding}
@@ -2577,34 +2564,6 @@
 
 It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work.
 
-\subsection{PKCS \#1 v1.5 Encoding}
-
-\index{pkcs\_1\_v15\_sa\_encode()}
-\begin{verbatim}
-int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
-                               int            hash_idx, unsigned long modulus_bitlen,
-                               unsigned char *out,      unsigned long *outlen);
-\end{verbatim}
-
-This will PKCS \#1 v1.5 signature encode the message hash ``msghash''  of length ``msghashlen''.  You have
-to tell this routine which hash produced the message hash in ``hash\_idx''.  The encoded hash is stored
-in ``out'' of length ``outlen''.
-
-\subsection{PKCS \#1 v1.5 Decoding}
-
-\index{pkcs\_1\_v15\_sa\_decode()}
-\begin{verbatim}
-int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
-                         const unsigned char *sig,     unsigned long siglen,
-                               int           hash_idx, unsigned long modulus_bitlen, 
-                               int          *res);
-\end{verbatim}
-
-This will PKCS \#1 v1.5 signature decode the data in ``sig'' of length ``siglen'' and compare the extracted
-hash against ``msghash'' of length ``msghashlen''.  You have to tell this routine which hash produced the
-message digest in ``hash\_idx''.  If the packet is valid and the hashes match ``res'' is set to $1$.  Otherwise,
-it is set to $0$.
-
 \section{RSA Operations}
 \subsection{Background}
 
@@ -2698,15 +2657,14 @@
 int rsa_decrypt_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, int *res,
+                          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 ``res'' is set to $0$.  Otherwise, it is set to $1$.
+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
@@ -2729,7 +2687,6 @@
 \begin{verbatim}
 int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
                     const unsigned char *msghash,  unsigned long msghashlen,
-                          prng_state    *prng,     int           prng_idx,
                           int            hash_idx, unsigned long saltlen,
                           int           *stat,     rsa_key      *key);
 \end{verbatim}
@@ -2799,8 +2756,6 @@
                               &l2, /* plaintext length */
                         "TestApp", /* lparam for this program */
                                 7, /* lparam is 7 bytes long */
-                             NULL, /* PRNG state */
-                         prng_idx, /* prng idx */
                          hash_idx, /* hash idx */
                              &res, /* validity of data */
                              &key) /* our RSA key */ 
@@ -3060,6 +3015,33 @@
 range in order from $\approx 2^{192}$ points to $\approx 2^{521}$.  According to the source document any key size greater
 than or equal to 256-bits is sufficient for long term security.  
 
+\section{Key Format}
+LibTomCrypt uses it's own format for ECC public and private keys.  While ANSI X9.62 partially specifies key formats (it covers public keys) it does it in a less
+than ideally simple manner.  In the case of LibTomCrypt it is meant \textbf{solely} for NIST $GF(p)$ curves.  The format of the keys is as follows:
+
+\begin{small}
+\begin{verbatim}
+ECCPublicKey ::= SEQUENCE {
+    flags       BIT STRING(1), -- public/private flag (always zero), 
+    keySize     INTEGER,       -- Curve size (in bits) divided by eight 
+                               -- and rounded down, e.g. 521 => 65
+    pubkey.x    INTEGER,       -- The X co-ordinate of the public key point
+    pubkey.y    INTEGER,       -- The Y co-ordinate of the public key point
+}
+
+ECCPrivateKey ::= SEQUENCE {
+    flags       BIT STRING(1), -- public/private flag (always one), 
+    keySize     INTEGER,       -- Curve size (in bits) divided by eight 
+                               -- and rounded down, e.g. 521 => 65
+    pubkey.x    INTEGER,       -- The X co-ordinate of the public key point
+    pubkey.y    INTEGER,       -- The Y co-ordinate of the public key point
+    secret.k    INTEGER,       -- The secret key scalar
+}
+\end{verbatim}
+\end{small}
+
+The first flags bit denotes whether the key is public (zero) or private (one).  
+
 \section{Core Functions}
 
 Like the DH routines there is a key structure ``ecc\_key'' used by the functions.  There is a function to make a key:
@@ -3069,8 +3051,8 @@
                  int keysize, ecc_key *key);
 \end{verbatim}
 
-The ``keysize'' is the size of the modulus in bytes desired.  Currently directly supported values are 20, 24, 28, 32, 48 and 65 bytes which
-correspond to key sizes of 160, 192, 224, 256, 384 and 521 bits respectively.  If you pass a key size that is between any key size
+The ``keysize'' is the size of the modulus in bytes desired.  Currently directly supported values are 24, 28, 32, 48 and 65 bytes which
+correspond to key sizes of 192, 224, 256, 384 and 521 bits respectively.  If you pass a key size that is between any key size
 it will round the keysize up to the next available one.  The rest of the parameters work like they do in the ``dh\_make\_key()'' function.  
 To free the ram allocated by a key call:
 \index{ecc\_free()}
@@ -3129,11 +3111,23 @@
                           ecc_key *key);
 \end{verbatim}
 
-Where ``in'' is an input symmetric key of no more than 32 bytes.  Essentially these routines created a random public key
+Where ``in'' is an input symmetric key of no more than 64 bytes.  Essentially these routines created a random public key
 and find the hash of the shared secret.  The message digest is than XOR'ed against the symmetric key.  All of the required
 data is placed in ``out'' by ``ecc\_encrypt\_key()''.   The hash chosen must produce a message digest at least as large
 as the symmetric key you are trying to share.
 
+\subsection{Encrypt Packet Format}
+
+The packet format for the encrypted keys is the following ASN.1 SEQUENCE:
+
+\begin{verbatim}
+ECCEncrypt ::= SEQUENCE {
+   hashID        OBJECT IDENTIFIER, -- OID of hash used
+   pubkey        OCTET STRING     , -- Encapsulated ECCPublicKey (see above)
+   skey          OCTET STRING       -- xor of plaintext and "hash of shared secret"
+}
+\end{verbatim}
+
 There are also functions to sign and verify the hash of a message.
 \index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()}
 \begin{verbatim}
@@ -3150,12 +3144,14 @@
 The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''.  It sets ``stat''
 to non-zero if the signature passes or zero if it fails.
 
+\subsection{Signature Format}
+The signature code is an implementation of X9.62 EC-DSA and the output is comformant for GF(p) curves.
 
 \section{ECC Keysizes}
 With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems.  The math will still work
 and in effect the signature will still work.  With ECC keys the strength of the signature is limited by the size of
-the hash or the size of they key, whichever is smaller.  For example, if you sign with SHA256 and a ECC-160 key in effect
-you have 160-bits of security (e.g. as if you signed with SHA-1).  
+the hash or the size of they key, whichever is smaller.  For example, if you sign with SHA256 and an ECC-192 key in effect
+you have 192-bits of security.  
 
 The library will not warn you if you make this mistake so it is important to check yourself before using the 
 signatures.
@@ -3170,6 +3166,38 @@
 The API for the DSA is essentially the same as the other PK algorithms.  Except in the case of DSA no encryption or
 decryption routines are provided.  
 
+\section{Key Format}
+Since no useful public standard for DSA key storage was presented to me during the course of this development I made my own ASN.1 SEQUENCE which I document
+now so that others can interoperate with this library.
+
+\begin{verbatim}
+DSAPublicKey ::= SEQUENCE {
+    publicFlags    BIT STRING(1), -- must be 0
+    g              INTEGER      , -- base generator, check that g^q mod p == 1
+                                  -- and that 1 < g < p - 1
+    p              INTEGER      , -- prime modulus 
+    q              INTEGER      , -- order of sub-group (must be prime)
+    y              INTEGER      , -- public key, specifically, g^x mod p, 
+                                  -- check that y^q mod p == 1
+                                  -- and that 1 < y < p - 1
+}
+
+DSAPrivateKey ::= SEQUENCE {
+    publicFlags    BIT STRING(1), -- must be 1
+    g              INTEGER      , -- base generator, check that g^q mod p == 1
+                                  -- and that 1 < g < p - 1
+    p              INTEGER      , -- prime modulus 
+    q              INTEGER      , -- order of sub-group (must be prime)
+    y              INTEGER      , -- public key, specifically, g^x mod p, 
+                                  -- check that y^q mod p == 1
+                                  -- and that 1 < y < p - 1
+    x              INTEGER        -- private key
+}
+\end{verbatim}
+
+The leading BIT STRING has a single bit in it which is zero for public keys and one for private keys.  This makes the structure uniquely decodable and easy
+to work with.
+
 \section{Key Generation}
 To make a DSA key you must call the following function
 \begin{verbatim}
@@ -3291,79 +3319,351 @@
 will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()).  
 
 \chapter{Standards Support}
-\section{DER Support}
-DER or ``Distinguished Encoding Rules'' is a subset of the ASN.1 encoding rules that is fully deterministic and
-ideal for cryptography.  In particular ASN.1 specifies an INTEGER type for storing arbitrary sized integers.  DER
-further limits the ASN.1 specifications to a deterministic encoding.
-
-\subsection{Storing INTEGER types}
-\index{der\_encode\_integer()}
-\begin{alltt}
-int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen);
-\end{alltt}
-
-This will store the integer in ``num'' to the output buffer ``out'' of length ``outlen''.  It only stores
-non--negative numbers.  It stores the number of octets used back in ``outlen''.
-
-\subsection{Reading INTEGER types}
-\index{der\_decode\_integer()}
-\begin{alltt}
-int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num);
-\end{alltt}
-This will decode the DER encoded INTEGER in ``in'' of length ``inlen'' and store the resulting integer
-in ``num''.  It will store the bytes read in ``inlen'' which is handy if you have to parse multiple
-data items out of a binary packet.
-
-\subsection{INTEGER length}
-\index{der\_length\_integer()}
-\begin{alltt}
-int der_length_integer(mp_int *num, unsigned long *len);
-\end{alltt}
-This will determine the length of the DER encoding of the integer ``num'' and store it in ``len''.
-
-\subsection{Multiple INTEGER types}
-To simplify the DER encoding/decoding there are two functions two handle multple types at once.
-
-\index{der\_put\_multi\_integer()}
-\index{der\_get\_multi\_integer()}
-\begin{alltt}
-int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, mp_int *num, ...);
-int der_get_multi_integer(const unsigned char *src, unsigned long *inlen,  mp_int *num, ...);
-\end{alltt}
-
-These will handle multiple encodings/decodings at once.  They work like their single operand counterparts
-except they handle a \textbf{NULL} terminated list of operands.
+\section{ASN.1 Formats}
+LibTomCrypt supports a variety of ASN.1 data types encoded with the Distinguished Encoding Rules (DER) suitable for various cryptographic protocols.  The data types
+are all provided with three basic functions with \textit{similar} prototypes.  One function has been dedicated to calculate the length in octets of a given
+format and two functions have been dedicated to encoding and decoding the format.  
+
+On top of the basic data types are the SEQUENCE and\footnote{Planned for LTC 1.06} SET data types which are collections of other ASN.1 types.  They are provided 
+in the same manner as the other data types except they use list of objects known as the \textbf{ltc\_asn1\_list} structure.  It is defined as 
+
+\index{ltc\_asn1\_list structure}
+\begin{verbatim}
+typedef struct {
+   int           type;
+   void         *data;
+   unsigned long size;
+   int           used;
+} ltc_asn1_list;
+\end{verbatim}
+
+The ``type'' field is one of the following ASN.1 field definitions.  The ``data'' pointer is a void pointer to the data to be encoded (or the destination) and the 
+``size'' field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type).  The ``used'' field is primarily for the CHOICE decoder
+and reflects if the particular member of a list was the decoded data type.  To help build the lists in an orderly fashion the macro
+``LTC\_SET\_ASN1(list, index, Type, Data, Size)'' has been provided.
+
+It will assign to the ``index''th position in the ``list'' the tripplet (Type, Data, Size).  An example usage would be:
+
+\begin{small}
+\begin{verbatim}
+...
+ltc_asn1_list   sequence[3];
+unsigned long   three=3;
+
+LTC_SET_ASN1(sequence, 0, LTC_ASN1_IA5_STRING,    "hello", 5);
+LTC_SET_ASN1(sequence, 1, LTC_ASN1_SHORT_INTEGER, &three,  1);
+LTC_SET_ASN1(sequence, 2, LTC_ASN1_NULL,           NULL,   0);
+\end{verbatim}
+\end{small}
+
+The macro is relatively safe with respect to modifying variables, for instance the following code is equivalent.
+
+\begin{small}
+\begin{verbatim}
+...
+ltc_asn1_list   sequence[3];
+unsigned long   three=3;
+int             x=0;
+LTC_SET_ASN1(sequence, x++, LTC_ASN1_IA5_STRING,    "hello", 5);
+LTC_SET_ASN1(sequence, x++, LTC_ASN1_SHORT_INTEGER, &three,  1);
+LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL,           NULL,   0);
+\end{verbatim}
+\end{small}
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|l|l|}
+\hline \textbf{Definition}           & \textbf{ASN.1 Type} \\
+\hline LTC\_ASN1\_EOL                & End of a ASN.1 list structure. \\
+\hline LTC\_ASN1\_INTEGER            & INTEGER (uses mp\_int) \\
+\hline LTC\_ASN1\_SHORT\_INTEGER     & INTEGER (32--bit using unsigned long) \\
+\hline LTC\_ASN1\_BIT\_STRING        & BIT STRING (one bit per char) \\
+\hline LTC\_ASN1\_OCTET\_STRING      & OCTET STRING (one octet per char) \\
+\hline LTC\_ASN1\_NULL               & NULL \\
+\hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER (words are in unsigned long) \\
+\hline LTC\_ASN1\_IA5\_STRING        & IA5 STRING (one octet per char) \\
+\hline LTC\_ASN1\_PRINTABLE\_STRING  & PRINTABLE STIRNG (one octet per char) \\
+\hline LTC\_ASN1\_UTCTIME            & UTCTIME (see ltc\_utctime structure) \\
+\hline LTC\_ASN1\_SEQUENCE           & SEQUENCE OF \\
+\hline LTC\_ASN1\_CHOICE             & CHOICE \\
+\hline
+\end{tabular}
+\caption{List of ASN.1 Supported Types}
+\end{small}
+\end{center}
+\end{figure}
+
+\subsection{SEQUENCE Type}
+The SEQUENCE data type is a collection of other ASN.1 data types encapsulated with a small header which is a useful way of sending multiple data types in one packet.
+
+\subsubsection{SEUQNECE Encoding}
+To encode a sequence a \textbf{ltc\_asn1\_list} array must be initialized with the members of the sequence and their respective pointers.  The encoding is performed
+with the following function.
+
+\index{der\_encode\_sequence()}
+\begin{verbatim}
+int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned char *out,  unsigned long *outlen);
+\end{verbatim}
+This encodes a sequence of items pointed to by ``list'' where the list has ``inlen'' items in it.  The SEQUENCE will be encoded to ``out'' and of length ``outlen''.  The
+function will terminate when it reads all the items out of the list (upto ``inlen'') or it encounters an item in the list with a type of \textbf{LTC\_ASN1\_EOL}.
+
+The ``data'' pointer in the list would be the same pointer you would pass to the respective ASN.1 encoder (e.g. der\_encode\_bit\_string()) and it is simply passed on
+verbatim to the dependent encoder.  The list can contain other SEQUENCE or SET types which enables you to have nested SEQUENCE and SET definitions.  In these cases
+the ``data'' pointer is simply a pointer to another \textbf{ltc\_asn1\_list}.
+
+\subsubsection{SEQUENCE Decoding}
+
+\index{der\_decode\_sequence()}
+
+Decoding a SEQUENCE is similar to encoding.  You set up an array of \textbf{ltc\_asn1\_list} where in this case the ``size'' member is the maximum size 
+(in certain cases).  For types such as IA5 STRING, BIT STRING, OCTET STRING (etc) the ``size'' field is updated after successful decoding to reflect how many
+units of the respective type has been loaded.  
+
+\begin{verbatim}
+int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
+                              ltc_asn1_list *list, unsigned long  outlen);
+\end{verbatim}
+
+This will decode upto ``outlen'' items from the input buffer ``in'' of length ``inlen'' octets.  The function will stop (gracefully) when it runs out of items to decode.
+It will fail (for among other reasons) when it runs out of input bytes to read, a data type is invalid or a heap failure occured.
+
+For the following types the ``size'' field will be updated to reflect the number of units read of the given type.
+\begin{enumerate}
+   \item BIT STRING
+   \item OCTET STRING
+   \item OBJECT IDENTIFIER
+   \item IA5 STRING
+   \item PRINTABLE STRING
+\end{enumerate}
+
+\subsubsection{SEQUENCE Length}
+
+The length of a SEQUENCE can be determined with the following function.
+
+\index{der\_length\_sequence()}
+\begin{verbatim}
+int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned long *outlen);
+\end{verbatim}
+
+This will get the encoding size for the given ``list'' of length ``inlen'' and store it in ``outlen''.  
+
+\subsubsection{SEQUENCE Multiple Argument Lists}
+
+For small or simple sequences an encoding or decoding can be performed with one of the following two functions.
+
+\index{der\_encode\_sequence\_multi()}
+\index{der\_decode\_sequence\_multi()}
 
 \begin{verbatim}
-#include <tomcrypt.h>
-int main(void)
-{
-   mp_int        a, b, c, d;
-   unsigned char buffer[1000];
-   unsigned long len;
-   int           err;
-
-   /* init a,b,c,d with some values ... */
-
-   /* ok we want to store them now... */
-   len = sizeof(buffer);
-   if ((err = der_put_multi_integer(buffer, &len, 
-                                    &a, &b, &c, &d, NULL)) != CRYPT_OK) {
-      // error
-   }
-   printf("I stored %lu bytes in buf\n", len);
-
-   /* ok say we want to get them back for fun */
-   /* len set previously...otherwise set it to the size of the packet */
-   if ((err = der_get_multi_integer(buffer, &len,
-                                    &a, &b, &c, &d, NULL)) != CRYPT_OK) {
-      // error
-   }
-   printf("I read %lu bytes from buf\n", len);
-}
+int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
+int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
+\end{verbatim}
+
+These either encode or decode (respectively) a SEQUENCE data type where the items in the sequence are specified after the length parameter.
+
+The list of items are specified as a triple of the form ``(type, size, data)''  where ``type'' is an \textbf{int}, ``size'' is a \textbf{unsigned long}
+and ``data'' is \textbf{void} pointer.  The list of items must be terminated with an item with the type \textbf{LTC\_ASN1\_EOL}.
+
+It's ideal that you cast the ``size'' values to unsigned long to ensure that the proper data type is passed to the function.  Constants such as ``1'' without
+a cast or prototype are of type \textbf{int} by default.  Appending \textit{UL} or prepending \textit{(unsigned long)} is enough to cast it to the correct type.
+
+\subsection{ASN.1 INTEGER}
+
+To encode or decode INTEGER data types use the following functions.
+
+\index{der\_encode\_integer()}
+\index{der\_decode\_integer()}
+\index{der\_length\_integer()}
+\begin{verbatim}
+int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen);
+int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num);
+int der_length_integer(mp_int *num, unsigned long *len);
+\end{verbatim}
+
+These will encode or decode a signed INTEGER data type using the ``mp\_int'' data type to store the large INTEGER.  To encode smaller values without allocating
+an mp\_int to store the value the ``short'' INTEGER functions were made available.
+
+\index{der\_encode\_short\_integer()}
+\index{der\_decode\_short\_integer()}
+\index{der\_length\_short\_integer()}
+\begin{verbatim}
+int der_encode_short_integer(unsigned long  num, 
+                             unsigned char *out, unsigned long *outlen);
+
+int der_decode_short_integer(const unsigned char *in,  unsigned long inlen, 
+                                   unsigned long *num);
+
+int der_length_short_integer(unsigned long num, unsigned long *outlen);
+\end{verbatim}
+
+These will encode or decode an unsigned \textbf{unsigned long} type (only reads upto 32--bits).  For values in the range $0 \dots 2^{32} - 1$ the integer 
+and short integer functions can encode and decode each others outputs.  
+
+\subsection{ASN.1 BIT STRING}
+
+\index{der\_encode\_bit\_string()}
+\index{der\_decode\_bit\_string()}
+\index{der\_length\_bit\_string()}
+\begin{verbatim}
+int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+
+int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+
+int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
+\end{verbatim}
+
+These will encode or decode a BIT STRING data type.  The bits are passed in (or read out) using one \textbf{char} per bit.  A non--zero value will be interpretted
+as a one bit and a zero value a zero bit.
+
+\subsection{ASN.1 OCTET STRING}
+
+\index{der\_encode\_octet\_string()}
+\index{der\_decode\_octet\_string()}
+\index{der\_length\_octet\_string()}
+\begin{verbatim}
+int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
+                                  unsigned char *out, unsigned long *outlen);
+
+int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
+                                  unsigned char *out, unsigned long *outlen);
+
+int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
+\end{verbatim}
+
+These will encode or decode an OCTET STRING data type.  The octets are stored using one \textbf{char} each.  
+
+\subsection{ASN.1 OBJECT IDENTIFIER}
+
+\index{der\_encode\_object\_identifier()}
+\index{der\_decode\_object\_identifier()}
+\index{der\_length\_object\_identifier()}
+\begin{verbatim}
+int der_encode_object_identifier(unsigned long *words, unsigned long  nwords,
+                                 unsigned char *out,   unsigned long *outlen);
+
+int der_decode_object_identifier(const unsigned char *in,    unsigned long  inlen,
+                                       unsigned long *words, unsigned long *outlen);
+
+int der_length_object_identifier(unsigned long *words, unsigned long nwords, 
+                                 unsigned long *outlen);
 \end{verbatim}
+
+These will encode or decode an OBJECT IDENTIFIER object.  The words of the OID are stored in individual \textbf{unsigned long} elements and must be in the range
+$0 \ldots 2^{32} - 1$.  
+
+\subsection{ASN.1 IA5 STRING}
+
+\index{der\_encode\_ia5\_string()}
+\index{der\_decode\_ia5\_string()}
+\index{der\_length\_ia5\_string()}
+\begin{verbatim}
+int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+
+int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+
+int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, 
+                                unsigned long *outlen);
+\end{verbatim}
+
+These will encode or decode an IA5 STRING.  The characters are read or stored in individual \textbf{char} elements.  This functions performs internal character
+to numerical conversions based on the conventions of the compiler being used.  For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on 
+say a SPARC machine.  Internally these functions have a table of literal characters and their numerical ASCII values.  This provides a stable conversion provided
+that the build platform honours the runtime platforms character conventions.
+
+If you're worried try building the test suite and running it.  It has hard coded test vectors to ensure it is operating properly. 
+
+\subsection{ASN.1 PRINTABLE STRING}
+
+\index{der\_encode\_printable\_string()}
+\index{der\_decode\_printable\_string()}
+\index{der\_length\_printable\_string()}
+\begin{verbatim}
+int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+
+int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+
+int der_length_printable_string(const unsigned char *octets, unsigned long noctets, 
+                                unsigned long *outlen);
+\end{verbatim}
+
+These will encode or decode an PRINTABLE STRING.  The characters are read or stored in individual \textbf{char} elements.  This functions performs internal character
+to numerical conversions based on the conventions of the compiler being used.  For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on 
+say a SPARC machine.  Internally these functions have a table of literal characters and their numerical ASCII values.  This provides a stable conversion provided
+that the build platform honours the runtime platforms character conventions.
+
+If you're worried try building the test suite and running it.  It has hard coded test vectors to ensure it is operating properly. 
+
+\subsection{ASN.1 UTCTIME}
+
+The UTCTIME type is to store a date and time in ASN.1 format.  It uses the following structure to organize the time.
+
+\begin{verbatim}
+typedef struct {
+   unsigned YY, /* year    00--99 */
+            MM, /* month   01--12 */
+            DD, /* day     01--31 */
+            hh, /* hour    00--23 */
+            mm, /* minute  00--59 */
+            ss, /* second  00--59 */
+            off_dir, /* timezone offset direction 0 == +, 1 == - */
+            off_hh, /* timezone offset hours */
+            off_mm; /* timezone offset minutes */
+} ltc_utctime;
+\end{verbatim}
+
+The time can be offset plus or minus a set amount of hours (off\_hh) and minutes (off\_mm).  When ``off\_dir'' is zero the time will be added otherwise it 
+will be subtracted.  
+
+For instance, the array $\lbrace 5, 6, 20, 22, 4, 00, 0, 5, 0 \rbrace$ represents the current time of 2005, June 20th, 22:04:00 with a time offset of +05h00.  
+
+\index{der\_encode\_utctime()}
+\index{der\_decode\_utctime()}
+\index{der\_length\_utctime()}
+\begin{verbatim}
+int der_encode_utctime(ltc_utctime *utctime, 
+                       unsigned char *out,   unsigned long *outlen);
+
+int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
+                             ltc_utctime   *out);
+
+int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
+\end{verbatim}
+
+The encoder will store time in one of the two ASN.1 formats, either ``YYMMDDhhmmssZ'' or ``YYMMDDhhmmss$\pm$hhmm'' and perform minimal error checking on the 
+input.  The decoder will read all valid ASN.1 formats and perform range checking on the values (not complete but rational) useful for catching packet errors.
+
+It is suggested that decoded data be further scrutinized (e.g. days of month in particular).
+
+\subsection{ASN.1 CHOICE}
+
+The CHOICE ASN.1 type represents a union of ASN.1 types all of which are stored in a ``ltc\_asn1\_list''.  There is no encoder for the CHOICE type, only a 
+decoder.  The decoder will scan through the provided list attempting to use the appropriate decoder on the input packet.  The list can contain any ASN.1 data
+type\footnote{Except it cannot have LTC\_ASN1\_INTEGER and LTC\_ASN1\_SHORT\_INTEGER simultaneously.} except for other CHOICE types.  
+
+There is no encoder for the CHOICE type as the actual DER encoding is the encoding of the chosen type.  
+
+\index{der\_decode\_choice()}
+\begin{verbatim}
+int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
+                            ltc_asn1_list *list, unsigned long  outlen);
+\end{verbatim}
+
+This will decode the input in the ``in'' field of length ``inlen''.  It uses the provided ASN.1 list specified in the ``list'' field which has ``outlen'' elements.  
+The ``inlen'' field will be updated with the length of the decoded data type as well as the respective entry in the ``list'' field will have the ``used'' flag 
+set to non--zero to reflect it was the data type decoded.
+
 \section{Password Based Cryptography}
 \subsection{PKCS \#5}
+\index{PKCS \#5}
 In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted.   PKCS \#5
 is made up of two algorithms, Algorithm One and Algorithm Two.  Algorithm One is the older fairly limited algorithm which has been implemented
 for completeness.  Algorithm Two is a bit more modern and more flexible to work with.
@@ -3436,7 +3736,6 @@
 \}
 \end{alltt}
 
-
 \chapter{Miscellaneous}
 \section{Base64 Encoding and Decoding}
 The library provides functions to encode and decode a RFC1521 base64 coding scheme.  This means that it can decode what it 
@@ -3634,7 +3933,6 @@
 \begin{center}
 \begin{tabular}{|c|c|}
     \hline ECC Key Size (bits) & Work Factor ($log_2$) \\
-    \hline 160 & 80  \\
     \hline 192 & 96  \\
     \hline 224 & 112 \\
     \hline 256 & 128 \\
@@ -3792,8 +4090,8 @@
 it will not speed up the encryption or decryption functions.
 
 \subsection{GCM\_TABLES}
-When defined GCM will use a 64KB table (per GCM state) which will greatly lower up the per--packet latency.  
-It also increases the initialization time.  
+When defined GCM will use a 64KB table (per GCM state) which will greatly speed up the per--packet latency.  
+It also increases the initialization time and isn't suitable when you are going to use a key a few times only.  
 
 \subsection{SMALL\_CODE}
 When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants.
@@ -3824,6 +4122,13 @@
 of your block cipher (e.g. 16 bytes for AES).  This means sadly if you're on a platform with 57--bit words (or something) you can't 
 use this mode.  So sad.
 
+\subsection{LTC\_PTHREAD}
+When this is activated all of the descriptor table functions will use pthread locking to ensure thread safe updates to the tables.  Note that 
+it doesn't prevent a thread that is passively using a table from being messed up by another thread that updates the table.
+
+Generally the rule of thumb is to setup the tables once at startup and then leave them be.  This added build flag simply makes updating
+the tables safer.
+
 \section{MPI Tweaks}
 \subsection{RSA Only Tweak}
 If you plan on only using RSA with moduli in the range of 1024 to 2560 bits you can enable a series of tweaks
@@ -4030,8 +4335,8 @@
 can specify the number of rounds they want through ``num\_rounds'' where $num\_rounds = 0$ means use the default.  The destination of a scheduled key is stored
 in ``skey''.
 
-This is where things get tricky.  Currently there is no provision to allocate memory during initialization since there is no ``cipher done'' function.  So you have
-to either use an existing member of the symmetric\_key union or alias your own structure over top of it provided symmetric\_key is not smaller.
+Inside the ``symmetric\_key'' union there is a ``void *data'' which you can use to allocate data if you need a data structure that doesn't fit with the existing
+ones provided.  Just make sure in your ``done()'' function that you free the allocated memory.
 
 \subsection{Single block ECB}
 To process a single block in ECB mode the ecb\_encrypt() and ecb\_decrypt() functions were provided.  The plaintext and ciphertext buffers are allowed to overlap so you 
@@ -4062,7 +4367,8 @@
 \subsubsection{Accelerated CTR}
 This function is meant for accelerated CTR encryption.  It is accessible through the accel\_ctr\_encrypt pointer.
 The ``blocks'' value is the number of complete blocks to process.  The ``IV'' is the CTR counter vector.  It is an input upon calling this function and must be
-updated by the function before returning.  The ``mode'' value indicates whether the counter is big ($mode = 1$) or little ($mode = 0$) endian.
+updated by the function before returning.  The ``mode'' value indicates whether the counter is big (mode = CTR\_COUNTER\_BIG\_ENDIAN) or 
+little (mode = CTR\_COUNTER\_LITTLE\_ENDIAN) endian.
 
 This function (and the way it's called) differs from the other two since ctr\_encrypt() allows any size input plaintext.  The accelerator will only be
 called if the following conditions are met.
@@ -4101,10 +4407,10 @@
     unsigned long hashsize;
     /** Input block size in octets */
     unsigned long blocksize;
-    /** ASN.1 DER identifier */
-    unsigned char DER[64];
+    /** ASN.1 OID */
+    unsigned long OID[16];
     /** Length of DER encoding */
-    unsigned long DERlen;
+    unsigned long OIDlen;
     /** Init a hash state
       @param hash   The hash to initialize
       @return CRYPT_OK if successful
@@ -4144,8 +4450,8 @@
 The `blocksize'' variable indicates the length of input (in octets) that the hash processes in a given
 invokation.
 
-\subsection{DER Identifier}
-This is the DER identifier (including the SEQUENCE header).  This is used solely for PKCS \#1 style signatures.  
+\subsection{OID Identifier}
+This is the universal ASN.1 Object Identifier for the hash.
 
 \subsection{Initialization}
 The init function initializes the hash and prepares it to process message bytes.
@@ -4251,3 +4557,7 @@
 \input{crypt.ind}
 
 \end{document}
+
+% $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $   
+% $Revision: 1.39 $   
+% $Date: 2005/06/27 13:08:28 $ 
--- a/demos/encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -235,3 +235,7 @@
    }
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/encrypt.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:56 $ */
--- a/demos/hashsum.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/hashsum.c	Wed Jul 06 12:10:23 2005 +0000
@@ -113,3 +113,7 @@
 #endif
 
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/hashsum.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:56 $ */
--- a/demos/multi.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -104,3 +104,7 @@
    return EXIT_SUCCESS;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/multi.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:56 $ */
--- a/demos/small.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/small.c	Wed Jul 06 12:10:23 2005 +0000
@@ -8,3 +8,7 @@
    register_hash(&sha256_desc);
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/small.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:56 $ */
--- a/demos/test.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -2,18 +2,23 @@
 
 int main(void)
 {
+   int x;
    reg_algs();
    printf("build == \n%s\n", crypt_build_settings);
-   printf("\ncipher_test..."); fflush(stdout); printf(cipher_hash_test() ? "failed" : "passed");
-   printf("\nmodes_test..."); fflush(stdout); printf(modes_test() ? "failed" : "passed");
-   printf("\nmac_test..."); fflush(stdout); printf(mac_test() ? "failed" : "passed");
-   printf("\npkcs_1_test..."); fflush(stdout); printf(pkcs_1_test() ? "failed" : "passed");
-   printf("\nstore_test..."); fflush(stdout); printf(store_test() ? "failed" : "passed");
-   printf("\nrsa_test..."); fflush(stdout); printf(rsa_test() ? "failed" : "passed");
-   printf("\necc_test..."); fflush(stdout); printf(ecc_tests() ? "failed" : "passed");
-   printf("\ndsa_test..."); fflush(stdout); printf(dsa_test() ? "failed" : "passed");
-   printf("\ndh_test..."); fflush(stdout); printf(dh_tests() ? "failed" : "passed");
-   printf("\nder_test..."); fflush(stdout); printf(der_tests() ? "failed" : "passed");
-
+   printf("\nstore_test...."); fflush(stdout); x = store_test();       printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\ncipher_test..."); fflush(stdout); x = cipher_hash_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\nmodes_test...."); fflush(stdout); x = modes_test();       printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\nder_test......"); fflush(stdout); x = der_tests();        printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\nmac_test......"); fflush(stdout); x = mac_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test();      printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\nrsa_test......"); fflush(stdout); x = rsa_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\necc_test......"); fflush(stdout); x = ecc_tests();        printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\ndsa_test......"); fflush(stdout); x = dsa_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\ndh_test......."); fflush(stdout); x = dh_tests();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\n");
    return EXIT_SUCCESS;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/test.c,v $ */
+/* $Revision: 1.12 $ */
+/* $Date: 2005/06/19 12:06:58 $ */
--- a/demos/timing.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/timing.c	Wed Jul 06 12:10:23 2005 +0000
@@ -17,7 +17,10 @@
 time_rsa();
 time_ecc();
 time_dh();
-
 return EXIT_SUCCESS;
 
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/timing.c,v $ */
+/* $Revision: 1.17 $ */
+/* $Date: 2005/06/23 02:16:26 $ */
--- a/demos/tv_gen.c	Tue May 10 17:02:59 2005 +0000
+++ b/demos/tv_gen.c	Wed Jul 06 12:10:23 2005 +0000
@@ -664,3 +664,7 @@
       
     
    
+
+/* $Source: /cvs/libtom/libtomcrypt/demos/tv_gen.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:56 $ */
--- a/doc/footer.html	Tue May 10 17:02:59 2005 +0000
+++ b/doc/footer.html	Wed Jul 06 12:10:23 2005 +0000
@@ -2,3 +2,9 @@
 Code by <a href="http://www.libtomcrypt.org/">Tom</a><br>
 Docs using <img src="doxygen.png" alt="doxygen" align="middle" border=0>
 <a href="http://jlcooke.ca/tom/hidden_image.png">
+
+<!--
+/* $Source: /cvs/libtom/libtomcrypt/doc/footer.html,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/07 10:09:20 $ */
+-->
--- a/doc/header.html	Tue May 10 17:02:59 2005 +0000
+++ b/doc/header.html	Wed Jul 06 12:10:23 2005 +0000
@@ -4,3 +4,9 @@
 <link href="doxygen.css" rel="stylesheet" type="text/css">
 </head><body>
 <!-- Generated by Doxygen 1.3.8 -->
+
+<!--
+/* $Source: /cvs/libtom/libtomcrypt/doc/header.html,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/07 10:09:20 $ */
+-->
--- a/genlist.sh	Tue May 10 17:02:59 2005 +0000
+++ b/genlist.sh	Wed Jul 06 12:10:23 2005 +0000
@@ -4,3 +4,7 @@
 perl ./parsenames.pl OBJECTS "$a"
 export a=`find . -type f | grep [.]/src | grep [.]h | sed -e 'se\./ee' | xargs`
 perl ./parsenames.pl HEADERS "$a"
+
+# $Source: /cvs/libtom/libtomcrypt/genlist.sh,v $   
+# $Revision: 1.3 $   
+# $Date: 2005/05/05 14:49:27 $ 
--- a/makefile.icc	Tue May 10 17:02:59 2005 +0000
+++ b/makefile.icc	Wed Jul 06 12:10:23 2005 +0000
@@ -22,7 +22,7 @@
 #ARFLAGS=r
 
 # Compilation flags. Note the += does not write over the user's CFLAGS!
-CFLAGS += -c -I./src/headers/ -DINTEL_CC
+CFLAGS += -c -Isrc/headers/ -Itestprof/ -DINTEL_CC
 
 #The default rule for make builds the libtomcrypt library.
 default:library
@@ -41,7 +41,13 @@
 #	B - Blend of P4 and PM [mobile]
 #
 # Default to just generic max opts
+ifdef LTC_SMALL
+CFLAGS += -O2 -xP -ip
+endif
+
+ifndef IGNORE_SPEED
 CFLAGS += -O3 -xP -ip 
+endif
 
 # want to see stuff?
 #CFLAGS += -opt_report
@@ -122,29 +128,43 @@
 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 src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \
-src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \
-src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
-src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \
-src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \
-src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
-src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
-src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \
-src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \
-src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
+src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
+src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \
+src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \
+src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \
+src/pk/asn1/der/integer/der_length_integer.o \
+src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_length_object_identifier.o \
+src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \
+src/pk/asn1/der/octet/der_length_octet_string.o \
+src/pk/asn1/der/printable_string/der_decode_printable_string.o \
+src/pk/asn1/der/printable_string/der_encode_printable_string.o \
+src/pk/asn1/der/printable_string/der_length_printable_string.o \
+src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_length_sequence.o \
+src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/short_integer/der_encode_short_integer.o \
+src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
+src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
+src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \
+src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
+src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o src/pk/packet_valid_header.o \
+src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
+src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
+src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
 src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \
-src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \
-src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
-src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o 
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
+src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
+src/prngs/sprng.o src/prngs/yarrow.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
+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
 
 #ciphers come in two flavours... enc+dec and enc 
 aes_enc.o: aes.c aes_tab.c
@@ -214,4 +234,9 @@
 	install -d -g root -o root $(DESTDIR)$(LIBPATH)
 	install -d -g root -o root $(DESTDIR)$(INCPATH)
 	install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH)
+	install -g root -o root $(LIBTEST) $(DESTDIR)$(LIBPATH)
 	install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH)
+
+# $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $   
+# $Revision: 1.33 $   
+# $Date: 2005/06/19 18:22:31 $ 
--- a/makefile.msvc	Tue May 10 17:02:59 2005 +0000
+++ b/makefile.msvc	Wed Jul 06 12:10:23 2005 +0000
@@ -57,29 +57,43 @@
 src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj src/modes/ecb/ecb_encrypt.obj \
 src/modes/ecb/ecb_start.obj src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj \
 src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj \
-src/modes/ofb/ofb_start.obj src/pk/asn1/der/der_decode_integer.obj src/pk/asn1/der/der_encode_integer.obj \
-src/pk/asn1/der/der_get_multi_integer.obj src/pk/asn1/der/der_length_integer.obj \
-src/pk/asn1/der/der_put_multi_integer.obj src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \
-src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj \
-src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj \
-src/pk/packet_valid_header.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \
-src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \
-src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v15_es_decode.obj \
-src/pk/pkcs1/pkcs_1_v15_es_encode.obj src/pk/pkcs1/pkcs_1_v15_sa_decode.obj \
-src/pk/pkcs1/pkcs_1_v15_sa_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
+src/modes/ofb/ofb_start.obj src/pk/asn1/der/bit/der_decode_bit_string.obj \
+src/pk/asn1/der/bit/der_encode_bit_string.obj src/pk/asn1/der/bit/der_length_bit_string.obj \
+src/pk/asn1/der/choice/der_decode_choice.obj src/pk/asn1/der/ia5/der_decode_ia5_string.obj \
+src/pk/asn1/der/ia5/der_encode_ia5_string.obj src/pk/asn1/der/ia5/der_length_ia5_string.obj \
+src/pk/asn1/der/integer/der_decode_integer.obj src/pk/asn1/der/integer/der_encode_integer.obj \
+src/pk/asn1/der/integer/der_length_integer.obj \
+src/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \
+src/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \
+src/pk/asn1/der/object_identifier/der_length_object_identifier.obj \
+src/pk/asn1/der/octet/der_decode_octet_string.obj src/pk/asn1/der/octet/der_encode_octet_string.obj \
+src/pk/asn1/der/octet/der_length_octet_string.obj \
+src/pk/asn1/der/printable_string/der_decode_printable_string.obj \
+src/pk/asn1/der/printable_string/der_encode_printable_string.obj \
+src/pk/asn1/der/printable_string/der_length_printable_string.obj \
+src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \
+src/pk/asn1/der/sequence/der_encode_sequence.obj src/pk/asn1/der/sequence/der_encode_sequence_multi.obj \
+src/pk/asn1/der/sequence/der_length_sequence.obj \
+src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
+src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
+src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
+src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
+src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj \
+src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \
+src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj src/pk/packet_valid_header.obj \
+src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \
+src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \
+src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
 src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \
-src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_v15_decrypt_key.obj \
-src/pk/rsa/rsa_v15_encrypt_key.obj src/pk/rsa/rsa_v15_sign_hash.obj src/pk/rsa/rsa_v15_verify_hash.obj \
-src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \
-src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj 
+src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \
+src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \
+src/prngs/sprng.obj src/prngs/yarrow.obj 
 
-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
+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
 
 #ciphers come in two flavours... enc+dec and enc
 src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
@@ -102,3 +116,7 @@
 
 timing: demos/timing.c library
 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib
+
+# $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $   
+# $Revision: 1.15 $   
+# $Date: 2005/06/27 12:37:06 $ 
--- a/makefile.shared	Tue May 10 17:02:59 2005 +0000
+++ b/makefile.shared	Wed Jul 06 12:10:23 2005 +0000
@@ -6,7 +6,7 @@
 # Tom St Denis
 
 # The version
-VERSION=0:102
+VERSION=0:105
 
 # Compiler and Linker Names
 CC=libtool --mode=compile gcc
@@ -18,14 +18,18 @@
 #CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
 #			 -Wmissing-declarations -Wpointer-arith 
 
+ifndef IGNORE_SPEED
+
 # optimize for SPEED
-CFLAGS += -O3 -funroll-all-loops
+CFLAGS += -O3 -funroll-loops
 
 # add -fomit-frame-pointer.  hinders debugging!
 CFLAGS += -fomit-frame-pointer
 
 # optimize for SIZE
-#CFLAGS += -Os
+#CFLAGS += -Os -DLTC_SMALL_CODE
+
+endif
 
 # compile for DEBUGING (required for ccmalloc checking!!!)
 #CFLAGS += -g3
@@ -45,7 +49,6 @@
 TEST=test
 TIMING=timing
 
-
 #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.
@@ -55,16 +58,27 @@
 DATAPATH=/usr/share/doc/libtomcrypt/pdf
 
 #Who do we install as?
+ifdef INSTALL_USER
+USER=$(INSTALL_USER)
+else
 USER=root
-GROUP=wheel
+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?
+ifndef IGNORE_MPI
 MPIOBJECT=src/misc/mpi/mpi.o
-
+else 
 #If you don't want mpi.o then add this
-#MPISHARED=$(LIBPATH)/libtommath.la
+MPISHARED=$(LIBPATH)/libtommath.la
+endif
 
 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 \
@@ -115,29 +129,43 @@
 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 src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \
-src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \
-src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
-src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \
-src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \
-src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
-src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
-src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \
-src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \
-src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
+src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
+src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \
+src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \
+src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \
+src/pk/asn1/der/integer/der_length_integer.o \
+src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_length_object_identifier.o \
+src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \
+src/pk/asn1/der/octet/der_length_octet_string.o \
+src/pk/asn1/der/printable_string/der_decode_printable_string.o \
+src/pk/asn1/der/printable_string/der_encode_printable_string.o \
+src/pk/asn1/der/printable_string/der_length_printable_string.o \
+src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_length_sequence.o \
+src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/short_integer/der_encode_short_integer.o \
+src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
+src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
+src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \
+src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
+src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o src/pk/packet_valid_header.o \
+src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
+src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
+src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
 src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
-src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \
-src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \
-src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
-src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o 
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
+src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
+src/prngs/sprng.o src/prngs/yarrow.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
+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
@@ -164,7 +192,7 @@
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 
 #This rule makes the libtomcrypt library.
-library: $(LIBTEST) $(LIBNAME)
+library: $(LIBNAME)
 
 $(LIBTEST):
 	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBNAME=$(LIBTEST) make -f makefile.shared
@@ -180,19 +208,22 @@
 #This rule makes the hash program included with libtomcrypt
 hashsum: library
 	gcc $(CFLAGS) demos/hashsum.c -o hashsum.o
-	gcc -o hashsum hashsum.o -ltomcrypt_prof -ltomcrypt $(MPISHARED)
+	gcc -o hashsum hashsum.o -ltomcrypt $(MPISHARED)
 
 #makes the crypt program
 crypt: library 
 	gcc $(CFLAGS) demos/encrypt.c -o encrypt.o
-	gcc -o crypt encrypt.o -ltomcrypt_prof -ltomcrypt $(MPISHARED)
+	gcc -o crypt encrypt.o -ltomcrypt $(MPISHARED)
 
 tv_gen: library $(TVS)
-	gcc -o tv_gen $(TVS) -ltomcrypt_prof -ltomcrypt $(MPISHARED)
+	gcc -o tv_gen $(TVS) -ltomcrypt $(MPISHARED)
 
-test: library $(TESTS)
+test: library $(LIBTEST) $(TESTS)
 	gcc -o $(TEST) $(TESTS) -ltomcrypt_prof -ltomcrypt $(MPISHARED)
 
-timing: library $(TIMINGS)
+timing: library $(LIBTEST) $(TIMINGS)
 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(MPISHARED)
 
+# $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $   
+# $Revision: 1.19 $   
+# $Date: 2005/06/27 12:37:06 $ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mess.sh	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,4 @@
+#!/bin/bash
+if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here" ; exit 1; fi
+
+
--- a/notes/etc/saferp_optimizer.c	Tue May 10 17:02:59 2005 +0000
+++ b/notes/etc/saferp_optimizer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -171,3 +171,7 @@
    return 0;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/notes/etc/saferp_optimizer.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/notes/etc/whirlgen.c	Tue May 10 17:02:59 2005 +0000
+++ b/notes/etc/whirlgen.c	Wed Jul 06 12:10:23 2005 +0000
@@ -89,3 +89,7 @@
 }
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/notes/etc/whirlgen.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/notes/etc/whirltest.c	Tue May 10 17:02:59 2005 +0000
+++ b/notes/etc/whirltest.c	Wed Jul 06 12:10:23 2005 +0000
@@ -13,3 +13,7 @@
    }
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/notes/etc/whirltest.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/notes/tech0005.txt	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,18 @@
+Tech Note 0005
+Minimizing Code Space
+Tom St Denis
+
+Introduction
+------------
+
+Tweaking...
+
+You can disable whole classes of algorithms on the command line with the LTC_NO_* defines.  From there you can manually turn on what you want to enable.  
+
+The following build with GCC 3.4.3 on an AMD64 box gets you AES, CTR mode, SHA-256, HMAC, Yarrow, full RSA PKCS #1, PKCS #5, ASN.1 DER and MPI in 
+roughly 80KB of code.
+
+CFLAGS="-DSC_RSA_1 -DLTC_NO_CIPHERS -DLTC_NO_HASHES -DLTC_NO_PRNGS -DLTC_NO_MACS -DLTC_NO_MODES -DLTC_NO_PK -DRIJNDAEL -DCTR -DSHA256 \
+-DHMAC -DYARROW -DMRSA -DMPI -Os -fomit-frame-pointer" make IGNORE_SPEED=1
+
+Neato eh?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/notes/tech0006.txt	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,91 @@
+Tech Note 0006
+PK Standards Compliance
+Tom St Denis
+
+RSA
+----
+
+PKCS #1 compliance.
+
+Key Format:  RSAPublicKey and RSAPrivateKey as per PKCS #1 v2.1
+Encryption:  OAEP as per PKCS #1
+Signature :  PSS  as per PKCS #1
+
+DSA
+----
+
+The NIST DSA algorithm
+
+Key Format:  HomeBrew [see below]
+Signature :  ANSI X9.62 format [see below].
+
+Keys are stored as 
+
+DSAPublicKey ::= SEQUENCE {
+    publicFlags    BIT STRING(1), -- must be 0
+    g              INTEGER      , -- base generator, check that g^q mod p == 1
+                                  -- and that 1 < g < p - 1
+    p              INTEGER      , -- prime modulus 
+    q              INTEGER      , -- order of sub-group (must be prime)
+    y              INTEGER      , -- public key, specifically, g^x mod p, 
+                                  -- check that y^q mod p == 1
+                                  -- and that 1 < y < p - 1
+}
+
+DSAPrivateKey ::= SEQUENCE {
+    publicFlags    BIT STRING(1), -- must be 1
+    g              INTEGER      , -- base generator, check that g^q mod p == 1
+                                  -- and that 1 < g < p - 1
+    p              INTEGER      , -- prime modulus 
+    q              INTEGER      , -- order of sub-group (must be prime)
+    y              INTEGER      , -- public key, specifically, g^x mod p, 
+                                  -- check that y^q mod p == 1
+                                  -- and that 1 < y < p - 1
+    x              INTEGER        -- private key
+}
+
+Signatures are stored as 
+
+DSASignature ::= SEQUENCE {
+    r, s           INTEGER        -- signature parameters
+}
+
+ECC
+----
+
+The ANSI X9.62 and X9.63 algorithms [partial].  Supports all NIST GF(p) curves.
+
+Key Format   :  Homebrew [see below, only GF(p) NIST curves supported]
+Signature    :  X9.62 compliant
+Encryption   :  Homebrew [based on X9.63, differs in that the public point is stored as an ECCPublicKey]
+Shared Secret:  X9.63 compliant
+
+ECCPublicKey ::= SEQUENCE {
+    flags       BIT STRING(1), -- public/private flag (always zero), 
+    keySize     INTEGER,       -- Curve size (in bits) divided by eight 
+                               -- and rounded down, e.g. 521 => 65
+    pubkey.x    INTEGER,       -- The X co-ordinate of the public key point
+    pubkey.y    INTEGER,       -- The Y co-ordinate of the public key point
+}
+
+ECCPrivateKey ::= SEQUENCE {
+    flags       BIT STRING(1), -- public/private flag (always one), 
+    keySize     INTEGER,       -- Curve size (in bits) divided by eight 
+                               -- and rounded down, e.g. 521 => 65
+    pubkey.x    INTEGER,       -- The X co-ordinate of the public key point
+    pubkey.y    INTEGER,       -- The Y co-ordinate of the public key point
+    secret.k    INTEGER,       -- The secret key scalar
+}
+
+The encryption works by finding the X9.63 shared secret and hashing it.  The hash is then simply XOR'ed against the message [which must be at most the size
+of the hash digest].  The format of the encrypted text is as follows
+
+ECCEncrypted ::= SEQUENCE {
+    hashOID     OBJECT IDENTIFIER,   -- The OID of the hash used
+    pubkey      OCTET STRING     ,   -- Encapsulation of a random ECCPublicKey
+    skey        OCTET STRING         -- The encrypted text (which the hash was XOR'ed against)
+}
+
+% $Source: /cvs/libtom/libtomcrypt/notes/tech0006.txt,v $   
+% $Revision: 1.2 $   
+% $Date: 2005/06/18 02:26:27 $ 
--- a/parsenames.pl	Tue May 10 17:02:59 2005 +0000
+++ b/parsenames.pl	Wed Jul 06 12:10:23 2005 +0000
@@ -20,3 +20,7 @@
 if ($ARGV[0] eq "HEADERS") { print "testprof/tomcrypt_test.h"; }
 
 print "\n\n";
+
+# $Source: /cvs/libtom/libtomcrypt/parsenames.pl,v $   
+# $Revision: 1.3 $   
+# $Date: 2005/05/05 14:49:27 $ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/run.sh	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,35 @@
+#!/bin/bash
+bash build.sh " $1" "$2 -O2" "$3 IGNORE_SPEED=1"
+if [ -a testok.txt ] && [ -f testok.txt ]; then
+   echo
+else
+	echo
+	echo "Test failed"
+	exit 1
+fi
+
+rm -f testok.txt
+bash build.sh " $1" "$2 -Os" " $3 IGNORE_SPEED=1 LTC_SMALL=1"
+if [ -a testok.txt ] && [ -f testok.txt ]; then
+   echo
+else
+	echo
+	echo "Test failed"
+	exit 1
+fi
+
+rm -f testok.txt
+bash build.sh " $1" " $2" " $3"
+if [ -a testok.txt ] && [ -f testok.txt ]; then
+   echo
+else
+	echo
+	echo "Test failed"
+	exit 1
+fi
+
+exit 0
+
+# $Source: /cvs/libtom/libtomcrypt/run.sh,v $   
+# $Revision: 1.13 $   
+# $Date: 2005/05/11 18:59:53 $ 
--- a/src/ciphers/aes/aes.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/aes/aes.c	Wed Jul 06 12:10:23 2005 +0000
@@ -129,7 +129,7 @@
 #endif    
     LTC_ARGCHK(key  != NULL);
     LTC_ARGCHK(skey != NULL);
-    
+  
     if (keylen != 16 && keylen != 24 && keylen != 32) {
        return CRYPT_INVALID_KEYSIZE;
     }
@@ -749,3 +749,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/aes/aes_tab.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/aes/aes_tab.c	Wed Jul 06 12:10:23 2005 +0000
@@ -1018,3 +1018,7 @@
     0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
     0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
 };
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes_tab.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/anubis.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/anubis.c	Wed Jul 06 12:10:23 2005 +0000
@@ -1548,3 +1548,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/anubis.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/blowfish.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/blowfish.c	Wed Jul 06 12:10:23 2005 +0000
@@ -581,3 +581,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/blowfish.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/cast5.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/cast5.c	Wed Jul 06 12:10:23 2005 +0000
@@ -709,3 +709,7 @@
 } 
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/cast5.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/des.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/des.c	Wed Jul 06 12:10:23 2005 +0000
@@ -1900,3 +1900,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/des.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/khazad.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/khazad.c	Wed Jul 06 12:10:23 2005 +0000
@@ -845,3 +845,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/khazad.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/noekeon.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/noekeon.c	Wed Jul 06 12:10:23 2005 +0000
@@ -290,3 +290,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/noekeon.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/rc2.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/rc2.c	Wed Jul 06 12:10:23 2005 +0000
@@ -348,3 +348,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc2.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/rc5.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/rc5.c	Wed Jul 06 12:10:23 2005 +0000
@@ -308,3 +308,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc5.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/rc6.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/rc6.c	Wed Jul 06 12:10:23 2005 +0000
@@ -337,3 +337,7 @@
 #endif /*RC6*/
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc6.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/safer/safer.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/safer/safer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -481,3 +481,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/safer/safer_tab.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/safer/safer_tab.c	Wed Jul 06 12:10:23 2005 +0000
@@ -62,3 +62,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer_tab.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/safer/saferp.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/safer/saferp.c	Wed Jul 06 12:10:23 2005 +0000
@@ -549,3 +549,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/saferp.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/skipjack.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/skipjack.c	Wed Jul 06 12:10:23 2005 +0000
@@ -329,3 +329,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/skipjack.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/twofish/twofish.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/twofish/twofish.c	Wed Jul 06 12:10:23 2005 +0000
@@ -702,3 +702,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/twofish/twofish_tab.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/twofish/twofish_tab.c	Wed Jul 06 12:10:23 2005 +0000
@@ -490,3 +490,7 @@
 #endif /* TWOFISH_ALL_TABLES */
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish_tab.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/ciphers/xtea.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/ciphers/xtea.c	Wed Jul 06 12:10:23 2005 +0000
@@ -201,3 +201,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/ciphers/xtea.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ccm/ccm_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ccm/ccm_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -293,7 +293,6 @@
 
 #ifdef LTC_CLEAN_STACK
    zeromem(skey,   sizeof(*skey));
-   zeromem(B,      sizeof(B));
    zeromem(PAD,    sizeof(PAD));
    zeromem(CTRPAD, sizeof(CTRPAD));
 #endif
@@ -304,3 +303,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ccm/ccm_memory.c,v $ */
+/* $Revision: 1.9 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ccm/ccm_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ccm/ccm_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -168,3 +168,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ccm/ccm_test.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_addheader.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_addheader.c	Wed Jul 06 12:10:23 2005 +0000
@@ -32,3 +32,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_addheader.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -44,3 +44,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_decrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_decrypt_verify_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_decrypt_verify_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -102,3 +102,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -88,3 +88,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -45,3 +45,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_encrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_encrypt_authenticate_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_encrypt_authenticate_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -76,3 +76,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_init.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_init.c	Wed Jul 06 12:10:23 2005 +0000
@@ -108,11 +108,9 @@
    /* note we don't finish the headeromac, this allows us to add more header later */
 
    /* setup the CTR mode */
-   if ((err = ctr_start(cipher, eax->N, key, keylen, 0, &eax->ctr)) != CRYPT_OK) {
+   if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) {
       goto LBL_ERR; 
    }
-   /* use big-endian counter */
-   eax->ctr.mode = 1;
 
    /* setup the OMAC for the ciphertext */
    if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { 
@@ -140,3 +138,7 @@
 }
 
 #endif 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_init.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/eax/eax_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/eax/eax_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -276,3 +276,7 @@
 }
 
 #endif /* EAX_MODE */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_add_aad.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_add_aad.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,8 +27,11 @@
 int gcm_add_aad(gcm_state *gcm,
                const unsigned char *adata,  unsigned long adatalen)
 {
-   unsigned long x, y;
+   unsigned long x;
    int           err;
+#ifdef LTC_FAST
+   unsigned long y;
+#endif
 
    LTC_ARGCHK(gcm    != NULL);
    if (adatalen > 0) {
@@ -115,3 +118,7 @@
 }
 #endif
    
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_aad.c,v $ */
+/* $Revision: 1.14 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_add_iv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_add_iv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -88,3 +88,7 @@
 
 #endif
    
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_iv.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -75,3 +75,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_done.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_gf_mult.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_gf_mult.c	Wed Jul 06 12:10:23 2005 +0000
@@ -31,6 +31,7 @@
 static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
 static const unsigned char poly[] = { 0x00, 0xE1 };
 
+     
 /**
   GCM GF multiplier (internal use only) 
   @param a   First value
@@ -87,3 +88,7 @@
 
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c,v $ */
+/* $Revision: 1.16 $ */
+/* $Date: 2005/05/21 14:33:42 $ */
--- a/src/encauth/gcm/gcm_init.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_init.c	Wed Jul 06 12:10:23 2005 +0000
@@ -17,6 +17,46 @@
 
 #ifdef GCM_MODE
 
+#ifdef GCM_TABLES
+
+/* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format.  Since only the 
+ * lower 16 bits are not zero'ed I removed the upper 14 bytes */
+static const unsigned char gcm_shift_table[256*2] = {
+0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e,
+0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e,
+0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e,
+0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e,
+0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e,
+0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e,
+0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e,
+0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e,
+0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce,
+0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde,
+0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee,
+0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe,
+0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e,
+0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e,
+0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae,
+0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe,
+0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e,
+0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e,
+0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e,
+0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e,
+0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e,
+0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e,
+0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e,
+0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e,
+0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce,
+0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde,
+0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee,
+0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe,
+0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e,
+0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e,
+0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae,
+0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe };
+
+#endif
+
 /**
   Initialize a GCM state
   @param gcm     The GCM state to initialize
@@ -31,7 +71,7 @@
    int           err;
    unsigned char B[16];
 #ifdef GCM_TABLES
-   int           x, y;
+   int           x, y, z, t;
 #endif
 
    LTC_ARGCHK(gcm != NULL);
@@ -72,17 +112,34 @@
 
 #ifdef GCM_TABLES
    /* setup tables */
+
+   /* generate the first table as it has no shifting (from which we make the other tables) */
    zeromem(B, 16);
-   for (x = 0; x < 16; x++) {
-       for (y = 0; y < 256; y++) {
-            B[x] = y;
-            gcm_gf_mult(gcm->H, B, &gcm->PC[x][y][0]);
-       }
-       B[x] = 0;
+   for (y = 0; y < 256; y++) {
+        B[0] = y;
+        gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
    }
+
+   /* now generate the rest of the tables based the previous table */
+   for (x = 1; x < 16; x++) {
+      for (y = 0; y < 256; y++) {
+         /* now shift it right by 8 bits */
+         t = gcm->PC[x-1][y][15];
+         for (z = 15; z > 0; z--) {
+             gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
+         }
+         gcm->PC[x][y][0] = gcm_shift_table[t<<1];
+         gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
+     }
+  }
+
 #endif
 
    return CRYPT_OK;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_init.c,v $ */
+/* $Revision: 1.15 $ */
+/* $Date: 2005/05/21 15:05:19 $ */
--- a/src/encauth/gcm/gcm_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -87,3 +87,7 @@
 }
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_memory.c,v $ */
+/* $Revision: 1.19 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_process.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_process.c	Wed Jul 06 12:10:23 2005 +0000
@@ -141,3 +141,7 @@
 
 #endif
    
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_process.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_reset.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_reset.c	Wed Jul 06 12:10:23 2005 +0000
@@ -38,3 +38,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_reset.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/gcm/gcm_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/gcm/gcm_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -281,7 +281,6 @@
 };
    int           idx, err;
    unsigned long x, y;
-   gcm_state     gcm;
    unsigned char out[2][64], T[2][16];
 
    /* find aes */
@@ -363,3 +362,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_test.c,v $ */
+/* $Revision: 1.15 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -71,3 +71,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_decrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_decrypt_verify_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_decrypt_verify_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -80,3 +80,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_done_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_done_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -74,3 +74,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_done_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_done_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -40,3 +40,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -64,3 +64,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_encrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_encrypt_authenticate_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -78,3 +78,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_init.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_init.c	Wed Jul 06 12:10:23 2005 +0000
@@ -127,3 +127,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_init.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_ntz.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_ntz.c	Wed Jul 06 12:10:23 2005 +0000
@@ -36,3 +36,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_ntz.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_shift_xor.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_shift_xor.c	Wed Jul 06 12:10:23 2005 +0000
@@ -33,3 +33,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/ocb_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/ocb_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -231,3 +231,7 @@
    -- hard to stream [you can't emit ciphertext until full block]
    -- The setup is somewhat complicated...
 */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/encauth/ocb/s_ocb_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/encauth/ocb/s_ocb_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -138,3 +138,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/s_ocb_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/hashes/chc/chc.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/chc/chc.c	Wed Jul 06 12:10:23 2005 +0000
@@ -291,3 +291,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/chc/chc.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/hashes/helper/hash_file.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/helper/hash_file.c	Wed Jul 06 12:10:23 2005 +0000
@@ -51,3 +51,7 @@
 #endif
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_file.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/hashes/helper/hash_filehandle.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/helper/hash_filehandle.c	Wed Jul 06 12:10:23 2005 +0000
@@ -64,3 +64,7 @@
 #endif
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_filehandle.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/hashes/helper/hash_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/helper/hash_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -62,3 +62,7 @@
 
     return err;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/hashes/helper/hash_memory_multi.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/helper/hash_memory_multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -80,3 +80,7 @@
     va_end(args);
     return err;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory_multi.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/hashes/md2.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/md2.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,11 +24,9 @@
     16,
     16,
 
-    /* DER encoding */
-    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
-      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 
-      0x04, 0x10 },
-    18,
+    /* OID */
+   { 1, 2, 840, 113549, 2, 2,  },
+   6,
 
     &md2_init,
     &md2_process,
@@ -246,3 +244,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md2.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/md4.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/md4.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,9 +24,9 @@
     16,
     64,
  
-    /* DER encoding (not yet supported) */
-    { 0x00 },
-    0,    
+    /* OID */
+   { 1, 2, 840, 113549, 2, 4,  },
+   6,
 
     &md4_init,
     &md4_process,
@@ -300,3 +300,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md4.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/md5.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/md5.c	Wed Jul 06 12:10:23 2005 +0000
@@ -25,11 +25,9 @@
     16,
     64,
 
-    /* DER identifier */
-    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
-      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 
-      0x04, 0x10 },
-    18,
+    /* OID */
+   { 1, 2, 840, 113549, 2, 5,  },
+   6,
 
     &md5_init,
     &md5_process,
@@ -363,3 +361,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/rmd128.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/rmd128.c	Wed Jul 06 12:10:23 2005 +0000
@@ -30,9 +30,9 @@
     16,
     64,
 
-    /* DER identifier (not supported) */
-    { 0x00 },
-    0,
+    /* OID */
+   { 1, 0, 10118, 3, 0, 50 },
+   6,
 
     &rmd128_init,
     &rmd128_process,
@@ -403,3 +403,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd128.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/rmd160.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/rmd160.c	Wed Jul 06 12:10:23 2005 +0000
@@ -30,10 +30,9 @@
     20,
     64,
 
-    /* DER identifier */
-    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 
-      0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 },
-    15,
+    /* OID */
+   { 1, 3, 36, 3, 2, 1,  },
+   6,
 
     &rmd160_init,
     &rmd160_process,
@@ -463,3 +462,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd160.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/sha1.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/sha1.c	Wed Jul 06 12:10:23 2005 +0000
@@ -25,9 +25,9 @@
     20,
     64,
 
-    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 
-      0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 },
-    15,
+    /* OID */
+   { 1, 3, 14, 3, 2, 26,  },
+   6,
 
     &sha1_init,
     &sha1_process,
@@ -281,3 +281,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/sha2/sha224.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/sha2/sha224.c	Wed Jul 06 12:10:23 2005 +0000
@@ -20,9 +20,9 @@
     28,
     64,
 
-    /* DER identifier (not supported) */
-    { 0x00 },
-    0,
+    /* OID */
+   { 2, 16, 840, 1, 101, 3, 4, 2, 4,  },
+   9,
 
     &sha224_init,
     &sha256_process,
@@ -118,3 +118,7 @@
  #endif
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha224.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/sha2/sha256.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/sha2/sha256.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,11 +24,9 @@
     32,
     64,
 
-    /* DER identifier */
-    { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 
-      0x00, 0x04, 0x20 },
-    19,
+    /* OID */
+   { 2, 16, 840, 1, 101, 3, 4, 2, 1,  },
+   9,
     
     &sha256_init,
     &sha256_process,
@@ -335,3 +333,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/sha2/sha384.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/sha2/sha384.c	Wed Jul 06 12:10:23 2005 +0000
@@ -20,11 +20,9 @@
     48,
     128,
 
-    /* DER identifier */
-    { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 
-      0x00, 0x04, 0x30 },
-    19,
+    /* OID */
+   { 2, 16, 840, 1, 101, 3, 4, 2, 2,  },
+   9,
 
     &sha384_init,
     &sha512_process,
@@ -130,3 +128,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha384.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/sha2/sha512.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/sha2/sha512.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,11 +24,9 @@
     64,
     128,
 
-    /* DER identifier */
-    { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 
-      0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 
-      0x00, 0x04, 0x40 },
-    19,
+    /* OID */
+   { 2, 16, 840, 1, 101, 3, 4, 2, 3,  },
+   9,
 
     &sha512_init,
     &sha512_process,
@@ -314,3 +312,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha512.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/tiger.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/tiger.c	Wed Jul 06 12:10:23 2005 +0000
@@ -25,11 +25,9 @@
     24,
     64,
 
-    /* DER identifier */
-    { 0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 
-      0x01, 0x04, 0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 
-      0x00, 0x04, 0x18 },
-    19,
+    /* OID */
+   { 1, 3, 6, 1, 4, 1, 11591, 12, 2,  },
+   9,
 
     &tiger_init,
     &tiger_process,
@@ -809,3 +807,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/tiger.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/whirl/whirl.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/whirl/whirl.c	Wed Jul 06 12:10:23 2005 +0000
@@ -25,9 +25,9 @@
     64,
     64,
 
-    /* DER encoding (not yet supported) */
-    { 0x00 },
-    0,
+   /* OID */
+   { 1, 0, 10118, 3, 0, 55 },
+   6,
 
     &whirlpool_init,
     &whirlpool_process,
@@ -307,3 +307,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/whirl/whirl.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/23 02:42:07 $ */
--- a/src/hashes/whirl/whirltab.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/hashes/whirl/whirltab.c	Wed Jul 06 12:10:23 2005 +0000
@@ -577,3 +577,7 @@
 CONST64(0x6302aa71c81949d9),
 };
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/hashes/whirl/whirltab.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/ltc_tommath.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/ltc_tommath.h	Wed Jul 06 12:10:23 2005 +0000
@@ -575,3 +575,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/ltc_tommath.h,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tomcrypt.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt.h	Wed Jul 06 12:10:23 2005 +0000
@@ -16,8 +16,8 @@
 #endif
 
 /* version */
-#define CRYPT   0x0102
-#define SCRYPT  "1.02"
+#define CRYPT   0x0105
+#define SCRYPT  "1.05"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE  128
@@ -80,3 +80,7 @@
 
 #endif /* TOMCRYPT_H_ */
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/06/19 18:03:25 $ */
--- a/src/headers/tomcrypt_argchk.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_argchk.h	Wed Jul 06 12:10:23 2005 +0000
@@ -19,3 +19,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_argchk.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tomcrypt_cfg.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_cfg.h	Wed Jul 06 12:10:23 2005 +0000
@@ -106,3 +106,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cfg.h,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tomcrypt_cipher.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_cipher.h	Wed Jul 06 12:10:23 2005 +0000
@@ -32,7 +32,7 @@
 
 #ifdef RIJNDAEL
 struct rijndael_key {
-   ulong32 eK[64], dK[64];
+   ulong32 eK[60], dK[60];
    int Nr;
 };
 #endif
@@ -599,8 +599,15 @@
 #endif
 
 #ifdef CTR
-int ctr_start(int cipher, const unsigned char *IV, const unsigned char *key, 
-              int keylen, int num_rounds, symmetric_CTR *ctr);
+
+#define CTR_COUNTER_LITTLE_ENDIAN    0
+#define CTR_COUNTER_BIG_ENDIAN       1
+
+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 ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
 int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
 int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
@@ -611,9 +618,12 @@
 int find_cipher(const char *name);
 int find_cipher_any(const char *name, int blocklen, int keylen);
 int find_cipher_id(unsigned char ID);
-
 int register_cipher(const struct ltc_cipher_descriptor *cipher);
 int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
-
 int cipher_is_valid(int idx);
 
+LTC_MUTEX_PROTO(ltc_cipher_mutex);
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */
+/* $Revision: 1.16 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/headers/tomcrypt_custom.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_custom.h	Wed Jul 06 12:10:23 2005 +0000
@@ -1,6 +1,3 @@
-/* This header is meant to be included before mycrypt.h in projects where
- * you don't want to throw all the defines in a makefile. 
- */
 #ifndef TOMCRYPT_CUSTOM_H_
 #define TOMCRYPT_CUSTOM_H_
 
@@ -81,7 +78,16 @@
 /* Various tidbits of modern neatoness */
 #define BASE64
 
+/* default no functions */
+#define LTC_MUTEX_GLOBAL(x)
+#define LTC_MUTEX_PROTO(x)
+#define LTC_MUTEX_LOCK(x)
+#define LTC_MUTEX_UNLOCK(x)
 #define FORTUNA_POOLS 0
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */
+/* $Revision: 1.17 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/headers/tomcrypt_hash.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_hash.h	Wed Jul 06 12:10:23 2005 +0000
@@ -132,10 +132,11 @@
     unsigned long hashsize;
     /** Input block size in octets */
     unsigned long blocksize;
-    /** ASN.1 DER identifier */
-    unsigned char DER[64];
+    /** ASN.1 OID */
+    unsigned long OID[16];
     /** Length of DER encoding */
-    unsigned long DERlen;
+    unsigned long OIDlen;
+
     /** Init a hash state
       @param hash   The hash to initialize
       @return CRYPT_OK if successful
@@ -278,6 +279,8 @@
 int unregister_hash(const struct ltc_hash_descriptor *hash);
 int hash_is_valid(int idx);
 
+LTC_MUTEX_PROTO(ltc_hash_mutex);
+
 int hash_memory(int hash, 
                 const unsigned char *in,  unsigned long inlen, 
                       unsigned char *out, unsigned long *outlen);
@@ -292,29 +295,29 @@
 {                                                                                           \
     unsigned long n;                                                                        \
     int           err;                                                                      \
-    LTC_ARGCHK(md != NULL);                                                                    \
-    LTC_ARGCHK(in != NULL);                                                                   \
+    LTC_ARGCHK(md != NULL);                                                                 \
+    LTC_ARGCHK(in != NULL);                                                                 \
     if (md-> state_var .curlen > sizeof(md-> state_var .buf)) {                             \
        return CRYPT_INVALID_ARG;                                                            \
     }                                                                                       \
-    while (inlen > 0) {                                                                       \
-        if (md-> state_var .curlen == 0 && inlen >= block_size) {                             \
-           if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \
-              return err;         \
-           }                                        \
+    while (inlen > 0) {                                                                     \
+        if (md-> state_var .curlen == 0 && inlen >= block_size) {                           \
+           if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) {               \
+              return err;                                                                   \
+           }                                                                                \
            md-> state_var .length += block_size * 8;                                        \
-           in             += block_size;                                                   \
-           inlen          -= block_size;                                                   \
+           in             += block_size;                                                    \
+           inlen          -= block_size;                                                    \
         } else {                                                                            \
-           n = MIN(inlen, (block_size - md-> state_var .curlen));                             \
-           memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);             \
+           n = MIN(inlen, (block_size - md-> state_var .curlen));                           \
+           memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n);              \
            md-> state_var .curlen += n;                                                     \
-           in             += n;                                                            \
-           inlen          -= n;                                                            \
+           in             += n;                                                             \
+           inlen          -= n;                                                             \
            if (md-> state_var .curlen == block_size) {                                      \
-              if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {\
-                 return err;                                      \
-              } \
+              if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {            \
+                 return err;                                                                \
+              }                                                                             \
               md-> state_var .length += 8*block_size;                                       \
               md-> state_var .curlen = 0;                                                   \
            }                                                                                \
@@ -322,3 +325,7 @@
     }                                                                                       \
     return CRYPT_OK;                                                                        \
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */
+/* $Revision: 1.12 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/headers/tomcrypt_mac.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_mac.h	Wed Jul 06 12:10:23 2005 +0000
@@ -295,3 +295,7 @@
                          unsigned char *out);
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tomcrypt_macros.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_macros.h	Wed Jul 06 12:10:23 2005 +0000
@@ -132,7 +132,7 @@
 #ifdef ENDIAN_32BITWORD 
 
 #define STORE32L(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
+     { ulong32  __t = (x); memcpy(y, &__t, 4); }
 
 #define LOAD32L(x, y)         \
      memcpy(&(x), y, 4);
@@ -152,7 +152,7 @@
 #else /* 64-bit words then  */
 
 #define STORE32L(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
+     { ulong32 __t = (x); memcpy(y, &__t, 4); }
 
 #define LOAD32L(x, y)         \
      { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
@@ -193,7 +193,7 @@
 #ifdef ENDIAN_32BITWORD 
 
 #define STORE32H(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
+     { ulong32 __t = (x); memcpy(y, &__t, 4); }
 
 #define LOAD32H(x, y)         \
      memcpy(&(x), y, 4);
@@ -213,7 +213,7 @@
 #else /* 64-bit words then  */
 
 #define STORE32H(x, y)        \
-     { unsigned long __t = (x); memcpy(y, &__t, 4); }
+     { ulong32 __t = (x); memcpy(y, &__t, 4); }
 
 #define LOAD32H(x, y)         \
      { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
@@ -371,3 +371,7 @@
 #else
    #define byte(x, n) (((x) >> (8 * (n))) & 255)
 #endif   
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tomcrypt_misc.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_misc.h	Wed Jul 06 12:10:23 2005 +0000
@@ -15,3 +15,7 @@
 int mpi_to_ltc_error(int err);
 
 extern const char *crypt_build_settings;
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tomcrypt_pk.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_pk.h	Wed Jul 06 12:10:23 2005 +0000
@@ -84,9 +84,6 @@
 #define MIN_RSA_SIZE 1024
 #define MAX_RSA_SIZE 4096
 
-/* Stack required for temps (plus padding) */
-// #define RSA_STACK    (8 + (MAX_RSA_SIZE/8))
-
 typedef struct Rsa_key {
     int type;
     mp_int e, d, N, p, q, qP, dP, dQ;
@@ -123,26 +120,6 @@
                           int            hash_idx, unsigned long saltlen,
                           int           *stat,     rsa_key      *key);
 
-/* these use PKCS #1 v1.5 padding */
-int rsa_v15_encrypt_key(const unsigned char *in,    unsigned long  inlen,
-                              unsigned char *out,   unsigned long *outlen,
-                              prng_state    *prng,     int            prng_idx, 
-                              rsa_key       *key);
-         
-int rsa_v15_decrypt_key(const unsigned char *in,     unsigned long  inlen,
-                              unsigned char *out,    unsigned long  outlen, 
-                              int           *stat,   rsa_key       *key);
-
-int rsa_v15_sign_hash(const unsigned char *in,       unsigned long  inlen, 
-                            unsigned char *out,      unsigned long *siglen, 
-                            int            hash_idx, rsa_key       *key);
-
-int rsa_v15_verify_hash(const unsigned char *sig,      unsigned long siglen,
-                        const unsigned char *hash,     unsigned long hashlen,
-                              int            hash_idx, int          *stat,     
-                              rsa_key       *key);
-
-
 /* PKCS #1 import/export */
 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
@@ -244,10 +221,19 @@
 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
 void dsa_free(dsa_key *key);
 
+
+int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
+                                   mp_int *r,   mp_int *s,
+                               prng_state *prng, int wprng, dsa_key *key);
+
 int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
                         unsigned char *out, unsigned long *outlen,
                         prng_state *prng, int wprng, dsa_key *key);
 
+int dsa_verify_hash_raw(         mp_int *r,          mp_int *s,
+                    const unsigned char *hash, unsigned long hashlen, 
+                                    int *stat,      dsa_key *key);
+
 int dsa_verify_hash(const unsigned char *sig,  unsigned long siglen,
                     const unsigned char *hash, unsigned long hashlen, 
                           int           *stat, dsa_key       *key);
@@ -262,9 +248,134 @@
 
 #ifdef LTC_DER
 /* DER handling */
+
+enum {
+ LTC_ASN1_EOL,
+ LTC_ASN1_INTEGER,
+ LTC_ASN1_SHORT_INTEGER,
+ LTC_ASN1_BIT_STRING,
+ LTC_ASN1_OCTET_STRING,
+ LTC_ASN1_NULL,
+ LTC_ASN1_OBJECT_IDENTIFIER,
+ LTC_ASN1_IA5_STRING,
+ LTC_ASN1_PRINTABLE_STRING,
+ LTC_ASN1_UTCTIME,
+
+ LTC_ASN1_CHOICE,
+ LTC_ASN1_SEQUENCE
+};
+
+typedef struct {
+   int           type;
+   void         *data;
+   unsigned long size;
+   int           used;
+} ltc_asn1_list;
+
+#define LTC_SET_ASN1(list, index, Type, Data, Size)  \
+   do {                                              \
+      int LTC_MACRO_temp            = (index);       \
+      ltc_asn1_list *LTC_MACRO_list = (list);        \
+      LTC_MACRO_list[LTC_MACRO_temp].type = (Type);  \
+      LTC_MACRO_list[LTC_MACRO_temp].data = (Data);  \
+      LTC_MACRO_list[LTC_MACRO_temp].size = (Size);  \
+      LTC_MACRO_list[LTC_MACRO_temp].used = 0;       \
+   } while (0);
+
+/* SEQUENCE */
+int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned char *out,  unsigned long *outlen);
+
+int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
+                              ltc_asn1_list *list, unsigned long  outlen);
+
+int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned long *outlen);
+
+/* VA list handy helpers */
+int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
+int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
+
+/* INTEGER */
 int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen);
-int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num);
+int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num);
 int der_length_integer(mp_int *num, unsigned long *len);
-int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, mp_int *num, ...);
-int der_get_multi_integer(const unsigned char *src, unsigned long *inlen,  mp_int *num, ...);
+
+/* INTEGER -- handy for 0..2^32-1 values */
+int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num);
+int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen);
+int der_length_short_integer(unsigned long num, unsigned long *outlen);
+
+/* BIT STRING */
+int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
+
+/* OCTET STRING */
+int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
+                                  unsigned char *out, unsigned long *outlen);
+int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
+                                  unsigned char *out, unsigned long *outlen);
+int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
+
+/* OBJECT IDENTIFIER */
+int der_encode_object_identifier(unsigned long *words, unsigned long  nwords,
+                                 unsigned char *out,   unsigned long *outlen);
+int der_decode_object_identifier(const unsigned char *in,    unsigned long  inlen,
+                                       unsigned long *words, unsigned long *outlen);
+int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen);
+unsigned long der_object_identifier_bits(unsigned long x);
+
+/* IA5 STRING */
+int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
+
+int der_ia5_char_encode(int c);
+int der_ia5_value_decode(int v);
+
+/* Printable STRING */
+int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen);
+int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen);
+
+int der_printable_char_encode(int c);
+int der_printable_value_decode(int v);
+
+/* CHOICE */
+int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
+                            ltc_asn1_list *list, unsigned long  outlen);
+
+/* UTCTime */
+typedef struct {
+   unsigned YY, /* year */
+            MM, /* month */
+            DD, /* day */
+            hh, /* hour */
+            mm, /* minute */
+            ss, /* second */
+            off_dir, /* timezone offset direction 0 == +, 1 == - */
+            off_hh, /* timezone offset hours */
+            off_mm; /* timezone offset minutes */
+} ltc_utctime;
+
+int der_encode_utctime(ltc_utctime *utctime, 
+                       unsigned char *out,   unsigned long *outlen);
+
+int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
+                             ltc_utctime   *out);
+
+int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
+
+
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */
+/* $Revision: 1.30 $ */
+/* $Date: 2005/06/19 11:23:03 $ */
--- a/src/headers/tomcrypt_pkcs.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_pkcs.h	Wed Jul 06 12:10:23 2005 +0000
@@ -10,7 +10,7 @@
 int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out);
 int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen);
 
-/* *** v2.0 padding */
+/* *** v2.1 padding */
 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,
@@ -34,32 +34,6 @@
                             unsigned long saltlen,  int           hash_idx,
                             unsigned long modulus_bitlen, int    *res);
 
-/* *** v1.5 padding */
-/* encryption padding */
-int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
-                               unsigned long  modulus_bitlen, 
-                               prng_state    *prng,   int           prng_idx,
-                               unsigned char *out,    unsigned long *outlen);
-
-/* note "outlen" is fixed, you have to tell this decoder how big
- * the original message was.  Unlike the OAEP decoder it cannot auto-detect it.
- */
-int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
-                               unsigned long modulus_bitlen,
-                               unsigned char *out,  unsigned long outlen,
-                               int           *res);
-
-/* signature padding */
-int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
-                               int            hash_idx, unsigned long modulus_bitlen,
-                               unsigned char *out,      unsigned long *outlen);
-
-int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
-                         const unsigned char *sig,     unsigned long siglen,
-                               int           hash_idx, unsigned long modulus_bitlen, 
-                               int          *res);
-
-
 #endif /* PKCS_1 */
 
 /* ===> PKCS #5 -- Password Based Cryptography <=== */
@@ -78,3 +52,7 @@
                 unsigned char *out,            unsigned long *outlen);
 
 #endif  /* PKCS_5 */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/14 11:46:08 $ */
--- a/src/headers/tomcrypt_prng.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tomcrypt_prng.h	Wed Jul 06 12:10:23 2005 +0000
@@ -178,6 +178,7 @@
 int register_prng(const struct ltc_prng_descriptor *prng);
 int unregister_prng(const struct ltc_prng_descriptor *prng);
 int prng_is_valid(int idx);
+LTC_MUTEX_PROTO(ltc_prng_mutex);
 
 /* Slow RNG you **might** be able to use to seed a PRNG with.  Be careful as this
  * might not work on all platforms as planned
@@ -188,3 +189,7 @@
 
 int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/headers/tommath_class.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tommath_class.h	Wed Jul 06 12:10:23 2005 +0000
@@ -992,3 +992,7 @@
 #else
 #define LTM_LAST
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tommath_class.h,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/headers/tommath_superclass.h	Tue May 10 17:02:59 2005 +0000
+++ b/src/headers/tommath_superclass.h	Wed Jul 06 12:10:23 2005 +0000
@@ -1,10 +1,14 @@
 /* super class file for PK algos */
 
 /* default ... include all MPI */
+#ifndef SC_RSA_1
+
 #define LTM_ALL
 
+#endif
+
 /* RSA only (does not support DH/DSA/ECC) */
-// #define SC_RSA_1
+/* #define SC_RSA_1 */
 
 /* For reference.... On an Athlon64 optimizing for speed...
 
@@ -70,3 +74,7 @@
 #endif
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/headers/tommath_superclass.h,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/14 13:27:20 $ */
--- a/src/mac/hmac/hmac_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -103,3 +103,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_done.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/hmac/hmac_file.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_file.c	Wed Jul 06 12:10:23 2005 +0000
@@ -87,3 +87,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_file.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/hmac/hmac_init.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_init.c	Wed Jul 06 12:10:23 2005 +0000
@@ -106,3 +106,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_init.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/hmac/hmac_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -71,3 +71,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/hmac/hmac_memory_multi.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_memory_multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -86,3 +86,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_memory_multi.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/hmac/hmac_process.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_process.c	Wed Jul 06 12:10:23 2005 +0000
@@ -37,3 +37,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_process.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/hmac/hmac_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/hmac/hmac_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -310,3 +310,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/omac/omac_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -78,3 +78,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/omac/omac_file.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_file.c	Wed Jul 06 12:10:23 2005 +0000
@@ -77,3 +77,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_file.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/omac/omac_init.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_init.c	Wed Jul 06 12:10:23 2005 +0000
@@ -39,7 +39,7 @@
    }
 
 #ifdef LTC_FAST
-   if (16 % sizeof(LTC_FAST_TYPE)) {
+   if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) {
        return CRYPT_INVALID_ARG;
    }
 #endif
@@ -93,3 +93,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_init.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/06/06 10:22:44 $ */
--- a/src/mac/omac/omac_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -69,3 +69,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/omac/omac_memory_multi.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_memory_multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -84,3 +84,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_memory_multi.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/omac/omac_process.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_process.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,7 +27,8 @@
 */
 int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
 {
-   int err, n, x;
+   unsigned long n, x;
+   int           err;
 
    LTC_ARGCHK(omac  != NULL);
    LTC_ARGCHK(in    != NULL);
@@ -57,7 +58,7 @@
    while (inlen != 0) { 
        /* ok if the block is full we xor in prev, encrypt and replace prev */
        if (omac->buflen == omac->blklen) {
-          for (x = 0; x < omac->blklen; x++) {
+          for (x = 0; x < (unsigned long)omac->blklen; x++) {
               omac->block[x] ^= omac->prev[x];
           }
           cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key);
@@ -77,3 +78,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_process.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/05 14:35:58 $ */
--- a/src/mac/omac/omac_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/omac/omac_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -104,3 +104,7 @@
 }   
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pelican/pelican.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pelican/pelican.c	Wed Jul 06 12:10:23 2005 +0000
@@ -102,6 +102,12 @@
 
    LTC_ARGCHK(pelmac != NULL);
    LTC_ARGCHK(in     != NULL);
+
+   /* check range */
+   if (pelmac->buflen < 0 || pelmac->buflen > 15) {
+      return CRYPT_INVALID_ARG;
+   }
+
 #ifdef LTC_FAST
    if (pelmac->buflen == 0) {
       while (inlen & ~15) {
@@ -136,6 +142,12 @@
 {
    LTC_ARGCHK(pelmac  != NULL);
    LTC_ARGCHK(out     != NULL);
+
+   /* check range */
+   if (pelmac->buflen < 0 || pelmac->buflen > 16) {
+      return CRYPT_INVALID_ARG;
+   }
+
    if  (pelmac->buflen == 16) {
        four_rounds(pelmac);
        pelmac->buflen = 0;
@@ -147,3 +159,7 @@
 }                        
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican.c,v $ */
+/* $Revision: 1.16 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pelican/pelican_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pelican/pelican_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -53,3 +53,7 @@
 
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican_memory.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pelican/pelican_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pelican/pelican_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -114,3 +114,7 @@
 
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican_test.c,v $ */
+/* $Revision: 1.9 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -66,3 +66,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_file.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_file.c	Wed Jul 06 12:10:23 2005 +0000
@@ -78,3 +78,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_file.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_init.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_init.c	Wed Jul 06 12:10:23 2005 +0000
@@ -138,3 +138,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_init.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_memory.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_memory.c	Wed Jul 06 12:10:23 2005 +0000
@@ -68,3 +68,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_memory.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_memory_multi.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_memory_multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -83,3 +83,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_memory_multi.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_ntz.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_ntz.c	Wed Jul 06 12:10:23 2005 +0000
@@ -33,3 +33,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_ntz.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_process.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_process.c	Wed Jul 06 12:10:23 2005 +0000
@@ -90,3 +90,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_process.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_shift_xor.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_shift_xor.c	Wed Jul 06 12:10:23 2005 +0000
@@ -38,3 +38,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_shift_xor.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/mac/pmac/pmac_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/mac/pmac/pmac_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -159,3 +159,7 @@
 
 
  
+
+/* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/base64/base64_decode.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/base64/base64_decode.c	Wed Jul 06 12:10:23 2005 +0000
@@ -98,3 +98,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/base64/base64_encode.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/base64/base64_encode.c	Wed Jul 06 12:10:23 2005 +0000
@@ -74,3 +74,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_encode.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/burn_stack.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/burn_stack.c	Wed Jul 06 12:10:23 2005 +0000
@@ -28,3 +28,7 @@
 }
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/burn_stack.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/crypt/crypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -297,8 +297,21 @@
 #if defined(LTC_NO_ASM)
     " LTC_NO_ASM "
 #endif
+#if defined(LTC_NO_TEST)
+    " LTC_NO_TEST "
+#endif
+#if defined(LTC_NO_TABLES)
+    " LTC_NO_TABLES "
+#endif
+#if defined(LTC_PTHREAD)
+    " LTC_PTHREAD "
+#endif
     "\n"
     "\n\n\n"
     ;
 	*/
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt.c,v $ */
+/* $Revision: 1.11 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_argchk.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_argchk.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,3 +24,7 @@
  (void)raise(SIGABRT);
 }
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_argchk.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/crypt/crypt_cipher_descriptor.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_cipher_descriptor.c	Wed Jul 06 12:10:23 2005 +0000
@@ -19,3 +19,9 @@
 { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
  };
 
+LTC_MUTEX_GLOBAL(ltc_cipher_mutex);
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_cipher_descriptor.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_cipher_is_valid.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_cipher_is_valid.c	Wed Jul 06 12:10:23 2005 +0000
@@ -22,8 +22,15 @@
 */
 int cipher_is_valid(int idx)
 {
+   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
+      LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
       return CRYPT_INVALID_CIPHER;
    }
+   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
    return CRYPT_OK;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_cipher_is_valid.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_find_cipher.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_cipher.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,11 +24,18 @@
 {
    int x;
    LTC_ARGCHK(name != NULL);
+   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) {
+          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
           return x;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
    return -1;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_find_cipher_any.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_cipher_any.c	Wed Jul 06 12:10:23 2005 +0000
@@ -31,13 +31,20 @@
    x = find_cipher(name);
    if (x != -1) return x;
 
+   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (cipher_descriptor[x].name == NULL) {
           continue;
        }
        if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
+          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
           return x;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher_any.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_find_cipher_id.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_cipher_id.c	Wed Jul 06 12:10:23 2005 +0000
@@ -23,10 +23,18 @@
 int find_cipher_id(unsigned char ID)
 {
    int x;
+   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (cipher_descriptor[x].ID == ID) {
-          return (cipher_descriptor[x].name == NULL) ? -1 : x;
+          x = (cipher_descriptor[x].name == NULL) ? -1 : x;
+          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
+          return x;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher_id.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_find_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,10 +24,17 @@
 {
    int x;
    LTC_ARGCHK(name != NULL);
+   LTC_MUTEX_LOCK(&ltc_hash_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (hash_descriptor[x].name != NULL && strcmp(hash_descriptor[x].name, name) == 0) {
+          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
           return x;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_find_hash_any.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_hash_any.c	Wed Jul 06 12:10:23 2005 +0000
@@ -28,6 +28,7 @@
    x = find_hash(name);
    if (x != -1) return x;
 
+   LTC_MUTEX_LOCK(&ltc_hash_mutex);
    y = MAXBLOCKSIZE+1;
    z = -1;
    for (x = 0; x < TAB_SIZE; x++) {
@@ -39,5 +40,10 @@
           y = hash_descriptor[x].hashsize;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
    return z;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_any.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_find_hash_id.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_hash_id.c	Wed Jul 06 12:10:23 2005 +0000
@@ -23,10 +23,18 @@
 int find_hash_id(unsigned char ID)
 {
    int x;
+   LTC_MUTEX_LOCK(&ltc_hash_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
-       if (hash_descriptor[x].ID == ID) {
-          return (hash_descriptor[x].name == NULL) ? -1 : x;
-       }
+      if (hash_descriptor[x].ID == ID) {
+          x = (hash_descriptor[x].name == NULL) ? -1 : x;
+          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
+          return x;
+      }
    }
+   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_id.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/06/19 18:03:25 $ */
--- a/src/misc/crypt/crypt_find_prng.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_find_prng.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,11 +24,18 @@
 {
    int x;
    LTC_ARGCHK(name != NULL);
+   LTC_MUTEX_LOCK(&ltc_prng_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if ((prng_descriptor[x].name != NULL) && strcmp(prng_descriptor[x].name, name) == 0) {
+          LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
           return x;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
    return -1;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_prng.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_hash_descriptor.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_hash_descriptor.c	Wed Jul 06 12:10:23 2005 +0000
@@ -18,3 +18,10 @@
 struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
 { NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL }
 };
+
+LTC_MUTEX_GLOBAL(ltc_hash_mutex);
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_hash_is_valid.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_hash_is_valid.c	Wed Jul 06 12:10:23 2005 +0000
@@ -22,8 +22,15 @@
 */
 int hash_is_valid(int idx)
 {
+   LTC_MUTEX_LOCK(&ltc_hash_mutex);
    if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
+      LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
       return CRYPT_INVALID_HASH;
    }
+   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
    return CRYPT_OK;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_prng_descriptor.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_prng_descriptor.c	Wed Jul 06 12:10:23 2005 +0000
@@ -17,3 +17,10 @@
 struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
 { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 };
+
+LTC_MUTEX_GLOBAL(ltc_prng_mutex);
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_prng_is_valid.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_prng_is_valid.c	Wed Jul 06 12:10:23 2005 +0000
@@ -22,8 +22,15 @@
 */
 int prng_is_valid(int idx)
 {
+   LTC_MUTEX_LOCK(&ltc_prng_mutex);
    if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
+      LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
       return CRYPT_INVALID_PRNG;
    }
+   LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
    return CRYPT_OK;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_register_cipher.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_register_cipher.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,8 +27,10 @@
    LTC_ARGCHK(cipher != NULL);
 
    /* is it already registered? */
+   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
+          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
           return x;
        }
    }
@@ -37,10 +39,16 @@
    for (x = 0; x < TAB_SIZE; x++) {
        if (cipher_descriptor[x].name == NULL) {
           XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
+          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
           return x;
        }
    }
 
    /* no spot */
+   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_cipher.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_register_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_register_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,8 +27,10 @@
    LTC_ARGCHK(hash != NULL);
 
    /* is it already registered? */
+   LTC_MUTEX_LOCK(&ltc_hash_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (memcmp(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
+          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
           return x;
        }
    }
@@ -37,10 +39,16 @@
    for (x = 0; x < TAB_SIZE; x++) {
        if (hash_descriptor[x].name == NULL) {
           XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
+          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
           return x;
        }
    }
 
    /* no spot */
+   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_hash.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_register_prng.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_register_prng.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,8 +27,10 @@
    LTC_ARGCHK(prng != NULL);
 
    /* is it already registered? */
+   LTC_MUTEX_LOCK(&ltc_prng_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (memcmp(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
+          LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
           return x;
        }
    }
@@ -37,10 +39,16 @@
    for (x = 0; x < TAB_SIZE; x++) {
        if (prng_descriptor[x].name == NULL) {
           XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
+          LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
           return x;
        }
    }
 
    /* no spot */
+   LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
    return -1;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_prng.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_unregister_cipher.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_unregister_cipher.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,12 +27,19 @@
    LTC_ARGCHK(cipher != NULL);
 
    /* is it already registered? */
+   LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (memcmp(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
           cipher_descriptor[x].name = NULL;
           cipher_descriptor[x].ID   = 255;
+          LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
           return CRYPT_OK;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
    return CRYPT_ERROR;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_cipher.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_unregister_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_unregister_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,11 +27,18 @@
    LTC_ARGCHK(hash != NULL);
 
    /* is it already registered? */
+   LTC_MUTEX_LOCK(&ltc_hash_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (memcmp(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
           hash_descriptor[x].name = NULL;
+          LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
           return CRYPT_OK;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
    return CRYPT_ERROR;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_hash.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/crypt/crypt_unregister_prng.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/crypt/crypt_unregister_prng.c	Wed Jul 06 12:10:23 2005 +0000
@@ -25,13 +25,20 @@
    int x;
 
    LTC_ARGCHK(prng != NULL);
-
+ 
    /* is it already registered? */
+   LTC_MUTEX_LOCK(&ltc_prng_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
        if (memcmp(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) {
           prng_descriptor[x].name = NULL;
+          LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
           return CRYPT_OK;
        }
    }
+   LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
    return CRYPT_ERROR;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_prng.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 18:00:28 $ */
--- a/src/misc/error_to_string.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/error_to_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -68,3 +68,7 @@
    }   
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/error_to_string.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/mpi/is_prime.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/mpi/is_prime.c	Wed Jul 06 12:10:23 2005 +0000
@@ -30,3 +30,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/mpi/is_prime.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/mpi/mpi_to_ltc_error.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/mpi/mpi_to_ltc_error.c	Wed Jul 06 12:10:23 2005 +0000
@@ -42,3 +42,7 @@
 }
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/mpi/mpi_to_ltc_error.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/mpi/rand_prime.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/mpi/rand_prime.c	Wed Jul 06 12:10:23 2005 +0000
@@ -64,3 +64,7 @@
       
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/mpi/rand_prime.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/pkcs5/pkcs_5_1.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/pkcs5/pkcs_5_1.c	Wed Jul 06 12:10:23 2005 +0000
@@ -100,3 +100,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_1.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/pkcs5/pkcs_5_2.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/pkcs5/pkcs_5_2.c	Wed Jul 06 12:10:23 2005 +0000
@@ -123,3 +123,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/misc/zeromem.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/misc/zeromem.c	Wed Jul 06 12:10:23 2005 +0000
@@ -28,3 +28,7 @@
       *mem++ = 0;
    }
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/misc/zeromem.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cbc/cbc_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cbc/cbc_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -89,3 +89,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_decrypt.c,v $ */
+/* $Revision: 1.9 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cbc/cbc_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cbc/cbc_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -36,3 +36,7 @@
    
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cbc/cbc_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cbc/cbc_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -90,3 +90,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_encrypt.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cbc/cbc_getiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cbc/cbc_getiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -39,3 +39,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_getiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cbc/cbc_setiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cbc/cbc_setiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -38,3 +38,7 @@
 
 #endif 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_setiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cbc/cbc_start.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cbc/cbc_start.c	Wed Jul 06 12:10:23 2005 +0000
@@ -56,3 +56,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_start.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cfb/cfb_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cfb/cfb_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -59,3 +59,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_decrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cfb/cfb_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cfb/cfb_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -36,3 +36,7 @@
    
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cfb/cfb_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cfb/cfb_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -57,3 +57,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_encrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cfb/cfb_getiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cfb/cfb_getiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -39,3 +39,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_getiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cfb/cfb_setiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cfb/cfb_setiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -47,3 +47,7 @@
 
 #endif 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_setiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/cfb/cfb_start.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/cfb/cfb_start.c	Wed Jul 06 12:10:23 2005 +0000
@@ -61,3 +61,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_start.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ctr/ctr_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ctr/ctr_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -36,3 +36,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_decrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ctr/ctr_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ctr/ctr_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -36,3 +36,7 @@
    
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ctr/ctr_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ctr/ctr_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -60,7 +60,7 @@
       /* is the pad empty? */
       if (ctr->padlen == ctr->blocklen) {
          /* increment counter */
-         if (ctr->mode == 0) {
+         if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
             /* little-endian */
             for (x = 0; x < ctr->blocklen; x++) {
                ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
@@ -102,3 +102,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_encrypt.c,v $ */
+/* $Revision: 1.13 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ctr/ctr_getiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ctr/ctr_getiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -39,3 +39,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_getiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ctr/ctr_setiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ctr/ctr_setiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -52,3 +52,7 @@
 
 #endif 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_setiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ctr/ctr_start.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ctr/ctr_start.c	Wed Jul 06 12:10:23 2005 +0000
@@ -21,19 +21,23 @@
 /**
    Initialize a CTR context
    @param cipher      The index of the cipher desired
-   @param count       The initial vector
+   @param IV          The initial vector
    @param key         The secret key 
    @param keylen      The length of the secret key (octets)
    @param num_rounds  Number of rounds in the cipher desired (0 for default)
+   @param ctr_mode    The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN)
    @param ctr         The CTR state to initialize
    @return CRYPT_OK if successful
 */
-int ctr_start(int cipher, const unsigned char *count, const unsigned char *key, int keylen, 
-              int num_rounds, symmetric_CTR *ctr)
+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 x, err;
 
-   LTC_ARGCHK(count != NULL);
+   LTC_ARGCHK(IV  != NULL);
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(ctr != NULL);
 
@@ -51,12 +55,16 @@
    ctr->blocklen = cipher_descriptor[cipher].block_length;
    ctr->cipher   = cipher;
    ctr->padlen   = 0;
-   ctr->mode     = 0;
+   ctr->mode     = ctr_mode;
    for (x = 0; x < ctr->blocklen; x++) {
-       ctr->ctr[x] = count[x];
+       ctr->ctr[x] = IV[x];
    }
    cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
    return CRYPT_OK;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_start.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ecb/ecb_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ecb/ecb_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -53,3 +53,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_decrypt.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ecb/ecb_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ecb/ecb_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -18,7 +18,7 @@
 #ifdef ECB
 
 /** Terminate the chain
-  @param rcb    The ECB chain to terminate
+  @param ecb    The ECB chain to terminate
   @return CRYPT_OK on success
 */
 int ecb_done(symmetric_ECB *ecb)
@@ -36,3 +36,7 @@
    
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_done.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ecb/ecb_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ecb/ecb_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -53,3 +53,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_encrypt.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ecb/ecb_start.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ecb/ecb_start.c	Wed Jul 06 12:10:23 2005 +0000
@@ -42,3 +42,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_start.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ofb/ofb_decrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ofb/ofb_decrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -37,3 +37,7 @@
 #endif
 
  
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_decrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ofb/ofb_done.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ofb/ofb_done.c	Wed Jul 06 12:10:23 2005 +0000
@@ -36,3 +36,7 @@
    
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_done.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ofb/ofb_encrypt.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ofb/ofb_encrypt.c	Wed Jul 06 12:10:23 2005 +0000
@@ -52,3 +52,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_encrypt.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ofb/ofb_getiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ofb/ofb_getiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -39,3 +39,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_getiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ofb/ofb_setiv.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ofb/ofb_setiv.c	Wed Jul 06 12:10:23 2005 +0000
@@ -47,3 +47,7 @@
 
 #endif 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_setiv.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/modes/ofb/ofb_start.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/modes/ofb/ofb_start.c	Wed Jul 06 12:10:23 2005 +0000
@@ -54,3 +54,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_start.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/bit/der_decode_bit_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,101 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_bit_string.c
+  ASN.1 DER, encode a BIT STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store a BIT STRING
+  @param in      The DER encoded BIT STRING
+  @param inlen   The size of the DER BIT STRING
+  @param out     [out] The array of bits stored (one per char)
+  @param outlen  [in/out] The number of bits stored
+  @return CRYPT_OK if successful
+*/
+int der_decode_bit_string(const unsigned char *in,  unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen)
+{
+   unsigned long dlen, blen, x, y;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* packet must be at least 4 bytes */
+   if (inlen < 4) {
+       return CRYPT_INVALID_ARG;
+   }
+
+   /* check for 0x03 */
+   if ((in[0]&0x1F) != 0x03) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+    /* offset in the data */
+    x = 1;
+
+   /* get the length of the data */
+   if (in[x] & 0x80) {
+      /* long format get number of length bytes */
+      y = in[x++] & 127;
+
+      /* invalid if 0 or > 2 */
+      if (y == 0 || y > 2) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* read the data len */
+      dlen = 0;
+      while (y--) {
+         dlen = (dlen << 8) | (unsigned long)in[x++];
+      }
+   } else {
+      /* short format */
+      dlen = in[x++] & 127;
+   }
+  
+   /* is the data len too long or too short? */
+   if ((dlen == 0) || (dlen + x > inlen)) {
+       return CRYPT_INVALID_PACKET;
+   }
+
+   /* get padding count */
+   blen = ((dlen - 1) << 3) - (in[x++] & 7);
+
+   /* too many bits? */
+   if (blen > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* decode/store the bits */
+   for (y = 0; y < blen; y++) {
+       out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
+       if ((y & 7) == 7) {
+          ++x;
+       }
+   }
+
+   /* we done */
+   *outlen = blen;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/bit/der_encode_bit_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,87 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_bit_string.c
+  ASN.1 DER, encode a BIT STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store a BIT STRING
+  @param in       The array of bits to store (one per char)
+  @param inlen    The number of bits tostore
+  @param out      [out] The destination for the DER encoded BIT STRING
+  @param outlen   [in/out] The max size and resulting size of the DER BIT STRING
+  @return CRYPT_OK if successful
+*/
+int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen)
+{
+   unsigned long len, x, y, buf;
+   int           err;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* avoid overflows */
+   if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
+      return err;
+   }
+
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* store header (include bit padding count in length) */
+   x = 0;
+   y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
+
+   out[x++] = 0x03;
+   if (y < 128) {
+      out[x++] = y;
+   } else if (y < 256) {
+      out[x++] = 0x81;
+      out[x++] = y;
+   } else if (y < 65536) {
+      out[x++] = 0x82;
+      out[x++] = (y>>8)&255;
+      out[x++] = y&255;
+   }
+
+   /* store number of zero padding bits */
+   out[x++] = (8 - inlen) & 7;
+
+   /* store the bits in big endian format */
+   for (y = buf = 0; y < inlen; y++) {
+       buf |= (in[y] ? 1 : 0) << (7 - (y & 7));
+       if ((y & 7) == 7) {
+          out[x++] = buf;
+          buf      = 0;
+       }
+   }
+   /* store last byte */
+   if (inlen & 7) {
+      out[x++] = buf;
+   }
+   *outlen = x;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/bit/der_length_bit_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,54 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_bit_string.c
+  ASN.1 DER, get length of BIT STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+/**
+  Gets length of DER encoding of BIT STRING 
+  @param nbits  The number of bits in the string to encode
+  @param outlen [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
+{
+   unsigned long nbytes;
+   LTC_ARGCHK(outlen != NULL);
+
+   /* get the number of the bytes */
+   nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
+ 
+   if (nbytes < 128) {
+      /* 03 LL PP DD DD DD ... */
+      *outlen = 2 + nbytes;
+   } else if (nbytes < 256) {
+      /* 03 81 LL PP DD DD DD ... */
+      *outlen = 3 + nbytes;
+   } else if (nbytes < 65536) {
+      /* 03 82 LL LL PP DD DD DD ... */
+      *outlen = 4 + nbytes;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   return CRYPT_OK;
+}
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/choice/der_decode_choice.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,168 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_choice.c
+  ASN.1 DER, decode a CHOICE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+   Decode a CHOICE
+   @param in       The DER encoded input
+   @param inlen    [in/out] The size of the input and resulting size of read type
+   @param list     The list of items to decode
+   @param outlen   The number of items in the list
+   @return CRYPT_OK on success
+*/
+int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
+                            ltc_asn1_list *list, unsigned long  outlen)
+{
+   unsigned long size, x, z;
+   void          *data;
+
+   LTC_ARGCHK(in    != NULL);
+   LTC_ARGCHK(inlen != NULL);
+   LTC_ARGCHK(list  != NULL);
+
+   /* get blk size */
+   if (*inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* set all of the "used" flags to zero */
+   for (x = 0; x < outlen; x++) {
+       list[x].used = 0;
+   }
+
+   /* now scan until we have a winner */
+   for (x = 0; x < outlen; x++) {
+       size = list[x].size;
+       data = list[x].data;
+
+       switch (list[x].type) {
+           case LTC_ASN1_INTEGER:
+               if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
+                  if (der_length_integer(data, &z) == CRYPT_OK) {
+                      list[x].used = 1;
+                      *inlen       = z;
+                      return CRYPT_OK;
+                  }
+               }
+               break;
+
+           case LTC_ASN1_SHORT_INTEGER:
+               if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
+                  if (der_length_short_integer(size, &z) == CRYPT_OK) {
+                      list[x].used = 1;
+                      *inlen       = z;
+                      return CRYPT_OK;
+                  }
+               }
+               break;
+
+           case LTC_ASN1_BIT_STRING:
+               if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
+                  if (der_length_bit_string(size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     list[x].size = size;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
+           case LTC_ASN1_OCTET_STRING:
+               if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
+                  if (der_length_octet_string(size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     list[x].size = size;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
+           case LTC_ASN1_NULL:
+               if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
+                  *inlen = 2;
+                  return CRYPT_OK;
+               }
+               break;
+                  
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+               if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
+                  if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     list[x].size = size;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
+           case LTC_ASN1_IA5_STRING:
+               if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
+                  if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     list[x].size = size;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
+
+           case LTC_ASN1_PRINTABLE_STRING:
+               if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
+                  if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     list[x].size = size;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
+           case LTC_ASN1_UTCTIME:
+               z = *inlen;
+               if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
+                  list[x].used = 1;
+                  *inlen       = z;
+                  return CRYPT_OK;
+               }
+               break;
+
+           case LTC_ASN1_SEQUENCE:
+               if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
+                  if (der_length_sequence(data, size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
+           default:
+               return CRYPT_INVALID_ARG;
+       }
+   }
+
+   return CRYPT_INVALID_PACKET;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/19 11:25:01 $ */
--- a/src/pk/asn1/der/der_decode_integer.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-  @file der_decode_integer.c
-  ASN.1 DER, decode an integer, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/* decodes a DER INTEGER in [in].  You have to tell this function
- * how many bytes are available [inlen].  It will then attempt to 
- * read the INTEGER.  If all goes well it stores the number of bytes
- * read in [inlen] and the number in [num].
- */
-/**
-  Read a mp_int integer
-  @param in       The DER encoded data
-  @param inlen    [in] Size of the in data, [out] number of bytes read
-  @param num      The first mp_int to decode
-  @return CRYPT_OK if successful
-*/
-int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num)
-{
-   unsigned long tmplen, y, z;
-
-   LTC_ARGCHK(num    != NULL);
-   LTC_ARGCHK(in     != NULL);
-   LTC_ARGCHK(inlen  != NULL);
-
-   /* save copy of max output size */
-   tmplen = *inlen;
-   *inlen = 0;
-
-   /* min DER INTEGER is 0x02 01 00 == 0 */
-   if (tmplen < (1 + 1 + 1)) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* ok expect 0x02 when we AND with 0011 1111 [3F] */
-   if ((*in++ & 0x3F) != 0x02) {
-      return CRYPT_INVALID_PACKET;
-   }
-   ++(*inlen);
-
-   /* now decode the len stuff */
-   z = *in++;
-   ++(*inlen);
-
-   if ((z & 0x80) == 0x00) {
-      /* short form */
-
-      /* will it overflow? */
-      if (*inlen + z > tmplen) {
-         return CRYPT_INVALID_PACKET;
-      }
-     
-      /* no so read it */
-      (*inlen) += z;
-      return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z));
-   } else {
-      /* long form */
-      z &= 0x7F;
-      
-      /* will number of length bytes overflow? (or > 4) */
-      if (((*inlen + z) > tmplen) || (z > 4)) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* now read it in */
-      y = 0;
-      while (z--) {
-         y = ((unsigned long)(*in++)) | (y << 8);
-         ++(*inlen);
-      }
-
-      /* now will reading y bytes overrun? */
-      if ((*inlen + y) > tmplen) {
-         return CRYPT_INVALID_PACKET;
-      }
-
-      /* no so read it */
-      (*inlen) += y;
-      return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y));
-   }
-}
-
-#endif
--- a/src/pk/asn1/der/der_encode_integer.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-  @file der_encode_integer.c
-  ASN.1 DER, encode an integer, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
-/**
-  Store a mp_int integer
-  @param num      The first mp_int to encode
-  @param out      [out] The destination for the DER encoded integers
-  @param outlen   [in/out] The max size and resulting size of the DER encoded integers
-  @return CRYPT_OK if successful
-*/
-int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen)
-{  
-   unsigned long tmplen, x, y, z;
-   int           err, leading_zero;
-
-   LTC_ARGCHK(num    != NULL);
-   LTC_ARGCHK(out    != NULL);
-   LTC_ARGCHK(outlen != NULL);
-
-   /* find out how big this will be */
-   if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
-      return err;
-   }
-
-   if (*outlen < tmplen) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
-   /* we only need a leading zero if the msb of the first byte is one */
-   if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) {
-      leading_zero = 1;
-   } else {
-      leading_zero = 0;
-   }
-
-   /* get length of num in bytes (plus 1 since we force the msbyte to zero) */
-   y = mp_unsigned_bin_size(num) + leading_zero;
-
-   /* now store initial data */
-   *out++ = 0x02;
-   if (y < 128) {
-      /* short form */
-      *out++ = (unsigned char)y;
-   } else {
-      /* long form (relies on y != 0) */
-
-      /* get length of length... ;-) */
-      x = y;
-      z = 0;
-      while (x) {
-         ++z;
-         x >>= 8;
-      }
-      
-      /* store length of length */
-      *out++ = 0x80 | ((unsigned char)z);
-
-      /* now store length */
-      
-      /* first shift length up so msbyte != 0 */
-      x = y;
-      while ((x & 0xFF000000) == 0) {
-          x <<= 8;
-      }
-
-      /* now store length */
-      while (z--) {
-         *out++ = (unsigned char)((x >> 24) & 0xFF);
-         x <<= 8;
-      }
-   }
-
-   /* now store msbyte of zero if num is non-zero */
-   if (leading_zero) {
-      *out++ = 0x00;
-   }
-
-   /* if it's not zero store it as big endian */
-   if (mp_iszero(num) == MP_NO) {
-      /* now store the mpint */
-      if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) {
-          return mpi_to_ltc_error(err);
-      }
-   }
-
-   /* we good */
-   *outlen = tmplen; 
-   return CRYPT_OK;
-}
-
-#endif
--- a/src/pk/asn1/der/der_get_multi_integer.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include <stdarg.h>
-#include "tomcrypt.h"
-
-/**
-  @file der_get_multi_integer.c
-  ASN.1 DER, read multiple integers, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/* will read multiple DER INTEGER encoded mp_ints from src
- * of upto [inlen] bytes.  It will store the number of bytes
- * read back into [inlen].
- */
-/**
-  Read multiple mp_int integers one after another
-  @param src      The DER encoded integers
-  @param inlen    [in] The length of the src buffer, [out] the amount of bytes read
-  @param num      The first mp_int to decode
-  @param ...      A NULL terminated list of mp_ints to decode
-  @return CRYPT_OK if successful
-*/
-int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, 
-                  mp_int *num, ...)
-{
-   va_list        args;
-   mp_int        *next;
-   unsigned long  wrote, len;
-   int            err;
-
-   LTC_ARGCHK(src    != NULL);
-   LTC_ARGCHK(inlen  != NULL);
-
-   /* setup va list */
-   next  = num;
-   len   = *inlen;
-   wrote = 0;
-   va_start(args, num);
-
-   while (next != NULL) {
-       if ((err = der_decode_integer(src, inlen, next)) != CRYPT_OK) {
-          va_end(args);
-          return err;
-       }
-       wrote += *inlen;
-       src   += *inlen;
-       len   -= *inlen;
-       *inlen = len;
-        next     = va_arg(args, mp_int*);
-   }
-   va_end(args);
-   *inlen = wrote;
-   return CRYPT_OK;
-}
-
-#endif
--- a/src/pk/asn1/der/der_length_integer.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-  @file der_length_integer.c
-  ASN.1 DER, get length of encoding, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-/**
-  Gets length of DER encoding of num 
-  @param num    The mp_int to get the size of 
-  @param outlen [out] The length of the DER encoding for the given integer
-  @return CRYPT_OK if successful
-*/
-int der_length_integer(mp_int *num, unsigned long *outlen)
-{
-   unsigned long z, len;
-   int           leading_zero;
-
-   LTC_ARGCHK(num     != NULL);
-   LTC_ARGCHK(outlen  != NULL);
-
-   /* we only need a leading zero if the msb of the first byte is one */
-   if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) {
-      leading_zero = 1;
-   } else {
-      leading_zero = 0;
-   }
-
-   /* size for bignum */
-   z = len = leading_zero + mp_unsigned_bin_size(num);
-
-   /* we need a 0x02 */
-   ++len;
-
-   /* now we need a length */
-   if (z < 128) {
-      /* short form */
-      ++len;
-   } else {
-      /* long form (relies on z != 0) */
-      ++len;
-
-      while (z) {
-         ++len;
-         z >>= 8;
-      }
-   }
-
-   *outlen = len; 
-   return CRYPT_OK;
-}
-
-#endif
--- a/src/pk/asn1/der/der_put_multi_integer.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include <stdarg.h>
-#include "tomcrypt.h"
-
-/**
-  @file der_put_multi_integer.c
-  ASN.1 DER, store multiple integers, Tom St Denis
-*/
-
-
-#ifdef LTC_DER
-
-/* store multiple mp_ints in DER INTEGER format to the out, will not
- * overflow the length you give it [outlen] and store the number of 
- * bytes used in [outlen] 
- */
-/**
-  Store multiple mp_int integers one after another
-  @param out      [out] The destination for the DER encoded integers
-  @param outlen   [in/out] The max size and resulting size of the DER encoded integers
-  @param num      The first mp_int to encode
-  @param ...      A NULL terminated list of mp_ints to encode
-  @return CRYPT_OK if successful
-*/
-int der_put_multi_integer(unsigned char *out, unsigned long *outlen, 
-                  mp_int *num, ...)
-{
-   va_list        args;
-   mp_int        *next;
-   unsigned long  wrote, len;
-   int            err;
-
-   LTC_ARGCHK(out    != NULL);
-   LTC_ARGCHK(outlen != NULL);
-
-   /* setup va list */
-   next  = num;
-   len   = *outlen;
-   wrote = 0;
-   va_start(args, num);
-
-   while (next != NULL) {
-        if ((err = der_encode_integer(next, out, outlen)) != CRYPT_OK) {
-           va_end(args);
-           return err;
-        }
-        wrote   += *outlen;
-        out     += *outlen;
-        len     -= *outlen;
-        *outlen  = len;
-        next     = va_arg(args, mp_int*);
-   }
-   va_end(args);
-   *outlen = wrote;
-   return CRYPT_OK;
-}
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/ia5/der_decode_ia5_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,95 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_ia5_string.c
+  ASN.1 DER, encode a IA5 STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store a IA5 STRING
+  @param in      The DER encoded IA5 STRING
+  @param inlen   The size of the DER IA5 STRING
+  @param out     [out] The array of octets stored (one per char)
+  @param outlen  [in/out] The number of octets stored
+  @return CRYPT_OK if successful
+*/
+int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+   int           t;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* must have header at least */
+   if (inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* check for 0x16 */
+   if ((in[0] & 0x1F) != 0x16) {
+      return CRYPT_INVALID_PACKET;
+   }
+   x = 1;
+
+   /* decode the length */
+   if (in[x] & 0x80) {
+      /* valid # of bytes in length are 1,2,3 */
+      y = in[x] & 0x7F;
+      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* read the length in */
+      len = 0;
+      ++x;
+      while (y--) {
+         len = (len << 8) | in[x++];
+      }
+   } else {
+      len = in[x++] & 0x7F;
+   }
+
+   /* is it too long? */
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   if (len + x > inlen) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* read the data */
+   for (y = 0; y < len; y++) {
+       t = der_ia5_value_decode(in[x++]);
+       if (t == -1) {
+           return CRYPT_INVALID_ARG;
+       }
+       out[y] = t;
+   }
+
+   *outlen = y;
+
+   return CRYPT_OK;
+}
+ 
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/ia5/der_encode_ia5_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,84 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_ia5_string.c
+  ASN.1 DER, encode a IA5 STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+  Store an IA5 STRING
+  @param in       The array of IA5 to store (one per char)
+  @param inlen    The number of IA5 to store
+  @param out      [out] The destination for the DER encoded IA5 STRING
+  @param outlen   [in/out] The max size and resulting size of the DER IA5 STRING
+  @return CRYPT_OK if successful
+*/
+int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+   int           err;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* get the size */
+   if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) {
+      return err; 
+   }
+
+   /* too big? */
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* encode the header+len */
+   x = 0;
+   out[x++] = 0x16;
+   if (inlen < 128) {
+      out[x++] = inlen;
+   } else if (inlen < 256) {
+      out[x++] = 0x81;
+      out[x++] = inlen;
+   } else if (inlen < 65536UL) {
+      out[x++] = 0x82;
+      out[x++] = (inlen>>8)&255;
+      out[x++] = inlen&255;
+   } else if (inlen < 16777216UL) {
+      out[x++] = 0x83;
+      out[x++] = (inlen>>16)&255;
+      out[x++] = (inlen>>8)&255;
+      out[x++] = inlen&255;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* store octets */
+   for (y = 0; y < inlen; y++) {
+       out[x++] = der_ia5_char_encode(in[y]);
+   }
+
+   /* retun length */
+   *outlen = x;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/ia5/der_length_ia5_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,194 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_ia5_string.c
+  ASN.1 DER, get length of IA5 STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+static const struct {
+   int code, value;
+} ia5_table[] = {
+{ '\0', 0 },
+{ '\a', 7 }, 
+{ '\b', 8 }, 
+{ '\t', 9 }, 
+{ '\n', 10 }, 
+{ '\f', 12 }, 
+{ '\r', 13 }, 
+{ ' ', 32 }, 
+{ '!', 33 }, 
+{ '"', 34 }, 
+{ '#', 35 }, 
+{ '$', 36 }, 
+{ '%', 37 }, 
+{ '&', 38 }, 
+{ '\'', 39 }, 
+{ '(', 40 }, 
+{ ')', 41 }, 
+{ '*', 42 }, 
+{ '+', 43 }, 
+{ ',', 44 }, 
+{ '-', 45 }, 
+{ '.', 46 }, 
+{ '/', 47 }, 
+{ '0', 48 }, 
+{ '1', 49 }, 
+{ '2', 50 }, 
+{ '3', 51 }, 
+{ '4', 52 }, 
+{ '5', 53 }, 
+{ '6', 54 }, 
+{ '7', 55 }, 
+{ '8', 56 }, 
+{ '9', 57 }, 
+{ ':', 58 }, 
+{ ';', 59 }, 
+{ '<', 60 }, 
+{ '=', 61 }, 
+{ '>', 62 }, 
+{ '?', 63 }, 
+{ '@', 64 }, 
+{ 'A', 65 }, 
+{ 'B', 66 }, 
+{ 'C', 67 }, 
+{ 'D', 68 }, 
+{ 'E', 69 }, 
+{ 'F', 70 }, 
+{ 'G', 71 }, 
+{ 'H', 72 }, 
+{ 'I', 73 }, 
+{ 'J', 74 }, 
+{ 'K', 75 }, 
+{ 'L', 76 }, 
+{ 'M', 77 }, 
+{ 'N', 78 }, 
+{ 'O', 79 }, 
+{ 'P', 80 }, 
+{ 'Q', 81 }, 
+{ 'R', 82 }, 
+{ 'S', 83 }, 
+{ 'T', 84 }, 
+{ 'U', 85 }, 
+{ 'V', 86 }, 
+{ 'W', 87 }, 
+{ 'X', 88 }, 
+{ 'Y', 89 }, 
+{ 'Z', 90 }, 
+{ '[', 91 }, 
+{ '\\', 92 }, 
+{ ']', 93 }, 
+{ '^', 94 }, 
+{ '_', 95 }, 
+{ '`', 96 }, 
+{ 'a', 97 }, 
+{ 'b', 98 }, 
+{ 'c', 99 }, 
+{ 'd', 100 }, 
+{ 'e', 101 }, 
+{ 'f', 102 }, 
+{ 'g', 103 }, 
+{ 'h', 104 }, 
+{ 'i', 105 }, 
+{ 'j', 106 }, 
+{ 'k', 107 }, 
+{ 'l', 108 }, 
+{ 'm', 109 }, 
+{ 'n', 110 }, 
+{ 'o', 111 }, 
+{ 'p', 112 }, 
+{ 'q', 113 }, 
+{ 'r', 114 }, 
+{ 's', 115 }, 
+{ 't', 116 }, 
+{ 'u', 117 }, 
+{ 'v', 118 }, 
+{ 'w', 119 }, 
+{ 'x', 120 }, 
+{ 'y', 121 }, 
+{ 'z', 122 }, 
+{ '{', 123 }, 
+{ '|', 124 }, 
+{ '}', 125 }, 
+{ '~', 126 }
+};
+
+int der_ia5_char_encode(int c)
+{
+   int x;
+   for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
+       if (ia5_table[x].code == c) {
+          return ia5_table[x].value;
+       }
+   }
+   return -1;
+}
+
+int der_ia5_value_decode(int v)
+{
+   int x;
+   for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
+       if (ia5_table[x].value == v) {
+          return ia5_table[x].code;
+       }
+   }
+   return -1;
+}
+   
+/**
+  Gets length of DER encoding of IA5 STRING 
+  @param octets   The values you want to encode 
+  @param noctets  The number of octets in the string to encode
+  @param outlen   [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
+{
+   unsigned long x;
+
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(octets != NULL);
+
+   /* scan string for validity */
+   for (x = 0; x < noctets; x++) {
+       if (der_ia5_char_encode(octets[x]) == -1) {
+          return CRYPT_INVALID_ARG;
+       }
+   }
+
+   if (noctets < 128) {
+      /* 16 LL DD DD DD ... */
+      *outlen = 2 + noctets;
+   } else if (noctets < 256) {
+      /* 16 81 LL DD DD DD ... */
+      *outlen = 3 + noctets;
+   } else if (noctets < 65536UL) {
+      /* 16 82 LL LL DD DD DD ... */
+      *outlen = 4 + noctets;
+   } else if (noctets < 16777216UL) {
+      /* 16 83 LL LL LL DD DD DD ... */
+      *outlen = 5 + noctets;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   return CRYPT_OK;
+}
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/integer/der_decode_integer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,110 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_integer.c
+  ASN.1 DER, decode an integer, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Read a mp_int integer
+  @param in       The DER encoded data
+  @param inlen    Size of DER encoded data
+  @param num      The first mp_int to decode
+  @return CRYPT_OK if successful
+*/
+int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num)
+{
+   unsigned long x, y, z;
+   int           err;
+
+   LTC_ARGCHK(num    != NULL);
+   LTC_ARGCHK(in     != NULL);
+
+   /* min DER INTEGER is 0x02 01 00 == 0 */
+   if (inlen < (1 + 1 + 1)) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* ok expect 0x02 when we AND with 0001 1111 [1F] */
+   x = 0;
+   if ((in[x++] & 0x1F) != 0x02) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* now decode the len stuff */
+   z = in[x++];
+
+   if ((z & 0x80) == 0x00) {
+      /* short form */
+
+      /* will it overflow? */
+      if (x + z > inlen) {
+         return CRYPT_INVALID_PACKET;
+      }
+     
+      /* no so read it */
+      if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, z))) != CRYPT_OK) {
+         return err;
+      }
+   } else {
+      /* long form */
+      z &= 0x7F;
+      
+      /* will number of length bytes overflow? (or > 4) */
+      if (((x + z) > inlen) || (z > 4) || (z == 0)) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* now read it in */
+      y = 0;
+      while (z--) {
+         y = ((unsigned long)(in[x++])) | (y << 8);
+      }
+
+      /* now will reading y bytes overrun? */
+      if ((x + y) > inlen) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* no so read it */
+      if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, y))) != CRYPT_OK) {
+         return err;
+      }
+   }
+
+   /* see if it's negative */
+   if (in[x] & 0x80) {
+      mp_int tmp;
+      if (mp_init(&tmp) != MP_OKAY) {
+         return CRYPT_MEM;
+      }
+
+      if (mp_2expt(&tmp, mp_count_bits(num)) != MP_OKAY || mp_sub(num, &tmp, num) != MP_OKAY) {
+         mp_clear(&tmp);
+         return CRYPT_MEM;
+      }
+      mp_clear(&tmp);
+   } 
+
+   return CRYPT_OK;
+
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/06/01 00:06:05 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/integer/der_encode_integer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,128 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_integer.c
+  ASN.1 DER, encode an integer, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
+/**
+  Store a mp_int integer
+  @param num      The first mp_int to encode
+  @param out      [out] The destination for the DER encoded integers
+  @param outlen   [in/out] The max size and resulting size of the DER encoded integers
+  @return CRYPT_OK if successful
+*/
+int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen)
+{  
+   unsigned long tmplen, y;
+   int           err, leading_zero;
+
+   LTC_ARGCHK(num    != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* find out how big this will be */
+   if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
+      return err;
+   }
+
+   if (*outlen < tmplen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   if (mp_cmp_d(num, 0) != MP_LT) {
+      /* we only need a leading zero if the msb of the first byte is one */
+      if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) {
+         leading_zero = 1;
+      } else {
+         leading_zero = 0;
+      }
+
+      /* get length of num in bytes (plus 1 since we force the msbyte to zero) */
+      y = mp_unsigned_bin_size(num) + leading_zero;
+   } else {
+      leading_zero = 0;
+      y            = mp_count_bits(num);
+      y            = y + (8 - (y & 7));
+      y            = y >> 3;
+
+   }
+
+   /* now store initial data */
+   *out++ = 0x02;
+   if (y < 128) {
+      /* short form */
+      *out++ = (unsigned char)y;
+   } else if (y < 256) {
+      *out++ = 0x81;
+      *out++ = y;
+   } else if (y < 65536UL) {
+      *out++ = 0x82;
+      *out++ = (y>>8)&255;
+      *out++ = y;
+   } else if (y < 16777216UL) {
+      *out++ = 0x83;
+      *out++ = (y>>16)&255;
+      *out++ = (y>>8)&255;
+      *out++ = y;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* now store msbyte of zero if num is non-zero */
+   if (leading_zero) {
+      *out++ = 0x00;
+   }
+
+   /* if it's not zero store it as big endian */
+   if (mp_cmp_d(num, 0) == MP_GT) {
+      /* now store the mpint */
+      if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) {
+          return mpi_to_ltc_error(err);
+      }
+   } else if (mp_iszero(num) != MP_YES) {
+      mp_int tmp;
+      /* negative */
+      if (mp_init(&tmp) != MP_OKAY) {
+         return CRYPT_MEM;
+      }
+
+      /* 2^roundup and subtract */
+      y = mp_count_bits(num);
+      y = y + (8 - (y & 7));
+      if (mp_2expt(&tmp, y) != MP_OKAY || mp_add(&tmp, num, &tmp) != MP_OKAY) {
+         mp_clear(&tmp);
+         return CRYPT_MEM;
+      }
+
+      if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) {
+         mp_clear(&tmp);
+         return mpi_to_ltc_error(err);
+      }
+      mp_clear(&tmp);
+   }
+
+   /* we good */
+   *outlen = tmplen; 
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/integer/der_length_integer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,81 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_integer.c
+  ASN.1 DER, get length of encoding, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+/**
+  Gets length of DER encoding of num 
+  @param num    The mp_int to get the size of 
+  @param outlen [out] The length of the DER encoding for the given integer
+  @return CRYPT_OK if successful
+*/
+int der_length_integer(mp_int *num, unsigned long *outlen)
+{
+   unsigned long z, len;
+   int           leading_zero;
+
+   LTC_ARGCHK(num     != NULL);
+   LTC_ARGCHK(outlen  != NULL);
+
+   if (mp_cmp_d(num, 0) != MP_LT) {
+      /* positive */
+
+      /* we only need a leading zero if the msb of the first byte is one */
+      if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) {
+         leading_zero = 1;
+      } else {
+         leading_zero = 0;
+      }
+
+      /* size for bignum */
+      z = len = leading_zero + mp_unsigned_bin_size(num);
+   } else {
+      /* it's negative */
+      /* find power of 2 that is a multiple of eight and greater than count bits */
+      leading_zero = 0;
+      z = mp_count_bits(num);
+      z = z + (8 - (z & 7));
+      len = z = z >> 3;
+   }
+
+   /* now we need a length */
+   if (z < 128) {
+      /* short form */
+      ++len;
+   } else {
+      /* long form (relies on z != 0), assumes length bytes < 128 */
+      ++len;
+
+      while (z) {
+         ++len;
+         z >>= 8;
+      }
+   }
+
+   /* we need a 0x02 to indicate it's INTEGER */
+   ++len;
+
+   /* return length */
+   *outlen = len; 
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,99 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_object_identifier.c
+  ASN.1 DER, Decode Object Identifier, Tom St Denis
+*/
+
+#ifdef LTC_DER
+/**
+  Decode OID data and store the array of integers in words
+  @param in      The OID DER encoded data
+  @param inlen   The length of the OID data
+  @param words   [out] The destination of the OID words
+  @param outlen  [in/out] The number of OID words
+  @return CRYPT_OK if successful
+*/
+int der_decode_object_identifier(const unsigned char *in,    unsigned long  inlen,
+                                       unsigned long *words, unsigned long *outlen)
+{
+   unsigned long x, y, t, len;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(words  != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* header is at least 3 bytes */
+   if (inlen < 3) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* must be room for at least two words */
+   if (*outlen < 2) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* decode the packet header */
+   x = 0;
+   if ((in[x++] & 0x1F) != 0x06) {
+      return CRYPT_INVALID_PACKET;
+   }
+   
+   /* get the length */
+   if (in[x] < 128) {
+      len = in[x++]; 
+   } else {
+       if (in[x] < 0x81 || in[x] > 0x82) {
+          return CRYPT_INVALID_PACKET;
+       }
+       y   = in[x++] & 0x7F;
+       len = 0;
+       while (y--) {
+          len = (len << 8) | (unsigned long)in[x++];
+       }
+   }
+
+   if (len < 1 || (len + x) > inlen) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* decode word1 and word2 */
+   --len;
+   t = in[x++];
+   words[0] = t/40;
+   words[1] = t%40;
+
+   /* decode rest */
+   y = 2;
+   t = 0;
+   while (len--) {
+       t = (t << 7) | (in[x] & 0x7F);
+       if (!(in[x++] & 0x80)) {
+           /* store t */
+           if (y >= *outlen) {
+              return CRYPT_BUFFER_OVERFLOW;
+           }
+           words[y++] = t;
+           t          = 0;
+       }
+   }
+       
+   *outlen = y;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,103 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_object_identifier.c
+  ASN.1 DER, Encode Object Identifier, Tom St Denis
+*/
+
+#ifdef LTC_DER
+/**
+  Encode an OID
+  @param words   The words to encode  (upto 32-bits each)
+  @param nwords  The number of words in the OID
+  @param out     [out] Destination of OID data
+  @param outlen  [in/out] The max and resulting size of the OID
+  @return CRYPT_OK if successful
+*/
+int der_encode_object_identifier(unsigned long *words, unsigned long  nwords,
+                                 unsigned char *out,   unsigned long *outlen)
+{
+   unsigned long i, x, y, z, t, mask;
+   int           err;
+
+   LTC_ARGCHK(words  != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* check length */
+   if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) {
+      return err;
+   }
+   if (x > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* compute length to store OID data */
+   z = 1;
+   for (y = 2; y < nwords; y++) {
+       t = der_object_identifier_bits(words[y]);
+       z += t/7 + ((t%7) ? 1 : 0);
+   }
+
+   /* store header + length */
+   x = 0; 
+   out[x++] = 0x06;
+   if (z < 128) {
+      out[x++] = z;
+   } else if (z < 256) {
+      out[x++] = 0x81;
+      out[x++] = z;
+   } else if (z < 65536UL) {
+      out[x++] = 0x82;
+      out[x++] = (z>>8)&255;
+      out[x++] = z&255;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* store first byte */
+   out[x++] = words[0] * 40 + words[1];   
+   
+    for (i = 2; i < nwords; i++) {
+        /* store 7 bit words in little endian */
+        t    = words[i] & 0xFFFFFFFF;
+        if (t) {
+           y    = x;
+           mask = 0;
+           while (t) {
+               out[x++] = (t & 0x7F) | mask;
+               t    >>= 7;
+               mask  |= 0x80;  /* upper bit is set on all but the last byte */
+           }
+           /* now swap bytes y...x-1 */
+           z = x - 1;
+           while (y < z) {
+               t = out[y]; out[y] = out[z]; out[z] = t;
+               ++y; 
+               --z;
+           }
+       } else {
+          /* zero word */
+          out[x++] = 0x00;
+       }
+   }
+
+   *outlen = x;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/object_identifier/der_length_object_identifier.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,84 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_object_identifier.c
+  ASN.1 DER, get length of Object Identifier, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+unsigned long der_object_identifier_bits(unsigned long x)
+{
+   unsigned long c;
+   x &= 0xFFFFFFFF;
+   c  = 0;
+   while (x) {
+     ++c;
+     x >>= 1;
+   }
+   return c;
+}
+
+
+/**
+  Gets length of DER encoding of Object Identifier
+  @param nwords   The number of OID words 
+  @param words    The actual OID words to get the size of
+  @param outlen   [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen)
+{
+   unsigned long y, z, t;   
+
+   LTC_ARGCHK(words  != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+
+   /* must be >= 2 words */
+   if (nwords < 2) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* word1 = 0,1,2 and word2 0..39 */
+   if (words[0] > 2 || words[1] > 39) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* leading byte of first two words */
+   z = 1;
+   for (y = 2; y < nwords; y++) {
+       t = der_object_identifier_bits(words[y]);
+       z += t/7 + ((t%7) ? 1 : 0);
+   }
+
+   /* now depending on the length our length encoding changes */
+   if (z < 128) {
+      z += 2;
+   } else if (z < 256) {
+      z += 3;
+   } else if (z < 65536UL) {
+      z += 4;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   *outlen = z;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/octet/der_decode_octet_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,90 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_octet_string.c
+  ASN.1 DER, encode a OCTET STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store a OCTET STRING
+  @param in      The DER encoded OCTET STRING
+  @param inlen   The size of the DER OCTET STRING
+  @param out     [out] The array of octets stored (one per char)
+  @param outlen  [in/out] The number of octets stored
+  @return CRYPT_OK if successful
+*/
+int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
+                                  unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* must have header at least */
+   if (inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* check for 0x04 */
+   if ((in[0] & 0x1F) != 0x04) {
+      return CRYPT_INVALID_PACKET;
+   }
+   x = 1;
+
+   /* decode the length */
+   if (in[x] & 0x80) {
+      /* valid # of bytes in length are 1,2,3 */
+      y = in[x] & 0x7F;
+      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* read the length in */
+      len = 0;
+      ++x;
+      while (y--) {
+         len = (len << 8) | in[x++];
+      }
+   } else {
+      len = in[x++] & 0x7F;
+   }
+
+   /* is it too long? */
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   if (len + x > inlen) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* read the data */
+   for (y = 0; y < len; y++) {
+       out[y] = in[x++];
+   }
+
+   *outlen = y;
+
+   return CRYPT_OK;
+}
+ 
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/octet/der_encode_octet_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,85 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_octet_string.c
+  ASN.1 DER, encode a OCTET STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store an OCTET STRING
+  @param in       The array of OCTETS to store (one per char)
+  @param inlen    The number of OCTETS to store
+  @param out      [out] The destination for the DER encoded OCTET STRING
+  @param outlen   [in/out] The max size and resulting size of the DER OCTET STRING
+  @return CRYPT_OK if successful
+*/
+int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
+                                  unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+   int           err;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* get the size */
+   if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) {
+      return err; 
+   }
+
+   /* too big? */
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* encode the header+len */
+   x = 0;
+   out[x++] = 0x04;
+   if (inlen < 128) {
+      out[x++] = inlen;
+   } else if (inlen < 256) {
+      out[x++] = 0x81;
+      out[x++] = inlen;
+   } else if (inlen < 65536UL) {
+      out[x++] = 0x82;
+      out[x++] = (inlen>>8)&255;
+      out[x++] = inlen&255;
+   } else if (inlen < 16777216UL) {
+      out[x++] = 0x83;
+      out[x++] = (inlen>>16)&255;
+      out[x++] = (inlen>>8)&255;
+      out[x++] = inlen&255;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* store octets */
+   for (y = 0; y < inlen; y++) {
+       out[x++] = in[y];
+   }
+
+   /* retun length */
+   *outlen = x;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/octet/der_length_octet_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,53 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_octet_string.c
+  ASN.1 DER, get length of OCTET STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+/**
+  Gets length of DER encoding of OCTET STRING 
+  @param noctets  The number of octets in the string to encode
+  @param outlen   [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
+{
+   LTC_ARGCHK(outlen != NULL);
+
+   if (noctets < 128) {
+      /* 04 LL DD DD DD ... */
+      *outlen = 2 + noctets;
+   } else if (noctets < 256) {
+      /* 04 81 LL DD DD DD ... */
+      *outlen = 3 + noctets;
+   } else if (noctets < 65536UL) {
+      /* 04 82 LL LL DD DD DD ... */
+      *outlen = 4 + noctets;
+   } else if (noctets < 16777216UL) {
+      /* 04 83 LL LL LL DD DD DD ... */
+      *outlen = 5 + noctets;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   return CRYPT_OK;
+}
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/16 15:08:11 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/printable_string/der_decode_printable_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,95 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_printable_string.c
+  ASN.1 DER, encode a printable STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store a printable STRING
+  @param in      The DER encoded printable STRING
+  @param inlen   The size of the DER printable STRING
+  @param out     [out] The array of octets stored (one per char)
+  @param outlen  [in/out] The number of octets stored
+  @return CRYPT_OK if successful
+*/
+int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+   int           t;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* must have header at least */
+   if (inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* check for 0x13 */
+   if ((in[0] & 0x1F) != 0x13) {
+      return CRYPT_INVALID_PACKET;
+   }
+   x = 1;
+
+   /* decode the length */
+   if (in[x] & 0x80) {
+      /* valid # of bytes in length are 1,2,3 */
+      y = in[x] & 0x7F;
+      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* read the length in */
+      len = 0;
+      ++x;
+      while (y--) {
+         len = (len << 8) | in[x++];
+      }
+   } else {
+      len = in[x++] & 0x7F;
+   }
+
+   /* is it too long? */
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   if (len + x > inlen) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* read the data */
+   for (y = 0; y < len; y++) {
+       t = der_printable_value_decode(in[x++]);
+       if (t == -1) {
+           return CRYPT_INVALID_ARG;
+       }
+       out[y] = t;
+   }
+
+   *outlen = y;
+
+   return CRYPT_OK;
+}
+ 
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/21 02:29:54 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/printable_string/der_encode_printable_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,84 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_printable_string.c
+  ASN.1 DER, encode a printable STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+  Store an printable STRING
+  @param in       The array of printable to store (one per char)
+  @param inlen    The number of printable to store
+  @param out      [out] The destination for the DER encoded printable STRING
+  @param outlen   [in/out] The max size and resulting size of the DER printable STRING
+  @return CRYPT_OK if successful
+*/
+int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
+                                unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+   int           err;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* get the size */
+   if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) {
+      return err; 
+   }
+
+   /* too big? */
+   if (len > *outlen) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* encode the header+len */
+   x = 0;
+   out[x++] = 0x13;
+   if (inlen < 128) {
+      out[x++] = inlen;
+   } else if (inlen < 256) {
+      out[x++] = 0x81;
+      out[x++] = inlen;
+   } else if (inlen < 65536UL) {
+      out[x++] = 0x82;
+      out[x++] = (inlen>>8)&255;
+      out[x++] = inlen&255;
+   } else if (inlen < 16777216UL) {
+      out[x++] = 0x83;
+      out[x++] = (inlen>>16)&255;
+      out[x++] = (inlen>>8)&255;
+      out[x++] = inlen&255;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* store octets */
+   for (y = 0; y < inlen; y++) {
+       out[x++] = der_printable_char_encode(in[y]);
+   }
+
+   /* retun length */
+   *outlen = x;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/21 02:29:54 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/printable_string/der_length_printable_string.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,166 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_printable_string.c
+  ASN.1 DER, get length of Printable STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+static const struct {
+   int code, value;
+} printable_table[] = {
+{ ' ', 32 }, 
+{ '\'', 39 }, 
+{ '(', 40 }, 
+{ ')', 41 }, 
+{ '+', 43 }, 
+{ ',', 44 }, 
+{ '-', 45 }, 
+{ '.', 46 }, 
+{ '/', 47 }, 
+{ '0', 48 }, 
+{ '1', 49 }, 
+{ '2', 50 }, 
+{ '3', 51 }, 
+{ '4', 52 }, 
+{ '5', 53 }, 
+{ '6', 54 }, 
+{ '7', 55 }, 
+{ '8', 56 }, 
+{ '9', 57 }, 
+{ ':', 58 }, 
+{ '=', 61 }, 
+{ '?', 63 }, 
+{ 'A', 65 }, 
+{ 'B', 66 }, 
+{ 'C', 67 }, 
+{ 'D', 68 }, 
+{ 'E', 69 }, 
+{ 'F', 70 }, 
+{ 'G', 71 }, 
+{ 'H', 72 }, 
+{ 'I', 73 }, 
+{ 'J', 74 }, 
+{ 'K', 75 }, 
+{ 'L', 76 }, 
+{ 'M', 77 }, 
+{ 'N', 78 }, 
+{ 'O', 79 }, 
+{ 'P', 80 }, 
+{ 'Q', 81 }, 
+{ 'R', 82 }, 
+{ 'S', 83 }, 
+{ 'T', 84 }, 
+{ 'U', 85 }, 
+{ 'V', 86 }, 
+{ 'W', 87 }, 
+{ 'X', 88 }, 
+{ 'Y', 89 }, 
+{ 'Z', 90 }, 
+{ 'a', 97 }, 
+{ 'b', 98 }, 
+{ 'c', 99 }, 
+{ 'd', 100 }, 
+{ 'e', 101 }, 
+{ 'f', 102 }, 
+{ 'g', 103 }, 
+{ 'h', 104 }, 
+{ 'i', 105 }, 
+{ 'j', 106 }, 
+{ 'k', 107 }, 
+{ 'l', 108 }, 
+{ 'm', 109 }, 
+{ 'n', 110 }, 
+{ 'o', 111 }, 
+{ 'p', 112 }, 
+{ 'q', 113 }, 
+{ 'r', 114 }, 
+{ 's', 115 }, 
+{ 't', 116 }, 
+{ 'u', 117 }, 
+{ 'v', 118 }, 
+{ 'w', 119 }, 
+{ 'x', 120 }, 
+{ 'y', 121 }, 
+{ 'z', 122 }, 
+};
+
+int der_printable_char_encode(int c)
+{
+   int x;
+   for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
+       if (printable_table[x].code == c) {
+          return printable_table[x].value;
+       }
+   }
+   return -1;
+}
+
+int der_printable_value_decode(int v)
+{
+   int x;
+   for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
+       if (printable_table[x].value == v) {
+          return printable_table[x].code;
+       }
+   }
+   return -1;
+}
+   
+/**
+  Gets length of DER encoding of Printable STRING 
+  @param octets   The values you want to encode 
+  @param noctets  The number of octets in the string to encode
+  @param outlen   [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
+{
+   unsigned long x;
+
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(octets != NULL);
+
+   /* scan string for validity */
+   for (x = 0; x < noctets; x++) {
+       if (der_printable_char_encode(octets[x]) == -1) {
+          return CRYPT_INVALID_ARG;
+       }
+   }
+
+   if (noctets < 128) {
+      /* 16 LL DD DD DD ... */
+      *outlen = 2 + noctets;
+   } else if (noctets < 256) {
+      /* 16 81 LL DD DD DD ... */
+      *outlen = 3 + noctets;
+   } else if (noctets < 65536UL) {
+      /* 16 82 LL LL DD DD DD ... */
+      *outlen = 4 + noctets;
+   } else if (noctets < 16777216UL) {
+      /* 16 83 LL LL LL DD DD DD ... */
+      *outlen = 5 + noctets;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   return CRYPT_OK;
+}
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */
+/* $Revision: 1.1 $ */
+/* $Date: 2005/05/21 02:29:54 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/sequence/der_decode_sequence.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,234 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+#include <stdarg.h>
+
+
+/**
+  @file der_decode_sequence.c
+  ASN.1 DER, decode a SEQUENCE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+   Decode a SEQUENCE
+   @param in       The DER encoded input
+   @param inlen    The size of the input
+   @param list     The list of items to decode
+   @param outlen   The number of items in the list
+   @return CRYPT_OK on success
+*/
+int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
+                              ltc_asn1_list *list, unsigned long  outlen)
+{
+   int           err, type;
+   unsigned long size, x, y, z, i, blksize;
+   void          *data;
+
+   LTC_ARGCHK(in   != NULL);
+   LTC_ARGCHK(list != NULL);
+
+   /* get blk size */
+   if (inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* sequence type? */
+   x = 0;
+   if (in[x++] != 0x30) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   if (in[x] < 128) {
+      blksize = in[x++];
+   } else if (in[x] & 0x80) {
+      if (in[x] < 0x81 || in[x] > 0x83) {
+         return CRYPT_INVALID_PACKET;
+      }
+      y = in[x++] & 0x7F;
+
+      /* would reading the len bytes overrun? */
+      if (x + y > inlen) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* read len */
+      blksize = 0;
+      while (y--) {
+          blksize = (blksize << 8) | (unsigned long)in[x++];
+      }
+  }
+
+  /* would this blksize overflow? */
+  if (x + blksize > inlen) {
+     return CRYPT_INVALID_PACKET;
+  }
+
+  /* ok read data */
+   inlen = blksize;
+   for (i = 0; i < outlen; i++) {
+       type = list[i].type;
+       size = list[i].size;
+       data = list[i].data;
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+               z = inlen;
+               if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+
+           case LTC_ASN1_SHORT_INTEGER:
+               z = inlen;
+               if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               if ((err = der_length_short_integer(size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           case LTC_ASN1_BIT_STRING:
+               z = inlen;
+               if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               list[i].size = size;
+               if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           case LTC_ASN1_OCTET_STRING:
+               z = inlen;
+               if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               list[i].size = size;
+               if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           case LTC_ASN1_NULL:
+               if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
+                  err = CRYPT_INVALID_PACKET;
+                  goto LBL_ERR;
+               }
+               x     += 2;
+               inlen -= 2;
+               break;
+                  
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+               z = inlen;
+               if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               list[i].size = size;
+               if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           case LTC_ASN1_IA5_STRING:
+               z = inlen;
+               if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               list[i].size = size;
+               if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+
+           case LTC_ASN1_PRINTABLE_STRING:
+               z = inlen;
+               if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               list[i].size = size;
+               if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           case LTC_ASN1_UTCTIME:
+               z = inlen;
+               if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           case LTC_ASN1_SEQUENCE:
+               z = inlen;
+               if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+
+           case LTC_ASN1_CHOICE:
+               z = inlen;
+               if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x     += z;
+               inlen -= z;
+               break;
+
+           default:
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+   err = CRYPT_OK;   
+
+LBL_ERR:
+   return err;
+}  
+ 
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/06/18 19:20:23 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/sequence/der_decode_sequence_multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,124 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+#include <stdarg.h>
+
+
+/**
+  @file der_decode_sequence_multi.c
+  ASN.1 DER, decode a SEQUENCE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
+{
+   int           err, type;
+   unsigned long size, x;
+   void          *data;
+   va_list       args;
+   ltc_asn1_list *list;
+
+   LTC_ARGCHK(in    != NULL);
+
+   /* get size of output that will be required */
+   va_start(args, inlen);
+   x = 0;
+   for (;;) {
+       type = va_arg(args, int);
+       size = va_arg(args, unsigned long);
+       data = va_arg(args, void*);
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+           case LTC_ASN1_SHORT_INTEGER:
+           case LTC_ASN1_BIT_STRING:
+           case LTC_ASN1_OCTET_STRING:
+           case LTC_ASN1_NULL:
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+           case LTC_ASN1_IA5_STRING:
+           case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTCTIME:
+           case LTC_ASN1_SEQUENCE:
+           case LTC_ASN1_CHOICE:
+                ++x; 
+                break;
+          
+           default:
+               va_end(args);
+               return CRYPT_INVALID_ARG;
+       }
+   }
+   va_end(args);
+
+   /* allocate structure for x elements */
+   if (x == 0) {
+      return CRYPT_NOP;
+   }
+
+   list = XCALLOC(sizeof(*list), x);
+   if (list == NULL) {
+      return CRYPT_MEM;
+   }
+
+   /* fill in the structure */
+   va_start(args, inlen);
+   x = 0;
+   for (;;) {
+       type = va_arg(args, int);
+       size = va_arg(args, unsigned long);
+       data = va_arg(args, void*);
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+           case LTC_ASN1_SHORT_INTEGER:
+           case LTC_ASN1_BIT_STRING:
+           case LTC_ASN1_OCTET_STRING:
+           case LTC_ASN1_NULL:
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+           case LTC_ASN1_IA5_STRING:
+           case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTCTIME:
+           case LTC_ASN1_SEQUENCE:
+           case LTC_ASN1_CHOICE:
+                list[x].type   = type;
+                list[x].size   = size;
+                list[x++].data = data;
+                break;
+         
+           default:
+               va_end(args);
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+   va_end(args);
+
+   err = der_decode_sequence(in, inlen, list, x);
+LBL_ERR:
+   XFREE(list);
+   return err;
+}
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/06/18 19:20:23 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/sequence/der_encode_sequence.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,281 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+#include <stdarg.h>
+
+
+/**
+  @file der_encode_sequence.c
+  ASN.1 DER, encode a SEQUENCE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+   Encode a SEQUENCE
+   @param list      The list of items to encode
+   @param inlen     The number of items in the list
+   @param out       [out] The destination 
+   @param outlen    [in/out] The size of the output
+   @return CRYPT_OK on success
+*/
+int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned char *out,  unsigned long *outlen) 
+{
+   int           err, type;
+   unsigned long size, x, y, z, i;
+   void          *data;
+
+   LTC_ARGCHK(list    != NULL);
+   LTC_ARGCHK(out     != NULL);
+   LTC_ARGCHK(outlen  != NULL);
+
+   /* get size of output that will be required */
+   y = 0;
+   for (i = 0; i < inlen; i++) {
+       type = list[i].type;
+       size = list[i].size;
+       data = list[i].data;
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+               if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_SHORT_INTEGER:
+               if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_BIT_STRING:
+               if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_OCTET_STRING:
+               if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_NULL:
+               y += 2;
+               break;
+
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+               if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_IA5_STRING:
+               if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_PRINTABLE_STRING:
+               if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_UTCTIME:
+               if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_SEQUENCE:
+               if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+          
+           default:
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+
+   /* calc header size */
+   z = y;
+   if (y < 128) {
+      y += 2;
+   } else if (y < 256) {
+      /* 0x30 0x81 LL */
+      y += 3;
+   } else if (y < 65536UL) {
+      /* 0x30 0x82 LL LL */
+      y += 4;
+   } else if (y < 16777216UL) {
+      /* 0x30 0x83 LL LL LL */
+      y += 5;
+   } else {
+      err = CRYPT_INVALID_ARG;
+      goto LBL_ERR;
+   }
+
+   /* too big ? */
+   if (*outlen < y) {
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto LBL_ERR;
+   }
+
+   /* store header */
+   x = 0;
+   out[x++] = 0x30;
+   if (z < 128) {
+      out[x++] = z;
+   } else if (z < 256) {
+      out[x++] = 0x81;
+      out[x++] = z;
+   } else if (z < 65536UL) {
+      out[x++] = 0x82;
+      out[x++] = (z>>8UL)&255;
+      out[x++] = z&255;
+   } else if (z < 16777216UL) {
+      out[x++] = 0x83;
+      out[x++] = (z>>16UL)&255;
+      out[x++] = (z>>8UL)&255;
+      out[x++] = z&255;
+   }
+
+   /* store data */
+   *outlen -= x;
+   for (i = 0; i < inlen; i++) {
+       type = list[i].type;
+       size = list[i].size;
+       data = list[i].data;
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+               z = *outlen;
+               if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_SHORT_INTEGER:
+               z = *outlen;
+               if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_BIT_STRING:
+               z = *outlen;
+               if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_OCTET_STRING:
+               z = *outlen;
+               if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_NULL:
+               out[x++] = 0x05;
+               out[x++] = 0x00;
+               *outlen -= 2;
+               break;
+
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+               z = *outlen;
+               if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_IA5_STRING:
+               z = *outlen;
+               if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+          
+           case LTC_ASN1_PRINTABLE_STRING:
+               z = *outlen;
+               if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_UTCTIME:
+               z = *outlen;
+               if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_SEQUENCE:
+               z = *outlen;
+               if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           default:
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+   *outlen = x;
+   err = CRYPT_OK;   
+
+LBL_ERR:
+   return err;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/sequence/der_encode_sequence_multi.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,123 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+#include <stdarg.h>
+
+
+/**
+  @file der_encode_sequence_multi.c
+  ASN.1 DER, encode a SEQUENCE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
+{
+   int           err, type;
+   unsigned long size, x;
+   void          *data;
+   va_list       args;
+   ltc_asn1_list *list;
+
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* get size of output that will be required */
+   va_start(args, outlen);
+   x = 0;
+   for (;;) {
+       type = va_arg(args, int);
+       size = va_arg(args, unsigned long);
+       data = va_arg(args, void*);
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+           case LTC_ASN1_SHORT_INTEGER:
+           case LTC_ASN1_BIT_STRING:
+           case LTC_ASN1_OCTET_STRING:
+           case LTC_ASN1_NULL:
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+           case LTC_ASN1_IA5_STRING:
+           case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTCTIME:
+           case LTC_ASN1_SEQUENCE:
+                ++x; 
+                break;
+          
+           default:
+               va_end(args);
+               return CRYPT_INVALID_ARG;
+       }
+   }
+   va_end(args);
+
+   /* allocate structure for x elements */
+   if (x == 0) {
+      return CRYPT_NOP;
+   }
+
+   list = XCALLOC(sizeof(*list), x);
+   if (list == NULL) {
+      return CRYPT_MEM;
+   }
+
+   /* fill in the structure */
+   va_start(args, outlen);
+   x = 0;
+   for (;;) {
+       type = va_arg(args, int);
+       size = va_arg(args, unsigned long);
+       data = va_arg(args, void*);
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+           case LTC_ASN1_SHORT_INTEGER:
+           case LTC_ASN1_BIT_STRING:
+           case LTC_ASN1_OCTET_STRING:
+           case LTC_ASN1_NULL:
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+           case LTC_ASN1_IA5_STRING:
+           case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTCTIME:
+           case LTC_ASN1_SEQUENCE:
+                list[x].type   = type;
+                list[x].size   = size;
+                list[x++].data = data;
+                break;
+         
+           default:
+               va_end(args);
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+   va_end(args);
+
+   err = der_encode_sequence(list, x, out, outlen);   
+LBL_ERR:
+   XFREE(list);
+   return err;
+}
+
+#endif
+
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/06/18 19:20:23 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/sequence/der_length_sequence.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,144 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+#include <stdarg.h>
+
+
+/**
+  @file der_length_sequence.c
+  ASN.1 DER, length a SEQUENCE, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+   Get the length of a DER sequence 
+   @param list   The sequences of items in the SEQUENCE
+   @param inlen  The number of items
+   @param outlen [out] The length required in octets to store it 
+   @return CRYPT_OK on success
+*/
+int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
+                        unsigned long *outlen) 
+{
+   int           err, type;
+   unsigned long size, x, y, z, i;
+   void          *data;
+
+   LTC_ARGCHK(list    != NULL);
+   LTC_ARGCHK(outlen  != NULL);
+
+   /* get size of output that will be required */
+   y = 0;
+   for (i = 0; i < inlen; i++) {
+       type = list[i].type;
+       size = list[i].size;
+       data = list[i].data;
+
+       if (type == LTC_ASN1_EOL) { 
+          break;
+       }
+
+       switch (type) {
+           case LTC_ASN1_INTEGER:
+               if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_SHORT_INTEGER:
+               if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_BIT_STRING:
+               if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_OCTET_STRING:
+               if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_NULL:
+               y += 2;
+               break;
+
+           case LTC_ASN1_OBJECT_IDENTIFIER:
+               if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_IA5_STRING:
+               if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_PRINTABLE_STRING:
+               if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+           case LTC_ASN1_SEQUENCE:
+               if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
+          
+           default:
+               err = CRYPT_INVALID_ARG;
+               goto LBL_ERR;
+       }
+   }
+
+   /* calc header size */
+   z = y;
+   if (y < 128) {
+      y += 2;
+   } else if (y < 256) {
+      /* 0x30 0x81 LL */
+      y += 3;
+   } else if (y < 65536UL) {
+      /* 0x30 0x82 LL LL */
+      y += 4;
+   } else if (y < 16777216UL) {
+      /* 0x30 0x83 LL LL LL */
+      y += 5;
+   } else {
+      err = CRYPT_INVALID_ARG;
+      goto LBL_ERR;
+   }
+
+   /* store size */
+   *outlen = y;
+   err     = CRYPT_OK;
+
+LBL_ERR:
+   return err;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/short_integer/der_decode_short_integer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,68 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_short_integer.c
+  ASN.1 DER, decode an integer, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Read a mp_int integer
+  @param in       The DER encoded data
+  @param inlen    Size of data
+  @param num      [out] The integer to decode
+  @return CRYPT_OK if successful
+*/
+int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num)
+{
+   unsigned long len, x, y;
+
+   LTC_ARGCHK(num    != NULL);
+   LTC_ARGCHK(in     != NULL);
+
+   /* check length */
+   if (inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* check header */
+   x = 0;
+   if ((in[x++] & 0x1F) != 0x02) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* get the packet len */
+   len = in[x++];
+
+   if (x + len > inlen) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* read number */
+   y = 0;
+   while (len--) {
+      y = (y<<8) | (unsigned long)in[x++];
+   }
+   *num = y;
+
+   return CRYPT_OK;
+
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/23 01:04:13 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/short_integer/der_encode_short_integer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,97 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_short_integer.c
+  ASN.1 DER, encode an integer, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/* Exports a positive integer as DER format (upto 32-bits in size) */
+/**
+  Store a mp_int integer
+  @param num      The integer to encode
+  @param out      [out] The destination for the DER encoded integers
+  @param outlen   [in/out] The max size and resulting size of the DER encoded integers
+  @return CRYPT_OK if successful
+*/
+int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen)
+{  
+   unsigned long len, x, y, z;
+   int           err;
+   
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* force to 32 bits */
+   num &= 0xFFFFFFFFUL;
+
+   /* find out how big this will be */
+   if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) {
+      return err;
+   }
+
+   if (*outlen < len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* get len of output */
+   z = 0;
+   y = num;
+   while (y) {
+     ++z;
+     y >>= 8;
+   }
+
+   /* handle zero */
+   if (z == 0) {
+      z = 1;
+   }
+
+   /* see if msb is set */
+   z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
+
+   /* adjust the number so the msB is non-zero */
+   for (x = 0; (z <= 4) && (x < (4 - z)); x++) {
+      num <<= 8;
+   }
+
+   /* store header */
+   x = 0;
+   out[x++] = 0x02;
+   out[x++] = z;
+
+   /* if 31st bit is set output a leading zero and decrement count */
+   if (z == 5) {
+      out[x++] = 0;
+      --z;
+   }
+
+   /* store values */
+   for (y = 0; y < z; y++) {
+      out[x++] = (num >> 24) & 0xFF;
+      num    <<= 8;
+   }
+
+   /* we good */
+   *outlen = x;
+ 
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/23 01:27:03 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/short_integer/der_length_short_integer.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,69 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_short_integer.c
+  ASN.1 DER, get length of encoding, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+/**
+  Gets length of DER encoding of num 
+  @param num    The integer to get the size of 
+  @param outlen [out] The length of the DER encoding for the given integer
+  @return CRYPT_OK if successful
+*/
+int der_length_short_integer(unsigned long num, unsigned long *outlen)
+{
+   unsigned long z, y, len;
+
+   LTC_ARGCHK(outlen  != NULL);
+
+   /* force to 32 bits */
+   num &= 0xFFFFFFFFUL;
+
+   /* get the number of bytes */
+   z = 0;
+   y = num;
+   while (y) {
+     ++z;
+     y >>= 8;
+   }
+
+   /* handle zero */
+   if (z == 0) {
+      z = 1;
+   }
+
+   /* we need a 0x02 to indicate it's INTEGER */
+   len = 1;
+
+   /* length byte */
+   ++len;
+
+   /* bytes in value */
+   len += z;
+
+   /* see if msb is set */
+   len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
+
+   /* return length */
+   *outlen = len; 
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/23 01:35:38 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/utctime/der_decode_utctime.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,120 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_utctime.c
+  ASN.1 DER, decode a  UTCTIME, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+static int char_to_int(unsigned char x)
+{
+   switch (x)  {
+      case '0': return 0;
+      case '1': return 1;
+      case '2': return 2;
+      case '3': return 3;
+      case '4': return 4;
+      case '5': return 5;
+      case '6': return 6;
+      case '7': return 7;
+      case '8': return 8;
+      case '9': return 9;
+   }
+   return 100;
+}
+
+#define DECODE_V(y, max) \
+   y  = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
+   if (y >= max) return CRYPT_INVALID_PACKET;           \
+   x += 2;
+
+int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
+                             ltc_utctime   *out)
+{
+   unsigned char buf[32];
+   unsigned long x;
+   int           y;
+
+   LTC_ARGCHK(in    != NULL);
+   LTC_ARGCHK(inlen != NULL);
+   LTC_ARGCHK(out   != NULL);
+
+   /* check header */
+   if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* decode the string */
+   for (x = 0; x < in[1]; x++) {
+       y = der_ia5_value_decode(in[x+2]);
+       if (y == -1) {
+          return CRYPT_INVALID_PACKET;
+       }
+       buf[x] = y;
+   }
+   *inlen = 2 + x;
+
+
+   /* possible encodings are 
+YYMMDDhhmmZ
+YYMMDDhhmm+hh'mm'
+YYMMDDhhmm-hh'mm'
+YYMMDDhhmmssZ
+YYMMDDhhmmss+hh'mm'
+YYMMDDhhmmss-hh'mm'
+
+    So let's do a trivial decode upto [including] mm 
+   */
+
+    x = 0;
+    DECODE_V(out->YY, 100);
+    DECODE_V(out->MM, 13);
+    DECODE_V(out->DD, 32);
+    DECODE_V(out->hh, 24);
+    DECODE_V(out->mm, 60);
+
+    /* clear timezone and seconds info */
+    out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
+
+    /* now is it Z, +, - or 0-9 */
+    if (buf[x] == 'Z') {
+       return CRYPT_OK;
+    } else if (buf[x] == '+' || buf[x] == '-') {
+       out->off_dir = (buf[x++] == '+') ? 0 : 1;
+       DECODE_V(out->off_hh, 24);
+       DECODE_V(out->off_mm, 60);
+       return CRYPT_OK;
+    }
+
+    /* decode seconds */
+    DECODE_V(out->ss, 60);
+
+    /* now is it Z, +, - */
+    if (buf[x] == 'Z') {
+       return CRYPT_OK;
+    } else if (buf[x] == '+' || buf[x] == '-') {
+       out->off_dir = (buf[x++] == '+') ? 0 : 1;
+       DECODE_V(out->off_hh, 24);
+       DECODE_V(out->off_mm, 60);
+       return CRYPT_OK;
+    } else {
+       return CRYPT_INVALID_PACKET;
+    }
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/06/19 12:07:00 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/utctime/der_encode_utctime.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,80 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_utctime.c
+  ASN.1 DER, encode a  UTCTIME, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+static const char *baseten = "0123456789";
+
+#define STORE_V(y) \
+    out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
+    out[x++] = der_ia5_char_encode(baseten[y % 10]);
+
+/**
+  Gets length of DER encoding of UTCTIME
+  @param outlen [out] The length of the DER encoding
+  @return CRYPT_OK if successful
+*/
+int der_encode_utctime(ltc_utctime *utctime, 
+                       unsigned char *out,   unsigned long *outlen)
+{
+    unsigned long x, tmplen;
+    int           err;
+ 
+    LTC_ARGCHK(utctime != NULL);
+    LTC_ARGCHK(out     != NULL);
+    LTC_ARGCHK(outlen  != NULL);
+
+    if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) {
+       return err;
+    }
+    if (tmplen > *outlen) {
+        return CRYPT_BUFFER_OVERFLOW;
+    }
+    
+    /* store header */
+    out[0] = 0x17;
+
+    /* store values */
+    x = 2;
+    STORE_V(utctime->YY);
+    STORE_V(utctime->MM);
+    STORE_V(utctime->DD);
+    STORE_V(utctime->hh);
+    STORE_V(utctime->mm);
+    STORE_V(utctime->ss);
+
+    if (utctime->off_mm || utctime->off_hh) {
+       out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+');
+       STORE_V(utctime->off_hh);
+       STORE_V(utctime->off_mm);
+    } else {
+       out[x++] = der_ia5_char_encode('Z');
+    }
+
+    /* store length */
+    out[1] = x - 2;
+   
+    /* all good let's return */
+    *outlen = x;
+    return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/06/19 12:07:00 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pk/asn1/der/utctime/der_length_utctime.c	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,45 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_utctime.c
+  ASN.1 DER, get length of UTCTIME, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+  Gets length of DER encoding of UTCTIME
+  @param outlen [out] The length of the DER encoding
+  @return CRYPT_OK if successful
+*/
+int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen)
+{
+   LTC_ARGCHK(outlen  != NULL);
+   LTC_ARGCHK(utctime != NULL);
+
+   if (utctime->off_hh == 0 && utctime->off_mm == 0) {
+      /* we encode as YYMMDDhhmmssZ */
+      *outlen = 2 + 13;
+   } else {
+      /* we encode as YYMMDDhhmmss{+|-}hh'mm' */
+      *outlen = 2 + 17;
+   }
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/06/19 11:23:04 $ */
--- a/src/pk/dh/dh.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dh/dh.c	Wed Jul 06 12:10:23 2005 +0000
@@ -518,3 +518,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dh/dh.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/dh/dh_sys.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dh/dh_sys.c	Wed Jul 06 12:10:23 2005 +0000
@@ -493,3 +493,7 @@
    return err;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dh/dh_sys.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/dsa/dsa_export.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_export.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,18 +27,13 @@
 */
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key)
 {
-   unsigned long y, z;
-   int err;
+   unsigned char flags[1];
 
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(key    != NULL);
 
    /* can we store the static header?  */
-   if (*outlen < (PACKET_SIZE + 1 + 2)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-   
    if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
       return CRYPT_PK_TYPE_MISMATCH;
    }
@@ -47,29 +42,31 @@
       return CRYPT_INVALID_ARG;
    }
 
-   /* store header */
-   packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY);
-   y = PACKET_SIZE;
-
-   /* store g, p, q, qord */
-   out[y++] = type;
-   out[y++] = (key->qord>>8)&255;
-   out[y++] = key->qord & 255;
+   flags[0] = (type != PK_PUBLIC) ? 1 : 0;
 
-   OUTPUT_BIGNUM(&key->g,out,y,z);
-   OUTPUT_BIGNUM(&key->p,out,y,z);
-   OUTPUT_BIGNUM(&key->q,out,y,z);
-
-   /* public exponent */
-   OUTPUT_BIGNUM(&key->y,out,y,z);
-   
    if (type == PK_PRIVATE) {
-      OUTPUT_BIGNUM(&key->x,out,y,z);
+      return der_encode_sequence_multi(out, outlen,
+                                 LTC_ASN1_BIT_STRING,   1UL, flags,
+                                 LTC_ASN1_INTEGER,      1UL, &key->g,
+                                 LTC_ASN1_INTEGER,      1UL, &key->p,
+                                 LTC_ASN1_INTEGER,      1UL, &key->q,
+                                 LTC_ASN1_INTEGER,      1UL, &key->y,
+                                 LTC_ASN1_INTEGER,      1UL, &key->x,
+                                 LTC_ASN1_EOL,          0UL, NULL);
+   } else {
+      return der_encode_sequence_multi(out, outlen,
+                                 LTC_ASN1_BIT_STRING,   1UL, flags,
+                                 LTC_ASN1_INTEGER,      1UL, &key->g,
+                                 LTC_ASN1_INTEGER,      1UL, &key->p,
+                                 LTC_ASN1_INTEGER,      1UL, &key->q,
+                                 LTC_ASN1_INTEGER,      1UL, &key->y,
+                                 LTC_ASN1_EOL,          0UL, NULL);
    }
-
-   *outlen = y;
-   return CRYPT_OK;
 }
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_export.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/06/03 19:24:31 $ */
--- a/src/pk/dsa/dsa_free.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_free.c	Wed Jul 06 12:10:23 2005 +0000
@@ -28,3 +28,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_free.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/dsa/dsa_import.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_import.c	Wed Jul 06 12:10:23 2005 +0000
@@ -26,46 +26,64 @@
 */
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
 {
-   unsigned long x, y;
+   unsigned char flags[1];
    int           err;
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
 
-   /* check length */
-   if ((1+2+PACKET_SIZE) > inlen) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* check type */
-   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DSA, PACKET_SUB_KEY)) != CRYPT_OK) {
-      return err;
-   }
-   y = PACKET_SIZE;
-
    /* init key */
    if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != MP_OKAY) {
       return CRYPT_MEM;
    }
 
-   /* read type/qord */
-   key->type = in[y++];
-   key->qord = ((unsigned)in[y]<<8)|((unsigned)in[y+1]);
-   y += 2;
-
-   /* input publics */
-   INPUT_BIGNUM(&key->g,in,x,y, inlen);
-   INPUT_BIGNUM(&key->p,in,x,y, inlen);
-   INPUT_BIGNUM(&key->q,in,x,y, inlen);
-   INPUT_BIGNUM(&key->y,in,x,y, inlen);
-   if (key->type == PK_PRIVATE) {
-      INPUT_BIGNUM(&key->x,in,x,y, inlen);
+   /* get key type */
+   if ((err = der_decode_sequence_multi(in, inlen,
+                                  LTC_ASN1_BIT_STRING, 1UL, flags,
+                                  LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
+      goto error;
    }
 
-   return CRYPT_OK;
+   if (flags[0] == 1) {
+      if ((err = der_decode_sequence_multi(in, inlen,
+                                 LTC_ASN1_BIT_STRING,   1UL, flags,
+                                 LTC_ASN1_INTEGER,      1UL, &key->g,
+                                 LTC_ASN1_INTEGER,      1UL, &key->p,
+                                 LTC_ASN1_INTEGER,      1UL, &key->q,
+                                 LTC_ASN1_INTEGER,      1UL, &key->y,
+                                 LTC_ASN1_INTEGER,      1UL, &key->x,
+                                 LTC_ASN1_EOL,          0UL, NULL)) != CRYPT_OK) {
+         goto error;
+      }
+      key->type = PK_PRIVATE;
+   } else {
+      if ((err = der_decode_sequence_multi(in, inlen,
+                                 LTC_ASN1_BIT_STRING,   1UL, flags,
+                                 LTC_ASN1_INTEGER,      1UL, &key->g,
+                                 LTC_ASN1_INTEGER,      1UL, &key->p,
+                                 LTC_ASN1_INTEGER,      1UL, &key->q,
+                                 LTC_ASN1_INTEGER,      1UL, &key->y,
+                                 LTC_ASN1_EOL,          0UL, NULL)) != CRYPT_OK) {
+         goto error;
+      }
+      key->type = PK_PUBLIC;
+  }
+  key->qord = mp_unsigned_bin_size(&key->q);
+
+  if (key->qord >= MDSA_MAX_GROUP || key->qord <= 15 ||
+      key->qord >= mp_unsigned_bin_size(&key->p) || (mp_unsigned_bin_size(&key->p) - key->qord) >= MDSA_DELTA) {
+      err = CRYPT_INVALID_PACKET;
+      goto error;
+   }
+
+  return CRYPT_OK;
 error: 
    mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
    return err;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_import.c,v $ */
+/* $Revision: 1.7 $ */
+/* $Date: 2005/06/08 23:31:17 $ */
--- a/src/pk/dsa/dsa_make_key.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_make_key.c	Wed Jul 06 12:10:23 2005 +0000
@@ -70,15 +70,15 @@
    }
 
    /* force magnitude */
-   buf[0] = 1;
+   buf[0] |= 0xC0;
 
    /* force even */
-   buf[modulus_size - group_size] &= ~1;
+   buf[modulus_size - group_size - 1] &= ~1;
 
-   if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size+1)) != MP_OKAY) { goto error; }
+   if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size)) != MP_OKAY) { goto error; }
    if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY)                             { goto error; }
    if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY)                               { goto error; }
-   
+
    /* now loop until p is prime */
    for (;;) {
        if ((err = is_prime(&key->p, &res)) != CRYPT_OK)                                { goto LBL_ERR; }
@@ -140,3 +140,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/11 05:45:35 $ */
--- a/src/pk/dsa/dsa_sign_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_sign_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -21,26 +21,25 @@
   Sign a hash with DSA
   @param in       The hash to sign
   @param inlen    The length of the hash to sign
-  @param out      [out] Where to store the signature
-  @param outlen   [in/out] The max size and resulting size of the signature
+  @param r        The "r" integer of the signature (caller must initialize with mp_init() first)
+  @param s        The "s" integer of the signature (caller must initialize with mp_init() first)
   @param prng     An active PRNG state
   @param wprng    The index of the PRNG desired
   @param key      A private DSA key
   @return CRYPT_OK if successful
 */
-int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
-                        unsigned char *out, unsigned long *outlen,
-                        prng_state *prng, int wprng, dsa_key *key)
+int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
+                                   mp_int *r,   mp_int *s,
+                               prng_state *prng, int wprng, dsa_key *key)
 {
-   mp_int         k, kinv, tmp, r, s;
+   mp_int         k, kinv, tmp;
    unsigned char *buf;
    int            err;
-   unsigned long  out1, out2;
 
-   LTC_ARGCHK(in     != NULL);
-   LTC_ARGCHK(out    != NULL);
-   LTC_ARGCHK(outlen != NULL);
-   LTC_ARGCHK(key    != NULL);
+   LTC_ARGCHK(in  != NULL);
+   LTC_ARGCHK(r   != NULL);
+   LTC_ARGCHK(s   != NULL);
+   LTC_ARGCHK(key != NULL);
 
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
@@ -60,7 +59,7 @@
    }
 
    /* Init our temps */
-   if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY)               { goto error; }
+   if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != MP_OKAY)               { goto error; }
 
 retry:
 
@@ -85,37 +84,26 @@
    if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY)                              { goto error; }
 
    /* now find r = g^k mod p mod q */
-   if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY)                       { goto error; }
-   if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY)                                    { goto error; }
+   if ((err = mp_exptmod(&key->g, &k, &key->p, r)) != MP_OKAY)                        { goto error; }
+   if ((err = mp_mod(r, &key->q, r)) != MP_OKAY)                                      { goto error; }
 
-   if (mp_iszero(&r) == MP_YES)                                                       { goto retry; }
+   if (mp_iszero(r) == MP_YES)                                                        { goto retry; }
 
    /* now find s = (in + xr)/k mod q */
    if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY)     { goto error; }
-   if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY)                                    { goto error; }
-   if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY)                                       { goto error; }
-   if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY)                          { goto error; }
-
-   if (mp_iszero(&s) == MP_YES)                                                       { goto retry; }
+   if ((err = mp_mul(&key->x, r, s)) != MP_OKAY)                                      { goto error; }
+   if ((err = mp_add(s, &tmp, s)) != MP_OKAY)                                         { goto error; }
+   if ((err = mp_mulmod(s, &kinv, &key->q, s)) != MP_OKAY)                            { goto error; }
 
-   /* now store em both */
-   
-   /* first check that we have enough room */
-   if ((err = der_length_integer(&s, &out1)) != CRYPT_OK)                             { goto LBL_ERR; }
-   if ((err = der_length_integer(&r, &out2)) != CRYPT_OK)                             { goto LBL_ERR; }
-   if (*outlen < (out1+out2)) {
-      err = CRYPT_BUFFER_OVERFLOW;
-      goto LBL_ERR;
-   }
+   if (mp_iszero(s) == MP_YES)                                                        { goto retry; }
 
-   /* store ints */
-   err = der_put_multi_integer(out, outlen, &r, &s, NULL);
+   err = CRYPT_OK;
    goto LBL_ERR;
 
 error: 
    err = mpi_to_ltc_error(err);
 LBL_ERR: 
-   mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL);
+   mp_clear_multi(&k, &kinv, &tmp, NULL);
 #ifdef LTC_CLEAN_STACK
    zeromem(buf, MDSA_MAX_GROUP);
 #endif
@@ -123,4 +111,49 @@
    return err;
 }
 
+/**
+  Sign a hash with DSA
+  @param in       The hash to sign
+  @param inlen    The length of the hash to sign
+  @param out      [out] Where to store the signature
+  @param outlen   [in/out] The max size and resulting size of the signature
+  @param prng     An active PRNG state
+  @param wprng    The index of the PRNG desired
+  @param key      A private DSA key
+  @return CRYPT_OK if successful
+*/
+int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
+                        unsigned char *out, unsigned long *outlen,
+                        prng_state *prng, int wprng, dsa_key *key)
+{
+   mp_int        r, s;
+   int           err;
+
+   LTC_ARGCHK(in      != NULL);
+   LTC_ARGCHK(out     != NULL);
+   LTC_ARGCHK(outlen  != NULL);
+   LTC_ARGCHK(key     != NULL);
+
+   if (mp_init_multi(&r, &s, NULL) != MP_OKAY) {
+      return CRYPT_MEM;
+   }
+
+   if ((err = dsa_sign_hash_raw(in, inlen, &r, &s, prng, wprng, key)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   err = der_encode_sequence_multi(out, outlen, 
+                             LTC_ASN1_INTEGER, 1UL, &r, 
+                             LTC_ASN1_INTEGER, 1UL, &s, 
+                             LTC_ASN1_EOL,     0UL, NULL);
+
+LBL_ERR:
+   mp_clear_multi(&r, &s, NULL);
+   return err;
+}
+
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_sign_hash.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/15 21:48:59 $ */
--- a/src/pk/dsa/dsa_verify_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_verify_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -20,6 +20,71 @@
 
 /**
   Verify a DSA signature
+  @param r        DSA "r" parameter
+  @param s        DSA "s" parameter
+  @param hash     The hash that was signed
+  @param hashlen  The length of the hash that was signed
+  @param stat     [out] The result of the signature verification, 1==valid, 0==invalid
+  @param key      The corresponding public DH key
+  @return CRYPT_OK if successful (even if the signature is invalid)
+*/
+int dsa_verify_hash_raw(         mp_int *r,          mp_int *s,
+                    const unsigned char *hash, unsigned long hashlen, 
+                                    int *stat,      dsa_key *key)
+{
+   mp_int        w, v, u1, u2;
+   int           err;
+
+   LTC_ARGCHK(r    != NULL);
+   LTC_ARGCHK(s    != NULL);
+   LTC_ARGCHK(stat != NULL);
+   LTC_ARGCHK(key  != NULL);
+
+   /* default to invalid signature */
+   *stat = 0;
+
+   /* init our variables */
+   if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
+   }
+
+   /* neither r or s can be null or >q*/
+   if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES || mp_cmp(r, &key->q) != MP_LT || mp_cmp(s, &key->q) != MP_LT) {
+      err = CRYPT_INVALID_PACKET;
+      goto done;
+   }
+   
+   /* w = 1/s mod q */
+   if ((err = mp_invmod(s, &key->q, &w)) != MP_OKAY)                                      { goto error; }
+
+   /* u1 = m * w mod q */
+   if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, hashlen)) != MP_OKAY)       { goto error; }
+   if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY)                                { goto error; }
+
+   /* u2 = r*w mod q */
+   if ((err = mp_mulmod(r, &w, &key->q, &u2)) != MP_OKAY)                                 { goto error; } 
+
+   /* v = g^u1 * y^u2 mod p mod q */
+   if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY)                                { goto error; }
+   if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY)                                         { goto error; }
+
+   /* if r = v then we're set */
+   if (mp_cmp(r, &v) == MP_EQ) {
+      *stat = 1;
+   }
+
+   err = CRYPT_OK;
+   goto done;
+
+error : err = mpi_to_ltc_error(err);
+done  : mp_clear_multi(&w, &v, &u1, &u2, NULL);
+   return err;
+}
+
+/**
+  Verify a DSA signature
   @param sig      The signature
   @param siglen   The length of the signature (octets)
   @param hash     The hash that was signed
@@ -32,59 +97,32 @@
                     const unsigned char *hash, unsigned long hashlen, 
                     int *stat, dsa_key *key)
 {
-   mp_int        r, s, w, v, u1, u2;
-   int           err;
+   int    err;
+   mp_int r, s;
 
-   LTC_ARGCHK(sig  != NULL);
-   LTC_ARGCHK(hash != NULL);
-   LTC_ARGCHK(stat != NULL);
-   LTC_ARGCHK(key  != NULL);
-
-   /* default to invalid signature */
-   *stat = 0;
-
-   /* init our variables */
-   if ((err = mp_init_multi(&r, &s, &w, &v, &u1, &u2, NULL)) != MP_OKAY) {
-      return mpi_to_ltc_error(err);
+   if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) {
+      return CRYPT_MEM;
    }
 
-   /* read in r followed by s */
-   if ((err = der_get_multi_integer(sig, &siglen, &r, &s, NULL)) != CRYPT_OK)              { goto done; }
-
-   /* neither r or s can be null */
-   if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES) {
-      err = CRYPT_INVALID_PACKET;
-      goto done;
-   }
-   
-   /* w = 1/s mod q */
-   if ((err = mp_invmod(&s, &key->q, &w)) != MP_OKAY)                                      { goto error; }
-
-   /* u1 = m * w mod q */
-   if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, hashlen)) != MP_OKAY)       { goto error; }
-   if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY)                                { goto error; }
-
-   /* u2 = r*w mod q */
-   if ((err = mp_mulmod(&r, &w, &key->q, &u2)) != MP_OKAY)                                 { goto error; } 
-
-   /* v = g^u1 * y^u2 mod p mod q */
-   if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY)                          { goto error; }
-   if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY)                          { goto error; }
-   if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY)                                { goto error; }
-   if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY)                                         { goto error; }
-
-   /* if r = v then we're set */
-   if (mp_cmp(&r, &v) == MP_EQ) {
-      *stat = 1;
+   /* decode the sequence */
+   if ((err = der_decode_sequence_multi(sig, siglen,
+                                  LTC_ASN1_INTEGER, 1UL, &r, 
+                                  LTC_ASN1_INTEGER, 1UL, &s, 
+                                  LTC_ASN1_EOL,     0UL, NULL)) != CRYPT_OK) {
+      goto LBL_ERR;
    }
 
-   err = CRYPT_OK;
-   goto done;
+   /* do the op */
+   err = dsa_verify_hash_raw(&r, &s, hash, hashlen, stat, key);
 
-error : err = mpi_to_ltc_error(err);
-done  : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL);
+LBL_ERR:
+   mp_clear_multi(&r, &s, NULL);
    return err;
 }
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_hash.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/15 21:48:59 $ */
--- a/src/pk/dsa/dsa_verify_key.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/dsa/dsa_verify_key.c	Wed Jul 06 12:10:23 2005 +0000
@@ -96,3 +96,7 @@
    return err;
 }
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_key.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/ecc/ecc.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/ecc/ecc.c	Wed Jul 06 12:10:23 2005 +0000
@@ -24,7 +24,7 @@
 #ifdef MECC
 
 /* size of our temp buffers for exported keys */
-#define ECC_BUF_SIZE 160
+#define ECC_BUF_SIZE 256
 
 /* max private key size */
 #define ECC_MAXSIZE  66
@@ -34,22 +34,6 @@
    int size;
    char *name, *prime, *B, *order, *Gx, *Gy;
 } sets[] = {
-#ifdef ECC160
-{
-   20,
-   "ECC-160",
-   /* prime */
-   "G00000000000000000000000007",
-   /* B */
-   "1oUV2vOaSlWbxr6",
-   /* order */
-   "G0000000000004sCQUtDxaqDUN5",
-   /* Gx */
-   "jpqOf1BHus6Yd/pyhyVpP",
-   /* Gy */
-   "D/wykuuIFfr+vPyx7kQEPu8MixO",
-},
-#endif
 #ifdef ECC192
 {
     24,
@@ -76,19 +60,20 @@
    "ECC-224",
 
    /* prime */
-   "400000000000000000000000000000000000BV",
+   "3/////////////////////0000000000000001",
 
    /* B */
-   "21HkWGL2CxJIp",
+   "2q1Gg530Ipg/L1CbPGHB2trx/OkYSBEKCZLV+q",
 
    /* order */
-   "4000000000000000000Kxnixk9t8MLzMiV264/",
+   "3//////////////////nQYuBZmFXFTAKLSN2ez",
 
    /* Gx */
-   "jpqOf1BHus6Yd/pyhyVpP",
+   "2t3WozQxI/Vp8JaBbA0y7JLi8H8ZGoWDOHN1qX",
+
 
    /* Gy */
-   "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
+   "2zDsE8jVSZ+qmYt+RDGtMWMWT7P4JLWPc507uq",
 },
 #endif
 #ifdef ECC256
@@ -165,70 +150,6 @@
 }
 };
 
-#if 0
-
-/* you plug in a prime and B value and it finds a pseudo-random base point */
-void ecc_find_base(void)
-{
-   static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951";
-   static char *order = "26959946667150639794667015087019637467111563745054605861463538557247";
-   static char *b     = "9538957348957353489587";
-   mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y;
-   char buf[4096];
-   int i;
-
-   mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
-   mp_read_radix(&p, prime, 10);
-   mp_read_radix(&r, order, 10);
-   mp_read_radix(&B, b, 10);
-
-   /* get (p+1)/4 */
-   mp_add_d(&p, 1, &pp);
-   mp_div_2(&pp, &pp);
-   mp_div_2(&pp, &pp);
-
-   buf[0] = 0;
-   do {
-      printf("."); fflush(stdout);
-      /* make a random value of x */
-      for (i = 0; i < 16; i++) buf[i+1] = rand() & 255;
-      mp_read_raw(&x, buf, 17);
-      mp_copy(&x, &tx);
-
-      /* now compute x^3 - 3x + b */
-      mp_expt_d(&x, 3, &tmp1);
-      mp_mul_d(&x, 3, &tmp2);
-      mp_sub(&tmp1, &tmp2, &tmp1);
-      mp_add(&tmp1, &B, &tmp1);
-      mp_mod(&tmp1, &p, &tmp1);
-
-      /* now compute sqrt via x^((p+1)/4) */
-      mp_exptmod(&tmp1, &pp, &p, &tmp2);
-      mp_copy(&tmp2, &ty);
-
-      /* now square it */
-      mp_sqrmod(&tmp2, &p, &tmp2);
-
-      /* tmp2 should equal tmp1 */
-   } while (mp_cmp(&tmp1, &tmp2));
-
-   /* now output values in way that libtomcrypt wants */
-   mp_todecimal(&p, buf);
-   printf("\n\np==%s\n", buf);
-   mp_tohex(&B, buf);
-   printf("b==%s\n", buf);
-   mp_todecimal(&r, buf);
-   printf("r==%s\n", buf);
-   mp_tohex(&tx, buf);
-   printf("Gx==%s\n", buf);
-   mp_tohex(&ty, buf);
-   printf("Gy==%s\n", buf);
-
-   mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
-}
- 
-#endif
-
 static int is_valid_idx(int n)
 {
    int x;
@@ -263,7 +184,7 @@
    }
 }
 
-static int ecc_map(ecc_point *P, mp_int *modulus, mp_int *mu)
+static int ecc_map(ecc_point *P, mp_int *modulus, mp_digit mp)
 {
    mp_int t1, t2;
    int err;
@@ -272,20 +193,23 @@
       return CRYPT_MEM;
    }
 
+   /* first map z back to normal */
+   if ((err = mp_montgomery_reduce(&P->z, modulus, mp)) != MP_OKAY)           { goto error; }
+
    /* get 1/z */
-   if ((err = mp_invmod(&P->z, modulus, &t1)) != MP_OKAY)                   { goto error; }
+   if ((err = mp_invmod(&P->z, modulus, &t1)) != MP_OKAY)                     { goto error; }
  
    /* get 1/z^2 and 1/z^3 */
-   if ((err = mp_sqr(&t1, &t2)) != MP_OKAY)                        { goto error; }
-   if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY)             { goto error; }
-   if ((err = mp_mul(&t1, &t2, &t1)) != MP_OKAY)                   { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)             { goto error; }
+   if ((err = mp_sqr(&t1, &t2)) != MP_OKAY)                                   { goto error; }
+   if ((err = mp_mod(&t2, modulus, &t2)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_mul(&t1, &t2, &t1)) != MP_OKAY)                              { goto error; }
+   if ((err = mp_mod(&t1, modulus, &t1)) != MP_OKAY)                          { goto error; }
 
    /* multiply against x/y */
-   if ((err = mp_mul(&P->x, &t2, &P->x)) != MP_OKAY)               { goto error; }
-   if ((err = mp_reduce(&P->x, modulus, mu)) != MP_OKAY)           { goto error; }
-   if ((err = mp_mul(&P->y, &t1, &P->y)) != MP_OKAY)               { goto error; }
-   if ((err = mp_reduce(&P->y, modulus, mu)) != MP_OKAY)           { goto error; }
+   if ((err = mp_mul(&P->x, &t2, &P->x)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&P->x, modulus, mp)) != MP_OKAY)           { goto error; }
+   if ((err = mp_mul(&P->y, &t1, &P->y)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&P->y, modulus, mp)) != MP_OKAY)           { goto error; }
    mp_set(&P->z, 1);
 
    err = CRYPT_OK;
@@ -298,9 +222,8 @@
 
 }
 
-
 /* double a point R = 2P, R can be P*/
-static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
+static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_digit mp)
 {
    mp_int t1, t2;
    int err;
@@ -315,10 +238,10 @@
 
    /* t1 = Z * Z */
    if ((err = mp_sqr(&R->z, &t1)) != MP_OKAY)                                      { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                             { goto error; }
+   if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)                  { goto error; }
    /* Z = Y * Z */
    if ((err = mp_mul(&R->z, &R->y, &R->z)) != MP_OKAY)                             { goto error; }
-   if ((err = mp_reduce(&R->z, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&R->z, modulus, mp)) != MP_OKAY)                { goto error; }
    /* Z = 2Z */
    if ((err = mp_mul_2(&R->z, &R->z)) != MP_OKAY)                                  { goto error; }
    if (mp_cmp(&R->z, modulus) != MP_LT) {
@@ -337,7 +260,7 @@
    }
    /* T2 = T1 * T2 */
    if ((err = mp_mul(&t1, &t2, &t2)) != MP_OKAY)                                   { goto error; }
-   if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY)                             { goto error; }
+   if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY)                  { goto error; }
    /* T1 = 2T2 */
    if ((err = mp_mul_2(&t2, &t1)) != MP_OKAY)                                      { goto error; }
    if (mp_cmp(&t1, modulus) != MP_LT) {
@@ -356,10 +279,10 @@
    }
    /* Y = Y * Y */
    if ((err = mp_sqr(&R->y, &R->y)) != MP_OKAY)                                    { goto error; }
-   if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&R->y, modulus, mp)) != MP_OKAY)                { goto error; }
    /* T2 = Y * Y */
    if ((err = mp_sqr(&R->y, &t2)) != MP_OKAY)                                      { goto error; }
-   if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY)                             { goto error; }
+   if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY)                  { goto error; }
    /* T2 = T2/2 */
    if (mp_isodd(&t2)) {
       if ((err = mp_add(&t2, modulus, &t2)) != MP_OKAY)                            { goto error; }
@@ -367,11 +290,11 @@
    if ((err = mp_div_2(&t2, &t2)) != MP_OKAY)                                      { goto error; }
    /* Y = Y * X */
    if ((err = mp_mul(&R->y, &R->x, &R->y)) != MP_OKAY)                             { goto error; }
-   if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&R->y, modulus, mp)) != MP_OKAY)                { goto error; }
 
    /* X  = T1 * T1 */
    if ((err = mp_sqr(&t1, &R->x)) != MP_OKAY)                                      { goto error; }
-   if ((err = mp_reduce(&R->x, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&R->x, modulus, mp)) != MP_OKAY)                { goto error; }
    /* X = X - Y */
    if ((err = mp_sub(&R->x, &R->y, &R->x)) != MP_OKAY)                             { goto error; }
    if (mp_cmp_d(&R->x, 0) == MP_LT) {
@@ -390,7 +313,7 @@
    }
    /* Y = Y * T1 */
    if ((err = mp_mul(&R->y, &t1, &R->y)) != MP_OKAY)                               { goto error; }
-   if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&R->y, modulus, mp)) != MP_OKAY)                { goto error; }
    /* Y = Y - T2 */
    if ((err = mp_sub(&R->y, &t2, &R->y)) != MP_OKAY)                               { goto error; }
    if (mp_cmp_d(&R->y, 0) == MP_LT) {
@@ -407,7 +330,7 @@
 }
 
 /* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */
-static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu)
+static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_digit mp)
 {
    mp_int t1, t2, x, y, z;
    int err;
@@ -420,34 +343,31 @@
    if ((err = mp_copy(&P->y, &y)) != MP_OKAY)                                   { goto error; }
    if ((err = mp_copy(&P->z, &z)) != MP_OKAY)                                   { goto error; }
 
-   /* if Z' != 1 */
-   if (mp_cmp_d(&Q->z, 1) != MP_EQ) {
       /* T1 = Z' * Z' */
       if ((err = mp_sqr(&Q->z, &t1)) != MP_OKAY)                                { goto error; }
-      if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                       { goto error; }
+      if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)            { goto error; }
       /* X = X * T1 */
       if ((err = mp_mul(&t1, &x, &x)) != MP_OKAY)                               { goto error; }
-      if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY)                        { goto error; }
+      if ((err = mp_montgomery_reduce(&x, modulus, mp)) != MP_OKAY)             { goto error; }
       /* T1 = Z' * T1 */
       if ((err = mp_mul(&Q->z, &t1, &t1)) != MP_OKAY)                           { goto error; }
-      if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                       { goto error; }
+      if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)            { goto error; }
       /* Y = Y * T1 */
       if ((err = mp_mul(&t1, &y, &y)) != MP_OKAY)                               { goto error; }
-      if ((err = mp_reduce(&y, modulus, mu)) != MP_OKAY)                        { goto error; }
-   }
+      if ((err = mp_montgomery_reduce(&y, modulus, mp)) != MP_OKAY)             { goto error; }
 
    /* T1 = Z*Z */
    if ((err = mp_sqr(&z, &t1)) != MP_OKAY)                                      { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)               { goto error; }
    /* T2 = X' * T1 */
    if ((err = mp_mul(&Q->x, &t1, &t2)) != MP_OKAY)                              { goto error; }
-   if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY)               { goto error; }
    /* T1 = Z * T1 */
    if ((err = mp_mul(&z, &t1, &t1)) != MP_OKAY)                                 { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)               { goto error; }
    /* T1 = Y' * T1 */
    if ((err = mp_mul(&Q->y, &t1, &t1)) != MP_OKAY)                              { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)               { goto error; }
 
    /* Y = Y - T1 */
    if ((err = mp_sub(&y, &t1, &y)) != MP_OKAY)                                  { goto error; }
@@ -484,28 +404,28 @@
    if (mp_cmp_d(&Q->z, 1) != MP_EQ) {
       /* Z = Z * Z' */
       if ((err = mp_mul(&z, &Q->z, &z)) != MP_OKAY)                             { goto error; }
-      if ((err = mp_reduce(&z, modulus, mu)) != MP_OKAY)                        { goto error; }
+      if ((err = mp_montgomery_reduce(&z, modulus, mp)) != MP_OKAY)             { goto error; }
    }
    /* Z = Z * X */
    if ((err = mp_mul(&z, &x, &z)) != MP_OKAY)                                   { goto error; }
-   if ((err = mp_reduce(&z, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&z, modulus, mp)) != MP_OKAY)                { goto error; }
 
    /* T1 = T1 * X  */
    if ((err = mp_mul(&t1, &x, &t1)) != MP_OKAY)                                 { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)               { goto error; }
    /* X = X * X */
    if ((err = mp_sqr(&x, &x)) != MP_OKAY)                                       { goto error; }
-   if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&x, modulus, mp)) != MP_OKAY)                { goto error; }
    /* T2 = T2 * x */
    if ((err = mp_mul(&t2, &x, &t2)) != MP_OKAY)                                 { goto error; }
-   if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY)               { goto error; }
    /* T1 = T1 * X  */
    if ((err = mp_mul(&t1, &x, &t1)) != MP_OKAY)                                 { goto error; }
-   if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY)               { goto error; }
  
    /* X = Y*Y */
    if ((err = mp_sqr(&y, &x)) != MP_OKAY)                                       { goto error; }
-   if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY)                           { goto error; }
+   if ((err = mp_montgomery_reduce(&x, modulus, mp)) != MP_OKAY)                { goto error; }
    /* X = X - T2 */
    if ((err = mp_sub(&x, &t2, &x)) != MP_OKAY)                                  { goto error; }
    if (mp_cmp_d(&x, 0) == MP_LT) {
@@ -524,7 +444,7 @@
    }
    /* T2 = T2 * Y */
    if ((err = mp_mul(&t2, &y, &t2)) != MP_OKAY)                                 { goto error; }
-   if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY)                          { goto error; }
+   if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY)               { goto error; }
    /* Y = T2 - T1 */
    if ((err = mp_sub(&t2, &t1, &y)) != MP_OKAY)                                 { goto error; }
    if (mp_cmp_d(&y, 0) == MP_LT) {
@@ -553,22 +473,25 @@
 #define WINSIZE 4
 
 /* perform R = kG where k == integer and G == ecc_point */
-static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
+static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus, int map)
 {
    ecc_point *tG, *M[8];
    int        i, j, err;
    mp_int     mu;
-   mp_digit   buf;
+   mp_digit   buf, mp;
    int        first, bitbuf, bitcpy, bitcnt, mode, digidx;
 
-  /* init barrett reduction */
-  if ((err = mp_init(&mu)) != MP_OKAY) {
-      return mpi_to_ltc_error(err);
-  }
-  if ((err = mp_reduce_setup(&mu, modulus)) != MP_OKAY) {
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) {
+      return CRYPT_INVALID_ARG;
+   }
+   if ((err = mp_init(&mu)) != MP_OKAY) {
+      return CRYPT_MEM;
+   }
+   if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) {
       mp_clear(&mu);
-      return mpi_to_ltc_error(err);
-  }
+      return CRYPT_INVALID_ARG;
+   }
 
   /* alloc ram for window temps */
   for (i = 0; i < 8; i++) {
@@ -586,20 +509,21 @@
    tG = new_point();
    if (tG == NULL)                                                            { err = CRYPT_MEM; goto done; }
 
-   /* tG = G */
-   if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY)                             { goto error; }
-   if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY)                             { goto error; }
-   if ((err = mp_copy(&G->z, &tG->z)) != MP_OKAY)                             { goto error; }
+   /* tG = G  and convert to montgomery */
+   if ((err = mp_mulmod(&G->x, &mu, modulus, &tG->x)) != MP_OKAY)             { goto error; }
+   if ((err = mp_mulmod(&G->y, &mu, modulus, &tG->y)) != MP_OKAY)             { goto error; }
+   if ((err = mp_mulmod(&G->z, &mu, modulus, &tG->z)) != MP_OKAY)             { goto error; }
+   mp_clear(&mu);
    
    /* calc the M tab, which holds kG for k==8..15 */
    /* M[0] == 8G */
-   if ((err = dbl_point(G, M[0], modulus, &mu)) != CRYPT_OK)                  { goto done; }
-   if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK)               { goto done; }
-   if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK)               { goto done; }
+   if ((err = dbl_point(tG,   M[0], modulus, mp)) != CRYPT_OK)               { goto done; }
+   if ((err = dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK)               { goto done; }
+   if ((err = dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK)               { goto done; }
 
    /* now find (8+k)G for k=1..7 */
    for (j = 9; j < 16; j++) {
-       if ((err = add_point(M[j-9], G, M[j-8], modulus, &mu)) != CRYPT_OK)    { goto done; }
+       if ((err = add_point(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK)   { goto done; }
    }
 
    /* setup sliding window */
@@ -621,7 +545,7 @@
        bitcnt = (int) DIGIT_BIT;
      }
 
-     /* grab the next msb from the multiplicand */
+     /* grab the next msb from the ltiplicand */
      i = (buf >> (DIGIT_BIT - 1)) & 1;
      buf <<= 1;
 
@@ -632,7 +556,7 @@
 
      /* if the bit is zero and mode == 1 then we double */
      if (mode == 1 && i == 0) {
-        if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK)                { goto done; }
+        if ((err = dbl_point(R, R, modulus, mp)) != CRYPT_OK)                { goto done; }
         continue;
      }
 
@@ -653,11 +577,11 @@
          /* ok window is filled so double as required and add  */
          /* double first */
          for (j = 0; j < WINSIZE; j++) {
-           if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK)             { goto done; }
+           if ((err = dbl_point(R, R, modulus, mp)) != CRYPT_OK)             { goto done; }
          }
 
          /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
-         if ((err = add_point(R, M[bitbuf-8], R, modulus, &mu)) != CRYPT_OK)  { goto done; }
+         if ((err = add_point(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK)  { goto done; }
        }
        /* empty window and reset */
        bitcpy = bitbuf = 0;
@@ -671,7 +595,7 @@
      for (j = 0; j < bitcpy; j++) {
        /* only double if we have had at least one add first */
        if (first == 0) {
-          if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK)               { goto done; }
+          if ((err = dbl_point(R, R, modulus, mp)) != CRYPT_OK)               { goto done; }
        }
 
        bitbuf <<= 1;
@@ -684,14 +608,19 @@
             first = 0;
          } else {
             /* then add */
-            if ((err = add_point(R, tG, R, modulus, &mu)) != CRYPT_OK)         { goto done; }
+            if ((err = add_point(R, tG, R, modulus, mp)) != CRYPT_OK)         { goto done; }
          }
        }
      }
    }
 
    /* map R back from projective space */
-   err = ecc_map(R, modulus, &mu);
+   if (map) {
+      err = ecc_map(R, modulus, mp);
+   } else {
+      err = CRYPT_OK;
+   }
+
    goto done;
 error:
    err = mpi_to_ltc_error(err);
@@ -700,7 +629,6 @@
    for (i = 0; i < 8; i++) {
        del_point(M[i]);
    }
-   mp_clear(&mu);
    return err;
 }
 
@@ -756,7 +684,7 @@
 
        /* then we should have G == (order + 1)G */
        if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY)                          { goto error; }
-       if ((err = ecc_mulmod(&order, G, GG, &modulus)) != CRYPT_OK)                 { goto done; }
+       if ((err = ecc_mulmod(&order, G, GG, &modulus, 1)) != CRYPT_OK)              { goto done; }
        if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) {
           err = CRYPT_FAIL_TESTVECTOR;
           goto done;
@@ -855,7 +783,7 @@
    if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; }
 
    /* make the public key */
-   if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime)) != CRYPT_OK)             { goto LBL_ERR; }
+   if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1)) != CRYPT_OK)          { goto LBL_ERR; }
    key->type = PK_PRIVATE;
 
    /* shrink key */
@@ -892,89 +820,6 @@
    mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL);
 }
 
-static int compress_y_point(ecc_point *pt, int idx, int *result)
-{
-   mp_int tmp, tmp2, p;
-   int err;
-
-   LTC_ARGCHK(pt     != NULL);
-   LTC_ARGCHK(result != NULL);
-
-   if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
-      return mpi_to_ltc_error(err);
-   }
-
-   /* get x^3 - 3x + b */
-   if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
-   if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = pX^3  */
-   if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY)                 { goto error; } /* tmp2 = 3*pX^3 */
-   if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp - tmp2 */
-   if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp + p */
-   if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY)  { goto error; } /* p = prime */
-   if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp mod p */
-
-   /* now find square root */
-   if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY)                     { goto error; } /* tmp2 = p + 1 */
-   if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY)           { goto error; } /* tmp2 = (p+1)/4 */
-   if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY)          { goto error; } /* tmp  = (x^3 - 3x + b)^((p+1)/4) mod p */
-
-   /* if tmp equals the y point give a 0, otherwise 1 */
-   if (mp_cmp(&tmp, &pt->y) == 0) {
-      *result = 0;
-   } else {
-      *result = 1;
-   }
-
-   err = CRYPT_OK;
-   goto done;
-error:
-   err = mpi_to_ltc_error(err);
-done:
-   mp_clear_multi(&p, &tmp, &tmp2, NULL);
-   return err;
-}
-
-static int expand_y_point(ecc_point *pt, int idx, int result)
-{
-   mp_int tmp, tmp2, p;
-   int err;
-
-   LTC_ARGCHK(pt != NULL);
-
-   if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
-      return CRYPT_MEM;
-   }
-
-   /* get x^3 - 3x + b */
-   if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
-   if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = pX^3 */
-   if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY)                 { goto error; } /* tmp2 = 3*pX^3 */
-   if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp - tmp2 */
-   if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp + p */
-   if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY)  { goto error; } /* p = prime */
-   if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp mod p */
-
-   /* now find square root */
-   if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY)                     { goto error; } /* tmp2 = p + 1 */
-   if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY)           { goto error; } /* tmp2 = (p+1)/4 */
-   if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY)          { goto error; } /* tmp  = (x^3 - 3x + b)^((p+1)/4) mod p */
-
-   /* if result==0, then y==tmp, otherwise y==p-tmp */
-   if (result == 0) {
-      if ((err = mp_copy(&tmp, &pt->y) != MP_OKAY))                   { goto error; }
-   } else {
-      if ((err = mp_sub(&p, &tmp, &pt->y) != MP_OKAY))                { goto error; }
-   }
-
-   err = CRYPT_OK;
-   goto done;
-error:
-   err = mpi_to_ltc_error(err);
-done:
-   mp_clear_multi(&p, &tmp, &tmp2, NULL);
-   return err;
-}
-
 /**
   Export an ECC key as a binary packet
   @param out     [out] Destination for the key
@@ -985,46 +830,46 @@
 */
 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
 {
-   unsigned long y, z;
-   int cp, err;
+   int           err;
+   unsigned char flags[1];
+   unsigned long key_size;
 
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(key    != NULL);
    
-   /* can we store the static header?  */
-   if (*outlen < (PACKET_SIZE + 3)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
    /* type valid? */
    if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
       return CRYPT_PK_TYPE_MISMATCH;
    }
 
-   /* output type and magic byte */
-   y = PACKET_SIZE;
-   out[y++] = (unsigned char)type;
-   out[y++] = (unsigned char)sets[key->idx].size;
+   if (is_valid_idx(key->idx) == 0) {
+      return CRYPT_INVALID_ARG;
+   }
 
-   /* output x coordinate */
-   OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z);
-
-   /* compress y and output it  */
-   if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) {
-      return err;
-   }
-   out[y++] = (unsigned char)cp;
+   /* we store the NIST byte size */
+   key_size = sets[key->idx].size;
 
    if (type == PK_PRIVATE) {
-      OUTPUT_BIGNUM(&key->k, out, y, z);
+       flags[0] = 1;
+       err = der_encode_sequence_multi(out, outlen,
+                                 LTC_ASN1_BIT_STRING,      1UL, flags,
+                                 LTC_ASN1_SHORT_INTEGER,   1UL, &key_size,
+                                 LTC_ASN1_INTEGER,         1UL, &key->pubkey.x,
+                                 LTC_ASN1_INTEGER,         1UL, &key->pubkey.y,
+                                 LTC_ASN1_INTEGER,         1UL, &key->k,
+                                 LTC_ASN1_EOL,             0UL, NULL);
+   } else {
+       flags[0] = 0;
+       err = der_encode_sequence_multi(out, outlen,
+                                 LTC_ASN1_BIT_STRING,      1UL, flags,
+                                 LTC_ASN1_SHORT_INTEGER,   1UL, &key_size,
+                                 LTC_ASN1_INTEGER,         1UL, &key->pubkey.x,
+                                 LTC_ASN1_INTEGER,         1UL, &key->pubkey.y,
+                                 LTC_ASN1_EOL,             0UL, NULL);
    }
 
-   /* store header */
-   packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_KEY);
-   *outlen = y;
-
-   return CRYPT_OK;
+   return err;
 }
 
 /**
@@ -1036,72 +881,63 @@
 */
 int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
 {
-   unsigned long x, y, s;
-   int err;
+   unsigned long key_size;
+   unsigned char flags[1];
+   int           err;
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
 
-   /* check length */
-   if ((3+PACKET_SIZE) > inlen) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* check type */
-   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
-      return err;
-   }
-
    /* init key */
    if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != MP_OKAY) {
       return CRYPT_MEM;
    }
 
-   y = PACKET_SIZE;
-   key->type = (int)in[y++];
-   s = (unsigned long)in[y++];
-
-   for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
-   if (sets[x].size == 0) {
-      err = CRYPT_INVALID_KEYSIZE;
-      goto error;
-   }
-   key->idx = (int)x;
-
-   /* type check both values */
-   if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE))  {
-      err = CRYPT_INVALID_PACKET;
+   /* find out what type of key it is */
+   if ((err = der_decode_sequence_multi(in, inlen, 
+                                  LTC_ASN1_BIT_STRING, 1UL, &flags,
+                                  LTC_ASN1_EOL,        0UL, NULL)) != CRYPT_OK) {
       goto error;
    }
 
-   /* is the key idx valid? */
-   if (is_valid_idx(key->idx) != 1) {
+
+   if (flags[0] == 1) {
+      /* private key */
+      key->type = PK_PRIVATE;
+      if ((err = der_decode_sequence_multi(in, inlen,
+                                     LTC_ASN1_BIT_STRING,      1UL, flags,
+                                     LTC_ASN1_SHORT_INTEGER,   1UL, &key_size,
+                                     LTC_ASN1_INTEGER,         1UL, &key->pubkey.x,
+                                     LTC_ASN1_INTEGER,         1UL, &key->pubkey.y,
+                                     LTC_ASN1_INTEGER,         1UL, &key->k,
+                                     LTC_ASN1_EOL,             0UL, NULL)) != CRYPT_OK) {
+         goto error;
+      }
+   } else {
+      /* public key */
+      /* private key */
+      key->type = PK_PUBLIC;
+      if ((err = der_decode_sequence_multi(in, inlen,
+                                     LTC_ASN1_BIT_STRING,      1UL, flags,
+                                     LTC_ASN1_SHORT_INTEGER,   1UL, &key_size,
+                                     LTC_ASN1_INTEGER,         1UL, &key->pubkey.x,
+                                     LTC_ASN1_INTEGER,         1UL, &key->pubkey.y,
+                                     LTC_ASN1_EOL,             0UL, NULL)) != CRYPT_OK) {
+         goto error;
+      }
+   }
+
+   /* find the idx */
+   for (key->idx = 0; sets[key->idx].size && (unsigned long)sets[key->idx].size != key_size; ++key->idx);
+   if (sets[key->idx].size == 0) {
       err = CRYPT_INVALID_PACKET;
       goto error;
    }
 
-   /* load x coordinate */
-   INPUT_BIGNUM(&key->pubkey.x, in, x, y, inlen);
-
-   /* load y */
-   x = (unsigned long)in[y++];
-   if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) {
-       goto error;
-   }
-
-   if (key->type == PK_PRIVATE) {
-      /* load private key */
-      INPUT_BIGNUM(&key->k, in, x, y, inlen);
-   }
-
-   /* eliminate private key if public */
-   if (key->type == PK_PUBLIC) {
-      mp_clear(&key->k);
-   }
-
-   /* z is always 1 */
+   /* set z */
    mp_set(&key->pubkey.z, 1);
 
+   /* we're good */
    return CRYPT_OK;
 error:
    mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL);
@@ -1112,14 +948,14 @@
   Create an ECC shared secret between two keys
   @param private_key      The private ECC key
   @param public_key       The public key
-  @param out              [out] Destination of the shared secret
+  @param out              [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63)
   @param outlen           [in/out] The max size and resulting size of the shared secret
   @return CRYPT_OK if successful
 */
 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
                       unsigned char *out, unsigned long *outlen)
 {
-   unsigned long x, y;
+   unsigned long x;
    ecc_point *result;
    mp_int prime;
    int err;
@@ -1134,6 +970,10 @@
       return CRYPT_PK_NOT_PRIVATE;
    }
 
+   if (is_valid_idx(private_key->idx) == 0) {
+      return CRYPT_INVALID_ARG;
+   }
+
    if (private_key->idx != public_key->idx) {
       return CRYPT_PK_TYPE_MISMATCH;
    }
@@ -1149,21 +989,19 @@
       return mpi_to_ltc_error(err);
    }
 
-   if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY)   { goto error; }
-   if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
+   if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY)            { goto error; }
+   if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime, 1)) != CRYPT_OK)       { goto done1; }
 
-   x = (unsigned long)mp_unsigned_bin_size(&result->x);
-   y = (unsigned long)mp_unsigned_bin_size(&result->y);
-
-   if (*outlen < (x+y)) {
+   x = (unsigned long)mp_unsigned_bin_size(&prime);
+   if (*outlen < x) {
       err = CRYPT_BUFFER_OVERFLOW;
       goto done1;
    }
-   *outlen = x+y;
-   if ((err = mp_to_unsigned_bin(&result->x, out))   != MP_OKAY)          { goto error; }
-   if ((err = mp_to_unsigned_bin(&result->y, out+x)) != MP_OKAY)          { goto error; }
+   zeromem(out, x);
+   if ((err = mp_to_unsigned_bin(&result->x, out + (x - mp_unsigned_bin_size(&result->x))))   != MP_OKAY)          { goto error; }
 
-   err = CRYPT_OK;
+   err     = CRYPT_OK;
+   *outlen = x;
    goto done1;
 error:
    err = mpi_to_ltc_error(err);
@@ -1192,3 +1030,7 @@
 #endif
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc.c,v $ */
+/* $Revision: 1.20 $ */
+/* $Date: 2005/06/14 20:42:28 $ */
--- a/src/pk/ecc/ecc_sys.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/ecc/ecc_sys.c	Wed Jul 06 12:10:23 2005 +0000
@@ -33,7 +33,7 @@
 {
     unsigned char *pub_expt, *ecc_shared, *skey;
     ecc_key        pubkey;
-    unsigned long  x, y, z, hashsize, pubkeysize;
+    unsigned long  x, y, pubkeysize;
     int            err;
 
     LTC_ARGCHK(in      != NULL);
@@ -82,53 +82,29 @@
        goto LBL_ERR;
     }
     
-    /* now check if the out buffer is big enough */
-    if (*outlen < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) {
-       ecc_free(&pubkey);
-       err = CRYPT_BUFFER_OVERFLOW;
-       goto LBL_ERR;
-    }
-
     /* make random key */
-    hashsize  = hash_descriptor[hash].hashsize;
-    x = ECC_BUF_SIZE;
+    x        = ECC_BUF_SIZE;
     if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
        ecc_free(&pubkey);
        goto LBL_ERR;
     }
     ecc_free(&pubkey);
-    z = MAXBLOCKSIZE;
-    if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) {
+    y = MAXBLOCKSIZE;
+    if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
        goto LBL_ERR;
     }
     
-    /* store header */
-    packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);    
-
-    /* output header */
-    y = PACKET_SIZE;
- 
-    /* size of hash name and the name itself */
-    out[y++] = hash_descriptor[hash].ID;
-
-    /* length of ECC pubkey and the key itself */
-    STORE32L(pubkeysize, out+y);
-    y += 4;
-
-    for (x = 0; x < pubkeysize; x++, y++) {
-        out[y] = pub_expt[x];
+    /* Encrypt key */
+    for (x = 0; x < inlen; x++) {
+      skey[x] ^= in[x];
     }
 
-    STORE32L(inlen, out+y);
-    y += 4;
+    err = der_encode_sequence_multi(out, outlen,
+                                    LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID,
+                                    LTC_ASN1_OCTET_STRING,       pubkeysize,                     pub_expt,
+                                    LTC_ASN1_OCTET_STRING,       inlen,                          skey,
+                                    LTC_ASN1_EOL,                0UL,                            NULL);
 
-    /* Encrypt/Store the encrypted key */
-    for (x = 0; x < inlen; x++, y++) {
-      out[y] = skey[x] ^ in[x];
-    }
-    *outlen = y;
-
-    err = CRYPT_OK;
 LBL_ERR:
 #ifdef LTC_CLEAN_STACK
     /* clean up */
@@ -157,10 +133,11 @@
                           unsigned char *out, unsigned long *outlen, 
                           ecc_key *key)
 {
-   unsigned char *shared_secret, *skey;
-   unsigned long  x, y, z, hashsize, keysize;
+   unsigned char *ecc_shared, *skey, *pub_expt;
+   unsigned long  x, y, hashOID[32];
    int            hash, err;
    ecc_key        pubkey;
+   ltc_asn1_list  decode[3];
 
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
@@ -172,98 +149,93 @@
       return CRYPT_PK_NOT_PRIVATE;
    }
    
-   /* correct length ? */
-   if (inlen < PACKET_SIZE+1+4+4) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      inlen -= PACKET_SIZE+1+4+4;
-   }
-
-   /* is header correct? */
-   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
+   /* decode to find out hash */
+   LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
+ 
+   if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
       return err;
    }
+   for (hash = 0; hash_descriptor[hash].name   != NULL             && 
+                  (hash_descriptor[hash].OIDlen != decode[0].size   || 
+                   memcmp(hash_descriptor[hash].OID, hashOID, sizeof(unsigned long)*decode[0].size)); hash++);
 
-   /* now lets get the hash name */
-   y = PACKET_SIZE;
-   hash = find_hash_id(in[y++]);
-   if (hash == -1) {
-      return CRYPT_INVALID_HASH;
+   if (hash_descriptor[hash].name == NULL) {
+      return CRYPT_INVALID_PACKET;
    }
 
-   /* common values */
-   hashsize  = hash_descriptor[hash].hashsize;
-
-   /* get public key */
-   LOAD32L(x, in+y);
-   if (inlen < x) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      inlen -= x;
-   }
-   y += 4;
-   if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) {
-      return err;
-   }
-   y += x;
+   /* we now have the hash! */
 
    /* allocate memory */
-   shared_secret = XMALLOC(ECC_BUF_SIZE);
-   skey          = XMALLOC(MAXBLOCKSIZE);
-   if (shared_secret == NULL || skey == NULL) {
-      if (shared_secret != NULL) {
-         XFREE(shared_secret);
+   pub_expt   = XMALLOC(ECC_BUF_SIZE);
+   ecc_shared = XMALLOC(ECC_BUF_SIZE);
+   skey       = XMALLOC(MAXBLOCKSIZE);
+   if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
+      if (pub_expt != NULL) {
+         XFREE(pub_expt);
+      }
+      if (ecc_shared != NULL) {
+         XFREE(ecc_shared);
       }
       if (skey != NULL) {
          XFREE(skey);
       }
-      ecc_free(&pubkey);
       return CRYPT_MEM;
    }
+   LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING,      pub_expt,  ECC_BUF_SIZE);
+   LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE);
+
+   /* read the structure in now */
+   if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   /* import ECC key from packet */
+   if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
 
    /* make shared key */
    x = ECC_BUF_SIZE;
-   if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
+   if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
       ecc_free(&pubkey);
       goto LBL_ERR;
    }
    ecc_free(&pubkey);
 
-   z = MAXBLOCKSIZE;
-   if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
+   y = MAXBLOCKSIZE;
+   if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   /* ensure the hash of the shared secret is at least as big as the encrypt itself */
+   if (decode[2].size > y) {
+      err = CRYPT_INVALID_PACKET;
       goto LBL_ERR;
    }
 
-   LOAD32L(keysize, in+y);
-   if (inlen < keysize) {
-      err = CRYPT_INVALID_PACKET;
+   /* avoid buffer overflow */
+   if (*outlen < decode[2].size) {
+      err = CRYPT_BUFFER_OVERFLOW;
       goto LBL_ERR;
-   } else {
-      inlen -= keysize;
-   }
-   y += 4;
-
-   if (*outlen < keysize) {
-       err = CRYPT_BUFFER_OVERFLOW;
-       goto LBL_ERR;
    }
 
    /* Decrypt the key */
-   for (x = 0; x < keysize; x++, y++) {
-     out[x] = skey[x] ^ in[y];
+   for (x = 0; x < decode[2].size; x++) {
+     out[x] = skey[x] ^ ecc_shared[x];
    }
-
-   *outlen = keysize;
+   *outlen = x;
 
    err = CRYPT_OK;
 LBL_ERR:
 #ifdef LTC_CLEAN_STACK
-   zeromem(shared_secret, ECC_BUF_SIZE);
-   zeromem(skey,          MAXBLOCKSIZE);
+   zeromem(pub_expt,   ECC_BUF_SIZE);
+   zeromem(ecc_shared, ECC_BUF_SIZE);
+   zeromem(skey,       MAXBLOCKSIZE);
 #endif
 
+   XFREE(pub_expt);
+   XFREE(ecc_shared);
    XFREE(skey);
-   XFREE(shared_secret);
 
    return err;
 }
@@ -284,9 +256,7 @@
                         prng_state *prng, int wprng, ecc_key *key)
 {
    ecc_key       pubkey;
-   mp_int        b, p;
-   unsigned char *epubkey, *er;
-   unsigned long x, y, pubkeysize, rsize;
+   mp_int        r, s, e, p;
    int           err;
 
    LTC_ARGCHK(in     != NULL);
@@ -308,116 +278,65 @@
       return err;
    }
 
-   /* make up a key and export the public copy */
-   if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* allocate ram */
-   epubkey = XMALLOC(ECC_BUF_SIZE);
-   er      = XMALLOC(ECC_BUF_SIZE);
-   if (epubkey == NULL || er == NULL) {
-      if (epubkey != NULL) {
-         XFREE(epubkey);
-      }
-      if (er != NULL) {
-         XFREE(er);
-      }
-      ecc_free(&pubkey);
-      return CRYPT_MEM;
-   }
-
-   pubkeysize = ECC_BUF_SIZE;
-   if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
-      ecc_free(&pubkey);
-      goto LBL_ERR;
-   }
-
-   /* get the hash and load it as a bignum into 'b' */
+   /* get the hash and load it as a bignum into 'e' */
    /* init the bignums */
-   if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { 
+   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != MP_OKAY) { 
       ecc_free(&pubkey);
       err = mpi_to_ltc_error(err);
       goto LBL_ERR;
    }
    if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY)        { goto error; }
-   if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY)  { goto error; }
+   if ((err = mp_read_unsigned_bin(&e, (unsigned char *)in, (int)inlen)) != MP_OKAY)  { goto error; }
 
-   /* find b = (m - x)/k */
-   if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY)            { goto error; } /* k = 1/k */
-   if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY)                 { goto error; } /* b = m - x */
-   if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY)               { goto error; } /* b = (m - x)/k */
+   /* make up a key and export the public copy */
+   for (;;) {
+      if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
+         return err;
+      }
+
+      /* find r = x1 mod n */
+      if ((err = mp_mod(&pubkey.pubkey.x, &p, &r)) != MP_OKAY)                           { goto error; }
 
-   /* export it */
-   rsize = (unsigned long)mp_unsigned_bin_size(&b);
-   if (rsize > ECC_BUF_SIZE) { 
-      err = CRYPT_BUFFER_OVERFLOW;
-      goto error; 
-   }
-   if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY)                     { goto error; }
+      if (mp_iszero(&r)) {
+         ecc_free(&pubkey);
+      } else { 
+        /* find s = (e + xr)/k */
+        if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY)            { goto error; } /* k = 1/k */
+        if ((err = mp_mulmod(&key->k, &r, &p, &s)) != MP_OKAY)                 { goto error; } /* s = xr */
+        if ((err = mp_addmod(&e, &s, &p, &s)) != MP_OKAY)                      { goto error; } /* s = e +  xr */
+        if ((err = mp_mulmod(&s, &pubkey.k, &p, &s)) != MP_OKAY)               { goto error; } /* s = (e + xr)/k */
 
-   /* now lets check the outlen before we write */
-   if (*outlen < (12 + rsize + pubkeysize)) {
-      err = CRYPT_BUFFER_OVERFLOW;
-      goto LBL_ERR;
+        if (mp_iszero(&s)) {
+           ecc_free(&pubkey);
+        } else {
+           break;
+        }
+      }
    }
 
-   /* lets output */
-   y = PACKET_SIZE;
-   
-   /* size of public key */
-   STORE32L(pubkeysize, out+y);
-   y += 4;
-
-   /* copy the public key */
-   for (x = 0; x < pubkeysize; x++, y++) {
-       out[y] = epubkey[x];
-   }
-
-   /* size of 'r' */
-   STORE32L(rsize, out+y);
-   y += 4;
-
-   /* copy r */
-   for (x = 0; x < rsize; x++, y++) {
-       out[y] = er[x];
-   }
-
-   /* store header */
-   packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED);
-   *outlen = y;
-
-   /* all ok */
-   err = CRYPT_OK;
+   /* store as SEQUENCE { r, s -- integer } */
+   err = der_encode_sequence_multi(out, outlen,
+                             LTC_ASN1_INTEGER, 1UL, &r,
+                             LTC_ASN1_INTEGER, 1UL, &s,
+                             LTC_ASN1_EOL, 0UL, NULL);
    goto LBL_ERR;
 error:
    err = mpi_to_ltc_error(err);
 LBL_ERR:
-   mp_clear_multi(&b, &p, NULL);
+   mp_clear_multi(&r, &s, &p, &e, NULL);
    ecc_free(&pubkey);
-#ifdef LTC_CLEAN_STACK
-   zeromem(er,      ECC_BUF_SIZE);
-   zeromem(epubkey, ECC_BUF_SIZE);
-#endif
-
-   XFREE(epubkey);
-   XFREE(er);
 
    return err;   
 }
 
-/* verify that mG = (bA + Y)
- *
- * The signatures work by making up a fresh key "a" with a public key "A".  Now we want to sign so the 
- * public key Y = xG can verify it.
+/* verify 
  *
- * b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it]
- * A = kG therefore bA == ((m-x)/k)kG == (m-x)G
- *
- * Adding Y = xG to the bA gives us (m-x)G + xG == mG
- *
- * The user given only xG, kG and b cannot determine k or x which means they can't find the private key.
- * 
+ * w  = s^-1 mod n
+ * u1 = xw 
+ * u2 = rw
+ * X = u1*G + u2*Q
+ * v = X_x1 mod n
+ * accept if v == r
  */
 
 /**
@@ -434,10 +353,9 @@
                     const unsigned char *hash, unsigned long hashlen, 
                     int *stat, ecc_key *key)
 {
-   ecc_point    *mG;
-   ecc_key       pubkey;
-   mp_int        b, p, m, mu;
-   unsigned long x, y;
+   ecc_point    *mG, *mQ;
+   mp_int        r, s, v, w, u1, u2, e, p, m;
+   mp_digit      mp;
    int           err;
 
    LTC_ARGCHK(sig  != NULL);
@@ -448,89 +366,81 @@
    /* default to invalid signature */
    *stat = 0;
 
-   if (siglen < PACKET_SIZE+4+4) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      siglen -= PACKET_SIZE+4+4;
+   /* is the IDX valid ?  */
+   if (is_valid_idx(key->idx) != 1) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+
+   /* allocate ints */
+   if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != MP_OKAY) {
+      return CRYPT_MEM;
+   }
+
+   /* allocate points */
+   mG = new_point();
+   mQ = new_point();
+   if (mQ  == NULL || mG == NULL) {
+      err = CRYPT_MEM;
+      goto done;
+   }
+
+   /* parse header */
+   if ((err = der_decode_sequence_multi(sig, siglen,
+                                  LTC_ASN1_INTEGER, 1UL, &r,
+                                  LTC_ASN1_INTEGER, 1UL, &s,
+                                  LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
+      goto done;
+   }
+
+   /* get the order */
+   if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY)                  { goto error; }
+
+   /* get the modulus */
+   if ((err = mp_read_radix(&m, (char *)sets[key->idx].prime, 64)) != MP_OKAY)                  { goto error; }
+
+   /* check for zero */
+   if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || mp_cmp(&s, &p) != MP_LT) {
+      err = CRYPT_INVALID_PACKET;
+      goto done;
    }
 
-   /* is the message format correct? */
-   if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) {
-      return err;
-   }     
-
-   /* get hash name */
-   y = PACKET_SIZE;
+   /* read hash */
+   if ((err = mp_read_unsigned_bin(&e, (unsigned char *)hash, (int)hashlen)) != MP_OKAY)        { goto error; }
 
-   /* get size of public key */
-   LOAD32L(x, sig+y);
-   if (siglen < x) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      siglen -= x;
-   }
-   y += 4;
-
-   /* load the public key */
-   if ((err = ecc_import((unsigned char*)sig+y, x, &pubkey)) != CRYPT_OK) {
-      return err;
-   }
-   y += x;
-
-   /* load size of 'b' */
-   LOAD32L(x, sig+y);
-   if (siglen < x) {
-      return CRYPT_INVALID_PACKET;
-   } else {
-      siglen -= x;
-   }
-   y += 4;
+   /*  w  = s^-1 mod n */
+   if ((err = mp_invmod(&s, &p, &w)) != MP_OKAY)                                                { goto error; }
 
-   /* init values */
-   if ((err = mp_init_multi(&b, &m, &p, &mu, NULL)) != MP_OKAY) { 
-      ecc_free(&pubkey);
-      return mpi_to_ltc_error(err);
-   }
-
-   mG = new_point();
-   if (mG == NULL) { 
-      mp_clear_multi(&b, &m, &p, &mu, NULL);
-      ecc_free(&pubkey);
-      return CRYPT_MEM;
-   } 
-
-   /* load b */
-   if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x)) != MP_OKAY)        { goto error; }
-   y += x;
+   /* u1 = ew */
+   if ((err = mp_mulmod(&e, &w, &p, &u1)) != MP_OKAY)                                           { goto error; }
 
-   /* get m in binary a bignum */
-   if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)hashlen)) != MP_OKAY)   { goto error; }
-   
-   /* load prime */
-   if ((err = mp_read_radix(&p, (char *)sets[key->idx].prime, 64)) != MP_OKAY)             { goto error; }
-   
-   /* calculate barrett stuff */
-   mp_set(&mu, 1); 
-   mp_lshd(&mu, 2 * USED(&p));
-   if ((err = mp_div(&mu, &p, &mu, NULL)) != MP_OKAY)                                      { goto error; }
+   /* u2 = rw */
+   if ((err = mp_mulmod(&r, &w, &p, &u2)) != MP_OKAY)                                           { goto error; }
 
-   /* get bA */
-   if ((err = ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p)) != CRYPT_OK)                  { goto done; }
-   
-   /* get bA + Y */
-   if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK)    { goto done; }
-
-   /* we have to transform it */
-   if ((err = ecc_map(&pubkey.pubkey, &p, &mu)) != CRYPT_OK)                                    { goto done; }
-
-   /* get mG */
+   /* find mG = u1*G */
    if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY)                 { goto error; }
    if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY)                 { goto error; }
-   mp_set(&mG->z, 1);
-   if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK)                                          { goto done; }
+   mp_set(&mG->z, 1);  
+   if ((err = ecc_mulmod(&u1, mG, mG, &m, 0)) != CRYPT_OK)                                      { goto done; }
 
-   /* compare mG to bA + Y */
-   if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) {
+   /* find mQ = u2*Q */
+   if ((err = mp_copy(&key->pubkey.x, &mQ->x)) != MP_OKAY)                                      { goto error; }
+   if ((err = mp_copy(&key->pubkey.y, &mQ->y)) != MP_OKAY)                                      { goto error; }
+   if ((err = mp_copy(&key->pubkey.z, &mQ->z)) != MP_OKAY)                                      { goto error; }
+   if ((err = ecc_mulmod(&u2, mQ, mQ, &m, 0)) != CRYPT_OK)                                      { goto done; }
+  
+   /* find the montgomery mp */
+   if ((err = mp_montgomery_setup(&m, &mp)) != MP_OKAY)                                         { goto error; }
+   /* add them */
+   if ((err = add_point(mQ, mG, mG, &m, mp)) != CRYPT_OK)                                       { goto done; }
+   
+   /* reduce */
+   if ((err = ecc_map(mG, &m, mp)) != CRYPT_OK)                                                 { goto done; }
+
+   /* v = X_x1 mod n */
+   if ((err = mp_mod(&mG->x, &p, &v)) != CRYPT_OK)                                              { goto done; }
+
+   /* does v == r */
+   if (mp_cmp(&v, &r) == MP_EQ) {
       *stat = 1;
    }
 
@@ -541,8 +451,12 @@
    err = mpi_to_ltc_error(err);
 done:
    del_point(mG);
-   ecc_free(&pubkey);
-   mp_clear_multi(&p, &m, &b, &mu, NULL);
+   del_point(mQ);
+   mp_clear_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL);
    return err;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sys.c,v $ */
+/* $Revision: 1.18 $ */
+/* $Date: 2005/06/14 20:47:55 $ */
--- a/src/pk/packet_store_header.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/packet_store_header.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,3 +27,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/packet_store_header.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/packet_valid_header.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/packet_valid_header.c	Wed Jul 06 12:10:23 2005 +0000
@@ -35,3 +35,7 @@
 #endif
 
  
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/packet_valid_header.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_i2osp.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_i2osp.c	Wed Jul 06 12:10:23 2005 +0000
@@ -49,3 +49,7 @@
 
 #endif /* PKCS_1 */
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_i2osp.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_mgf1.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_mgf1.c	Wed Jul 06 12:10:23 2005 +0000
@@ -102,3 +102,7 @@
 }
 
 #endif /* PKCS_1 */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_oaep_decode.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c	Wed Jul 06 12:10:23 2005 +0000
@@ -63,7 +63,7 @@
    /* allocate ram for DB/mask/salt of size modulus_len */
    DB   = XMALLOC(modulus_len);
    mask = XMALLOC(modulus_len);
-   seed = XMALLOC(modulus_len);
+   seed = XMALLOC(hLen);
    if (DB == NULL || mask == NULL || seed == NULL) {
       if (DB != NULL) {
          XFREE(DB);
@@ -92,14 +92,13 @@
    }
 
    /* now read the masked seed */
-   for (x = 1, y = 0; y < hLen; y++) {
-      seed[y] = msg[x++];
-   }
+   x = 1;
+   XMEMCPY(seed, msg + x, hLen);
+   x += hLen;
 
    /* now read the masked DB */
-   for (y = 0; y < modulus_len - hLen - 1; y++) {
-      DB[y] = msg[x++];
-   }
+   XMEMCPY(DB, msg + x, modulus_len - hLen - 1);
+   x += modulus_len - hLen - 1;
 
    /* compute MGF1 of maskedDB (hLen) */ 
    if ((err = pkcs_1_mgf1(DB, modulus_len - hLen - 1, hash_idx, mask, hLen)) != CRYPT_OK) {
@@ -161,9 +160,8 @@
 
    /* copy message */
    *outlen = (modulus_len - hLen - 1) - x;
-   for (y = 0; x != (modulus_len - hLen - 1); ) {
-       out[y++] = DB[x++];
-   }
+   XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x);
+   x += modulus_len - hLen - 1;
 
    /* valid packet */
    *res = 1;
@@ -172,7 +170,7 @@
 LBL_ERR:
 #ifdef LTC_CLEAN_STACK
    zeromem(DB,   modulus_len);
-   zeromem(seed, modulus_len);
+   zeromem(seed, hLen);
    zeromem(mask, modulus_len);
 #endif
 
@@ -184,3 +182,7 @@
 }
 
 #endif /* PKCS_1 */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/06/18 02:37:06 $ */
--- a/src/pk/pkcs1/pkcs_1_oaep_encode.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_oaep_encode.c	Wed Jul 06 12:10:23 2005 +0000
@@ -66,7 +66,7 @@
    /* allocate ram for DB/mask/salt of size modulus_len */
    DB   = XMALLOC(modulus_len);
    mask = XMALLOC(modulus_len);
-   seed = XMALLOC(modulus_len);
+   seed = XMALLOC(hLen);
    if (DB == NULL || mask == NULL || seed == NULL) {
       if (DB != NULL) {
          XFREE(DB);
@@ -97,16 +97,15 @@
    /* append PS then 0x01 (to lhash)  */
    x = hLen;
    y = modulus_len - msglen - 2*hLen - 2;
-   while (y--) {
-      DB[x++] = 0x00;
-   }
+   XMEMSET(DB+x, 0, y);
+   x += y;
+
+   /* 0x01 byte */
    DB[x++] = 0x01;
 
-   /* message */
-   y = msglen;
-   while (y--) {
-     DB[x++] = *msg++;
-   }
+   /* message (length = msglen) */
+   XMEMCPY(DB+x, msg, msglen);
+   x += msglen;
 
    /* now choose a random seed */
    if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) {
@@ -143,19 +142,18 @@
    /* start output which is 0x00 || maskedSeed || maskedDB */
    x = 0;
    out[x++] = 0x00;
-   for (y = 0; y < hLen; y++) {
-      out[x++] = seed[y];
-   }
-   for (y = 0; y < modulus_len - hLen - 1; y++) {
-      out[x++] = DB[y];
-   }
+   XMEMCPY(out+x, seed, hLen);
+   x += hLen;
+   XMEMCPY(out+x, DB, modulus_len - hLen - 1);
+   x += modulus_len - hLen - 1;
+
    *outlen = x;
     
    err = CRYPT_OK;
 LBL_ERR:
 #ifdef LTC_CLEAN_STACK
    zeromem(DB,   modulus_len);
-   zeromem(seed, modulus_len);
+   zeromem(seed, hLen);
    zeromem(mask, modulus_len);
 #endif
 
@@ -168,3 +166,7 @@
 
 #endif /* PKCS_1 */
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_encode.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_os2ip.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_os2ip.c	Wed Jul 06 12:10:23 2005 +0000
@@ -35,3 +35,7 @@
 
 #endif /* PKCS_1 */
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_os2ip.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_pss_decode.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_pss_decode.c	Wed Jul 06 12:10:23 2005 +0000
@@ -87,14 +87,13 @@
    }
 
    /* copy out the DB */
-   for (x = 0; x < modulus_len - hLen - 1; x++) {
-      DB[x] = sig[x];
-   }
+   x = 0;
+   XMEMCPY(DB, sig + x, modulus_len - hLen - 1);
+   x += modulus_len - hLen - 1;
 
    /* copy out the hash */
-   for (y = 0; y < hLen; y++) {
-      hash[y] = sig[x++];
-   }
+   XMEMCPY(hash, sig + x, hLen);
+   x += hLen;
 
    /* check the MSB */
    if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
@@ -172,3 +171,7 @@
 }
 
 #endif /* PKCS_1 */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_pss_encode.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/pkcs1/pkcs_1_pss_encode.c	Wed Jul 06 12:10:23 2005 +0000
@@ -110,13 +110,12 @@
    }
 
    /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
-   for (x = 0; x < (modulus_len - saltlen - hLen - 2); x++) {
-       DB[x] = 0x00;
-   }
+   x = 0;
+   XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2);
+   x += modulus_len - saltlen - hLen - 2;
    DB[x++] = 0x01;
-   for (y = 0; y < saltlen; y++) {
-      DB[x++] = salt[y];
-   }
+   XMEMCPY(DB + x, salt, saltlen);
+   x += saltlen;
 
    /* generate mask of length modulus_len - hLen - 1 from hash */
    if ((err = pkcs_1_mgf1(hash, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) {
@@ -134,14 +133,15 @@
       goto LBL_ERR;
    }
 
-   /* DB */
-   for (y = x = 0; x < modulus_len - hLen - 1; x++) {
-       out[y++] = DB[x];
-   }
+   /* DB len = modulus_len - hLen - 1 */
+   y = 0;
+   XMEMCPY(out + y, DB, modulus_len - hLen - 1);
+   y += modulus_len - hLen - 1;
+
    /* hash */
-   for (x = 0; x < hLen; x++) {
-       out[y++] = hash[x];
-   }
+   XMEMCPY(out + y, hash, hLen);
+   y += hLen;
+
    /* 0xBC */
    out[y] = 0xBC;
 
@@ -168,3 +168,7 @@
 }
 
 #endif /* PKCS_1 */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/pkcs1/pkcs_1_v15_es_decode.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/** 
-  @file pkcs_1_v15_es_decode.c
-  PKCS #1 v1.5 Encryption Padding, Tom St Denis 
-*/
-
-#ifdef PKCS_1
-
-/**
-  PKCS #1 v1.5 Encryption Decoding
-  @param msg             The padded data
-  @param msglen          The length of the padded data (octets)
-  @param modulus_bitlen  The bit length of the RSA modulus
-  @param out             [out] Where to store the decoded data
-  @param outlen          The length of the decoded data
-  @param res             [out] Result of the decoding, 1==valid, 0==invalid
-  @return CRYPT_OK if successful
-*/
-int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
-                               unsigned long modulus_bitlen,
-                               unsigned char *out,  unsigned long outlen,
-                               int           *res)
-{
-   unsigned long x, modulus_bytelen;
-
-   LTC_ARGCHK(msg != NULL);
-   LTC_ARGCHK(out != NULL);
-   LTC_ARGCHK(res != NULL);
-   
-   /* default to failed */
-   *res = 0;
-
-   modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
-
-   /* must be at least modulus_bytelen bytes long */
-   if (msglen != modulus_bytelen) {
-      return CRYPT_INVALID_ARG;
-   }
-
-   /* should start with 0x00 0x02 */
-   if (msg[0] != 0x00 || msg[1] != 0x02) {
-      return CRYPT_OK;
-   }
-   
-   /* skip over PS */
-   x = 2 + (modulus_bytelen - outlen - 3);
-
-   /* should be 0x00 */
-   if (msg[x++] != 0x00) {
-      return CRYPT_OK;
-   }
-
-   /* the message is left */
-   if (x + outlen > modulus_bytelen) {
-      return CRYPT_PK_INVALID_SIZE;
-   }
-   XMEMCPY(out, msg + x, outlen);
-   *res = 1;
-   return CRYPT_OK;
-}
-
-#endif 
-
--- a/src/pk/pkcs1/pkcs_1_v15_es_encode.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/** 
-  @file pkcs_1_v15_es_encode.c
-  v1.5 Encryption Padding for PKCS #1, Tom St Denis 
-*/
-
-#ifdef PKCS_1
-
-/**
-  PKCS #1 v1.5 Encryption Padding
-  @param msg            The data to encode
-  @param msglen         The length of the data (octets)
-  @param modulus_bitlen The bit length of the RSA modulus
-  @param prng           An active PRNG
-  @param prng_idx       The index of the PRNG desired
-  @param out            [out] The destination of the padding
-  @param outlen         [in/out] The max size and resulting size of the padding
-  @return CRYPT_OK if successful
-*/
-int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
-                               unsigned long  modulus_bitlen, 
-                               prng_state    *prng,   int           prng_idx,
-                               unsigned char *out,    unsigned long *outlen)
-{ 
-   unsigned long modulus_bytelen, x, y;
-
-   LTC_ARGCHK(msg    != NULL);
-   LTC_ARGCHK(out    != NULL);
-   LTC_ARGCHK(outlen != NULL);
-
-   /* get modulus len */
-   modulus_bytelen = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
-   if (modulus_bytelen < 12) {
-      return CRYPT_INVALID_ARG;
-   }
-
-   /* verify length */
-   if (msglen > (modulus_bytelen - 11) || *outlen < modulus_bytelen) {
-      return CRYPT_PK_INVALID_SIZE;
-   }
-
-   /* 0x00 0x02 PS 0x00 M */
-   x = 0;
-   out[x++] = 0x00;
-   out[x++] = 0x02;
-   y = modulus_bytelen - msglen - 3;
-   if (prng_descriptor[prng_idx].read(out+x, y, prng) != y) {
-      return CRYPT_ERROR_READPRNG;
-   }
-   x += y;
-   out[x++] = 0x00;
-   XMEMCPY(out+x, msg, msglen);
-   *outlen = modulus_bytelen;
-
-   return CRYPT_OK;
-}
-
-#endif /* PKCS_1 */
--- a/src/pk/pkcs1/pkcs_1_v15_sa_decode.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/** 
-  @file pkcs_1_v15_sa_decode.c
-  PKCS #1 v1.5 Signature Padding, Tom St Denis 
-*/
-
-#ifdef PKCS_1
-
-/**
-  Perform PKCS #1 v1.5 Signature Decoding
-  @param msghash         The hash that was signed
-  @param msghashlen      The length of the hash
-  @param sig             The signature [padded data]
-  @param siglen          The length of the signature
-  @param hash_idx        The index of the hash used
-  @param modulus_bitlen  The bit length of the RSA modulus 
-  @param res             [out]  Result of comparison, 1==valid, 0==invalid
-  @return CRYPT_OK if successful
-*/
-int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
-                         const unsigned char *sig,     unsigned long siglen,
-                               int           hash_idx, unsigned long modulus_bitlen, 
-                               int          *res)
-{
-   unsigned long x, y, modulus_bytelen, derlen;
-   int err;
-   
-   LTC_ARGCHK(msghash != NULL);
-   LTC_ARGCHK(sig     != NULL);
-   LTC_ARGCHK(res     != NULL);
-
-   /* default to invalid */
-   *res = 0;
-
-   /* valid hash ? */
-   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* get derlen */
-   derlen = hash_descriptor[hash_idx].DERlen;
-
-   /* get modulus len */
-   modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
-
-   /* valid sizes? */
-   if ((msghashlen + 3 + derlen > modulus_bytelen) || (siglen != modulus_bytelen)) {
-      return CRYPT_PK_INVALID_SIZE;
-   }
-
-   /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
-   x = 0;
-   if (sig[x++] != 0x00 || sig[x++] != 0x01) {
-      return CRYPT_OK;
-   }
-
-   /* now follows (modulus_bytelen - 3 - derlen - msghashlen) 0xFF bytes */
-   for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
-     if (sig[x++] != 0xFF) {
-        return CRYPT_OK;
-     }
-   }
-
-   if (sig[x++] != 0x00) {
-      return CRYPT_OK;
-   }
-
-   for (y = 0; y < derlen; y++) {
-      if (sig[x++] != hash_descriptor[hash_idx].DER[y]) {
-         return CRYPT_OK;
-      }
-   }
-
-   if (memcmp(msghash, sig+x, msghashlen) == 0) {
-      *res = 1;
-   }
-   return CRYPT_OK;
-}
-
-#endif 
--- a/src/pk/pkcs1/pkcs_1_v15_sa_encode.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/** 
-  @file pkcs_1_v15_sa_encode.c
-  PKCS #1 v1.5 Signature Padding, Tom St Denis 
-*/
-
-#ifdef PKCS_1
-
-/**
-  Perform PKCS #1 v1.5 Signature Padding
-  @param msghash         The hash you wish to incorporate in the padding
-  @param msghashlen      The length of the hash
-  @param hash_idx        The index of the hash used
-  @param modulus_bitlen  The length of the RSA modulus that will sign this (bits)
-  @param out             [out] Where to store the padded data
-  @param outlen          [in/out] Max size and resulting size of the padded data
-  @return CRYPT_OK if successful
-*/
-int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
-                               int            hash_idx, unsigned long modulus_bitlen,
-                               unsigned char *out,      unsigned long *outlen)
-{
-  unsigned long derlen, modulus_bytelen, x, y;
-  int err;
-
-  LTC_ARGCHK(msghash != NULL)
-  LTC_ARGCHK(out     != NULL);
-  LTC_ARGCHK(outlen  != NULL);
-
-  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
-     return err;
-  }
-
-  /* hack, to detect any hash without a DER OID */
-  if (hash_descriptor[hash_idx].DERlen == 0) {
-     return CRYPT_INVALID_ARG; 
-  }
-
-  /* get modulus len */
-  modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
-
-  /* get der len ok?  Forgive my lame German accent.... */
-  derlen = hash_descriptor[hash_idx].DERlen;
-
-  /* valid sizes? */
-  if (msghashlen + 3 + derlen > modulus_bytelen) {
-     return CRYPT_PK_INVALID_SIZE;
-  }
-
-  if (*outlen < modulus_bytelen) {
-     return CRYPT_BUFFER_OVERFLOW;
-  }
-
-  /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
-  x = 0;
-  out[x++] = 0x00;
-  out[x++] = 0x01;
-  for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
-     out[x++] = 0xFF;
-  }
-  out[x++] = 0x00;
-  for (y = 0; y < derlen; y++) {
-     out[x++] = hash_descriptor[hash_idx].DER[y];
-  }
-  for (y = 0; y < msghashlen; y++) {
-     out[x++] = msghash[y];
-  }
-
-  *outlen = modulus_bytelen;
-  return CRYPT_OK;
-}
-
-#endif /* PKCS_1 */
--- a/src/pk/rsa/rsa_decrypt_key.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_decrypt_key.c	Wed Jul 06 12:10:23 2005 +0000
@@ -87,3 +87,7 @@
 
 
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_decrypt_key.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/rsa/rsa_encrypt_key.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_encrypt_key.c	Wed Jul 06 12:10:23 2005 +0000
@@ -74,3 +74,7 @@
 }
 
 #endif /* MRSA */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/rsa/rsa_export.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_export.c	Wed Jul 06 12:10:23 2005 +0000
@@ -27,7 +27,8 @@
 */    
 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
 {
-   int err, x;
+   int           err;
+   unsigned long zero=0;
 
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);
@@ -37,62 +38,39 @@
    if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) {
       return CRYPT_PK_INVALID_TYPE;
    }
-   if (*outlen < 4) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-  
-   /* Mental Note: push space for the header 0x30 0x82 LL LL (LL = length of packet EXcluding 4 bytes) 
-    * we assume LL > 255 which is true since the smallest RSA key has a 128-byte modulus (1024-bit)
-    */
-   *outlen -= 4;
 
    if (type == PK_PRIVATE) {
       /* private key */
-      mp_int zero;
-
-      /* first INTEGER == 0 to signify two-prime RSA */
-      if ((err = mp_init(&zero)) != MP_OKAY) {
-         return mpi_to_ltc_error(err);
-      }
- 
       /* output is 
             Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p
        */
-      if ((err = der_put_multi_integer(
-                          out+4, outlen, &zero, &key->N, &key->e,
-                          &key->d, &key->p, &key->q, &key->dP,
-                          &key->dQ, &key->qP, NULL)) != CRYPT_OK) {
-         mp_clear(&zero);
+      if ((err = der_encode_sequence_multi(out, outlen, 
+                          LTC_ASN1_SHORT_INTEGER, 1UL, &zero, 
+                          LTC_ASN1_INTEGER, 1UL, &key->N, 
+                          LTC_ASN1_INTEGER, 1UL, &key->e,
+                          LTC_ASN1_INTEGER, 1UL, &key->d, 
+                          LTC_ASN1_INTEGER, 1UL, &key->p, 
+                          LTC_ASN1_INTEGER, 1UL, &key->q, 
+                          LTC_ASN1_INTEGER, 1UL, &key->dP,
+                          LTC_ASN1_INTEGER, 1UL, &key->dQ, 
+                          LTC_ASN1_INTEGER, 1UL, &key->qP, 
+                          LTC_ASN1_EOL,     0UL, NULL)) != CRYPT_OK) {
          return err;
       }
  
       /* clear zero and return */
-      mp_clear(&zero);
+      return CRYPT_OK;
    } else {
       /* public key */
-      if ((err = der_put_multi_integer(out+4, outlen, &key->N, &key->e, NULL)) != CRYPT_OK) {
-         return err;
-      }
+      return der_encode_sequence_multi(out, outlen, 
+                                 LTC_ASN1_INTEGER, 1UL, &key->N, 
+                                 LTC_ASN1_INTEGER, 1UL, &key->e, 
+                                 LTC_ASN1_EOL,     0UL, NULL);
    }
-
-   /* store the header */
-   out[0] = 0x30;
-   if (*outlen < 256) {
-      /* shift the output up one byte if the header is only 3 bytes */
-      for (x = 0; x < *outlen; x++) {
-          out[x+3] = out[x+4];
-      }
-      out[1] = 0x81;
-      out[2] = (*outlen & 255);
-      *outlen += 3;
-   } else {
-      out[1] = 0x82;
-      out[2] = (*outlen >> 8) & 255;
-      out[3] = (*outlen & 255);
-      *outlen += 4;
-   }
-   return err;
 }
 
 #endif /* MRSA */
 
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_export.c,v $ */
+/* $Revision: 1.11 $ */
+/* $Date: 2005/06/04 01:42:48 $ */
--- a/src/pk/rsa/rsa_exptmod.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_exptmod.c	Wed Jul 06 12:10:23 2005 +0000
@@ -86,6 +86,12 @@
       err = CRYPT_BUFFER_OVERFLOW;
       goto done;
    }
+
+   /* this should never happen ... */
+   if (mp_unsigned_bin_size(&tmp) > mp_unsigned_bin_size(&key->N)) {
+      err = CRYPT_ERROR;
+      goto done;
+   }
    *outlen = x;
 
    /* convert it */
@@ -103,3 +109,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */
+/* $Revision: 1.4 $ */
+/* $Date: 2005/06/23 02:10:22 $ */
--- a/src/pk/rsa/rsa_free.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_free.c	Wed Jul 06 12:10:23 2005 +0000
@@ -29,3 +29,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_free.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/rsa/rsa_import.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_import.c	Wed Jul 06 12:10:23 2005 +0000
@@ -18,7 +18,7 @@
 #ifdef MRSA
 
 /**
-  Import an RSAPublicKey or RSAPrivateKey [two-prime only, defined in PKCS #1 v2.1]
+  Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1]
   @param in      The packet to import from
   @param inlen   It's length (octets)
   @param key     [out] Destination for newly imported key
@@ -26,65 +26,39 @@
 */
 int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
 {
-   unsigned long x, y;
-   int err;
+   int           err;
+   mp_int        zero;
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
 
    /* init key */
-   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
-                     &key->p, &key->q, NULL)) != MP_OKAY) {
+   if ((err = mp_init_multi(&zero, &key->e, &key->d, &key->N, &key->dQ, 
+                            &key->dP, &key->qP, &key->p, &key->q, NULL)) != MP_OKAY) {
       return mpi_to_ltc_error(err);
    }
 
-   /* check the header */
-   if (inlen < 4) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* should be 0x30 0x8{1|2} LL LL */
-   if ((in[0] != 0x30) || ((in[1] != 0x81) && (in[1] != 0x82))) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* ok all the ASN.1 params are fine so far, let's move up */
-   x = ((unsigned long)in[2]);
-   y = 0;
-   if ((in[1] & ~0x80) == 2) {
-      x   = (x << 8) + ((unsigned long)in[3]) + 1;
-      in += 1;
-      y   = 1;
-   }
-   in += 3; /* advance input */
-   x  += 3; /* size of packet according to header */
-   y  += 3; /* used input */
-
-   if (x != inlen) {
-      return CRYPT_INVALID_PACKET;
-   }
-   
-   /* decrement inlen by the header size */
-   inlen -= y;
-
-   /* read first number, it's either N or 0 [0 == private key] */
-   x = inlen;
-   if ((err = der_get_multi_integer(in, &x, &key->N, NULL)) != CRYPT_OK) {
+   if ((err = der_decode_sequence_multi(in, inlen, 
+                                  LTC_ASN1_INTEGER, 1UL, &key->N, 
+                                  LTC_ASN1_EOL,     0UL, NULL)) != CRYPT_OK) {
       goto LBL_ERR;
    }
 
-   /* advance */
-   inlen -= x;
-   in    += x;
-
    if (mp_cmp_d(&key->N, 0) == MP_EQ) {
       /* it's a private key */
-      if ((err = der_get_multi_integer(in, &inlen, &key->N, &key->e,
-                          &key->d, &key->p, &key->q, &key->dP,
-                          &key->dQ, &key->qP, NULL)) != CRYPT_OK) {
+      if ((err = der_decode_sequence_multi(in, inlen, 
+                          LTC_ASN1_INTEGER, 1UL, &zero, 
+                          LTC_ASN1_INTEGER, 1UL, &key->N, 
+                          LTC_ASN1_INTEGER, 1UL, &key->e,
+                          LTC_ASN1_INTEGER, 1UL, &key->d, 
+                          LTC_ASN1_INTEGER, 1UL, &key->p, 
+                          LTC_ASN1_INTEGER, 1UL, &key->q, 
+                          LTC_ASN1_INTEGER, 1UL, &key->dP,
+                          LTC_ASN1_INTEGER, 1UL, &key->dQ, 
+                          LTC_ASN1_INTEGER, 1UL, &key->qP, 
+                          LTC_ASN1_EOL,     0UL, NULL)) != CRYPT_OK) {
          goto LBL_ERR;
       }
-
       key->type = PK_PRIVATE;
    } else if (mp_cmp_d(&key->N, 1) == MP_EQ) {
       /* we don't support multi-prime RSA */
@@ -92,21 +66,27 @@
       goto LBL_ERR;
    } else {
       /* it's a public key and we lack e */
-      if ((err = der_get_multi_integer(in, &inlen, &key->e, NULL)) != CRYPT_OK) {
+      if ((err = der_decode_sequence_multi(in, inlen, 
+                                     LTC_ASN1_INTEGER, 1UL, &key->N, 
+                                     LTC_ASN1_INTEGER, 1UL, &key->e, 
+                                     LTC_ASN1_EOL,     0UL, NULL)) != CRYPT_OK) {
          goto LBL_ERR;
       }
 
       /* free up some ram */
       mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL);
-
       key->type = PK_PUBLIC;
    }
    return CRYPT_OK;
 LBL_ERR:
-   mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
+   mp_clear_multi(&zero, &key->d, &key->e, &key->N, &key->dQ, &key->dP,
                   &key->qP, &key->p, &key->q, NULL);
    return err;
 }
 
 #endif /* MRSA */
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */
+/* $Revision: 1.10 $ */
+/* $Date: 2005/06/03 18:48:28 $ */
--- a/src/pk/rsa/rsa_make_key.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_make_key.c	Wed Jul 06 12:10:23 2005 +0000
@@ -119,3 +119,7 @@
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_make_key.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/rsa/rsa_sign_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_sign_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -73,3 +73,7 @@
 }
 
 #endif /* MRSA */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_sign_hash.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/pk/rsa/rsa_v15_decrypt_key.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-   /* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-  @file rsa_v15_decrypt_key.c
-  RSA PKCS v1.5 Decryption, Tom St Denis
-*/  
-
-#ifdef MRSA
-
-/**
-   RSA decrypt then PKCS #1 v1.5 depad 
-   @param in        The ciphertext
-   @param inlen     The length of the ciphertext (octets)
-   @param out       [out] The plaintext
-   @param outlen    The length of the plaintext (you have to tell this function as it's not part of PKCS #1 v1.0 padding!)
-   @param stat      [out] Status of decryption, 1==valid, 0==invalid
-   @param key       The corresponding private RSA key
-   @return CRYPT_OK if successful (even if invalid)   
-*/
-int rsa_v15_decrypt_key(const unsigned char *in,     unsigned long  inlen,
-                              unsigned char *out,    unsigned long  outlen, 
-                              int           *stat,   rsa_key       *key)
-{
-  unsigned long modulus_bitlen, modulus_bytelen, x;
-  int           err;
-  unsigned char *tmp;
-  
-  LTC_ARGCHK(out    != NULL);
-  LTC_ARGCHK(key    != NULL);
-  LTC_ARGCHK(stat   != NULL);
- 
-  /* default to invalid */
-  *stat = 0;
-
-  /* get modulus len in bits */
-  modulus_bitlen = mp_count_bits(&(key->N));
-
-  /* outlen must be at least the size of the modulus */
-  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
-  if (modulus_bytelen != inlen) {
-     return CRYPT_INVALID_PACKET;
-  }
-
-  /* allocate ram */
-  tmp = XMALLOC(inlen);
-  if (tmp == NULL) {
-     return CRYPT_MEM;
-  }
-
-  /* rsa decode the packet */
-  x = inlen;
-  if ((err = rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
-     XFREE(tmp);
-     return err;
-  }
-
-  /* PKCS #1 v1.5 depad */
-  err = pkcs_1_v15_es_decode(tmp, x, modulus_bitlen, out, outlen, stat);
-  XFREE(tmp);
-  return err;
-}
-
-#endif
--- a/src/pk/rsa/rsa_v15_encrypt_key.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-  @file rsa_v15_encrypt_key.c
-  RSA PKCS v1.5 Encryption, Tom St Denis
-*/  
-
-#ifdef MRSA
-
-/** 
-   PKCS #1 v1.5 pad then encrypt
-   @param in          The plaintext
-   @param inlen       The length of the plaintext (octets)
-   @param out         [out] The ciphertext
-   @param outlen      [in/out] The max size and resulting size of the ciphertext 
-   @param prng        An active PRNG
-   @param prng_idx    The index of the desired PRNG
-   @param key         The public RSA key
-   @return CRYPT_OK if successful
-*/   
-int rsa_v15_encrypt_key(const unsigned char *in,    unsigned long  inlen,
-                              unsigned char *out,   unsigned long *outlen,
-                              prng_state    *prng,  int            prng_idx, 
-                              rsa_key       *key)
-{
-  unsigned long modulus_bitlen, modulus_bytelen, x;
-  int           err;
-  
-  LTC_ARGCHK(in     != NULL);
-  LTC_ARGCHK(out    != NULL);
-  LTC_ARGCHK(outlen != NULL);
-  LTC_ARGCHK(key    != NULL);
-  
-  /* valid prng? */
-  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
-     return err;
-  }
-  
-  /* get modulus len in bits */
-  modulus_bitlen = mp_count_bits(&(key->N));
-
-  /* outlen must be at least the size of the modulus */
-  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
-  if (modulus_bytelen > *outlen) {
-     return CRYPT_BUFFER_OVERFLOW;
-  }
-  
-  /* pad it */
-  x = *outlen;
-  if ((err = pkcs_1_v15_es_encode(in, inlen, modulus_bitlen, prng, prng_idx, out, &x)) != CRYPT_OK) {
-     return err;
-  }
-  
-  /* encrypt it */
-  return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key);
-}
-
-#endif
--- a/src/pk/rsa/rsa_v15_sign_hash.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-   @file rsa_v15_sign_hash.c
-   RSA PKCS v1.5 Signature, Tom St Denis
-*/   
-
-#ifdef MRSA
-
-/** 
-   PKCS #1 v1.5 pad then sign
-   @param in             The hash to sign
-   @param inlen          The length of the message hash (octets)
-   @param out            [out] The signature
-   @param siglen         [in/out] The max size and resulting size of the signature
-   @param hash_idx       The index of the hash desired
-   @param key            The private RSA key to perform the signature with
-   @return CRYPT_OK if successful
-*/
-int rsa_v15_sign_hash(const unsigned char *in,       unsigned long  inlen, 
-                            unsigned char *out,      unsigned long *siglen, 
-                            int            hash_idx, rsa_key       *key)
-{
-   unsigned long modulus_bitlen, modulus_bytelen, x;
-   int           err;
-   
-  LTC_ARGCHK(in  != NULL);
-  LTC_ARGCHK(out      != NULL);
-  LTC_ARGCHK(siglen   != NULL);
-  LTC_ARGCHK(key      != NULL);
-  
-  /* valid hash ? */
-  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
-     return err;
-  }
-  
-  /* get modulus len in bits */
-  modulus_bitlen = mp_count_bits(&(key->N));
-
-  /* outlen must be at least the size of the modulus */
-  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
-  if (modulus_bytelen > *siglen) {
-     return CRYPT_BUFFER_OVERFLOW;
-  }
-      
-  /* PKCS #1 v1.5 pad the key */
-  x = *siglen;
-  if ((err = pkcs_1_v15_sa_encode(in, inlen, hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) {
-     return err;
-  }
-
-  /* RSA encode it */
-  return rsa_exptmod(out, x, out, siglen, PK_PRIVATE, key);
-}
-
-#endif
--- a/src/pk/rsa/rsa_v15_verify_hash.c	Tue May 10 17:02:59 2005 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "tomcrypt.h"
-
-/**
-  @file rsa_v15_verify_hash.c
-  RSA PKCS v1.5 Signature verification, Tom St Denis
-*/  
-
-#ifdef MRSA
-
-/** 
-   RSA de-sign then PKCS v1.5 signature depad
-   @param sig           The signature data
-   @param siglen        The length of the signature (octets)
-   @param hash          The hash of the message that was signed
-   @param hashlen       The length of the hash of the message that was signed (octets)
-   @param hash_idx      The index of the desired hash
-   @param stat          [out] The result of the signature comparison, 1==valid, 0==invalid
-   @param key           The corresponding public RSA key that performed the signature
-   @return CRYPT_OK if successful (even if the signature is invalid)
-*/
-int rsa_v15_verify_hash(const unsigned char *sig,      unsigned long siglen,
-                        const unsigned char *hash,  unsigned long hashlen,
-                              int            hash_idx, int          *stat,     
-                              rsa_key       *key)
-{
-   unsigned long modulus_bitlen, modulus_bytelen, x;
-   int           err;
-   unsigned char *tmpbuf;
-   
-  LTC_ARGCHK(hash  != NULL);
-  LTC_ARGCHK(sig      != NULL);
-  LTC_ARGCHK(stat     != NULL);
-  LTC_ARGCHK(key      != NULL);
-
-  /* default to invalid */
-  *stat = 0;
-  
-  /* valid hash ? */
-  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
-     return err;
-  }
-  
-  /* get modulus len in bits */
-  modulus_bitlen = mp_count_bits(&(key->N));
-
-  /* outlen must be at least the size of the modulus */
-  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
-  if (modulus_bytelen != siglen) {
-     return CRYPT_INVALID_PACKET;
-  }
-  
-  /* allocate temp buffer for decoded sig */
-  tmpbuf = XMALLOC(siglen);
-  if (tmpbuf == NULL) {
-     return CRYPT_MEM;
-  }
-      
-  /* RSA decode it  */
-  x = siglen;
-  if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
-     XFREE(tmpbuf);
-     return err;
-  }
-  
-  /* PSS decode it */
-  err = pkcs_1_v15_sa_decode(hash, hashlen, tmpbuf, x, hash_idx, modulus_bitlen, stat);
-  XFREE(tmpbuf);
-  return err;
-}
-
-#endif
--- a/src/pk/rsa/rsa_verify_hash.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/pk/rsa/rsa_verify_hash.c	Wed Jul 06 12:10:23 2005 +0000
@@ -80,3 +80,7 @@
 }
 
 #endif /* MRSA */
+
+/* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_verify_hash.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/fortuna.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/fortuna.c	Wed Jul 06 12:10:23 2005 +0000
@@ -384,3 +384,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/fortuna.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/rc4.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/rc4.c	Wed Jul 06 12:10:23 2005 +0000
@@ -258,3 +258,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/rc4.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/rng_get_bytes.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/rng_get_bytes.c	Wed Jul 06 12:10:23 2005 +0000
@@ -138,3 +138,7 @@
 #endif
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/rng_get_bytes.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/rng_make_prng.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/rng_make_prng.c	Wed Jul 06 12:10:23 2005 +0000
@@ -63,3 +63,7 @@
    return CRYPT_OK;
 }
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/rng_make_prng.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/sober128.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/sober128.c	Wed Jul 06 12:10:23 2005 +0000
@@ -489,3 +489,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/sober128tab.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/sober128tab.c	Wed Jul 06 12:10:23 2005 +0000
@@ -2,7 +2,7 @@
    @file sober128tab.c
    SOBER-128 Tables
 */   
-/* $Id: sober128tab.c,v 1.1.1.1 2005/03/18 23:19:17 root Exp $ */
+/* $Id: sober128tab.c,v 1.2 2005/05/05 14:35:59 tom Exp $ */
 /* @(#)TuringMultab.h   1.3 (QUALCOMM) 02/09/03 */
 /* Multiplication table for Turing using 0xD02B4367 */
 static const ulong32 Multab[256] = {
@@ -72,7 +72,7 @@
     0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
 };
 
-/* $Id: sober128tab.c,v 1.1.1.1 2005/03/18 23:19:17 root Exp $ */
+/* $Id: sober128tab.c,v 1.2 2005/05/05 14:35:59 tom Exp $ */
 /* Sbox for SOBER-128 */
 /*
  * This is really the combination of two SBoxes; the least significant
@@ -156,3 +156,7 @@
     0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
     0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
 };
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128tab.c,v $ */
+/* $Revision: 1.2 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/sprng.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/sprng.c	Wed Jul 06 12:10:23 2005 +0000
@@ -130,3 +130,7 @@
 
 
  
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/sprng.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/src/prngs/yarrow.c	Tue May 10 17:02:59 2005 +0000
+++ b/src/prngs/yarrow.c	Wed Jul 06 12:10:23 2005 +0000
@@ -186,6 +186,7 @@
                         prng->yarrow.pool,       /* IV */
                         prng->yarrow.pool, ks,   /* KEY and key size */
                         0,                       /* number of rounds */
+                        CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
                         &prng->yarrow.ctr)) != CRYPT_OK) {
       return err;
    }
@@ -310,3 +311,7 @@
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testbuild.sh	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,11 @@
+#!/bin/bash
+echo "$1 (Build Only, $2, $3)..."
+make clean 1>/dev/null 2>/dev/null
+echo -n "building..."
+touch testok.txt
+CFLAGS="$2" make -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 && rm -f testok.txt && exit 1)
+if find testok.txt -type f 1>/dev/null 2>/dev/null ; then
+   echo "successful"
+   exit 0
+fi
+exit 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testme.sh	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# date
+echo "date="`date`
+
+# output version
+echo "Testing verion" `grep "^VERSION=" makefile | sed "s/.*=//"`
+#grep "VERSION=" makefile | perl -e "@a = split('=', <>); print @a[1];"`
+
+# get uname 
+echo "uname="`uname -a`
+echo
+
+# stock build
+bash run.sh "STOCK" " " $1 || exit 1
+
+# SMALL code
+bash run.sh "SMALL" "-DLTC_SMALL_CODE" $1 || exit 1
+
+# NOTABLES
+bash run.sh "NOTABLES" "-DLTC_NO_TABLES" $1 || exit 1
+
+# SMALL+NOTABLES
+bash run.sh "SMALL+NOTABLES" "-DLTC_SMALL_CODE -DLTC_NO_TABLES" $1 || exit 1
+
+# CLEANSTACK
+bash run.sh "CLEANSTACK" "-DLTC_CLEAN_STACK" $1 || exit 1
+
+# CLEANSTACK + SMALL
+bash run.sh "CLEANSTACK+SMALL" "-DLTC_SMALL_CODE -DLTC_CLEAN_STACK" $1 || exit 1
+
+# CLEANSTACK + NOTABLES
+bash run.sh "CLEANSTACK+NOTABLES" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK" $1 || exit 1
+
+# CLEANSTACK + NOTABLES + SMALL
+bash run.sh "CLEANSTACK+NOTABLES+SMALL" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK -DLTC_SMALL_CODE" $1 || exit 1
+
+# NO_FAST
+bash run.sh "NO_FAST" "-DLTC_NO_FAST" $1 || exit 1
+
+# NO_ASM
+bash run.sh "NO_ASM" "-DLTC_NO_ASM" $1 || exit 1
+
+# test build with no testing
+bash testbuild.sh "NOTEST" "-DLTC_NO_TEST" $1 || exit 1
+
+# test build with no file routines
+bash testbuild.sh "NOFILE" "-DLTC_NO_FILE" $1 || exit 1
+
+# $Source: /cvs/libtom/libtomcrypt/testme.sh,v $   
+# $Revision: 1.16 $   
+# $Date: 2005/05/11 18:59:53 $ 
--- a/testprof/base64_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/base64_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -12,9 +12,13 @@
        l2 = sizeof(tmp);
        DO(base64_decode(out, l1, tmp, &l2));
        if (l2 != x || memcmp(tmp, in, x)) {
-           printf("base64  failed %lu %lu %lu", x, l1, l2);
+           fprintf(stderr, "base64  failed %lu %lu %lu", x, l1, l2);
            return 1;
        }
    }
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/base64_test.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/21 12:51:25 $ */
--- a/testprof/cipher_hash_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/cipher_hash_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -39,3 +39,7 @@
    
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/cipher_hash_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/testprof/der_tests.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/der_tests.c	Wed Jul 06 12:10:23 2005 +0000
@@ -4,91 +4,367 @@
 
 int der_tests(void)
 {
-   printf("NOP");
+   fprintf(stderr, "NOP");
    return 0;
 }
 
 #else
 
+static int der_choice_test(void)
+{
+   ltc_asn1_list types[7], host[1];
+   unsigned char bitbuf[10], octetbuf[10], ia5buf[10], printbuf[10], outbuf[256];
+   unsigned long integer, oidbuf[10], outlen, inlen, x, y;
+   mp_int        mpinteger;
+   ltc_utctime   utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
+
+   /* setup variables */
+   for (x = 0; x < sizeof(bitbuf); x++)   { bitbuf[x]   = x & 1; }
+   for (x = 0; x < sizeof(octetbuf); x++) { octetbuf[x] = x;     }
+   for (x = 0; x < sizeof(ia5buf); x++)   { ia5buf[x]   = 'a';   }
+   for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a';   }
+   integer = 1;
+   for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++)   { oidbuf[x] = x + 1;   }
+   DO(mpi_to_ltc_error(mp_init(&mpinteger)));
+
+   for (x = 0; x < 14; x++) {
+       /* setup list */
+       LTC_SET_ASN1(types, 0, LTC_ASN1_PRINTABLE_STRING, printbuf, sizeof(printbuf));
+       LTC_SET_ASN1(types, 1, LTC_ASN1_BIT_STRING, bitbuf, sizeof(bitbuf));
+       LTC_SET_ASN1(types, 2, LTC_ASN1_OCTET_STRING, octetbuf, sizeof(octetbuf));
+       LTC_SET_ASN1(types, 3, LTC_ASN1_IA5_STRING, ia5buf, sizeof(ia5buf));
+       if (x > 7) {
+          LTC_SET_ASN1(types, 4, LTC_ASN1_SHORT_INTEGER, &integer, 1);
+       } else {
+          LTC_SET_ASN1(types, 4, LTC_ASN1_INTEGER, &mpinteger, 1);
+       }
+       LTC_SET_ASN1(types, 5, LTC_ASN1_OBJECT_IDENTIFIER, oidbuf, sizeof(oidbuf)/sizeof(oidbuf[0]));
+       LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1);
+
+       LTC_SET_ASN1(host, 0, LTC_ASN1_CHOICE, types, 7);
+
+       
+       /* encode */
+       outlen = sizeof(outbuf);
+       DO(der_encode_sequence(&types[x>6?x-7:x], 1, outbuf, &outlen));
+
+       /* decode it */
+       inlen = outlen;
+       DO(der_decode_sequence(outbuf, inlen, &host, 1));
+
+       for (y = 0; y < 7; y++) {
+           if (types[y].used && y != (x>6?x-7:x)) {
+               fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to one\n", y, x);
+               return 1;
+           }
+           if (!types[y].used && y == (x>6?x-7:x)) {
+               fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to zero\n", y, x);
+               return 1;
+           }
+      }
+  }
+  mp_clear(&mpinteger);
+  return 0;
+}
+   
+
 int der_tests(void)
 {
-   unsigned long x, y, z, zz;
-   unsigned char buf[2][4096];
+   unsigned long x, y, z, zz, oid[2][32];
+   unsigned char buf[3][2048];
    mp_int a, b, c, d, e, f, g;
 
+   static const unsigned char rsa_oid_der[] = { 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d };
+   static const unsigned long rsa_oid[]     = { 1, 2, 840, 113549 };
+
+   static const unsigned char rsa_ia5[]     = "[email protected]";
+   static const unsigned char rsa_ia5_der[] = { 0x16, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31,
+                                                0x40, 0x72, 0x73, 0x61, 0x2e, 0x63, 0x6f, 0x6d };
+
+   static const unsigned char rsa_printable[] = "Test User 1";
+   static const unsigned char rsa_printable_der[] = { 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 
+                                                      0x73, 0x65, 0x72, 0x20, 0x31 };
+
+   static const ltc_utctime   rsa_time1 = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
+   static const ltc_utctime   rsa_time2 = { 91, 5, 6, 23, 45, 40, 0, 0, 0 };
+   ltc_utctime                tmp_time;
+
+   static const unsigned char rsa_time1_der[] = { 0x17, 0x11, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x36, 0x34, 0x35, 0x34, 0x30, 0x2D, 0x30, 0x37, 0x30, 0x30 };
+   static const unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a };
+
    DO(mpi_to_ltc_error(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL)));
    for (zz = 0; zz < 16; zz++) {
       for (z = 0; z < 1024; z++) {
          if (yarrow_read(buf[0], z, &yarrow_prng) != z) {
-            printf("Failed to read %lu bytes from yarrow\n", z);
+            fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z);
             return 1;
          }
          DO(mpi_to_ltc_error(mp_read_unsigned_bin(&a, buf[0], z)));
+         if (mp_iszero(&a) == MP_NO) { a.sign = buf[0][0] & 1 ? MP_ZPOS : MP_NEG; }
          x = sizeof(buf[0]);
          DO(der_encode_integer(&a, buf[0], &x));
-         y = x;
+         DO(der_length_integer(&a, &y));
+         if (y != x) { fprintf(stderr, "DER INTEGER size mismatch\n"); return 1; }
          mp_zero(&b);
-         DO(der_decode_integer(buf[0], &y, &b));
+         DO(der_decode_integer(buf[0], y, &b));
          if (y != x || mp_cmp(&a, &b) != MP_EQ) {
-            printf("%lu: %lu vs %lu\n", z, x, y);
+            fprintf(stderr, "%lu: %lu vs %lu\n", z, x, y);
 #ifdef BN_MP_TORADIX_C
             mp_todecimal(&a, buf[0]);
             mp_todecimal(&b, buf[1]);
-            printf("a == %s\nb == %s\n", buf[0], buf[1]);
+            fprintf(stderr, "a == %s\nb == %s\n", buf[0], buf[1]);
 #endif
             mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
             return 1;
          }
       }
    }
-   
+
+/* test short integer */
+   for (zz = 0; zz < 256; zz++) {
+      for (z = 1; z < 4; z++) {
+         if (yarrow_read(buf[0], z, &yarrow_prng) != z) {
+            fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z);
+            return 1;
+         }
+         /* encode with normal */
+         DO(mpi_to_ltc_error(mp_read_unsigned_bin(&a, buf[0], z)));
+
+         x = sizeof(buf[0]);
+         DO(der_encode_integer(&a, buf[0], &x));
+
+         /* encode with short */
+         y = sizeof(buf[1]);
+         DO(der_encode_short_integer(mp_get_int(&a), buf[1], &y));
+         if (x != y || memcmp(buf[0], buf[1], x)) {
+            fprintf(stderr, "DER INTEGER short encoding failed, %lu, %lu\n", x, y);
+            for (z = 0; z < x; z++) fprintf(stderr, "%02x ", buf[0][z]); fprintf(stderr, "\n");
+            for (z = 0; z < y; z++) fprintf(stderr, "%02x ", buf[1][z]); fprintf(stderr, "\n");
+            mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
+            return 1;
+         }
+
+         /* decode it */
+         x = 0;
+         DO(der_decode_short_integer(buf[1], y, &x));
+         if (x != mp_get_int(&a)) {
+            fprintf(stderr, "DER INTEGER short decoding failed, %lu, %lu\n", x, mp_get_int(&a));
+            mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
+            return 1;
+         }
+      }
+   } 
+   mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
 
-/* test the multi */
-   mp_set(&a, 1);
-   x = sizeof(buf[0]);
-   DO(der_put_multi_integer(buf[0], &x, &a, NULL));
-   y = x;
-   mp_zero(&a);
-   DO(der_get_multi_integer(buf[0], &y, &a, NULL));   
-   if (x != y || mp_cmp_d(&a, 1)) {
-      printf("%lu, %lu, %d\n", x, y, mp_cmp_d(&a, 1));
-      mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
-      return 1;
-   }   
+   
+/* Test bit string */
+   for (zz = 1; zz < 1536; zz++) {
+       yarrow_read(buf[0], zz, &yarrow_prng);
+       for (z = 0; z < zz; z++) {
+           buf[0][z] &= 0x01;
+       }
+       x = sizeof(buf[1]);
+       DO(der_encode_bit_string(buf[0], zz, buf[1], &x));
+       DO(der_length_bit_string(zz, &y));
+       if (y != x) { 
+          fprintf(stderr, "\nDER BIT STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y);
+          return 1;
+       }
 
-   mp_set(&a, 1);
-   mp_set(&b, 2);
+       y = sizeof(buf[2]);
+       DO(der_decode_bit_string(buf[1], x, buf[2], &y));
+       if (y != zz || memcmp(buf[0], buf[2], zz)) {
+          fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz));
+          return 1;
+       }
+   }
+
+/* Test octet string */
+   for (zz = 1; zz < 1536; zz++) {
+       yarrow_read(buf[0], zz, &yarrow_prng);
+       x = sizeof(buf[1]);
+       DO(der_encode_octet_string(buf[0], zz, buf[1], &x));
+       DO(der_length_octet_string(zz, &y));
+       if (y != x) { 
+          fprintf(stderr, "\nDER OCTET STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y);
+          return 1;
+       }
+       y = sizeof(buf[2]);
+       DO(der_decode_octet_string(buf[1], x, buf[2], &y));
+       if (y != zz || memcmp(buf[0], buf[2], zz)) {
+          fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz));
+          return 1;
+       }
+   }
+
+/* test OID */
    x = sizeof(buf[0]);
-   DO(der_put_multi_integer(buf[0], &x, &a, &b, NULL));
-   y = x;
-   mp_zero(&a);
-   mp_zero(&b);
-   DO(der_get_multi_integer(buf[0], &y, &a, &b, NULL));   
-   if (x != y || mp_cmp_d(&a, 1) || mp_cmp_d(&b, 2)) {
-      printf("%lu, %lu, %d, %d\n", x, y, mp_cmp_d(&a, 1), mp_cmp_d(&b, 2));
-      mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
+   DO(der_encode_object_identifier(rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x));
+   if (x != sizeof(rsa_oid_der) || memcmp(rsa_oid_der, buf[0], x)) {
+      fprintf(stderr, "rsa_oid_der encode failed to match, %lu, ", x);
+      for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]);
+      fprintf(stderr, "\n");
+      return 1;
+   }
+
+   y = sizeof(oid[0])/sizeof(oid[0][0]);
+   DO(der_decode_object_identifier(buf[0], x, oid[0], &y));
+   if (y != sizeof(rsa_oid)/sizeof(rsa_oid[0]) || memcmp(rsa_oid, oid[0], sizeof(rsa_oid))) {
+      fprintf(stderr, "rsa_oid_der decode failed to match, %lu, ", y);
+      for (z = 0; z < y; z++) fprintf(stderr, "%lu ", oid[0][z]);
+      fprintf(stderr, "\n");
       return 1;
-   }   
+   }
+
+   /* do random strings */
+   for (zz = 0; zz < 5000; zz++) {
+       /* pick a random number of words */
+       yarrow_read(buf[0], 4, &yarrow_prng);
+       LOAD32L(z, buf[0]);
+       z = 2 + (z % ((sizeof(oid[0])/sizeof(oid[0][0])) - 2));
+       
+       /* fill them in */
+       oid[0][0] = buf[0][0] % 3;
+       oid[0][1] = buf[0][1] % 40;
+
+       for (y = 2; y < z; y++) {
+          yarrow_read(buf[0], 4, &yarrow_prng);
+          LOAD32L(oid[0][y], buf[0]);
+       }
+
+       /* encode it */
+       x = sizeof(buf[0]);
+       DO(der_encode_object_identifier(oid[0], z, buf[0], &x));
+       DO(der_length_object_identifier(oid[0], z, &y));
+       if (x != y) {
+          fprintf(stderr, "Random OID %lu test failed, length mismatch: %lu, %lu\n", z, x, y);
+          for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]);
+          return 1;
+       }
+       
+       /* decode it */
+       y = sizeof(oid[0])/sizeof(oid[0][0]);
+       DO(der_decode_object_identifier(buf[0], x, oid[1], &y));
+       if (y != z) {
+          fprintf(stderr, "Random OID %lu test failed, decode length mismatch: %lu, %lu\n", z, x, y);
+          return 1;
+       }
+       if (memcmp(oid[0], oid[1], sizeof(oid[0][0]) * z)) {
+          fprintf(stderr, "Random OID %lu test failed, decoded values wrong\n", z);
+          for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); fprintf(stderr, "\n\n Got \n\n");
+          for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[1][x]);
+          return 1;
+       }
+   }
+
+/* IA5 string */
+   x = sizeof(buf[0]);
+   DO(der_encode_ia5_string(rsa_ia5, strlen(rsa_ia5), buf[0], &x));
+   if (x != sizeof(rsa_ia5_der) || memcmp(buf[0], rsa_ia5_der, x)) {
+      fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der));
+      return 1;
+   }
+   DO(der_length_ia5_string(rsa_ia5, strlen(rsa_ia5), &y));
+   if (y != x) {
+      fprintf(stderr, "IA5 length failed to match: %lu, %lu\n", x, y);
+      return 1;
+   }
+   y = sizeof(buf[1]);
+   DO(der_decode_ia5_string(buf[0], x, buf[1], &y));
+   if (y != strlen(rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen(rsa_ia5))) {
+       fprintf(stderr, "DER IA5 failed test vector\n");
+       return 1;
+   }
 
-   mp_set(&a, 1);
-   mp_set(&b, 2);
-   mp_set(&c, 3);
+/* Printable string */
+   x = sizeof(buf[0]);
+   DO(der_encode_printable_string(rsa_printable, strlen(rsa_printable), buf[0], &x));
+   if (x != sizeof(rsa_printable_der) || memcmp(buf[0], rsa_printable_der, x)) {
+      fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der));
+      return 1;
+   }
+   DO(der_length_printable_string(rsa_printable, strlen(rsa_printable), &y));
+   if (y != x) {
+      fprintf(stderr, "printable length failed to match: %lu, %lu\n", x, y);
+      return 1;
+   }
+   y = sizeof(buf[1]);
+   DO(der_decode_printable_string(buf[0], x, buf[1], &y));
+   if (y != strlen(rsa_printable) || memcmp(buf[1], rsa_printable, strlen(rsa_printable))) {
+       fprintf(stderr, "DER printable failed test vector\n");
+       return 1;
+   }
+
+/* Test UTC time */
    x = sizeof(buf[0]);
-   DO(der_put_multi_integer(buf[0], &x, &a, &b, &c, NULL));
-   y = x;
-   mp_zero(&a);
-   mp_zero(&b);
-   mp_zero(&c);
-   DO(der_get_multi_integer(buf[0], &y, &a, &b, &c, NULL));   
-   if (x != y || mp_cmp_d(&a, 1) || mp_cmp_d(&b, 2) || mp_cmp_d(&c, 3)) {
-      printf("%lu, %lu, %d, %d, %d\n", x, y, mp_cmp_d(&a, 1), mp_cmp_d(&b, 2), mp_cmp_d(&c, 3));
-      mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
+   DO(der_encode_utctime(&rsa_time1, buf[0], &x));
+   if (x != sizeof(rsa_time1_der) || memcmp(buf[0], rsa_time1_der, x)) {
+      fprintf(stderr, "UTCTIME encode of rsa_time1 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der));
+fprintf(stderr, "\n\n");
+for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n");
+
+      return 1;
+   }
+   DO(der_length_utctime(&rsa_time1, &y));
+   if (y != x) {
+      fprintf(stderr, "UTCTIME length failed to match for rsa_time1: %lu, %lu\n", x, y);
+      return 1;
+   }
+   DO(der_decode_utctime(buf[0], &y, &tmp_time));
+   if (y != x || memcmp(&rsa_time1, &tmp_time, sizeof(ltc_utctime))) {
+      fprintf(stderr, "UTCTIME decode failed for rsa_time1: %lu %lu\n", x, y);
+fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n", 
+tmp_time.YY,
+tmp_time.MM,
+tmp_time.DD,
+tmp_time.hh,
+tmp_time.mm,
+tmp_time.ss,
+tmp_time.off_dir,
+tmp_time.off_mm,
+tmp_time.off_hh);
       return 1;
-   }   
+   }
+
+   x = sizeof(buf[0]);
+   DO(der_encode_utctime(&rsa_time2, buf[0], &x));
+   if (x != sizeof(rsa_time2_der) || memcmp(buf[0], rsa_time2_der, x)) {
+      fprintf(stderr, "UTCTIME encode of rsa_time2 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der));
+fprintf(stderr, "\n\n");
+for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n");
+
+      return 1;
+   }
+   DO(der_length_utctime(&rsa_time2, &y));
+   if (y != x) {
+      fprintf(stderr, "UTCTIME length failed to match for rsa_time2: %lu, %lu\n", x, y);
+      return 1;
+   }
+   DO(der_decode_utctime(buf[0], &y, &tmp_time));
+   if (y != x || memcmp(&rsa_time2, &tmp_time, sizeof(ltc_utctime))) {
+      fprintf(stderr, "UTCTIME decode failed for rsa_time2: %lu %lu\n", x, y);
+fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n", 
+tmp_time.YY,
+tmp_time.MM,
+tmp_time.DD,
+tmp_time.hh,
+tmp_time.mm,
+tmp_time.ss,
+tmp_time.off_dir,
+tmp_time.off_mm,
+tmp_time.off_hh);
 
 
-   mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL);
-   return 0;
+      return 1;
+   }
+
+
+
+   return der_choice_test();
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/der_tests.c,v $ */
+/* $Revision: 1.25 $ */
+/* $Date: 2005/06/20 20:37:45 $ */
--- a/testprof/dh_tests.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/dh_tests.c	Wed Jul 06 12:10:23 2005 +0000
@@ -22,11 +22,11 @@
   y = 4096;
   DO(dh_shared_secret (&userb, &usera, buf[1], &y));
   if (y != x) {
-    printf ("DH Shared keys are not same size.\n");
+    fprintf(stderr, "DH Shared keys are not same size.\n");
     return 1;
   }
   if (memcmp (buf[0], buf[1], x)) {
-    printf ("DH Shared keys not same contents.\n");
+    fprintf(stderr, "DH Shared keys not same contents.\n");
     return 1;
   }
 
@@ -41,11 +41,11 @@
   DO(dh_shared_secret (&usera, &userb, buf[2], &z));
 
   if (z != x) {
-    printf ("failed.  Size don't match?\n");
+    fprintf(stderr, "failed.  Size don't match?\n");
     return 1;
   }
   if (memcmp (buf[0], buf[2], x)) {
-    printf ("Failed.  Content didn't match.\n");
+    fprintf(stderr, "Failed.  Content didn't match.\n");
     return 1;
   }
   dh_free (&usera);
@@ -62,12 +62,12 @@
   x = sizeof (buf[0]);
   DO(dh_decrypt_key (buf[1], y, buf[0], &x, &usera));
   if (x != 16) {
-    printf ("Failed (length)\n");
+    fprintf(stderr, "Failed (length)\n");
     return 1;
   }
   for (x = 0; x < 16; x++)
     if (buf[0][x] != x) {
-      printf ("Failed (contents)\n");
+      fprintf(stderr, "Failed (contents)\n");
       return 1;
     }
 
@@ -81,7 +81,7 @@
   buf[0][0] ^= 1;
   DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
   if (!(stat == 1 && stat2 == 0)) { 
-     printf("dh_sign/verify_hash %d %d", stat, stat2);
+     fprintf(stderr, "dh_sign/verify_hash %d %d", stat, stat2);
      return 1;
   }
   dh_free (&usera);
@@ -92,8 +92,12 @@
 
 int dh_tests(void)
 {
-   printf("NOP");
+   fprintf(stderr, "NOP");
    return 0;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/dh_tests.c,v $ */
+/* $Revision: 1.5 $ */
+/* $Date: 2005/05/21 12:51:25 $ */
--- a/testprof/dsa_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/dsa_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -14,7 +14,7 @@
 
    /* verify it */
    DO(dsa_verify_key(&key, &stat1));
-   if (stat1 == 0) { printf("dsa_verify_key "); return 1; }
+   if (stat1 == 0) { fprintf(stderr, "dsa_verify_key "); return 1; }
 
    /* sign the message */
    x = sizeof(out);
@@ -27,7 +27,7 @@
    msg[0] ^= 1;
    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key));
    msg[0] ^= 1;
-   if (!(stat1 == 1 && stat2 == 0)) { printf("dsa_verify %d %d", stat1, stat2); return 1; }
+   if (!(stat1 == 1 && stat2 == 0)) { fprintf(stderr, "dsa_verify %d %d", stat1, stat2); return 1; }
 
    /* test exporting it */
    x = sizeof(out2);
@@ -36,16 +36,17 @@
 
    /* verify a signature with it */
    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
-   if (stat1 == 0) { printf("dsa_verify (import private) %d ", stat1); return 1; }
+   if (stat1 == 0) { fprintf(stderr, "dsa_verify (import private) %d ", stat1); return 1; }
    dsa_free(&key2);
 
    /* export as public now */
    x = sizeof(out2);
    DO(dsa_export(out2, &x, PK_PUBLIC, &key));
+
    DO(dsa_import(out2, x, &key2));
    /* verify a signature with it */
    DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
-   if (stat1 == 0) { printf("dsa_verify (import public) %d ", stat1); return 1; }
+   if (stat1 == 0) { fprintf(stderr, "dsa_verify (import public) %d ", stat1); return 1; }
    dsa_free(&key2);
    dsa_free(&key);
 
@@ -56,8 +57,12 @@
 
 int dsa_test(void)
 {
-  printf("NOP");
+  fprintf(stderr, "NOP");
   return 0;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/dsa_test.c,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/06/03 19:24:32 $ */
--- a/testprof/ecc_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/ecc_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -2,102 +2,123 @@
 
 #ifdef MECC
 
+static int sizes[] = {
+#ifdef ECC192
+24,
+#endif
+#ifdef ECC224
+28,
+#endif
+#ifdef ECC256
+32,
+#endif
+#ifdef ECC384
+48,
+#endif
+#ifdef ECC512
+65
+#endif
+};
+
 int ecc_tests (void)
 {
   unsigned char buf[4][4096];
-  unsigned long x, y, z;
+  unsigned long x, y, z, s;
   int           stat, stat2;
   ecc_key usera, userb, pubKey, privKey;
 	
   DO(ecc_test ());
 
-  /* make up two keys */
-  DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &usera));
-  DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &userb));
+  for (s = 0; s < (int)(sizeof(sizes)/sizeof(sizes[0])); s++) {
+     /* make up two keys */
+     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
+     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb));
 
-  /* make the shared secret */
-  x = 4096;
-  DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
+     /* make the shared secret */
+     x = 4096;
+     DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
 
-  y = 4096;
-  DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
+     y = 4096;
+     DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
 
-  if (y != x) {
-    printf ("ecc Shared keys are not same size.");
-    return 1;
-  }
+     if (y != x) {
+       fprintf(stderr, "ecc Shared keys are not same size.");
+       return 1;
+     }
 
-  if (memcmp (buf[0], buf[1], x)) {
-    printf ("ecc Shared keys not same contents.");
-    return 1;
-  }
+     if (memcmp (buf[0], buf[1], x)) {
+       fprintf(stderr, "ecc Shared keys not same contents.");
+       return 1;
+     }
 
-  /* now export userb */
-  y = 4096;
-  DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
-  ecc_free (&userb);
+     /* now export userb */
+     y = 4096;
+     DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
+     ecc_free (&userb);
 
-  /* import and make the shared secret again */
-  DO(ecc_import (buf[1], y, &userb));
+     /* import and make the shared secret again */
+     DO(ecc_import (buf[1], y, &userb));
 
-  z = 4096;
-  DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
+     z = 4096;
+     DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
 
-  if (z != x) {
-    printf ("failed.  Size don't match?");
-    return 1;
-  }
-  if (memcmp (buf[0], buf[2], x)) {
-    printf ("Failed.  Content didn't match.");
-    return 1;
-  }
-  ecc_free (&usera);
-  ecc_free (&userb);
+     if (z != x) {
+       fprintf(stderr, "failed.  Size don't match?");
+       return 1;
+     }
+     if (memcmp (buf[0], buf[2], x)) {
+       fprintf(stderr, "Failed.  Contents didn't match.");
+       return 1;
+     }
+     ecc_free (&usera);
+     ecc_free (&userb);
 
-/* test encrypt_key */
-  DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &usera));
+     /* test encrypt_key */
+     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
+
+     /* export key */
+     x = sizeof(buf[0]);
+     DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera));
+     DO(ecc_import(buf[0], x, &pubKey));
+     x = sizeof(buf[0]);
+     DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera));
+     DO(ecc_import(buf[0], x, &privKey));
 
-/* export key */
-  x = sizeof(buf[0]);
-  DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera));
-  DO(ecc_import(buf[0], x, &pubKey));
-  x = sizeof(buf[0]);
-  DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera));
-  DO(ecc_import(buf[0], x, &privKey));
-
-  for (x = 0; x < 32; x++) {
-    buf[0][x] = x;
+     for (x = 0; x < 32; x++) {
+        buf[0][x] = x;
+     }
+     y = sizeof (buf[1]);
+     DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey));
+     zeromem (buf[0], sizeof (buf[0]));
+     x = sizeof (buf[0]);
+     DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey));
+     if (x != 32) {
+       fprintf(stderr, "Failed (length)");
+       return 1;
+     }
+     for (x = 0; x < 32; x++) {
+        if (buf[0][x] != x) {
+           fprintf(stderr, "Failed (contents)");
+           return 1;
+        }
+     }
+     /* test sign_hash */
+     for (x = 0; x < 16; x++) {
+        buf[0][x] = x;
+     }
+     x = sizeof (buf[1]);
+     DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey));
+     DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey));
+     buf[0][0] ^= 1;
+     DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey));
+     if (!(stat == 1 && stat2 == 0)) { 
+        fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2);
+        return 1;
+     }
+     ecc_free (&usera); 
+     ecc_free (&pubKey);
+     ecc_free (&privKey);
   }
-  y = sizeof (buf[1]);
-  DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey));
-  zeromem (buf[0], sizeof (buf[0]));
-  x = sizeof (buf[0]);
-  DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey));
-  if (x != 32) {
-    printf ("Failed (length)");
-    return 1;
-  }
-  for (x = 0; x < 32; x++)
-    if (buf[0][x] != x) {
-      printf ("Failed (contents)");
-      return 1;
-    }
-/* test sign_hash */
-  for (x = 0; x < 16; x++) {
-    buf[0][x] = x;
-  }
-  x = sizeof (buf[1]);
-  DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey));
-  DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey));
-  buf[0][0] ^= 1;
-  DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey));
-  if (!(stat == 1 && stat2 == 0)) { 
-    printf("ecc_verify_hash failed %d, %d, ", stat, stat2);
-    return 1;
-  }
-  ecc_free (&usera); 
-  ecc_free (&pubKey);
-  ecc_free (&privKey);
   return 0;
 }
 
@@ -105,8 +126,12 @@
 
 int ecc_tests(void)
 {
-   printf("NOP");
+   fprintf(stderr, "NOP");
    return 0;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/ecc_test.c,v $ */
+/* $Revision: 1.9 $ */
+/* $Date: 2005/06/14 19:43:29 $ */
--- a/testprof/mac_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/mac_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -29,3 +29,7 @@
 #endif
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/mac_test.c,v $ */
+/* $Revision: 1.3 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/testprof/makefile.icc	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/makefile.icc	Wed Jul 06 12:10:23 2005 +0000
@@ -1,4 +1,4 @@
-CFLAGS += -I../src/headers -I./ -O3 -xP -ip 
+CFLAGS += -I../src/headers -I./ 
 CC=icc
 
 OBJECTS = base64_test.o cipher_hash_test.o der_tests.o dh_tests.o                        \
--- a/testprof/modes_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/modes_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -19,7 +19,7 @@
    /* get idx of AES handy */
    cipher_idx = find_cipher("aes");
    if (cipher_idx == -1) {
-      printf("test requires AES");
+      fprintf(stderr, "test requires AES");
       return 1;
    }
    
@@ -30,7 +30,7 @@
    l = sizeof(iv2);
    DO(cbc_getiv(iv2, &l, &cbc));
    if (l != 16 || memcmp(iv2, iv, 16)) {
-      printf("cbc_getiv failed");
+      fprintf(stderr, "cbc_getiv failed");
       return 1;
    }
    DO(cbc_encrypt(pt, ct, 64, &cbc));
@@ -40,7 +40,7 @@
    zeromem(tmp, sizeof(tmp));
    DO(cbc_decrypt(ct, tmp, 64, &cbc));
    if (memcmp(tmp, pt, 64) != 0) {
-      printf("CBC failed");
+      fprintf(stderr, "CBC failed");
       return 1;
    }
 #endif
@@ -53,7 +53,7 @@
    DO(cfb_getiv(iv2, &l, &cfb));
    /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */
    if (l != 16) {
-      printf("cfb_getiv failed");
+      fprintf(stderr, "cfb_getiv failed");
       return 1;
    }
    DO(cfb_encrypt(pt, ct, 64, &cfb));
@@ -63,7 +63,7 @@
    zeromem(tmp, sizeof(tmp));
    DO(cfb_decrypt(ct, tmp, 64, &cfb));
    if (memcmp(tmp, pt, 64) != 0) {
-      printf("CFB failed");
+      fprintf(stderr, "CFB failed");
       return 1;
    }
 #endif
@@ -75,7 +75,7 @@
    l = sizeof(iv2);
    DO(ofb_getiv(iv2, &l, &ofb));
    if (l != 16 || memcmp(iv2, iv, 16)) {
-      printf("ofb_getiv failed");
+      fprintf(stderr, "ofb_getiv failed");
       return 1;
    }
    DO(ofb_encrypt(pt, ct, 64, &ofb));
@@ -85,7 +85,7 @@
    zeromem(tmp, sizeof(tmp));
    DO(ofb_decrypt(ct, tmp, 64, &ofb));
    if (memcmp(tmp, pt, 64) != 0) {
-      printf("OFB failed");
+      fprintf(stderr, "OFB failed");
       return 1;
    }
 #endif
@@ -93,11 +93,11 @@
 #ifdef CTR   
    /* test CTR mode */
    /* encode the block */
-   DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr));
+   DO(ctr_start(cipher_idx, iv, key, 16, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr));
    l = sizeof(iv2);
    DO(ctr_getiv(iv2, &l, &ctr));
    if (l != 16 || memcmp(iv2, iv, 16)) {
-      printf("ctr_getiv failed");
+      fprintf(stderr, "ctr_getiv failed");
       return 1;
    }
    DO(ctr_encrypt(pt, ct, 57, &ctr));
@@ -107,10 +107,14 @@
    zeromem(tmp, sizeof(tmp));
    DO(ctr_decrypt(ct, tmp, 57, &ctr));
    if (memcmp(tmp, pt, 57) != 0) {
-      printf("CTR failed");
+      fprintf(stderr, "CTR failed");
       return 1;
    }
 #endif
          
    return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/modes_test.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/21 12:51:25 $ */
--- a/testprof/pkcs_1_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/pkcs_1_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -14,7 +14,7 @@
    prng_idx = find_prng("yarrow");
    
    if (hash_idx == -1 || prng_idx == -1) {
-      printf("pkcs_1 tests require sha1/yarrow");
+      fprintf(stderr, "pkcs_1 tests require sha1/yarrow");
       return 1;
    }   
 
@@ -29,30 +29,6 @@
       /* random modulus len (v1.5 must be multiple of 8 though arbitrary sizes seem to work) */
       modlen = 800 + 8 * (abs(rand()) % 28);
 
-      /* PKCS v1.5 testing (encryption) */
-      l1 = sizeof(buf[1]);
-      DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &yarrow_prng, prng_idx, buf[1], &l1));
-      DO(pkcs_1_v15_es_decode(buf[1], l1, modlen, buf[2], l3, &res1));
-      if (res1 != 1 || memcmp(buf[0], buf[2], l3)) {
-         printf("pkcs v1.5 encrypt failed %d, %lu, %lu ", res1, l1, l3);
-         return 1;
-      }
-
-      /* PKCS v1.5 testing (signatures) */
-      l1 = sizeof(buf[1]);
-      DO(pkcs_1_v15_sa_encode(buf[0], l3, hash_idx, modlen, buf[1], &l1));
-      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res1));
-      buf[0][i1 = abs(rand()) % l3] ^= 1;
-      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res2));
-      buf[0][i1] ^= 1;
-      buf[1][i2 = abs(rand()) % l1] ^= 1;
-      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res3));
-
-      if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
-         printf("pkcs v1.5 sign failed %d %d %d ", res1, res2, res3);
-         return 1;
-      }
-
       /* pick a random lparam len [0..16] */
       lparamlen = abs(rand()) % 17;
 
@@ -71,16 +47,16 @@
       DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1));
 
       if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
-         printf("Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
-         printf("ORIGINAL:\n");
+         fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
+         fprintf(stderr, "ORIGINAL:\n");
          for (x = 0; x < l3; x++) {
-             printf("%02x ", buf[0][x]);
+             fprintf(stderr, "%02x ", buf[0][x]);
          }
-         printf("\nRESULT:\n");
+         fprintf(stderr, "\nRESULT:\n");
          for (x = 0; x < l2; x++) {
-             printf("%02x ", buf[2][x]);
+             fprintf(stderr, "%02x ", buf[2][x]);
          }
-         printf("\n\n");
+         fprintf(stderr, "\n\n");
          return 1;
       }
 
@@ -97,7 +73,7 @@
       DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3));
 
       if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
-         printf("PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);
+         fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);
          return 1;
       }
    }
@@ -108,9 +84,13 @@
 
 int pkcs_1_test(void)
 {
-   printf("NOP");
+   fprintf(stderr, "NOP");
    return 0;
 }
 
 #endif
 
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/pkcs_1_test.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/21 12:51:25 $ */
--- a/testprof/rsa_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/rsa_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -4,18 +4,125 @@
 
 #define RSA_MSGSIZE 78
 
+/* These are test keys [see file test.key] that I use to test my import/export against */
+static const unsigned char openssl_private_rsa[] = {
+   0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 
+   0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, 
+   0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, 
+   0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, 
+   0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, 
+   0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, 
+   0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, 
+   0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 
+   0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, 
+   0x02, 0x81, 0x81, 0x00, 0xc8, 0x62, 0xb9, 0xea, 0xde, 0x44, 0x53, 0x1d, 0x56, 0x97, 0xd9, 0x97, 
+   0x9e, 0x1a, 0xcf, 0x30, 0x1e, 0x0a, 0x88, 0x45, 0x86, 0x29, 0x30, 0xa3, 0x4d, 0x9f, 0x61, 0x65, 
+   0x73, 0xe0, 0xd6, 0x87, 0x8f, 0xb6, 0xf3, 0x06, 0xa3, 0x82, 0xdc, 0x7c, 0xac, 0xfe, 0x9b, 0x28, 
+   0x9a, 0xae, 0xfd, 0xfb, 0xfe, 0x2f, 0x0e, 0xd8, 0x97, 0x04, 0xe3, 0xbb, 0x1f, 0xd1, 0xec, 0x0d, 
+   0xba, 0xa3, 0x49, 0x7f, 0x47, 0xac, 0x8a, 0x44, 0x04, 0x7e, 0x86, 0xb7, 0x39, 0x42, 0x3f, 0xad, 
+   0x1e, 0xb7, 0x0e, 0xa5, 0x51, 0xf4, 0x40, 0x63, 0x1e, 0xfd, 0xbd, 0xea, 0x9f, 0x41, 0x9f, 0xa8, 
+   0x90, 0x1d, 0x6f, 0x0a, 0x5a, 0x95, 0x13, 0x11, 0x0d, 0x80, 0xaf, 0x5f, 0x64, 0x98, 0x8a, 0x2c, 
+   0x78, 0x68, 0x65, 0xb0, 0x2b, 0x8b, 0xa2, 0x53, 0x87, 0xca, 0xf1, 0x64, 0x04, 0xab, 0xf2, 0x7b, 
+   0xdb, 0x83, 0xc8, 0x81, 0x02, 0x41, 0x00, 0xf7, 0xbe, 0x5e, 0x23, 0xc3, 0x32, 0x3f, 0xbf, 0x8b, 
+   0x8e, 0x3a, 0xee, 0xfc, 0xfc, 0xcb, 0xe5, 0xf7, 0xf1, 0x0b, 0xbc, 0x42, 0x82, 0xae, 0xd5, 0x7a, 
+   0x3e, 0xca, 0xf7, 0xd5, 0x69, 0x3f, 0x64, 0x25, 0xa2, 0x1f, 0xb7, 0x75, 0x75, 0x05, 0x92, 0x42, 
+   0xeb, 0xb8, 0xf1, 0xf3, 0x0a, 0x05, 0xe3, 0x94, 0xd1, 0x55, 0x78, 0x35, 0xa0, 0x36, 0xa0, 0x9b, 
+   0x7c, 0x92, 0x84, 0x6c, 0xdd, 0xdc, 0x4d, 0x02, 0x41, 0x00, 0xd6, 0x86, 0x0e, 0x85, 0x42, 0x0b, 
+   0x04, 0x08, 0x84, 0x21, 0x60, 0xf0, 0x0e, 0x0d, 0x88, 0xfd, 0x1e, 0x36, 0x10, 0x65, 0x4f, 0x1e, 
+   0x53, 0xb4, 0x08, 0x72, 0x80, 0x5c, 0x3f, 0x59, 0x66, 0x17, 0xe6, 0x98, 0xf2, 0xe9, 0x6c, 0x7a, 
+   0x06, 0x4c, 0xac, 0x76, 0x3d, 0xed, 0x8c, 0xa1, 0xce, 0xad, 0x1b, 0xbd, 0xb4, 0x7d, 0x28, 0xbc, 
+   0xe3, 0x0e, 0x38, 0x8d, 0x99, 0xd8, 0x05, 0xb5, 0xa3, 0x71, 0x02, 0x40, 0x6d, 0xeb, 0xc3, 0x2d, 
+   0x2e, 0xf0, 0x5e, 0xa4, 0x88, 0x31, 0x05, 0x29, 0x00, 0x8a, 0xd1, 0x95, 0x29, 0x9b, 0x83, 0xcf, 
+   0x75, 0xdb, 0x31, 0xe3, 0x7a, 0x27, 0xde, 0x3a, 0x74, 0x30, 0x0c, 0x76, 0x4c, 0xd4, 0x50, 0x2a, 
+   0x40, 0x2d, 0x39, 0xd9, 0x99, 0x63, 0xa9, 0x5d, 0x80, 0xae, 0x53, 0xca, 0x94, 0x3f, 0x05, 0x23, 
+   0x1e, 0xf8, 0x05, 0x04, 0xe1, 0xb8, 0x35, 0xf2, 0x17, 0xb3, 0xa0, 0x89, 0x02, 0x41, 0x00, 0xab, 
+   0x90, 0x88, 0xfa, 0x60, 0x08, 0x29, 0x50, 0x9a, 0x43, 0x8b, 0xa0, 0x50, 0xcc, 0xd8, 0x5a, 0xfe, 
+   0x97, 0x64, 0x63, 0x71, 0x74, 0x22, 0xa3, 0x20, 0x02, 0x5a, 0xcf, 0xeb, 0xc6, 0x16, 0x95, 0x54, 
+   0xd1, 0xcb, 0xab, 0x8d, 0x1a, 0xc6, 0x00, 0xfa, 0x08, 0x92, 0x9c, 0x71, 0xd5, 0x52, 0x52, 0x35, 
+   0x96, 0x71, 0x4b, 0x8b, 0x92, 0x0c, 0xd0, 0xe9, 0xbf, 0xad, 0x63, 0x0b, 0xa5, 0xe9, 0xb1, 0x02, 
+   0x41, 0x00, 0xdc, 0xcc, 0x27, 0xc8, 0xe4, 0xdc, 0x62, 0x48, 0xd5, 0x9b, 0xaf, 0xf5, 0xab, 0x60, 
+   0xf6, 0x21, 0xfd, 0x53, 0xe2, 0xb7, 0x5d, 0x09, 0xc9, 0x1a, 0xa1, 0x04, 0xa9, 0xfc, 0x61, 0x2c, 
+   0x5d, 0x04, 0x58, 0x3a, 0x5a, 0x39, 0xf1, 0x4a, 0x21, 0x56, 0x67, 0xfd, 0xcc, 0x20, 0xa3, 0x8f, 
+   0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e, 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17, 
+   0x4a, 0x9f,  };
+
+
+/*** NOTE:  OpenSSL seems to have more to their public key format.  I've stripped the extra headers... */
+static const unsigned char openssl_public_rsa[] = {
+   0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 
+   0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 
+   0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 
+   0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 
+   0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 
+   0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 
+   0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 
+   0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 
+   0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 
+   0x00, 0x01,  };
+
+static int rsa_compat_test(void)
+{
+   rsa_key key;
+   unsigned char buf[1024];
+   unsigned long len;
+
+   /* try reading the key */
+   DO(rsa_import(openssl_private_rsa, sizeof(openssl_private_rsa), &key));
+
+   /* now try to export private/public and compare */
+   len = sizeof(buf);
+   DO(rsa_export(buf, &len, PK_PRIVATE, &key));
+   if (len != sizeof(openssl_private_rsa) || memcmp(buf, openssl_private_rsa, len)) {
+      fprintf(stderr, "RSA private export failed to match OpenSSL output, %lu, %lu\n", len, sizeof(openssl_private_rsa));
+
+
+{
+int x;
+printf("\n\n");
+for (x = 0; x < len; ) { if (buf[x] == openssl_private_rsa[x]) printf("-- "); else printf("%02x ", buf[x]^openssl_private_rsa[x]); if (!(++x & 15)) printf("\n"); }
+}
+printf("\n\n");
+
+      return 1;
+   }
+
+   len = sizeof(buf);
+   DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+   if (len != sizeof(openssl_public_rsa) || memcmp(buf, openssl_public_rsa, len)) {
+      fprintf(stderr, "RSA(private) public export failed to match OpenSSL output\n");
+      return 1;
+   }
+   rsa_free(&key);
+
+   /* try reading the public key */
+   DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key));
+   len = sizeof(buf);
+   DO(rsa_export(buf, &len, PK_PUBLIC, &key));
+   if (len != sizeof(openssl_public_rsa) || memcmp(buf, openssl_public_rsa, len)) {
+      fprintf(stderr, "RSA(public) public export failed to match OpenSSL output\n");
+      return 1;
+   }
+   rsa_free(&key);
+
+   return 0;
+}   
+
 int rsa_test(void)
 {
    unsigned char in[1024], out[1024], tmp[1024];
    rsa_key       key, privKey, pubKey;
-   int           hash_idx, prng_idx, stat, stat2, cnt;
-   unsigned long rsa_msgsize, len, len2;
+   int           hash_idx, prng_idx, stat, stat2;
+   unsigned long rsa_msgsize, len, len2, cnt;
    static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
+
+   if (rsa_compat_test() != 0) {
+      return 1;
+   }
       
    hash_idx = find_hash("sha1");
    prng_idx = find_prng("yarrow");
    if (hash_idx == -1 || prng_idx == -1) {
-      printf("rsa_test requires SHA1 and yarrow");
+      fprintf(stderr, "rsa_test requires SHA1 and yarrow");
       return 1;
    }
    
@@ -23,32 +130,32 @@
    for (cnt = 0; cnt < 10; cnt++) {
       DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key));
       if (mp_count_bits(&key.N) != 1024) {
-         printf("rsa_1024 key modulus has %d bits\n", mp_count_bits(&key.N));
+         fprintf(stderr, "rsa_1024 key modulus has %d bits\n", mp_count_bits(&key.N));
 
 len = mp_unsigned_bin_size(&key.N);
 mp_to_unsigned_bin(&key.N, tmp);
-printf("N == \n");
+ fprintf(stderr, "N == \n");
 for (cnt = 0; cnt < len; ) {
-   printf("%02x ", tmp[cnt]);
-   if (!(++cnt & 15)) printf("\n");
+   fprintf(stderr, "%02x ", tmp[cnt]);
+   if (!(++cnt & 15)) fprintf(stderr, "\n");
 }
 
 len = mp_unsigned_bin_size(&key.p);
 mp_to_unsigned_bin(&key.p, tmp);
-printf("p == \n");
+ fprintf(stderr, "p == \n");
 for (cnt = 0; cnt < len; ) {
-   printf("%02x ", tmp[cnt]);
-   if (!(++cnt & 15)) printf("\n");
+   fprintf(stderr, "%02x ", tmp[cnt]);
+   if (!(++cnt & 15)) fprintf(stderr, "\n");
 }
 
 len = mp_unsigned_bin_size(&key.q);
 mp_to_unsigned_bin(&key.q, tmp);
-printf("\nq == \n");
+ fprintf(stderr, "\nq == \n");
 for (cnt = 0; cnt < len; ) {
-   printf("%02x ", tmp[cnt]);
-   if (!(++cnt & 15)) printf("\n");
+   fprintf(stderr, "%02x ", tmp[cnt]);
+   if (!(++cnt & 15)) fprintf(stderr, "\n");
 }
-printf("\n");
+ fprintf(stderr, "\n");
 
 
          return 1;
@@ -57,38 +164,7 @@
          rsa_free(&key);
       }
    }
-   
-   /* test PKCS #1 v1.5 */
-   for (cnt = 0; cnt < 4; cnt++) {
-   for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) {
-      /* make a random key/msg */
-      yarrow_read(in, rsa_msgsize, &yarrow_prng);
-
-      len  = sizeof(out);
-      len2 = rsa_msgsize;
-
-      /* encrypt */
-      DO(rsa_v15_encrypt_key(in, rsa_msgsize, out, &len, &yarrow_prng, prng_idx, &key));
-      DO(rsa_v15_decrypt_key(out, len, tmp, rsa_msgsize, &stat, &key));
-      if (stat != 1 || memcmp(tmp, in, rsa_msgsize)) {
-         printf("PKCS #1 v1.5 encrypt/decrypt failure (rsa_msgsize: %lu, stat: %d)\n", rsa_msgsize, stat);
-         return 1;
-      }
-   }
-   }
-
-   /* signature */
-   len = sizeof(out);
-   DO(rsa_v15_sign_hash(in, 20, out, &len, hash_idx, &key));
-   in[1] ^= 1;
-   DO(rsa_v15_verify_hash(out, len, in, 20, hash_idx, &stat, &key));
-   in[1] ^= 1;
-   DO(rsa_v15_verify_hash(out, len, in, 20, hash_idx, &stat2, &key));
-   if (!(stat == 0 && stat2 == 1)) {
-      printf("PKCS #1 v1.5 sign/verify failure (stat %d, stat2 %d)\n", stat, stat2);
-      return 1;
-   }
-   
+    
    /* encrypt the key (without lparam) */
    for (cnt = 0; cnt < 4; cnt++) {
    for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) {
@@ -105,35 +181,35 @@
       /* change a byte back */
       out[8] ^= 1;
       if (len2 != rsa_msgsize) {
-         printf("\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2);
+         fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2);
          return 1;
       }
 
       len2 = rsa_msgsize;
       DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key));
       if (!(stat == 1 && stat2 == 0)) {
-         printf("rsa_decrypt_key failed");
+         fprintf(stderr, "rsa_decrypt_key failed");
          return 1;
       }
       if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) {
          unsigned long x;
-         printf("\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2);
-         printf("Original contents: \n"); 
+         fprintf(stderr, "\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2);
+         fprintf(stderr, "Original contents: \n"); 
          for (x = 0; x < rsa_msgsize; ) {
-             printf("%02x ", in[x]);
+             fprintf(stderr, "%02x ", in[x]);
              if (!(++x % 16)) {
-                printf("\n");
+                fprintf(stderr, "\n");
              }
          }
-         printf("\n");
-         printf("Output contents: \n"); 
+         fprintf(stderr, "\n");
+         fprintf(stderr, "Output contents: \n"); 
          for (x = 0; x < rsa_msgsize; ) {
-             printf("%02x ", out[x]);
+             fprintf(stderr, "%02x ", out[x]);
              if (!(++x % 16)) {
-                printf("\n");
+                fprintf(stderr, "\n");
              }
          }     
-         printf("\n");
+         fprintf(stderr, "\n");
          return 1;
       }
    }
@@ -148,7 +224,7 @@
       out[8] ^= 1;
       DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key));
       if (len2 != rsa_msgsize) {
-         printf("\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2);
+         fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2);
          return 1;
       }
       /* change a byte back */
@@ -157,11 +233,11 @@
       len2 = rsa_msgsize;
       DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key));
       if (!(stat == 1 && stat2 == 0)) {
-         printf("rsa_decrypt_key failed");
+         fprintf(stderr, "rsa_decrypt_key failed");
          return 1;
       }
       if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) {
-         printf("rsa_decrypt_key mismatch len %lu", len2);
+         fprintf(stderr, "rsa_decrypt_key mismatch len %lu", len2);
          return 1;
       }
    }
@@ -185,7 +261,7 @@
    DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key));
    
    if (!(stat == 1 && stat2 == 0)) {
-      printf("rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2);
+      fprintf(stderr, "rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2);
       rsa_free(&key);
       rsa_free(&pubKey);
       rsa_free(&privKey);
@@ -201,7 +277,7 @@
    DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey));
    
    if (!(stat == 1 && stat2 == 0)) {
-      printf("rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2);
+      fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2);
       rsa_free(&key);
       rsa_free(&pubKey);
       rsa_free(&privKey);
@@ -217,7 +293,7 @@
    DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey));
    
    if (!(stat == 1 && stat2 == 0)) {
-      printf("rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2);
+      fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2);
       rsa_free(&key);
       rsa_free(&pubKey);
       rsa_free(&privKey);
@@ -233,7 +309,7 @@
    DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey));
    
    if (!(stat == 1 && stat2 == 0)) {
-      printf("rsa_verify_hash (salted) failed, %d, %d", stat, stat2);
+      fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2);
       rsa_free(&key);
       rsa_free(&pubKey);
       rsa_free(&privKey);
@@ -251,8 +327,12 @@
 
 int rsa_test(void)
 {
-   printf("NOP");
+   fprintf(stderr, "NOP");
    return 0;
 }
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/rsa_test.c,v $ */
+/* $Revision: 1.10 $ */
+/* $Date: 2005/06/03 19:18:33 $ */
--- a/testprof/store_test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/store_test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -3,13 +3,17 @@
 /* Test store/load macros with offsets */
 int store_test(void)
 {
-  unsigned char buf[24];
+  unsigned char buf[256];
   int y;
   ulong32 L, L1;
   ulong64 LL, LL1;
+#ifdef LTC_FAST
+  int x, z;
+#endif
 
-  L = 0x12345678UL;
   for (y = 0; y < 4; y++) {
+      L  = 0x12345678UL;
+      L1 = 0;
       STORE32L(L, buf + y);
       LOAD32L(L1, buf + y);
       if (L1 != L) {
@@ -24,8 +28,9 @@
       }
   }
 
-  LL = CONST64 (0x01020304050607);
   for (y = 0; y < 8; y++) {
+      LL = CONST64 (0x01020304050607);
+      LL1 = 0;
       STORE64L(LL, buf + y);
       LOAD64L(LL1, buf + y);
       if (LL1 != LL) {
@@ -40,5 +45,34 @@
       }
   }
 
+/* test LTC_FAST */
+#ifdef LTC_FAST
+  y = 16;
+
+  for (z = 0; z < y; z++) {
+     /* fill y bytes with random */
+     yarrow_read(buf+z,   y, &yarrow_prng);
+     yarrow_read(buf+z+y, y, &yarrow_prng);
+
+     /* now XOR it byte for byte */
+     for (x = 0; x < y; x++) {
+         buf[2*y+z+x] = buf[z+x] ^ buf[z+y+x];
+     }
+
+     /* now XOR it word for word */
+     for (x = 0; x < y; x += sizeof(LTC_FAST_TYPE)) {
+        *((LTC_FAST_TYPE*)(&buf[3*y+z+x])) = *((LTC_FAST_TYPE*)(&buf[z+x])) ^ *((LTC_FAST_TYPE*)(&buf[z+y+x]));
+     }
+
+     if (memcmp(&buf[2*y+z], &buf[3*y+z], y)) {
+        fprintf(stderr, "\nLTC_FAST failed at offset %d\n", z);
+        return 1;
+     }
+  }
+#endif
   return 0;
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/store_test.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/testprof/test.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/test.c	Wed Jul 06 12:10:23 2005 +0000
@@ -7,3 +7,7 @@
       exit(EXIT_FAILURE);
    }
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/test.c,v $ */
+/* $Revision: 1.6 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testprof/test.key	Wed Jul 06 12:10:23 2005 +0000
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97bfYUtlmXl
+P3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7kEY5BaHxh
+E9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE/QIDAQAB
+AoGBAMhiuereRFMdVpfZl54azzAeCohFhikwo02fYWVz4NaHj7bzBqOC3Hys/pso
+mq79+/4vDtiXBOO7H9HsDbqjSX9HrIpEBH6GtzlCP60etw6lUfRAYx79veqfQZ+o
+kB1vClqVExENgK9fZJiKLHhoZbAri6JTh8rxZASr8nvbg8iBAkEA975eI8MyP7+L
+jjru/PzL5ffxC7xCgq7Vej7K99VpP2Qloh+3dXUFkkLruPHzCgXjlNFVeDWgNqCb
+fJKEbN3cTQJBANaGDoVCCwQIhCFg8A4NiP0eNhBlTx5TtAhygFw/WWYX5pjy6Wx6
+Bkysdj3tjKHOrRu9tH0ovOMOOI2Z2AW1o3ECQG3rwy0u8F6kiDEFKQCK0ZUpm4PP
+ddsx43on3jp0MAx2TNRQKkAtOdmZY6ldgK5TypQ/BSMe+AUE4bg18hezoIkCQQCr
+kIj6YAgpUJpDi6BQzNha/pdkY3F0IqMgAlrP68YWlVTRy6uNGsYA+giSnHHVUlI1
+lnFLi5IM0Om/rWMLpemxAkEA3MwnyOTcYkjVm6/1q2D2If1T4rddCckaoQSp/GEs
+XQRYOlo58UohVmf9zCCjj3gYWnk9Lo5+hgrmqDPBBBdKnw==
+-----END RSA PRIVATE KEY-----
--- a/testprof/tomcrypt_test.h	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/tomcrypt_test.h	Wed Jul 06 12:10:23 2005 +0000
@@ -71,3 +71,7 @@
 
 
 #endif
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/tomcrypt_test.h,v $ */
+/* $Revision: 1.8 $ */
+/* $Date: 2005/05/05 14:35:59 $ */
--- a/testprof/x86_prof.c	Tue May 10 17:02:59 2005 +0000
+++ b/testprof/x86_prof.c	Wed Jul 06 12:10:23 2005 +0000
@@ -21,10 +21,10 @@
    // qsort the results
    qsort(results, no_results, sizeof(struct list), &sorter);
 
-   printf("\n");
+   fprintf(stderr, "\n");
    if (type == 0) {
       for (x = 0; x < no_results; x++) {
-         printf("%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1);
+         fprintf(stderr, "%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1);
       } 
    } else if (type == 1) {
       for (x = 0; x < no_results; x++) {
@@ -42,7 +42,7 @@
 /* RDTSC from Scott Duplichan */
 ulong64 rdtsc (void)
    {
-   #if defined __GNUC__
+   #if defined __GNUC__ && !defined(LTC_NO_ASM)
       #ifdef INTEL_CC
 			ulong64 a;
 			asm ( " rdtsc ":"=A"(a));
@@ -62,11 +62,11 @@
       #endif
 
    // Microsoft and Intel Windows compilers
-   #elif defined _M_IX86
+   #elif defined _M_IX86 && !defined(LTC_NO_ASM)
      __asm rdtsc
-   #elif defined _M_AMD64
+   #elif defined _M_AMD64 && !defined(LTC_NO_ASM)
      return __rdtsc ();
-   #elif defined _M_IA64
+   #elif defined _M_IA64 && !defined(LTC_NO_ASM)
      #if defined __INTEL_COMPILER
        #include <ia64intrin.h>
      #endif
@@ -104,7 +104,7 @@
       c2 = (t2 > c2) ? t2 : c2;
    }
    skew = c2 - c1;
-   printf("Clock Skew: %lu\n", (unsigned long)skew);
+   fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew);
 }
 
 void reg_algs(void)
@@ -199,7 +199,7 @@
 #ifdef CHC_HASH
   register_hash(&chc_desc);
   if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) {
-     printf("chc_register error: %s\n", error_to_string(err));
+     fprintf(stderr, "chc_register error: %s\n", error_to_string(err));
      exit(EXIT_FAILURE);
   }
 #endif
@@ -231,7 +231,7 @@
   int    (*func) (const unsigned char *, int , int , symmetric_key *);
   unsigned char key[MAXBLOCKSIZE];
 
-  printf ("\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n");
+  fprintf(stderr, "\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n");
   no_results = 0; 
  for (x = 0; cipher_descriptor[x].name != NULL; x++) {
 #define DO1(k)   func(k, kl, 0, &skey);
@@ -249,7 +249,7 @@
     t1 = c1 - skew;
     results[no_results].spd1 = results[no_results].avg = t1;
     results[no_results++].id = x;
-    printf("."); fflush(stdout);
+    fprintf(stderr, "."); fflush(stdout);
 
 #undef DO1
    }
@@ -266,7 +266,7 @@
   unsigned char key[MAXBLOCKSIZE], pt[4096];
   int err;
 
-  printf ("\n\nECB Time Trials for the Symmetric Ciphers:\n");
+  fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n");
   no_results = 0;
   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
     ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb);
@@ -318,7 +318,7 @@
     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
     ++no_results;
-    printf("."); fflush(stdout);
+    fprintf(stderr, "."); fflush(stdout);
     
 #undef DO2
 #undef DO1
@@ -337,7 +337,7 @@
   unsigned char key[MAXBLOCKSIZE], pt[4096];
   int err;
 
-  printf ("\n\nCBC Time Trials for the Symmetric Ciphers:\n");
+  fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n");
   no_results = 0;
   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
     cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc);
@@ -389,7 +389,7 @@
     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
     ++no_results;
-    printf("."); fflush(stdout);
+    fprintf(stderr, "."); fflush(stdout);
     
 #undef DO2
 #undef DO1
@@ -399,7 +399,7 @@
    return 0;
 }
 #else
-int time_cipher2(void) { printf("NO CBC\n"); return 0; }
+int time_cipher2(void) { fprintf(stderr, "NO CBC\n"); return 0; }
 #endif
 
 #ifdef CTR
@@ -411,10 +411,10 @@
   unsigned char key[MAXBLOCKSIZE], pt[4096];
   int err;
 
-  printf ("\n\nCTR Time Trials for the Symmetric Ciphers:\n");
+  fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n");
   no_results = 0;
   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
-    ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &ctr);
+    ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr);
 
     /* sanity check on cipher */
     if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
@@ -463,7 +463,7 @@
     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
     ++no_results;
-    printf("."); fflush(stdout);
+    fprintf(stderr, "."); fflush(stdout);
     
 #undef DO2
 #undef DO1
@@ -473,7 +473,7 @@
    return 0;
 }
 #else
-int time_cipher3(void) { printf("NO CTR\n"); return 0; }
+int time_cipher3(void) { fprintf(stderr, "NO CTR\n"); return 0; }
 #endif
 
 int time_hash(void)
@@ -485,7 +485,7 @@
   unsigned char pt[MAXBLOCKSIZE];
 
 
-  printf ("\n\nHASH Time Trials for:\n");
+  fprintf(stderr, "\n\nHASH Time Trials for:\n");
   no_results = 0;
   for (x = 0; hash_descriptor[x].name != NULL; x++) {
 
@@ -518,7 +518,7 @@
     results[no_results].id = x;
     results[no_results].spd1 = results[no_results].avg = t1;
     ++no_results;
-    printf("."); fflush(stdout);
+    fprintf(stderr, "."); fflush(stdout);
 #undef DO2
 #undef DO1
    }
@@ -534,7 +534,7 @@
    unsigned long x, y;
    mp_int  a, b, c;
 
-   printf("Timing Multiplying:\n");
+   fprintf(stderr, "Timing Multiplying:\n");
    mp_init_multi(&a,&b,&c,NULL);
    for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) {
        mp_rand(&a, x);
@@ -551,7 +551,7 @@
            t1 = (t_read() - t1)>>1;
            if (t1 < t2) t2 = t1;
        }
-       printf("%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2);
+       fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2);
    }
    mp_clear_multi(&a,&b,&c,NULL);
 
@@ -565,7 +565,7 @@
    unsigned long x, y;
    mp_int  a, b;
 
-   printf("Timing Squaring:\n");
+   fprintf(stderr, "Timing Squaring:\n");
    mp_init_multi(&a,&b,NULL);
    for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) {
        mp_rand(&a, x);
@@ -581,7 +581,7 @@
            t1 = (t_read() - t1)>>1;
            if (t1 < t2) t2 = t1;
        }
-       printf("%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2);
+       fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2);
    }
    mp_clear_multi(&a,&b,NULL);
 
@@ -589,8 +589,8 @@
 #undef DO2
 }
 #else
-void time_mult(void) { printf("NO MULT\n"); }
-void time_sqr(void) { printf("NO SQR\n"); }
+void time_mult(void) { fprintf(stderr, "NO MULT\n"); }
+void time_sqr(void) { fprintf(stderr, "NO SQR\n"); }
 #endif
    
 void time_prng(void)
@@ -601,7 +601,7 @@
    unsigned long x, y;
    int           err;
 
-   printf("Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n");
+   fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n");
    for (x = 0; prng_descriptor[x].name != NULL; x++) {
 
       /* sanity check on prng */
@@ -616,7 +616,7 @@
       prng_descriptor[x].ready(&tprng);
       t2 = -1;
 
-#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { printf("\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); }
+#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { fprintf(stderr, "\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); }
 #define DO2 DO1 DO1
       for (y = 0; y < 10000; y++) {
          t_start();
@@ -625,7 +625,7 @@
          t1 = (t_read() - t1)>>1;
          if (t1 < t2) t2 = t1;
       }
-      printf("%20s: %5llu ", prng_descriptor[x].name, t2>>12);
+      fprintf(stderr, "%20s: %5llu ", prng_descriptor[x].name, t2>>12);
 #undef DO2
 #undef DO1
 
@@ -638,7 +638,7 @@
          t1 = (t_read() - t1)>>1;
          if (t1 < t2) t2 = t1;
       }
-      printf("%5llu\n", t2);
+      fprintf(stderr, "%5llu\n", t2);
 #undef DO2
 #undef DO1
 
@@ -672,7 +672,7 @@
            }
        }
        t2 >>= 4;
-       printf("RSA-%lu make_key    took %15llu cycles\n", x, t2);
+       fprintf(stderr, "RSA-%lu make_key    took %15llu cycles\n", x, t2);
 
        t2 = 0;
        for (y = 0; y < 16; y++) {
@@ -689,7 +689,7 @@
            t2 += t1;
        }
        t2 >>= 4;
-       printf("RSA-%lu encrypt_key took %15llu cycles\n", x, t2);
+       fprintf(stderr, "RSA-%lu encrypt_key took %15llu cycles\n", x, t2);
 
        t2 = 0;
        for (y = 0; y < 16; y++) {
@@ -705,14 +705,14 @@
            t2 += t1;
        }
        t2 >>= 4;
-       printf("RSA-%lu decrypt_key took %15llu cycles\n", x, t2);
+       fprintf(stderr, "RSA-%lu decrypt_key took %15llu cycles\n", x, t2);
 
 
        rsa_free(&key);
   }
 }
 #else
-void time_rsa(void) { printf("NO RSA\n"); }
+void time_rsa(void) { fprintf(stderr, "NO RSA\n"); }
 #endif
 
 #ifdef MECC
@@ -724,7 +724,7 @@
    unsigned char buf[2][4096];
    unsigned long i, x, y, z;
    int           err;
-   static unsigned long sizes[] = {160/8, 256/8, 521/8, 100000};
+   static unsigned long sizes[] = {192/8, 256/8, 384/8, 521/8, 100000};
 
    for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
        t2 = 0;
@@ -743,7 +743,7 @@
            }
        }
        t2 >>= 4;
-       printf("ECC-%lu make_key    took %15llu cycles\n", x*8, t2);
+       fprintf(stderr, "ECC-%lu make_key    took %15llu cycles\n", x*8, t2);
 
        t2 = 0;
        for (y = 0; y < 16; y++) {
@@ -759,12 +759,12 @@
            t2 += t1;
        }
        t2 >>= 4;
-       printf("ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2);
+       fprintf(stderr, "ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2);
        ecc_free(&key);
   }
 }
 #else
-void time_ecc(void) { printf("NO ECC\n"); }
+void time_ecc(void) { fprintf(stderr, "NO ECC\n"); }
 #endif
 
 #ifdef MDH
@@ -795,7 +795,7 @@
            }
        }
        t2 >>= 4;
-       printf("DH-%4lu make_key    took %15llu cycles\n", x*8, t2);
+       fprintf(stderr, "DH-%4lu make_key    took %15llu cycles\n", x*8, t2);
 
        t2 = 0;
        for (y = 0; y < 16; y++) {
@@ -811,12 +811,12 @@
            t2 += t1;
        }
        t2 >>= 4;
-       printf("DH-%4lu encrypt_key took %15llu cycles\n", x*8, t2);
+       fprintf(stderr, "DH-%4lu encrypt_key took %15llu cycles\n", x*8, t2);
        dh_free(&key);
   }
 }
 #else
-void time_dh(void) { printf("NO DH\n"); }
+void time_dh(void) { fprintf(stderr, "NO DH\n"); }
 #endif
 
 void time_macs_(unsigned long MAC_SIZE)
@@ -826,7 +826,7 @@
    unsigned long x, z;
    int err, cipher_idx, hash_idx;
 
-   printf("\nMAC Timings (cycles/byte on %dKB blocks):\n", MAC_SIZE);
+   fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE);
 
    buf = XMALLOC(MAC_SIZE*1024);
    if (buf == NULL) {
@@ -853,7 +853,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("OMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "OMAC-AES\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
 #ifdef PMAC
@@ -869,7 +869,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("PMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "PMAC-AES\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
 #ifdef PELICAN
@@ -885,7 +885,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("PELICAN \t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "PELICAN \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
 #ifdef HMAC
@@ -901,7 +901,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("HMAC-MD5\t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "HMAC-MD5\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
    XFREE(buf);
@@ -921,7 +921,7 @@
    unsigned long x, z;
    int err, cipher_idx;
 
-   printf("\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %dKB blocks):\n", MAC_SIZE);
+   fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE);
 
    buf = XMALLOC(MAC_SIZE*1024);
    if (buf == NULL) {
@@ -948,7 +948,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("EAX \t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "EAX \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
 #ifdef OCB_MODE
@@ -964,7 +964,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("OCB \t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "OCB \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
 #ifdef CCM_MODE
@@ -980,7 +980,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("CCM \t\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "CCM \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 #endif
 
 #ifdef GCM_MODE
@@ -996,12 +996,12 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("GCM (no-precomp)\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "GCM (no-precomp)\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
 
    {
    gcm_state gcm;
 
-   if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { printf("gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); }
+   if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); }
    t2 = -1;
    for (x = 0; x < 10000; x++) {
         t_start();
@@ -1031,7 +1031,7 @@
         t1 = t_read() - t1;
         if (t1 < t2) t2 = t1;
    }
-   printf("GCM (precomp)\t%9llu\n", t2/(MAC_SIZE*1024));
+   fprintf(stderr, "GCM (precomp)\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024));
    }
 
 #endif
@@ -1044,3 +1044,7 @@
    time_encmacs_(4);
    time_encmacs_(32);
 }
+
+/* $Source: /cvs/libtom/libtomcrypt/testprof/x86_prof.c,v $ */
+/* $Revision: 1.16 $ */
+/* $Date: 2005/06/14 20:44:23 $ */