Browse Source

added libtomcrypt-1.16

Tom St Denis 19 years ago
parent
commit
e24b01d392
100 changed files with 2185 additions and 813 deletions
  1. 3 3
      Doxyfile
  2. 3 0
      README
  3. 7 4
      TODO
  4. 28 2
      changes
  5. 8 6
      crypt.lof
  6. 333 353
      crypt.tex
  7. BIN
      doc/crypt.pdf
  8. 10 8
      makefile
  9. 9 7
      makefile.icc
  10. 9 7
      makefile.msvc
  11. 10 8
      makefile.shared
  12. 239 0
      makefile.unix
  13. 6 6
      src/ciphers/twofish/twofish.c
  14. 4 4
      src/encauth/ccm/ccm_memory.c
  15. 1 1
      src/encauth/ccm/ccm_test.c
  16. 4 4
      src/encauth/gcm/gcm_process.c
  17. 41 27
      src/encauth/gcm/gcm_test.c
  18. 2 2
      src/headers/tomcrypt.h
  19. 2 0
      src/headers/tomcrypt_cfg.h
  20. 33 0
      src/headers/tomcrypt_custom.h
  21. 16 16
      src/headers/tomcrypt_macros.h
  22. 14 0
      src/headers/tomcrypt_math.h
  23. 45 6
      src/headers/tomcrypt_pk.h
  24. 1 1
      src/mac/f9/f9_file.c
  25. 1 1
      src/mac/f9/f9_memory.c
  26. 1 1
      src/mac/f9/f9_process.c
  27. 1 1
      src/mac/f9/f9_test.c
  28. 1 1
      src/mac/pelican/pelican_test.c
  29. 1 1
      src/mac/xcbc/xcbc_memory.c
  30. 1 1
      src/mac/xcbc/xcbc_test.c
  31. 314 0
      src/math/fp/ltc_ecc_fp_mulmod.c
  32. 11 2
      src/math/gmp_desc.c
  33. 11 2
      src/math/ltm_desc.c
  34. 12 3
      src/math/tfm_desc.c
  35. 3 0
      src/misc/crypt/crypt.c
  36. 1 1
      src/misc/crypt/crypt_find_cipher.c
  37. 1 1
      src/misc/crypt/crypt_find_hash.c
  38. 1 1
      src/misc/crypt/crypt_find_prng.c
  39. 7 7
      src/modes/cbc/cbc_decrypt.c
  40. 10 10
      src/modes/cbc/cbc_encrypt.c
  41. 1 1
      src/modes/cfb/cfb_decrypt.c
  42. 1 1
      src/modes/cfb/cfb_encrypt.c
  43. 7 7
      src/modes/ctr/ctr_encrypt.c
  44. 1 1
      src/modes/ofb/ofb_encrypt.c
  45. 7 6
      src/pk/asn1/der/bit/der_encode_bit_string.c
  46. 11 0
      src/pk/asn1/der/choice/der_decode_choice.c
  47. 7 7
      src/pk/asn1/der/ia5/der_encode_ia5_string.c
  48. 6 6
      src/pk/asn1/der/integer/der_encode_integer.c
  49. 6 6
      src/pk/asn1/der/object_identifier/der_decode_object_identifier.c
  50. 6 6
      src/pk/asn1/der/object_identifier/der_encode_object_identifier.c
  51. 7 7
      src/pk/asn1/der/octet/der_encode_octet_string.c
  52. 7 7
      src/pk/asn1/der/printable_string/der_encode_printable_string.c
  53. 21 9
      src/pk/asn1/der/sequence/der_decode_sequence_ex.c
  54. 29 10
      src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
  55. 2 0
      src/pk/asn1/der/sequence/der_decode_sequence_multi.c
  56. 36 20
      src/pk/asn1/der/sequence/der_encode_sequence_ex.c
  57. 2 0
      src/pk/asn1/der/sequence/der_encode_sequence_multi.c
  58. 13 6
      src/pk/asn1/der/sequence/der_length_sequence.c
  59. 1 0
      src/pk/asn1/der/set/der_encode_set.c
  60. 2 2
      src/pk/asn1/der/short_integer/der_encode_short_integer.c
  61. 1 1
      src/pk/asn1/der/utctime/der_encode_utctime.c
  62. 111 0
      src/pk/asn1/der/utf8/der_decode_utf8_string.c
  63. 105 0
      src/pk/asn1/der/utf8/der_encode_utf8_string.c
  64. 83 0
      src/pk/asn1/der/utf8/der_length_utf8_string.c
  65. 1 1
      src/pk/dsa/dsa_decrypt_key.c
  66. 0 1
      src/pk/dsa/dsa_encrypt_key.c
  67. 6 7
      src/pk/dsa/dsa_make_key.c
  68. 3 3
      src/pk/dsa/dsa_shared_secret.c
  69. 5 7
      src/pk/dsa/dsa_sign_hash.c
  70. 3 5
      src/pk/dsa/dsa_verify_hash.c
  71. 8 9
      src/pk/dsa/dsa_verify_key.c
  72. 2 2
      src/pk/ecc/ecc_ansi_x963_export.c
  73. 27 13
      src/pk/ecc/ecc_ansi_x963_import.c
  74. 1 1
      src/pk/ecc/ecc_encrypt_key.c
  75. 1 1
      src/pk/ecc/ecc_export.c
  76. 1 1
      src/pk/ecc/ecc_get_size.c
  77. 27 10
      src/pk/ecc/ecc_import.c
  78. 37 24
      src/pk/ecc/ecc_make_key.c
  79. 7 7
      src/pk/ecc/ecc_shared_secret.c
  80. 11 15
      src/pk/ecc/ecc_sign_hash.c
  81. 0 1
      src/pk/ecc/ecc_test.c
  82. 26 21
      src/pk/ecc/ecc_verify_hash.c
  83. 4 3
      src/pk/ecc/ltc_ecc_is_valid_idx.c
  84. 2 3
      src/pk/ecc/ltc_ecc_map.c
  85. 207 0
      src/pk/ecc/ltc_ecc_mul2add.c
  86. 9 4
      src/pk/ecc/ltc_ecc_mulmod.c
  87. 7 2
      src/pk/ecc/ltc_ecc_mulmod_timing.c
  88. 1 1
      src/pk/ecc/ltc_ecc_points.c
  89. 1 2
      src/pk/ecc/ltc_ecc_projective_add_point.c
  90. 4 5
      src/pk/ecc/ltc_ecc_projective_dbl_point.c
  91. 4 4
      src/pk/pkcs1/pkcs_1_pss_decode.c
  92. 10 9
      src/pk/pkcs1/pkcs_1_v1_5_decode.c
  93. 3 5
      src/pk/rsa/rsa_exptmod.c
  94. 1 2
      src/pk/rsa/rsa_free.c
  95. 4 5
      src/pk/rsa/rsa_import.c
  96. 30 33
      src/pk/rsa/rsa_make_key.c
  97. 1 0
      src/pk/rsa/rsa_verify_hash.c
  98. 3 3
      src/prngs/fortuna.c
  99. 6 2
      src/prngs/rng_get_bytes.c
  100. 44 0
      testprof/der_tests.c

+ 3 - 3
Doxyfile

@@ -23,7 +23,7 @@ PROJECT_NAME           = LibTomCrypt
 # This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         = 1.15
+PROJECT_NUMBER         = 1.16
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
@@ -1028,14 +1028,14 @@ CLASS_DIAGRAMS         = YES
 # inheritance and usage relations if the target is undocumented 
 # or is not a class.
 
-HIDE_UNDOC_RELATIONS   = YES
+HIDE_UNDOC_RELATIONS   = NO
 
 # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
 # available from the path. This tool is part of Graphviz, a graph visualization 
 # toolkit from AT&T and Lucent Bell Labs. The other options in this section 
 # have no effect if this option is set to NO (the default)
 
-HAVE_DOT               = YES
+HAVE_DOT               = NO
 
 # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
 # will generate a graph for each documented class showing the direct and 

+ 3 - 0
README

@@ -0,0 +1,3 @@
+See doc/crypt.pdf
+
+

+ 7 - 4
TODO

@@ -1,8 +1,11 @@
-- document makefile flags [INSTALL_* for instance]
+stopped at ch12
+-- needs examples for ecc/dsa!!! (and for asn.1)
+
+must have for v1.16
 - document PK build flags
-- merge PKCS #1 v1.5 back in, document changes to rsa_encrypt and rsa_sign
+- document makefile flags [INSTALL_* for instance]
+- prepare manual for printing (both soft and hard cover)
 
-for v1.16
-- Add ECC double-mult-add to plugin and make optional accelerator for baseline and MECC_FP [two goals]
+Nice to have [in order of precedence]
 - add X9.63 IES
 - add CPP macros like OpenSSL has for ASN1 (e.g. encode/decode functions, etc) shameless ripoff :-)

+ 28 - 2
changes

@@ -1,3 +1,29 @@
+December 16th, 2006
+v1.16 -- Brian Gladman pointed out that a recent change to GCM broke how the IV was handled.  Currently the code complies against his test vectors
+         so the code should be considered frozen now.
+      -- Trevor from Cryptography Research Inc. submitted patches to convert the ECC code to be generic allowing curve parameters to be submitted
+         at runtime.  
+      -- Fixed various doxygen comments
+      -- Added UTF8 support to the ASN1 code
+      -- Fixed STOREXXH macros for x86 platforms (Fix found at Elliptic Inc.)
+      -- Added makefile.unix which is BSD compatible, you have to manually tweak it since well I don't use it normally
+      -- removed a few lingering memcpy's
+      -- Fixed memory free errors in ecc_sign_hash() that can arise if the mp_init_multi() fails
+      -- Fixed incorrect return value in pkcs_1_pss_decode() which would correctly set res to 0 (indicating an incorrect signature) but 
+         would return CRYPT_OK to the caller
+      -- ltc_ecc_mulmod() could leak memory if mp_init(&mu) failed, fixed.  Would you believe that ltc_ecc_mulmod_timing() had the same
+         bug?  Also fixed.  :-)
+      -- Added Shamir's trick to the ECC side (defined as LTC_ECC_SHAMIR, enabled by default), gets ~1.34x to ~1.40x faster ECC verifications
+      -- Added Brian's vector #46 to the GCM code.  It catches the ctr counter error from v1.15.  Originally I was going to add all of his vectors,
+         but they're not as easy to parse and I got a lot of other things to do.  Regression!
+      -- Various other small fixes to the ECC code to clean up error handling (I think most of that was from the move in 1.06 to the plugins)
+         All of the errors were in cleaning up from heap failures.  So they were not likely to be triggered in normal usage
+         Made similar fixes to the RSA and DSA code (my bad)
+      -- Cryptography Research Inc. contributed a bunch of fixes to silence warnings (with MSVC) w.r.t. assigned data to unsigned char types.
+      -- Martin Marko suggested some fixes to make the RNG build with WinCE.
+      -- Updates to the manual for print (some fixes thanks to Martin Marko)
+      
+
 November 17th, 2006
 v1.15 -- Andreas Lange found that if sha256_init DID fail in fortuna it wouldn't clean up the state correctly.  Thanks.
          Fortunately sha256_init cannot fail (as of v1.14) :-)
@@ -1525,6 +1551,6 @@ v0.02  -- Changed RC5 to only allow 12 to 24 rounds
 v0.01  -- We will call this the first version.
 
 /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
-/* $Revision: 1.257 $ */
-/* $Date: 2006/11/17 15:18:44 $ */
+/* $Revision: 1.274 $ */
+/* $Date: 2006/12/16 19:08:17 $ */
 

+ 8 - 6
crypt.lof

@@ -3,20 +3,22 @@
 \contentsline {figure}{\numberline {2.1}{\ignorespaces Load And Store Macros}}{9}{figure.2.1}
 \contentsline {figure}{\numberline {2.2}{\ignorespaces Rotate Macros}}{9}{figure.2.2}
 \addvspace {10\p@ }
-\contentsline {figure}{\numberline {3.1}{\ignorespaces Built--In Software Ciphers}}{25}{figure.3.1}
-\contentsline {figure}{\numberline {3.2}{\ignorespaces Twofish Build Options}}{27}{figure.3.2}
+\contentsline {figure}{\numberline {3.1}{\ignorespaces Built--In Software Ciphers}}{19}{figure.3.1}
+\contentsline {figure}{\numberline {3.2}{\ignorespaces Twofish Build Options}}{21}{figure.3.2}
 \addvspace {10\p@ }
-\contentsline {figure}{\numberline {4.1}{\ignorespaces Built--In Software Hashes}}{63}{figure.4.1}
+\contentsline {figure}{\numberline {4.1}{\ignorespaces Built--In Software Hashes}}{57}{figure.4.1}
 \addvspace {10\p@ }
 \addvspace {10\p@ }
-\contentsline {figure}{\numberline {6.1}{\ignorespaces List of Provided PRNGs}}{83}{figure.6.1}
+\contentsline {figure}{\numberline {6.1}{\ignorespaces List of Provided PRNGs}}{82}{figure.6.1}
 \addvspace {10\p@ }
 \addvspace {10\p@ }
 \addvspace {10\p@ }
-\contentsline {figure}{\numberline {9.1}{\ignorespaces DSA Key Sizes}}{111}{figure.9.1}
+\contentsline {figure}{\numberline {9.1}{\ignorespaces DSA Key Sizes}}{119}{figure.9.1}
 \addvspace {10\p@ }
-\contentsline {figure}{\numberline {10.1}{\ignorespaces List of ASN.1 Supported Types}}{119}{figure.10.1}
+\contentsline {figure}{\numberline {10.1}{\ignorespaces List of ASN.1 Supported Types}}{127}{figure.10.1}
 \addvspace {10\p@ }
 \addvspace {10\p@ }
+\contentsline {figure}{\numberline {12.1}{\ignorespaces RSA/DH Key Strength}}{149}{figure.12.1}
+\contentsline {figure}{\numberline {12.2}{\ignorespaces ECC Key Strength}}{149}{figure.12.2}
 \addvspace {10\p@ }
 \addvspace {10\p@ }

File diff suppressed because it is too large
+ 333 - 353
crypt.tex


BIN
doc/crypt.pdf


+ 10 - 8
makefile

@@ -4,7 +4,7 @@
 # Modified by Clay Culver
 
 # The version
-VERSION=1.15
+VERSION=1.16
 
 # Compiler and Linker Names
 #CC=gcc
@@ -187,15 +187,17 @@ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_
 src/pk/asn1/der/short_integer/der_encode_short_integer.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
-src/pk/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/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \
+src/pk/asn1/der/utf8/der_length_utf8_string.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/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.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_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.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 \
@@ -378,5 +380,5 @@ zipup: no_oops docs
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
-# $Revision: 1.142 $ 
-# $Date: 2006/11/08 22:38:16 $ 
+# $Revision: 1.145 $ 
+# $Date: 2006/12/02 19:23:21 $ 

+ 9 - 7
makefile.icc

@@ -179,15 +179,17 @@ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_
 src/pk/asn1/der/short_integer/der_encode_short_integer.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
-src/pk/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/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \
+src/pk/asn1/der/utf8/der_length_utf8_string.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/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.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_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.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 \
@@ -285,6 +287,6 @@ install: library
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $   
-# $Revision: 1.71 $   
-# $Date: 2006/11/08 22:38:16 $ 
+# $Revision: 1.73 $   
+# $Date: 2006/12/02 19:23:21 $ 
 

+ 9 - 7
makefile.msvc

@@ -89,15 +89,17 @@ src/pk/asn1/der/set/der_encode_setof.obj src/pk/asn1/der/short_integer/der_decod
 src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
 src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
 src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
-src/pk/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/asn1/der/utf8/der_decode_utf8_string.obj src/pk/asn1/der/utf8/der_encode_utf8_string.obj \
+src/pk/asn1/der/utf8/der_length_utf8_string.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/ecc/ecc_ansi_x963_export.obj src/pk/ecc/ecc_ansi_x963_import.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_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj src/pk/ecc/ltc_ecc_mul2add.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 \
@@ -143,5 +145,5 @@ timing: demos/timing.c library
 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $   
