Browse Source

added libtomcrypt-1.08

Tom St Denis 20 years ago
parent
commit
1eeff0bfb4

+ 1 - 1
Doxyfile

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

+ 0 - 42
TODO

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

+ 13 - 2
changes

@@ -1,3 +1,14 @@
+November 24th, 2005
+v1.08 -- Added SET and SET OF support to the ASN.1 side
+      -- Fixed up X macros, added QSORT to the mix [thanks SET/SETOF]
+      -- Added XMEMCMP to the list of X macros
+      -- In der_decode_sequence() the SHORT_INTEGER type was not being handled correctly [oddly enough it worked just enough to make RSA work ... go figure!]
+      -- Fixed bug in math descriptors where if you hadn't defined MECC (ECC support) you would get linker errors
+      -- Added RSA accelerators to the math descriptors to make it possible to not include the stock routines if you supply your own.
+      -- dsa_decrypt_key() was erroneously dependent on MECC not MDSA ... whoops
+      -- Moved DSA size limits to tomcrypt_pk.h so they're defined with LTC_NO_PK+MDSA
+      -- cleaned up tomcrypt_custom.h to make customizable PK easier (and also cleaned up the error traps so they're correctly reported)
+
 November 18th, 2005
 November 18th, 2005
 v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly.  That's because as of a few releases ago
 v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly.  That's because as of a few releases ago
          I added support to set the mode of the counter at init time
          I added support to set the mode of the counter at init time
@@ -1383,6 +1394,6 @@ v0.02  -- Changed RC5 to only allow 12 to 24 rounds
 v0.01  -- We will call this the first version.
 v0.01  -- We will call this the first version.
 
 
 /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
 /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
-/* $Revision: 1.151 $ */
-/* $Date: 2005/11/17 22:04:00 $ */
+/* $Revision: 1.161 $ */
+/* $Date: 2005/11/24 03:30:18 $ */
 
 

+ 71 - 7
crypt.tex

@@ -47,7 +47,7 @@
 \def\gap{\vspace{0.5ex}}
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \makeindex
 \begin{document}
 \begin{document}
-\title{LibTomCrypt \\ Version 1.07}
+\title{LibTomCrypt \\ Version 1.08}
 \author{Tom St Denis \\
 \author{Tom St Denis \\
 \\
 \\
 [email protected] \\
 [email protected] \\
@@ -3198,7 +3198,7 @@ LibTomCrypt supports a variety of ASN.1 data types encoded with the Distinguishe
 are all provided with three basic functions with \textit{similar} prototypes.  One function has been dedicated to calculate the length in octets of a given
 are all provided with three basic functions with \textit{similar} prototypes.  One function has been dedicated to calculate the length in octets of a given
 format and two functions have been dedicated to encoding and decoding the format.  
 format and two functions have been dedicated to encoding and decoding the format.  
 
 
-On top of the basic data types are the SEQUENCE and\footnote{Planned for LTC 1.06} SET data types which are collections of other ASN.1 types.  They are provided 
+On top of the basic data types are the SEQUENCE and SET data types which are collections of other ASN.1 types.  They are provided 
 in the same manner as the other data types except they use list of objects known as the \textbf{ltc\_asn1\_list} structure.  It is defined as 
 in the same manner as the other data types except they use list of objects known as the \textbf{ltc\_asn1\_list} structure.  It is defined as 
 
 
 \index{ltc\_asn1\_list structure}
 \index{ltc\_asn1\_list structure}
@@ -3262,7 +3262,9 @@ LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL,           NULL,   0);
 \hline LTC\_ASN1\_IA5\_STRING        & IA5 STRING (one octet per char) \\
 \hline LTC\_ASN1\_IA5\_STRING        & IA5 STRING (one octet per char) \\
 \hline LTC\_ASN1\_PRINTABLE\_STRING  & PRINTABLE STIRNG (one octet per char) \\
 \hline LTC\_ASN1\_PRINTABLE\_STRING  & PRINTABLE STIRNG (one octet per char) \\
 \hline LTC\_ASN1\_UTCTIME            & UTCTIME (see ltc\_utctime structure) \\
 \hline LTC\_ASN1\_UTCTIME            & UTCTIME (see ltc\_utctime structure) \\
-\hline LTC\_ASN1\_SEQUENCE           & SEQUENCE OF \\
+\hline LTC\_ASN1\_SEQUENCE           & SEQUENCE (and SEQUENCE OF) \\
+\hline LTC\_ASN1\_SET                & SET \\
+\hline LTC\_ASN1\_SETOF              & SET OF \\
 \hline LTC\_ASN1\_CHOICE             & CHOICE \\
 \hline LTC\_ASN1\_CHOICE             & CHOICE \\
 \hline
 \hline
 \end{tabular}
 \end{tabular}
@@ -3347,6 +3349,68 @@ and ``data'' is \textbf{void} pointer.  The list of items must be terminated wit
 It's ideal that you cast the ``size'' values to unsigned long to ensure that the proper data type is passed to the function.  Constants such as ``1'' without
 It's ideal that you cast the ``size'' values to unsigned long to ensure that the proper data type is passed to the function.  Constants such as ``1'' without
 a cast or prototype are of type \textbf{int} by default.  Appending \textit{UL} or prepending \textit{(unsigned long)} is enough to cast it to the correct type.
 a cast or prototype are of type \textbf{int} by default.  Appending \textit{UL} or prepending \textit{(unsigned long)} is enough to cast it to the correct type.
 
 
+\subsection{SET and SET OF}
+
+\index{SET} \index{SET OF}
+SET and SET OF are related to the SEQUENCE type in that they can be pretty much be decoded with the same code.  However, they are different and they should
+be carefully noted.  The SET type is an unordered array of ASN.1 types sorted by the TAG (type identifier) whereas the SET OF type is an ordered array of 
+a \textbf{single} ASN.1 object sorted in ascending order by the DER their respective encodings.
+
+\subsubsection{SET Encoding}
+
+SETs use the same array structure of ltc\_asn1\_list that the SEQUENCE functions use.  They are encoded with the following function.
+
+\index{der\_encode\_set()}
+\begin{verbatim}
+int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
+                   unsigned char *out,  unsigned long *outlen);
+\end{verbatim}            
+
+This will encode the list of ASN.1 objects in ``list'' of length ``inlen'' objects and store the output in ``out'' of length ``outlen'' bytes.  The function
+will make a copy of the list provided and sort it by the TAG.  Objects with identical TAGs are additionally sorted on their original placement in the 
+array (to make the process deterministic).
+
+This function will \textbf{NOT} recognize ``DEFAULT'' objects and it is the responsibility of the caller to remove them as required.
+
+\subsubsection{SET Decoding}
+
+The SET type can be decoded with the following function.
+
+\index{der\_decode\_set()}
+\begin{verbatim}
+int der_decode_set(const unsigned char *in,   unsigned long  inlen,
+                   ltc_asn1_list       *list, unsigned long  outlen);
+\end{verbatim}
+
+This will decode the SET specified by ``list'' of length ``outlen'' objects from the input buffer ``in'' of length ``inlen'' octets.
+
+It handles the fact that SETs are not strictly ordered and will make multiple passes (as required) through the list to decode all the objects.  
+
+\subsubsection{SET Length}
+The length of a SET can be determined by calling der\_length\_sequence() since they have the same encoding length.
+
+\subsubsection{SET OF Encoding}
+A ``SET OF'' object is an array of identifical objects (e.g. OCTET STRING) sorted in ascending order by the DER encoding of the object.  They are 
+used to store objects deterministically based solely on their encoding.  It uses the same array structure of ltc\_asn1\_list that the SEQUENCE functions
+use.  They are encoded with the following function.
+
+\index{der\_encode\_setof()}
+\begin{verbatim}
+int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
+                     unsigned char *out,  unsigned long *outlen);
+\end{verbatim}
+
+This will encode a ``SET OF'' containing the ``list'' of ``inlen'' ASN.1 objects and store the encoding in the output buffer ``out'' of length ``outlen''.
+
+The routine will first encode the SET OF in an unordered fashion (in a temporary buffer) then sort using the XQSORT macro and copy back to the output buffer.  This
+means you need at least enough memory to keep an additional copy of the output on the heap.  
+
+\subsubsection{SET OF Decoding}
+Since the decoding of a ``SET OF'' object is unambiguous it can be decoded with der\_decode\_sequence().  
+
+\subsubsection{SET OF Length}
+Like the SET type the der\_length\_sequence() function can be used to determine the length of a ``SET OF'' object.
+
 \subsection{ASN.1 INTEGER}
 \subsection{ASN.1 INTEGER}
 
 
 To encode or decode INTEGER data types use the following functions.
 To encode or decode INTEGER data types use the following functions.
