Browse Source

added libtomcrypt-1.07

Tom St Denis 20 years ago
parent
commit
4a1a5796de
100 changed files with 3695 additions and 1968 deletions
  1. 1 1
      Doxyfile
  2. 37 0
      TODO
  3. 45 4
      changes
  4. 232 71
      crypt.tex
  5. 2 2
      demos/encrypt.c
  6. 2 1
      demos/test.c
  7. 3 1
      demos/timing.c
  8. 2 2
      demos/tv_gen.c
  9. BIN
      doc/crypt.pdf
  10. 51 29
      makefile
  11. 23 16
      makefile.icc
  12. 25 15
      makefile.msvc
  13. 40 22
      makefile.shared
  14. 16 8
      src/ciphers/aes/aes.c
  15. 6 2
      src/ciphers/anubis.c
  16. 15 8
      src/ciphers/blowfish.c
  17. 13 8
      src/ciphers/cast5.c
  18. 13 5
      src/ciphers/des.c
  19. 6 2
      src/ciphers/khazad.c
  20. 15 8
      src/ciphers/noekeon.c
  21. 16 8
      src/ciphers/rc2.c
  22. 16 8
      src/ciphers/rc5.c
  23. 13 8
      src/ciphers/rc6.c
  24. 12 8
      src/ciphers/safer/safer.c
  25. 6 2
      src/ciphers/safer/saferp.c
  26. 16 8
      src/ciphers/skipjack.c
  27. 15 8
      src/ciphers/twofish/twofish.c
  28. 6 2
      src/ciphers/xtea.c
  29. 61 26
      src/encauth/ccm/ccm_memory.c
  30. 11 5
      src/encauth/ccm/ccm_test.c
  31. 3 1
      src/encauth/gcm/gcm_done.c
  32. 3 1
      src/encauth/gcm/gcm_init.c
  33. 2 2
      src/encauth/gcm/gcm_memory.c
  34. 12 4
      src/encauth/gcm/gcm_process.c
  35. 3 1
      src/encauth/ocb/ocb_decrypt.c
  36. 3 1
      src/encauth/ocb/ocb_encrypt.c
  37. 6 2
      src/encauth/ocb/ocb_init.c
  38. 8 4
      src/encauth/ocb/s_ocb_done.c
  39. 2 2
      src/headers/tomcrypt.h
  40. 8 0
      src/headers/tomcrypt_cfg.h
  41. 52 42
      src/headers/tomcrypt_cipher.h
  42. 15 6
      src/headers/tomcrypt_custom.h
  43. 1 0
      src/headers/tomcrypt_mac.h
  44. 44 0
      src/headers/tomcrypt_macros.h
  45. 25 1
      src/headers/tomcrypt_math.h
  46. 123 27
      src/headers/tomcrypt_pk.h
  47. 2 2
      src/headers/tomcrypt_pkcs.h
  48. 2 0
      src/headers/tomcrypt_prng.h
  49. 3 1
      src/mac/omac/omac_done.c
  50. 3 1
      src/mac/omac/omac_init.c
  51. 6 2
      src/mac/omac/omac_process.c
  52. 3 1
      src/mac/pmac/pmac_done.c
  53. 6 3
      src/mac/pmac/pmac_init.c
  54. 6 2
      src/mac/pmac/pmac_process.c
  55. 12 3
      src/math/ltm_desc.c
  56. 1 0
      src/math/multi.c
  57. 14 4
      src/math/tfm_desc.c
  58. 9 3
      src/misc/crypt/crypt.c
  59. 4 2
      src/modes/cbc/cbc_decrypt.c
  60. 4 2
      src/modes/cbc/cbc_encrypt.c
  61. 3 1
      src/modes/cfb/cfb_decrypt.c
  62. 3 1
      src/modes/cfb/cfb_encrypt.c
  63. 1 3
      src/modes/cfb/cfb_setiv.c
  64. 1 3
      src/modes/cfb/cfb_start.c
  65. 6 2
      src/modes/ctr/ctr_encrypt.c
  66. 1 3
      src/modes/ctr/ctr_setiv.c
  67. 1 2
      src/modes/ctr/ctr_start.c
  68. 4 2
      src/modes/ecb/ecb_decrypt.c
  69. 4 2
      src/modes/ecb/ecb_encrypt.c
  70. 3 1
      src/modes/ofb/ofb_encrypt.c
  71. 1 2
      src/modes/ofb/ofb_setiv.c
  72. 2 2
      src/pk/asn1/der/bit/der_decode_bit_string.c
  73. 1 0
      src/pk/asn1/der/choice/der_decode_choice.c
  74. 352 0
      src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
  75. 7 0
      src/pk/asn1/der/sequence/der_length_sequence.c
  76. 63 0
      src/pk/asn1/der/sequence/der_sequence_free.c
  77. 138 0
      src/pk/dsa/dsa_decrypt_key.c
  78. 136 0
      src/pk/dsa/dsa_encrypt_key.c
  79. 1 0
      src/pk/dsa/dsa_import.c
  80. 1 0
      src/pk/dsa/dsa_make_key.c
  81. 71 0
      src/pk/dsa/dsa_shared_secret.c
  82. 0 1064
      src/pk/ecc/ecc.c
  83. 149 0
      src/pk/ecc/ecc_decrypt_key.c
  84. 136 0
      src/pk/ecc/ecc_encrypt_key.c
  85. 82 0
      src/pk/ecc/ecc_export.c
  86. 40 0
      src/pk/ecc/ecc_free.c
  87. 44 0
      src/pk/ecc/ecc_get_size.c
  88. 155 0
      src/pk/ecc/ecc_import.c
  89. 112 0
      src/pk/ecc/ecc_make_key.c
  90. 94 0
      src/pk/ecc/ecc_shared_secret.c
  91. 118 0
      src/pk/ecc/ecc_sign_hash.c
  92. 48 0
      src/pk/ecc/ecc_sizes.c
  93. 0 472
      src/pk/ecc/ecc_sys.c
  94. 96 0
      src/pk/ecc/ecc_test.c
  95. 160 0
      src/pk/ecc/ecc_verify_hash.c
  96. 45 0
      src/pk/ecc/ltc_ecc_is_valid_idx.c
  97. 77 0
      src/pk/ecc/ltc_ecc_map.c
  98. 213 0
      src/pk/ecc/ltc_ecc_mulmod.c
  99. 162 0
      src/pk/ecc/ltc_ecc_mulmod_timing.c
  100. 60 0
      src/pk/ecc/ltc_ecc_points.c

+ 1 - 1
Doxyfile

@@ -23,7 +23,7 @@ PROJECT_NAME           = LibTomCrypt
 # This could be handy for archiving the generated documentation or 
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 # if some version control system is used.
 
 
-PROJECT_NUMBER         = 1.06
+PROJECT_NUMBER         = 1.07
 
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
 # base path where the generated documentation will be put. 

+ 37 - 0
TODO

@@ -1,6 +1,43 @@
 For 1.07
 For 1.07
 
 
+                
 1. [3 hours]    ASN.1 SET and T61String [punishment, add UTF8 to the list!]
 1. [3 hours]    ASN.1 SET and T61String [punishment, add UTF8 to the list!]
 
 
+4. [short]      Make parameters in descriptors common, e.g. cipher.block_length => cipher.block_size, hash.blocksize => hash.block_size
 
 
+DONE
+----
 
 
+0. [important]  Make ciphers enc/dec routines return int [for accel].  Make the ciphers themselves return CRYPT_OK [default] *AND* make
+                all dependent code check the returns 
+                [x] gcm
+                [x] ccm
+                [x] yarrow
+                [x] fortuna
+                [x] eax
+                [x] ocb
+                [x] omac
+                [x] pmac
+                [x] pelican
+                [x] ctr
+                [x] cbc
+                [x] ecb
+                [x] cfb
+                [x] ofb
+
+2. [many]       ASN.1 flexidecoder.  Basically decode and construct a list of decoded ASN.1 types on the fly.
+                This will allow easy decoding of things like X.509 as their orders can be "screwed up".
+                The concept is simple, just read the ID byte and use a linked list.  I'll do this after step #1.
+
+3. [short]      Make the cipher/hash accelerators return int [not void] to signal errors.  Whoops
+
+5. [short]      Swap arguments of MGF1 around so hash_idx is first
+
+6. [longish]    Re-write parts of the ECC api, re-factor the code, convert to w-NAF, add FP support, add ecc point verifier
+
+7. [shortish]   Provide DH for the DSA code e.g. dsa_encrypt_key()
+
+8. [worthit]    Move the ECC code for point mul and what not as symbols that the TFM/LTM descriptors link in.  Means a change to the hierarchy.  This allows
+                code that uses ECC plugins to simply ignore this code [e.g. save space]
+
+9. [short]      Document the flexi decoder and how it relates to the other DER routines

+ 45 - 4
changes

@@ -1,3 +1,44 @@
+November 18th, 2005
+v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly.  That's because as of a few releases ago
+         I added support to set the mode of the counter at init time
+      -- Fixed some "testprof" make issues
+      -- Added RSA keygen to the math descriptors
+      -- Fixed install_test target ... oops
+      -- made the "ranlib" program renamable useful for cross-compiling
+      -- Made the cipher accelerators return error codes.  :-)
+      -- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets
+      -- Added "Katja" public key crypto.  It's based on the recent N = p^2q work by Katja.  I added OAEP padding
+         to it.  Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly
+         analyzed.   It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also
+         some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible.
+      -- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya  :-)
+      -- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER
+      -- Cleaned up the LIBTEST_S definitions in both GNU makefiles.  A few minor touchups as well.
+      -- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this.  
+      -- der_decode_choice() would fail to mark a NULL as "used" when decoding.  Fixed
+      -- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-)
+      -- Added mp_neg() to the math descriptors.
+      -- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent)
+      -- Made the math descriptors buildable when RSA has been undefined
+      -- ECC timing demo now capable of detecting which curves have been defined
+      -- Refactored the ECC code so it's easier to maintain.  (note: the form of this code hasn't really changed since I first added ECC ... :-/)
+      -- Updated the documentation w.r.t. ECC and the accelerators to keep it current
+      -- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error.
+      -- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes)
+      -- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters)
+      -- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead!
+      -- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used)
+      -- ECC code now ALWAYS uses the accelerator interface.  This allows people who use the accelerators to not have the stock
+         ECC point add/dbl/mul code linked in.  Yeah space savings! Rah Rah Rah.
+      -- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at
+         build time (e.g. LTC_PTHREAD == pthreads)
+      -- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock)
+      -- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-)
+      -- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that]
+      -- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD]
+      -- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing
+         their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask)
+
 August 1st, 2005
 August 1st, 2005
 v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson]
 v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson]
       -- Added fourth ARGCHK type which outputs to stderr and continues.  Useful if you trap sigsegv.   [Valient Gough]
       -- Added fourth ARGCHK type which outputs to stderr and continues.  Useful if you trap sigsegv.   [Valient Gough]
@@ -234,7 +275,7 @@ October 29th, 2004
 v0.99  -- Merged in the latest version of LTM which includes all of the recent bug fixes
 v0.99  -- Merged in the latest version of LTM which includes all of the recent bug fixes
        -- Deprecated LTMSSE and removed it (to be replaced with TFM later on)
        -- Deprecated LTMSSE and removed it (to be replaced with TFM later on)
        -- Stefan Arentz pointed out that mp_s_rmap should be extern
        -- Stefan Arentz pointed out that mp_s_rmap should be extern
-       -- Kristian Gjøsteen pointed out that there are typos in the 
+       -- Kristian Gj?steen pointed out that there are typos in the 
           "test" makefile and minor issues in Yarrow and Sober [just cosmetics really]
           "test" makefile and minor issues in Yarrow and Sober [just cosmetics really]
        -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword 
        -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword 
           so changed the PRNG api to use "pexport" and "pimport"
           so changed the PRNG api to use "pexport" and "pimport"
@@ -613,7 +654,7 @@ v0.81  -- Merged in new makefile from Clay Culver and Mike Frysinger
           as much as possible.  This sped the routine up quite a bit.
           as much as possible.  This sped the routine up quite a bit.
        -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
        -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
        -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
        -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
-          (fix due to Mika Boström)
+          (fix due to Mika Bostr?m)
        -- Merged in LibTomMath for kicks
        -- Merged in LibTomMath for kicks
        -- Changed the build process so that by default "mycrypt_custom.h" is included and provided
        -- Changed the build process so that by default "mycrypt_custom.h" is included and provided
           The makefile doesn't include any build options anymore
           The makefile doesn't include any build options anymore
@@ -1342,6 +1383,6 @@ v0.02  -- Changed RC5 to only allow 12 to 24 rounds
 v0.01  -- We will call this the first version.
 v0.01  -- We will call this the first version.
 
 
 /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
 /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
-/* $Revision: 1.123 $ */
-/* $Date: 2005/08/01 16:50:34 $ */
+/* $Revision: 1.151 $ */
+/* $Date: 2005/11/17 22:04:00 $ */
 
 

+ 232 - 71
crypt.tex

@@ -47,7 +47,7 @@
 \def\gap{\vspace{0.5ex}}
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \makeindex
 \begin{document}
 \begin{document}
-\title{LibTomCrypt \\ Version 1.06}
+\title{LibTomCrypt \\ Version 1.07}
 \author{Tom St Denis \\
 \author{Tom St Denis \\
 \\
 \\
 [email protected] \\
 [email protected] \\
@@ -236,8 +236,7 @@ int main(void) {
 }
 }
 \end{verbatim}
 \end{verbatim}
 
 
-The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and 
-``ltc\_tommath.h'' (the bignum library routines).
+The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'' and ``ctype.h''.
 
 
 \section{Macros}
 \section{Macros}
 
 
@@ -363,16 +362,17 @@ done with a key you can simply discard it (e.g. they can be on the stack).
 To encrypt or decrypt a block in ECB mode there are these two function classes
 To encrypt or decrypt a block in ECB mode there are these two function classes
 \index{Cipher Encrypt} \index{Cipher Decrypt}
 \index{Cipher Encrypt} \index{Cipher Decrypt}
 \begin{verbatim}
 \begin{verbatim}
-void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
+int XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
                      symmetric_key *skey);
                      symmetric_key *skey);
 
 
-void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
+int XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
                      symmetric_key *skey);
                      symmetric_key *skey);
 \end{verbatim}
 \end{verbatim}
 These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
 These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
 which cipher you are using.} and store the result where you want it.  It is possible that the input and output buffer are 
 which cipher you are using.} and store the result where you want it.  It is possible that the input and output buffer are 
 the same buffer.  For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and 
 the same buffer.  For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and 
-``ct''\footnote{ct stands for ciphertext.} is the output.  For the decryption function it's the opposite.  To test a particular 
+``ct''\footnote{ct stands for ciphertext.} is the output.  For the decryption function it's the opposite.  They both
+return \textbf{CRYPT\_OK} on success.  To test a particular 
 cipher against test vectors\footnote{As published in their design papers.} call the self-test function
 cipher against test vectors\footnote{As published in their design papers.} call the self-test function
  
  
 \subsection{Self--Testing}
 \subsection{Self--Testing}
@@ -496,39 +496,47 @@ struct _cipher_descriptor {
         block_length, 
         block_length, 
         default_rounds;
         default_rounds;
    int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
    int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-   void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-   void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
-   int (*test)(void);
+   int  (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+   int  (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+   int  (*test)(void);
    void (*done)(symmetric_key *skey);      
    void (*done)(symmetric_key *skey);      
    int  (*keysize)(int *keysize);
    int  (*keysize)(int *keysize);
 
 
-   void (*accel_ecb_encrypt)(const unsigned char *pt, 
+   int (*accel_ecb_encrypt)(const unsigned char *pt, 
                                    unsigned char *ct, 
                                    unsigned char *ct, 
                                    unsigned long blocks, symmetric_key *skey);
                                    unsigned long blocks, symmetric_key *skey);
-   void (*accel_ecb_decrypt)(const unsigned char *ct, 
+   int (*accel_ecb_decrypt)(const unsigned char *ct, 
                                    unsigned char *pt, 
                                    unsigned char *pt, 
                                    unsigned long blocks, symmetric_key *skey);
                                    unsigned long blocks, symmetric_key *skey);
-   void (*accel_cbc_encrypt)(const unsigned char *pt, 
+   int (*accel_cbc_encrypt)(const unsigned char *pt, 
                                    unsigned char *ct, 
                                    unsigned char *ct, 
                                    unsigned long blocks, unsigned char *IV, 
                                    unsigned long blocks, unsigned char *IV, 
                                    symmetric_key *skey);
                                    symmetric_key *skey);
-   void (*accel_cbc_decrypt)(const unsigned char *ct, 
+   int (*accel_cbc_decrypt)(const unsigned char *ct, 
                                    unsigned char *pt, 
                                    unsigned char *pt, 
                                    unsigned long blocks, unsigned char *IV, 
                                    unsigned long blocks, unsigned char *IV, 
                                    symmetric_key *skey);
                                    symmetric_key *skey);
-   void (*accel_ctr_encrypt)(const unsigned char *pt, 
+   int (*accel_ctr_encrypt)(const unsigned char *pt, 
                                    unsigned char *ct, 
                                    unsigned char *ct, 
                                    unsigned long blocks, unsigned char *IV, 
                                    unsigned long blocks, unsigned char *IV, 
                                    int mode, symmetric_key *skey);
                                    int mode, symmetric_key *skey);
-   void (*accel_ccm_memory)(
+   int (*accel_ccm_memory)(
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *key,    unsigned long keylen,
+       symmetric_key       *uskey,
        const unsigned char *nonce,  unsigned long noncelen,
        const unsigned char *nonce,  unsigned long noncelen,
        const unsigned char *header, unsigned long headerlen,
        const unsigned char *header, unsigned long headerlen,
              unsigned char *pt,     unsigned long ptlen,
              unsigned char *pt,     unsigned long ptlen,
              unsigned char *ct,
              unsigned char *ct,
              unsigned char *tag,    unsigned long *taglen,
              unsigned char *tag,    unsigned long *taglen,
                        int  direction);
                        int  direction);
-
+   int (*accel_gcm_memory)(
+       const unsigned char *key,    unsigned long keylen,
+       const unsigned char *IV,     unsigned long IVlen,
+       const unsigned char *adata,  unsigned long adatalen,
+             unsigned char *pt,     unsigned long ptlen,
+             unsigned char *ct,
+             unsigned char *tag,    unsigned long *taglen,
+                       int direction);
 };
 };
 \end{verbatim}
 \end{verbatim}
 \end{small}
 \end{small}
@@ -1200,6 +1208,7 @@ function that performs the protocol.
 \begin{verbatim}
 \begin{verbatim}
 int ccm_memory(int cipher,
 int ccm_memory(int cipher,
     const unsigned char *key,    unsigned long keylen,
     const unsigned char *key,    unsigned long keylen,
+    symmetric_key       *uskey,
     const unsigned char *nonce,  unsigned long noncelen,
     const unsigned char *nonce,  unsigned long noncelen,
     const unsigned char *header, unsigned long headerlen,
     const unsigned char *header, unsigned long headerlen,
           unsigned char *pt,     unsigned long ptlen,
           unsigned char *pt,     unsigned long ptlen,
@@ -1209,9 +1218,15 @@ int ccm_memory(int cipher,
 \end{verbatim}
 \end{verbatim}
 
 
 This performs the ``CCM'' operation on the data.  The ``cipher'' variable indicates which cipher in the descriptor table to use.  It must have a 
 This performs the ``CCM'' operation on the data.  The ``cipher'' variable indicates which cipher in the descriptor table to use.  It must have a 
-16--byte block size for CCM.  The key is ``key'' with a length of ``keylen'' octets.  The nonce or salt is ``nonce'' of
-length ``noncelen'' octets.  The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header''
-of length ``headerlen'' octets.  The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}).  
+16--byte block size for CCM.  
+
+The key can be specified in one of two fashions.  First it can be passed as an array of octets in ``key'' of length ``keylen''.  Alternatively,
+it can be passed in as a previously scheduled key in ``uskey''.  The latter fashion saves time when the same key is used for multiple packets.  If
+``uskey'' is not \textbf{NULL} then ``key'' may be \textbf{NULL} (and vice-versa). 
+
+The nonce or salt is ``nonce'' of length ``noncelen'' octets.  The header is meta--data you want to send with the message but not have 
+encrypted, it is stored in ``header'' of length ``headerlen'' octets.  The header can be zero octets long (if $headerlen = 0$ then 
+you can pass ``header'' as \textbf{NULL}).  
 
 
 The plaintext is stored in ``pt'' and the ciphertext in ``ct''.  The length of both are expected to be equal and is passed in as ``ptlen''.  It is
 The plaintext is stored in ``pt'' and the ciphertext in ``ct''.  The length of both are expected to be equal and is passed in as ``ptlen''.  It is
 allowable that $pt = ct$.  The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or 
 allowable that $pt = ct$.  The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or 
@@ -2902,28 +2917,39 @@ int ecc_shared_secret(ecc_key *private_key,
 The ``private\_key'' is your own key and ``public\_key'' is the key the other user sent you.   Note that this function stores only the 
 The ``private\_key'' is your own key and ``public\_key'' is the key the other user sent you.   Note that this function stores only the 
 $x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH.  
 $x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH.  
 
 
-\section{ECC Packet}
+\section{ECC Diffie-Hellman Encryption}
 Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key
 Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key
 algorithms.
 algorithms.
 
 
-\index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()}
+\index{ecc\_encrypt\_key()}
 \begin{verbatim}
 \begin{verbatim}
 int ecc_encrypt_key(const unsigned char *in,   unsigned long  inlen,
 int ecc_encrypt_key(const unsigned char *in,   unsigned long  inlen,
                           unsigned char *out,  unsigned long *outlen, 
                           unsigned char *out,  unsigned long *outlen, 
                           prng_state *prng, int wprng, int hash, 
                           prng_state *prng, int wprng, int hash, 
                           ecc_key *key);
                           ecc_key *key);
+\end{verbatim}
+
+Where ``in'' is an input symmetric key of no more than 64 bytes.  This function creates a random public key
+and computes the hash of the shared secret.  The message digest is then 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.
+
+The data is encrypted to the public ECC ``key'' such that only the holder of the private key can decrypt the payload.  If you want
+to have multiple recipients you will have to call this function for each public ECC key you want to encrypt to.
+
 
 
+\index{ecc\_decrypt\_key()}
+\begin{verbatim}
 int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
 int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
                           unsigned char *out, unsigned long *outlen, 
                           unsigned char *out, unsigned long *outlen, 
                           ecc_key *key);
                           ecc_key *key);
 \end{verbatim}
 \end{verbatim}
 
 
-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.
+This function will decrypt an encrypted payload.  The ``key'' provided must be the private key corresponding to the public key
+used during encryption.  If the wrong key is provided the function won't specifically return an error code.  It is important
+to use some form of challenge response in that case (e.g. compute a MAC of a known string).
 
 
-\subsection{Encrypt Packet Format}
+\subsection{Encrypt Encryption Format}
 
 
 The packet format for the encrypted keys is the following ASN.1 SEQUENCE:
 The packet format for the encrypted keys is the following ASN.1 SEQUENCE:
 
 
@@ -2935,30 +2961,40 @@ ECCEncrypt ::= SEQUENCE {
 }
 }
 \end{verbatim}
 \end{verbatim}
 
 
+\section{ECC DSA Signatures}
+
 There are also functions to sign and verify the hash of a message.
 There are also functions to sign and verify the hash of a message.
-\index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()}
+\index{ecc\_sign\_hash()}
 \begin{verbatim}
 \begin{verbatim}
 int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
                         unsigned char *out, unsigned long *outlen,
                         unsigned char *out, unsigned long *outlen,
                         prng_state *prng, int wprng, ecc_key *key);
                         prng_state *prng, int wprng, ecc_key *key);
+\end{verbatim}
 
 
+This function will EC--DSA sign the message digest stored in the buffer ``in'' of length inlen octets.  The signature
+will be stored in the ``out'' buffer of length ``outlen''.  The function requires a properly seeded PRNG and 
+the ECC ``key'' provided must be a private key.
+
+\index{ecc\_verify\_hash()}
+\begin{verbatim}
 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
                     const unsigned char *hash, unsigned long hashlen, 
                     const unsigned char *hash, unsigned long hashlen, 
                           int *stat, ecc_key *key);
                           int *stat, ecc_key *key);
 \end{verbatim}
 \end{verbatim}
 
 
-The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.  
-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.
+This function will verify the EC-DSA signature in ``sig'' of length ``siglen'' against the message digest ``hash''.  
+It will store a non--zero value in ``stat'' if the signature is valid.  Note that the function will not return
+an error if the signature is invalid.  It will if the actual signature payload is an invalid format.  They ECC ``key''
+must be the public (or private) ECC key corresponding to the key that performed the signature.
 
 
 \subsection{Signature Format}
 \subsection{Signature Format}
-The signature code is an implementation of X9.62 EC-DSA and the output is comformant for GF(p) curves.
+The signature code is an implementation of X9.62 EC--DSA and the output is comformant for GF(p) curves.
 
 
 \section{ECC Keysizes}
 \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
 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
 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 an ECC-192 key in effect
 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.  
+you have 96-bits of security.  
 
 
 The library will not warn you if you make this mistake so it is important to check yourself before using the 
 The library will not warn you if you make this mistake so it is important to check yourself before using the 
 signatures.
 signatures.