-# $Revision: 1.49 $   
-# $Date: 2006/11/08 22:38:16 $ 
+# $Revision: 1.51 $   
+# $Date: 2006/12/02 19:23:21 $ 

+ 10 - 8
makefile.shared

@@ -6,7 +6,7 @@
 # Tom St Denis
 
 # The version
-VERSION=0:115
+VERSION=0:116
 
 # Compiler and Linker Names
 CC=libtool --mode=compile --tag=CC gcc 
@@ -184,15 +184,17 @@ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_
 src/pk/asn1/der/short_integer/der_encode_short_integer.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
-src/pk/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/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \
+src/pk/asn1/der/utf8/der_length_utf8_string.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/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.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_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.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 \
@@ -273,5 +275,5 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $   
-# $Revision: 1.73 $   
-# $Date: 2006/11/08 22:38:16 $ 
+# $Revision: 1.76 $   
+# $Date: 2006/12/02 19:23:21 $ 

+ 239 - 0
makefile.unix

@@ -0,0 +1,239 @@
+# MAKEFILE for bsd make
+#
+# Tom St Denis
+
+# Compiler and Linker Names
+CC=cc
+LD=ld
+
+# Archiver [makes .a files]
+AR=ar
+ARFLAGS=r
+
+# Compilation flags. Note the += does not write over the user's CFLAGS!
+CFLAGS = -c -I./testprof/ -I./src/headers/ -DLTC_SOURCE -O2 ${CFLAGS_OPTS} -o $@
+
+LIBNAME=libtomcrypt.a
+LIBTEST=libtomcrypt_prof.a
+LIBTEST_S=$(LIBTEST)
+
+HASH=hashsum
+CRYPT=encrypt
+SMALL=small
+PROF=x86_prof
+TV=tv_gen
+MULTI=multi
+TIMING=timing
+TEST=test
+
+#LIBPATH-The directory for libtomcrypt to be installed to.
+#INCPATH-The directory to install the header files for libtomcrypt.
+#DATAPATH-The directory to install the pdf docs.
+LIBPATH=/usr/local/lib
+INCPATH=/usr/local/include
+DATAPATH=/usr/local/share/doc/libtomcrypt/pdf
+
+#Who do we install as?
+USER=root
+
+GROUP=wheel
+
+#List of objects to compile.
+#START_INS
+OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \
+src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \
+src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o \
+src/ciphers/safer/safer_tab.o src/ciphers/safer/saferp.o src/ciphers/skipjack.o \
+src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \
+src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \
+src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o src/encauth/eax/eax_encrypt.o \
+src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_init.o \
+src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o src/encauth/gcm/gcm_add_iv.o \
+src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o src/encauth/gcm/gcm_init.o \
+src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o src/encauth/gcm/gcm_process.o \
+src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o src/encauth/ocb/ocb_decrypt.o \
+src/encauth/ocb/ocb_decrypt_verify_memory.o src/encauth/ocb/ocb_done_decrypt.o \
+src/encauth/ocb/ocb_done_encrypt.o src/encauth/ocb/ocb_encrypt.o \
+src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o \
+src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o \
+src/hashes/chc/chc.o src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o \
+src/hashes/helper/hash_memory.o src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o \
+src/hashes/md5.o src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o \
+src/hashes/sha1.o src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o \
+src/hashes/whirl/whirl.o src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o \
+src/mac/f9/f9_memory.o src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o \
+src/mac/hmac/hmac_done.o src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \
+src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \
+src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \
+src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \
+src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \
+src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \
+src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \
+src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \
+src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \
+src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \
+src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \
+src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \
+src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt.o \
+src/misc/crypt/crypt_argchk.o src/misc/crypt/crypt_cipher_descriptor.o \
+src/misc/crypt/crypt_cipher_is_valid.o src/misc/crypt/crypt_find_cipher.o \
+src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher_id.o \
+src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_any.o \
+src/misc/crypt/crypt_find_hash_id.o src/misc/crypt/crypt_find_hash_oid.o \
+src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o src/misc/crypt/crypt_hash_descriptor.o \
+src/misc/crypt/crypt_hash_is_valid.o src/misc/crypt/crypt_ltc_mp_descriptor.o \
+src/misc/crypt/crypt_prng_descriptor.o src/misc/crypt/crypt_prng_is_valid.o \
+src/misc/crypt/crypt_register_cipher.o src/misc/crypt/crypt_register_hash.o \
+src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_unregister_cipher.o \
+src/misc/crypt/crypt_unregister_hash.o src/misc/crypt/crypt_unregister_prng.o \
+src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o \
+src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o \
+src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o \
+src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o \
+src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o \
+src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o \
+src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
+src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
+src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
+src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
+src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \
+src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \
+src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
+src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
+src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
+src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \
+src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \
+src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \
+src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \
+src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \
+src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_length_object_identifier.o \
+src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \
+src/pk/asn1/der/octet/der_length_octet_string.o \
+src/pk/asn1/der/printable_string/der_decode_printable_string.o \
+src/pk/asn1/der/printable_string/der_encode_printable_string.o \
+src/pk/asn1/der/printable_string/der_length_printable_string.o \
+src/pk/asn1/der/sequence/der_decode_sequence_ex.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_ex.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/set/der_encode_set.o \
+src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/short_integer/der_encode_short_integer.o \
+src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
+src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
+src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \
+src/pk/asn1/der/utf8/der_length_utf8_string.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/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.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_mul2add.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/pkcs1/pkcs_1_v1_5_decode.o \
+src/pk/pkcs1/pkcs_1_v1_5_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 \
+src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
+src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \
+src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \
+src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+
+#END_INS
+
+TESTOBJECTS=demos/test.o
+HASHOBJECTS=demos/hashsum.o
+CRYPTOBJECTS=demos/encrypt.o
+SMALLOBJECTS=demos/small.o
+TVS=demos/tv_gen.o
+MULTIS=demos/multi.o
+TIMINGS=demos/timing.o
+TESTS=demos/test.o
+
+#Files left over from making the crypt.pdf.
+LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out
+
+#Compressed filenames
+COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
+
+#The default rule for make builds the libtomcrypt library.
+default:library
+
+#ciphers come in two flavours... enc+dec and enc 
+src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
+
+#These are the rules to make certain object files.
+src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
+src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
+src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
+src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
+src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
+
+#This rule makes the libtomcrypt library.
+library: $(LIBNAME)
+
+testprof/$(LIBTEST): 
+	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) 
+
+$(LIBNAME): $(OBJECTS)
+	$(AR) $(ARFLAGS) $@ $(OBJECTS)
+	$(RANLIB) $@
+
+#This rule makes the hash program included with libtomcrypt
+hashsum: library $(HASHOBJECTS)
+	$(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN)
+
+#makes the crypt program
+crypt: library $(CRYPTOBJECTS)
+	$(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN)
+
+#makes the small program
+small: library $(SMALLOBJECTS)
+	$(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN)
+	
+tv_gen: library $(TVS)
+	$(CC) $(LDFLAGS) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV)
+
+multi: library $(MULTIS)
+	$(CC) $(MULTIS) $(LIBNAME) $(EXTRALIBS) -o $(MULTI)
+
+timing: library testprof/$(LIBTEST) $(TIMINGS)
+	$(CC) $(LDFLAGS) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING)
+
+test: library testprof/$(LIBTEST) $(TESTS)
+	$(CC) $(LDFLAGS) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST)
+
+#This rule installs the library and the header files. This must be run
+#as root in order to have a high enough permission to write to the correct
+#directories and to set the owner and group to root.
+install: library
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
+	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
+	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
+
+install_test: testprof/$(LIBTEST)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH)
+
+# $Source: /cvs/libtom/libtomcrypt/makefile.unix,v $ 
+# $Revision: 1.4 $ 
+# $Date: 2006/12/02 19:23:21 $ 

+ 6 - 6
src/ciphers/twofish/twofish.c

@@ -412,8 +412,8 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
    /* make the sboxes (large ram variant) */
    if (k == 2) {
         for (x = 0; x < 256; x++) {
-           tmpx0 = sbox(0, x);
-           tmpx1 = sbox(1, x);
+           tmpx0 = (unsigned char)sbox(0, x);
+           tmpx1 = (unsigned char)sbox(1, x);
            skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0);
            skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1);
            skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2);
@@ -421,8 +421,8 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
         }
    } else if (k == 3) {
         for (x = 0; x < 256; x++) {
-           tmpx0 = sbox(0, x);
-           tmpx1 = sbox(1, x);
+           tmpx0 = (unsigned char)sbox(0, x);
+           tmpx1 = (unsigned char)sbox(1, x);
            skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0);
            skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1);
            skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2);
@@ -430,8 +430,8 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
         }
    } else {
         for (x = 0; x < 256; x++) {
-           tmpx0 = sbox(0, x);
-           tmpx1 = sbox(1, x);
+           tmpx0 = (unsigned char)sbox(0, x);
+           tmpx1 = (unsigned char)sbox(1, x);
            skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0);
            skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1);
            skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2);

+ 4 - 4
src/encauth/ccm/ccm_memory.c

@@ -140,9 +140,9 @@ int ccm_memory(int cipher,
 
    /* form B_0 == flags | Nonce N | l(m) */
    x = 0;
-   PAD[x++] = ((headerlen > 0) ? (1<<6) : 0) |
+   PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
             (((*taglen - 2)>>1)<<3)        |
-            (L-1);
+            (L-1));
 
    /* nonce */
    for (y = 0; y < (16 - (L + 1)); y++) {
@@ -162,7 +162,7 @@ int ccm_memory(int cipher,
        PAD[x++] = 0;
    }
    for (; y < L; y++) {
-       PAD[x++] = (len >> 24) & 255;
+       PAD[x++] = (unsigned char)((len >> 24) & 255);
        len <<= 8;
    }
 
@@ -212,7 +212,7 @@ int ccm_memory(int cipher,
    x = 0;
 
    /* flags */
-   ctr[x++] = L-1;
+   ctr[x++] = (unsigned char)L-1;
  
    /* nonce */
    for (y = 0; y < (16 - (L+1)); ++y) {

+ 1 - 1
src/encauth/ccm/ccm_test.c

@@ -157,7 +157,7 @@ int ccm_test(void)
                             tests[x].header, tests[x].headerlen,
                             buf2, tests[x].ptlen,
                             buf,
-                            tag2, &taglen, 1	)) != CRYPT_OK) {
+                            tag2, &taglen, 1   )) != CRYPT_OK) {
          return err;
       }
 

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

@@ -58,7 +58,7 @@ int gcm_process(gcm_state *gcm,
       }
 
       /* increment counter */