@@ -3547,8 +3611,8 @@ The flexi decoder uses the same ``ltc\_asn1\_list'' but instead of being stored
 and ``child''.  The list works as a ``doubly-linked list'' structure where decoded items at the same level are sibblings (using next and prev) and items
 and ``child''.  The list works as a ``doubly-linked list'' structure where decoded items at the same level are sibblings (using next and prev) and items
 encoded in a SEQUENCE are stored as a child element.
 encoded in a SEQUENCE are stored as a child element.
 
 
-When a SEQUENCE has been encountered a SEQUENCE item is added as a sibbling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child pointer points to a new list
-of items contained within the sequence\footnote{The same will be true for the SET data type when I eventually support it.}.
+When a SEQUENCE or SET has been encountered a SEQUENCE (or SET resp.) item will be added as a sibbling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child 
+pointer points to a new list of items contained within the object.
 
 
 \index{der\_decode\_sequence\_flexi()}
 \index{der\_decode\_sequence\_flexi()}
 \begin{verbatim}
 \begin{verbatim}
@@ -5012,5 +5076,5 @@ Since the function is given the entire RSA key (for private keys only) CRT is po
 \end{document}
 \end{document}
 
 
 % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $   
 % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $   
-% $Revision: 1.55 $   
-% $Date: 2005/11/18 01:45:03 $ 
+% $Revision: 1.59 $   
+% $Date: 2005/11/24 01:53:18 $ 

BIN
doc/crypt.pdf


+ 11 - 6
makefile

@@ -4,7 +4,7 @@
 # Modified by Clay Culver
 # Modified by Clay Culver
 
 
 # The version
 # The version
-VERSION=1.07
+VERSION=1.08
 
 
 # Compiler and Linker Names
 # Compiler and Linker Names
 #CC=gcc
 #CC=gcc
@@ -101,6 +101,7 @@ GROUP=wheel
 endif
 endif
 
 
 #List of objects to compile.
 #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 \
 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/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o \
 src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o \
 src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \
 src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \
@@ -165,10 +166,13 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
 src/pk/asn1/der/printable_string/der_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_printable_string.o \
 src/pk/asn1/der/printable_string/der_length_printable_string.o \
 src/pk/asn1/der/printable_string/der_length_printable_string.o \
-src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
-src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
+src/pk/asn1/der/sequence/der_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_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
-src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/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_encode_short_integer.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
@@ -196,6 +200,7 @@ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt
 src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.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_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+#END_INS
 
 
 TESTOBJECTS=demos/test.o
 TESTOBJECTS=demos/test.o
 HASHOBJECTS=demos/hashsum.o
 HASHOBJECTS=demos/hashsum.o
@@ -356,5 +361,5 @@ zipup: no_oops docs
 
 
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
 # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
-# $Revision: 1.103 $ 
-# $Date: 2005/11/18 01:46:22 $ 
+# $Revision: 1.108 $ 
+# $Date: 2005/11/23 02:34:57 $ 

+ 11 - 5
makefile.icc

@@ -88,6 +88,7 @@ ifndef DATAPATH
 endif
 endif
 
 
 #List of objects to compile.
 #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 \
 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/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o \
 src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o \
 src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \
 src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \
@@ -152,10 +153,13 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
 src/pk/asn1/der/printable_string/der_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_printable_string.o \
 src/pk/asn1/der/printable_string/der_length_printable_string.o \
 src/pk/asn1/der/printable_string/der_length_printable_string.o \
-src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
-src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
+src/pk/asn1/der/sequence/der_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_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
-src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/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_encode_short_integer.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
@@ -183,6 +187,7 @@ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt
 src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.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_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+#END_INS
 
 
 #Who do we install as?
 #Who do we install as?
 ifdef INSTALL_USER
 ifdef INSTALL_USER
@@ -261,5 +266,6 @@ install: library
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $   
 # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $   
-# $Revision: 1.44 $   
-# $Date: 2005/11/18 01:46:22 $ 
+# $Revision: 1.45 $   
+# $Date: 2005/11/23 02:34:57 $ 
+

+ 10 - 6
makefile.msvc

@@ -3,6 +3,7 @@
 #Tom St Denis
 #Tom St Denis
 CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF)
 CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF)
 
 
+#START_INS
 OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
 OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
 src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
 src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
 src/ciphers/rc5.obj src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/safer_tab.obj \
 src/ciphers/rc5.obj src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/safer_tab.obj \
@@ -67,10 +68,13 @@ src/pk/asn1/der/octet/der_length_octet_string.obj \
 src/pk/asn1/der/printable_string/der_decode_printable_string.obj \
 src/pk/asn1/der/printable_string/der_decode_printable_string.obj \
 src/pk/asn1/der/printable_string/der_encode_printable_string.obj \
 src/pk/asn1/der/printable_string/der_encode_printable_string.obj \
 src/pk/asn1/der/printable_string/der_length_printable_string.obj \
 src/pk/asn1/der/printable_string/der_length_printable_string.obj \
-src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \
-src/pk/asn1/der/sequence/der_decode_sequence_multi.obj src/pk/asn1/der/sequence/der_encode_sequence.obj \
+src/pk/asn1/der/sequence/der_decode_sequence_ex.obj \
+src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \
+src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \
+src/pk/asn1/der/sequence/der_encode_sequence_ex.obj \
 src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \
 src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \
-src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
+src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/set/der_encode_set.obj \
+src/pk/asn1/der/set/der_encode_setof.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
 src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
 src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
 src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
 src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
 src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
 src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
@@ -98,6 +102,7 @@ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt
 src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.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_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+#END_INS
 
 
 default: library
 default: library
 
 
@@ -124,6 +129,5 @@ timing: demos/timing.c library
 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $   
 # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $   
-# $Revision: 1.24 $   
-# $Date: 2005/11/18 01:46:22 $ 
-
+# $Revision: 1.25 $   
+# $Date: 2005/11/23 02:34:57 $ 

+ 11 - 7
makefile.shared

@@ -6,7 +6,7 @@
 # Tom St Denis
 # Tom St Denis
 
 
 # The version
 # The version
-VERSION=0:107
+VERSION=0:108
 
 
 # Compiler and Linker Names
 # Compiler and Linker Names
 CC=libtool --mode=compile gcc 
 CC=libtool --mode=compile gcc 