@@ -3077,6 +3113,7 @@ This will test ``key'' and store the result in ``stat''.  If the result is $stat
 and should not be used at all.  If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned).
 and should not be used at all.  If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned).
 
 
 \section{Signatures}
 \section{Signatures}
+\subsection{Signature Generation}
 To generate a DSA signature call the following function
 To generate a DSA signature call the following function
 
 
 \index{dsa\_sign\_hash()}
 \index{dsa\_sign\_hash()}
@@ -3090,6 +3127,7 @@ Which will sign the data in ``in'' of length ``inlen'' bytes.  The signature is
 of the signature in ``outlen''.  If the signature is longer than the size you initially specify in ``outlen'' nothing
 of the signature in ``outlen''.  If the signature is longer than the size you initially specify in ``outlen'' nothing
 is stored and the function returns an error code.  The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion.
 is stored and the function returns an error code.  The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion.
 
 
+\subsection{Signature Verification}
 To verify a hash created with that function use the following function
 To verify a hash created with that function use the following function
 
 
 \index{dsa\_verify\_hash()} 
 \index{dsa\_verify\_hash()} 
@@ -3101,6 +3139,35 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
 Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''.  
 Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''.  
 It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$.  
 It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$.  
 
 
+\section{DSA Encrypt and Decrypt}
+As of version 1.07 the DSA keys can be used to encrypt and decrypt small payloads.  It works similar to the ECC encryption where
+a shared key is computed and the hash of the shared key xor'ed against the plaintext forms the ciphertext.
+
+\subsection{DSA Encryption}
+This function will encrypt a small payload with a recipients public DSA key.
+
+\index{dsa\_encrypt\_key()}
+\begin{verbatim}
+int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen,
+                          unsigned char *out,  unsigned long *outlen, 
+                          prng_state *prng, int wprng, int hash, 
+                          dsa_key *key);
+\end{verbatim}
+
+This will encrypt the payload in ``in'' of length ``inlen'' and store the ciphertext in the output buffer ``out''.  The
+length of the ciphertext ``outlen'' must be originally set to the length of the output buffer.  The DSA ``key'' can be 
+a public key.
+
+\subsection{DSA Decryption}
+
+\index{dsa\_decrypt\_key()}
+\begin{verbatim}                      
+int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen,
+                          unsigned char *out, unsigned long *outlen, 
+                          dsa_key *key);
+\end{verbatim}
+This will decrypt the ciphertext ``in'' of length ``inlen'' and store the original payload in ``out'' of length ``outlen''.  The DSA ``key'' must be a private key.
+
 \section{Import and Export}
 \section{Import and Export}
 
 
 To export a DSA key so that it can be transported use the following function
 To export a DSA key so that it can be transported use the following function
@@ -3137,13 +3204,16 @@ in the same manner as the other data types except they use list of objects known
 \index{ltc\_asn1\_list structure}
 \index{ltc\_asn1\_list structure}
 \begin{verbatim}
 \begin{verbatim}
 typedef struct {
 typedef struct {
-   int           type;
-   void         *data;
-   unsigned long size;
-   int           used;
+   int                    type;
+   void                  *data;
+   unsigned long          size;
+   int                    used;
+   struct ltc_asn1_list_ *prev,  *next, 
+                         *child, *parent;
 } ltc_asn1_list;
 } ltc_asn1_list;
 \end{verbatim}
 \end{verbatim}
 
 
+\index{LTC\_SET\_ASN1 macro}
 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 
 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
 ``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
 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
@@ -3468,6 +3538,45 @@ This will decode the input in the ``in'' field of length ``inlen''.  It uses the
 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 
 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.
 set to non--zero to reflect it was the data type decoded.
 
 
+\subsection{ASN.1 Flexi Decoder}
+The ASN.1 ``flexi'' decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing
+the structure of the data.  Where der\_decode\_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely
+free form.
+
+The flexi decoder uses the same ``ltc\_asn1\_list'' but instead of being stored in an array it uses the linked list pointers ``prev'', ``next'', ``parent'' 
+and ``child''.  The list works as a ``doubly-linked list'' structure where decoded items at the same level are sibblings (using next and prev) and items
+encoded in a SEQUENCE are stored as a child element.
+
+When a SEQUENCE has been encountered a SEQUENCE item is added as a sibbling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child pointer points to a new list
+of items contained within the sequence\footnote{The same will be true for the SET data type when I eventually support it.}.
+
+\index{der\_decode\_sequence\_flexi()}
+\begin{verbatim}
+int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, 
+                                     ltc_asn1_list **out);
+\end{verbatim}
+
+This will decode items in the ``in'' buffer of max input length ``inlen'' and store the newly created pointer to the list in ``out''.  This function allocates
+all required memory for the decoding.  It stores the number of octets read back into ``inlen''.
+
+The function will terminate when either it hits an invalid ASN.1 type octet or it reads ``inlen'' octets.  An early terminate is a soft error and returns
+normally.  The decoded list ``out'' will point to the very first element of the list (e.g. both parent and prev pointers will be \textbf{NULL}).  
+
+An invalid decoding will terminate the process and free the allocated memory automatically.  
+
+\textbf{Note} that the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly.  You will have to first 
+have to convert the list by first storing all of the sibblings in an array then storing all the children as sub-lists of a sequence using the ``.data'' 
+pointer.  Currently no function in LibTomCrypt provides this ability.
+
+To free the list use the following function.
+
+\index{der\_sequence\_free()}
+\begin{verbatim}
+void der_sequence_free(ltc_asn1_list *in);
+\end{verbatim}
+
+This will free all of the memory allocated by der\_decode\_sequence\_flexi().
+
 \section{Password Based Cryptography}
 \section{Password Based Cryptography}
 \subsection{PKCS \#5}
 \subsection{PKCS \#5}
 \index{PKCS \#5}
 \index{PKCS \#5}
@@ -3729,6 +3838,26 @@ libraries.  One for LibTomMath and one for TomsFastMath.
 All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process.  Most of the 
 All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process.  Most of the 
 settings can be overwritten from the command line which makes custom installation a breeze.
 settings can be overwritten from the command line which makes custom installation a breeze.
 
 
+\index{MAKE}
+\index{CC}
+\index{AR}
+\subsection{MAKE, CC and AR}
+The MAKE, CC and AR flags can all be overwritten.  They default to ``make'', ``\$CC'' and ``\$AR'' respectively.  
+
+Changing MAKE allows you to change what program will be invoked to handle sub--directories.  E.g.
+
+\begin{verbatim}
+MAKE=gmake gmake install
+\end{verbatim}
+
+Will build and install the libraries with the ``gmake'' tool.  Similarly
+
+\begin{verbatim}
+CC=arm-gcc AR=arm-ar make 
+\end{verbatim}
+
+Will build the library using ``arm--gcc'' as the compiler and ``arm--ar'' as the archiver.
+
 \subsection{IGNORE\_SPEED}
 \subsection{IGNORE\_SPEED}
 \index{IGNORE\_SPEED}
 \index{IGNORE\_SPEED}
 When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new
 When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new
@@ -3758,7 +3887,8 @@ directory which defaults to ``/usr/lib''.  \textbf{INCPATH} is the prefix for th
 All four can be used to create custom install locations depending on the nature of the OS and file system in use.
 All four can be used to create custom install locations depending on the nature of the OS and file system in use.
 
 
 \begin{verbatim}
 \begin{verbatim}
-make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include DATAPATH=/home/tom/project/docs install
+make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include \
+     DATAPATH=/home/tom/project/docs install
 \end{verbatim}
 \end{verbatim}
 
 
 This will build the library and install it to the directories under ``/home/tom/project/''.  e.g.
 This will build the library and install it to the directories under ``/home/tom/project/''.  e.g.
@@ -3848,13 +3978,11 @@ LibTomCrypt can also be built as a shared library through the ``makefile.shared'
 that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time.  
 that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time.  
 
 
 \begin{verbatim}
 \begin{verbatim}
-CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared
+CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install
 \end{verbatim}
 \end{verbatim}
 
 
-This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well).
-Note that unlike the static build there is no ``install'' target.  The default action of this make script is to install the library.
-
-The shared build process requires libtool to be installed.
+This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well).  The 
+shared build process requires libtool to be installed.
 
 
 \section{tomcrypt\_cfg.h}
 \section{tomcrypt\_cfg.h}
 The file ``tomcrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour 
 The file ``tomcrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour 
@@ -4025,26 +4153,31 @@ struct ltc_cipher_descriptor {
       @param skey        [out] The destination of the scheduled key
       @param skey        [out] The destination of the scheduled key
       @return CRYPT_OK if successful
       @return CRYPT_OK if successful
    */
    */
-   int  (*setup)(const unsigned char *key, int keylen, 
-                 int num_rounds, symmetric_key *skey);
+   int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
    /** Encrypt a block
    /** Encrypt a block
       @param pt      The plaintext
       @param pt      The plaintext
       @param ct      [out] The ciphertext
       @param ct      [out] The ciphertext
       @param skey    The scheduled key
       @param skey    The scheduled key
+      @return CRYPT_OK if successful
    */
    */
-   void (*ecb_encrypt)(const unsigned char *pt, 
-                             unsigned char *ct, symmetric_key *skey);
+   int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
    /** Decrypt a block
    /** Decrypt a block
       @param ct      The ciphertext
       @param ct      The ciphertext
       @param pt      [out] The plaintext
       @param pt      [out] The plaintext
       @param skey    The scheduled key
       @param skey    The scheduled key
+      @return CRYPT_OK if successful
    */
    */
-   void (*ecb_decrypt)(const unsigned char *ct, 
-                             unsigned char *pt, symmetric_key *skey);
+   int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
    /** Test the block cipher
    /** Test the block cipher
        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
    */
    */
    int (*test)(void);
    int (*test)(void);
+
+   /** Terminate the context 
+      @param skey    The scheduled key
+   */
+   void (*done)(symmetric_key *skey);      
+
    /** Determine a key size
    /** Determine a key size
        @param keysize    [in/out] The size of the key desired and the suggested size
        @param keysize    [in/out] The size of the key desired and the suggested size
        @return CRYPT_OK if successful
        @return CRYPT_OK if successful
@@ -4057,20 +4190,20 @@ struct ltc_cipher_descriptor {
        @param ct      Ciphertext
        @param ct      Ciphertext
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_ecb_encrypt)(const unsigned char *pt, 
-                                   unsigned char *ct, unsigned long blocks, 
-                             symmetric_key *skey);
+   int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, 
+                                  unsigned long blocks, symmetric_key *skey);
 
 
    /** Accelerated ECB decryption 
    /** Accelerated ECB decryption 
        @param pt      Plaintext
        @param pt      Plaintext
        @param ct      Ciphertext
        @param ct      Ciphertext
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_ecb_decrypt)(const unsigned char *ct, 
-                                   unsigned char *pt, unsigned long blocks, 
-                             symmetric_key *skey);
+   int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, 
+                                  unsigned long blocks, symmetric_key *skey);
 
 
    /** Accelerated CBC encryption 
    /** Accelerated CBC encryption 
        @param pt      Plaintext
        @param pt      Plaintext
@@ -4078,10 +4211,11 @@ struct ltc_cipher_descriptor {
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param IV      The initial value (input/output)
        @param IV      The initial value (input/output)
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_cbc_encrypt)(const unsigned char *pt, 
-                                   unsigned char *ct, unsigned long blocks, 
-                                   unsigned char *IV, symmetric_key *skey);
+   int (*accel_cbc_encrypt)(const unsigned char *pt,    unsigned char *ct, 
+                                  unsigned long blocks, unsigned char *IV, 
+                                  symmetric_key *skey);
 
 
    /** Accelerated CBC decryption 
    /** Accelerated CBC decryption 
        @param pt      Plaintext
        @param pt      Plaintext
@@ -4089,10 +4223,11 @@ struct ltc_cipher_descriptor {
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param IV      The initial value (input/output)
        @param IV      The initial value (input/output)
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_cbc_decrypt)(const unsigned char *ct, 
-                                   unsigned char *pt, unsigned long blocks, 
-                                   unsigned char *IV, symmetric_key *skey);
+   int (*accel_cbc_decrypt)(const unsigned char *ct,    unsigned char *pt, 
+                                  unsigned long blocks, unsigned char *IV, 
+                                  symmetric_key *skey);
 
 
    /** Accelerated CTR encryption 
    /** Accelerated CTR encryption 
        @param pt      Plaintext
        @param pt      Plaintext
@@ -4101,14 +4236,16 @@ struct ltc_cipher_descriptor {
        @param IV      The initial value (input/output)
        @param IV      The initial value (input/output)
        @param mode    little or big endian counter (mode=0 or mode=1)
        @param mode    little or big endian counter (mode=0 or mode=1)
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_ctr_encrypt)(const unsigned char *pt, 
-                                   unsigned char *ct, unsigned long blocks, 
-                                   unsigned char *IV, int mode, symmetric_key *skey);
+   int (*accel_ctr_encrypt)(const unsigned char *pt,    unsigned char *ct,
+                                  unsigned long blocks, unsigned char *IV, 
+                                  int mode, symmetric_key *skey);
 
 
    /** Accelerated CCM packet (one-shot)
    /** Accelerated CCM packet (one-shot)
        @param key        The secret key to use
        @param key        The secret key to use
        @param keylen     The length of the secret key (octets)
        @param keylen     The length of the secret key (octets)
+       @param uskey      A previously scheduled key [optional can be NULL]
        @param nonce      The session nonce [use once]
        @param nonce      The session nonce [use once]
        @param noncelen   The length of the nonce
        @param noncelen   The length of the nonce
        @param header     The header for the session
        @param header     The header for the session
@@ -4121,8 +4258,9 @@ struct ltc_cipher_descriptor {
        @param direction  Encrypt or Decrypt direction (0 or 1)
        @param direction  Encrypt or Decrypt direction (0 or 1)
        @return CRYPT_OK if successful
        @return CRYPT_OK if successful
    */
    */
-   void (*accel_ccm_memory)(
+   int (*accel_ccm_memory)(
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *key,    unsigned long keylen,
+       symmetric_key       *uskey,
        const unsigned char *nonce,  unsigned long noncelen,
        const unsigned char *nonce,  unsigned long noncelen,
        const unsigned char *header, unsigned long headerlen,
        const unsigned char *header, unsigned long headerlen,
              unsigned char *pt,     unsigned long ptlen,
              unsigned char *pt,     unsigned long ptlen,
@@ -4143,8 +4281,9 @@ struct ltc_cipher_descriptor {
        @param tag               [out] The MAC tag
        @param tag               [out] The MAC tag
        @param taglen            [in/out] The MAC tag length
        @param taglen            [in/out] The MAC tag length
        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
+       @return CRYPT_OK on success
    */
    */
-   void (*accel_gcm_memory)(
+   int (*accel_gcm_memory)(
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *IV,     unsigned long IVlen,
        const unsigned char *IV,     unsigned long IVlen,
        const unsigned char *adata,  unsigned long adatalen,
        const unsigned char *adata,  unsigned long adatalen,
@@ -4152,7 +4291,6 @@ struct ltc_cipher_descriptor {
              unsigned char *ct, 
              unsigned char *ct, 
              unsigned char *tag,    unsigned long *taglen,
              unsigned char *tag,    unsigned long *taglen,
                        int direction);
                        int direction);
-
 };
 };
 \end{verbatim}
 \end{verbatim}
 \end{small}
 \end{small}
@@ -4231,8 +4369,22 @@ buffer provided) before encrypting it to create the pad.
 The accelerator will only be used to encrypt whole blocks.  Partial blocks are always handled in software.
 The accelerator will only be used to encrypt whole blocks.  Partial blocks are always handled in software.
 
 
 \subsubsection{Accelerated CCM}
 \subsubsection{Accelerated CCM}
-This function is meant for accelerated CCM encryption or decryption.  It processes the entire packet in one call.  Note that the setup() function will not
-be called prior to this.  This function must handle scheduling the key provided on its own.
+This function is meant for accelerated CCM encryption or decryption.  It processes the entire packet in one call.  You can optimize the work flow somewhat
+by allowing the caller to call the setup() function first to schedule the key if your accelerator cannot do the key schedule on the fly (for instance).  This 
+function MUST support both key passing methods.
+
+\begin{center}
+\begin{small}
+\begin{tabular}{|r|r|l|}
+\hline \textbf{key} & \textbf{uskey} & \textbf{Source of key} \\
+\hline NULL         & NULL           & Error, not supported \\
+\hline non-NULL     & NULL           & Use key, do a key schedule \\
+\hline NULL         & non-NULL       & Use uskey, key schedule not required \\
+\hline non-NULL     & non-NULL       & Use uskey, key schedule not required \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
 
 
 \subsubsection{Accelerated GCM}
 \subsubsection{Accelerated GCM}
 This function is meant for accelerated GCM encryption or decryption.  It processes the entire packet in one call.  Note that the setup() function will not
 This function is meant for accelerated GCM encryption or decryption.  It processes the entire packet in one call.  Note that the setup() function will not
@@ -4560,7 +4712,6 @@ typedef struct {
    */
    */
    int (*add)(void *a, void *b, void *c);
    int (*add)(void *a, void *b, void *c);
 
 
-
    /** add two integers 
    /** add two integers 
      @param a   The first source integer
      @param a   The first source integer
      @param b   The second source integer (single digit of upto bits_per_digit in length)
      @param b   The second source integer (single digit of upto bits_per_digit in length)
@@ -4748,6 +4899,16 @@ typedef struct {
 
 
 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
 
 
+   /** RSA Key Generation 
+       @param prng     An active PRNG state
+       @param wprng    The index of the PRNG desired
+       @param size     The size of the modulus (key size) desired (octets)
+       @param e        The "e" value (public key).  e==65537 is a good choice
+       @param key      [out] Destination of a newly created private key pair
+       @return CRYPT_OK if successful, upon error all allocated ram is freed
+    */
+    int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
+
    /** RSA exponentiation
    /** RSA exponentiation
       @param in       The octet array representing the base
       @param in       The octet array representing the base
       @param inlen    The length of the input
       @param inlen    The length of the input
@@ -4851,5 +5012,5 @@ Since the function is given the entire RSA key (for private keys only) CRT is po
 \end{document}
 \end{document}
 
 
 % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $   
 % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $   
-% $Revision: 1.45 $   
-% $Date: 2005/08/01 16:59:29 $ 
+% $Revision: 1.55 $   
+% $Date: 2005/11/18 01:45:03 $ 

+ 2 - 2
demos/encrypt.c

@@ -170,7 +170,7 @@ int main(int argc, char *argv[])
          exit(-1);
          exit(-1);
       }
       }
    
    
-      if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
+      if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
          printf("ctr_start error: %s\n",error_to_string(errno));
          printf("ctr_start error: %s\n",error_to_string(errno));
          exit(-1);
          exit(-1);
       }
       }
@@ -212,7 +212,7 @@ int main(int argc, char *argv[])
          exit(-1);
          exit(-1);
       }
       }
 
 
-      if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
+      if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
          printf("ctr_start error: %s\n",error_to_string(errno));
          printf("ctr_start error: %s\n",error_to_string(errno));
          exit(-1);
          exit(-1);
       }
       }

+ 2 - 1
demos/test.c

@@ -22,8 +22,9 @@ int main(void)
    printf("\nmac_test......"); fflush(stdout); x = mac_test();         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("\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("\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("\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("\ndsa_test......"); fflush(stdout); x = dsa_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
+   printf("\nkatja_test...."); fflush(stdout); x = katja_test();       printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
    printf("\n");
    printf("\n");
    return EXIT_SUCCESS;
    return EXIT_SUCCESS;
 }
 }

+ 3 - 1
demos/timing.c

@@ -14,7 +14,6 @@ reg_algs();
    extern ltc_math_descriptor EXT_MATH_LIB;
    extern ltc_math_descriptor EXT_MATH_LIB;
    ltc_mp = EXT_MATH_LIB;
    ltc_mp = EXT_MATH_LIB;
 #endif
 #endif
-
 time_keysched();
 time_keysched();
 time_cipher();
 time_cipher();
 time_cipher2();
 time_cipher2();
@@ -27,6 +26,9 @@ time_mult();
 time_sqr();
 time_sqr();
 time_rsa();
 time_rsa();
 time_ecc();
 time_ecc();
+#ifdef USE_LTM
+time_katja();
+#endif
 return EXIT_SUCCESS;
 return EXIT_SUCCESS;
 
 
 }
 }

+ 2 - 2
demos/tv_gen.c

@@ -551,7 +551,7 @@ void ccm_gen(void)
             plaintext[z] = (unsigned char)(z & 255);
             plaintext[z] = (unsigned char)(z & 255);
          }
          }
          len = sizeof(tag);
          len = sizeof(tag);
-         if ((err = ccm_memory(x, key, kl, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
+         if ((err = ccm_memory(x, key, kl, NULL, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
             printf("Error CCM'ing: %s\n", error_to_string(err));
             printf("Error CCM'ing: %s\n", error_to_string(err));
             exit(EXIT_FAILURE);
             exit(EXIT_FAILURE);
          }
          }
@@ -682,7 +682,7 @@ void ecc_gen(void)
         mp_set(G->z, 1);  
         mp_set(G->z, 1);  
 
 
         while (mp_cmp(k, order) == LTC_MP_LT) {
         while (mp_cmp(k, order) == LTC_MP_LT) {
-            ltc_ecc_mulmod(k, G, R, modulus, 1);
+            ltc_mp.ecc_ptmul(k, G, R, modulus, 1);
             mp_tohex(k,    str); fprintf(out, "%s, ", str);
             mp_tohex(k,    str); fprintf(out, "%s, ", str);
             mp_tohex(R->x, str); fprintf(out, "%s, ", str);
             mp_tohex(R->x, str); fprintf(out, "%s, ", str);
             mp_tohex(R->y, str); fprintf(out, "%s\n", str);
             mp_tohex(R->y, str); fprintf(out, "%s\n", str);

BIN
doc/crypt.pdf


+ 51 - 29
makefile

@@ -4,7 +4,7 @@
 # Modified by Clay Culver
 # Modified by Clay Culver
 
 
 # The version
 # The version
-VERSION=1.06
+VERSION=1.07
 
 
 # Compiler and Linker Names
 # Compiler and Linker Names
 #CC=gcc
 #CC=gcc
@@ -14,12 +14,23 @@ VERSION=1.06
 #AR=ar
 #AR=ar
 #ARFLAGS=r
 #ARFLAGS=r
 
 
+ifndef MAKE
+  MAKE=make
+endif
+
+# ranlib tools
+ifndef RANLIB
+   RANLIB=ranlib
+endif
+
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter -DLTC_SOURCE
 CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter -DLTC_SOURCE
 
 
 # additional warnings (newer GCC 3.4 and higher)
 # additional warnings (newer GCC 3.4 and higher)
-#CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
-#		  -Wmissing-declarations -Wpointer-arith 
+ifdef GCC_34
+CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
+		  -Wmissing-declarations -Wpointer-arith 
+endif
 
 
 ifndef IGNORE_SPEED
 ifndef IGNORE_SPEED
 
 
@@ -47,8 +58,8 @@ ifndef LIBNAME
 endif
 endif
 ifndef LIBTEST
 ifndef LIBTEST
    LIBTEST=libtomcrypt_prof.a
    LIBTEST=libtomcrypt_prof.a
-   LIBTEST_S=$(LIBTEST)
 endif
 endif
+LIBTEST_S=$(LIBTEST)
 
 
 HASH=hashsum
 HASH=hashsum
 CRYPT=encrypt
 CRYPT=encrypt
@@ -154,22 +165,31 @@ 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_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_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/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/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.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/sequence/der_sequence_free.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_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/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/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.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_decrypt_key.o src/pk/dsa/dsa_encrypt_key.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_shared_secret.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/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/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_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/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
+src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
+src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
+src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
+src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
+src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
+src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
+src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
+src/pk/katja/katja_make_key.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_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/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 HEADERS=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_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@@ -203,8 +223,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
 src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
 src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
 src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
-src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
-src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
 src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
 src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 
 
@@ -212,11 +230,11 @@ src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 library: $(LIBNAME)
 library: $(LIBNAME)
 
 
 testprof/$(LIBTEST): 
 testprof/$(LIBTEST): 
-	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) make 
+	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) 
 
 
 $(LIBNAME): $(OBJECTS)
 $(LIBNAME): $(OBJECTS)
 	$(AR) $(ARFLAGS) $@ $(OBJECTS) 
 	$(AR) $(ARFLAGS) $@ $(OBJECTS) 
-	ranlib $(LIBNAME)
+	$(RANLIB) $@
 
 
 #This rule makes the hash program included with libtomcrypt
 #This rule makes the hash program included with libtomcrypt
 hashsum: library $(HASHOBJECTS)
 hashsum: library $(HASHOBJECTS)
@@ -242,28 +260,33 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
 test: library testprof/$(LIBTEST) $(TESTS)
 test: library testprof/$(LIBTEST) $(TESTS)
 	$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST)
 	$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST)
 
 
-
 #This rule installs the library and the header files. This must be run
 #This rule installs the library and the header files. This must be run
 #as root in order to have a high enough permission to write to the correct
 #as root in order to have a high enough permission to write to the correct
 #directories and to set the owner and group to root.
 #directories and to set the owner and group to root.
+ifndef NODOCS
 install: library docs
 install: library docs
+else
+install: library
+endif
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
 	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
 	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
+ifndef NODOCS
 	install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH)
 	install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH)
+endif
 
 
-install_test: $(LIBTEST)
+install_test: testprof/$(LIBTEST)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
-	install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH)
+	install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH)
 
 
 profile:
 profile:
-	CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov
+	CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
 	./timing
 	./timing
 	rm -f timing `find . -type f | grep [.][ao] | xargs`
 	rm -f timing `find . -type f | grep [.][ao] | xargs`
-	CFLAGS="$(CFLAGS) -fprofile-use" make timing EXTRALIBS=-lgcov
+	CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
 
 
 
 
 #This rule cleans the source tree of all compiled code, not including the pdf
 #This rule cleans the source tree of all compiled code, not including the pdf
@@ -291,7 +314,7 @@ clean:
 #build the doxy files (requires Doxygen, tetex and patience)
 #build the doxy files (requires Doxygen, tetex and patience)
 doxy:
 doxy:
 	doxygen
 	doxygen
-	cd doc/doxygen/latex ; make ; mv -f refman.pdf ../../.
+	cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../.
 	echo The huge doxygen PDF should be available as doc/refman.pdf
 	echo The huge doxygen PDF should be available as doc/refman.pdf
 	
 	
 #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
 #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
@@ -333,6 +356,5 @@ zipup: no_oops docs
 
 
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
 # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
-# $Revision: 1.86 $ 
-# $Date: 2005/07/30 04:54:20 $ 
-
+# $Revision: 1.103 $ 
+# $Date: 2005/11/18 01:46:22 $ 

+ 23 - 16
makefile.icc

@@ -152,22 +152,31 @@ 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_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_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/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/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.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/sequence/der_sequence_free.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_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/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/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.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_decrypt_key.o src/pk/dsa/dsa_encrypt_key.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_shared_secret.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/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/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_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/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
+src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
+src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
+src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
+src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
+src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
+src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
+src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
+src/pk/katja/katja_make_key.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_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/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 HEADERS=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_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@@ -207,8 +216,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
 src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
 src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
 src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
-src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
-src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
 src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
 src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 
 
@@ -254,5 +261,5 @@ install: library
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $   
 # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $   
-# $Revision: 1.39 $   
-# $Date: 2005/07/30 23:38:39 $ 
+# $Revision: 1.44 $   
+# $Date: 2005/11/18 01:46:22 $ 

+ 25 - 15
makefile.msvc

@@ -1,7 +1,7 @@
 #MSVC Makefile [tested with MSVC 6.00 with SP5]
 #MSVC Makefile [tested with MSVC 6.00 with SP5]
 #
 #
 #Tom St Denis
 #Tom St Denis
-CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@
+CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF)
 
 
 OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
 OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
 src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
 src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
@@ -67,22 +67,31 @@ 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_decode_printable_string.obj \
 src/pk/asn1/der/printable_string/der_encode_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/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/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_flexi.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/sequence/der_sequence_free.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_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/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/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.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_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.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_shared_secret.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/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/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_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/ecc/ecc_decrypt_key.obj src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_free.obj \
+src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.obj \
+src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj \
+src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ltc_ecc_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj \
+src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \
+src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \
+src/pk/katja/katja_decrypt_key.obj src/pk/katja/katja_encrypt_key.obj src/pk/katja/katja_export.obj \
+src/pk/katja/katja_exptmod.obj src/pk/katja/katja_free.obj src/pk/katja/katja_import.obj \
+src/pk/katja/katja_make_key.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_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/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 HEADERS=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_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@@ -115,5 +124,6 @@ timing: demos/timing.c library
 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $   
 # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $   
-# $Revision: 1.17 $   
-# $Date: 2005/07/30 23:42:57 $ 
+# $Revision: 1.24 $   
+# $Date: 2005/11/18 01:46:22 $ 
+

+ 40 - 22
makefile.shared

@@ -6,10 +6,15 @@
 # Tom St Denis
 # Tom St Denis
 
 
 # The version
 # The version
-VERSION=0:106
+VERSION=0:107
 
 
 # Compiler and Linker Names
 # Compiler and Linker Names
-CC=libtool --mode=compile gcc
+CC=libtool --mode=compile gcc 
+
+# ranlib tools
+ifndef RANLIB
+   RANLIB=ranlib
+endif
 
 
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE
 CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE
@@ -39,8 +44,10 @@ endif
 #CFLAGS += -DLTC_NO_ROLC
 #CFLAGS += -DLTC_NO_ROLC
 
 
 #Output filenames for various targets.
 #Output filenames for various targets.
-ifndef LIBTEST
+ifndef LIBTEST_S
    LIBTEST_S=libtomcrypt_prof.a
    LIBTEST_S=libtomcrypt_prof.a
+endif
+ifndef LIBTEST
    LIBTEST=libtomcrypt_prof.la
    LIBTEST=libtomcrypt_prof.la
 endif
 endif
 ifndef LIBNAME
 ifndef LIBNAME
@@ -152,22 +159,31 @@ 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_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_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/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/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.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/sequence/der_sequence_free.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_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/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/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.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_decrypt_key.o src/pk/dsa/dsa_encrypt_key.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_shared_secret.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/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/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_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/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
+src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
+src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
+src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
+src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
+src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
+src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
+src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
+src/pk/katja/katja_make_key.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_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/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 HEADERS=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_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@@ -194,8 +210,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
 src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
 src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
 src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
 src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
-src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
-src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
 src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
 src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
 
 
@@ -205,10 +219,13 @@ library: $(LIBNAME)
 testprof/$(LIBTEST):
 testprof/$(LIBTEST):
 	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared
 	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared
 
 
-$(LIBNAME): $(OBJECTS)
+objs: $(OBJECTS)
+
+$(LIBNAME): $(OBJECTS) testprof/$(LIBTEST)
 	libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION)
 	libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION)
-	libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | grep "src/" | xargs`  $(EXTRALIBS) -o $(LIBNAME_S)
-	ranlib $(LIBNAME_S)
+
+install: $(LIBNAME)
+	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared install
 	libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la
 	libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
@@ -233,5 +250,6 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $   
 # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $   
-# $Revision: 1.25 $   
-# $Date: 2005/07/30 04:54:20 $ 
+# $Revision: 1.36 $   
+# $Date: 2005/11/18 01:46:22 $ 
+

+ 16 - 8
src/ciphers/aes/aes.c

@@ -281,11 +281,12 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s
   @param pt The input plaintext (16 bytes)
   @param pt The input plaintext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
+static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
 #else
 #else
-void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@@ -440,13 +441,16 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
         (Te4_0[byte(t2, 0)]) ^ 
         (Te4_0[byte(t2, 0)]) ^ 
         rk[3];
         rk[3];
     STORE32H(s3, ct+12);
     STORE32H(s3, ct+12);
+
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
+int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
 {
 {
-   _rijndael_ecb_encrypt(pt, ct, skey);
+   int err = _rijndael_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
+   return err;
 }
 }
 #endif
 #endif
 
 
@@ -457,11 +461,12 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
   @param ct The input ciphertext (16 bytes)
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
+static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
 #else
 #else
-void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@@ -615,14 +620,17 @@ void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
         (Td4[byte(t0, 0)] & 0x000000ff) ^
         (Td4[byte(t0, 0)] & 0x000000ff) ^
         rk[3];
         rk[3];
     STORE32H(s3, pt+12);
     STORE32H(s3, pt+12);
+
+    return CRYPT_OK;
 }
 }
 
 
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
+int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
 {
 {
-   _rijndael_ecb_decrypt(ct, pt, skey);
+   int err = _rijndael_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 6 - 2
src/ciphers/anubis.c

@@ -1134,13 +1134,15 @@ static void anubis_crypt(const unsigned char *plaintext, unsigned char *cipherte
   @param pt The input plaintext (16 bytes)
   @param pt The input plaintext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
-void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(skey != NULL);
    LTC_ARGCHK(skey != NULL);
    anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
    anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -1148,13 +1150,15 @@ void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
   @param ct The input ciphertext (16 bytes)
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
-void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(skey != NULL);
    LTC_ARGCHK(skey != NULL);
    anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);
    anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**

+ 15 - 8
src/ciphers/blowfish.c

@@ -385,11 +385,12 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 L, R;
    ulong32 L, R;
@@ -428,13 +429,16 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
    /* store */
    /* store */
    STORE32H(R, &ct[0]);
    STORE32H(R, &ct[0]);
    STORE32H(L, &ct[4]);
    STORE32H(L, &ct[4]);
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-    _blowfish_ecb_encrypt(pt, ct, skey);
+    int err = _blowfish_ecb_encrypt(pt, ct, skey);
     burn_stack(sizeof(ulong32) * 2 + sizeof(int));
     burn_stack(sizeof(ulong32) * 2 + sizeof(int));
+    return err;
 }
 }
 #endif
 #endif
 
 
@@ -443,11 +447,12 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 L, R;
    ulong32 L, R;
@@ -486,13 +491,15 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
    /* store */
    /* store */
    STORE32H(L, &pt[0]);
    STORE32H(L, &pt[0]);
    STORE32H(R, &pt[4]);
    STORE32H(R, &pt[4]);
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-    _blowfish_ecb_decrypt(ct, pt, skey);
+    int err = _blowfish_ecb_decrypt(ct, pt, skey);
     burn_stack(sizeof(ulong32) * 2 + sizeof(int));
     burn_stack(sizeof(ulong32) * 2 + sizeof(int));
+    return err;
 }
 }
 #endif
 #endif
 
 

+ 13 - 8
src/ciphers/cast5.c

@@ -536,9 +536,9 @@ INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
   @param skey The key as scheduled
   @param skey The key as scheduled
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 R, L;
    ulong32 R, L;
@@ -569,14 +569,16 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
    }
    }
    STORE32H(R,&ct[0]);
    STORE32H(R,&ct[0]);
    STORE32H(L,&ct[4]);
    STORE32H(L,&ct[4]);