-      for (y = 15; y >= 0; y--) {
+      for (y = 15; y >= 12; y--) {
           if (++gcm->Y[y] & 255) { break; }
       }
       /* encrypt the counter */
@@ -88,7 +88,7 @@ int gcm_process(gcm_state *gcm,
              gcm->pttotlen += 128;
              gcm_mult_h(gcm, gcm->X);
              /* increment counter */
-             for (y = 15; y >= 0; y--) {
+             for (y = 15; y >= 12; y--) {
                  if (++gcm->Y[y] & 255) { break; }
              }
              if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
@@ -106,7 +106,7 @@ int gcm_process(gcm_state *gcm,
              gcm->pttotlen += 128;
              gcm_mult_h(gcm, gcm->X);
              /* increment counter */
-             for (y = 15; y >= 0; y--) {
+             for (y = 15; y >= 12; y--) {
                  if (++gcm->Y[y] & 255) { break; }
              }
              if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
@@ -124,7 +124,7 @@ int gcm_process(gcm_state *gcm,
           gcm_mult_h(gcm, gcm->X);
           
           /* increment counter */
-          for (y = 15; y >= 0; y--) {
+          for (y = 15; y >= 12; y--) {
               if (++gcm->Y[y] & 255) { break; }
           }
           if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {

+ 41 - 27
src/encauth/gcm/gcm_test.c

@@ -29,13 +29,13 @@ int gcm_test(void)
    static const struct {
        unsigned char K[32];
        int           keylen;
-       unsigned char P[64];
+       unsigned char P[128];
        unsigned long ptlen;
-		 unsigned char A[64];
+       unsigned char A[128];
        unsigned long alen;
-       unsigned char IV[64];
+       unsigned char IV[128];
        unsigned long IVlen;
-       unsigned char C[64];
+       unsigned char C[128];
        unsigned char T[16];
    } tests[] = {
 
@@ -277,42 +277,56 @@ int gcm_test(void)
      0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, }
 },
 
-#if 0
-
-/* test case #10 */
+/* test case #46 from BG (catches the LTC bug of v1.15) */
 {
-   { 0xdb, 0xbc, 0x85, 0x66, 0xd6, 0xf5, 0xb1, 0x58, 
-     0xda, 0x99, 0xa2, 0xff, 0x2e, 0x01, 0xdd, 0xa6, 
-     0x29, 0xb8, 0x9c, 0x34, 0xad, 0x1e, 0x5f, 0xeb, 
-     0xa7, 0x0e, 0x7a, 0xae, 0x43, 0x28, 0x28, 0x9c },
-   32,
-
-   { 0xce, 0x20, 0x27, 0xb4, 0x7a, 0x84, 0x32, 0x52, 
-     0x01, 0x34, 0x65, 0x83, 0x4d, 0x75, 0xfd, 0x0f },
+   /* key */
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    16,
 
-   { 0 },
-   0,
+   /* PT */
+   { 0xa2, 0xaa, 0xb3, 0xad, 0x8b, 0x17, 0xac, 0xdd, 
+     0xa2, 0x88, 0x42, 0x6c, 0xd7, 0xc4, 0x29, 0xb7, 
+     0xca, 0x86, 0xb7, 0xac, 0xa0, 0x58, 0x09, 0xc7, 
+     0x0c, 0xe8, 0x2d, 0xb2, 0x57, 0x11, 0xcb, 0x53,
+     0x02, 0xeb, 0x27, 0x43, 0xb0, 0x36, 0xf3, 0xd7, 
+     0x50, 0xd6, 0xcf, 0x0d, 0xc0, 0xac, 0xb9, 0x29, 
+     0x50, 0xd5, 0x46, 0xdb, 0x30, 0x8f, 0x93, 0xb4, 
+     0xff, 0x24, 0x4a, 0xfa, 0x9d, 0xc7, 0x2b, 0xcd,
+     0x75, 0x8d, 0x2c },
+   67,
+
+   /* ADATA */
+   { 0x68, 0x8e, 0x1a, 0xa9, 0x84, 0xde, 0x92, 0x6d, 
+     0xc7, 0xb4, 0xc4, 0x7f, 0x44 },
+   13,   
 
-   { 0xcf, 0xc0, 0x6e, 0x72, 0x2b, 0xe9, 0x87, 0xb3, 
-     0x76, 0x7f, 0x70, 0xa7, 0xb8, 0x56, 0xb7, 0x74 },
+   /* IV */
+   { 0xb7, 0x21, 0x38, 0xb5, 0xa0, 0x5f, 0xf5, 0x07, 
+     0x0e, 0x8c, 0xd9, 0x41, 0x83, 0xf7, 0x61, 0xd8 },
    16,
 
-   { 0x03, 0x30, 0xea, 0x65, 0xb1, 0xf4, 0x8a, 0xd7, 
-     0x18, 0xc3, 0xf1, 0xf3, 0xdc, 0xef, 0xe4, 0x20 },
+   /* CT */
+   { 0xcb, 0xc8, 0xd2, 0xf1, 0x54, 0x81, 0xa4, 0xcc, 
+     0x7d, 0xd1, 0xe1, 0x9a, 0xaa, 0x83, 0xde, 0x56, 
+     0x78, 0x48, 0x3e, 0xc3, 0x59, 0xae, 0x7d, 0xec, 
+     0x2a, 0xb8, 0xd5, 0x34, 0xe0, 0x90, 0x6f, 0x4b,
+     0x46, 0x63, 0xfa, 0xff, 0x58, 0xa8, 0xb2, 0xd7, 
+     0x33, 0xb8, 0x45, 0xee, 0xf7, 0xc9, 0xb3, 0x31, 
+     0xe9, 0xe1, 0x0e, 0xb2, 0x61, 0x2c, 0x99, 0x5f, 
+     0xeb, 0x1a, 0xc1, 0x5a, 0x62, 0x86, 0xcc, 0xe8,
+     0xb2, 0x97, 0xa8 },
 
-   { 0xe9, 0xef, 0xa9, 0x97, 0xd0, 0xae, 0x82, 0x42, 
-     0x90, 0xbb, 0x5a, 0x66, 0x95, 0xff, 0x2c, 0x7a }
+   /* TAG */
+   { 0x8d, 0x2d, 0x2a, 0x93, 0x72, 0x62, 0x6f, 0x6b, 
+     0xee, 0x85, 0x80, 0x27, 0x6a, 0x63, 0x66, 0xbf }
 }
 
-#endif
-
-
 /* rest of test cases are the same except AES key size changes... ignored... */
 };
    int           idx, err;
    unsigned long x, y;
-   unsigned char out[2][64], T[2][16];
+   unsigned char out[2][128], T[2][16];
 
    /* find aes */
    idx = find_cipher("aes");

+ 2 - 2
src/headers/tomcrypt.h

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

+ 2 - 0
src/headers/tomcrypt_cfg.h

@@ -39,6 +39,8 @@ LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n);
 LTC_EXPORT int   LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n);
 LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n);
 
+LTC_EXPORT int   LTC_CALL XSTRCMP(const char *s1, const char *s2);
+
 #endif
 
 /* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */

+ 33 - 0
src/headers/tomcrypt_custom.h

@@ -3,27 +3,54 @@
 
 /* macros for various libc functions you can change for embedded targets */
 #ifndef XMALLOC
+   #ifdef malloc 
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XMALLOC  malloc
 #endif
 #ifndef XREALLOC
+   #ifdef realloc 
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XREALLOC realloc
 #endif
 #ifndef XCALLOC
+   #ifdef calloc 
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XCALLOC  calloc
 #endif
 #ifndef XFREE
+   #ifdef free
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XFREE    free
 #endif
 
 #ifndef XMEMSET
+   #ifdef memset
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XMEMSET  memset
 #endif
 #ifndef XMEMCPY
+   #ifdef memcpy
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XMEMCPY  memcpy
 #endif
 #ifndef XMEMCMP
+   #ifdef memcmp 
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XMEMCMP  memcmp
 #endif
+#ifndef XSTRCMP
+   #ifdef strcmp
+   #define LTC_NO_PROTOTYPES
+   #endif
+#define XSTRCMP strcmp
+#endif
 
 #ifndef XCLOCK
 #define XCLOCK   clock
@@ -33,6 +60,9 @@
 #endif
 
 #ifndef XQSORT
+   #ifdef qsort
+   #define LTC_NO_PROTOTYPES
+   #endif
 #define XQSORT qsort
 #endif
 
@@ -276,6 +306,9 @@
 /* ECC */
 #define MECC
 
+/* use Shamir's trick for point mul (speeds up signature verification) */
+#define LTC_ECC_SHAMIR
+
 #if defined(TFM_DESC) && defined(MECC)
    #define MECC_ACCEL
 #endif   

+ 16 - 16
src/headers/tomcrypt_macros.h

@@ -72,9 +72,9 @@
 #define STORE32H(x, y)           \
 asm __volatile__ (               \
    "bswapl %0     \n\t"          \
-   "movl   %0,(%2)\n\t"          \
+   "movl   %0,(%1)\n\t"          \
    "bswapl %0     \n\t"          \
-      :"=r"(x):"0"(x), "r"(y));
+      ::"r"(x), "r"(y));
 
 #define LOAD32H(x, y)          \
 asm __volatile__ (             \
@@ -103,9 +103,9 @@ asm __volatile__ (             \
 #define STORE64H(x, y)           \
 asm __volatile__ (               \
    "bswapq %0     \n\t"          \
-   "movq   %0,(%2)\n\t"          \
+   "movq   %0,(%1)\n\t"          \
    "bswapq %0     \n\t"          \
-      :"=r"(x):"0"(x), "r"(y):"0");
+      ::"r"(x), "r"(y));
 
 #define LOAD64H(x, y)          \
 asm __volatile__ (             \
@@ -132,10 +132,10 @@ asm __volatile__ (             \
 #ifdef ENDIAN_32BITWORD 
 
 #define STORE32L(x, y)        \
-     { ulong32  __t = (x); memcpy(y, &__t, 4); }
+     { ulong32  __t = (x); XMEMCPY(y, &__t, 4); }
 
 #define LOAD32L(x, y)         \
-     memcpy(&(x), y, 4);
+     XMEMCPY(&(x), y, 4);
 
 #define STORE64L(x, y)                                                                     \
      { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
@@ -152,16 +152,16 @@ asm __volatile__ (             \
 #else /* 64-bit words then  */
 
 #define STORE32L(x, y)        \
-     { ulong32 __t = (x); memcpy(y, &__t, 4); }
+     { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
 
 #define LOAD32L(x, y)         \
-     { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
+     { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
 
 #define STORE64L(x, y)        \
-     { ulong64 __t = (x); memcpy(y, &__t, 8); }
+     { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
 
 #define LOAD64L(x, y)         \
-    { memcpy(&(x), y, 8); }
+    { XMEMCPY(&(x), y, 8); }
 
 #endif /* ENDIAN_64BITWORD */
 
@@ -193,10 +193,10 @@ asm __volatile__ (             \
 #ifdef ENDIAN_32BITWORD 
 
 #define STORE32H(x, y)        \
-     { ulong32 __t = (x); memcpy(y, &__t, 4); }
+     { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
 
 #define LOAD32H(x, y)         \
-     memcpy(&(x), y, 4);
+     XMEMCPY(&(x), y, 4);
 
 #define STORE64H(x, y)                                                                     \
      { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \
@@ -213,16 +213,16 @@ asm __volatile__ (             \
 #else /* 64-bit words then  */
 
 #define STORE32H(x, y)        \
-     { ulong32 __t = (x); memcpy(y, &__t, 4); }
+     { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
 
 #define LOAD32H(x, y)         \
-     { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
+     { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
 
 #define STORE64H(x, y)        \
-     { ulong64 __t = (x); memcpy(y, &__t, 8); }
+     { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
 
 #define LOAD64H(x, y)         \
-    { memcpy(&(x), y, 8); }
+    { XMEMCPY(&(x), y, 8); }
 
 #endif /* ENDIAN_64BITWORD */
 #endif /* ENDIAN_BIG */

+ 14 - 0
src/headers/tomcrypt_math.h

@@ -372,6 +372,20 @@ typedef struct {
    */
    int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
 
+   /** Computes kA*A + kB*B = C using Shamir's Trick
+       @param A        First point to multiply
+       @param kA       What to multiple A by
+       @param B        Second point to multiply
+       @param kB       What to multiple B by
+       @param C        [out] Destination point (can overlap with A or B
+       @param modulus  Modulus for curve 
+       @return CRYPT_OK on success
+   */ 
+   int (*ecc_mul2add)(ecc_point *A, void *kA,
+                      ecc_point *B, void *kB,
+                      ecc_point *C,
+                           void *modulus);
+
 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
 
    /** RSA Key Generation 

+ 45 - 6
src/headers/tomcrypt_pk.h

@@ -160,19 +160,19 @@ typedef struct {
    /** name of curve */
    char *name; 
 
-   /** The prime that defines the field the curve is in (encoded in base-64) */
+   /** The prime that defines the field the curve is in (encoded in hex) */
    char *prime;
 
-   /** The fields B param (base64) */
+   /** The fields B param (hex) */
    char *B;
 
-   /** The order of the curve (base64) */
+   /** The order of the curve (hex) */
    char *order;
   
-   /** The x co-ordinate of the base point on the curve (base64) */
+   /** The x co-ordinate of the base point on the curve (hex) */
    char *Gx;
  
-   /** The y co-ordinate of the base point on the curve (base64) */
+   /** The y co-ordinate of the base point on the curve (hex) */
    char *Gy;
 } ltc_ecc_set_type;
 
@@ -193,9 +193,12 @@ typedef struct {
     /** Type of key, PK_PRIVATE or PK_PUBLIC */
     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; if -1, then this key is using user supplied curve in dp */
     int idx;
 
+	/** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */
+	const ltc_ecc_set_type *dp;
+
     /** The public key */
     ecc_point pubkey;
 
@@ -211,13 +214,16 @@ void ecc_sizes(int *low, int *high);
 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_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
 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_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp);
 
 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
+int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
 
 int  ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, 
                        unsigned char *out, unsigned long *outlen);
@@ -263,6 +269,22 @@ void ltc_ecc_fp_free(void);
 /* R = kG */
 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
 
+#ifdef LTC_ECC_SHAMIR
+/* kA*A + kB*B = C */
+int ltc_ecc_mul2add(ecc_point *A, void *kA,
+                    ecc_point *B, void *kB,
+                    ecc_point *C,
+                         void *modulus);
+
+#ifdef MECC_FP
+int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
+                       ecc_point *B, void *kB,
+                       ecc_point *C, void *modulus);
+#endif
+
+#endif
+
+
 /* map P to affine from projective */
 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
 
@@ -351,6 +373,7 @@ enum {
  LTC_ASN1_OBJECT_IDENTIFIER,
  LTC_ASN1_IA5_STRING,
  LTC_ASN1_PRINTABLE_STRING,
+ LTC_ASN1_UTF8_STRING,
  LTC_ASN1_UTCTIME,
  LTC_ASN1_CHOICE,
  LTC_ASN1_SEQUENCE,
@@ -472,6 +495,22 @@ int der_length_printable_string(const unsigned char *octets, unsigned long nocte
 int der_printable_char_encode(int c);
 int der_printable_value_decode(int v);
 
+/* UTF-8 */
+#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED)) && !defined(LTC_NO_WCHAR)
+#include <wchar.h>
+#else
+typedef ulong32 wchar_t;
+#endif
+
+int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
+                           unsigned char *out, unsigned long *outlen);
+
+int der_decode_utf8_string(const unsigned char *in,  unsigned long inlen,
+                                       wchar_t *out, unsigned long *outlen);
+unsigned long der_utf8_charsize(const wchar_t c);
+int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen);
+
+
 /* CHOICE */
 int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
                             ltc_asn1_list *list, unsigned long  outlen);

+ 1 - 1
src/mac/f9/f9_file.c

@@ -64,7 +64,7 @@ int f9_file(int cipher,
    } while (x == sizeof(buf));
    fclose(in);
 
-   if ((err = f9_done(&f9, 	out, outlen)) != CRYPT_OK) {
+   if ((err = f9_done(&f9,    out, outlen)) != CRYPT_OK) {
       return err;
    }
 

+ 1 - 1
src/mac/f9/f9_memory.c

@@ -12,7 +12,7 @@
 
 /**
   @file f9_process.c
-  f9 Support, terminate the state
+  f9 Support, Process a block through F9-MAC
 */
 
 #ifdef LTC_F9_MODE

+ 1 - 1
src/mac/f9/f9_process.c

@@ -18,7 +18,7 @@
 #ifdef LTC_F9_MODE
 
 /** Process data through f9-MAC
-  @param f9     The f9-MAC state
+  @param f9       The f9-MAC state
   @param in       Input data to process
   @param inlen    Length of input in octets
   Return CRYPT_OK on success

+ 1 - 1
src/mac/f9/f9_test.c

@@ -12,7 +12,7 @@
 
 /**
   @file f9_test.c
-  f9 Support, terminate the state
+  f9 Support, Test F9 mode 
 */
 
 #ifdef LTC_F9_MODE

+ 1 - 1
src/mac/pelican/pelican_test.c

@@ -24,7 +24,7 @@ int pelican_test(void)
 #else
    static const struct {
         unsigned char K[32], MSG[64], T[16];
-	int keylen, ptlen;
+   int keylen, ptlen;
    } tests[] = {
 /* K=16, M=0 */
 {

+ 1 - 1
src/mac/xcbc/xcbc_memory.c

@@ -12,7 +12,7 @@
 
 /**
   @file xcbc_process.c
-  XCBC Support, terminate the state
+  XCBC Support, XCBC-MAC a block of memory
 */
 
 #ifdef LTC_XCBC

+ 1 - 1
src/mac/xcbc/xcbc_test.c

@@ -12,7 +12,7 @@
 
 /**
   @file xcbc_test.c
-  XCBC Support, terminate the state
+  XCBC Support, Test XCBC-MAC mode
 */
 
 #ifdef LTC_XCBC

+ 314 - 0
src/math/fp/ltc_ecc_fp_mulmod.c

@@ -897,6 +897,320 @@ static int accel_fp_mul(int idx, void *k, ecc_point *R, void *modulus, void *mp,
    return err;
 }
 
+#ifdef LTC_ECC_SHAMIR
+/* perform a fixed point ECC mulmod */
+static int accel_fp_mul2add(int idx1, int idx2, 
+                            void *kA, void *kB,
+                            ecc_point *R, void *modulus, void *mp)
+{
+   unsigned char kb[2][128];
+   int      x;
+   unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB;
+   void     *tka, *tkb, *order;
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ltc_ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ltc_ecc_sets[x].size) break;
+      }
+   
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+      
+      if ((err = mp_init(&order)) != CRYPT_OK) {
+         return err;
+      }      
+      if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
+         mp_clear(&order);
+         return err;
+      }
+
+      /* kA must be less than modulus */
+      if (mp_cmp(kA, order) != LTC_MP_LT) {
+         if ((err = mp_init(&tka)) != CRYPT_OK) {
+            mp_clear(order);
+            return err;
+         }
+         if ((err = mp_mod(kA, order, tka)) != CRYPT_OK) {
+            mp_clear(tka);
+            mp_clear(order);
+            return err;
+         }
+      } else {
+         tka = kA;
+      }
+      mp_clear(order);
+   } else {
+      tka = kA;
+   }       
+
+   /* if it's smaller than modulus we fine */
+   if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) {
+      /* find order */
+      y = mp_unsigned_bin_size(modulus);
+      for (x = 0; ltc_ecc_sets[x].size; x++) {
+         if (y <= (unsigned)ltc_ecc_sets[x].size) break;
+      }
+   
+      /* back off if we are on the 521 bit curve */
+      if (y == 66) --x;
+      
+      if ((err = mp_init(&order)) != CRYPT_OK) {
+         return err;
+      }      
+      if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) {
+         mp_clear(&order);
+         return err;
+      }
+
+      /* kB must be less than modulus */
+      if (mp_cmp(kB, order) != LTC_MP_LT) {
+         if ((err = mp_init(&tkb)) != CRYPT_OK) {
+            mp_clear(order);
+            return err;
+         }
+         if ((err = mp_mod(kB, order, tkb)) != CRYPT_OK) {
+            mp_clear(tkb);
+            mp_clear(order);
+            return err;
+         }
+      } else {
+         tkb = kB;
+      }
+      mp_clear(order);
+   } else {
+      tkb = kB;
+   }     
+
+   /* get bitlen and round up to next multiple of FP_LUT */
+   bitlen  = mp_unsigned_bin_size(modulus) << 3;
+   x       = bitlen % FP_LUT;
+   if (x) {
+      bitlen += FP_LUT - x;
+   }  
+   lut_gap = bitlen / FP_LUT;
+        
+   /* get the k value */
+   if ((mp_unsigned_bin_size(tka) > (sizeof(kb[0]) - 2)) || (mp_unsigned_bin_size(tkb) > (sizeof(kb[0]) - 2))  ) {
+      if (tka != kA) {
+         mp_clear(tka);
+      }         
+      if (tkb != kB) {
+         mp_clear(tkb);
+      }         
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   
+   /* store k */
+   zeromem(kb, sizeof(kb));
+   if ((err = mp_to_unsigned_bin(tka, kb[0])) != CRYPT_OK) {
+      if (tka != kA) {
+         mp_clear(tka);
+      }         
+      if (tkb != kB) {
+         mp_clear(tkb);
+      }         
+      return err;
+   }
+   
+   /* let's reverse kb so it's little endian */
+   x = 0;
+   y = mp_unsigned_bin_size(tka) - 1;
+   if (tka != kA) {
+      mp_clear(tka);
+   }         
+   while ((unsigned)x < y) {
+      z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z;
+      ++x; --y;
+   }      
+   
+   /* store b */
+   if ((err = mp_to_unsigned_bin(tkb, kb[1])) != CRYPT_OK) {
+      if (tkb != kB) {
+         mp_clear(tkb);
+      }         
+      return err;
+   }
+
+   x = 0;
+   y = mp_unsigned_bin_size(tkb) - 1;
+   if (tkb != kB) {
+      mp_clear(tkb);
+   }         
+   while ((unsigned)x < y) {
+      z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z;
+      ++x; --y;
+   }      
+
+   /* at this point we can start, yipee */
+   first = 1;
+   for (x = lut_gap-1; x >= 0; x--) {
+       /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */
+       bitpos = x;
+       for (y = zA = zB = 0; y < FP_LUT; y++) {
+          zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y;
+          zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y;
+          bitpos += lut_gap;                               /* it's y*lut_gap + x, but here we can avoid the mult in each loop */
+       }
+              
+       /* double if not first */
+       if (!first) {
+          if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
+             return err;
+          }
+       }
+       
+       /* add if not first, otherwise copy */          
+       if (!first) {
+          if (zA) {
+             if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) {
+                return err;
+             }
+          }
+          if (zB) {
+             if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
+                return err;
+             }
+          }
+       } else {
+          if (zA) {
+              if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != CRYPT_OK) || 
+                 (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != CRYPT_OK) || 
+                 (mp_copy(fp_cache[idx1].mu,        R->z) != CRYPT_OK)) { return CRYPT_MEM; }
+                 first = 0;              
+          }
+          if (zB && first == 0) {
+             if (zB) {
+                if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
+                   return err;
+                }
+             }
+          } else if (zB && first == 1) {
+              if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != CRYPT_OK) || 
+                 (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != CRYPT_OK) || 
+                 (mp_copy(fp_cache[idx2].mu,        R->z) != CRYPT_OK)) { return CRYPT_MEM; }
+                 first = 0;              
+          }
+       }
+   }     
+   zeromem(kb, sizeof(kb));
+   return ltc_ecc_map(R, modulus, mp);
+}
+
+/** ECC Fixed Point mulmod global
+    @param k        The multiplicand
+    @param G        Base point to multiply
+    @param R        [out] Destination of product
+    @param modulus  The modulus for the curve
+    @param map      [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form
+    @return CRYPT_OK if successful
+*/   
+int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
+                       ecc_point *B, void *kB,
+                       ecc_point *C, void *modulus)
+{
+   int  idx1, idx2, err;
+   void *mp, *mu;
+   
+   mp = NULL;
+   mu = NULL;
+   LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
+      /* find point */
+      idx1 = find_base(A);
+
+      /* no entry? */
+      if (idx1 == -1) {
+         /* find hole and add it */
+         idx1 = find_hole();
+
+         if ((err = add_entry(idx1, A)) != CRYPT_OK) {
+            goto LBL_ERR;
+         }
+      }
+
+      /* increment LRU */
+      ++(fp_cache[idx1].lru_count);
+ 
+      /* find point */
+      idx2 = find_base(B);
+
+      /* no entry? */
+      if (idx2 == -1) {
+         /* find hole and add it */
+         idx2 = find_hole();
+
+         if ((err = add_entry(idx2, B)) != CRYPT_OK) {
+            goto LBL_ERR;
+         }
+      }
+
+      /* increment LRU */
+      ++(fp_cache[idx2].lru_count);
+
+      /* if it's 2 build the LUT, if it's higher just use the LUT */
+      if (fp_cache[idx1].lru_count == 2) {
+         /* compute mp */
+         if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
+
+         /* compute mu */
+         if ((err = mp_init(&mu)) != CRYPT_OK) {
+             goto LBL_ERR;
+         }
+         if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
+            goto LBL_ERR;
+         }            
+                 
+         /* build the LUT */
+         if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) {
+             goto LBL_ERR;;
+         }  
+      }
+
+      /* if it's 2 build the LUT, if it's higher just use the LUT */
+      if (fp_cache[idx2].lru_count == 2) {
+         if (mp == NULL) {
+            /* compute mp */
+            if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
+
+            /* compute mu */
+            if ((err = mp_init(&mu)) != CRYPT_OK) {
+                goto LBL_ERR;
+            }
+            if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
+               goto LBL_ERR;
+            }            
+         }
+                 
+         /* build the LUT */
+         if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) {
+             goto LBL_ERR;;
+         }  
+      }
+
+
+      if (fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) {
+         if (mp == NULL) {
+            /* compute mp */
+            if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
+         }
+         err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
+      } else {
+         err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus);
+      }
+LBL_ERR:
+    LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
+    if (mp != NULL) {
+       mp_montgomery_free(mp);
+    }       
+    if (mu != NULL) {
+       mp_clear(mu);
+    }       
+    return err;
+}
+#endif
+
 /** ECC Fixed Point mulmod global
     @param k        The multiplicand
     @param G        Base point to multiply

+ 11 - 2
src/math/gmp_desc.c

@@ -448,9 +448,18 @@ const ltc_math_descriptor gmp_desc = {
    &ltc_ecc_projective_add_point,
    &ltc_ecc_projective_dbl_point,
    &ltc_ecc_map,
+#ifdef LTC_ECC_SHAMIR
+#ifdef MECC_FP
+   &ltc_ecc_fp_mul2add,
 #else
-   NULL, NULL, NULL, NULL,
-#endif
+   &ltc_ecc_mul2add,
+#endif /* MECC_FP */
+#else
+   NULL,
+#endif /* LTC_ECC_SHAMIR */
+#else
+   NULL, NULL, NULL, NULL, NULL
+#endif /* MECC */
 
 #ifdef MRSA
    &rsa_make_key,