@@ -95,6 +95,7 @@ GROUP=wheel
 endif
 endif
 
 
 #List of objects to compile.
 #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 \
 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/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o \
 src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o src/ciphers/rc2.o \
 src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \
 src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/safer_tab.o \
@@ -159,10 +160,13 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
 src/pk/asn1/der/printable_string/der_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_decode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_printable_string.o \
 src/pk/asn1/der/printable_string/der_encode_printable_string.o \
 src/pk/asn1/der/printable_string/der_length_printable_string.o \
 src/pk/asn1/der/printable_string/der_length_printable_string.o \
-src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
-src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
+src/pk/asn1/der/sequence/der_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_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
-src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/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_encode_short_integer.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
 src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
@@ -190,6 +194,7 @@ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt
 src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.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_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
 src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
+#END_INS
 
 
 TESTOBJECTS=demos/test.o
 TESTOBJECTS=demos/test.o
 HASHOBJECTS=demos/hashsum.o
 HASHOBJECTS=demos/hashsum.o
@@ -250,6 +255,5 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
 
 
 # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $   
 # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $   
-# $Revision: 1.36 $   
-# $Date: 2005/11/18 01:46:22 $ 
-
+# $Revision: 1.38 $   
+# $Date: 2005/11/23 02:34:57 $ 

+ 2 - 2
src/headers/tomcrypt.h

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

+ 5 - 1
src/headers/tomcrypt_cfg.h

@@ -13,12 +13,16 @@ void *XREALLOC(void *p, size_t n);
 void *XCALLOC(size_t n, size_t s);
 void *XCALLOC(size_t n, size_t s);
 void XFREE(void *p);
 void XFREE(void *p);
 
 
+void XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
+
+
 /* change the clock function too */
 /* change the clock function too */
- clock_t XCLOCK(void);
+clock_t XCLOCK(void);
 
 
 /* various other functions */
 /* various other functions */
 void *XMEMCPY(void *dest, const void *src, size_t n);
 void *XMEMCPY(void *dest, const void *src, size_t n);
 int   XMEMCMP(const void *s1, const void *s2, size_t n);
 int   XMEMCMP(const void *s1, const void *s2, size_t n);
+void *XMEMSET(void *s, int c, size_t n);
 
 
 /* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
 /* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */
 #ifndef ARGTYPE
 #ifndef ARGTYPE

+ 52 - 22
src/headers/tomcrypt_custom.h

@@ -2,16 +2,39 @@
 #define TOMCRYPT_CUSTOM_H_
 #define TOMCRYPT_CUSTOM_H_
 
 
 /* macros for various libc functions you can change for embedded targets */
 /* macros for various libc functions you can change for embedded targets */
+#ifndef XMALLOC
 #define XMALLOC  malloc
 #define XMALLOC  malloc
+#endif
+#ifndef XREALLOC
 #define XREALLOC realloc
 #define XREALLOC realloc
+#endif
+#ifndef XCALLOC
 #define XCALLOC  calloc
 #define XCALLOC  calloc
+#endif
+#ifndef XFREE
 #define XFREE    free
 #define XFREE    free
+#endif
 
 
+#ifndef XMEMSET
 #define XMEMSET  memset
 #define XMEMSET  memset
+#endif
+#ifndef XMEMCPY
 #define XMEMCPY  memcpy
 #define XMEMCPY  memcpy
+#endif
+#ifndef XMEMCMP
+#define XMEMCMP  memcmp
+#endif
 
 
+#ifndef XCLOCK
 #define XCLOCK   clock
 #define XCLOCK   clock
+#endif
+#ifndef XCLOCKS_PER_SEC
 #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
 #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
+#endif
+
+#ifndef XQSORT
+#define XQSORT qsort
+#endif
 
 
 /* Use small code where possible */
 /* Use small code where possible */
 /* #define LTC_SMALL_CODE */
 /* #define LTC_SMALL_CODE */
@@ -186,15 +209,11 @@
 /* Include RSA support */
 /* Include RSA support */
 #define MRSA
 #define MRSA
 
 
-/* Include Katja (an Rabin variant like RSA) */
+/* Include Katja (a Rabin variant like RSA) */
 // #define MKAT 
 // #define MKAT 
 
 
 /* Digital Signature Algorithm */
 /* Digital Signature Algorithm */
 #define MDSA
 #define MDSA
-/* Max diff between group and modulus size in bytes */
-#define MDSA_DELTA     512
-/* Max DSA group size in bytes (default allows 4k-bit groups) */
-#define MDSA_MAX_GROUP 512
 
 
 /* ECC */
 /* ECC */
 #define MECC
 #define MECC
@@ -202,18 +221,6 @@
 /* Timing Resistant? */
 /* Timing Resistant? */
 /* #define LTC_ECC_TIMING_RESISTANT */
 /* #define LTC_ECC_TIMING_RESISTANT */
 
 
-/* Supported ECC Key Sizes */
-#ifndef LTC_NO_CURVES
-   #define ECC192
-   #define ECC224
-   #define ECC256
-   #define ECC384
-   #define ECC521
-#endif
-
-/* Include the MPI functionality?  (required by the PK algorithms) */
-#define MPI
-
 #endif /* LTC_NO_PK */
 #endif /* LTC_NO_PK */
 
 
 /* PKCS #1 (RSA) and #5 (Password Handling) stuff */
 /* PKCS #1 (RSA) and #5 (Password Handling) stuff */
@@ -224,18 +231,38 @@
 
 
 /* Include ASN.1 DER (required by DSA/RSA) */
 /* Include ASN.1 DER (required by DSA/RSA) */
 #define LTC_DER
 #define LTC_DER
-#if defined(LTC_DER) && !defined(MPI) 
-   #error ASN.1 DER requires MPI functionality
+
+#endif /* LTC_NO_PKCS */
+
+/* cleanup */
+
+#ifdef MECC
+/* Supported ECC Key Sizes */
+#ifndef LTC_NO_CURVES
+   #define ECC192
+   #define ECC224
+   #define ECC256
+   #define ECC384
+   #define ECC521
+#endif
 #endif
 #endif
 
 
-#if (defined(MDSA) || defined(MRSA)) && !defined(LTC_DER)
-   #error RSA/DSA requires ASN.1 DER functionality, make sure LTC_DER is enabled
+#if defined(MECC) || defined(MRSA) || defined(MDSA) || defined(MKATJA)
+   /* Include the MPI functionality?  (required by the PK algorithms) */
+   #define MPI
 #endif
 #endif
 
 
-#endif /* LTC_NO_PKCS */
+#ifdef MRSA
+   #define PKCS_1
+#endif   
 
 
+#if defined(LTC_DER) && !defined(MPI) 
+   #error ASN.1 DER requires MPI functionality
 #endif
 #endif
 
 
+#if (defined(MDSA) || defined(MRSA) || defined(MECC) || defined(MKATJA)) && !defined(LTC_DER)
+   #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled
+#endif
 
 
 /* THREAD management */
 /* THREAD management */
 
 
@@ -262,6 +289,9 @@
 
 
 #endif
 #endif
 
 
+#endif
+
+
 
 
 /* $Source$ */
 /* $Source$ */
 /* $Revision$ */
 /* $Revision$ */

+ 27 - 10
src/headers/tomcrypt_pk.h

@@ -244,6 +244,12 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
 
 
 #ifdef MDSA
 #ifdef MDSA
 
 