+   return CRYPT_OK;
 }
 }
 
 
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-   _cast5_ecb_encrypt(pt,ct,skey);
+   int err =_cast5_ecb_encrypt(pt,ct,skey);
    burn_stack(sizeof(ulong32)*3);
    burn_stack(sizeof(ulong32)*3);
+   return err;
 }
 }
 #endif
 #endif
 
 
@@ -587,9 +589,9 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
   @param skey The key as scheduled 
   @param skey The key as scheduled 
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 R, L;
    ulong32 R, L;
@@ -620,13 +622,16 @@ void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
    L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
    L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
    STORE32H(L,&pt[0]);
    STORE32H(L,&pt[0]);
    STORE32H(R,&pt[4]);
    STORE32H(R,&pt[4]);
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-   _cast5_ecb_decrypt(ct,pt,skey);
+   int err = _cast5_ecb_decrypt(ct,pt,skey);
    burn_stack(sizeof(ulong32)*3);
    burn_stack(sizeof(ulong32)*3);
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 13 - 5
src/ciphers/des.c

@@ -1582,8 +1582,9 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
-void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
     ulong32 work[2];
     ulong32 work[2];
     LTC_ARGCHK(pt   != NULL);
     LTC_ARGCHK(pt   != NULL);
@@ -1594,6 +1595,7 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
     desfunc(work, skey->des.ek);
     desfunc(work, skey->des.ek);
     STORE32H(work[0],ct+0);
     STORE32H(work[0],ct+0);
     STORE32H(work[1],ct+4);
     STORE32H(work[1],ct+4);
+    return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -1601,8 +1603,9 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
-void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
     ulong32 work[2];
     ulong32 work[2];
     LTC_ARGCHK(pt   != NULL);
     LTC_ARGCHK(pt   != NULL);
@@ -1612,7 +1615,8 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
     LOAD32H(work[1], ct+4);
     LOAD32H(work[1], ct+4);
     desfunc(work, skey->des.dk);
     desfunc(work, skey->des.dk);
     STORE32H(work[0],pt+0);
     STORE32H(work[0],pt+0);
-    STORE32H(work[1],pt+4);
+    STORE32H(work[1],pt+4);  
+    return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -1620,8 +1624,9 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
-void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
     ulong32 work[2];
     ulong32 work[2];
     
     
@@ -1635,6 +1640,7 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
     desfunc(work, skey->des3.ek[2]);
     desfunc(work, skey->des3.ek[2]);
     STORE32H(work[0],ct+0);
     STORE32H(work[0],ct+0);
     STORE32H(work[1],ct+4);
     STORE32H(work[1],ct+4);
+    return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -1642,8 +1648,9 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
-void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
     ulong32 work[2];
     ulong32 work[2];
     LTC_ARGCHK(pt   != NULL);
     LTC_ARGCHK(pt   != NULL);
@@ -1656,6 +1663,7 @@ void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
     desfunc(work, skey->des3.dk[2]);
     desfunc(work, skey->des3.dk[2]);
     STORE32H(work[0],pt+0);
     STORE32H(work[0],pt+0);
     STORE32H(work[1],pt+4);
     STORE32H(work[1],pt+4);
+    return CRYPT_OK;
 }
 }
 
 
 /**
 /**

+ 6 - 2
src/ciphers/khazad.c

@@ -741,13 +741,15 @@ static void khazad_crypt(const unsigned char *plaintext, unsigned char *cipherte
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
-void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(skey != NULL);
    LTC_ARGCHK(skey != NULL);
    khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
    khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -755,13 +757,15 @@ void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
-void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(pt   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(ct   != NULL);
    LTC_ARGCHK(skey != NULL);
    LTC_ARGCHK(skey != NULL);
    khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
    khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**

+ 15 - 8
src/ciphers/noekeon.c

@@ -107,11 +107,12 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
   @param pt The input plaintext (16 bytes)
   @param pt The input plaintext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 a,b,c,d,temp;
    ulong32 a,b,c,d,temp;
@@ -142,13 +143,16 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
    
    
    STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
    STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
    STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
    STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-   _noekeon_ecb_encrypt(pt, ct, skey);
+   int err = _noekeon_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(ulong32) * 5 + sizeof(int));
    burn_stack(sizeof(ulong32) * 5 + sizeof(int));
+   return CRYPT_OK;
 }
 }
 #endif
 #endif
 
 
@@ -157,11 +161,12 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
   @param ct The input ciphertext (16 bytes)
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 a,b,c,d, temp;
    ulong32 a,b,c,d, temp;
@@ -192,13 +197,15 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
    a ^= RC[0];
    a ^= RC[0];
    STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
    STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
    STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
    STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-   _noekeon_ecb_decrypt(ct, pt, skey);
+   int err = _noekeon_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(ulong32) * 5 + sizeof(int));
    burn_stack(sizeof(ulong32) * 5 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 16 - 8
src/ciphers/rc2.c

@@ -125,13 +125,14 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rc2_ecb_encrypt( const unsigned char *pt,
+static int _rc2_ecb_encrypt( const unsigned char *pt,
                             unsigned char *ct,
                             unsigned char *ct,
                             symmetric_key *skey)
                             symmetric_key *skey)
 #else
 #else
-void rc2_ecb_encrypt( const unsigned char *pt,
+int rc2_ecb_encrypt( const unsigned char *pt,
                             unsigned char *ct,
                             unsigned char *ct,
                             symmetric_key *skey)
                             symmetric_key *skey)
 #endif
 #endif
@@ -179,15 +180,18 @@ void rc2_ecb_encrypt( const unsigned char *pt,
     ct[5] = (unsigned char)(x54 >> 8);
     ct[5] = (unsigned char)(x54 >> 8);
     ct[6] = (unsigned char)x76;
     ct[6] = (unsigned char)x76;
     ct[7] = (unsigned char)(x76 >> 8);
     ct[7] = (unsigned char)(x76 >> 8);
+ 
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void rc2_ecb_encrypt( const unsigned char *pt,
+int rc2_ecb_encrypt( const unsigned char *pt,
                             unsigned char *ct,
                             unsigned char *ct,
                             symmetric_key *skey)
                             symmetric_key *skey)
 {
 {
-    _rc2_ecb_encrypt(pt, ct, skey);
+    int err = _rc2_ecb_encrypt(pt, ct, skey);
     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
+    return err;
 }
 }
 #endif
 #endif
 
 
@@ -199,13 +203,14 @@ void rc2_ecb_encrypt( const unsigned char *pt,
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rc2_ecb_decrypt( const unsigned char *ct,
+static int _rc2_ecb_decrypt( const unsigned char *ct,
                             unsigned char *pt,
                             unsigned char *pt,
                             symmetric_key *skey)
                             symmetric_key *skey)
 #else
 #else
-void rc2_ecb_decrypt( const unsigned char *ct,
+int rc2_ecb_decrypt( const unsigned char *ct,
                             unsigned char *pt,
                             unsigned char *pt,
                             symmetric_key *skey)
                             symmetric_key *skey)
 #endif
 #endif
@@ -254,15 +259,18 @@ void rc2_ecb_decrypt( const unsigned char *ct,
     pt[5] = (unsigned char)(x54 >> 8);
     pt[5] = (unsigned char)(x54 >> 8);
     pt[6] = (unsigned char)x76;
     pt[6] = (unsigned char)x76;
     pt[7] = (unsigned char)(x76 >> 8);
     pt[7] = (unsigned char)(x76 >> 8);
+
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void rc2_ecb_decrypt( const unsigned char *ct,
+int rc2_ecb_decrypt( const unsigned char *ct,
                             unsigned char *pt,
                             unsigned char *pt,
                             symmetric_key *skey)
                             symmetric_key *skey)
 {
 {
-    _rc2_ecb_decrypt(ct, pt, skey);
+    int err = _rc2_ecb_decrypt(ct, pt, skey);
     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
+    return err;
 }
 }
 #endif
 #endif
 
 

+ 16 - 8
src/ciphers/rc5.c

@@ -123,11 +123,12 @@ int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 A, B, *K;
    ulong32 A, B, *K;
@@ -159,13 +160,16 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
    }
    }
    STORE32L(A, &ct[0]);
    STORE32L(A, &ct[0]);
    STORE32L(B, &ct[4]);
    STORE32L(B, &ct[4]);
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-   _rc5_ecb_encrypt(pt, ct, skey);
+   int err = _rc5_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(ulong32) * 2 + sizeof(int));
    burn_stack(sizeof(ulong32) * 2 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 
@@ -174,11 +178,12 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 A, B, *K;
    ulong32 A, B, *K;
@@ -211,13 +216,16 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
    B -= skey->rc5.K[1];
    B -= skey->rc5.K[1];
    STORE32L(A, &pt[0]);
    STORE32L(A, &pt[0]);
    STORE32L(B, &pt[4]);
    STORE32L(B, &pt[4]);
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-   _rc5_ecb_decrypt(ct, pt, skey);
+   int err = _rc5_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(ulong32) * 2 + sizeof(int));
    burn_stack(sizeof(ulong32) * 2 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 13 - 8
src/ciphers/rc6.c

@@ -120,9 +120,9 @@ int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
   @param skey The key as scheduled
   @param skey The key as scheduled
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 a,b,c,d,t,u, *K;
    ulong32 a,b,c,d,t,u, *K;
@@ -155,13 +155,15 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
    a += skey->rc6.K[42];
    a += skey->rc6.K[42];
    c += skey->rc6.K[43];
    c += skey->rc6.K[43];
    STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
    STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-   _rc6_ecb_encrypt(pt, ct, skey);
+   int err = _rc6_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(ulong32) * 6 + sizeof(int));
    burn_stack(sizeof(ulong32) * 6 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 
@@ -172,9 +174,9 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
   @param skey The key as scheduled 
   @param skey The key as scheduled 
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
    ulong32 a,b,c,d,t,u, *K;
    ulong32 a,b,c,d,t,u, *K;
@@ -208,13 +210,16 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
    b -= skey->rc6.K[0];
    b -= skey->rc6.K[0];
    d -= skey->rc6.K[1];
    d -= skey->rc6.K[1];
    STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
    STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-   _rc6_ecb_decrypt(ct, pt, skey);
+   int err = _rc6_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(ulong32) * 6 + sizeof(int));
    burn_stack(sizeof(ulong32) * 6 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 12 - 8
src/ciphers/safer/safer.c

@@ -246,11 +246,11 @@ int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symme
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _safer_ecb_encrypt(const unsigned char *block_in,
+static int _safer_ecb_encrypt(const unsigned char *block_in,
                              unsigned char *block_out,
                              unsigned char *block_out,
                              symmetric_key *skey)
                              symmetric_key *skey)
 #else
 #else
-void safer_ecb_encrypt(const unsigned char *block_in,
+int safer_ecb_encrypt(const unsigned char *block_in,
                              unsigned char *block_out,
                              unsigned char *block_out,
                              symmetric_key *skey)
                              symmetric_key *skey)
 #endif
 #endif
@@ -285,24 +285,26 @@ void safer_ecb_encrypt(const unsigned char *block_in,
     block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
     block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void safer_ecb_encrypt(const unsigned char *block_in,
+int safer_ecb_encrypt(const unsigned char *block_in,
                              unsigned char *block_out,
                              unsigned char *block_out,
                              symmetric_key *skey)
                              symmetric_key *skey)
 {
 {
-    _safer_ecb_encrypt(block_in, block_out, skey);
+    int err = _safer_ecb_encrypt(block_in, block_out, skey);
     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
+    return err;
 }
 }
 #endif
 #endif
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _safer_ecb_decrypt(const unsigned char *block_in,
+static int _safer_ecb_decrypt(const unsigned char *block_in,
                              unsigned char *block_out,
                              unsigned char *block_out,
                              symmetric_key *skey)
                              symmetric_key *skey)
 #else
 #else
-void safer_ecb_decrypt(const unsigned char *block_in,
+int safer_ecb_decrypt(const unsigned char *block_in,
                              unsigned char *block_out,
                              unsigned char *block_out,
                              symmetric_key *skey)
                              symmetric_key *skey)
 #endif
 #endif
@@ -338,15 +340,17 @@ void safer_ecb_decrypt(const unsigned char *block_in,
     block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
     block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void safer_ecb_decrypt(const unsigned char *block_in,
+int safer_ecb_decrypt(const unsigned char *block_in,
                              unsigned char *block_out,
                              unsigned char *block_out,
                              symmetric_key *skey)
                              symmetric_key *skey)
 {
 {
-    _safer_ecb_decrypt(block_in, block_out, skey);
+    int err = _safer_ecb_decrypt(block_in, block_out, skey);
     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
+    return err;
 }
 }
 #endif
 #endif
 
 

+ 6 - 2
src/ciphers/safer/saferp.c

@@ -329,8 +329,9 @@ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric
   @param pt The input plaintext (16 bytes)
   @param pt The input plaintext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
-void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
    unsigned char b[16];
    unsigned char b[16];
    int x;
    int x;
@@ -384,6 +385,7 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
    zeromem(b, sizeof(b));
    zeromem(b, sizeof(b));
 #endif
 #endif
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -391,8 +393,9 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
   @param ct The input ciphertext (16 bytes)
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
-void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
    unsigned char b[16];
    unsigned char b[16];
    int x;
    int x;
@@ -446,6 +449,7 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
    zeromem(b, sizeof(b));
    zeromem(b, sizeof(b));
 #endif
 #endif
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**

+ 16 - 8
src/ciphers/skipjack.c

@@ -138,11 +138,12 @@ static unsigned ig_func(unsigned w, int *kp, unsigned char *key)
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
    unsigned w1,w2,w3,w4,tmp,tmp1;
    unsigned w1,w2,w3,w4,tmp,tmp1;
@@ -183,13 +184,16 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
    ct[2] = (w2>>8)&255; ct[3] = w2&255;
    ct[2] = (w2>>8)&255; ct[3] = w2&255;
    ct[4] = (w3>>8)&255; ct[5] = w3&255;
    ct[4] = (w3>>8)&255; ct[5] = w3&255;
    ct[6] = (w4>>8)&255; ct[7] = w4&255;
    ct[6] = (w4>>8)&255; ct[7] = w4&255;
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-   _skipjack_ecb_encrypt(pt, ct, skey);
+   int err = _skipjack_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
    burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
+   return err;
 }
 }
 #endif
 #endif
 
 
@@ -198,11 +202,12 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
    unsigned w1,w2,w3,w4,tmp;
    unsigned w1,w2,w3,w4,tmp;
@@ -247,13 +252,16 @@ void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
    pt[2] = (w2>>8)&255; pt[3] = w2&255;
    pt[2] = (w2>>8)&255; pt[3] = w2&255;
    pt[4] = (w3>>8)&255; pt[5] = w3&255;
    pt[4] = (w3>>8)&255; pt[5] = w3&255;
    pt[6] = (w4>>8)&255; pt[7] = w4&255;
    pt[6] = (w4>>8)&255; pt[7] = w4&255;
+
+   return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-   _skipjack_ecb_decrypt(ct, pt, skey);
+   int err = _skipjack_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
    burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 15 - 8
src/ciphers/twofish/twofish.c

@@ -465,11 +465,12 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
   @param pt The input plaintext (16 bytes)
   @param pt The input plaintext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param ct The output ciphertext (16 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #else
 #else
-void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 #endif
 {
 {
     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
@@ -519,13 +520,16 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
     /* store output */
     /* store output */
     STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
     STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
     STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
     STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