+ 11 - 2
src/math/ltm_desc.c

@@ -454,9 +454,18 @@ const ltc_math_descriptor ltm_desc = {
    &ltc_ecc_projective_add_point,
    &ltc_ecc_projective_dbl_point,
    &ltc_ecc_map,
+#ifdef LTC_ECC_SHAMIR
+#ifdef MECC_FP
+   &ltc_ecc_fp_mul2add,
 #else
-   NULL, NULL, NULL, NULL,
-#endif
+   &ltc_ecc_mul2add,
+#endif /* MECC_FP */
+#else
+   NULL,
+#endif /* LTC_ECC_SHAMIR */
+#else
+   NULL, NULL, NULL, NULL, NULL,
+#endif /* MECC */
 
 #ifdef MRSA
    &rsa_make_key,

+ 12 - 3
src/math/tfm_desc.c

@@ -745,11 +745,20 @@ const ltc_math_descriptor tfm_desc = {
 #else
    &ltc_ecc_projective_add_point,
    &ltc_ecc_projective_dbl_point,
-#endif
+#endif /* MECC_ACCEL */
    &ltc_ecc_map,
+#ifdef LTC_ECC_SHAMIR
+#ifdef MECC_FP
+   &ltc_ecc_fp_mul2add,
 #else
-   NULL, NULL, NULL, NULL,
-#endif
+   &ltc_ecc_mul2add,
+#endif /* MECC_FP */
+#else
+   NULL,
+#endif /* LTC_ECC_SHAMIR */
+#else
+   NULL, NULL, NULL, NULL, NULL,
+#endif /* MECC */
 
 #ifdef MRSA
    &rsa_make_key,

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

@@ -350,6 +350,9 @@ const char *crypt_build_settings =
 #endif    
 #if defined(MECC_FP)
    " MECC_FP "
+#endif
+#if defined(LTC_ECC_SHAMIR)
+   " LTC_ECC_SHAMIR "
 #endif
     "\n"
     "\n\n\n"

+ 1 - 1
src/misc/crypt/crypt_find_cipher.c

@@ -26,7 +26,7 @@ int find_cipher(const char *name)
    LTC_ARGCHK(name != NULL);
    LTC_MUTEX_LOCK(&ltc_cipher_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
-       if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) {
+       if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) {
           LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
           return x;
        }

+ 1 - 1
src/misc/crypt/crypt_find_hash.c

@@ -26,7 +26,7 @@ int find_hash(const char *name)
    LTC_ARGCHK(name != NULL);
    LTC_MUTEX_LOCK(&ltc_hash_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
-       if (hash_descriptor[x].name != NULL && strcmp(hash_descriptor[x].name, name) == 0) {
+       if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
           LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
           return x;
        }

+ 1 - 1
src/misc/crypt/crypt_find_prng.c

@@ -26,7 +26,7 @@ int find_prng(const char *name)
    LTC_ARGCHK(name != NULL);
    LTC_MUTEX_LOCK(&ltc_prng_mutex);
    for (x = 0; x < TAB_SIZE; x++) {
-       if ((prng_descriptor[x].name != NULL) && strcmp(prng_descriptor[x].name, name) == 0) {
+       if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) {
           LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
           return x;
        }

+ 7 - 7
src/modes/cbc/cbc_decrypt.c

@@ -69,18 +69,18 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
 
          /* xor IV against plaintext */
          #if defined(LTC_FAST)
-	     for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
-	         tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x));
-		 *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
-		 *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy;
-	     }
-	 #else 
+        for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
+            tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x));
+       *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
+       *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy;
+        }
+    #else 
             for (x = 0; x < cbc->blocklen; x++) {
                tmpy       = tmp[x] ^ cbc->IV[x];
                cbc->IV[x] = ct[x];
                pt[x]      = tmpy;
             }
-	 #endif
+    #endif
        
          ct  += cbc->blocklen;
          pt  += cbc->blocklen;

+ 10 - 10
src/modes/cbc/cbc_encrypt.c

@@ -58,14 +58,14 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
       while (len) {
          /* xor IV against plaintext */
          #if defined(LTC_FAST)
-	     for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
-	         *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x));
-	     }
-	 #else 
+        for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
+            *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x));
+        }
+    #else 
             for (x = 0; x < cbc->blocklen; x++) {
                cbc->IV[x] ^= pt[x];
             }
-	 #endif
+    #endif
 
          /* encrypt */
          if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
@@ -74,14 +74,14 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
 
         /* store IV [ciphertext] for a future block */
          #if defined(LTC_FAST)
-	     for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
-	         *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
-	     }
-	 #else 
+        for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
+            *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
+        }
+    #else 
              for (x = 0; x < cbc->blocklen; x++) {
                 cbc->IV[x] = ct[x];
              }
-	 #endif
+    #endif
         
         ct  += cbc->blocklen;
         pt  += cbc->blocklen;

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

@@ -54,7 +54,7 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
        *pt = *ct ^ cfb->IV[cfb->padlen];
        ++pt; 
        ++ct;
-       ++cfb->padlen;
+       ++(cfb->padlen);
    }
    return CRYPT_OK;
 }

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

@@ -53,7 +53,7 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
        cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
        ++pt; 
        ++ct;
-       ++cfb->padlen;
+       ++(cfb->padlen);
    }
    return CRYPT_OK;
 }

+ 7 - 7
src/modes/ctr/ctr_encrypt.c

@@ -92,13 +92,13 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
             *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^
                                                            *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x));
          }
-	    pt         += ctr->blocklen;
-	    ct         += ctr->blocklen;
-	    len        -= ctr->blocklen;
-	    ctr->padlen = ctr->blocklen;
-	    continue;
-	   }
-#endif	 
+       pt         += ctr->blocklen;
+       ct         += ctr->blocklen;
+       len        -= ctr->blocklen;
+       ctr->padlen = ctr->blocklen;
+       continue;
+      }
+#endif    
       *ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
       --len;
    }

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

@@ -48,7 +48,7 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
           }
           ofb->padlen = 0;
        }
-       *ct++ = *pt++ ^ ofb->IV[ofb->padlen++];
+       *ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++];
    }
    return CRYPT_OK;
 }

+ 7 - 6
src/pk/asn1/der/bit/der_encode_bit_string.c

@@ -29,7 +29,8 @@
 int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
                                 unsigned char *out, unsigned long *outlen)
 {
-   unsigned long len, x, y, buf;
+   unsigned long len, x, y;
+   unsigned char buf;
    int           err;
 
    LTC_ARGCHK(in     != NULL);
@@ -52,18 +53,18 @@ int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
 
    out[x++] = 0x03;
    if (y < 128) {
-      out[x++] = y;
+      out[x++] = (unsigned char)y;
    } else if (y < 256) {
       out[x++] = 0x81;
-      out[x++] = y;
+      out[x++] = (unsigned char)y;
    } else if (y < 65536) {
       out[x++] = 0x82;
-      out[x++] = (y>>8)&255;
-      out[x++] = y&255;
+      out[x++] = (unsigned char)((y>>8)&255);
+      out[x++] = (unsigned char)(y&255);
    }
 
    /* store number of zero padding bits */
-   out[x++] = (8 - inlen) & 7;
+   out[x++] = (unsigned char)((8 - inlen) & 7);
 
    /* store the bits in big endian format */
    for (y = buf = 0; y < inlen; y++) {

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

@@ -135,6 +135,17 @@ int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
                }
                break;
 
+           case LTC_ASN1_UTF8_STRING:
+               if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
+                  if (der_length_utf8_string(data, size, &z) == CRYPT_OK) {
+                     list[x].used = 1;
+                     list[x].size = size;
+                     *inlen       = z;
+                     return CRYPT_OK;
+                  }
+               }
+               break;
+
            case LTC_ASN1_UTCTIME:
                z = *inlen;
                if (der_decode_utctime(in, &z, data) == CRYPT_OK) {

+ 7 - 7
src/pk/asn1/der/ia5/der_encode_ia5_string.c

@@ -50,19 +50,19 @@ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
    x = 0;
    out[x++] = 0x16;
    if (inlen < 128) {
-      out[x++] = inlen;
+      out[x++] = (unsigned char)inlen;
    } else if (inlen < 256) {
       out[x++] = 0x81;
-      out[x++] = inlen;
+      out[x++] = (unsigned char)inlen;
    } else if (inlen < 65536UL) {
       out[x++] = 0x82;
-      out[x++] = (inlen>>8)&255;
-      out[x++] = inlen&255;
+      out[x++] = (unsigned char)((inlen>>8)&255);
+      out[x++] = (unsigned char)(inlen&255);
    } else if (inlen < 16777216UL) {
       out[x++] = 0x83;
-      out[x++] = (inlen>>16)&255;
-      out[x++] = (inlen>>8)&255;
-      out[x++] = inlen&255;
+      out[x++] = (unsigned char)((inlen>>16)&255);
+      out[x++] = (unsigned char)((inlen>>8)&255);
+      out[x++] = (unsigned char)(inlen&255);
    } else {
       return CRYPT_INVALID_ARG;
    }

+ 6 - 6
src/pk/asn1/der/integer/der_encode_integer.c

@@ -70,16 +70,16 @@ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
       *out++ = (unsigned char)y;
    } else if (y < 256) {
       *out++ = 0x81;
-      *out++ = y;
+      *out++ = (unsigned char)y;
    } else if (y < 65536UL) {
       *out++ = 0x82;
-      *out++ = (y>>8)&255;
-      *out++ = y;
+      *out++ = (unsigned char)((y>>8)&255);
+      *out++ = (unsigned char)y;
    } else if (y < 16777216UL) {
       *out++ = 0x83;
-      *out++ = (y>>16)&255;
-      *out++ = (y>>8)&255;
-      *out++ = y;
+      *out++ = (unsigned char)((y>>16)&255);
+      *out++ = (unsigned char)((y>>8)&255);
+      *out++ = (unsigned char)y;
    } else {
       return CRYPT_INVALID_ARG;
    }