+/* Max diff between group and modulus size in bytes */
+#define MDSA_DELTA     512
+
+/* Max DSA group size in bytes (default allows 4k-bit groups) */
+#define MDSA_MAX_GROUP 512
+
 /** DSA key structure */
 /** DSA key structure */
 typedef struct {
 typedef struct {
    /** The key type, PK_PRIVATE or PK_PUBLIC */
    /** The key type, PK_PRIVATE or PK_PUBLIC */
@@ -300,8 +306,6 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
 int dsa_verify_key(dsa_key *key, int *stat);
 int dsa_verify_key(dsa_key *key, int *stat);
 
 
-
-
 int dsa_shared_secret(void          *private_key, void *base,
 int dsa_shared_secret(void          *private_key, void *base,
                       dsa_key       *public_key,
                       dsa_key       *public_key,
                       unsigned char *out,         unsigned long *outlen);
                       unsigned char *out,         unsigned long *outlen);
@@ -321,9 +325,10 @@ enum {
  LTC_ASN1_IA5_STRING,
  LTC_ASN1_IA5_STRING,
  LTC_ASN1_PRINTABLE_STRING,
  LTC_ASN1_PRINTABLE_STRING,
  LTC_ASN1_UTCTIME,
  LTC_ASN1_UTCTIME,
-
  LTC_ASN1_CHOICE,
  LTC_ASN1_CHOICE,
- LTC_ASN1_SEQUENCE
+ LTC_ASN1_SEQUENCE,
+ LTC_ASN1_SET,
+ LTC_ASN1_SETOF
 };
 };
 
 
 /** A LTC ASN.1 list type */
 /** A LTC ASN.1 list type */
@@ -351,23 +356,35 @@ typedef struct ltc_asn1_list_ {
    } while (0);
    } while (0);
 
 
 /* SEQUENCE */
 /* SEQUENCE */
-int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
-                        unsigned char *out,  unsigned long *outlen);
+int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
+                           unsigned char *out,  unsigned long *outlen, int type_of);
+                          
+#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE)                        
 
 
-int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
-                              ltc_asn1_list *list, unsigned long  outlen);
+int der_decode_sequence_ex(const unsigned char *in, unsigned long  inlen,
+                           ltc_asn1_list *list,     unsigned long  outlen, int ordered);
+                              
+#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
 
 
 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
                         unsigned long *outlen);
                         unsigned long *outlen);
 
 
+/* SET */
+#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
+#define der_length_set der_length_sequence
+int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
+                   unsigned char *out,  unsigned long *outlen);
+
+int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
+                     unsigned char *out,  unsigned long *outlen);
+                        
 /* VA list handy helpers with triplets of <type, size, data> */
 /* VA list handy helpers with triplets of <type, size, data> */
 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
 int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
 int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
 
 
-/* handle unknown list decoder */
+/* FLEXI DECODER handle unknown list decoder */
 int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
 int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
 void der_free_sequence_flexi(ltc_asn1_list *list);
 void der_free_sequence_flexi(ltc_asn1_list *list);
-
 void der_sequence_free(ltc_asn1_list *in);
 void der_sequence_free(ltc_asn1_list *in);
 
 
 /* INTEGER */
 /* INTEGER */

+ 10 - 2
src/math/ltm_desc.c

@@ -428,12 +428,20 @@ const ltc_math_descriptor ltm_desc = {
    &exptmod,
    &exptmod,
    &isprime,
    &isprime,
 
 
+#ifdef MECC
    &ltc_ecc_mulmod,
    &ltc_ecc_mulmod,
    &ltc_ecc_projective_add_point,
    &ltc_ecc_projective_add_point,
    &ltc_ecc_map,
    &ltc_ecc_map,
+#else
+   NULL, NULL, NULL,
+#endif
 
 
-   NULL,
-   NULL
+#ifdef MRSA
+   &rsa_make_key,
+   &rsa_exptmod,
+#else
+   NULL, NULL
+#endif
 };
 };
 
 
 
 

+ 11 - 2
src/math/tfm_desc.c

@@ -440,12 +440,21 @@ const ltc_math_descriptor tfm_desc = {
    &exptmod,
    &exptmod,
    &isprime,
    &isprime,
 
 
+#ifdef MECC
    &ltc_ecc_mulmod,
    &ltc_ecc_mulmod,
    &ltc_ecc_projective_add_point,
    &ltc_ecc_projective_add_point,
    &ltc_ecc_map,
    &ltc_ecc_map,
+#else
+   NULL, NULL, NULL,
+#endif
 
 
-   NULL,
-   NULL
+#ifdef MRSA
+   &rsa_make_key,
+   &rsa_exptmod,
+#else
+   NULL, NULL
+#endif
+   
 };
 };
 
 
 
 

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