+
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
-   _twofish_ecb_encrypt(pt, ct, skey);
+   int err = _twofish_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(ulong32) * 10 + sizeof(int));
    burn_stack(sizeof(ulong32) * 10 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 
@@ -534,11 +538,12 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
   @param ct The input ciphertext (16 bytes)
   @param ct The input ciphertext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param pt The output plaintext (16 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #else
 #else
-void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 #endif
 {
 {
     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
@@ -591,13 +596,15 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
     /* store */
     /* store */
     STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
     STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
     STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
     STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
+    return CRYPT_OK;
 }
 }
 
 
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
-void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
-   _twofish_ecb_decrypt(ct, pt, skey);
+   int err =_twofish_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(ulong32) * 10 + sizeof(int));
    burn_stack(sizeof(ulong32) * 10 + sizeof(int));
+   return err;
 }
 }
 #endif
 #endif
 
 

+ 6 - 2
src/ciphers/xtea.c

@@ -71,8 +71,9 @@ int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
   @param pt The input plaintext (8 bytes)
   @param pt The input plaintext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param ct The output ciphertext (8 bytes)
   @param skey The key as scheduled
   @param skey The key as scheduled
+  @return CRYPT_OK if successful
 */
 */
-void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 {
 {
    unsigned long y, z;
    unsigned long y, z;
    int r;
    int r;
@@ -98,6 +99,7 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
    }
    }
    STORE32L(y, &ct[0]);
    STORE32L(y, &ct[0]);
    STORE32L(z, &ct[4]);
    STORE32L(z, &ct[4]);
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**
@@ -105,8 +107,9 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
   @param ct The input ciphertext (8 bytes)
   @param ct The input ciphertext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param pt The output plaintext (8 bytes)
   @param skey The key as scheduled 
   @param skey The key as scheduled 
+  @return CRYPT_OK if successful
 */
 */
-void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 {
 {
    unsigned long y, z;
    unsigned long y, z;
    int r;
    int r;
@@ -132,6 +135,7 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
    }
    }
    STORE32L(y, &pt[0]);
    STORE32L(y, &pt[0]);
    STORE32L(z, &pt[4]);
    STORE32L(z, &pt[4]);
+   return CRYPT_OK;
 }
 }
 
 
 /**
 /**

+ 61 - 26
src/encauth/ccm/ccm_memory.c

@@ -22,6 +22,7 @@
    @param cipher     The index of the cipher desired
    @param cipher     The index of the cipher desired
    @param key        The secret key to use
    @param key        The secret key to use
    @param keylen     The length of the secret key (octets)
    @param keylen     The length of the secret key (octets)
+   @param uskey      A previously scheduled key [optional can be NULL]
    @param nonce      The session nonce [use once]
    @param nonce      The session nonce [use once]
    @param noncelen   The length of the nonce
    @param noncelen   The length of the nonce
    @param header     The header for the session
    @param header     The header for the session
@@ -36,6 +37,7 @@
 */
 */
 int ccm_memory(int cipher,
 int ccm_memory(int cipher,
     const unsigned char *key,    unsigned long keylen,
     const unsigned char *key,    unsigned long keylen,
+    symmetric_key       *uskey,
     const unsigned char *nonce,  unsigned long noncelen,
     const unsigned char *nonce,  unsigned long noncelen,
     const unsigned char *header, unsigned long headerlen,
     const unsigned char *header, unsigned long headerlen,
           unsigned char *pt,     unsigned long ptlen,
           unsigned char *pt,     unsigned long ptlen,
@@ -48,7 +50,9 @@ int ccm_memory(int cipher,
    int            err;
    int            err;
    unsigned long  len, L, x, y, z, CTRlen;
    unsigned long  len, L, x, y, z, CTRlen;
 
 
-   LTC_ARGCHK(key    != NULL);
+   if (uskey == NULL) {
+      LTC_ARGCHK(key    != NULL);
+   }
    LTC_ARGCHK(nonce  != NULL);
    LTC_ARGCHK(nonce  != NULL);
    if (headerlen > 0) {
    if (headerlen > 0) {
       LTC_ARGCHK(header != NULL);
       LTC_ARGCHK(header != NULL);
@@ -85,15 +89,15 @@ int ccm_memory(int cipher,
 
 
    /* is there an accelerator? */
    /* is there an accelerator? */
    if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
    if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
-       cipher_descriptor[cipher].accel_ccm_memory(
+       return cipher_descriptor[cipher].accel_ccm_memory(
            key,    keylen,
            key,    keylen,
+           uskey,
            nonce,  noncelen,
            nonce,  noncelen,
            header, headerlen,
            header, headerlen,
            pt,     ptlen,
            pt,     ptlen,
            ct, 
            ct, 
            tag,    taglen,
            tag,    taglen,
            direction);
            direction);
-      return CRYPT_OK;
    }
    }
 
 
    /* let's get the L value */
    /* let's get the L value */
@@ -114,15 +118,19 @@ int ccm_memory(int cipher,
    }
    }
 
 
    /* allocate mem for the symmetric key */
    /* allocate mem for the symmetric key */
-   skey = XMALLOC(sizeof(*skey));
-   if (skey == NULL) {
-      return CRYPT_MEM;
-   }
+   if (uskey == NULL) {
+      skey = XMALLOC(sizeof(*skey));
+      if (skey == NULL) {
+         return CRYPT_MEM;
+      }
 
 
-   /* initialize the cipher */
-   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
-      XFREE(skey);
-      return err;
+      /* initialize the cipher */
+      if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
+         XFREE(skey);
+         return err;
+      }
+   } else {
+      skey = uskey;
    }
    }
 
 
    /* form B_0 == flags | Nonce N | l(m) */
    /* form B_0 == flags | Nonce N | l(m) */
@@ -154,7 +162,9 @@ int ccm_memory(int cipher,
    }
    }
 
 
    /* encrypt PAD */
    /* encrypt PAD */
-   cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+       goto error;
+   }
 
 
    /* handle header */
    /* handle header */
    if (headerlen > 0) {
    if (headerlen > 0) {
@@ -177,7 +187,9 @@ int ccm_memory(int cipher,
       for (y = 0; y < headerlen; y++) {
       for (y = 0; y < headerlen; y++) {
           if (x == 16) {
           if (x == 16) {
              /* full block so let's encrypt it */
              /* full block so let's encrypt it */
-             cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+             if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+                goto error;
+             }
              x = 0;
              x = 0;
           }
           }
           PAD[x++] ^= header[y];
           PAD[x++] ^= header[y];
@@ -185,7 +197,9 @@ int ccm_memory(int cipher,
 
 
       /* remainder? */
       /* remainder? */
       if (x != 0) {
       if (x != 0) {
-         cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+         if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+            goto error;
+         }
       }
       }
    }
    }
 
 
@@ -219,14 +233,18 @@ int ccm_memory(int cipher,
                     ctr[z] = (ctr[z] + 1) & 255;
                     ctr[z] = (ctr[z] + 1) & 255;
                     if (ctr[z]) break;
                     if (ctr[z]) break;
                 }
                 }
-                cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
+                if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
+                   goto error;
+                }
 
 
                 /* xor the PT against the pad first */
                 /* xor the PT against the pad first */
                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
                     *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
                     *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
                 }
                 }
-                cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+                if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+                   goto error;
+                }
              }
              }
          } else {
          } else {
              for (; y < (ptlen & ~15); y += 16) {
              for (; y < (ptlen & ~15); y += 16) {
@@ -235,14 +253,18 @@ int ccm_memory(int cipher,
                     ctr[z] = (ctr[z] + 1) & 255;
                     ctr[z] = (ctr[z] + 1) & 255;
                     if (ctr[z]) break;
                     if (ctr[z]) break;
                 }
                 }
-                cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
+                if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
+                   goto error;
+                }
 
 
                 /* xor the PT against the pad last */
                 /* xor the PT against the pad last */
                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
                     *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
                     *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
                 }
                 }
-                cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+                if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+                   goto error;
+                }
              }
              }
          }
          }
      }
      }
@@ -255,7 +277,9 @@ int ccm_memory(int cipher,
                  ctr[z] = (ctr[z] + 1) & 255;
                  ctr[z] = (ctr[z] + 1) & 255;
                  if (ctr[z]) break;
                  if (ctr[z]) break;
              }
              }
-             cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
+             if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
+                goto error;
+             }
              CTRlen = 0;
              CTRlen = 0;
           }
           }
 
 
@@ -269,21 +293,30 @@ int ccm_memory(int cipher,
           }
           }
 
 
           if (x == 16) {
           if (x == 16) {
-             cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+             if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+                goto error;
+             }
              x = 0;
              x = 0;
           }
           }
           PAD[x++] ^= b;
           PAD[x++] ^= b;
       }
       }
              
              
       if (x != 0) {
       if (x != 0) {
-         cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
+         if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
+            goto error;
+         }
       }
       }
    }
    }
 
 
    /* setup CTR for the TAG */
    /* setup CTR for the TAG */
    ctr[14] = ctr[15] = 0x00;
    ctr[14] = ctr[15] = 0x00;
-   cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
-   cipher_descriptor[cipher].done(skey);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
+      goto error;
+   }
+
+   if (skey != uskey) {
+      cipher_descriptor[cipher].done(skey);
+   }
 
 
    /* store the TAG */
    /* store the TAG */
    for (x = 0; x < 16 && x < *taglen; x++) {
    for (x = 0; x < 16 && x < *taglen; x++) {
@@ -296,10 +329,12 @@ int ccm_memory(int cipher,
    zeromem(PAD,    sizeof(PAD));
    zeromem(PAD,    sizeof(PAD));
    zeromem(CTRPAD, sizeof(CTRPAD));
    zeromem(CTRPAD, sizeof(CTRPAD));
 #endif
 #endif
+error:
+   if (skey != uskey) {
+      XFREE(skey);
+   }
 
 
-   XFREE(skey);
-
-   return CRYPT_OK;
+   return err;
 }
 }
 
 
 #endif
 #endif

+ 11 - 5
src/encauth/ccm/ccm_test.c

@@ -116,6 +116,7 @@ int ccm_test(void)
   unsigned long taglen, x;
   unsigned long taglen, x;
   unsigned char buf[64], buf2[64], tag2[16], tag[16];
   unsigned char buf[64], buf2[64], tag2[16], tag[16];
   int           err, idx;
   int           err, idx;
+  symmetric_key skey;
 
 
   idx = find_cipher("aes");
   idx = find_cipher("aes");
   if (idx == -1) {
   if (idx == -1) {
@@ -127,8 +128,13 @@ int ccm_test(void)
 
 
   for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
   for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
       taglen = tests[x].taglen;
       taglen = tests[x].taglen;
+      if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
+         return err;
+      }
+      
       if ((err = ccm_memory(idx,
       if ((err = ccm_memory(idx,
                             tests[x].key, 16,
                             tests[x].key, 16,
+                            &skey,
                             tests[x].nonce, tests[x].noncelen,
                             tests[x].nonce, tests[x].noncelen,
                             tests[x].header, tests[x].headerlen,
                             tests[x].header, tests[x].headerlen,
                             (unsigned char*)tests[x].pt, tests[x].ptlen,
                             (unsigned char*)tests[x].pt, tests[x].ptlen,
@@ -146,6 +152,7 @@ int ccm_test(void)
 
 
       if ((err = ccm_memory(idx,
       if ((err = ccm_memory(idx,
                             tests[x].key, 16,
                             tests[x].key, 16,
+                            NULL,
                             tests[x].nonce, tests[x].noncelen,
                             tests[x].nonce, tests[x].noncelen,
                             tests[x].header, tests[x].headerlen,
                             tests[x].header, tests[x].headerlen,
                             buf2, tests[x].ptlen,
                             buf2, tests[x].ptlen,
@@ -154,14 +161,13 @@ int ccm_test(void)
          return err;
          return err;
       }
       }
 
 
-     if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) {
+      if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) {
          return CRYPT_FAIL_TESTVECTOR;
          return CRYPT_FAIL_TESTVECTOR;
       }
       }
-     if (memcmp(tag2, tests[x].tag, tests[x].taglen)) {
+      if (memcmp(tag2, tests[x].tag, tests[x].taglen)) {
          return CRYPT_FAIL_TESTVECTOR;
          return CRYPT_FAIL_TESTVECTOR;
-     }
- 
-
+      }
+      cipher_descriptor[idx].done(&skey);
   }
   }
   return CRYPT_OK;
   return CRYPT_OK;
 #endif
 #endif

+ 3 - 1
src/encauth/gcm/gcm_done.c

@@ -62,7 +62,9 @@ int gcm_done(gcm_state *gcm,
    gcm_mult_h(gcm, gcm->X);
    gcm_mult_h(gcm, gcm->X);
 
 
    /* encrypt original counter */
    /* encrypt original counter */
-   cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K);
+   if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
+      return err;
+   }
    for (x = 0; x < 16 && x < *taglen; x++) {
    for (x = 0; x < 16 && x < *taglen; x++) {
        tag[x] = gcm->buf[x] ^ gcm->X[x];
        tag[x] = gcm->buf[x] ^ gcm->X[x];
    }
    }

+ 3 - 1
src/encauth/gcm/gcm_init.c

@@ -98,7 +98,9 @@ int gcm_init(gcm_state *gcm, int cipher,
 
 
    /* H = E(0) */
    /* H = E(0) */
    zeromem(B, 16);
    zeromem(B, 16);
-   cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
+      return err;
+   }
 
 
    /* setup state */
    /* setup state */
    zeromem(gcm->buf, sizeof(gcm->buf));
    zeromem(gcm->buf, sizeof(gcm->buf));

+ 2 - 2
src/encauth/gcm/gcm_memory.c

@@ -51,7 +51,8 @@ int gcm_memory(      int           cipher,
     }
     }
  
  
     if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
     if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
-       cipher_descriptor[cipher].accel_gcm_memory
+       return 
+         cipher_descriptor[cipher].accel_gcm_memory
                                           (key,   keylen,
                                           (key,   keylen,
                                            IV,    IVlen,
                                            IV,    IVlen,
                                            adata, adatalen,
                                            adata, adatalen,
@@ -59,7 +60,6 @@ int gcm_memory(      int           cipher,
                                            ct,
                                            ct,
                                            tag,   taglen,
                                            tag,   taglen,
                                            direction);
                                            direction);
-       return CRYPT_OK;
     }
     }
 
 
 
 

+ 12 - 4
src/encauth/gcm/gcm_process.c

@@ -62,7 +62,9 @@ int gcm_process(gcm_state *gcm,
           if (++gcm->Y[y]) { break; }
           if (++gcm->Y[y]) { break; }
       }
       }
       /* encrypt the counter */
       /* encrypt the counter */
-      cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);     
+      if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
+         return err;
+      }
 
 
       gcm->buflen = 0;
       gcm->buflen = 0;
       gcm->mode   = GCM_MODE_TEXT;
       gcm->mode   = GCM_MODE_TEXT;
@@ -89,7 +91,9 @@ int gcm_process(gcm_state *gcm,
              for (y = 15; y >= 12; y--) {
              for (y = 15; y >= 12; y--) {
                  if (++gcm->Y[y]) { break; }
                  if (++gcm->Y[y]) { break; }
              }
              }
-             cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
+             if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
+                return err;
+             }
          }
          }
       } else {
       } else {
          for (x = 0; x < (ptlen & ~15); x += 16) {
          for (x = 0; x < (ptlen & ~15); x += 16) {
@@ -105,7 +109,9 @@ int gcm_process(gcm_state *gcm,
              for (y = 15; y >= 12; y--) {
              for (y = 15; y >= 12; y--) {
                  if (++gcm->Y[y]) { break; }
                  if (++gcm->Y[y]) { break; }
              }
              }
-             cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
+             if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
+                return err;
+             }
          }
          }
      }
      }
    }
    }
@@ -121,7 +127,9 @@ int gcm_process(gcm_state *gcm,
           for (y = 15; y >= 12; y--) {
           for (y = 15; y >= 12; y--) {
               if (++gcm->Y[y]) { break; }
               if (++gcm->Y[y]) { break; }
           }
           }
-          cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
+          if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
+             return err;
+          }
           gcm->buflen = 0;
           gcm->buflen = 0;
        }
        }
 
 

+ 3 - 1
src/encauth/ocb/ocb_decrypt.c

@@ -51,7 +51,9 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
    for (x = 0; x < ocb->block_len; x++) {
    for (x = 0; x < ocb->block_len; x++) {
        tmp[x] = ct[x] ^ Z[x];
        tmp[x] = ct[x] ^ Z[x];
    }
    }
-   cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key);
+   if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) {
+      return err;
+   }
    for (x = 0; x < ocb->block_len; x++) {
    for (x = 0; x < ocb->block_len; x++) {
        pt[x] ^= Z[x];
        pt[x] ^= Z[x];
    }
    }

+ 3 - 1
src/encauth/ocb/ocb_encrypt.c

@@ -51,7 +51,9 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
    for (x = 0; x < ocb->block_len; x++) {
    for (x = 0; x < ocb->block_len; x++) {
        tmp[x] = pt[x] ^ Z[x];
        tmp[x] = pt[x] ^ Z[x];
    }
    }
-   cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key);
+   if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) {
+      return err;
+   }
    for (x = 0; x < ocb->block_len; x++) {
    for (x = 0; x < ocb->block_len; x++) {
        ct[x] ^= Z[x];
        ct[x] ^= Z[x];
    }
    }

+ 6 - 2
src/encauth/ocb/ocb_init.c

@@ -76,13 +76,17 @@ int ocb_init(ocb_state *ocb, int cipher,
  
  
    /* find L = E[0] */
    /* find L = E[0] */
    zeromem(ocb->L, ocb->block_len);
    zeromem(ocb->L, ocb->block_len);
-   cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {
+      return err;
+   }
 
 
    /* find R = E[N xor L] */
    /* find R = E[N xor L] */
    for (x = 0; x < ocb->block_len; x++) {
    for (x = 0; x < ocb->block_len; x++) {
        ocb->R[x] = ocb->L[x] ^ nonce[x];
        ocb->R[x] = ocb->L[x] ^ nonce[x];
    }
    }
-   cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {
+      return err;
+   }
 
 
    /* find Ls[i] = L << i for i == 0..31 */
    /* find Ls[i] = L << i for i == 0..31 */
    XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);
    XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);

+ 8 - 4
src/encauth/ocb/s_ocb_done.c

@@ -84,7 +84,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
    }
    }
 
 
    /* Y[m] = E(X[m])) */
    /* Y[m] = E(X[m])) */
-   cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key);
+   if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) {
+      goto error;
+   }
 
 
    if (mode == 1) {
    if (mode == 1) {
       /* decrypt mode, so let's xor it first */
       /* decrypt mode, so let's xor it first */
@@ -113,7 +115,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
    }
    }
    
    
    /* encrypt checksum, er... tag!! */
    /* encrypt checksum, er... tag!! */
-   cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key);
+   if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) {
+      goto error;
+   }
    cipher_descriptor[ocb->cipher].done(&ocb->key);
    cipher_descriptor[ocb->cipher].done(&ocb->key);
 
 
    /* now store it */
    /* now store it */
@@ -128,12 +132,12 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
    zeromem(Z, MAXBLOCKSIZE);
    zeromem(Z, MAXBLOCKSIZE);
    zeromem(ocb, sizeof(*ocb));
    zeromem(ocb, sizeof(*ocb));
 #endif
 #endif
-   
+error:   
    XFREE(X);
    XFREE(X);
    XFREE(Y);
    XFREE(Y);
    XFREE(Z);
    XFREE(Z);
 
 
-   return CRYPT_OK;
+   return err;
 }
 }
 
 
 #endif
 #endif

+ 2 - 2
src/headers/tomcrypt.h