+ 6 - 6
src/pk/asn1/der/object_identifier/der_decode_object_identifier.c

@@ -77,13 +77,13 @@ int der_decode_object_identifier(const unsigned char *in,    unsigned long  inle
            if (y >= *outlen) {
               return CRYPT_BUFFER_OVERFLOW;
            }
-	   if (y == 0) {
-	      words[0] = t / 40;
-	      words[1] = t % 40;
-	      y = 2;
-	   } else {
+      if (y == 0) {
+         words[0] = t / 40;
+         words[1] = t % 40;
+         y = 2;
+      } else {
               words[y++] = t;
-	   }
+      }
            t          = 0;
        }
    }

+ 6 - 6
src/pk/asn1/der/object_identifier/der_encode_object_identifier.c

@@ -58,14 +58,14 @@ int der_encode_object_identifier(unsigned long *words, unsigned long  nwords,
    x = 0; 
    out[x++] = 0x06;
    if (z < 128) {
-      out[x++] = z;
+      out[x++] = (unsigned char)z;
    } else if (z < 256) {
       out[x++] = 0x81;
-      out[x++] = z;
+      out[x++] = (unsigned char)z;
    } else if (z < 65536UL) {
       out[x++] = 0x82;
-      out[x++] = (z>>8)&255;
-      out[x++] = z&255;
+      out[x++] = (unsigned char)((z>>8)&255);
+      out[x++] = (unsigned char)(z&255);
    } else {
       return CRYPT_INVALID_ARG;
    }
@@ -79,14 +79,14 @@ int der_encode_object_identifier(unsigned long *words, unsigned long  nwords,
            y    = x;
            mask = 0;
            while (t) {
-               out[x++] = (t & 0x7F) | mask;
+               out[x++] = (unsigned char)((t & 0x7F) | mask);
                t    >>= 7;
                mask  |= 0x80;  /* upper bit is set on all but the last byte */
            }
            /* now swap bytes y...x-1 */
            z = x - 1;
            while (y < z) {
-               t = out[y]; out[y] = out[z]; out[z] = t;
+               t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t;
                ++y; 
                --z;
            }

+ 7 - 7
src/pk/asn1/der/octet/der_encode_octet_string.c

@@ -51,19 +51,19 @@ int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
    x = 0;
    out[x++] = 0x04;
    if (inlen < 128) {
-      out[x++] = inlen;
+      out[x++] = (unsigned char)inlen;
    } else if (inlen < 256) {
       out[x++] = 0x81;
-      out[x++] = inlen;
+      out[x++] = (unsigned char)inlen;
    } else if (inlen < 65536UL) {
       out[x++] = 0x82;
-      out[x++] = (inlen>>8)&255;
-      out[x++] = inlen&255;
+      out[x++] = (unsigned char)((inlen>>8)&255);
+      out[x++] = (unsigned char)(inlen&255);
    } else if (inlen < 16777216UL) {
       out[x++] = 0x83;
-      out[x++] = (inlen>>16)&255;
-      out[x++] = (inlen>>8)&255;
-      out[x++] = inlen&255;
+      out[x++] = (unsigned char)((inlen>>16)&255);
+      out[x++] = (unsigned char)((inlen>>8)&255);
+      out[x++] = (unsigned char)(inlen&255);
    } else {
       return CRYPT_INVALID_ARG;
    }

+ 7 - 7
src/pk/asn1/der/printable_string/der_encode_printable_string.c

@@ -50,19 +50,19 @@ int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
    x = 0;
    out[x++] = 0x13;
    if (inlen < 128) {
-      out[x++] = inlen;
+      out[x++] = (unsigned char)inlen;
    } else if (inlen < 256) {
       out[x++] = 0x81;
-      out[x++] = inlen;
+      out[x++] = (unsigned char)inlen;
    } else if (inlen < 65536UL) {
       out[x++] = 0x82;
-      out[x++] = (inlen>>8)&255;
-      out[x++] = inlen&255;
+      out[x++] = (unsigned char)((inlen>>8)&255);
+      out[x++] = (unsigned char)(inlen&255);
    } else if (inlen < 16777216UL) {
       out[x++] = 0x83;
-      out[x++] = (inlen>>16)&255;
-      out[x++] = (inlen>>8)&255;
-      out[x++] = inlen&255;
+      out[x++] = (unsigned char)((inlen>>16)&255);
+      out[x++] = (unsigned char)((inlen>>8)&255);
+      out[x++] = (unsigned char)(inlen&255);
    } else {
       return CRYPT_INVALID_ARG;
    }

+ 21 - 9
src/pk/asn1/der/sequence/der_decode_sequence_ex.c

@@ -95,15 +95,15 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long  inlen,
 
        switch (type) {
            case LTC_ASN1_BOOLEAN:
-	            z = inlen;
-	            if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
-	                goto LBL_ERR;
-	            }
-	            if ((err = der_length_boolean(&z)) != CRYPT_OK) {
-	                goto LBL_ERR;
-	             }
-	             break;
-	       
+               z = inlen;
+               if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
+                   goto LBL_ERR;
+               }
+               if ((err = der_length_boolean(&z)) != CRYPT_OK) {
+                   goto LBL_ERR;
+                }
+                break;
+          
            case LTC_ASN1_INTEGER:
                z = inlen;
                if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
@@ -197,6 +197,18 @@ int der_decode_sequence_ex(const unsigned char *in, unsigned long  inlen,
                }
                break;
 
+           case LTC_ASN1_UTF8_STRING:
+               z = inlen;
+               if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
+                  goto LBL_ERR;
+               }
+               list[i].size = size;
+               if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               break;
+
            case LTC_ASN1_UTCTIME:
                z = inlen;
                if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {

+ 29 - 10
src/pk/asn1/der/sequence/der_decode_sequence_flexi.c

@@ -105,18 +105,18 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
       /* now switch on type */
       switch (type) {
          case 0x01: /* BOOLEAN */
-	         l->type = LTC_ASN1_BOOLEAN;
-	         l->size = 1;
-	         l->data = XCALLOC(1, sizeof(int));
-	    
-	         if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
-	            goto error;
+            l->type = LTC_ASN1_BOOLEAN;
+            l->size = 1;
+            l->data = XCALLOC(1, sizeof(int));
+       
+            if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
+               goto error;
             }
-	     
-	         if ((err = der_length_boolean(&len)) != CRYPT_OK) {
-	            goto error;
+        
+            if ((err = der_length_boolean(&len)) != CRYPT_OK) {
+               goto error;
             }
-	         break;
+            break;
 
          case 0x02: /* INTEGER */
              /* init field */
@@ -218,7 +218,26 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
             }
             l->data = realloc_tmp;
             break;
+  
+         case 0x0C: /* UTF8 */
          
+            /* init field */
+            l->type = LTC_ASN1_UTF8_STRING;
+            l->size = len;
+
+            if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
+               err = CRYPT_MEM;
+               goto error;
+            }
+            
+            if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
+               goto error;
+            }
+            
+            if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
+               goto error;
+            }
+            break;
 
          case 0x13: /* PRINTABLE */
          

+ 2 - 0
src/pk/asn1/der/sequence/der_decode_sequence_multi.c

@@ -58,6 +58,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
            case LTC_ASN1_OBJECT_IDENTIFIER:
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTF8_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SET:
            case LTC_ASN1_SETOF:
@@ -105,6 +106,7 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
            case LTC_ASN1_OBJECT_IDENTIFIER:
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTF8_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SET:

+ 36 - 20
src/pk/asn1/der/sequence/der_encode_sequence_ex.c

@@ -52,11 +52,11 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
 
        switch (type) {
             case LTC_ASN1_BOOLEAN:
-	            if ((err = der_length_boolean(&x)) != CRYPT_OK) {
-	               goto LBL_ERR;
-	            }
-	            y += x;
-	            break;
+               if ((err = der_length_boolean(&x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
 
            case LTC_ASN1_INTEGER:
                if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
@@ -111,6 +111,13 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
                y += x;
                break;
 
+           case LTC_ASN1_UTF8_STRING:
+               if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
            case LTC_ASN1_UTCTIME:
                if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
                   goto LBL_ERR;
@@ -163,19 +170,19 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
    out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
       
    if (z < 128) {
-      out[x++] = z;
+      out[x++] = (unsigned char)z;
    } else if (z < 256) {
       out[x++] = 0x81;
-      out[x++] = z;
+      out[x++] = (unsigned char)z;
    } else if (z < 65536UL) {
       out[x++] = 0x82;
-      out[x++] = (z>>8UL)&255;
-      out[x++] = z&255;
+      out[x++] = (unsigned char)((z>>8UL)&255);
+      out[x++] = (unsigned char)(z&255);
    } else if (z < 16777216UL) {
       out[x++] = 0x83;
-      out[x++] = (z>>16UL)&255;
-      out[x++] = (z>>8UL)&255;
-      out[x++] = z&255;
+      out[x++] = (unsigned char)((z>>16UL)&255);
+      out[x++] = (unsigned char)((z>>8UL)&255);
+      out[x++] = (unsigned char)(z&255);
    }
 
    /* store data */
@@ -191,14 +198,14 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
 
        switch (type) {
             case LTC_ASN1_BOOLEAN:
-	            z = *outlen;
-	            if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
-	               goto LBL_ERR;
-	            }
-	            x       += z;
-	            *outlen -= z;
-	            break;
-	       
+               z = *outlen;
+               if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+          
            case LTC_ASN1_INTEGER:
                z = *outlen;
                if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
@@ -268,6 +275,15 @@ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
                *outlen -= z;
                break;
 
+           case LTC_ASN1_UTF8_STRING:
+               z = *outlen;
+               if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
            case LTC_ASN1_UTCTIME:
                z = *outlen;
                if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {

+ 2 - 0
src/pk/asn1/der/sequence/der_encode_sequence_multi.c

@@ -59,6 +59,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
            case LTC_ASN1_OBJECT_IDENTIFIER:
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTF8_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SET:
@@ -105,6 +106,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
            case LTC_ASN1_OBJECT_IDENTIFIER:
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
+           case LTC_ASN1_UTF8_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SET:

+ 13 - 6
src/pk/asn1/der/sequence/der_length_sequence.c

@@ -47,12 +47,12 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
 
        switch (type) {
            case LTC_ASN1_BOOLEAN:
-	           if ((err = der_length_boolean(&x)) != CRYPT_OK) {
-	              goto LBL_ERR;
-	           }
-	           y += x;
-	           break;
-	       
+              if ((err = der_length_boolean(&x)) != CRYPT_OK) {
+                 goto LBL_ERR;
+              }
+              y += x;
+              break;
+          
            case LTC_ASN1_INTEGER:
                if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
                   goto LBL_ERR;
@@ -113,6 +113,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
                y += x;
                break;
 
+           case LTC_ASN1_UTF8_STRING:
+               if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               y += x;
+               break;
+
            case LTC_ASN1_SET:
            case LTC_ASN1_SETOF:
            case LTC_ASN1_SEQUENCE:

+ 1 - 0
src/pk/asn1/der/set/der_encode_set.c

@@ -28,6 +28,7 @@ static int ltc_to_asn1(int v)
       case LTC_ASN1_OCTET_STRING:            return 0x04;
       case LTC_ASN1_NULL:                    return 0x05;
       case LTC_ASN1_OBJECT_IDENTIFIER:       return 0x06;
+      case LTC_ASN1_UTF8_STRING:             return 0x0C;
       case LTC_ASN1_PRINTABLE_STRING:        return 0x13;
       case LTC_ASN1_IA5_STRING:              return 0x16;
       case LTC_ASN1_UTCTIME:                 return 0x17;

+ 2 - 2
src/pk/asn1/der/short_integer/der_encode_short_integer.c

@@ -70,7 +70,7 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon
    /* store header */
    x = 0;
    out[x++] = 0x02;
-   out[x++] = z;
+   out[x++] = (unsigned char)z;
 
    /* if 31st bit is set output a leading zero and decrement count */
    if (z == 5) {
@@ -80,7 +80,7 @@ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned lon
 
    /* store values */
    for (y = 0; y < z; y++) {
-      out[x++] = (num >> 24) & 0xFF;
+      out[x++] = (unsigned char)((num >> 24) & 0xFF);
       num    <<= 8;
    }
 

+ 1 - 1
src/pk/asn1/der/utctime/der_encode_utctime.c

@@ -69,7 +69,7 @@ int der_encode_utctime(ltc_utctime *utctime,
     }
 
     /* store length */
-    out[1] = x - 2;
+    out[1] = (unsigned char)(x - 2);
    
     /* all good let's return */
     *outlen = x;

+ 111 - 0
src/pk/asn1/der/utf8/der_decode_utf8_string.c

@@ -0,0 +1,111 @@
+/* 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.com
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_decode_utf8_string.c
+  ASN.1 DER, encode a UTF8 STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store a UTF8 STRING
+  @param in      The DER encoded UTF8 STRING
+  @param inlen   The size of the DER UTF8 STRING
+  @param out     [out] The array of utf8s stored (one per char)
+  @param outlen  [in/out] The number of utf8s stored
+  @return CRYPT_OK if successful
+*/
+int der_decode_utf8_string(const unsigned char *in,  unsigned long inlen,
+                                       wchar_t *out, unsigned long *outlen)
+{
+   wchar_t       tmp;
+   unsigned long x, y, z, len;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* must have header at least */
+   if (inlen < 2) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* check for 0x0C */
+   if ((in[0] & 0x1F) != 0x0C) {
+      return CRYPT_INVALID_PACKET;
+   }
+   x = 1;
+
+   /* decode the length */
+   if (in[x] & 0x80) {
+      /* valid # of bytes in length are 1,2,3 */
+      y = in[x] & 0x7F;
+      if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* read the length in */
+      len = 0;
+      ++x;
+      while (y--) {
+         len = (len << 8) | in[x++];
+      }
+   } else {
+      len = in[x++] & 0x7F;
+   }
+
+   if (len + x > inlen) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* proceed to decode */
+   for (y = 0; x < inlen; ) {
+      /* get first byte */
+      tmp = in[x++];
+ 
+      /* count number of bytes */
+      for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF);
+      
+      if (z > 4 || (x + (z - 1) > inlen)) {
+         return CRYPT_INVALID_PACKET;
+      }
+
+      /* decode, grab upper bits */
+      tmp >>= z;
+
+      /* grab remaining bytes */
+      if (z > 1) { --z; }
+      while (z-- != 0) {
+         if ((in[x] & 0xC0) != 0x80) {
+            return CRYPT_INVALID_PACKET;
+         }
+         tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F);
+      }
+
+      if (y > *outlen) {
+         *outlen = y;
+         return CRYPT_BUFFER_OVERFLOW;
+      }
+      out[y++] = tmp;
+   }
+   *outlen = y;
+
+   return CRYPT_OK;
+}
+ 
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 105 - 0
src/pk/asn1/der/utf8/der_encode_utf8_string.c

@@ -0,0 +1,105 @@
+/* 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.com
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_utf8_string.c
+  ASN.1 DER, encode a UTF8 STRING, Tom St Denis
+*/
+
+
+#ifdef LTC_DER
+
+/**
+  Store an UTF8 STRING
+  @param in       The array of UTF8 to store (one per wchar_t)
+  @param inlen    The number of UTF8 to store
+  @param out      [out] The destination for the DER encoded UTF8 STRING
+  @param outlen   [in/out] The max size and resulting size of the DER UTF8 STRING
+  @return CRYPT_OK if successful
+*/
+int der_encode_utf8_string(const wchar_t *in,  unsigned long inlen,
+                           unsigned char *out, unsigned long *outlen)
+{
+   unsigned long x, y, len;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(out    != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   /* get the size */
+   for (x = len = 0; x < inlen; x++) {
+       if (in[x] < 0 || in[x] > 0x1FFFF) { 
+          return CRYPT_INVALID_ARG;
+       }
+       len += der_utf8_charsize(in[x]);
+   }
+
+   if (len < 128) {
+      y = 2 + len;
+   } else if (len < 256) {
+      y = 3 + len;
+   } else if (len < 65536UL) {
+      y = 4 + len;
+   } else if (len < 16777216UL) {
+      y = 5 + len;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* too big? */
+   if (y > *outlen) {
+      *outlen = len;
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   /* encode the header+len */
+   x = 0;
+   out[x++] = 0x0C;
+   if (len < 128) {
+      out[x++] = len;
+   } else if (len < 256) {
+      out[x++] = 0x81;
+      out[x++] = len;
+   } else if (len < 65536UL) {
+      out[x++] = 0x82;
+      out[x++] = (len>>8)&255;
+      out[x++] = len&255;
+   } else if (len < 16777216UL) {
+      out[x++] = 0x83;
+      out[x++] = (len>>16)&255;
+      out[x++] = (len>>8)&255;
+      out[x++] = len&255;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* store UTF8 */
+   for (y = 0; y < inlen; y++) {
+       switch (der_utf8_charsize(in[y])) {
+          case 1: out[x++] = in[y]; break;
+          case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F);  out[x++] = 0x80 | (in[y] & 0x3F); break;
+          case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
+          case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
+       }
+   }
+
+   /* retun length */
+   *outlen = x;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 83 - 0
src/pk/asn1/der/utf8/der_length_utf8_string.c

@@ -0,0 +1,83 @@
+/* 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.com
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_length_utf8_string.c
+  ASN.1 DER, get length of UTF8 STRING, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/** Return the size in bytes of a UTF-8 character
+  @param c   The UTF-8 character to measure
+  @return    The size in bytes
+*/
+unsigned long der_utf8_charsize(const wchar_t c)
+{
+   if (c <= 0x7F) {
+      return 1;
+   } else if (c <= 0x7FF) {
+      return 2;
+   } else if (c <= 0xFFFF) {
+      return 3;
+   } else {
+      return 4;
+   }
+}
+
+/**
+  Gets length of DER encoding of UTF8 STRING 
+  @param in       The characters to measure the length of
+  @param noctets  The number of octets in the string to encode
+  @param outlen   [out] The length of the DER encoding for the given string
+  @return CRYPT_OK if successful
+*/
+int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
+{
+   unsigned long x, len;
+
+   LTC_ARGCHK(in     != NULL);
+   LTC_ARGCHK(outlen != NULL);
+
+   len = 0;
+   for (x = 0; x < noctets; x++) {
+      if (in[x] < 0 || in[x] > 0x10FFFF) {
+         return CRYPT_INVALID_ARG;
+      }
+      len += der_utf8_charsize(in[x]);
+   }
+
+   if (len < 128) {
+      /* 0C LL DD DD DD ... */
+      *outlen = 2 + len;
+   } else if (len < 256) {
+      /* 0C 81 LL DD DD DD ... */
+      *outlen = 3 + len;
+   } else if (len < 65536UL) {
+      /* 0C 82 LL LL DD DD DD ... */
+      *outlen = 4 + len;
+   } else if (len < 16777216UL) {
+      /* 0C 83 LL LL LL DD DD DD ... */
+      *outlen = 5 + len;
+   } else {
+      return CRYPT_INVALID_ARG;
+   }
+
+   return CRYPT_OK;
+}
+
+#endif
+
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 1 - 1
src/pk/dsa/dsa_decrypt_key.c

@@ -125,7 +125,7 @@ LBL_ERR:
 
    XFREE(expt);
    XFREE(skey);
-   
+  
    mp_clear(g_pub);
 
    return err;

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

@@ -125,7 +125,6 @@ LBL_ERR:
     XFREE(expt);
     
     mp_clear_multi(g_pub, g_priv, NULL);
-
     return err;
 }
 

+ 6 - 7
src/pk/dsa/dsa_make_key.c

@@ -54,11 +54,12 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
 
    /* init mp_ints  */
    if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
-      goto LBL_ERR;
+      XFREE(buf);
+      return err;
    }
 
    /* make our prime q */
-   if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK)             { goto LBL_ERR; }
+   if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK)                { goto error; }
 
    /* double q  */
    if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK)                                { goto error; }
@@ -66,7 +67,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
    /* now make a random string and multply it against q */
    if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
       err = CRYPT_ERROR_READPRNG;
-      goto LBL_ERR;
+      goto error;
    }
 
    /* force magnitude */
@@ -81,7 +82,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
 
    /* now loop until p is prime */
    for (;;) {
-       if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK)                     { goto LBL_ERR; }
+       if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK)                     { goto error; }
        if (res == LTC_MP_YES) break;
 
        /* add 2q to p and 2 to tmp2 */
@@ -106,7 +107,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
    do {
       if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) {
          err = CRYPT_ERROR_READPRNG;
-         goto LBL_ERR;
+         goto error;
       }
       if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK)           { goto error; }
    } while (mp_cmp_d(key->x, 1) != LTC_MP_GT);