@@ -144,6 +144,8 @@ int der_decode_choice(const unsigned char *in,   unsigned long *inlen,
                }
                }
                break;
                break;
 
 
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
                if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
                if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
                   if (der_length_sequence(data, size, &z) == CRYPT_OK) {
                   if (der_length_sequence(data, size, &z) == CRYPT_OK) {

+ 55 - 30
src/pk/asn1/der/sequence/der_decode_sequence.c → src/pk/asn1/der/sequence/der_decode_sequence_ex.c

@@ -13,7 +13,7 @@
 
 
 
 
 /**
 /**
-  @file der_decode_sequence.c
+  @file der_decode_sequence_ex.c
   ASN.1 DER, decode a SEQUENCE, Tom St Denis
   ASN.1 DER, decode a SEQUENCE, Tom St Denis
 */
 */
 
 
@@ -25,10 +25,11 @@
    @param inlen    The size of the input
    @param inlen    The size of the input
    @param list     The list of items to decode
    @param list     The list of items to decode
    @param outlen   The number of items in the list
    @param outlen   The number of items in the list
+   @param ordered  Search an unordeded or ordered list
    @return CRYPT_OK on success
    @return CRYPT_OK on success
 */
 */
-int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
-                              ltc_asn1_list *list, unsigned long  outlen)
+int der_decode_sequence_ex(const unsigned char *in, unsigned long  inlen,
+                           ltc_asn1_list *list,     unsigned long  outlen, int ordered)
 {
 {
    int           err, type;
    int           err, type;
    unsigned long size, x, y, z, i, blksize;
    unsigned long size, x, y, z, i, blksize;
@@ -36,17 +37,18 @@ int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
 
 
    LTC_ARGCHK(in   != NULL);
    LTC_ARGCHK(in   != NULL);
    LTC_ARGCHK(list != NULL);
    LTC_ARGCHK(list != NULL);
-
+   
    /* get blk size */
    /* get blk size */
    if (inlen < 2) {
    if (inlen < 2) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
 
 
-   /* sequence type? */
+   /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
    x = 0;
    x = 0;
-   if (in[x++] != 0x30) {
+   if (in[x] != 0x30 && in[x] != 0x31) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
+   ++x;
 
 
    if (in[x] < 128) {
    if (in[x] < 128) {
       blksize = in[x++];
       blksize = in[x++];
@@ -73,12 +75,19 @@ int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
      return CRYPT_INVALID_PACKET;
      return CRYPT_INVALID_PACKET;
   }
   }
 
 
+   /* mark all as unused */
+   for (i = 0; i < outlen; i++) {
+       list[i].used = 0;
+   }     
+
   /* ok read data */
   /* ok read data */
    inlen = blksize;
    inlen = blksize;
    for (i = 0; i < outlen; i++) {
    for (i = 0; i < outlen; i++) {
+       z    = 0;
        type = list[i].type;
        type = list[i].type;
        size = list[i].size;
        size = list[i].size;
        data = list[i].data;
        data = list[i].data;
+       if (!ordered && list[i].used == 1) { continue; }
 
 
        if (type == LTC_ASN1_EOL) { 
        if (type == LTC_ASN1_EOL) { 
           break;
           break;
@@ -88,139 +97,155 @@ int der_decode_sequence(const unsigned char *in,   unsigned long  inlen,
            case LTC_ASN1_INTEGER:
            case LTC_ASN1_INTEGER:
                z = inlen;
                z = inlen;
                if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
                if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
+                  if (!ordered) {  continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
                if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
-
            case LTC_ASN1_SHORT_INTEGER:
            case LTC_ASN1_SHORT_INTEGER:
                z = inlen;
                z = inlen;
                if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
                if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               if ((err = der_length_short_integer(size, &z)) != CRYPT_OK) {
+               if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
+               
                break;
                break;
 
 
            case LTC_ASN1_BIT_STRING:
            case LTC_ASN1_BIT_STRING:
                z = inlen;
                z = inlen;
                if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
                if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                list[i].size = size;
                list[i].size = size;
                if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
                if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
            case LTC_ASN1_OCTET_STRING:
            case LTC_ASN1_OCTET_STRING:
                z = inlen;
                z = inlen;
                if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
                if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                list[i].size = size;
                list[i].size = size;
                if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
                if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
            case LTC_ASN1_NULL:
            case LTC_ASN1_NULL:
                if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
                if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
+                  if (!ordered) { continue; }
                   err = CRYPT_INVALID_PACKET;
                   err = CRYPT_INVALID_PACKET;
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += 2;
-               inlen -= 2;
+               z = 2;
                break;
                break;
                   
                   
            case LTC_ASN1_OBJECT_IDENTIFIER:
            case LTC_ASN1_OBJECT_IDENTIFIER:
                z = inlen;
                z = inlen;
                if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
                if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                list[i].size = size;
                list[i].size = size;
                if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
                if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_IA5_STRING:
                z = inlen;
                z = inlen;
                if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
                if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                list[i].size = size;
                list[i].size = size;
                if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
                if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
 
 
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
                z = inlen;
                z = inlen;
                if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
                if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                list[i].size = size;
                list[i].size = size;
                if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
                if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_UTCTIME:
                z = inlen;
                z = inlen;
                if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
                if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
+           case LTC_ASN1_SET:
+               z = inlen;
+               if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
+                  goto LBL_ERR;
+               }
+               if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               break;
+           
+           case LTC_ASN1_SETOF:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
                z = inlen;
                z = inlen;
                if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
                if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
                if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
 
 
            case LTC_ASN1_CHOICE:
            case LTC_ASN1_CHOICE:
                z = inlen;
                z = inlen;
                if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
                if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
+                  if (!ordered) { continue; }
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
-               x     += z;
-               inlen -= z;
                break;
                break;
 
 
            default:
            default:
                err = CRYPT_INVALID_ARG;
                err = CRYPT_INVALID_ARG;
                goto LBL_ERR;
                goto LBL_ERR;
        }
        }
+       x           += z;
+       inlen       -= z;
+       list[i].used = 1;
+       if (!ordered) { 
+          /* restart the decoder */
+          i = -1;
+       }          
    }
    }
+     
+   for (i = 0; i < outlen; i++) {
+      if (list[i].used == 0) {
+          err = CRYPT_INVALID_PACKET;
+          goto LBL_ERR;
+      }
+   }                
    err = CRYPT_OK;   
    err = CRYPT_OK;   
 
 
 LBL_ERR:
 LBL_ERR:

+ 4 - 3
src/pk/asn1/der/sequence/der_decode_sequence_flexi.c

@@ -12,7 +12,7 @@
 
 
 /**
 /**
   @file der_decode_sequence_flexi.c
   @file der_decode_sequence_flexi.c
-  ASN.1 DER, decode a SEQUENCE with a flexi parser, Tom St Denis
+  ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
 */
 */
 
 
 #ifdef LTC_DER
 #ifdef LTC_DER
@@ -268,9 +268,10 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
             break;
             break;
          
          
          case 0x30: /* SEQUENCE */
          case 0x30: /* SEQUENCE */
+         case 0x31: /* SET */
          
          
              /* init field */
              /* init field */
-             l->type = LTC_ASN1_SEQUENCE;
+             l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET;
              
              
              /* we have to decode the SEQUENCE header and get it's length */
              /* we have to decode the SEQUENCE header and get it's length */
              
              
@@ -280,7 +281,7 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
                 /* read length byte */
                 /* read length byte */
                 x = *in++; --(*inlen);
                 x = *in++; --(*inlen);
                 
                 
-                /* smallest SEQUENCE header */
+                /* smallest SEQUENCE/SET header */
                 y = 2;
                 y = 2;
                 
                 
                 /* now if it's > 127 the next bytes are the length of the length */
                 /* now if it's > 127 the next bytes are the length of the length */

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

@@ -51,6 +51,8 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_IA5_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_UTCTIME:
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_CHOICE:
            case LTC_ASN1_CHOICE:
                 ++x; 
                 ++x; 
@@ -96,6 +98,8 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:          
            case LTC_ASN1_CHOICE:
            case LTC_ASN1_CHOICE:
                 list[x].type   = type;
                 list[x].type   = type;
                 list[x].size   = size;
                 list[x].size   = size;

+ 28 - 7
src/pk/asn1/der/sequence/der_encode_sequence.c → src/pk/asn1/der/sequence/der_encode_sequence_ex.c

@@ -13,7 +13,7 @@
 
 
 
 
 /**
 /**
-  @file der_encode_sequence.c
+  @file der_encode_sequence_ex.c
   ASN.1 DER, encode a SEQUENCE, Tom St Denis
   ASN.1 DER, encode a SEQUENCE, Tom St Denis
 */
 */
 
 
@@ -25,10 +25,11 @@
    @param inlen     The number of items in the list
    @param inlen     The number of items in the list
    @param out       [out] The destination 
    @param out       [out] The destination 
    @param outlen    [in/out] The size of the output
    @param outlen    [in/out] The size of the output
+   @param type_of   LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
    @return CRYPT_OK on success
    @return CRYPT_OK on success
 */
 */
-int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
-                        unsigned char *out,  unsigned long *outlen) 
+int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
+                           unsigned char *out,  unsigned long *outlen, int type_of) 
 {
 {
    int           err, type;
    int           err, type;
    unsigned long size, x, y, z, i;
    unsigned long size, x, y, z, i;
@@ -110,13 +111,14 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
                y += x;
                y += x;
                break;
                break;
 
 
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                y += x;
                y += x;
                break;
                break;
-
           
           
            default:
            default:
                err = CRYPT_INVALID_ARG;
                err = CRYPT_INVALID_ARG;
@@ -150,7 +152,8 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
 
 
    /* store header */
    /* store header */
    x = 0;
    x = 0;
-   out[x++] = 0x30;
+   out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
+      
    if (z < 128) {
    if (z < 128) {
       out[x++] = z;
       out[x++] = z;
    } else if (z < 256) {
    } else if (z < 256) {
@@ -257,15 +260,33 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
                *outlen -= z;
                *outlen -= z;
                break;
                break;
 
 
-           case LTC_ASN1_SEQUENCE:
+           case LTC_ASN1_SET:
+               z = *outlen;
+               if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+
+           case LTC_ASN1_SETOF:
                z = *outlen;
                z = *outlen;
-               if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) {
+               if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
                }
                }
                x       += z;
                x       += z;
                *outlen -= z;
                *outlen -= z;
                break;
                break;
 
 
+           case LTC_ASN1_SEQUENCE:
+               z = *outlen;
+               if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
+                  goto LBL_ERR;
+               }
+               x       += z;
+               *outlen -= z;
+               break;
+           
            default:
            default:
                err = CRYPT_INVALID_ARG;
                err = CRYPT_INVALID_ARG;
                goto LBL_ERR;
                goto LBL_ERR;

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

@@ -53,6 +53,8 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:
                 ++x; 
                 ++x; 
                 break;
                 break;
           
           
@@ -96,6 +98,8 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_PRINTABLE_STRING:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_UTCTIME:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:
                 list[x].type   = type;
                 list[x].type   = type;
                 list[x].size   = size;
                 list[x].size   = size;
                 list[x++].data = data;
                 list[x++].data = data;

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

@@ -9,8 +9,6 @@
  * Tom St Denis, [email protected], http://libtomcrypt.org
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
  */
 #include "tomcrypt.h"
 #include "tomcrypt.h"
-#include <stdarg.h>
-
 
 
 /**
 /**
   @file der_length_sequence.c
   @file der_length_sequence.c
@@ -108,6 +106,8 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
                y += x;
                y += x;
                break;
                break;
 
 
+           case LTC_ASN1_SET:
+           case LTC_ASN1_SETOF:
            case LTC_ASN1_SEQUENCE:
            case LTC_ASN1_SEQUENCE:
                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
                   goto LBL_ERR;
                   goto LBL_ERR;
@@ -149,3 +149,7 @@ LBL_ERR:
 }
 }
 
 
 #endif
 #endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

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

@@ -44,6 +44,8 @@ void der_sequence_free(ltc_asn1_list *in)
       }
       }
       
       
       switch (in->type) { 
       switch (in->type) { 
+         case LTC_ASN1_SET:
+         case LTC_ASN1_SETOF:
          case LTC_ASN1_SEQUENCE: break;
          case LTC_ASN1_SEQUENCE: break;
          case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
          case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
          default               : if (in->data != NULL) { XFREE(in->data);    }
          default               : if (in->data != NULL) { XFREE(in->data);    }

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

@@ -0,0 +1,93 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+  * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_set.c
+  ASN.1 DER, Encode a SET, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+/* LTC define to ASN.1 TAG */
+static int ltc_to_asn1(int v)
+{
+   switch (v) {
+      case LTC_ASN1_INTEGER:
+      case LTC_ASN1_SHORT_INTEGER:           return 0x02;
+      case LTC_ASN1_BIT_STRING:              return 0x03;
+      case LTC_ASN1_OCTET_STRING:            return 0x04;
+      case LTC_ASN1_NULL:                    return 0x05;
+      case LTC_ASN1_OBJECT_IDENTIFIER:       return 0x06;
+      case LTC_ASN1_PRINTABLE_STRING:        return 0x13;
+      case LTC_ASN1_IA5_STRING:              return 0x16;
+      case LTC_ASN1_UTCTIME:                 return 0x17;
+      case LTC_ASN1_SEQUENCE:                return 0x30;
+      case LTC_ASN1_SET:
+      case LTC_ASN1_SETOF:                   return 0x31;
+      default: return -1;
+   }
+}         
+      
+
+static int qsort_helper(const void *a, const void *b)
+{
+   ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
+   int            r;
+   
+   r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
+   
+   /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC.  So we force it to be :-) */
+   if (r == 0) {
+      /* their order in the original list now determines the position */
+      return A->used - B->used;
+   } else {
+      return r;
+   }
+}   
+
+int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
+                   unsigned char *out,  unsigned long *outlen)
+{
+   ltc_asn1_list  *copy;
+   unsigned long   x;
+   int             err;
+   
+   /* make copy of list */
+   copy = XCALLOC(inlen, sizeof(*copy));
+   if (copy == NULL) {
+      return CRYPT_MEM;
+   }      
+   
+   /* fill in used member with index so we can fully sort it */
+   for (x = 0; x < inlen; x++) {
+       copy[x]      = list[x];
+       copy[x].used = x;
+   }       
+   
+   /* sort it by the "type" field */
+   XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);   
+   
+   /* call der_encode_sequence_ex() */
+   err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);   
+   
+   /* free list */
+   XFREE(copy);
+   
+   return err;
+}                   
+
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 154 - 0
src/pk/asn1/der/set/der_encode_setof.c

@@ -0,0 +1,154 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "tomcrypt.h"
+
+/**
+  @file der_encode_setof.c
+  ASN.1 DER, Encode SET OF, Tom St Denis
+*/
+
+#ifdef LTC_DER
+
+struct edge {
+   unsigned char *start;
+   unsigned long  size;
+};
+
+static int qsort_helper(const void *a, const void *b)
+{
+   struct edge   *A = (struct edge *)a, *B = (struct edge *)b;
+   int            r;
+   unsigned long  x;
+   
+   /* compare min length */
+   r = XMEMCMP(A->start, B->start, MIN(A->size, B->size));
+   
+   if (r == 0 && A->size != B->size) {
+      if (A->size > B->size) {
+         for (x = B->size; x < A->size; x++) {
+            if (A->start[x]) {
+               return 1;
+            }
+         }
+      } else {
+         for (x = A->size; x < B->size; x++) {
+            if (B->start[x]) {
+               return -1;
+            }
+         }
+      }         
+   }
+   
+   return r;      
+}
+
+int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
+                     unsigned char *out,  unsigned long *outlen)
+{
+   unsigned long  x, y, z, hdrlen;
+   int            err;
+   struct edge   *edges;
+   unsigned char *ptr, *buf;
+   
+   /* check that they're all the same type */
+   for (x = 1; x < inlen; x++) {
+      if (list[x].type != list[x-1].type) {
+         return CRYPT_INVALID_ARG;
+      }
+   }
+
+   /* alloc buffer to store copy of output */
+   buf = XCALLOC(1, *outlen);
+   if (buf == NULL) {
+      return CRYPT_MEM;
+   }      
+                  
+   /* encode list */
+   if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) {
+       XFREE(buf);
+       return err;
+   }
+   
+   /* allocate edges */
+   edges = XCALLOC(inlen, sizeof(*edges));
+   if (edges == NULL) {
+      XFREE(buf);
+      return CRYPT_MEM;
+   }      
+   
+   /* skip header */
+      ptr = buf + 1;
+
+      /* now skip length data */
+      x = *ptr++;
+      if (x >= 0x80) {
+         ptr += (x & 0x7F);
+      }
+      
+      /* get the size of the static header */
+      hdrlen = ((unsigned long)ptr) - ((unsigned long)buf);
+      
+      
+   /* scan for edges */
+   x = 0;
+   while (ptr < (buf + *outlen)) {
+      /* store start */
+      edges[x].start = ptr;
+      
+      /* skip type */
+      z = 1;
+      
+      /* parse length */
+      y = ptr[z++];
+      if (y < 128) {
+         edges[x].size = y;
+      } else {
+         y &= 0x7F;
+         edges[x].size = 0;
+         while (y--) {
+            edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]);
+         }
+      }
+      
+      /* skip content */
+      edges[x].size += z;
+      ptr           += edges[x].size;
+      ++x;
+   }      
+      
+   /* sort based on contents (using edges) */
+   XQSORT(edges, inlen, sizeof(*edges), &qsort_helper);
+   
+   /* copy static header */
+   XMEMCPY(out, buf, hdrlen);
+   
+   /* copy+sort using edges+indecies to output from buffer */
+   for (y = hdrlen, x = 0; x < inlen; x++) {
+      XMEMCPY(out+y, edges[x].start, edges[x].size);
+      y += edges[x].size;
+   }      
+   
+#ifdef LTC_CLEAN_STACK
+   zeromem(buf, *outlen);
+#endif      
+   
+   /* free buffers */
+   XFREE(edges);
+   XFREE(buf);
+   
+   return CRYPT_OK;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision$ */
+/* $Date$ */