@@ -16,8 +16,8 @@ extern "C" {
 #endif
 #endif
 
 
 /* version */
 /* version */
-#define CRYPT   0x0106
-#define SCRYPT  "1.06"
+#define CRYPT   0x0107
+#define SCRYPT  "1.07"
 
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE  128
 #define MAXBLOCKSIZE  128

+ 8 - 0
src/headers/tomcrypt_cfg.h

@@ -54,6 +54,14 @@ int   XMEMCMP(const void *s1, const void *s2, size_t n);
    #define LTC_FAST_TYPE    unsigned long
    #define LTC_FAST_TYPE    unsigned long
 #endif
 #endif
 
 
+/* detect PPC32 */
+#if defined(LTC_PPC32)
+   #define ENDIAN_BIG
+   #define ENDIAN_32BITWORD
+   #define LTC_FAST
+   #define LTC_FAST_TYPE    unsigned long
+#endif   
+
 /* detect sparc and sparc64 */
 /* detect sparc and sparc64 */
 #if defined(__sparc__)
 #if defined(__sparc__)
   #define ENDIAN_BIG
   #define ENDIAN_BIG

+ 52 - 42
src/headers/tomcrypt_cipher.h

@@ -263,14 +263,16 @@ extern struct ltc_cipher_descriptor {
       @param pt      The plaintext
       @param pt      The plaintext
       @param ct      [out] The ciphertext
       @param ct      [out] The ciphertext
       @param skey    The scheduled key
       @param skey    The scheduled key
+      @return CRYPT_OK if successful
    */
    */
-   void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+   int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
    /** Decrypt a block
    /** Decrypt a block
       @param ct      The ciphertext
       @param ct      The ciphertext
       @param pt      [out] The plaintext
       @param pt      [out] The plaintext
       @param skey    The scheduled key
       @param skey    The scheduled key
+      @return CRYPT_OK if successful
    */
    */
-   void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+   int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
    /** Test the block cipher
    /** Test the block cipher
        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
    */
    */
@@ -293,16 +295,18 @@ extern struct ltc_cipher_descriptor {
        @param ct      Ciphertext
        @param ct      Ciphertext
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
+   int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
 
 
    /** Accelerated ECB decryption 
    /** Accelerated ECB decryption 
        @param pt      Plaintext
        @param pt      Plaintext
        @param ct      Ciphertext
        @param ct      Ciphertext
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
+   int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
 
 
    /** Accelerated CBC encryption 
    /** Accelerated CBC encryption 
        @param pt      Plaintext
        @param pt      Plaintext
@@ -310,8 +314,9 @@ extern struct ltc_cipher_descriptor {
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param IV      The initial value (input/output)
        @param IV      The initial value (input/output)
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
+   int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
 
 
    /** Accelerated CBC decryption 
    /** Accelerated CBC decryption 
        @param pt      Plaintext
        @param pt      Plaintext
@@ -319,8 +324,9 @@ extern struct ltc_cipher_descriptor {
        @param blocks  The number of complete blocks to process
        @param blocks  The number of complete blocks to process
        @param IV      The initial value (input/output)
        @param IV      The initial value (input/output)
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
+   int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
 
 
    /** Accelerated CTR encryption 
    /** Accelerated CTR encryption 
        @param pt      Plaintext
        @param pt      Plaintext
@@ -329,12 +335,14 @@ extern struct ltc_cipher_descriptor {
        @param IV      The initial value (input/output)
        @param IV      The initial value (input/output)
        @param mode    little or big endian counter (mode=0 or mode=1)
        @param mode    little or big endian counter (mode=0 or mode=1)
        @param skey    The scheduled key context
        @param skey    The scheduled key context
+       @return CRYPT_OK if successful
    */
    */
-   void (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
+   int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
 
 
    /** Accelerated CCM packet (one-shot)
    /** Accelerated CCM packet (one-shot)
        @param key        The secret key to use
        @param key        The secret key to use
        @param keylen     The length of the secret key (octets)
        @param keylen     The length of the secret key (octets)
+       @param uskey      A previously scheduled key [optional can be NULL]
        @param nonce      The session nonce [use once]
        @param nonce      The session nonce [use once]
        @param noncelen   The length of the nonce
        @param noncelen   The length of the nonce
        @param header     The header for the session
        @param header     The header for the session
@@ -347,8 +355,9 @@ extern struct ltc_cipher_descriptor {
        @param direction  Encrypt or Decrypt direction (0 or 1)
        @param direction  Encrypt or Decrypt direction (0 or 1)
        @return CRYPT_OK if successful
        @return CRYPT_OK if successful
    */
    */
-   void (*accel_ccm_memory)(
+   int (*accel_ccm_memory)(
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *key,    unsigned long keylen,
+       symmetric_key       *uskey,
        const unsigned char *nonce,  unsigned long noncelen,
        const unsigned char *nonce,  unsigned long noncelen,
        const unsigned char *header, unsigned long headerlen,
        const unsigned char *header, unsigned long headerlen,
              unsigned char *pt,     unsigned long ptlen,
              unsigned char *pt,     unsigned long ptlen,
@@ -369,8 +378,9 @@ extern struct ltc_cipher_descriptor {
        @param tag               [out] The MAC tag
        @param tag               [out] The MAC tag
        @param taglen            [in/out] The MAC tag length
        @param taglen            [in/out] The MAC tag length
        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
+       @return CRYPT_OK on success
    */
    */
-   void (*accel_gcm_memory)(
+   int (*accel_gcm_memory)(
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *key,    unsigned long keylen,
        const unsigned char *IV,     unsigned long IVlen,
        const unsigned char *IV,     unsigned long IVlen,
        const unsigned char *adata,  unsigned long adatalen,
        const unsigned char *adata,  unsigned long adatalen,
@@ -382,8 +392,8 @@ extern struct ltc_cipher_descriptor {
 
 
 #ifdef BLOWFISH
 #ifdef BLOWFISH
 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int blowfish_test(void);
 int blowfish_test(void);
 void blowfish_done(symmetric_key *skey);
 void blowfish_done(symmetric_key *skey);
 int blowfish_keysize(int *keysize);
 int blowfish_keysize(int *keysize);
@@ -392,8 +402,8 @@ extern const struct ltc_cipher_descriptor blowfish_desc;
 
 
 #ifdef RC5
 #ifdef RC5
 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int rc5_test(void);
 int rc5_test(void);
 void rc5_done(symmetric_key *skey);
 void rc5_done(symmetric_key *skey);
 int rc5_keysize(int *keysize);
 int rc5_keysize(int *keysize);
@@ -402,8 +412,8 @@ extern const struct ltc_cipher_descriptor rc5_desc;
 
 
 #ifdef RC6
 #ifdef RC6
 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int rc6_test(void);
 int rc6_test(void);
 void rc6_done(symmetric_key *skey);
 void rc6_done(symmetric_key *skey);
 int rc6_keysize(int *keysize);
 int rc6_keysize(int *keysize);
@@ -412,8 +422,8 @@ extern const struct ltc_cipher_descriptor rc6_desc;
 
 
 #ifdef RC2
 #ifdef RC2
 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int rc2_test(void);
 int rc2_test(void);
 void rc2_done(symmetric_key *skey);
 void rc2_done(symmetric_key *skey);
 int rc2_keysize(int *keysize);
 int rc2_keysize(int *keysize);
@@ -422,8 +432,8 @@ extern const struct ltc_cipher_descriptor rc2_desc;
 
 
 #ifdef SAFERP
 #ifdef SAFERP
 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int saferp_test(void);
 int saferp_test(void);
 void saferp_done(symmetric_key *skey);
 void saferp_done(symmetric_key *skey);
 int saferp_keysize(int *keysize);
 int saferp_keysize(int *keysize);
@@ -435,8 +445,8 @@ int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmet
 int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
-void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
+int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
+int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
 int safer_k64_test(void);
 int safer_k64_test(void);
 int safer_sk64_test(void);
 int safer_sk64_test(void);
 int safer_sk128_test(void);
 int safer_sk128_test(void);
@@ -461,13 +471,13 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer
 #define aes_enc_keysize         rijndael_enc_keysize
 #define aes_enc_keysize         rijndael_enc_keysize
 
 
 int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int rijndael_test(void);
 int rijndael_test(void);
 void rijndael_done(symmetric_key *skey);
 void rijndael_done(symmetric_key *skey);
 int rijndael_keysize(int *keysize);
 int rijndael_keysize(int *keysize);
 int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
 void rijndael_enc_done(symmetric_key *skey);
 void rijndael_enc_done(symmetric_key *skey);
 int rijndael_enc_keysize(int *keysize);
 int rijndael_enc_keysize(int *keysize);
 extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
 extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
@@ -476,8 +486,8 @@ extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
 
 
 #ifdef XTEA
 #ifdef XTEA
 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int xtea_test(void);
 int xtea_test(void);
 void xtea_done(symmetric_key *skey);
 void xtea_done(symmetric_key *skey);
 int xtea_keysize(int *keysize);
 int xtea_keysize(int *keysize);
@@ -486,8 +496,8 @@ extern const struct ltc_cipher_descriptor xtea_desc;
 
 
 #ifdef TWOFISH
 #ifdef TWOFISH
 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int twofish_test(void);
 int twofish_test(void);
 void twofish_done(symmetric_key *skey);
 void twofish_done(symmetric_key *skey);
 int twofish_keysize(int *keysize);
 int twofish_keysize(int *keysize);
@@ -496,14 +506,14 @@ extern const struct ltc_cipher_descriptor twofish_desc;
 
 
 #ifdef DES
 #ifdef DES
 int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int des_test(void);
 int des_test(void);
 void des_done(symmetric_key *skey);
 void des_done(symmetric_key *skey);
 int des_keysize(int *keysize);
 int des_keysize(int *keysize);
 int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int des3_test(void);
 int des3_test(void);
 void des3_done(symmetric_key *skey);
 void des3_done(symmetric_key *skey);
 int des3_keysize(int *keysize);
 int des3_keysize(int *keysize);
@@ -512,8 +522,8 @@ extern const struct ltc_cipher_descriptor des_desc, des3_desc;
 
 
 #ifdef CAST5
 #ifdef CAST5
 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int cast5_test(void);
 int cast5_test(void);
 void cast5_done(symmetric_key *skey);
 void cast5_done(symmetric_key *skey);
 int cast5_keysize(int *keysize);
 int cast5_keysize(int *keysize);
@@ -522,8 +532,8 @@ extern const struct ltc_cipher_descriptor cast5_desc;
 
 
 #ifdef NOEKEON
 #ifdef NOEKEON
 int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int noekeon_test(void);
 int noekeon_test(void);
 void noekeon_done(symmetric_key *skey);
 void noekeon_done(symmetric_key *skey);
 int noekeon_keysize(int *keysize);
 int noekeon_keysize(int *keysize);
@@ -532,8 +542,8 @@ extern const struct ltc_cipher_descriptor noekeon_desc;
 
 
 #ifdef SKIPJACK
 #ifdef SKIPJACK
 int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int skipjack_test(void);
 int skipjack_test(void);
 void skipjack_done(symmetric_key *skey);
 void skipjack_done(symmetric_key *skey);
 int skipjack_keysize(int *keysize);
 int skipjack_keysize(int *keysize);
@@ -542,8 +552,8 @@ extern const struct ltc_cipher_descriptor skipjack_desc;
 
 
 #ifdef KHAZAD
 #ifdef KHAZAD
 int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int khazad_test(void);
 int khazad_test(void);
 void khazad_done(symmetric_key *skey);
 void khazad_done(symmetric_key *skey);
 int khazad_keysize(int *keysize);
 int khazad_keysize(int *keysize);
@@ -552,8 +562,8 @@ extern const struct ltc_cipher_descriptor khazad_desc;
 
 
 #ifdef ANUBIS
 #ifdef ANUBIS
 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
-void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
-void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
 int anubis_test(void);
 int anubis_test(void);
 void anubis_done(symmetric_key *skey);
 void anubis_done(symmetric_key *skey);
 int anubis_keysize(int *keysize);
 int anubis_keysize(int *keysize);

+ 15 - 6
src/headers/tomcrypt_custom.h

@@ -186,6 +186,9 @@
 /* Include RSA support */
 /* Include RSA support */
 #define MRSA
 #define MRSA
 
 
+/* Include Katja (an Rabin variant like RSA) */
+// #define MKAT 
+
 /* Digital Signature Algorithm */
 /* Digital Signature Algorithm */
 #define MDSA
 #define MDSA
 /* Max diff between group and modulus size in bytes */
 /* Max diff between group and modulus size in bytes */
@@ -200,11 +203,13 @@
 /* #define LTC_ECC_TIMING_RESISTANT */
 /* #define LTC_ECC_TIMING_RESISTANT */
 
 
 /* Supported ECC Key Sizes */
 /* Supported ECC Key Sizes */
-#define ECC192
-#define ECC224
-#define ECC256
-#define ECC384
-#define ECC521
+#ifndef LTC_NO_CURVES
+   #define ECC192
+   #define ECC224
+   #define ECC256
+   #define ECC384
+   #define ECC521
+#endif
 
 
 /* Include the MPI functionality?  (required by the PK algorithms) */
 /* Include the MPI functionality?  (required by the PK algorithms) */
 #define MPI
 #define MPI
@@ -240,14 +245,18 @@
 
 
 #define LTC_MUTEX_GLOBAL(x)   pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
 #define LTC_MUTEX_GLOBAL(x)   pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
 #define LTC_MUTEX_PROTO(x)    extern pthread_mutex_t x;
 #define LTC_MUTEX_PROTO(x)    extern pthread_mutex_t x;
+#define LTC_MUTEX_TYPE(x)     pthread_mutex_t x;
+#define LTC_MUTEX_INIT(x)     pthread_mutex_init(x, NULL);
 #define LTC_MUTEX_LOCK(x)     pthread_mutex_lock(x);
 #define LTC_MUTEX_LOCK(x)     pthread_mutex_lock(x);
 #define LTC_MUTEX_UNLOCK(x)   pthread_mutex_unlock(x);
 #define LTC_MUTEX_UNLOCK(x)   pthread_mutex_unlock(x);
 
 
-#else 
+#else
 
 
 /* default no functions */
 /* default no functions */
 #define LTC_MUTEX_GLOBAL(x)
 #define LTC_MUTEX_GLOBAL(x)
 #define LTC_MUTEX_PROTO(x)
 #define LTC_MUTEX_PROTO(x)
+#define LTC_MUTEX_TYPE(x)
+#define LTC_MUTEX_INIT(x)
 #define LTC_MUTEX_LOCK(x)
 #define LTC_MUTEX_LOCK(x)
 #define LTC_MUTEX_UNLOCK(x)
 #define LTC_MUTEX_UNLOCK(x)
 
 

+ 1 - 0
src/headers/tomcrypt_mac.h

@@ -200,6 +200,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
 
 
 int ccm_memory(int cipher,
 int ccm_memory(int cipher,
     const unsigned char *key,    unsigned long keylen,
     const unsigned char *key,    unsigned long keylen,
+    symmetric_key       *uskey,
     const unsigned char *nonce,  unsigned long noncelen,
     const unsigned char *nonce,  unsigned long noncelen,
     const unsigned char *header, unsigned long headerlen,
     const unsigned char *header, unsigned long headerlen,
           unsigned char *pt,     unsigned long ptlen,
           unsigned char *pt,     unsigned long ptlen,

+ 44 - 0
src/headers/tomcrypt_macros.h

@@ -285,6 +285,50 @@ static inline unsigned RORc(unsigned word, const int i)
 
 
 #endif
 #endif
 
 
+#elif defined(LTC_PPC32)
+
+static inline unsigned ROL(unsigned word, int i)
+{
+   asm ("rotlw %0,%0,%2"
+      :"=r" (word)
+      :"0" (word),"r" (i));
+   return word;
+}
+
+static inline unsigned ROR(unsigned word, int i)
+{
+   asm ("rotlw %0,%0,%2"
+      :"=r" (word)
+      :"0" (word),"r" (32-i));
+   return word;
+}
+
+#ifndef LTC_NO_ROLC
+
+static inline unsigned ROLc(unsigned word, const int i)
+{
+   asm ("rotlwi %0,%0,%2"
+      :"=r" (word)
+      :"0" (word),"I" (i));
+   return word;
+}
+
+static inline unsigned RORc(unsigned word, const int i)
+{
+   asm ("rotrwi %0,%0,%2"
+      :"=r" (word)
+      :"0" (word),"I" (i));
+   return word;
+}
+
+#else
+
+#define ROLc ROL
+#define RORc ROR
+
+#endif
+
+
 #else
 #else
 
 
 /* rotates the hard way */
 /* rotates the hard way */

+ 25 - 1
src/headers/tomcrypt_math.h

@@ -11,6 +11,10 @@
    typedef void ecc_point;
    typedef void ecc_point;
 #endif
 #endif
 
 
+#ifndef MRSA
+   typedef void rsa_key;
+#endif
+
 /** math descriptor */
 /** math descriptor */
 typedef struct {
 typedef struct {
    /** Name of the math provider */
    /** Name of the math provider */
@@ -42,6 +46,13 @@ typedef struct {
 
 
 /* ---- data movement ---- */
 /* ---- data movement ---- */
 
 
+   /** negate
+      @param   src   The number to negate
+      @param   dst   The destination
+      @return CRYPT_OK on success
+   */
+   int (*neg)(void *src, void *dst);
+   
    /** copy 
    /** copy 
       @param   src   The number to copy from
       @param   src   The number to copy from
       @param   dst   The number to write to 
       @param   dst   The number to write to 
@@ -339,11 +350,22 @@ typedef struct {
 
 
 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
 
 
+   /** RSA Key Generation 
+       @param prng     An active PRNG state
+       @param wprng    The index of the PRNG desired
+       @param size     The size of the modulus (key size) desired (octets)
+       @param e        The "e" value (public key).  e==65537 is a good choice
+       @param key      [out] Destination of a newly created private key pair
+       @return CRYPT_OK if successful, upon error all allocated ram is freed
+    */
+    int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
+   
+
    /** RSA exponentiation
    /** RSA exponentiation
       @param in       The octet array representing the base
       @param in       The octet array representing the base
       @param inlen    The length of the input
       @param inlen    The length of the input
       @param out      The destination (to be stored in an octet array format)
       @param out      The destination (to be stored in an octet array format)
-      @param outlen   The length of the output buffer and the resulting size (zero padded to the size of the modulus
+      @param outlen   The length of the output buffer and the resulting size (zero padded to the size of the modulus)
       @param which    PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
       @param which    PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
       @param key      The RSA key to use 
       @param key      The RSA key to use 
       @return CRYPT_OK on success
       @return CRYPT_OK on success
@@ -375,7 +397,9 @@ extern const ltc_math_descriptor tfm_desc;
 #define mp_init_multi                ltc_init_multi
 #define mp_init_multi                ltc_init_multi
 #define mp_clear(a)                  ltc_mp.deinit(a)
 #define mp_clear(a)                  ltc_mp.deinit(a)
 #define mp_clear_multi               ltc_deinit_multi
 #define mp_clear_multi               ltc_deinit_multi
+#define mp_init_copy(a, b)           ltc_mp.init_copy(a, b)
 
 
+#define mp_neg(a, b)                 ltc_mp.neg(a, b)
 #define mp_copy(a, b)                ltc_mp.copy(a, b)
 #define mp_copy(a, b)                ltc_mp.copy(a, b)
 
 
 #define mp_set(a, b)                 ltc_mp.set_int(a, b)
 #define mp_set(a, b)                 ltc_mp.set_int(a, b)

+ 123 - 27
src/headers/tomcrypt_pk.h

@@ -73,9 +73,70 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
                         
                         
 #endif
 #endif
 
 
+/* ---- Katja ---- */
+#ifdef MKAT
+
+/* Min and Max KAT key sizes (in bits) */
+#define MIN_KAT_SIZE 1024
+#define MAX_KAT_SIZE 4096
+
+/** Katja PKCS style key */
+typedef struct KAT_key {
+    /** Type of key, PK_PRIVATE or PK_PUBLIC */
+    int type;
+    /** The private exponent */
+    void *d; 
+    /** The modulus */
+    void *N; 
+    /** The p factor of N */
+    void *p; 
+    /** The q factor of N */
+    void *q; 
+    /** The 1/q mod p CRT param */
+    void *qP; 
+    /** The d mod (p - 1) CRT param */
+    void *dP; 
+    /** The d mod (q - 1) CRT param */
+    void *dQ;
+    /** The pq param */
+    void *pq;
+} katja_key;
+
+int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
+
+int katja_exptmod(const unsigned char *in,   unsigned long inlen,
+                        unsigned char *out,  unsigned long *outlen, int which,
+                        katja_key *key);
+
+void katja_free(katja_key *key);
+
+/* These use PKCS #1 v2.0 padding */
+int katja_encrypt_key(const unsigned char *in,     unsigned long inlen,
+                            unsigned char *out,    unsigned long *outlen,
+                      const unsigned char *lparam, unsigned long lparamlen,
+                      prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
+                                        
+int katja_decrypt_key(const unsigned char *in,       unsigned long inlen,
+                            unsigned char *out,      unsigned long *outlen, 
+                      const unsigned char *lparam,   unsigned long lparamlen,
+                            int            hash_idx, int *stat,
+                            katja_key       *key);
+
+/* PKCS #1 import/export */
+int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
+int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
+                        
+#endif
+
 /* ---- ECC Routines ---- */
 /* ---- ECC Routines ---- */
 #ifdef MECC
 #ifdef MECC
 
 
+/* size of our temp buffers for exported keys */
+#define ECC_BUF_SIZE 256
+
+/* max private key size */
+#define ECC_MAXSIZE  66
+
 /** Structure defines a NIST GF(p) curve */
 /** Structure defines a NIST GF(p) curve */
 typedef struct {
 typedef struct {
    /** The size of the curve in octets */
    /** The size of the curve in octets */
@@ -104,8 +165,10 @@ typedef struct {
 typedef struct {
 typedef struct {
     /** The x co-ordinate */
     /** The x co-ordinate */
     void *x;
     void *x;
+
     /** The y co-ordinate */
     /** The y co-ordinate */
     void *y;
     void *y;
+
     /** The z co-ordinate */
     /** The z co-ordinate */
     void *z;
     void *z;
 } ecc_point;
 } ecc_point;
@@ -114,10 +177,13 @@ typedef struct {
 typedef struct {
 typedef struct {
     /** Type of key, PK_PRIVATE or PK_PUBLIC */
     /** Type of key, PK_PRIVATE or PK_PUBLIC */
     int type;
     int type;
+
     /** Index into the ltc_ecc_sets[] for the parameters of this curve */
     /** Index into the ltc_ecc_sets[] for the parameters of this curve */
     int idx;
     int idx;
+
     /** The public key */
     /** The public key */
     ecc_point pubkey;
     ecc_point pubkey;
+
     /** The private key */
     /** The private key */
     void *k;
     void *k;
 } ecc_key;
 } ecc_key;
@@ -125,47 +191,52 @@ typedef struct {
 /** the ECC params provided */
 /** the ECC params provided */
 extern const ltc_ecc_set_type ltc_ecc_sets[];
 extern const ltc_ecc_set_type ltc_ecc_sets[];
 
 
-int ecc_test(void);
+int  ecc_test(void);
 void ecc_sizes(int *low, int *high);
 void ecc_sizes(int *low, int *high);
-int ecc_get_size(ecc_key *key);
+int  ecc_get_size(ecc_key *key);
 
 
-int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
+int  ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
 void ecc_free(ecc_key *key);
 void ecc_free(ecc_key *key);
 
 
-int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
-int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
+int  ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
+int  ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
 
 
-int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, 
-                      unsigned char *out, unsigned long *outlen);
+int  ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, 
+                       unsigned char *out, unsigned long *outlen);
 
 
-int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
-                          unsigned char *out,  unsigned long *outlen, 
-                          prng_state *prng, int wprng, int hash, 
-                          ecc_key *key);
+int  ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
+                           unsigned char *out,  unsigned long *outlen, 
+                           prng_state *prng, int wprng, int hash, 
+                           ecc_key *key);
 
 
-int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
-                          unsigned char *out, unsigned long *outlen, 
-                          ecc_key *key);
+int  ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
+                           unsigned char *out, unsigned long *outlen, 
+                           ecc_key *key);
 
 
-int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                        unsigned char *out, unsigned long *outlen, 
-                        prng_state *prng, int wprng, ecc_key *key);
+int  ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
+                         unsigned char *out, unsigned long *outlen, 
+                         prng_state *prng, int wprng, ecc_key *key);
 
 
-int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
-                    const unsigned char *hash, unsigned long hashlen, 
-                    int *stat, ecc_key *key);
+int  ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
+                     const unsigned char *hash, unsigned long hashlen, 
+                     int *stat, ecc_key *key);
 
 
 /* low level functions */
 /* low level functions */
 ecc_point *ltc_ecc_new_point(void);
 ecc_point *ltc_ecc_new_point(void);
 void       ltc_ecc_del_point(ecc_point *p);
 void       ltc_ecc_del_point(ecc_point *p);
+int        ltc_ecc_is_valid_idx(int n);
+
 
 
 /* point ops (mp == montgomery digit) */
 /* point ops (mp == montgomery digit) */
 /* R = 2P */
 /* R = 2P */
-int ltc_ecc_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
+int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
+
 /* R = P + Q */
 /* R = P + Q */
-int ltc_ecc_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
+int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
+
 /* R = kG */
 /* R = kG */
 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
+
 /* map P to affine from projective */
 /* map P to affine from projective */
 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
 
 
@@ -177,16 +248,22 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
 typedef struct {
 typedef struct {
    /** The key type, PK_PRIVATE or PK_PUBLIC */
    /** The key type, PK_PRIVATE or PK_PUBLIC */
    int type; 
    int type; 
+
    /** The order of the sub-group used in octets */
    /** The order of the sub-group used in octets */
    int qord;
    int qord;
+
    /** The generator  */
    /** The generator  */
    void *g;
    void *g;
+
    /** The prime used to generate the sub-group */
    /** The prime used to generate the sub-group */
    void *q;
    void *q;
+
    /** The large prime that generats the field the contains the sub-group */
    /** The large prime that generats the field the contains the sub-group */
    void *p;
    void *p;
+
    /** The private key */
    /** The private key */
    void *x;
    void *x;
+
    /** The public key */
    /** The public key */
    void *y;
    void *y;
 } dsa_key;
 } dsa_key;
@@ -194,7 +271,6 @@ typedef struct {
 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
 void dsa_free(dsa_key *key);
 void dsa_free(dsa_key *key);
 
 
-
 int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
 int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
                                    void *r,   void *s,
                                    void *r,   void *s,
                                prng_state *prng, int wprng, dsa_key *key);
                                prng_state *prng, int wprng, dsa_key *key);
@@ -211,12 +287,24 @@ int dsa_verify_hash(const unsigned char *sig,  unsigned long siglen,
                     const unsigned char *hash, unsigned long hashlen, 
                     const unsigned char *hash, unsigned long hashlen, 
                           int           *stat, dsa_key       *key);
                           int           *stat, dsa_key       *key);
 
 
+int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen,
+                          unsigned char *out,  unsigned long *outlen, 
+                          prng_state *prng, int wprng, int hash, 
+                          dsa_key *key);
+                      
+int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen,
+                          unsigned char *out, unsigned long *outlen, 
+                          dsa_key *key);
+                          
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
-
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
-
 int dsa_verify_key(dsa_key *key, int *stat);
 int dsa_verify_key(dsa_key *key, int *stat);
 
 
+
+
+int dsa_shared_secret(void          *private_key, void *base,
+                      dsa_key       *public_key,
+                      unsigned char *out,         unsigned long *outlen);
 #endif
 #endif
 
 
 #ifdef LTC_DER
 #ifdef LTC_DER
@@ -239,7 +327,7 @@ enum {
 };
 };
 
 
 /** A LTC ASN.1 list type */
 /** A LTC ASN.1 list type */
-typedef struct {
+typedef struct ltc_asn1_list_ {
    /** The LTC ASN.1 enumerated type identifier */
    /** The LTC ASN.1 enumerated type identifier */
    int           type;
    int           type;
    /** The data to encode or place for decoding */
    /** The data to encode or place for decoding */
@@ -248,6 +336,8 @@ typedef struct {
    unsigned long size;
    unsigned long size;
    /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
    /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
    int           used;
    int           used;
+   /** prev/next entry in the list */
+   struct ltc_asn1_list_ *prev, *next, *child, *parent;
 } ltc_asn1_list;
 } ltc_asn1_list;
 
 
 #define LTC_SET_ASN1(list, index, Type, Data, Size)  \
 #define LTC_SET_ASN1(list, index, Type, Data, Size)  \
@@ -270,10 +360,16 @@ int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
                         unsigned long *outlen);
                         unsigned long *outlen);
 
 
-/* VA list handy helpers */
+/* VA list handy helpers with triplets of <type, size, data> */
 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
 
 
+/* handle unknown list decoder */
+int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
+void der_free_sequence_flexi(ltc_asn1_list *list);
+
+void der_sequence_free(ltc_asn1_list *in);
+
 /* INTEGER */
 /* INTEGER */
 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);

+ 2 - 2
src/headers/tomcrypt_pkcs.h

@@ -3,8 +3,8 @@
 /* ===> PKCS #1 -- RSA Cryptography <=== */
 /* ===> PKCS #1 -- RSA Cryptography <=== */
 #ifdef PKCS_1
 #ifdef PKCS_1
 
 
-int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
-                      int            hash_idx,
+int pkcs_1_mgf1(      int            hash_idx,
+                const unsigned char *seed, unsigned long seedlen,
                       unsigned char *mask, unsigned long masklen);
                       unsigned char *mask, unsigned long masklen);
 
 
 int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
 int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);

+ 2 - 0
src/headers/tomcrypt_prng.h

@@ -4,6 +4,7 @@ struct yarrow_prng {
     int                   cipher, hash;
     int                   cipher, hash;
     unsigned char         pool[MAXBLOCKSIZE];
     unsigned char         pool[MAXBLOCKSIZE];
     symmetric_CTR         ctr;
     symmetric_CTR         ctr;
+    LTC_MUTEX_TYPE(prng_lock)
 };
 };
 #endif
 #endif
 
 
@@ -28,6 +29,7 @@ struct fortuna_prng {
                   wd;            
                   wd;            
 
 
     ulong64       reset_cnt;  /* number of times we have reset */
     ulong64       reset_cnt;  /* number of times we have reset */
+    LTC_MUTEX_TYPE(prng_lock)
 };
 };
 #endif
 #endif
 
 

+ 3 - 1
src/mac/omac/omac_done.c

@@ -61,7 +61,9 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen)
    }
    }
 
 
    /* encrypt it */
    /* encrypt it */
-   cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key);
+   if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) {
+      return err;
+   }
    cipher_descriptor[omac->cipher_idx].done(&omac->key);
    cipher_descriptor[omac->cipher_idx].done(&omac->key);
  
  
    /* output it */
    /* output it */

+ 3 - 1
src/mac/omac/omac_init.c

@@ -63,7 +63,9 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l
 
 
    /* first calc L which is Ek(0) */
    /* first calc L which is Ek(0) */
    zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
    zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