@@ -122,11 +123,9 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
    err = CRYPT_OK;
    goto done;
 error: 
-LBL_ERR: 
     mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
 done: 
     mp_clear_multi(tmp, tmp2, NULL);
-
     XFREE(buf);
     return err;
 }

+ 3 - 3
src/pk/dsa/dsa_shared_secret.c

@@ -30,9 +30,9 @@ 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;
+   unsigned long  x;
+   void          *res;
+   int            err;
 
    LTC_ARGCHK(private_key != NULL);
    LTC_ARGCHK(public_key  != NULL);

+ 5 - 7
src/pk/dsa/dsa_sign_hash.c

@@ -59,7 +59,7 @@ int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen,
    }
 
    /* Init our temps */
-   if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK)                       { goto error; }
+   if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK)                       { goto ERRBUF; }
 
 retry:
 
@@ -67,7 +67,7 @@ retry:
       /* gen random k */
       if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
          err = CRYPT_ERROR_READPRNG;
-         goto LBL_ERR;
+         goto error;
       }
 
       /* read k */
@@ -98,11 +98,9 @@ retry:
    if (mp_iszero(s) == LTC_MP_YES)                                                     { goto retry; }
 
    err = CRYPT_OK;
-   goto LBL_ERR;
-
 error: 
-LBL_ERR: 
    mp_clear_multi(k, kinv, tmp, NULL);
+ERRBUF:
 #ifdef LTC_CLEAN_STACK
    zeromem(buf, MDSA_MAX_GROUP);
 #endif
@@ -138,7 +136,7 @@ int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
    }
 
    if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) {
-      goto LBL_ERR;
+      goto error;
    }
 
    err = der_encode_sequence_multi(out, outlen, 
@@ -146,7 +144,7 @@ int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
                              LTC_ASN1_INTEGER, 1UL, s, 
                              LTC_ASN1_EOL,     0UL, NULL);
 
-LBL_ERR:
+error:
    mp_clear_multi(r, s, NULL);
    return err;
 }

+ 3 - 5
src/pk/dsa/dsa_verify_hash.c

@@ -51,7 +51,7 @@ int dsa_verify_hash_raw(         void   *r,          void   *s,
    /* neither r or s can be null or >q*/
    if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, key->q) != LTC_MP_LT || mp_cmp(s, key->q) != LTC_MP_LT) {
       err = CRYPT_INVALID_PACKET;
-      goto done;
+      goto error;
    }
    
    /* w = 1/s mod q */
@@ -76,10 +76,8 @@ int dsa_verify_hash_raw(         void   *r,          void   *s,
    }
 
    err = CRYPT_OK;
-   goto done;
-
-error :
-done  : mp_clear_multi(w, v, u1, u2, NULL);
+error:
+   mp_clear_multi(w, v, u1, u2, NULL);
    return err;
 }
 

+ 8 - 9
src/pk/dsa/dsa_verify_key.c

@@ -53,45 +53,44 @@ int dsa_verify_key(dsa_key *key, int *stat)
    if (mp_cmp_d(key->g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) {
       return CRYPT_OK;
    }
-   if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK)               { goto error; }
-   if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK)                     { goto error; }
+   if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK)               { return err; }
+   if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK)                       { goto error; }
    if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) {
       err = CRYPT_OK;
-      goto done;
+      goto error;
    }
 
    /* 1 < y < p-1 */
    if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) {
       err = CRYPT_OK;
-      goto done;
+      goto error;
    }
 
    /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
    if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK)             { goto error; }
    if (mp_iszero(tmp2) != LTC_MP_YES) {
       err = CRYPT_OK;
-      goto done;
+      goto error;
    }
 
    if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK)    { goto error; }
    if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
       err = CRYPT_OK;
-      goto done;
+      goto error;
    }
 
    /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
    if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK)       { goto error; }
    if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
       err = CRYPT_OK;
-      goto done;
+      goto error;
    }
 
    /* at this point we are out of tests ;-( */
    err   = CRYPT_OK;
    *stat = 1;
-   goto done;
 error: 
-done : mp_clear_multi(tmp, tmp2, NULL);
+   mp_clear_multi(tmp, tmp2, NULL);
    return err;
 }
 #endif

+ 2 - 2
src/pk/ecc/ecc_ansi_x963_export.c

@@ -31,7 +31,7 @@
 */
 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen)
 {
-   unsigned char buf[128];
+   unsigned char buf[ECC_BUF_SIZE];
    unsigned long numlen;
 
    LTC_ARGCHK(key    != NULL);
@@ -41,7 +41,7 @@ int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen
    if (ltc_ecc_is_valid_idx(key->idx) == 0) {
       return CRYPT_INVALID_ARG;
    }
-   numlen = ltc_ecc_sets[key->idx].size;
+   numlen = key->dp->size;
 
    if (*outlen < (1 + 2*numlen)) {
       *outlen = 1 + 2*numlen;

+ 27 - 13
src/pk/ecc/ecc_ansi_x963_import.c

@@ -29,10 +29,15 @@
   @param key     [out] destination to store imported key \
 */
 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
+{
+   return ecc_ansi_x963_import_ex(in, inlen, key, NULL);
+}
+
+int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
 {
    int x, err;
  
-   LTC_ARGCHK(in != NULL);
+   LTC_ARGCHK(in  != NULL);
    LTC_ARGCHK(key != NULL);
    
    /* must be odd */
@@ -59,21 +64,30 @@ int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *
    if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) {
       goto error;
    }
-   mp_set(key->pubkey.z, 1);
+   if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; }
 
-   /* determine the idx */
-   for (x = 0; ltc_ecc_sets[x].size != 0; x++) {
-      if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) {
-         break;
+   if (dp == NULL) {
+     /* determine the idx */
+      for (x = 0; ltc_ecc_sets[x].size != 0; x++) {
+         if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) {
+            break;
+         }
       }
+      if (ltc_ecc_sets[x].size == 0) {
+         err = CRYPT_INVALID_PACKET;
+         goto error;
+      }
+      /* set the idx */
+      key->idx  = x;
+      key->dp = &ltc_ecc_sets[x];
+   } else {
+      if (((inlen-1)>>1) != (unsigned long) dp->size) {
+         err = CRYPT_INVALID_PACKET;
+         goto error;
+      }
+      key->idx = -1;
+      key->dp  = dp;
    }
-   if (ltc_ecc_sets[x].size == 0) {
-      err = CRYPT_INVALID_PACKET;
-      goto error;
-   }
-
-   /* set the idx */
-   key->idx  = x;
    key->type = PK_PUBLIC;
 
    /* we're done */

+ 1 - 1
src/pk/ecc/ecc_encrypt_key.c

@@ -64,7 +64,7 @@ int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen,
     }
 
     /* make a random key and export the public copy */
-    if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
+    if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) {
        return err;
     }
 

+ 1 - 1
src/pk/ecc/ecc_export.c

@@ -51,7 +51,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
    }
 
    /* we store the NIST byte size */
-   key_size = ltc_ecc_sets[key->idx].size;
+   key_size = key->dp->size;
 
    if (type == PK_PRIVATE) {
        flags[0] = 1;

+ 1 - 1
src/pk/ecc/ecc_get_size.c

@@ -32,7 +32,7 @@ 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;
+      return key->dp->size;
    else
       return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
 }

+ 27 - 10
src/pk/ecc/ecc_import.c

@@ -33,8 +33,8 @@ static int is_point(ecc_key *key)
    }
    
    /* load prime and b */
-   if ((err = mp_read_radix(prime, ltc_ecc_sets[key->idx].prime, 16)) != CRYPT_OK)            { goto error; }
-   if ((err = mp_read_radix(b, ltc_ecc_sets[key->idx].B, 16)) != CRYPT_OK)                    { goto error; }
+   if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK)                          { goto error; }
+   if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK)                                  { goto error; }
    
    /* compute y^2 */
    if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK)                                         { goto error; }
@@ -79,6 +79,19 @@ error:
   @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)
+{
+   return ecc_import_ex(in, inlen, key, NULL);
+}
+
+/**
+  Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones
+  @param in      The packet to import
+  @param inlen   The length of the packet
+  @param key     [out] The destination of the import
+  @param dp      pointer to user supplied params; must be the same as the params used when exporting
+  @return CRYPT_OK if successful, upon error all allocated memory will be freed
+*/
+int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp)
 {
    unsigned long key_size;
    unsigned char flags[1];
@@ -126,15 +139,20 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
       }
    }
 
-   /* 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;
+   if (dp == NULL) {
+     /* 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;
+     }
+     key->dp = &ltc_ecc_sets[key->idx];
+   } else {
+     key->idx = -1;
+     key->dp = dp;
    }
-
    /* set z */
-   mp_set(key->pubkey.z, 1);
+   if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; }
    
    /* is it a point on the curve?  */
    if ((err = is_point(key)) != CRYPT_OK) {
@@ -147,7 +165,6 @@ done:
    mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
    return err;
 }
-
 #endif
 /* $Source$ */
 /* $Revision$ */

+ 37 - 24
src/pk/ecc/ecc_make_key.c

@@ -33,27 +33,40 @@
 */
 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
 {
-   int            x, err;
+   int x, 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;
+   }
+   err = ecc_make_key_ex(prng, wprng, key, &ltc_ecc_sets[x]);
+   key->idx = x;
+   return err;
+}
+
+int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp)
+{
+   int            err;
    ecc_point     *base;
    void          *prime;
    unsigned char *buf;
+   int            keysize;
 
-   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(key         != NULL);
    LTC_ARGCHK(ltc_mp.name != NULL);
+   LTC_ARGCHK(dp          != 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;
+   key->idx = -1;
+   key->dp  = dp;
+   keysize  = dp->size;
 
    /* allocate ram */
    base = NULL;
@@ -65,43 +78,43 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
    /* make up random string */
    if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
       err = CRYPT_ERROR_READPRNG;
-      goto LBL_ERR2;
+      goto ERR_BUF;
    }
 
    /* 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;
+      goto ERR_BUF;
    }
    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;
+      goto errkey;
    }
 
    /* read in the specs for this key */
-   if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[key->idx].prime, 16)) != CRYPT_OK)      { goto done; }
-   if ((err = mp_read_radix(base->x, (char *)ltc_ecc_sets[key->idx].Gx, 16)) != CRYPT_OK)       { goto done; }
-   if ((err = mp_read_radix(base->y, (char *)ltc_ecc_sets[key->idx].Gy, 16)) != 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; }
+   if ((err = mp_read_radix(prime,   (char *)key->dp->prime, 16)) != CRYPT_OK)                  { goto errkey; }
+   if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK)                     { goto errkey; }
+   if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK)                     { goto errkey; }
+   if ((err = mp_set(base->z, 1)) != CRYPT_OK)                                                  { goto errkey; }
+   if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK)         { goto errkey; }
 
    /* make the public key */
-   if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK)              { goto done; }
+   if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK)              { goto errkey; }
    key->type = PK_PRIVATE;
 
    /* free up ram */
    err = CRYPT_OK;
-done:
+   goto cleanup;
+errkey:
+   mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
+cleanup:
    ltc_ecc_del_point(base);
    mp_clear(prime);
-LBL_ERR2:
+ERR_BUF:
 #ifdef LTC_CLEAN_STACK
    zeromem(buf, ECC_MAXSIZE);
 #endif
-
    XFREE(buf);