+ 2 - 1
src/pk/asn1/der/short_integer/der_length_short_integer.c

@@ -39,7 +39,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen)
      ++z;
      ++z;
      y >>= 8;
      y >>= 8;
    }
    }
-
+   
    /* handle zero */
    /* handle zero */
    if (z == 0) {
    if (z == 0) {
       z = 1;
       z = 1;
@@ -59,6 +59,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen)
 
 
    /* return length */
    /* return length */
    *outlen = len; 
    *outlen = len; 
+   
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 

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

@@ -15,7 +15,7 @@
   DSA Crypto, Tom St Denis
   DSA Crypto, Tom St Denis
 */  
 */  
 
 
-#ifdef MECC
+#ifdef MDSA
 
 
 /**
 /**
   Decrypt an DSA encrypted key
   Decrypt an DSA encrypted key

+ 1 - 1
src/pk/rsa/rsa_decrypt_key.c

@@ -70,7 +70,7 @@ int rsa_decrypt_key(const unsigned char *in,       unsigned long  inlen,
 
 
   /* rsa decode the packet */
   /* rsa decode the packet */
   x = inlen;
   x = inlen;
-  if ((err = rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
+  if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
      XFREE(tmp);
      XFREE(tmp);
      return err;
      return err;
   }
   }

+ 1 - 1
src/pk/rsa/rsa_encrypt_key.c

@@ -70,7 +70,7 @@ int rsa_encrypt_key(const unsigned char *in,     unsigned long inlen,
   }                                
   }                                
 
 
   /* rsa exptmod the OAEP pad */
   /* rsa exptmod the OAEP pad */