-   cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) {
+      return err;
+   }
 
 
    /* now do the mults, whoopy! */
    /* now do the mults, whoopy! */
    for (x = 0; x < 2; x++) {
    for (x = 0; x < 2; x++) {

+ 6 - 2
src/mac/omac/omac_process.c

@@ -49,7 +49,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
               *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y]));
               *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y]));
           }
           }
           in += 16;
           in += 16;
-          cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key);
+          if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
+             return err;
+          }
       }
       }
       inlen -= x;
       inlen -= x;
     }
     }
@@ -61,7 +63,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
           for (x = 0; x < (unsigned long)omac->blklen; x++) {
           for (x = 0; x < (unsigned long)omac->blklen; x++) {
               omac->block[x] ^= omac->prev[x];
               omac->block[x] ^= omac->prev[x];
           }
           }
-          cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key);
+          if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
+             return err;
+          }
           omac->buflen = 0;
           omac->buflen = 0;
        }
        }
 
 

+ 3 - 1
src/mac/pmac/pmac_done.c

@@ -49,7 +49,9 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen)
    }
    }
 
 
    /* encrypt it */
    /* encrypt it */
-   cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key);
+   if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) {
+      return err;
+   }
    cipher_descriptor[state->cipher_idx].done(&state->key);
    cipher_descriptor[state->cipher_idx].done(&state->key);
 
 
    /* store it */
    /* store it */

+ 6 - 3
src/mac/pmac/pmac_init.c

@@ -87,7 +87,9 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l
 
 
    /* find L = E[0] */
    /* find L = E[0] */
    zeromem(L, pmac->block_len);
    zeromem(L, pmac->block_len);
-   cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key);
+   if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {
+      goto error;
+   }
 
 
    /* find Ls[i] = L << i for i == 0..31 */
    /* find Ls[i] = L << i for i == 0..31 */
    XMEMCPY(pmac->Ls[0], L, pmac->block_len);
    XMEMCPY(pmac->Ls[0], L, pmac->block_len);
@@ -127,14 +129,15 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l
     zeromem(pmac->block,    sizeof(pmac->block));
     zeromem(pmac->block,    sizeof(pmac->block));
     zeromem(pmac->Li,       sizeof(pmac->Li));
     zeromem(pmac->Li,       sizeof(pmac->Li));
     zeromem(pmac->checksum, sizeof(pmac->checksum));
     zeromem(pmac->checksum, sizeof(pmac->checksum));
-
+    err = CRYPT_OK;
+error:
 #ifdef LTC_CLEAN_STACK
 #ifdef LTC_CLEAN_STACK
     zeromem(L, pmac->block_len);
     zeromem(L, pmac->block_len);
 #endif
 #endif
 
 
     XFREE(L);
     XFREE(L);
 
 
-    return CRYPT_OK;
+    return err;
 }
 }
 
 
 #endif
 #endif

+ 6 - 2
src/mac/pmac/pmac_process.c

@@ -50,7 +50,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
               *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y]));
               *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y]));
           }
           }
-          cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key);
+          if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
+             return err;
+          }
           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
               *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y]));
               *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y]));
           }
           }
@@ -67,7 +69,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
           for (x = 0; x < (unsigned long)pmac->block_len; x++) {
           for (x = 0; x < (unsigned long)pmac->block_len; x++) {
                Z[x] = pmac->Li[x] ^ pmac->block[x];
                Z[x] = pmac->Li[x] ^ pmac->block[x];
           }
           }
-          cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key);
+          if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
+             return err;
+           }
           for (x = 0; x < (unsigned long)pmac->block_len; x++) {
           for (x = 0; x < (unsigned long)pmac->block_len; x++) {
               pmac->checksum[x] ^= Z[x];
               pmac->checksum[x] ^= Z[x];
           }
           }

+ 12 - 3
src/math/ltm_desc.c

@@ -65,6 +65,13 @@ static void deinit(void *a)
    XFREE(a);
    XFREE(a);
 }
 }
 
 
+static int neg(void *a, void *b)
+{
+   LTC_ARGCHK(a != NULL);
+   LTC_ARGCHK(b != NULL);
+   return mpi_to_ltc_error(mp_neg(a, b));
+}
+
 static int copy(void *a, void *b)
 static int copy(void *a, void *b)
 {
 {
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(a != NULL);
@@ -379,6 +386,7 @@ const ltc_math_descriptor ltm_desc = {
    &init_copy,
    &init_copy,
    &deinit,
    &deinit,
 
 
+   &neg,
    &copy,
    &copy,
 
 
    &set_int,
    &set_int,
@@ -420,10 +428,11 @@ const ltc_math_descriptor ltm_desc = {
    &exptmod,
    &exptmod,
    &isprime,
    &isprime,
 
 
-   NULL,
-   NULL,
-   NULL,
+   &ltc_ecc_mulmod,
+   &ltc_ecc_projective_add_point,
+   &ltc_ecc_map,
 
 
+   NULL,
    NULL
    NULL
 };
 };
 
 

+ 1 - 0
src/math/multi.c

@@ -34,6 +34,7 @@ int ltc_init_multi(void **a, ...)
           va_end(clean_list);
           va_end(clean_list);
           return CRYPT_MEM;
           return CRYPT_MEM;
        }
        }
+       ++np;
        cur = va_arg(args, void**);
        cur = va_arg(args, void**);
    }
    }
    va_end(args);
    va_end(args);

+ 14 - 4
src/math/tfm_desc.c

@@ -59,6 +59,14 @@ static void deinit(void *a)
    XFREE(a);
    XFREE(a);
 }
 }
 
 
+static int neg(void *a, void *b)
+{
+   LTC_ARGCHK(a != NULL);
+   LTC_ARGCHK(b != NULL);
+   fp_neg(((fp_int*)a), ((fp_int*)b));
+   return CRYPT_OK;
+}
+
 static int copy(void *a, void *b)
 static int copy(void *a, void *b)
 {
 {
    LTC_ARGCHK(a != NULL);
    LTC_ARGCHK(a != NULL);
@@ -390,6 +398,7 @@ const ltc_math_descriptor tfm_desc = {
    &init_copy,
    &init_copy,
    &deinit,
    &deinit,
 
 
+   &neg,
    &copy,
    &copy,
 
 
    &set_int,
    &set_int,
@@ -422,7 +431,7 @@ const ltc_math_descriptor tfm_desc = {
 
 
    &mulmod,
    &mulmod,
    &invmod,
    &invmod,
-   
+
    &montgomery_setup,
    &montgomery_setup,
    &montgomery_normalization,
    &montgomery_normalization,
    &montgomery_reduce,
    &montgomery_reduce,
@@ -431,10 +440,11 @@ const ltc_math_descriptor tfm_desc = {
    &exptmod,
    &exptmod,
    &isprime,
    &isprime,
 
 
-   NULL,
-   NULL,
-   NULL,
+   &ltc_ecc_mulmod,
+   &ltc_ecc_projective_add_point,
+   &ltc_ecc_map,
 
 
+   NULL,
    NULL
    NULL
 };
 };
 
 

+ 9 - 3
src/misc/crypt/crypt.c

@@ -229,15 +229,18 @@ const char *crypt_build_settings =
 #if defined(MDSA)
 #if defined(MDSA)
     "   DSA\n"
     "   DSA\n"
 #endif
 #endif
+#if defined(MKAT)
+    "   Katja\n"
+#endif    
 
 
     "\nCompiler:\n"
     "\nCompiler:\n"
 #if defined(WIN32)
 #if defined(WIN32)
     "   WIN32 platform detected.\n"
     "   WIN32 platform detected.\n"
 #endif
 #endif
-#if defined(LBL_CYGWIN__)
+#if defined(__CYGWIN__)
     "   CYGWIN Detected.\n"
     "   CYGWIN Detected.\n"
 #endif
 #endif
-#if defined(LBL_DJGPP__)
+#if defined(__DJGPP__)
     "   DJGPP Detected.\n"
     "   DJGPP Detected.\n"
 #endif
 #endif
 #if defined(_MSC_VER)
 #if defined(_MSC_VER)
@@ -249,9 +252,12 @@ const char *crypt_build_settings =
 #if defined(INTEL_CC)
 #if defined(INTEL_CC)
     "   Intel C Compiler detected.\n"
     "   Intel C Compiler detected.\n"
 #endif
 #endif
-#if defined(LBL_x86_64__)
+#if defined(__x86_64__)
     "   x86-64 detected.\n"
     "   x86-64 detected.\n"
 #endif
 #endif
+#if defined(LTC_PPC32)
+    "   LTC_PPC32 defined \n"
+#endif    
 
 
     "\nVarious others: "
     "\nVarious others: "
 #if defined(BASE64)
 #if defined(BASE64)

+ 4 - 2
src/modes/cbc/cbc_decrypt.c

@@ -59,11 +59,13 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
 #endif
 #endif
    
    
    if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
    if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
-      cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
+      return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
    } else {
    } else {
       while (len) {
       while (len) {
          /* decrypt */
          /* decrypt */
-         cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
+         if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
+            return err;
+         }
 
 
          /* xor IV against plaintext */
          /* xor IV against plaintext */
          #if defined(LTC_FAST)
          #if defined(LTC_FAST)

+ 4 - 2
src/modes/cbc/cbc_encrypt.c

@@ -53,7 +53,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
 #endif
 #endif
 
 
    if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
    if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
-      cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
+      return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
    } else {
    } else {
       while (len) {
       while (len) {
          /* xor IV against plaintext */
          /* xor IV against plaintext */
@@ -68,7 +68,9 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
 	 #endif
 	 #endif
 
 
          /* encrypt */
          /* encrypt */
-         cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key);
+         if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
+            return err;
+         }
 
 
         /* store IV [ciphertext] for a future block */
         /* store IV [ciphertext] for a future block */
          #if defined(LTC_FAST)
          #if defined(LTC_FAST)

+ 3 - 1
src/modes/cfb/cfb_decrypt.c

@@ -45,7 +45,9 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
 
 
    while (len-- > 0) {
    while (len-- > 0) {
        if (cfb->padlen == cfb->blocklen) {
        if (cfb->padlen == cfb->blocklen) {
-          cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
+          if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
+             return err;
+          }
           cfb->padlen = 0;
           cfb->padlen = 0;
        }
        }
        cfb->pad[cfb->padlen] = *ct;
        cfb->pad[cfb->padlen] = *ct;

+ 3 - 1
src/modes/cfb/cfb_encrypt.c

@@ -45,7 +45,9 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
 
 
    while (len-- > 0) {
    while (len-- > 0) {
        if (cfb->padlen == cfb->blocklen) {
        if (cfb->padlen == cfb->blocklen) {
-          cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
+          if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
+             return err;
+          }
           cfb->padlen = 0;
           cfb->padlen = 0;
        }
        }
        cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
        cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);

+ 1 - 3
src/modes/cfb/cfb_setiv.c

@@ -40,9 +40,7 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
       
       
    /* force next block */
    /* force next block */
    cfb->padlen = 0;
    cfb->padlen = 0;
-   cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
-
-   return CRYPT_OK;
+   return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
 }
 }
 
 
 #endif 
 #endif 

+ 1 - 3
src/modes/cfb/cfb_start.c

@@ -54,10 +54,8 @@ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
    }
    }
 
 
    /* encrypt the IV */
    /* encrypt the IV */
-   cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
    cfb->padlen = 0;
    cfb->padlen = 0;
-
-   return CRYPT_OK;
+   return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
 }
 }
 
 
 #endif
 #endif

+ 6 - 2
src/modes/ctr/ctr_encrypt.c

@@ -52,7 +52,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
    
    
    /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
    /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
    if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
    if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
-      cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key);
+      if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
+         return err;
+      }
       len %= ctr->blocklen;
       len %= ctr->blocklen;
    }
    }
 
 
@@ -79,7 +81,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
          }
          }
 
 
          /* encrypt it */
          /* encrypt it */
-         cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
+         if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
+            return err;
+         }
          ctr->padlen = 0;
          ctr->padlen = 0;
       }
       }
 #ifdef LTC_FAST
 #ifdef LTC_FAST

+ 1 - 3
src/modes/ctr/ctr_setiv.c

@@ -45,9 +45,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
    
    
    /* force next block */
    /* force next block */
    ctr->padlen = 0;
    ctr->padlen = 0;
-   cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
-   
-   return CRYPT_OK;
+   return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
 }
 }
 
 
 #endif 
 #endif 

+ 1 - 2
src/modes/ctr/ctr_start.c

@@ -59,8 +59,7 @@ int ctr_start(               int   cipher,
    for (x = 0; x < ctr->blocklen; x++) {
    for (x = 0; x < ctr->blocklen; x++) {
        ctr->ctr[x] = IV[x];
        ctr->ctr[x] = IV[x];
    }
    }
-   cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
-   return CRYPT_OK;
+   return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
 }
 }
 
 
 #endif
 #endif

+ 4 - 2
src/modes/ecb/ecb_decrypt.c

@@ -40,10 +40,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
 
 
    /* check for accel */
    /* check for accel */
    if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
    if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
-      cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
+      return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
    } else {
    } else {
       while (len) {
       while (len) {
-         cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
+         if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) {
+            return err;
+         }
          pt  += cipher_descriptor[ecb->cipher].block_length;
          pt  += cipher_descriptor[ecb->cipher].block_length;
          ct  += cipher_descriptor[ecb->cipher].block_length;
          ct  += cipher_descriptor[ecb->cipher].block_length;
          len -= cipher_descriptor[ecb->cipher].block_length;
          len -= cipher_descriptor[ecb->cipher].block_length;

+ 4 - 2
src/modes/ecb/ecb_encrypt.c

@@ -40,10 +40,12 @@ int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
 
 
    /* check for accel */
    /* check for accel */
    if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
    if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
-      cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
+      return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
    } else {
    } else {
       while (len) {
       while (len) {
-         cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key);
+         if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) {
+            return err;
+         }
          pt  += cipher_descriptor[ecb->cipher].block_length;
          pt  += cipher_descriptor[ecb->cipher].block_length;
          ct  += cipher_descriptor[ecb->cipher].block_length;
          ct  += cipher_descriptor[ecb->cipher].block_length;
          len -= cipher_descriptor[ecb->cipher].block_length;
          len -= cipher_descriptor[ecb->cipher].block_length;

+ 3 - 1
src/modes/ofb/ofb_encrypt.c

@@ -43,7 +43,9 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
    
    
    while (len-- > 0) {
    while (len-- > 0) {
        if (ofb->padlen == ofb->blocklen) {
        if (ofb->padlen == ofb->blocklen) {
-          cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key);
+          if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
+             return err;
+          }
           ofb->padlen = 0;
           ofb->padlen = 0;
        }
        }
        *ct++ = *pt++ ^ ofb->IV[ofb->padlen++];
        *ct++ = *pt++ ^ ofb->IV[ofb->padlen++];

+ 1 - 2
src/modes/ofb/ofb_setiv.c

@@ -41,8 +41,7 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
 
 
    /* force next block */
    /* force next block */
    ofb->padlen = 0;
    ofb->padlen = 0;
-   cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
-   return CRYPT_OK;
+   return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
 }
 }
 
 
 #endif 
 #endif 

+ 2 - 2
src/pk/asn1/der/bit/der_decode_bit_string.c

@@ -51,7 +51,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen,
    /* get the length of the data */
    /* get the length of the data */
    if (in[x] & 0x80) {
    if (in[x] & 0x80) {
       /* long format get number of length bytes */
       /* long format get number of length bytes */
-      y = in[x++] & 127;
+      y = in[x++] & 0x7F;
 
 
       /* invalid if 0 or > 2 */
       /* invalid if 0 or > 2 */
       if (y == 0 || y > 2) {
       if (y == 0 || y > 2) {
@@ -65,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen,
       }
       }
    } else {
    } else {
       /* short format */
       /* short format */
-      dlen = in[x++] & 127;
+      dlen = in[x++] & 0x7F;
    }
    }
   
   
    /* is the data len too long or too short? */
    /* is the data len too long or too short? */

+ 1 - 0
src/pk/asn1/der/choice/der_decode_choice.c

@@ -96,6 +96,7 @@ int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
            case LTC_ASN1_NULL:
            case LTC_ASN1_NULL:
                if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
                if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
                   *inlen = 2;
                   *inlen = 2;
+                  list[x].used   = 1;
                   return CRYPT_OK;
                   return CRYPT_OK;
                }
                }
                break;
                break;

+ 352 - 0
src/pk/asn1/der/sequence/der_decode_sequence_flexi.c

@@ -0,0 +1,352 @@
+/* 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_sequence_flexi.c
+  ASN.1 DER, decode a SEQUENCE with a flexi parser, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+static unsigned long fetch_length(const unsigned char *in, unsigned long inlen)
+{
+   unsigned long x, y, z;
+
+   y = 0;
+
+   /* skip type and read len */
+   if (inlen < 2) {
+      return 0xFFFFFFFF;
+   }
+   ++in; ++y;
+   
+   /* read len */
+   x = *in++; ++y;
+   
+   /* <128 means literal */
+   if (x < 128) {
+      return x+y;
+   }
+   x     &= 0x7F; /* the lower 7 bits are the length of the length */
+   inlen -= 2;
+   
+   /* len means len of len! */
+   if (x == 0 || x > 4 || x > inlen) {
+      return 0xFFFFFFFF;
+   }
+   
+   y += x;
+   z = 0;
+   while (x--) {   
+      z = (z<<8) | ((unsigned long)*in);
+      ++in;
+   }
+   return z+y;
+}
+
+/** 
+   ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
+   @param in      The input buffer
+   @param inlen   [in/out] The length of the input buffer and on output the amount of decoded data 
+   @param out     [out] A pointer to the linked list
+   @return CRYPT_OK on success.
+*/   
+int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
+{
+   ltc_asn1_list *l;
+   unsigned long err, type, len, totlen, x, y;
+   void          *realloc_tmp;
+   
+   LTC_ARGCHK(in    != NULL);
+   LTC_ARGCHK(inlen != NULL);
+   LTC_ARGCHK(out   != NULL);
+
+   l = NULL;
+   totlen = 0;
+   
+   /* scan the input and and get lengths and what not */
+   while (*inlen) {     
+      /* read the type byte */
+      type = *in;
+
+      /* fetch length */
+      len = fetch_length(in, *inlen);
+      if (len > *inlen) {
+         err = CRYPT_INVALID_PACKET;
+         goto error;
+      }
+
+      /* alloc new link */
+      if (l == NULL) {
+         l = XCALLOC(1, sizeof(*l));
+         if (l == NULL) {
+            err = CRYPT_MEM;
+            goto error;
+         }
+      } else {
+         l->next = XCALLOC(1, sizeof(*l));
+         if (l->next == NULL) {
+            err = CRYPT_MEM;
+            goto error;
+         }
+         l->next->prev = l;
+         l = l->next;
+      }
+
+      /* now switch on type */
+      switch (type) {
+         case 0x02: /* INTEGER */
+             /* init field */
+             l->type = LTC_ASN1_INTEGER;
+             l->size = 1;
+             if ((err = mp_init(&l->data)) != CRYPT_OK) {
+                 goto error;
+             }
+             
+             /* decode field */
+             if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
+                 goto error;
+             }
+             
+             /* calc length of object */
+             if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
+                 goto error;
+             }
+             break;
+
+         case 0x03: /* BIT */
+            /* init field */
+            l->type = LTC_ASN1_BIT_STRING;
+            l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char.  */
+
+            if ((l->data = XCALLOC(1, l->size)) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            break;
+
+         case 0x04: /* OCTET */
+
+            /* init field */
+            l->type = LTC_ASN1_OCTET_STRING;
+            l->size = len;
+
+            if ((l->data = XCALLOC(1, l->size)) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            break;
+
+         case 0x05: /* NULL */
+         
+            /* valid NULL is 0x05 0x00 */
+            if (in[0] != 0x05 || in[1] != 0x00) {
+               err = CRYPT_INVALID_PACKET;
+               goto error;
+            }
+            
+            /* simple to store ;-) */
+            l->type = LTC_ASN1_NULL;
+            l->data = NULL;
+            l->size = 0;
+            len     = 2;
+            
+            break;
+         
+         case 0x06: /* OID */
+         
+            /* init field */
+            l->type = LTC_ASN1_OBJECT_IDENTIFIER;
+            l->size = len;
+
+            if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            /* resize it to save a bunch of mem */
+            if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
+               /* out of heap but this is not an error */
+               break;
+            }
+            l->data = realloc_tmp;
+            break;
+         
+
+         case 0x13: /* PRINTABLE */
+         
+            /* init field */
+            l->type = LTC_ASN1_PRINTABLE_STRING;
+            l->size = len;
+
+            if ((l->data = XCALLOC(1, l->size)) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            break;
+         
+         case 0x16: /* IA5 */
+         
+            /* init field */
+            l->type = LTC_ASN1_IA5_STRING;
+            l->size = len;
+
+            if ((l->data = XCALLOC(1, l->size)) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            break;
+         
+         case 0x17: /* UTC TIME */
+         
+            /* init field */
+            l->type = LTC_ASN1_UTCTIME;
+            l->size = 1;
+
+            if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            len = *inlen;
+            if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            break;
+         
+         case 0x30: /* SEQUENCE */
+         
+             /* init field */
+             l->type = LTC_ASN1_SEQUENCE;
+             
+             /* we have to decode the SEQUENCE header and get it's length */
+             
+                /* move past type */
+                ++in; --(*inlen);
+                
+                /* read length byte */
+                x = *in++; --(*inlen);
+                
+                /* smallest SEQUENCE header */
+                y = 2;
+                
+                /* now if it's > 127 the next bytes are the length of the length */
+                if (x > 128) {
+                   x      &= 0x7F;
+                   in     += x;
+                   *inlen -= x;
+                   
+                   /* update sequence header len */
+                   y      += x;
+                }
+             
+             /* Sequence elements go as child */
+             len = *inlen;
+             if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
+                goto error;
+             }
+             
+             /* len update */
+             totlen += y;
+             
+             /* link them up y0 */
+             l->child->parent = l;
+             
+             break;
+         default:
+           /* invalid byte ... this is a soft error */
+           /* remove link */
+           l       = l->prev;
+           XFREE(l->next);
+           l->next = NULL;
+           goto outside;
+      }
+      
+      /* advance pointers */
+      totlen  += len;
+      in      += len;
+      *inlen  -= len;
+   }
+   
+outside:   
+
+   /* rewind l please */
+   while (l->prev != NULL || l->parent != NULL) {
+      if (l->parent != NULL) {
+         l = l->parent;
+      } else {
+         l = l->prev;
+      }
+   }
+   
+   /* return */
+   *out   = l;
+   *inlen = totlen;
+   return CRYPT_OK;
+
+error:
+   /* free list */
+   der_sequence_free(l);
+
+   return err;
+}
+
+#endif
+
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 7 - 0
src/pk/asn1/der/sequence/der_length_sequence.c

@@ -101,6 +101,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
                y += x;
                y += x;
                break;
                break;
 
 
+           case LTC_ASN1_UTCTIME:
+               if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;

+ 63 - 0
src/pk/asn1/der/sequence/der_sequence_free.c