-
    return err;
 }
 

+ 7 - 7
src/pk/ecc/ecc_shared_secret.c

@@ -34,10 +34,10 @@
 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;
+   unsigned long  x;
+   ecc_point     *result;
+   void          *prime;
+   int            err;
 
    LTC_ARGCHK(private_key != NULL);
    LTC_ARGCHK(public_key  != NULL);
@@ -49,11 +49,11 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
       return CRYPT_PK_NOT_PRIVATE;
    }
 
-   if (ltc_ecc_is_valid_idx(private_key->idx) == 0) {
+   if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) {
       return CRYPT_INVALID_ARG;
    }
 
-   if (private_key->idx != public_key->idx) {
+   if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) {
       return CRYPT_PK_TYPE_MISMATCH;
    }
 
@@ -68,7 +68,7 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
       return err;
    }
 
-   if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[private_key->idx].prime, 16)) != CRYPT_OK)                 { goto done; }
+   if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != 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);

+ 11 - 15
src/pk/ecc/ecc_sign_hash.c

@@ -64,22 +64,21 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
    /* 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;
+      return err;
    }
-   if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 16)) != CRYPT_OK)        { goto error; }
-   if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)          { goto error; }
+   if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                      { goto errnokey; }
+   if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)          { goto errnokey; }
 
    /* 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;
+      if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) {
+         goto errnokey;
       }
 
       /* find r = x1 mod n */
       if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK)                 { goto error; }
 
-      if (mp_iszero(r)) {
+      if (mp_iszero(r) == LTC_MP_YES) {
          ecc_free(&pubkey);
       } else { 
         /* find s = (e + xr)/k */
@@ -88,10 +87,8 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
         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 {
+        ecc_free(&pubkey);
+        if (mp_iszero(s) == LTC_MP_NO) {
            break;
         }
       }
@@ -102,12 +99,11 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
                              LTC_ASN1_INTEGER, 1UL, r,
                              LTC_ASN1_INTEGER, 1UL, s,
                              LTC_ASN1_EOL, 0UL, NULL);
-   goto LBL_ERR;
+   goto errnokey;
 error:
-LBL_ERR:
-   mp_clear_multi(r, s, p, e, NULL);
    ecc_free(&pubkey);
-
+errnokey:
+   mp_clear_multi(r, s, p, e, NULL);
    return err;   
 }
 

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

@@ -80,7 +80,6 @@ int ecc_test(void)
        }
    }
    err = CRYPT_OK;
-   goto done;
 done:
    ltc_ecc_del_point(GG);
    ltc_ecc_del_point(G);

+ 26 - 21
src/pk/ecc/ecc_verify_hash.c

@@ -76,7 +76,7 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
    mQ = ltc_ecc_new_point();
    if (mQ  == NULL || mG == NULL) {
       err = CRYPT_MEM;
-      goto done;
+      goto error;
    }
 
    /* parse header */
@@ -84,19 +84,19 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
                                   LTC_ASN1_INTEGER, 1UL, r,
                                   LTC_ASN1_INTEGER, 1UL, s,
                                   LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
-      goto done;
+      goto error;
    }
 
    /* get the order */
-   if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 16)) != CRYPT_OK)                  { goto error; }
+   if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK)                                { goto error; }
 
    /* get the modulus */
-   if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 16)) != CRYPT_OK)                  { goto error; }
+   if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != 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;
+      goto error;
    }
 
    /* read hash */
@@ -111,28 +111,35 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
    /* 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, 16)) != CRYPT_OK)                 { goto error; }
-   if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 16)) != 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 mG and mQ */
+   if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK)                               { goto error; }
+   if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK)                               { goto error; }
+   if ((err = mp_set(mG->z, 1)) != CRYPT_OK)                                                            { goto error; }
 
-   /* 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; }
+
+   /* compute u1*mG + u2*mQ = mG */
+   if (ltc_mp.ecc_mul2add == NULL) {
+      if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK)                                       { goto error; }
+      if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK)                                       { goto error; }
   
-   /* 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; }
+      /* 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 error; }
    
-   /* reduce */
-   if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK)                                                   { goto done; }
+      /* reduce */
+      if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK)                                                { goto error; }
+   } else {
+      /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
+      if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK)                                { goto error; }
+   }
 
    /* v = X_x1 mod n */
-   if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK)                                                         { goto done; }
+   if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK)                                                         { goto error; }
 
    /* does v == r */
    if (mp_cmp(v, r) == LTC_MP_EQ) {
@@ -141,9 +148,7 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen,
 
    /* 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);

+ 4 - 3
src/pk/ecc/ltc_ecc_is_valid_idx.c

@@ -32,10 +32,11 @@ 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;
+   /* -1 is a valid index --- indicating that the domain params were supplied by the user */
+   if ((n >= -1) || (n < x)) {
+      return 1;
    }
-   return 1;
+   return 0;
 }
 
 #endif

+ 2 - 3
src/pk/ecc/ltc_ecc_map.c

@@ -33,7 +33,7 @@
 int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
 {
    void *t1, *t2;
-   int err;
+   int   err;
 
    LTC_ARGCHK(P       != NULL);
    LTC_ARGCHK(modulus != NULL);
@@ -60,10 +60,9 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
    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);
+   if ((err = mp_set(P->z, 1)) != CRYPT_OK)                                   { goto done; }
 
    err = CRYPT_OK;
-   goto done;
 done:
    mp_clear_multi(t1, t2, NULL);
    return err;

+ 207 - 0
src/pk/ecc/ltc_ecc_mul2add.c

@@ -0,0 +1,207 @@
+/* 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.com
+ */
+
+/* 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_mul2add.c
+  ECC Crypto, Shamir's Trick, Tom St Denis
+*/  
+
+#ifdef MECC
+
+#ifdef LTC_ECC_SHAMIR
+
+/** Computes kA*A + kB*B = C using Shamir's Trick
+  @param A        First point to multiply
+  @param kA       What to multiple A by
+  @param B        Second point to multiply
+  @param kB       What to multiple B by
+  @param C        [out] Destination point (can overlap with A or B
+  @param modulus  Modulus for curve 
+  @return CRYPT_OK on success
+*/ 
+int ltc_ecc_mul2add(ecc_point *A, void *kA,
+                    ecc_point *B, void *kB,
+                    ecc_point *C,
+                         void *modulus)
+{
+  ecc_point     *precomp[16];
+  unsigned       bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble;
+  unsigned char *tA, *tB;
+  int            err, first;
+  void          *mp, *mu;
+ 
+  /* argchks */
+  LTC_ARGCHK(A       != NULL);
+  LTC_ARGCHK(B       != NULL);
+  LTC_ARGCHK(C       != NULL);
+  LTC_ARGCHK(kA      != NULL);
+  LTC_ARGCHK(kB      != NULL);
+  LTC_ARGCHK(modulus != NULL);
+
+  /* allocate memory */
+  tA = XCALLOC(1, ECC_BUF_SIZE);
+  if (tA == NULL) {
+     return CRYPT_MEM;
+  }
+  tB = XCALLOC(1, ECC_BUF_SIZE);
+  if (tB == NULL) {
+     XFREE(tA);
+     return CRYPT_MEM;
+  }
+
+  /* get sizes */
+  lenA = mp_unsigned_bin_size(kA);
+  lenB = mp_unsigned_bin_size(kB);
+  len  = MAX(lenA, lenB);
+
+  /* sanity check */
+  if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) {
+     err = CRYPT_INVALID_ARG;
+     goto ERR_T;
+  }
+
+  /* extract and justify kA */
+  mp_to_unsigned_bin(kA, (len - lenA) + tA);
+
+  /* extract and justify kB */
+  mp_to_unsigned_bin(kB, (len - lenB) + tB);
+
+  /* allocate the table */
+  for (x = 0; x < 16; x++) {
+     precomp[x] = ltc_ecc_new_point();
+     if (precomp[x] == NULL) {
+         for (y = 0; y < x; ++y) {
+            ltc_ecc_del_point(precomp[y]);
+         }
+         err = CRYPT_MEM;
+         goto ERR_T;
+     }
+  }
+
+   /* init montgomery reduction */
+   if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
+      goto ERR_P;
+   }
+   if ((err = mp_init(&mu)) != CRYPT_OK) {
+      goto ERR_MP;
+   }
+   if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
+      goto ERR_MU;
+   }
+
+  /* copy ones ... */
+  if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK)                                         { goto ERR_MU; }
+  if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK)                                         { goto ERR_MU; }
+  if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK)                                         { goto ERR_MU; }
+
+  if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK)                                      { goto ERR_MU; }
+  if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK)                                      { goto ERR_MU; }
+  if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK)                                      { goto ERR_MU; }
+
+  /* precomp [i,0](A + B) table */
+  if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK)                               { goto ERR_MU; }
+  if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK)                   { goto ERR_MU; }
+
+  /* precomp [0,i](A + B) table */
+  if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK)                         { goto ERR_MU; }
+  if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK)          { goto ERR_MU; }
+
+  /* precomp [i,j](A + B) table (i != 0, j != 0) */
+  for (x = 1; x < 4; x++) {
+     for (y = 1; y < 4; y++) {
+        if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
+     }
+  }   
+
+  nibble  = 3;
+  first   = 1;
+  bitbufA = tA[0];
+  bitbufB = tB[0];
+
+  /* for every byte of the multiplicands */
+  for (x = -1;; ) {
+     /* grab a nibble */
+     if (++nibble == 4) {
+        ++x; if (x == len) break;
+        bitbufA = tA[x];
+        bitbufB = tB[x];
+        nibble  = 0;
+     }
+
+     /* extract two bits from both, shift/update */
+     nA = (bitbufA >> 6) & 0x03;
+     nB = (bitbufB >> 6) & 0x03;
+     bitbufA = (bitbufA << 2) & 0xFF;   
+     bitbufB = (bitbufB << 2) & 0xFF;   
+
+     /* if both zero, if first, continue */
+     if ((nA == 0) && (nB == 0) && (first == 1)) {
+        continue;
+     }
+
+     /* double twice, only if this isn't the first */
+     if (first == 0) {
+        /* double twice */
+        if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK)                  { goto ERR_MU; }
+        if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK)                  { goto ERR_MU; }
+     }
+
+     /* if not both zero */
+     if ((nA != 0) || (nB != 0)) {
+        if (first == 1) {
+           /* if first, copy from table */
+           first = 0;
+           if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK)           { goto ERR_MU; }
+           if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK)           { goto ERR_MU; }
+           if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK)           { goto ERR_MU; }
+        } else {
+           /* if not first, add from table */
+           if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
+        }
+     }
+  }
+
+  /* reduce to affine */
+  err = ltc_ecc_map(C, modulus, mp);
+
+  /* clean up */
+ERR_MU:
+   mp_clear(mu);
+ERR_MP:
+   mp_montgomery_free(mp);
+ERR_P:
+   for (x = 0; x < 16; x++) {
+       ltc_ecc_del_point(precomp[x]);
+   }
+ERR_T:
+#ifdef LTC_CLEAN_STACK
+   zeromem(tA, ECC_BUF_SIZE);
+   zeromem(tB, ECC_BUF_SIZE);
+#endif
+   XFREE(tA);
+   XFREE(tB);
+
+   return err;
+}
+
+#endif
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 9 - 4
src/pk/ecc/ltc_ecc_mulmod.c

@@ -54,6 +54,7 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
       return err;
    }
    if ((err = mp_init(&mu)) != CRYPT_OK) {
+      mp_montgomery_free(mp);
       return err;
    }
    if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
@@ -90,6 +91,7 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
       if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK)                   { goto done; }
    }
    mp_clear(mu);
+   mu = NULL;
    
    /* calc the M tab, which holds kG for k==8..15 */
    /* M[0] == 8G */
@@ -154,11 +156,11 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
          /* ok window is filled so double as required and add  */
          /* double first */
          for (j = 0; j < WINSIZE; j++) {
-           if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK)             { goto done; }
+           if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK)              { goto done; }
          }
 
          /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
-         if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK)  { goto done; }
+         if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK)   { goto done; }
        }
        /* empty window and reset */
        bitcpy = bitbuf = 0;
@@ -172,7 +174,7 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
      for (j = 0; j < bitcpy; j++) {
        /* only double if we have had at least one add first */
        if (first == 0) {
-          if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK)             { goto done; }
+          if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK)              { goto done; }
        }
 
        bitbuf <<= 1;
@@ -185,7 +187,7 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
             first = 0;
          } else {
             /* then add */
-            if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK)       { goto done; }
+            if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK)        { goto done; }
          }
        }
      }
@@ -198,6 +200,9 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
       err = CRYPT_OK;
    }
 done:
+   if (mu != NULL) {
+      mp_clear(mu);
+   }
    mp_montgomery_free(mp);
    ltc_ecc_del_point(tG);
    for (i = 0; i < 8; i++) {

+ 7 - 2
src/pk/ecc/ltc_ecc_mulmod_timing.c

@@ -52,11 +52,12 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
       return err;
    }
    if ((err = mp_init(&mu)) != CRYPT_OK) {
+      mp_montgomery_free(mp);
       return err;
    }
    if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
-      mp_montgomery_free(mp);
       mp_clear(mu);
+      mp_montgomery_free(mp);
       return err;
    }
 
@@ -67,8 +68,8 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
          for (j = 0; j < i; j++) {
              ltc_ecc_del_point(M[j]);
          }
-         mp_montgomery_free(mp);
          mp_clear(mu);
+         mp_montgomery_free(mp);
          return CRYPT_MEM;
       }
   }
@@ -82,6 +83,7 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
    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);
+   mu = NULL;
    
    /* calc the M tab */
    /* M[0] == G */
@@ -146,6 +148,9 @@ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
       err = CRYPT_OK;
    }
 done:
+   if (mu != NULL) {
+      mp_clear(mu);
+   }
    mp_montgomery_free(mp);
    ltc_ecc_del_point(tG);
    for (i = 0; i < 3; i++) {

+ 1 - 1
src/pk/ecc/ltc_ecc_points.c

@@ -30,7 +30,7 @@
 ecc_point *ltc_ecc_new_point(void)
 {
    ecc_point *p;
-   p = XMALLOC(sizeof(*p));
+   p = XCALLOC(1, sizeof(*p));
    if (p == NULL) {
       return NULL;
    }

+ 1 - 2
src/pk/ecc/ltc_ecc_projective_add_point.c

@@ -35,7 +35,7 @@
 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
 {
    void  *t1, *t2, *x, *y, *z;
-   int err;
+   int    err;
 
    LTC_ARGCHK(P       != NULL);
    LTC_ARGCHK(Q       != NULL);
@@ -183,7 +183,6 @@ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void
    if ((err = mp_copy(z, R->z)) != CRYPT_OK)                                   { goto done; }
 
    err = CRYPT_OK;
-   goto done;
 done:
    mp_clear_multi(t1, t2, x, y, z, NULL);
    return err;

+ 4 - 5
src/pk/ecc/ltc_ecc_projective_dbl_point.c

@@ -34,7 +34,7 @@
 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
 {
    void *t1, *t2;
-   int err;
+   int   err;
 
    LTC_ARGCHK(P       != NULL);
    LTC_ARGCHK(R       != NULL);
@@ -46,9 +46,9 @@ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void
    }
 
    if (P != R) {
-      if ((err = mp_copy(P->x, R->x)) != CRYPT_OK)                                   { goto done; }
-      if ((err = mp_copy(P->y, R->y)) != CRYPT_OK)                                   { goto done; }
-      if ((err = mp_copy(P->z, R->z)) != CRYPT_OK)                                   { goto done; }
+      if ((err = mp_copy(P->x, R->x)) != CRYPT_OK)                                { goto done; }
+      if ((err = mp_copy(P->y, R->y)) != CRYPT_OK)                                { goto done; }
+      if ((err = mp_copy(P->z, R->z)) != CRYPT_OK)                                { goto done; }
    }
 
    /* t1 = Z * Z */
@@ -136,7 +136,6 @@ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void
    }
  
    err = CRYPT_OK;
-   goto done;
 done:
    mp_clear_multi(t1, t2, NULL);
    return err;

+ 4 - 4
src/pk/pkcs1/pkcs_1_pss_decode.c

@@ -82,7 +82,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
 
    /* ensure the 0xBC byte */
    if (sig[siglen-1] != 0xBC) {
-      err = CRYPT_OK;
+      err = CRYPT_INVALID_PACKET;
       goto LBL_ERR;
    }
 
@@ -97,7 +97,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
 
    /* check the MSB */
    if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
-      err = CRYPT_OK;
+      err = CRYPT_INVALID_PACKET;
       goto LBL_ERR;
    }
 
@@ -119,14 +119,14 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
    /* check for zeroes and 0x01 */
    for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) {
        if (DB[x] != 0x00) {
-          err = CRYPT_OK;
+          err = CRYPT_INVALID_PACKET;
           goto LBL_ERR;
        }
    }
 
    /* check for the 0x01 */
    if (DB[x++] != 0x01) {
-      err = CRYPT_OK;
+      err = CRYPT_INVALID_PACKET;
       goto LBL_ERR;
    }
 