-  return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key);
+  return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key);
 }
 }
 
 
 #endif /* MRSA */
 #endif /* MRSA */

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

@@ -35,11 +35,6 @@ int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
    unsigned long x;
    unsigned long x;
    int           err;
    int           err;
 
 
-   /* Try the accelerator if present */
-   if (ltc_mp.rsa_me != NULL) {
-      return ltc_mp.rsa_me(in, inlen, out, outlen, which, key);
-   }
-
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(in     != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(out    != NULL);
    LTC_ARGCHK(outlen != NULL);
    LTC_ARGCHK(outlen != NULL);

+ 0 - 7
src/pk/rsa/rsa_make_key.c

@@ -32,14 +32,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
    int    err;
    int    err;
 
 
    LTC_ARGCHK(ltc_mp.name != NULL);
    LTC_ARGCHK(ltc_mp.name != NULL);
-
-   /* check for descriptor */
-   if (ltc_mp.rsa_keygen != NULL) {
-      return ltc_mp.rsa_keygen(prng, wprng, size, e, key);
-   }
-   
    LTC_ARGCHK(key != NULL);
    LTC_ARGCHK(key != NULL);
-  
 
 
    if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
    if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
       return CRYPT_INVALID_KEYSIZE;
       return CRYPT_INVALID_KEYSIZE;

+ 1 - 1
src/pk/rsa/rsa_sign_hash.c

@@ -69,7 +69,7 @@ int rsa_sign_hash(const unsigned char *in,       unsigned long  inlen,
   }
   }
 
 
   /* RSA encode it */
   /* RSA encode it */
-  return rsa_exptmod(out, x, out, outlen, PK_PRIVATE, key);
+  return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key);
 }
 }
 
 
 #endif /* MRSA */
 #endif /* MRSA */

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

@@ -68,7 +68,7 @@ int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
       
       
   /* RSA decode it  */
   /* RSA decode it  */
   x = siglen;
   x = siglen;
-  if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
+  if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
      XFREE(tmpbuf);
      XFREE(tmpbuf);
      return err;
      return err;
   }
   }

+ 156 - 8
testprof/der_tests.c

@@ -10,6 +10,98 @@ int der_tests(void)
 
 
 #else
 #else
 
 