@@ -0,0 +1,63 @@
+/* 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_sequence_free.c
+  ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/**
+  Free memory allocated by der_decode_sequence_flexi()
+  @param in     The list to free
+*/  
+void der_sequence_free(ltc_asn1_list *in)
+{
+   ltc_asn1_list *l;
+   
+   /* walk to the start of the chain */
+   while (in->prev != NULL || in->parent != NULL) {
+      if (in->parent != NULL) {
+          in = in->parent;
+      } else {
+          in = in->prev;
+      }
+   }
+   
+   /* now walk the list and free stuff */
+   while (in != NULL) {
+      /* is there a child? */
+      if (in->child) {
+         /* disconnect */
+         in->child->parent = NULL;
+         der_sequence_free(in->child);
+      }
+      
+      switch (in->type) { 
+         case LTC_ASN1_SEQUENCE: break;
+         case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
+         default               : if (in->data != NULL) { XFREE(in->data);    }
+      }
+      
+      /* move to next and free current */
+      l = in->next;
+      free(in);
+      in = l;
+   }     
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 138 - 0
src/pk/dsa/dsa_decrypt_key.c

@@ -0,0 +1,138 @@
+/* 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 dsa_decrypt_key.c
+  DSA Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Decrypt an DSA encrypted key
+  @param in       The ciphertext
+  @param inlen    The length of the ciphertext (octets)
+  @param out      [out] The plaintext
+  @param outlen   [in/out] The max size and resulting size of the plaintext
+  @param key      The corresponding private DSA key
+  @return CRYPT_OK if successful
+*/
+int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen,
+                          unsigned char *out, unsigned long *outlen, 
+                          dsa_key *key)
+{
+   unsigned char  *skey, *expt;
+   void           *g_pub;
+   unsigned long  x, y, hashOID[32];
+   int            hash, err;
+   ltc_asn1_list  decode[3];
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(key    != NULL);
+
+   /* right key type? */
+   if (key->type != PK_PRIVATE) {
+      return CRYPT_PK_NOT_PRIVATE;
+   }
+   
+   /* 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;
+   }
+
+   hash = find_hash_oid(hashOID, decode[0].size);                   
+   if (hash_is_valid(hash) != CRYPT_OK) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* we now have the hash! */
+   
+   if ((err = mp_init(&g_pub)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* allocate memory */
+   expt   = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
+   skey   = XMALLOC(MAXBLOCKSIZE);
+   if (expt == NULL || skey == NULL) {
+      if (expt != NULL) {
+         XFREE(expt);
+      }
+      if (skey != NULL) {
+         XFREE(skey);
+      }
+      mp_clear(g_pub);
+      return CRYPT_MEM;
+   }
+   
+   LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER,          g_pub,      1UL);
+   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;
+   }
+
+   /* make shared key */
+   x = mp_unsigned_bin_size(key->p) + 1;
+   if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) {
+      goto LBL_ERR;
+   }
+
+   y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE);
+   if ((err = hash_memory(hash, expt, x, expt, &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;
+   }
+
+   /* avoid buffer overflow */
+   if (*outlen < decode[2].size) {
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto LBL_ERR;
+   }
+
+   /* Decrypt the key */
+   for (x = 0; x < decode[2].size; x++) {
+     out[x] = expt[x] ^ skey[x];
+   }
+   *outlen = x;
+
+   err = CRYPT_OK;
+LBL_ERR:
+#ifdef LTC_CLEAN_STACK
+   zeromem(expt,   mp_unsigned_bin_size(key->p) + 1);
+   zeromem(skey,   MAXBLOCKSIZE);
+#endif
+
+   XFREE(expt);
+   XFREE(skey);
+   
+   mp_clear(g_pub);
+
+   return err;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 136 - 0
src/pk/dsa/dsa_encrypt_key.c

@@ -0,0 +1,136 @@
+/* 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 dsa_encrypt_key.c
+  DSA Crypto, Tom St Denis
+*/  
+
+#ifdef MDSA
+
+/**
+  Encrypt a symmetric key with DSA
+  @param in         The symmetric key you want to encrypt
+  @param inlen      The length of the key to encrypt (octets)
+  @param out        [out] The destination for the ciphertext
+  @param outlen     [in/out] The max size and resulting size of the ciphertext
+  @param prng       An active PRNG state
+  @param wprng      The index of the PRNG you wish to use 
+  @param hash       The index of the hash you want to use 
+  @param key        The DSA key you want to encrypt to
+  @return CRYPT_OK if successful
+*/
+int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen,
+                          unsigned char *out,  unsigned long *outlen, 
+                          prng_state *prng, int wprng, int hash, 
+                          dsa_key *key)
+{
+    unsigned char *expt, *skey;
+    void          *g_pub, *g_priv;
+    unsigned long  x, y;
+    int            err;
+
+    LTC_ARGCHK(in      != NULL);
+    LTC_ARGCHK(out     != NULL);
+    LTC_ARGCHK(outlen  != NULL);
+    LTC_ARGCHK(key     != NULL);
+
+    /* check that wprng/cipher/hash are not invalid */
+    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
+       return err;
+    }
+
+    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
+       return err;
+    }
+
+    if (inlen > hash_descriptor[hash].hashsize) {
+       return CRYPT_INVALID_HASH;
+    }
+
+    /* make a random key and export the public copy */
+    if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) {
+       return err;
+    }
+   
+    expt       = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
+    skey       = XMALLOC(MAXBLOCKSIZE);
+    if (expt == NULL  || skey == NULL) {
+       if (expt != NULL) {
+          XFREE(expt);
+       }
+       if (skey != NULL) {
+          XFREE(skey);
+       }
+       mp_clear_multi(g_pub, g_priv, NULL);
+       return CRYPT_MEM;
+    }
+    
+    /* make a random x, g^x pair */
+    x = mp_unsigned_bin_size(key->q);
+    if (prng_descriptor[wprng].read(expt, x, prng) != x) {
+       err = CRYPT_ERROR_READPRNG;
+       goto LBL_ERR;
+    }
+    
+    /* load x */
+    if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) {
+       goto LBL_ERR;
+    }
+    
+    /* compute y */
+    if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
+       goto LBL_ERR;
+    }
+    
+    /* make random key */
+    x        = mp_unsigned_bin_size(key->p) + 1;
+    if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) {
+       goto LBL_ERR;
+    }
+
+    y = MAXBLOCKSIZE;
+    if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) {
+       goto LBL_ERR;
+    }
+    
+    /* Encrypt key */
+    for (x = 0; x < inlen; x++) {
+      skey[x] ^= in[x];
+    }
+
+    err = der_encode_sequence_multi(out, outlen,
+                                    LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID,
+                                    LTC_ASN1_INTEGER,            1UL,                            g_pub,
+                                    LTC_ASN1_OCTET_STRING,       inlen,                          skey,
+                                    LTC_ASN1_EOL,                0UL,                            NULL);
+
+LBL_ERR:
+#ifdef LTC_CLEAN_STACK
+    /* clean up */
+    zeromem(expt,   mp_unsigned_bin_size(key->p) + 1);
+    zeromem(skey,   MAXBLOCKSIZE);
+#endif
+
+    XFREE(skey);
+    XFREE(expt);
+    
+    mp_clear_multi(g_pub, g_priv, NULL);
+
+    return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 1 - 0
src/pk/dsa/dsa_import.c

@@ -31,6 +31,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
 
 
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(ltc_mp.name != NULL);
 
 
    /* init key */
    /* init key */
    if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
    if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {

+ 1 - 0
src/pk/dsa/dsa_make_key.c

@@ -33,6 +33,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
    unsigned char *buf;
    unsigned char *buf;
 
 
    LTC_ARGCHK(key  != NULL);
    LTC_ARGCHK(key  != NULL);
+   LTC_ARGCHK(ltc_mp.name != NULL);
 
 
    /* check prng */
    /* check prng */
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {

+ 71 - 0
src/pk/dsa/dsa_shared_secret.c

@@ -0,0 +1,71 @@
+/* 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 dsa_shared_secret.c
+  DSA Crypto, Tom St Denis
+*/  
+
+#ifdef MDSA
+
+/**
+  Create a DSA shared secret between two keys
+  @param private_key      The private DSA key (the exponent)
+  @param base             The base of the exponentiation (allows this to be used for both encrypt and decrypt) 
+  @param public_key       The public key
+  @param out              [out] Destination of the shared secret
+  @param outlen           [in/out] The max size and resulting size of the shared secret
+  @return CRYPT_OK if successful
+*/
+int dsa_shared_secret(void          *private_key, void *base,
+                      dsa_key       *public_key,
+                      unsigned char *out,         unsigned long *outlen)
+{
+   unsigned long x;
+   void *res;
+   int err;
+
+   LTC_ARGCHK(private_key != NULL);
+   LTC_ARGCHK(public_key  != NULL);
+   LTC_ARGCHK(out         != NULL);
+   LTC_ARGCHK(outlen      != NULL);
+
+   /* make new point */
+   if ((err = mp_init(&res)) != CRYPT_OK) {
+      return err;
+   }
+
+   if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) {
+      mp_clear(res);
+      return err;
+   }
+   
+   x = (unsigned long)mp_unsigned_bin_size(res);
+   if (*outlen < x) {
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto done;
+   }
+   zeromem(out, x);
+   if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res))))   != CRYPT_OK)          { goto done; }
+
+   err     = CRYPT_OK;
+   *outlen = x;
+done:
+   mp_clear(res);
+   return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

File diff suppressed because it is too large
+ 0 - 1064
src/pk/ecc/ecc.c


+ 149 - 0
src/pk/ecc/ecc_decrypt_key.c

@@ -0,0 +1,149 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_decrypt_key.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Decrypt an ECC encrypted key
+  @param in       The ciphertext
+  @param inlen    The length of the ciphertext (octets)
+  @param out      [out] The plaintext
+  @param outlen   [in/out] The max size and resulting size of the plaintext
+  @param key      The corresponding private ECC key
+  @return CRYPT_OK if successful
+*/
+int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
+                          unsigned char *out, unsigned long *outlen, 
+                          ecc_key *key)
+{
+   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);
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(key    != NULL);
+
+   /* right key type? */
+   if (key->type != PK_PRIVATE) {
+      return CRYPT_PK_NOT_PRIVATE;
+   }
+   
+   /* 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;
+   }
+
+   hash = find_hash_oid(hashOID, decode[0].size);                   
+   if (hash_is_valid(hash) != CRYPT_OK) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* we now have the hash! */
+
+   /* allocate memory */
+   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);
+      }
+      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, ecc_shared, &x)) != CRYPT_OK) {
+      ecc_free(&pubkey);
+      goto LBL_ERR;
+   }
+   ecc_free(&pubkey);
+
+   y = MIN(ECC_BUF_SIZE, 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;
+   }
+
+   /* avoid buffer overflow */
+   if (*outlen < decode[2].size) {
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto LBL_ERR;
+   }
+
+   /* Decrypt the key */
+   for (x = 0; x < decode[2].size; x++) {
+     out[x] = skey[x] ^ ecc_shared[x];
+   }
+   *outlen = x;
+
+   err = CRYPT_OK;
+LBL_ERR:
+#ifdef LTC_CLEAN_STACK
+   zeromem(pub_expt,   ECC_BUF_SIZE);
+   zeromem(ecc_shared, ECC_BUF_SIZE);
+   zeromem(skey,       MAXBLOCKSIZE);
+#endif
+
+   XFREE(pub_expt);
+   XFREE(ecc_shared);
+   XFREE(skey);
+
+   return err;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 136 - 0
src/pk/ecc/ecc_encrypt_key.c

@@ -0,0 +1,136 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_encrypt_key.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Encrypt a symmetric key with ECC 
+  @param in         The symmetric key you want to encrypt
+  @param inlen      The length of the key to encrypt (octets)
+  @param out        [out] The destination for the ciphertext
+  @param outlen     [in/out] The max size and resulting size of the ciphertext
+  @param prng       An active PRNG state
+  @param wprng      The index of the PRNG you wish to use 
+  @param hash       The index of the hash you want to use 
+  @param key        The ECC key you want to encrypt to
+  @return CRYPT_OK if successful
+*/
+int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
+                          unsigned char *out,  unsigned long *outlen, 
+                          prng_state *prng, int wprng, int hash, 
+                          ecc_key *key)
+{
+    unsigned char *pub_expt, *ecc_shared, *skey;
+    ecc_key        pubkey;
+    unsigned long  x, y, pubkeysize;
+    int            err;
+
+    LTC_ARGCHK(in      != NULL);
+    LTC_ARGCHK(out     != NULL);
+    LTC_ARGCHK(outlen  != NULL);
+    LTC_ARGCHK(key     != NULL);
+
+    /* check that wprng/cipher/hash are not invalid */
+    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
+       return err;
+    }
+
+    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
+       return err;
+    }
+
+    if (inlen > hash_descriptor[hash].hashsize) {
+       return CRYPT_INVALID_HASH;
+    }
+
+    /* make a random key and export the public copy */
+    if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
+       return err;
+    }
+
+    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;
+    }
+
+    pubkeysize = ECC_BUF_SIZE;
+    if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
+       ecc_free(&pubkey);
+       goto LBL_ERR;
+    }
+    
+    /* make random key */
+    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);
+    y = MAXBLOCKSIZE;
+    if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
+       goto LBL_ERR;
+    }
+    
+    /* Encrypt key */
+    for (x = 0; x < inlen; x++) {
+      skey[x] ^= in[x];
+    }
+
+    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);
+
+LBL_ERR:
+#ifdef LTC_CLEAN_STACK
+    /* clean up */
+    zeromem(pub_expt,   ECC_BUF_SIZE);
+    zeromem(ecc_shared, ECC_BUF_SIZE);
+    zeromem(skey,       MAXBLOCKSIZE);
+#endif
+
+    XFREE(skey);
+    XFREE(ecc_shared);
+    XFREE(pub_expt);
+
+    return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 82 - 0
src/pk/ecc/ecc_export.c

@@ -0,0 +1,82 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_export.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Export an ECC key as a binary packet
+  @param out     [out] Destination for the key
+  @param outlen  [in/out] Max size and resulting size of the exported key
+  @param type    The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
+  @param key     The key to export
+  @return CRYPT_OK if successful
+*/
+int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
+{
+   int           err;
+   unsigned char flags[1];
+   unsigned long key_size;
+
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(key    != NULL);
+   
+   /* type valid? */
+   if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
+      return CRYPT_PK_TYPE_MISMATCH;
+   }
+
+   if (ltc_ecc_is_valid_idx(key->idx) == 0) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* we store the NIST byte size */
+   key_size = ltc_ecc_sets[key->idx].size;
+
+   if (type == PK_PRIVATE) {
+       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);
+   }
+
+   return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 40 - 0
src/pk/ecc/ecc_free.c

@@ -0,0 +1,40 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_free.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Free an ECC key from memory
+  @param key   The key you wish to free
+*/
+void ecc_free(ecc_key *key)
+{
+   LTC_ARGCHK(key != NULL);
+   mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 44 - 0
src/pk/ecc/ecc_get_size.c

@@ -0,0 +1,44 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_get_size.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Get the size of an ECC key
+  @param key    The key to get the size of 
+  @return The size (octets) of the key or INT_MAX on error
+*/
+int ecc_get_size(ecc_key *key)
+{
+   LTC_ARGCHK(key != NULL);
+   if (ltc_ecc_is_valid_idx(key->idx))
+      return ltc_ecc_sets[key->idx].size;
+   else
+      return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 155 - 0
src/pk/ecc/ecc_import.c

@@ -0,0 +1,155 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_import.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+static int is_point(ecc_key *key)
+{
+   void *prime, *b, *t1, *t2;
+   int err;
+   
+   if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) {
+      return err;
+   }
+   
+   /* load prime and b */
+   if ((err = mp_read_radix(prime, ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)            { goto error; }
+   if ((err = mp_read_radix(b, ltc_ecc_sets[key->idx].B, 64)) != CRYPT_OK)                    { goto error; }
+   
+   /* compute y^2 */
+   if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK)                                         { goto error; }
+   
+   /* compute x^3 */
+   if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK)                                         { goto error; }
+   if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK)                                             { goto error; }
+   if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK)                                     { goto error; }
+   
+   /* compute y^2 - x^3 */
+   if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK)                                                { goto error; }
+   
+   /* compute y^2 - x^3 + 3x */
+   if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
+   if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
+   if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; }
+   if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK)                                             { goto error; }
+   while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
+      if ((err = mp_add(t1, prime, t1)) != CRYPT_OK)                                          { goto error; }
+   }
+   while (mp_cmp(t1, prime) != LTC_MP_LT) {
+      if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK)                                          { goto error; }
+   }
+   
+   /* compare to b */
+   if (mp_cmp(t1, b) != LTC_MP_EQ) {
+      err = CRYPT_INVALID_PACKET;
+   } else {
+      err = CRYPT_OK;
+   }
+   
+error:
+   mp_clear_multi(prime, b, t1, t2, NULL);
+   return err;
+}
+
+/**
+  Import an ECC key from a binary packet
+  @param in      The packet to import
+  @param inlen   The length of the packet
+  @param key     [out] The destination of the import
+  @return CRYPT_OK if successful, upon error all allocated memory will be freed
+*/
+int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
+{
+   unsigned long key_size;
+   unsigned char flags[1];
+   int           err;
+
+   LTC_ARGCHK(in  != NULL);
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(ltc_mp.name != NULL);
+
+   /* init key */
+   if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) {
+      return CRYPT_MEM;
+   }
+
+   /* 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 done;
+   }
+
+
+   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 done;
+      }
+   } else {
+      /* public 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 done;
+      }
+   }
+
+   /* find the idx */
+   for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx);
+   if (ltc_ecc_sets[key->idx].size == 0) {
+      err = CRYPT_INVALID_PACKET;
+      goto done;
+   }
+
+   /* set z */
+   mp_set(key->pubkey.z, 1);
+   
+   /* is it a point on the curve?  */
+   if ((err = is_point(key)) != CRYPT_OK) {
+      goto done;
+   }
+
+   /* we're good */
+   return CRYPT_OK;
+done:
+   mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
+   return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 112 - 0
src/pk/ecc/ecc_make_key.c

@@ -0,0 +1,112 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_make_key.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Make a new ECC key 
+  @param prng         An active PRNG state
+  @param wprng        The index of the PRNG you wish to use
+  @param keysize      The keysize for the new key (in octets from 20 to 65 bytes)
+  @param key          [out] Destination of the newly created key
+  @return CRYPT_OK if successful, upon error all allocated memory will be freed
+*/
+int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
+{
+   int            x, err;
+   ecc_point     *base;
+   void          *prime;
+   unsigned char *buf;
+
+   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(ltc_mp.name != NULL);
+
+   /* good prng? */
+   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* find key size */
+   for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++);
+   keysize = ltc_ecc_sets[x].size;
+
+   if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) {
+      return CRYPT_INVALID_KEYSIZE;
+   }
+   key->idx = x;
+
+   /* allocate ram */
+   base = NULL;
+   buf  = XMALLOC(ECC_MAXSIZE);
+   if (buf == NULL) {
+      return CRYPT_MEM;
+   }
+
+   /* make up random string */
+   if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
+      err = CRYPT_ERROR_READPRNG;
+      goto LBL_ERR2;
+   }
+
+   /* setup the key variables */
+   if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL)) != CRYPT_OK) {
+      goto done;
+   }
+   base = ltc_ecc_new_point();
+   if (base == NULL) {
+      mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, NULL);
+      err = CRYPT_MEM;
+      goto done;
+   }
+
+   /* read in the specs for this key */
+   if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)      { goto done; }
+   if ((err = mp_read_radix(base->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK)       { goto done; }
+   if ((err = mp_read_radix(base->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK)       { goto done; }
+   mp_set(base->z, 1);
+   if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK)         { goto done; }
+
+   /* make the public key */
+   if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK)              { goto done; }
+   key->type = PK_PRIVATE;
+
+   /* free up ram */
+   err = CRYPT_OK;
+done:
+   ltc_ecc_del_point(base);
+   mp_clear(prime);
+LBL_ERR2:
+#ifdef LTC_CLEAN_STACK
+   zeromem(buf, ECC_MAXSIZE);
+#endif
+
+   XFREE(buf);
+
+   return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 94 - 0
src/pk/ecc/ecc_shared_secret.c

@@ -0,0 +1,94 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_shared_secret.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  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 (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;
+   ecc_point *result;
+   void *prime;
+   int err;
+
+   LTC_ARGCHK(private_key != NULL);
+   LTC_ARGCHK(public_key  != NULL);
+   LTC_ARGCHK(out         != NULL);
+   LTC_ARGCHK(outlen      != NULL);
+
+   /* type valid? */
+   if (private_key->type != PK_PRIVATE) {
+      return CRYPT_PK_NOT_PRIVATE;
+   }
+
+   if (ltc_ecc_is_valid_idx(private_key->idx) == 0) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   if (private_key->idx != public_key->idx) {
+      return CRYPT_PK_TYPE_MISMATCH;
+   }
+
+   /* make new point */
+   result = ltc_ecc_new_point();
+   if (result == NULL) {
+      return CRYPT_MEM;
+   }
+
+   if ((err = mp_init(&prime)) != CRYPT_OK) {
+      ltc_ecc_del_point(result);
+      return err;
+   }
+
+   if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[private_key->idx].prime, 64)) != CRYPT_OK)                 { goto done; }
+   if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK)                { goto done; }
+
+   x = (unsigned long)mp_unsigned_bin_size(prime);
+   if (*outlen < x) {
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto done;
+   }
+   zeromem(out, x);
+   if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x))))   != CRYPT_OK)           { goto done; }
+
+   err     = CRYPT_OK;
+   *outlen = x;
+done:
+   mp_clear(prime);
+   ltc_ecc_del_point(result);
+   return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 118 - 0
src/pk/ecc/ecc_sign_hash.c