+ 10 - 9
src/pk/pkcs1/pkcs_1_v1_5_decode.c

@@ -10,23 +10,24 @@
  */
 #include "tomcrypt.h"
 
-/*! \file pkcs_1_v1_5_decode.c
+/** @file pkcs_1_v1_5_decode.c
  *
  *  PKCS #1 v1.5 Padding. (Andreas Lange)
  */
 
 #ifdef PKCS_1
 
-/*! \brief PKCS #1 v1.5 decode.
+/** @brief PKCS #1 v1.5 decode.
  *
- *  \param msg              The encoded data to decode
- *  \param msglen           The length of the encoded data (octets)
- *  \param block_type       Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
- *  \param modulus_bitlen   The bit length of the RSA modulus
- *  \param out              [out] Destination of decoding
- *  \param outlen           [in/out] The max size and resulting size of the decoding
+ *  @param msg              The encoded data to decode
+ *  @param msglen           The length of the encoded data (octets)
+ *  @param block_type       Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks)
+ *  @param modulus_bitlen   The bit length of the RSA modulus
+ *  @param out              [out] Destination of decoding
+ *  @param outlen           [in/out] The max size and resulting size of the decoding
+ *  @param is_valid         [out] Boolean whether the padding was valid
  *
- *  \return CRYPT_OK if successful (even if invalid)
+ *  @return CRYPT_OK if successful (even if invalid)
  */
 int pkcs_1_v1_5_decode(const unsigned char *msg, 
                              unsigned long  msglen,

+ 3 - 5
src/pk/rsa/rsa_exptmod.c

@@ -57,7 +57,7 @@ int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
    /* sanity check on the input */
    if (mp_cmp(key->N, tmp) == LTC_MP_LT) {
       err = CRYPT_PK_INVALID_SIZE;
-      goto done;
+      goto error;
    }
 
    /* are we using the private exponent and is the key optimized? */
@@ -85,13 +85,13 @@ int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
    if (x > *outlen) {
       *outlen = x;
       err = CRYPT_BUFFER_OVERFLOW;
-      goto done;
+      goto error;
    }
 
    /* this should never happen ... */
    if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) {
       err = CRYPT_ERROR;
-      goto done;
+      goto error;
    }
    *outlen = x;
 
@@ -101,9 +101,7 @@ int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
 
    /* clean up and return */
    err = CRYPT_OK;
-   goto done;
 error:
-done:
    mp_clear_multi(tmp, tmpa, tmpb, NULL);
    return err;
 }

+ 1 - 2
src/pk/rsa/rsa_free.c

@@ -24,8 +24,7 @@
 void rsa_free(rsa_key *key)
 {
    LTC_ARGCHKVD(key != NULL);
-   mp_clear_multi( key->e,  key->d,  key->N,  key->dQ,  key->dP,
-                   key->qP,  key->p,  key->q, NULL);
+   mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
 }
 
 #endif

+ 4 - 5
src/pk/rsa/rsa_import.c

@@ -33,8 +33,8 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    ltc_asn1_list ssl_pubkey_hashoid[2];
    ltc_asn1_list ssl_pubkey[2];
 
-   LTC_ARGCHK(in  != NULL);
-   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(in          != NULL);
+   LTC_ARGCHK(key         != NULL);
    LTC_ARGCHK(ltc_mp.name != NULL);
 
    /* init key */
@@ -67,7 +67,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
       for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) {
           y = (y << 1) | tmpbuf[x];
           if (++z == 8) {
-             tmpbuf[t++] = y;
+             tmpbuf[t++] = (unsigned char)y;
              y           = 0;
              z           = 0;
           }
@@ -131,8 +131,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    }
    return CRYPT_OK;
 LBL_ERR:
-   mp_clear_multi(key->d,  key->e, key->N, key->dQ, key->dP,
-                  key->qP, key->p, key->q, NULL);
+   mp_clear_multi(key->d,  key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
    return err;
 }
 

+ 30 - 33
src/pk/rsa/rsa_make_key.c

@@ -32,7 +32,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
    int    err;
 
    LTC_ARGCHK(ltc_mp.name != NULL);
-   LTC_ARGCHK(key != NULL);
+   LTC_ARGCHK(key         != NULL);
 
    if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
       return CRYPT_INVALID_KEYSIZE;
@@ -51,60 +51,57 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
    }
 
    /* make primes p and q (optimization provided by Wayne Scott) */
-   if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto error; }            /* tmp3 = e */
+   if ((err = mp_set_int(tmp3, e)) != CRYPT_OK)                      { goto errkey; }  /* tmp3 = e */
 
    /* make prime "p" */
    do {
-       if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK)  { goto done; }
-       if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK)               { goto error; }  /* tmp1 = p-1 */
-       if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK)          { goto error; }  /* tmp2 = gcd(p-1, e) */
-   } while (mp_cmp_d( tmp2, 1) != 0);                                                /* while e divides p-1 */
+       if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK)  { goto errkey; }
+       if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK)               { goto errkey; }  /* tmp1 = p-1 */
+       if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK)          { goto errkey; }  /* tmp2 = gcd(p-1, e) */
+   } while (mp_cmp_d( tmp2, 1) != 0);                                                  /* while e divides p-1 */
 
    /* make prime "q" */
    do {
-       if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto done; }
-       if ((err = mp_sub_d( q, 1,  tmp1)) != CRYPT_OK)               { goto error; } /* tmp1 = q-1 */
-       if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK)          { goto error; } /* tmp2 = gcd(q-1, e) */
-   } while (mp_cmp_d( tmp2, 1) != 0);                                               /* while e divides q-1 */
+       if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK)  { goto errkey; }
+       if ((err = mp_sub_d( q, 1,  tmp1)) != CRYPT_OK)               { goto errkey; } /* tmp1 = q-1 */
+       if ((err = mp_gcd( tmp1,  tmp3,  tmp2)) != CRYPT_OK)          { goto errkey; } /* tmp2 = gcd(q-1, e) */
+   } while (mp_cmp_d( tmp2, 1) != 0);                                                 /* while e divides q-1 */
 
    /* tmp1 = lcm(p-1, q-1) */
-   if ((err = mp_sub_d( p, 1,  tmp2)) != CRYPT_OK)                  { goto error; } /* tmp2 = p-1 */
-                                                                   /* tmp1 = q-1 (previous do/while loop) */
-   if ((err = mp_lcm( tmp1,  tmp2,  tmp1)) != CRYPT_OK)             { goto error; } /* tmp1 = lcm(p-1, q-1) */
+   if ((err = mp_sub_d( p, 1,  tmp2)) != CRYPT_OK)                   { goto errkey; } /* tmp2 = p-1 */
+                                                                                      /* tmp1 = q-1 (previous do/while loop) */
+   if ((err = mp_lcm( tmp1,  tmp2,  tmp1)) != CRYPT_OK)              { goto errkey; } /* tmp1 = lcm(p-1, q-1) */
 
    /* make key */
-   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
-                     &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
-      goto error;
+   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
+      goto errkey;
    }
 
-   if ((err = mp_set_int( key->e, e)) != CRYPT_OK)                     { goto error2; } /* key->e =  e */
-   if ((err = mp_invmod( key->e,  tmp1,  key->d)) != CRYPT_OK)         { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */
-   if ((err = mp_mul( p,  q,  key->N)) != CRYPT_OK)                    { goto error2; } /* key->N = pq */
+   if ((err = mp_set_int( key->e, e)) != CRYPT_OK)                     { goto errkey; } /* key->e =  e */
+   if ((err = mp_invmod( key->e,  tmp1,  key->d)) != CRYPT_OK)         { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */
+   if ((err = mp_mul( p,  q,  key->N)) != CRYPT_OK)                    { goto errkey; } /* key->N = pq */
 
    /* optimize for CRT now */
    /* find d mod q-1 and d mod p-1 */
-   if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK)                     { goto error2; } /* tmp1 = q-1 */
-   if ((err = mp_sub_d( q, 1,  tmp2)) != CRYPT_OK)                     { goto error2; } /* tmp2 = p-1 */
-   if ((err = mp_mod( key->d,  tmp1,  key->dP)) != CRYPT_OK)           { goto error2; } /* dP = d mod p-1 */
-   if ((err = mp_mod( key->d,  tmp2,  key->dQ)) != CRYPT_OK)           { goto error2; } /* dQ = d mod q-1 */
-   if ((err = mp_invmod( q,  p,  key->qP)) != CRYPT_OK)                { goto error2; } /* qP = 1/q mod p */
+   if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK)                     { goto errkey; } /* tmp1 = q-1 */
+   if ((err = mp_sub_d( q, 1,  tmp2)) != CRYPT_OK)                     { goto errkey; } /* tmp2 = p-1 */
+   if ((err = mp_mod( key->d,  tmp1,  key->dP)) != CRYPT_OK)           { goto errkey; } /* dP = d mod p-1 */
+   if ((err = mp_mod( key->d,  tmp2,  key->dQ)) != CRYPT_OK)           { goto errkey; } /* dQ = d mod q-1 */
+   if ((err = mp_invmod( q,  p,  key->qP)) != CRYPT_OK)                { goto errkey; } /* qP = 1/q mod p */
 
-   if ((err = mp_copy( p,  key->p)) != CRYPT_OK)                       { goto error2; }
-   if ((err = mp_copy( q,  key->q)) != CRYPT_OK)                       { goto error2; }
+   if ((err = mp_copy( p,  key->p)) != CRYPT_OK)                       { goto errkey; }
+   if ((err = mp_copy( q,  key->q)) != CRYPT_OK)                       { goto errkey; }
 
    /* set key type (in this case it's CRT optimized) */
    key->type = PK_PRIVATE;
 
    /* return ok and free temps */
    err       = CRYPT_OK;
-   goto done;
-error2:
-   mp_clear_multi( key->d,  key->e,  key->N,  key->dQ,  key->dP,
-                   key->qP,  key->p,  key->q, NULL);
-error:
-done:
-   mp_clear_multi( tmp3,  tmp2,  tmp1,  p,  q, NULL);
+   goto cleanup;
+errkey:
+   mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL);
+cleanup:
+   mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL);
    return err;
 }
 

+ 1 - 0
src/pk/rsa/rsa_verify_hash.c

@@ -86,6 +86,7 @@ int rsa_verify_hash_ex(const unsigned char *sig,      unsigned long siglen,
 
   /* make sure the output is the right size */
   if (x != siglen) {
+     XFREE(tmpbuf);
      return CRYPT_INVALID_PACKET;
   }
 

+ 3 - 3
src/prngs/fortuna.c

@@ -143,8 +143,8 @@ int fortuna_start(prng_state *prng)
           return err;
        }
    }
-   prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.reset_cnt = 
-   prng->fortuna.wd = 0;
+   prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0;
+   prng->fortuna.reset_cnt = 0;
 
    /* reset bufs */
    zeromem(prng->fortuna.K, 32);
@@ -186,7 +186,7 @@ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state
 
    /* add s || length(in) || in to pool[pool_idx] */
    tmp[0] = 0;
-   tmp[1] = inlen;
+   tmp[1] = (unsigned char)inlen;
    if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) {
       LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock);
       return err;

+ 6 - 2
src/prngs/rng_get_bytes.c

@@ -50,7 +50,7 @@ static unsigned long rng_nix(unsigned char *buf, unsigned long len,
 #endif /* DEVRANDOM */
 
 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
-#if defined(CLOCKS_PER_SEC)
+#if defined(CLOCKS_PER_SEC) && !defined(WINCE)
 
 #define ANSI_RNG
 
@@ -87,8 +87,12 @@ static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
 #endif 
 
 /* Try the Microsoft CSP */
-#ifdef WIN32
+#if defined(WIN32) || defined(WINCE)
 #define _WIN32_WINNT 0x0400
+#ifdef WINCE
+   #define UNDER_CE
+   #define ARM
+#endif
 #include <windows.h>
 #include <wincrypt.h>
 

+ 44 - 0
testprof/der_tests.c

@@ -532,6 +532,14 @@ int der_tests(void)
    static const unsigned char rsa_time1_der[] = { 0x17, 0x11, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x36, 0x34, 0x35, 0x34, 0x30, 0x2D, 0x30, 0x37, 0x30, 0x30 };
    static const unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a };
 
+   static const wchar_t utf8_1[]           = { 0x0041, 0x2262, 0x0391, 0x002E };
+   static const unsigned char utf8_1_der[] = { 0x0C, 0x07, 0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E };
+   static const wchar_t utf8_2[]           = { 0xD55C, 0xAD6D, 0xC5B4 };
+   static const unsigned char utf8_2_der[] = { 0x0C, 0x09, 0xED, 0x95, 0x9C, 0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4 };
+
+   unsigned char utf8_buf[32];
+   wchar_t utf8_out[32];
+
    DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));
    for (zz = 0; zz < 16; zz++) {
 #ifdef USE_TFM
@@ -797,6 +805,42 @@ tmp_time.off_hh);
       return 1;
    }
 
+   /* UTF 8 */
+     /* encode it */
+     x = sizeof(utf8_buf);
+     DO(der_encode_utf8_string(utf8_1, sizeof(utf8_1) / sizeof(utf8_1[0]), utf8_buf, &x));
+     if (x != sizeof(utf8_1_der) || memcmp(utf8_buf, utf8_1_der, x)) {
+        fprintf(stderr, "DER UTF8_1 encoded to %lu bytes\n", x);
+        for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]); fprintf(stderr, "\n");
+        return 1;
+     }
+     /* decode it */
+     y = sizeof(utf8_out) / sizeof(utf8_out[0]);
+     DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y));
+     if (y != (sizeof(utf8_1) / sizeof(utf8_1[0])) || memcmp(utf8_1, utf8_out, y * sizeof(wchar_t))) {
+        fprintf(stderr, "DER UTF8_1 decoded to %lu wchar_t\n", y);
+        for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]); fprintf(stderr, "\n");
+        return 1;
+     }
+
+     /* encode it */
+     x = sizeof(utf8_buf);
+     DO(der_encode_utf8_string(utf8_2, sizeof(utf8_2) / sizeof(utf8_2[0]), utf8_buf, &x));
+     if (x != sizeof(utf8_2_der) || memcmp(utf8_buf, utf8_2_der, x)) {
+        fprintf(stderr, "DER UTF8_2 encoded to %lu bytes\n", x);
+        for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]); fprintf(stderr, "\n");
+        return 1;
+     }
+     /* decode it */
+     y = sizeof(utf8_out) / sizeof(utf8_out[0]);
+     DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y));
+     if (y != (sizeof(utf8_2) / sizeof(utf8_2[0])) || memcmp(utf8_2, utf8_out, y * sizeof(wchar_t))) {
+        fprintf(stderr, "DER UTF8_2 decoded to %lu wchar_t\n", y);
+        for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]); fprintf(stderr, "\n");
+        return 1;
+     }
+
+
    der_set_test();
    der_flexi_test();
    return der_choice_test();

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