+static void der_set_test(void)
+{
+   ltc_asn1_list list[10];
+   static const unsigned char oct_str[] = { 1, 2, 3, 4 };
+   static const unsigned char bin_str[] = { 1, 0, 0, 1 };
+   static const unsigned long int_val   = 12345678UL;
+
+   unsigned char strs[10][10], outbuf[128];
+   unsigned long x, val, outlen;
+   int           err;
+   
+   /* make structure and encode it */
+   LTC_SET_ASN1(list, 0, LTC_ASN1_OCTET_STRING,  oct_str, sizeof(oct_str));
+   LTC_SET_ASN1(list, 1, LTC_ASN1_BIT_STRING,    bin_str, sizeof(bin_str));
+   LTC_SET_ASN1(list, 2, LTC_ASN1_SHORT_INTEGER, &int_val, 1);
+   
+   /* encode it */
+   outlen = sizeof(outbuf);
+   if ((err = der_encode_set(list, 3, outbuf, &outlen)) != CRYPT_OK) {
+      fprintf(stderr, "error encoding set: %s\n", error_to_string(err));
+      exit(EXIT_FAILURE);
+   }
+   
+  
+   /* first let's test the set_decoder out of order to see what happens, we should get all the fields we expect even though they're in a diff order */
+   LTC_SET_ASN1(list, 0, LTC_ASN1_BIT_STRING,    strs[1], sizeof(strs[1]));
+   LTC_SET_ASN1(list, 1, LTC_ASN1_SHORT_INTEGER, &val, 1);
+   LTC_SET_ASN1(list, 2, LTC_ASN1_OCTET_STRING,  strs[0], sizeof(strs[0]));
+   
+   if ((err = der_decode_set(outbuf, outlen, list, 3)) != CRYPT_OK) {
+      fprintf(stderr, "error decoding set using der_decode_set: %s\n", error_to_string(err));
+      exit(EXIT_FAILURE);
+   }
+   
+   /* now compare the items */
+   if (memcmp(strs[0], oct_str, sizeof(oct_str))) {
+      fprintf(stderr, "error decoding set using der_decode_set (oct_str is wrong):\n");
+      exit(EXIT_FAILURE);
+   }
+      
+   if (memcmp(strs[1], bin_str, sizeof(bin_str))) {
+      fprintf(stderr, "error decoding set using der_decode_set (bin_str is wrong):\n");
+      exit(EXIT_FAILURE);
+   }
+   
+   if (val != int_val) {
+      fprintf(stderr, "error decoding set using der_decode_set (int_val is wrong):\n");
+      exit(EXIT_FAILURE);
+   }
+   
+   strcpy(strs[0], "one");
+   strcpy(strs[1], "one2");
+   strcpy(strs[2], "two");
+   strcpy(strs[3], "aaa");
+   strcpy(strs[4], "aaaa");
+   strcpy(strs[5], "aab");
+   strcpy(strs[6], "aaab");
+   strcpy(strs[7], "bbb");
+   strcpy(strs[8], "bbba");
+   strcpy(strs[9], "bbbb");
+   
+   for (x = 0; x < 10; x++) {
+       LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], strlen(strs[x]));
+   }
+   
+   outlen = sizeof(outbuf);
+   if ((err = der_encode_setof(list, 10, outbuf, &outlen)) != CRYPT_OK) {       
+      fprintf(stderr, "error encoding SET OF: %s\n", error_to_string(err));
+      exit(EXIT_FAILURE);
+   }
+   
+   for (x = 0; x < 10; x++) {
+       LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], sizeof(strs[x]) - 1);
+   }
+   XMEMSET(strs, 0, sizeof(strs));
+   
+   if ((err = der_decode_set(outbuf, outlen, list, 10)) != CRYPT_OK) {
+      fprintf(stderr, "error decoding SET OF: %s\n", error_to_string(err));
+      exit(EXIT_FAILURE);
+   }
+   
+   /* now compare */
+   for (x = 1; x < 10; x++) {
+      if (!(strlen(strs[x-1]) <= strlen(strs[x])) && strcmp(strs[x-1], strs[x]) >= 0) {
+         fprintf(stderr, "error SET OF order at %d is wrong\n", x);
+         exit(EXIT_FAILURE);
+      }
+   }      
+   
+}
+
+
 /* we are encoding 
 /* we are encoding 
 
 
   SEQUENCE {
   SEQUENCE {
@@ -24,6 +116,9 @@ int der_tests(void)
            SEQUENCE {
            SEQUENCE {
               OID       { 1, 2, 840, 113549 }
               OID       { 1, 2, 840, 113549 }
               NULL
               NULL
+              SET OF {
+                 PRINTABLE "333"  // WILL GET SORTED
+                 PRINTABLE "222"
            }
            }
         }
         }
      }
      }
@@ -34,6 +129,8 @@ int der_tests(void)
 static void der_flexi_test(void)
 static void der_flexi_test(void)
 {
 {
    static const char printable_str[]    = "printable";
    static const char printable_str[]    = "printable";
+   static const char set1_str[]         = "333";
+   static const char set2_str[]         = "222";
    static const char ia5_str[]          = "ia5";
    static const char ia5_str[]          = "ia5";
    static const unsigned long int_val   = 12345678UL;
    static const unsigned long int_val   = 12345678UL;
    static const ltc_utctime   utctime   = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
    static const ltc_utctime   utctime   = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
@@ -41,11 +138,11 @@ static void der_flexi_test(void)
    static const unsigned char bit_str[] = { 1, 0, 0, 1 };
    static const unsigned char bit_str[] = { 1, 0, 0, 1 };
    static const unsigned long oid_str[] = { 1, 2, 840, 113549 };
    static const unsigned long oid_str[] = { 1, 2, 840, 113549 };
    
    
-   unsigned char encode_buf[128];
+   unsigned char encode_buf[192];
    unsigned long encode_buf_len, decode_len;
    unsigned long encode_buf_len, decode_len;
    int           err;
    int           err;
    
    
-   ltc_asn1_list static_list[4][3], *decoded_list, *l;
+   ltc_asn1_list static_list[5][3], *decoded_list, *l;
    
    
    /* build list */
    /* build list */
    LTC_SET_ASN1(static_list[0], 0, LTC_ASN1_PRINTABLE_STRING, (void *)printable_str, strlen(printable_str));
    LTC_SET_ASN1(static_list[0], 0, LTC_ASN1_PRINTABLE_STRING, (void *)printable_str, strlen(printable_str));
@@ -58,11 +155,15 @@ static void der_flexi_test(void)
 
 
    LTC_SET_ASN1(static_list[2], 0, LTC_ASN1_OCTET_STRING,     (void *)oct_str,          4);
    LTC_SET_ASN1(static_list[2], 0, LTC_ASN1_OCTET_STRING,     (void *)oct_str,          4);
    LTC_SET_ASN1(static_list[2], 1, LTC_ASN1_BIT_STRING,       (void *)bit_str,          4);
    LTC_SET_ASN1(static_list[2], 1, LTC_ASN1_BIT_STRING,       (void *)bit_str,          4);
-   LTC_SET_ASN1(static_list[2], 2, LTC_ASN1_SEQUENCE,         static_list[3],   2);
+   LTC_SET_ASN1(static_list[2], 2, LTC_ASN1_SEQUENCE,         static_list[3],   3);
 
 
    LTC_SET_ASN1(static_list[3], 0, LTC_ASN1_OBJECT_IDENTIFIER,(void *)oid_str,          4);
    LTC_SET_ASN1(static_list[3], 0, LTC_ASN1_OBJECT_IDENTIFIER,(void *)oid_str,          4);
    LTC_SET_ASN1(static_list[3], 1, LTC_ASN1_NULL,             NULL,             0);
    LTC_SET_ASN1(static_list[3], 1, LTC_ASN1_NULL,             NULL,             0);
-   
+   LTC_SET_ASN1(static_list[3], 2, LTC_ASN1_SETOF,            static_list[4],   2);
+
+   LTC_SET_ASN1(static_list[4], 0, LTC_ASN1_PRINTABLE_STRING, set1_str, strlen(set1_str));
+   LTC_SET_ASN1(static_list[4], 1, LTC_ASN1_PRINTABLE_STRING, set2_str, strlen(set2_str));
+
    /* encode it */
    /* encode it */
    encode_buf_len = sizeof(encode_buf);
    encode_buf_len = sizeof(encode_buf);
    if ((err = der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len)) != CRYPT_OK) {
    if ((err = der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len)) != CRYPT_OK) {
@@ -292,6 +393,55 @@ static void der_flexi_test(void)
          fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
          fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
          exit(EXIT_FAILURE);
          exit(EXIT_FAILURE);
       }
       }
+      
+      /* move to next */
+      l = l->next;
+      
+   /* expect child anve move down */
+      if (l->next != NULL || l->child == NULL) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+      
+      if (l->type != LTC_ASN1_SET) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+      l = l->child;
+      
+   /* PRINTABLE STRING */
+      /* we expect printable_str */
+      if (l->next == NULL || l->child != NULL) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+   
+      if (l->type != LTC_ASN1_PRINTABLE_STRING) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+   
+/* note we compare set2_str FIRST because the SET OF is sorted and "222" comes before "333" */   
+      if (l->size != strlen(set2_str) || memcmp(set2_str, l->data, l->size)) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+   
+      /* move to next */
+      l = l->next;
+
+   /* PRINTABLE STRING */
+      /* we expect printable_str */
+      if (l->type != LTC_ASN1_PRINTABLE_STRING) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+   
+      if (l->size != strlen(set1_str) || memcmp(set1_str, l->data, l->size)) {
+         fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child);
+         exit(EXIT_FAILURE);
+      }
+   
 
 
    der_sequence_free(l);
    der_sequence_free(l);
 
 
@@ -379,8 +529,6 @@ 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_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 unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a };
 
 
-   der_flexi_test();
-
    DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));
    DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL));
    for (zz = 0; zz < 16; zz++) {
    for (zz = 0; zz < 16; zz++) {
 #ifdef USE_TFM
 #ifdef USE_TFM
@@ -651,8 +799,8 @@ tmp_time.off_hh);
       return 1;
       return 1;
    }
    }
 
 
-
-
+   der_set_test();
+   der_flexi_test();
    return der_choice_test();
    return der_choice_test();
 }
 }