@@ -0,0 +1,118 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_sign_hash.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Sign a message digest
+  @param in        The message digest to sign
+  @param inlen     The length of the digest
+  @param out       [out] The destination for 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 you wish to use
+  @param key       A private ECC key
+  @return CRYPT_OK if successful
+*/
+int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
+                        unsigned char *out, unsigned long *outlen, 
+                        prng_state *prng, int wprng, ecc_key *key)
+{
+   ecc_key       pubkey;
+   void          *r, *s, *e, *p;
+   int           err;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+   LTC_ARGCHK(key    != NULL);
+
+   /* is this a private key? */
+   if (key->type != PK_PRIVATE) {
+      return CRYPT_PK_NOT_PRIVATE;
+   }
+   
+   /* is the IDX valid ?  */
+   if (ltc_ecc_is_valid_idx(key->idx) != 1) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+   
+   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* get the hash and load it as a bignum into 'e' */
+   /* init the bignums */
+   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { 
+      ecc_free(&pubkey);
+      goto LBL_ERR;
+   }
+   if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)        { goto error; }
+   if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)  { goto error; }
+
+   /* 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)) != CRYPT_OK)                           { goto error; }
+
+      if (mp_iszero(r)) {
+         ecc_free(&pubkey);
+      } else { 
+        /* find s = (e + xr)/k */
+        if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)            { goto error; } /* k = 1/k */
+        if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)                  { goto error; } /* s = xr */
+        if ((err = mp_add(e, s, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */
+        if ((err = mp_mod(s, p, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */
+        if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK)                { goto error; } /* s = (e + xr)/k */
+
+        if (mp_iszero(s)) {
+           ecc_free(&pubkey);
+        } else {
+           break;
+        }
+      }
+   }
+
+   /* 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:
+LBL_ERR:
+   mp_clear_multi(r, s, p, e, NULL);
+   ecc_free(&pubkey);
+
+   return err;   
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 48 - 0
src/pk/ecc/ecc_sizes.c

@@ -0,0 +1,48 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_sizes.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+void ecc_sizes(int *low, int *high)
+{
+ int i;
+ LTC_ARGCHK(low  != NULL);
+ LTC_ARGCHK(high != NULL);
+
+ *low = INT_MAX;
+ *high = 0;
+ for (i = 0; ltc_ecc_sets[i].size != 0; i++) {
+     if (ltc_ecc_sets[i].size < *low)  {
+        *low  = ltc_ecc_sets[i].size;
+     }
+     if (ltc_ecc_sets[i].size > *high) {
+        *high = ltc_ecc_sets[i].size;
+     }
+ }
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 0 - 472
src/pk/ecc/ecc_sys.c

@@ -1,472 +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
- */
-
-/**
-  @file ecc_sys.c
-  ECC Crypto, Tom St Denis
-*/
-  
-/**
-  Encrypt a symmetric key with ECC 
-  @param in         The symmetric key you want to encrypt
-  @param inlen      The length of the key to encrypt (octets)
-  @param out        [out] The destination for the ciphertext
-  @param outlen     [in/out] The max size and resulting size of the ciphertext
-  @param prng       An active PRNG state
-  @param wprng      The index of the PRNG you wish to use 
-  @param hash       The index of the hash you want to use 
-  @param key        The ECC key you want to encrypt to
-  @return CRYPT_OK if successful
-*/
-int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
-                          unsigned char *out,  unsigned long *outlen, 
-                          prng_state *prng, int wprng, int hash, 
-                          ecc_key *key)
-{
-    unsigned char *pub_expt, *ecc_shared, *skey;
-    ecc_key        pubkey;
-    unsigned long  x, y, pubkeysize;
-    int            err;
-
-    LTC_ARGCHK(in      != NULL);
-    LTC_ARGCHK(out     != NULL);
-    LTC_ARGCHK(outlen  != NULL);
-    LTC_ARGCHK(key     != NULL);
-
-    /* check that wprng/cipher/hash are not invalid */
-    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
-       return err;
-    }
-
-    if ((err = hash_is_valid(hash)) != CRYPT_OK) {
-       return err;
-    }
-
-    if (inlen > hash_descriptor[hash].hashsize) {
-       return CRYPT_INVALID_HASH;
-    }
-
-    /* make a random key and export the public copy */
-    if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
-       return err;
-    }
-
-    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;
-    }
-
-    pubkeysize = ECC_BUF_SIZE;
-    if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
-       ecc_free(&pubkey);
-       goto LBL_ERR;
-    }
-    
-    /* make random key */
-    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);
-    y = MAXBLOCKSIZE;
-    if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
-       goto LBL_ERR;
-    }
-    
-    /* Encrypt key */
-    for (x = 0; x < inlen; x++) {
-      skey[x] ^= in[x];
-    }
-
-    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);
-
-LBL_ERR:
-#ifdef LTC_CLEAN_STACK
-    /* clean up */
-    zeromem(pub_expt,   ECC_BUF_SIZE);
-    zeromem(ecc_shared, ECC_BUF_SIZE);
-    zeromem(skey,       MAXBLOCKSIZE);
-#endif
-
-    XFREE(skey);
-    XFREE(ecc_shared);
-    XFREE(pub_expt);
-
-    return err;
-}
-
-/**
-  Decrypt an ECC encrypted key
-  @param in       The ciphertext
-  @param inlen    The length of the ciphertext (octets)
-  @param out      [out] The plaintext
-  @param outlen   [in/out] The max size and resulting size of the plaintext
-  @param key      The corresponding private ECC key
-  @return CRYPT_OK if successful
-*/
-int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen,
-                          unsigned char *out, unsigned long *outlen, 
-                          ecc_key *key)
-{
-   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);
-   LTC_ARGCHK(outlen != NULL);
-   LTC_ARGCHK(key    != NULL);
-
-   /* right key type? */
-   if (key->type != PK_PRIVATE) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-   
-   /* 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++);
-
-   if (hash_descriptor[hash].name == NULL) {
-      return CRYPT_INVALID_PACKET;
-   }
-
-   /* we now have the hash! */
-
-   /* allocate memory */
-   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);
-      }
-      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, ecc_shared, &x)) != CRYPT_OK) {
-      ecc_free(&pubkey);
-      goto LBL_ERR;
-   }
-   ecc_free(&pubkey);
-
-   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;
-   }
-
-   /* avoid buffer overflow */
-   if (*outlen < decode[2].size) {
-      err = CRYPT_BUFFER_OVERFLOW;
-      goto LBL_ERR;
-   }
-
-   /* Decrypt the key */
-   for (x = 0; x < decode[2].size; x++) {
-     out[x] = skey[x] ^ ecc_shared[x];
-   }
-   *outlen = x;
-
-   err = CRYPT_OK;
-LBL_ERR:
-#ifdef LTC_CLEAN_STACK
-   zeromem(pub_expt,   ECC_BUF_SIZE);
-   zeromem(ecc_shared, ECC_BUF_SIZE);
-   zeromem(skey,       MAXBLOCKSIZE);
-#endif
-
-   XFREE(pub_expt);
-   XFREE(ecc_shared);
-   XFREE(skey);
-
-   return err;
-}
-
-/**
-  Sign a message digest
-  @param in        The message digest to sign
-  @param inlen     The length of the digest
-  @param out       [out] The destination for 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 you wish to use
-  @param key       A private ECC key
-  @return CRYPT_OK if successful
-*/
-int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                        unsigned char *out, unsigned long *outlen, 
-                        prng_state *prng, int wprng, ecc_key *key)
-{
-   ecc_key       pubkey;
-   void          *r, *s, *e, *p;
-   int           err;
-
-   LTC_ARGCHK(in     != NULL);
-   LTC_ARGCHK(out    != NULL);
-   LTC_ARGCHK(outlen != NULL);
-   LTC_ARGCHK(key    != NULL);
-
-   /* is this a private key? */
-   if (key->type != PK_PRIVATE) {
-      return CRYPT_PK_NOT_PRIVATE;
-   }
-   
-   /* is the IDX valid ?  */
-   if (is_valid_idx(key->idx) != 1) {
-      return CRYPT_PK_INVALID_TYPE;
-   }
-   
-   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* get the hash and load it as a bignum into 'e' */
-   /* init the bignums */
-   if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { 
-      ecc_free(&pubkey);
-      goto LBL_ERR;
-   }
-   if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)        { goto error; }
-   if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)  { goto error; }
-
-   /* 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)) != CRYPT_OK)                           { goto error; }
-
-      if (mp_iszero(r)) {
-         ecc_free(&pubkey);
-      } else { 
-        /* find s = (e + xr)/k */
-        if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)            { goto error; } /* k = 1/k */
-        if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)                 { goto error; } /* s = xr */
-        if ((err = mp_add(e, s, s)) != CRYPT_OK)                      { goto error; } /* s = e +  xr */
-        if ((err = mp_mod(s, p, s)) != CRYPT_OK)                      { goto error; } /* s = e +  xr */
-        if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK)               { goto error; } /* s = (e + xr)/k */
-
-        if (mp_iszero(s)) {
-           ecc_free(&pubkey);
-        } else {
-           break;
-        }
-      }
-   }
-
-   /* 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:
-LBL_ERR:
-   mp_clear_multi(r, s, p, e, NULL);
-   ecc_free(&pubkey);
-
-   return err;   
-}
-
-/* verify 
- *
- * w  = s^-1 mod n
- * u1 = xw 
- * u2 = rw
- * X = u1*G + u2*Q
- * v = X_x1 mod n
- * accept if v == r
- */
-
-/**
-   Verify an ECC signature
-   @param sig         The signature to verify
-   @param siglen      The length of the signature (octets)
-   @param hash        The hash (message digest) that was signed
-   @param hashlen     The length of the hash (octets)
-   @param stat        Result of signature, 1==valid, 0==invalid
-   @param key         The corresponding public ECC key
-   @return CRYPT_OK if successful (even if the signature is not valid)
-*/
-int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
-                    const unsigned char *hash, unsigned long hashlen, 
-                    int *stat, ecc_key *key)
-{
-   ecc_point    *mG, *mQ;
-   void          *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
-   void          *mp;
-   int           err;
-
-   LTC_ARGCHK(sig  != NULL);
-   LTC_ARGCHK(hash != NULL);
-   LTC_ARGCHK(stat != NULL);
-   LTC_ARGCHK(key  != NULL);
-
-   /* default to invalid signature */
-   *stat = 0;
-   mp    = NULL;
-
-   /* 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)) != CRYPT_OK) {
-      return CRYPT_MEM;
-   }
-
-   /* allocate points */
-   mG = ltc_ecc_new_point();
-   mQ = ltc_ecc_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 *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)                  { goto error; }
-
-   /* get the modulus */
-   if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)                  { goto error; }
-
-   /* check for zero */
-   if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
-      err = CRYPT_INVALID_PACKET;
-      goto done;
-   }
-
-   /* read hash */
-   if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK)                { goto error; }
-
-   /*  w  = s^-1 mod n */
-   if ((err = mp_invmod(s, p, w)) != CRYPT_OK)                                                          { goto error; }
-
-   /* u1 = ew */
-   if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK)                                                      { goto error; }
-
-   /* u2 = rw */
-   if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK)                                                      { goto error; }
-
-   /* find mG = u1*G */
-   if ((err = mp_read_radix(mG->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK)                 { goto error; }
-   if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK)                 { goto error; }
-   mp_set(mG->z, 1);  
-   if ((err = ltc_ecc_mulmod(u1, mG, mG, m, 0)) != CRYPT_OK)                                            { goto done; }
-
-   /* find mQ = u2*Q */
-   if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK)                                               { goto error; }
-   if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK)                                               { goto error; }
-   if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK)                                               { goto error; }
-   if ((err = ltc_ecc_mulmod(u2, mQ, mQ, m, 0)) != CRYPT_OK)                                            { goto done; }
-  
-   /* find the montgomery mp */
-   if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK)                                                 { goto error; }
-   /* add them */
-   if (ltc_mp.ecc_ptadd != NULL) {
-      if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK)                                      { goto done; }
-   } else {
-      if ((err = ltc_ecc_add_point(mQ, mG, mG, m, mp)) != CRYPT_OK)                                     { goto done; }
-   }
-   
-   /* reduce */
-   if (ltc_mp.ecc_map != NULL) {
-      if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK)                                                { goto done; }
-   } else {
-      if ((err = ltc_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) == LTC_MP_EQ) {
-      *stat = 1;
-   }
-
-   /* clear up and return */
-   err = CRYPT_OK;
-   goto done;
-error:
-done:
-   ltc_ecc_del_point(mG);
-   ltc_ecc_del_point(mQ);
-   mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
-   if (mp != NULL) { 
-      mp_montgomery_free(mp);
-   }
-   return err;
-}
-
-
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */

+ 96 - 0
src/pk/ecc/ecc_test.c

@@ -0,0 +1,96 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_test.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Perform on the ECC system
+  @return CRYPT_OK if successful
+*/
+int ecc_test(void)
+{
+   void     *modulus, *order;
+   ecc_point  *G, *GG;
+   int i, err, primality;
+
+   if ((err = mp_init_multi(&modulus, &order, NULL)) != CRYPT_OK) {
+      return err;
+   }
+
+   G   = ltc_ecc_new_point();
+   GG  = ltc_ecc_new_point();
+   if (G == NULL || GG == NULL) {
+      mp_clear_multi(modulus, order, NULL);
+      ltc_ecc_del_point(G);
+      ltc_ecc_del_point(GG);
+      return CRYPT_MEM;
+   }
+
+   for (i = 0; ltc_ecc_sets[i].size; i++) {
+       #if 0
+          printf("Testing %d\n", ltc_ecc_sets[i].size);
+       #endif
+       if ((err = mp_read_radix(modulus, (char *)ltc_ecc_sets[i].prime, 64)) != CRYPT_OK)   { goto done; }
+       if ((err = mp_read_radix(order, (char *)ltc_ecc_sets[i].order, 64)) != CRYPT_OK)     { goto done; }
+
+       /* is prime actually prime? */
+       if ((err = mp_prime_is_prime(modulus, 8, &primality)) != CRYPT_OK)                   { goto done; }
+       if (primality == 0) {
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
+       }
+
+       /* is order prime ? */
+       if ((err = mp_prime_is_prime(order, 8, &primality)) != CRYPT_OK)                     { goto done; }
+       if (primality == 0) {
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
+       }
+
+       if ((err = mp_read_radix(G->x, (char *)ltc_ecc_sets[i].Gx, 64)) != CRYPT_OK)         { goto done; }
+       if ((err = mp_read_radix(G->y, (char *)ltc_ecc_sets[i].Gy, 64)) != CRYPT_OK)         { goto done; }
+       mp_set(G->z, 1);
+
+       /* then we should have G == (order + 1)G */
+       if ((err = mp_add_d(order, 1, order)) != CRYPT_OK)                                   { goto done; }
+       if ((err = ltc_mp.ecc_ptmul(order, G, GG, modulus, 1)) != CRYPT_OK)                  { goto done; }
+       if (mp_cmp(G->x, GG->x) != LTC_MP_EQ || mp_cmp(G->y, GG->y) != LTC_MP_EQ) {
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
+       }
+   }
+   err = CRYPT_OK;
+   goto done;
+done:
+   ltc_ecc_del_point(GG);
+   ltc_ecc_del_point(G);
+   mp_clear_multi(order, modulus, NULL);
+   return err;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 160 - 0
src/pk/ecc/ecc_verify_hash.c

@@ -0,0 +1,160 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ecc_verify_hash.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/* verify 
+ *
+ * w  = s^-1 mod n
+ * u1 = xw 
+ * u2 = rw
+ * X = u1*G + u2*Q
+ * v = X_x1 mod n
+ * accept if v == r
+ */
+
+/**
+   Verify an ECC signature
+   @param sig         The signature to verify
+   @param siglen      The length of the signature (octets)
+   @param hash        The hash (message digest) that was signed
+   @param hashlen     The length of the hash (octets)
+   @param stat        Result of signature, 1==valid, 0==invalid
+   @param key         The corresponding public ECC key
+   @return CRYPT_OK if successful (even if the signature is not valid)
+*/
+int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
+                    const unsigned char *hash, unsigned long hashlen, 
+                    int *stat, ecc_key *key)
+{
+   ecc_point    *mG, *mQ;
+   void          *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
+   void          *mp;
+   int           err;
+
+   LTC_ARGCHK(sig  != NULL);
+   LTC_ARGCHK(hash != NULL);
+   LTC_ARGCHK(stat != NULL);
+   LTC_ARGCHK(key  != NULL);
+
+   /* default to invalid signature */
+   *stat = 0;
+   mp    = NULL;
+
+   /* is the IDX valid ?  */
+   if (ltc_ecc_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)) != CRYPT_OK) {
+      return CRYPT_MEM;
+   }
+
+   /* allocate points */
+   mG = ltc_ecc_new_point();
+   mQ = ltc_ecc_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 *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)                  { goto error; }
+
+   /* get the modulus */
+   if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)                  { goto error; }
+
+   /* check for zero */
+   if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
+      err = CRYPT_INVALID_PACKET;
+      goto done;
+   }
+
+   /* read hash */
+   if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK)                { goto error; }
+
+   /*  w  = s^-1 mod n */
+   if ((err = mp_invmod(s, p, w)) != CRYPT_OK)                                                          { goto error; }
+
+   /* u1 = ew */
+   if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK)                                                      { goto error; }
+
+   /* u2 = rw */
+   if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK)                                                      { goto error; }
+
+   /* find mG = u1*G */
+   if ((err = mp_read_radix(mG->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK)                 { goto error; }
+   if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK)                 { goto error; }
+   mp_set(mG->z, 1);  
+   if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK)                                          { goto done; }
+
+   /* find mQ = u2*Q */
+   if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK)                                               { goto error; }
+   if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK)                                               { goto error; }
+   if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK)                                               { goto error; }
+   if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK)                                          { goto done; }
+  
+   /* find the montgomery mp */
+   if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK)                                                 { goto error; }
+   /* add them */
+   if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK)                                         { goto done; }
+   
+   /* reduce */
+   if ((err = ltc_mp.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) == LTC_MP_EQ) {
+      *stat = 1;
+   }
+
+   /* clear up and return */
+   err = CRYPT_OK;
+   goto done;
+error:
+done:
+   ltc_ecc_del_point(mG);
+   ltc_ecc_del_point(mQ);
+   mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
+   if (mp != NULL) { 
+      mp_montgomery_free(mp);
+   }
+   return err;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 45 - 0
src/pk/ecc/ltc_ecc_is_valid_idx.c

@@ -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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ltc_ecc_is_valid_idx.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/** Returns whether an ECC idx is valid or not
+  @param n   The idx number to check
+  @return 1 if valid, 0 if not
+*/  
+int ltc_ecc_is_valid_idx(int n)
+{
+   int x;
+
+   for (x = 0; ltc_ecc_sets[x].size != 0; x++);
+   if ((n < 0) || (n >= x)) {
+      return 0;
+   }
+   return 1;
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 77 - 0
src/pk/ecc/ltc_ecc_map.c

@@ -0,0 +1,77 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ltc_ecc_map.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+  Map a projective jacbobian point back to affine space
+  @param P        [in/out] The point to map
+  @param modulus  The modulus of the field the ECC curve is in
+  @param mp       The "b" value from montgomery_setup()
+  @return CRYPT_OK on success
+*/
+int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
+{
+   void *t1, *t2;
+   int err;
+
+   LTC_ARGCHK(P       != NULL);
+   LTC_ARGCHK(modulus != NULL);
+   LTC_ARGCHK(mp      != NULL);
+
+   if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
+      return CRYPT_MEM;
+   }
+
+   /* first map z back to normal */
+   if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK)           { goto done; }
+
+   /* get 1/z */
+   if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK)                      { goto done; }
+ 
+   /* get 1/z^2 and 1/z^3 */
+   if ((err = mp_sqr(t1, t2)) != CRYPT_OK)                                    { goto done; }
+   if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK)                           { goto done; }
+   if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK)                                { goto done; }
+   if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK)                           { goto done; }
+
+   /* multiply against x/y */
+   if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK)                            { goto done; }
+   if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK)           { goto done; }
+   if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK)                            { goto done; }
+   if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK)           { goto done; }
+   mp_set(P->z, 1);
+
+   err = CRYPT_OK;
+   goto done;
+done:
+   mp_clear_multi(t1, t2, NULL);
+   return err;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 213 - 0
src/pk/ecc/ltc_ecc_mulmod.c

@@ -0,0 +1,213 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ltc_ecc_mulmod.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+#ifndef LTC_ECC_TIMING_RESISTANT
+
+/* size of sliding window, don't change this! */
+#define WINSIZE 4
+
+/**
+   Perform a point multiplication 
+   @param k    The scalar to multiply by
+   @param G    The base point
+   @param R    [out] Destination for kG
+   @param modulus  The modulus of the field the ECC curve is in
+   @param map      Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
+   @return CRYPT_OK on success
+*/
+int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
+{
+   ecc_point *tG, *M[8];
+   int        i, j, err;
+   void       *mu, *mp;
+   unsigned long buf;
+   int        first, bitbuf, bitcpy, bitcnt, mode, digidx;
+
+   LTC_ARGCHK(k       != NULL);
+   LTC_ARGCHK(G       != NULL);
+   LTC_ARGCHK(R       != NULL);
+   LTC_ARGCHK(modulus != NULL);
+
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = mp_init(&mu)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
+      mp_montgomery_free(mp);
+      mp_clear(mu);
+      return err;
+   }
+  
+  /* alloc ram for window temps */
+  for (i = 0; i < 8; i++) {
+      M[i] = ltc_ecc_new_point();
+      if (M[i] == NULL) {
+         for (j = 0; j < i; j++) {
+             ltc_ecc_del_point(M[j]);
+         }
+         mp_montgomery_free(mp);
+         mp_clear(mu);
+         return CRYPT_MEM;
+      }
+  }
+
+   /* make a copy of G incase R==G */
+   tG = ltc_ecc_new_point();
+   if (tG == NULL)                                                                   { err = CRYPT_MEM; goto done; }
+
+   /* tG = G  and convert to montgomery */
+   if (mp_cmp_d(mu, 1) == LTC_MP_EQ) {
+      if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK)                                  { goto done; }
+      if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK)                                  { goto done; }
+      if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK)                                  { goto done; }
+   } else {      
+      if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK)                   { goto done; }
+      if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK)                   { goto done; }
+      if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK)                   { goto done; }
+   }
+   mp_clear(mu);
+   
+   /* calc the M tab, which holds kG for k==8..15 */
+   /* M[0] == 8G */
+   if ((err = ltc_ecc_projective_dbl_point(tG, M[0], modulus, mp)) != CRYPT_OK)               { goto done; }
+   if ((err = ltc_ecc_projective_dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK)               { goto done; }
+   if ((err = ltc_ecc_projective_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 = ltc_ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK)   { goto done; }
+   }
+
+   /* setup sliding window */
+   mode   = 0;
+   bitcnt = 1;
+   buf    = 0;
+   digidx = mp_get_digit_count(k) - 1;
+   bitcpy = bitbuf = 0;
+   first  = 1;
+
+   /* perform ops */
+   for (;;) {
+     /* grab next digit as required */
+     if (--bitcnt == 0) {
+       if (digidx == -1) {
+          break;
+       }
+       buf    = mp_get_digit(k, digidx);
+       bitcnt = (int) MP_DIGIT_BIT;
+       --digidx;
+     }
+
+     /* grab the next msb from the ltiplicand */
+     i = (buf >> (MP_DIGIT_BIT - 1)) & 1;
+     buf <<= 1;
+
+     /* skip leading zero bits */
+     if (mode == 0 && i == 0) {
+        continue;
+     }
+
+     /* if the bit is zero and mode == 1 then we double */
+     if (mode == 1 && i == 0) {
+        if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK)                 { goto done; }
+        continue;
+     }
+
+     /* else we add it to the window */
+     bitbuf |= (i << (WINSIZE - ++bitcpy));
+     mode = 2;
+
+     if (bitcpy == WINSIZE) {
+       /* if this is the first window we do a simple copy */
+       if (first == 1) {
+          /* R = kG [k = first window] */
+          if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK)                     { goto done; }
+          if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK)                     { goto done; }
+          if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK)                     { goto done; }
+          first = 0;
+       } else {
+         /* normal window */
+         /* ok window is filled so double as required and add  */
+         /* double first */
+         for (j = 0; j < WINSIZE; j++) {
+           if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK)             { goto done; }
+         }
+
+         /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
+         if ((err = ltc_ecc_projective_add_point(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK)  { goto done; }
+       }
+       /* empty window and reset */
+       bitcpy = bitbuf = 0;
+       mode = 1;
+    }
+  }
+
+   /* if bits remain then double/add */
+   if (mode == 2 && bitcpy > 0) {
+     /* double then add */
+     for (j = 0; j < bitcpy; j++) {
+       /* only double if we have had at least one add first */
+       if (first == 0) {
+          if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK)             { goto done; }
+       }
+
+       bitbuf <<= 1;
+       if ((bitbuf & (1 << WINSIZE)) != 0) {
+         if (first == 1){
+            /* first add, so copy */
+            if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK)                           { goto done; }
+            if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK)                           { goto done; }
+            if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK)                           { goto done; }
+            first = 0;
+         } else {
+            /* then add */
+            if ((err = ltc_ecc_projective_add_point(R, tG, R, modulus, mp)) != CRYPT_OK)       { goto done; }
+         }
+       }
+     }
+   }
+
+   /* map R back from projective space */
+   if (map) {
+      err = ltc_ecc_map(R, modulus, mp);
+   } else {
+      err = CRYPT_OK;
+   }
+done:
+   mp_montgomery_free(mp);
+   ltc_ecc_del_point(tG);
+   for (i = 0; i < 8; i++) {
+       ltc_ecc_del_point(M[i]);
+   }
+   return err;
+}
+
+#endif
+
+#undef WINSIZE
+
+#endif

+ 162 - 0
src/pk/ecc/ltc_ecc_mulmod_timing.c

@@ -0,0 +1,162 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ltc_ecc_mulmod_timing.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+#ifdef LTC_ECC_TIMING_RESISTANT
+
+/**
+   Perform a point multiplication  (timing resistant)
+   @param k    The scalar to multiply by
+   @param G    The base point
+   @param R    [out] Destination for kG
+   @param modulus  The modulus of the field the ECC curve is in
+   @param map      Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
+   @return CRYPT_OK on success
+*/
+int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
+{
+   ecc_point *tG, *M[3];
+   int        i, j, err;
+   void       *mu, *mp;
+   unsigned long buf;
+   int        first, bitbuf, bitcpy, bitcnt, mode, digidx;
+
+   LTC_ARGCHK(k       != NULL);
+   LTC_ARGCHK(G       != NULL);
+   LTC_ARGCHK(R       != NULL);
+   LTC_ARGCHK(modulus != NULL);
+
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = mp_init(&mu)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
+      mp_montgomery_free(mp);
+      mp_clear(mu);
+      return err;
+   }
+
+  /* alloc ram for window temps */
+  for (i = 0; i < 3; i++) {
+      M[i] = ltc_ecc_new_point();
+      if (M[i] == NULL) {
+         for (j = 0; j < i; j++) {
+             ltc_ecc_del_point(M[j]);
+         }
+         mp_montgomery_free(mp);
+         mp_clear(mu);
+         return CRYPT_MEM;
+      }
+  }
+
+   /* make a copy of G incase R==G */
+   tG = ltc_ecc_new_point();
+   if (tG == NULL)                                                                   { err = CRYPT_MEM; goto done; }
+
+   /* tG = G  and convert to montgomery */
+   if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK)                      { goto done; }
+   if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK)                      { goto done; }
+   if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK)                      { goto done; }
+   mp_clear(mu);
+   
+   /* calc the M tab, which holds kG for k==8..15 */
+   /* M[0] == G */
+   if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK)                                   { goto done; }
+   if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK)                                   { goto done; }
+   if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK)                                   { goto done; }
+   /* M[1] == 2G */
+   if ((err = ltc_ecc_projective_dbl_point(tG, M[1], modulus, mp)) != CRYPT_OK)                  { goto done; }
+
+   /* setup sliding window */
+   mode   = 0;
+   bitcnt = 1;
+   buf    = 0;
+   digidx = mp_get_digit_count(k) - 1;
+   bitcpy = bitbuf = 0;
+   first  = 1;
+
+   /* perform ops */
+   for (;;) {
+     /* grab next digit as required */
+      if (--bitcnt == 0) {
+         if (digidx == -1) {
+            break;
+         }
+         buf    = mp_get_digit(k, digidx);
+         bitcnt = (int) MP_DIGIT_BIT;
+         --digidx;
+      }
+
+      /* grab the next msb from the ltiplicand */
+      i = (buf >> (MP_DIGIT_BIT - 1)) & 1;
+      buf <<= 1;
+
+      if (mode == 0 && i == 0) {
+         /* dummy operations */
+         if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK)    { goto done; }
+         if ((err = ltc_ecc_projective_dbl_point(M[1], M[2], modulus, mp)) != CRYPT_OK)          { goto done; }
+         continue;
+      }
+
+      if (mode == 0 && i == 1) {
+         mode = 1;
+         /* dummy operations */
+         if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK)    { goto done; }
+         if ((err = ltc_ecc_projective_dbl_point(M[1], M[2], modulus, mp)) != CRYPT_OK)          { goto done; }
+         continue;
+      }
+
+      if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK)    { goto done; }
+      if ((err = ltc_ecc_projective_dbl_point(M[i], M[i], modulus, mp)) != CRYPT_OK)            { goto done; }
+   }
+
+   /* copy result out */
+   if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK)                                   { goto done; }
+   if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK)                                   { goto done; }
+   if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK)                                   { goto done; }
+
+   /* map R back from projective space */
+   if (map) {
+      err = ltc_ecc_map(R, modulus, mp);
+   } else {
+      err = CRYPT_OK;
+   }
+done:
+   mp_montgomery_free(mp);
+   ltc_ecc_del_point(tG);
+   for (i = 0; i < 3; i++) {
+       ltc_ecc_del_point(M[i]);
+   }
+   return err;
+}
+
+#endif
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

+ 60 - 0
src/pk/ecc/ltc_ecc_points.c

@@ -0,0 +1,60 @@
+/* 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
+ */
+
+/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
+ *
+ * All curves taken from NIST recommendation paper of July 1999
+ * Available at http://csrc.nist.gov/cryptval/dss.htm
+ */
+#include "tomcrypt.h"
+
+/**
+  @file ltc_ecc_points.c
+  ECC Crypto, Tom St Denis
+*/  
+
+#ifdef MECC
+
+/**
+   Allocate a new ECC point
+   @return A newly allocated point or NULL on error 
+*/
+ecc_point *ltc_ecc_new_point(void)
+{
+   ecc_point *p;
+   p = XMALLOC(sizeof(*p));
+   if (p == NULL) {
+      return NULL;
+   }
+   if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) {
+      XFREE(p);
+      return NULL;
+   }
+   return p;
+}
+
+/** Free an ECC point from memory
+  @param p   The point to free
+*/
+void ltc_ecc_del_point(ecc_point *p)
+{
+   /* prevents free'ing null arguments */
+   if (p != NULL) {
+      mp_clear_multi(p->x, p->y, p->z, NULL);
+      XFREE(p);
+   }
+}
+
+#endif
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */
+

Some files were not shown because too many files changed in this diff