added libtomcrypt-1.05

This commit is contained in:
Tom St Denis 2005-06-27 11:47:35 +00:00 committed by Steffen Jaeckel
parent 9da48eb84b
commit 9264e34ffb
49 changed files with 1008 additions and 109 deletions

View File

@ -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.04
PROJECT_NUMBER = 1.05
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

18
TODO
View File

@ -1,10 +1,10 @@
Things ideal for 1.05
- ASN.1 SET and UTCtime and CHOICE (hint for choice do it as a sep list and just use error codes to know when you got a hit)
- Start working towards making the bignum code plugable
- Add OID for ciphers and PRNGs to their descriptors
- Document the ASN.1 a bit more verbosely ;-)
- Some ASN.1 demo programs [for now read the source code!]
- export ECC functions globally
- Look into other ECC point muls and consider a "precomp" interface
For 1.06
1. export ECC functions globally [e.g. mulmod and the sets]
- goal is tv_gen module and test vectors
2. ASN.1 SET and T61String
3. phase out DH code [RSA/ECC/DSA is enough]
4. Some ASN.1 demo programs [for now read the source code!]
5. Start working towards making the bignum code plugable
6. Look into other ECC point muls and consider a "precomp" interface
7. Add OID for ciphers and PRNGs to their descriptors

View File

@ -2,7 +2,7 @@
echo "$1 ($2, $3)..."
make clean 1>/dev/null 2>/dev/null
echo -n "building..."
CFLAGS="$2 $CFLAGS" make -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1)
CFLAGS="$2 $CFLAGS" make -j3 -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1)
echo -n "testing..."
if [ -a test ] && [ -f test ] && [ -x test ]; then
((./test >test_std.txt 2>test_err.txt && ./tv_gen > tv.txt) && echo "$1 test passed." && echo "y" > testok.txt) || (echo "$1 test failed" && cat test_err.txt && exit 1)
@ -16,5 +16,5 @@ fi
exit 1
# $Source: /cvs/libtom/libtomcrypt/build.sh,v $
# $Revision: 1.4 $
# $Date: 2005/05/05 14:49:27 $
# $Revision: 1.5 $
# $Date: 2005/06/27 13:04:05 $

17
changes
View File

@ -1,3 +1,16 @@
June 27th, 2005
v1.05
-- Added Technote #6 which covers the current PK compliance.
-- Fixed buffer overflow in OAEP decoder
-- Added CHOICE to the list of ASN.1 types
-- Added UTCTIME to the list of ASN.1 types
-- Added MUTEX locks around descriptor table functions [but not on the functions that are dependent on them]
All functions call *_is_valid() before using a descriptor index which means the respective table must be unlocked before
it can be accessed. However, during the operation [e.g. CCM] if the descriptor has been altered the results will be
undefined.
-- Minor updates to the manual to reflect recent changes
-- Added a catch to for an error that should never come up in rsa_exptmod(). Just being thorough.
June 15th, 2005
v1.04
-- Fixed off by one [bit] error in dsa_make_key() it was too high by one bit [not a security problem just inconsistent]
@ -1308,6 +1321,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.97 $ */
/* $Date: 2005/06/14 23:09:41 $ */
/* $Revision: 1.106 $ */
/* $Date: 2005/06/27 12:37:06 $ */

104
crypt.tex
View File

@ -47,7 +47,7 @@
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{LibTomCrypt \\ Version 1.04}
\title{LibTomCrypt \\ Version 1.05}
\author{Tom St Denis \\
\\
tomstdenis@gmail.com \\
@ -3051,8 +3051,8 @@ int ecc_make_key(prng_state *prng, int wprng,
int keysize, ecc_key *key);
\end{verbatim}
The ``keysize'' is the size of the modulus in bytes desired. Currently directly supported values are 20, 24, 28, 32, 48 and 65 bytes which
correspond to key sizes of 160, 192, 224, 256, 384 and 521 bits respectively. If you pass a key size that is between any key size
The ``keysize'' is the size of the modulus in bytes desired. Currently directly supported values are 24, 28, 32, 48 and 65 bytes which
correspond to key sizes of 192, 224, 256, 384 and 521 bits respectively. If you pass a key size that is between any key size
it will round the keysize up to the next available one. The rest of the parameters work like they do in the ``dh\_make\_key()'' function.
To free the ram allocated by a key call:
\index{ecc\_free()}
@ -3150,8 +3150,8 @@ The signature code is an implementation of X9.62 EC-DSA and the output is comfor
\section{ECC Keysizes}
With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems. The math will still work
and in effect the signature will still work. With ECC keys the strength of the signature is limited by the size of
the hash or the size of they key, whichever is smaller. For example, if you sign with SHA256 and a ECC-160 key in effect
you have 160-bits of security (e.g. as if you signed with SHA-1).
the hash or the size of they key, whichever is smaller. For example, if you sign with SHA256 and an ECC-192 key in effect
you have 192-bits of security.
The library will not warn you if you make this mistake so it is important to check yourself before using the
signatures.
@ -3324,7 +3324,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
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.04} 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\footnote{Planned for LTC 1.06} SET data types which are collections of other ASN.1 types. They are provided
in the same manner as the other data types except they use list of objects known as the \textbf{ltc\_asn1\_list} structure. It is defined as
\index{ltc\_asn1\_list structure}
@ -3333,11 +3333,13 @@ typedef struct {
int type;
void *data;
unsigned long size;
int used;
} ltc_asn1_list;
\end{verbatim}
The ``type'' field is one of the following ASN.1 field definitions. The ``data'' pointer is a void pointer to the data to be encoded (or the destination) and the
``size'' field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type). To help build the lists in an orderly fashion the macro
``size'' field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type). The ``used'' field is primarily for the CHOICE decoder
and reflects if the particular member of a list was the decoded data type. To help build the lists in an orderly fashion the macro
``LTC\_SET\_ASN1(list, index, Type, Data, Size)'' has been provided.
It will assign to the ``index''th position in the ``list'' the tripplet (Type, Data, Size). An example usage would be:
@ -3382,7 +3384,9 @@ LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL, NULL, 0);
\hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER (words are in unsigned long) \\
\hline LTC\_ASN1\_IA5\_STRING & IA5 STRING (one octet per char) \\
\hline LTC\_ASN1\_PRINTABLE\_STRING & PRINTABLE STIRNG (one octet per char) \\
\hline LTC\_ASN1\_UTCTIME & UTCTIME (see ltc\_utctime structure) \\
\hline LTC\_ASN1\_SEQUENCE & SEQUENCE OF \\
\hline LTC\_ASN1\_CHOICE & CHOICE \\
\hline
\end{tabular}
\caption{List of ASN.1 Supported Types}
@ -3466,7 +3470,7 @@ 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
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.
\subsubsection{ASN.1 INTEGER}
\subsection{ASN.1 INTEGER}
To encode or decode INTEGER data types use the following functions.
@ -3498,7 +3502,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen);
These will encode or decode an unsigned \textbf{unsigned long} type (only reads upto 32--bits). For values in the range $0 \dots 2^{32} - 1$ the integer
and short integer functions can encode and decode each others outputs.
\subsubsection{ASN.1 BIT STRING}
\subsection{ASN.1 BIT STRING}
\index{der\_encode\_bit\_string()}
\index{der\_decode\_bit\_string()}
@ -3516,7 +3520,7 @@ int der_length_bit_string(unsigned long nbits, unsigned long *outlen);
These will encode or decode a BIT STRING data type. The bits are passed in (or read out) using one \textbf{char} per bit. A non--zero value will be interpretted
as a one bit and a zero value a zero bit.
\subsubsection{ASN.1 OCTET STRING}
\subsection{ASN.1 OCTET STRING}
\index{der\_encode\_octet\_string()}
\index{der\_decode\_octet\_string()}
@ -3533,7 +3537,7 @@ int der_length_octet_string(unsigned long noctets, unsigned long *outlen);
These will encode or decode an OCTET STRING data type. The octets are stored using one \textbf{char} each.
\subsubsection{ASN.1 OBJECT IDENTIFIER}
\subsection{ASN.1 OBJECT IDENTIFIER}
\index{der\_encode\_object\_identifier()}
\index{der\_decode\_object\_identifier()}
@ -3552,7 +3556,7 @@ int der_length_object_identifier(unsigned long *words, unsigned long nwords,
These will encode or decode an OBJECT IDENTIFIER object. The words of the OID are stored in individual \textbf{unsigned long} elements and must be in the range
$0 \ldots 2^{32} - 1$.
\subsubsection{ASN.1 IA5 STRING}
\subsection{ASN.1 IA5 STRING}
\index{der\_encode\_ia5\_string()}
\index{der\_decode\_ia5\_string()}
@ -3575,7 +3579,7 @@ that the build platform honours the runtime platforms character conventions.
If you're worried try building the test suite and running it. It has hard coded test vectors to ensure it is operating properly.
\subsubsection{ASN.1 PRINTABLE STRING}
\subsection{ASN.1 PRINTABLE STRING}
\index{der\_encode\_printable\_string()}
\index{der\_decode\_printable\_string()}
@ -3598,6 +3602,64 @@ that the build platform honours the runtime platforms character conventions.
If you're worried try building the test suite and running it. It has hard coded test vectors to ensure it is operating properly.
\subsection{ASN.1 UTCTIME}
The UTCTIME type is to store a date and time in ASN.1 format. It uses the following structure to organize the time.
\begin{verbatim}
typedef struct {
unsigned YY, /* year 00--99 */
MM, /* month 01--12 */
DD, /* day 01--31 */
hh, /* hour 00--23 */
mm, /* minute 00--59 */
ss, /* second 00--59 */
off_dir, /* timezone offset direction 0 == +, 1 == - */
off_hh, /* timezone offset hours */
off_mm; /* timezone offset minutes */
} ltc_utctime;
\end{verbatim}
The time can be offset plus or minus a set amount of hours (off\_hh) and minutes (off\_mm). When ``off\_dir'' is zero the time will be added otherwise it
will be subtracted.
For instance, the array $\lbrace 5, 6, 20, 22, 4, 00, 0, 5, 0 \rbrace$ represents the current time of 2005, June 20th, 22:04:00 with a time offset of +05h00.
\index{der\_encode\_utctime()}
\index{der\_decode\_utctime()}
\index{der\_length\_utctime()}
\begin{verbatim}
int der_encode_utctime(ltc_utctime *utctime,
unsigned char *out, unsigned long *outlen);
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
ltc_utctime *out);
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
\end{verbatim}
The encoder will store time in one of the two ASN.1 formats, either ``YYMMDDhhmmssZ'' or ``YYMMDDhhmmss$\pm$hhmm'' and perform minimal error checking on the
input. The decoder will read all valid ASN.1 formats and perform range checking on the values (not complete but rational) useful for catching packet errors.
It is suggested that decoded data be further scrutinized (e.g. days of month in particular).
\subsection{ASN.1 CHOICE}
The CHOICE ASN.1 type represents a union of ASN.1 types all of which are stored in a ``ltc\_asn1\_list''. There is no encoder for the CHOICE type, only a
decoder. The decoder will scan through the provided list attempting to use the appropriate decoder on the input packet. The list can contain any ASN.1 data
type\footnote{Except it cannot have LTC\_ASN1\_INTEGER and LTC\_ASN1\_SHORT\_INTEGER simultaneously.} except for other CHOICE types.
There is no encoder for the CHOICE type as the actual DER encoding is the encoding of the chosen type.
\index{der\_decode\_choice()}
\begin{verbatim}
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list *list, unsigned long outlen);
\end{verbatim}
This will decode the input in the ``in'' field of length ``inlen''. It uses the provided ASN.1 list specified in the ``list'' field which has ``outlen'' elements.
The ``inlen'' field will be updated with the length of the decoded data type as well as the respective entry in the ``list'' field will have the ``used'' flag
set to non--zero to reflect it was the data type decoded.
\section{Password Based Cryptography}
\subsection{PKCS \#5}
@ -3871,7 +3933,6 @@ $n$ it requires $\sqrt n$ work. The following table sumarizes the work required
\begin{center}
\begin{tabular}{|c|c|}
\hline ECC Key Size (bits) & Work Factor ($log_2$) \\
\hline 160 & 80 \\
\hline 192 & 96 \\
\hline 224 & 112 \\
\hline 256 & 128 \\
@ -4029,8 +4090,8 @@ will increase by approximately 500 bytes. If this is defined but TWOFISH\_SMALL
it will not speed up the encryption or decryption functions.
\subsection{GCM\_TABLES}
When defined GCM will use a 64KB table (per GCM state) which will greatly lower up the per--packet latency.
It also increases the initialization time.
When defined GCM will use a 64KB table (per GCM state) which will greatly speed up the per--packet latency.
It also increases the initialization time and isn't suitable when you are going to use a key a few times only.
\subsection{SMALL\_CODE}
When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants.
@ -4061,6 +4122,13 @@ data type you can perform integer operations with. Ideally it should be four or
of your block cipher (e.g. 16 bytes for AES). This means sadly if you're on a platform with 57--bit words (or something) you can't
use this mode. So sad.
\subsection{LTC\_PTHREAD}
When this is activated all of the descriptor table functions will use pthread locking to ensure thread safe updates to the tables. Note that
it doesn't prevent a thread that is passively using a table from being messed up by another thread that updates the table.
Generally the rule of thumb is to setup the tables once at startup and then leave them be. This added build flag simply makes updating
the tables safer.
\section{MPI Tweaks}
\subsection{RSA Only Tweak}
If you plan on only using RSA with moduli in the range of 1024 to 2560 bits you can enable a series of tweaks
@ -4491,5 +4559,5 @@ but should at least maintain the same level of state entropy.
\end{document}
% $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $
% $Revision: 1.33 $
% $Date: 2005/06/14 22:53:24 $
% $Revision: 1.39 $
% $Date: 2005/06/27 13:08:28 $

View File

@ -8,8 +8,8 @@ int main(void)
printf("\nstore_test...."); fflush(stdout); x = store_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\ncipher_test..."); fflush(stdout); x = cipher_hash_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nmodes_test...."); fflush(stdout); x = modes_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nmac_test......"); fflush(stdout); x = mac_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nder_test......"); fflush(stdout); x = der_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nmac_test......"); fflush(stdout); x = mac_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nrsa_test......"); fflush(stdout); x = rsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);

Binary file not shown.

View File

@ -4,7 +4,7 @@
# Modified by Clay Culver
# The version
VERSION=1.04
VERSION=1.05
# Compiler and Linker Names
#CC=gcc
@ -132,9 +132,10 @@ src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
src/modes/ofb/ofb_start.o src/pk/asn1/der/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/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/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 \
@ -148,16 +149,18 @@ src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_enco
src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \
src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \
src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \
src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \
src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o src/pk/packet_valid_header.o \
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
src/prngs/sprng.o src/prngs/yarrow.o
HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \
src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \
@ -321,5 +324,5 @@ zipup: no_oops docs
# $Source: /cvs/libtom/libtomcrypt/makefile,v $
# $Revision: 1.68 $
# $Date: 2005/06/14 22:53:24 $
# $Revision: 1.70 $
# $Date: 2005/06/19 18:03:24 $

View File

@ -130,9 +130,10 @@ src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
src/modes/ofb/ofb_start.o src/pk/asn1/der/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/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/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 \
@ -146,16 +147,18 @@ src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_enco
src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \
src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \
src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \
src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \
src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o src/pk/packet_valid_header.o \
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
src/prngs/sprng.o src/prngs/yarrow.o
HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \
src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \
@ -235,5 +238,5 @@ install: library
install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH)
# $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $
# $Revision: 1.32 $
# $Date: 2005/05/23 03:12:44 $
# $Revision: 1.33 $
# $Date: 2005/06/19 18:22:31 $

View File

@ -59,9 +59,10 @@ src/modes/ecb/ecb_start.obj src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done
src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj \
src/modes/ofb/ofb_start.obj src/pk/asn1/der/bit/der_decode_bit_string.obj \
src/pk/asn1/der/bit/der_encode_bit_string.obj src/pk/asn1/der/bit/der_length_bit_string.obj \
src/pk/asn1/der/ia5/der_decode_ia5_string.obj src/pk/asn1/der/ia5/der_encode_ia5_string.obj \
src/pk/asn1/der/ia5/der_length_ia5_string.obj src/pk/asn1/der/integer/der_decode_integer.obj \
src/pk/asn1/der/integer/der_encode_integer.obj src/pk/asn1/der/integer/der_length_integer.obj \
src/pk/asn1/der/choice/der_decode_choice.obj src/pk/asn1/der/ia5/der_decode_ia5_string.obj \
src/pk/asn1/der/ia5/der_encode_ia5_string.obj src/pk/asn1/der/ia5/der_length_ia5_string.obj \
src/pk/asn1/der/integer/der_decode_integer.obj src/pk/asn1/der/integer/der_encode_integer.obj \
src/pk/asn1/der/integer/der_length_integer.obj \
src/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \
src/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \
src/pk/asn1/der/object_identifier/der_length_object_identifier.obj \
@ -75,16 +76,18 @@ src/pk/asn1/der/sequence/der_encode_sequence.obj src/pk/asn1/der/sequence/der_en
src/pk/asn1/der/sequence/der_length_sequence.obj \
src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj \
src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj \
src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj \
src/pk/packet_valid_header.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \
src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \
src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj \
src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj \
src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj \
src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \
src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj
src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj \
src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj \
src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj src/pk/packet_valid_header.obj \
src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \
src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \
src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \
src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \
src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \
src/prngs/sprng.obj src/prngs/yarrow.obj
HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \
src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \
@ -92,8 +95,6 @@ src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h src/headers/tommath_clas
src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_misc.h \
src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h
#ciphers come in two flavours... enc+dec and enc
src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes.c /Fosrc/ciphers/aes/aes_enc.obj
@ -117,5 +118,5 @@ timing: demos/timing.c library
cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib
# $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $
# $Revision: 1.14 $
# $Date: 2005/06/08 23:37:40 $
# $Revision: 1.15 $
# $Date: 2005/06/27 12:37:06 $

View File

@ -6,7 +6,7 @@
# Tom St Denis
# The version
VERSION=0:104
VERSION=0:105
# Compiler and Linker Names
CC=libtool --mode=compile gcc
@ -131,9 +131,10 @@ src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
src/modes/ofb/ofb_start.o src/pk/asn1/der/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/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/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 \
@ -147,16 +148,18 @@ src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_enco
src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \
src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \
src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \
src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \
src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o \
src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o src/pk/packet_valid_header.o \
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
src/prngs/sprng.o src/prngs/yarrow.o
HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \
src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \
@ -222,5 +225,5 @@ timing: library $(LIBTEST) $(TIMINGS)
gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(MPISHARED)
# $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $
# $Revision: 1.17 $
# $Date: 2005/06/14 22:53:25 $
# $Revision: 1.19 $
# $Date: 2005/06/27 12:37:06 $

91
notes/tech0006.txt Normal file
View File

@ -0,0 +1,91 @@
Tech Note 0006
PK Standards Compliance
Tom St Denis
RSA
----
PKCS #1 compliance.
Key Format: RSAPublicKey and RSAPrivateKey as per PKCS #1 v2.1
Encryption: OAEP as per PKCS #1
Signature : PSS as per PKCS #1
DSA
----
The NIST DSA algorithm
Key Format: HomeBrew [see below]
Signature : ANSI X9.62 format [see below].
Keys are stored as
DSAPublicKey ::= SEQUENCE {
publicFlags BIT STRING(1), -- must be 0
g INTEGER , -- base generator, check that g^q mod p == 1
-- and that 1 < g < p - 1
p INTEGER , -- prime modulus
q INTEGER , -- order of sub-group (must be prime)
y INTEGER , -- public key, specifically, g^x mod p,
-- check that y^q mod p == 1
-- and that 1 < y < p - 1
}
DSAPrivateKey ::= SEQUENCE {
publicFlags BIT STRING(1), -- must be 1
g INTEGER , -- base generator, check that g^q mod p == 1
-- and that 1 < g < p - 1
p INTEGER , -- prime modulus
q INTEGER , -- order of sub-group (must be prime)
y INTEGER , -- public key, specifically, g^x mod p,
-- check that y^q mod p == 1
-- and that 1 < y < p - 1
x INTEGER -- private key
}
Signatures are stored as
DSASignature ::= SEQUENCE {
r, s INTEGER -- signature parameters
}
ECC
----
The ANSI X9.62 and X9.63 algorithms [partial]. Supports all NIST GF(p) curves.
Key Format : Homebrew [see below, only GF(p) NIST curves supported]
Signature : X9.62 compliant
Encryption : Homebrew [based on X9.63, differs in that the public point is stored as an ECCPublicKey]
Shared Secret: X9.63 compliant
ECCPublicKey ::= SEQUENCE {
flags BIT STRING(1), -- public/private flag (always zero),
keySize INTEGER, -- Curve size (in bits) divided by eight
-- and rounded down, e.g. 521 => 65
pubkey.x INTEGER, -- The X co-ordinate of the public key point
pubkey.y INTEGER, -- The Y co-ordinate of the public key point
}
ECCPrivateKey ::= SEQUENCE {
flags BIT STRING(1), -- public/private flag (always one),
keySize INTEGER, -- Curve size (in bits) divided by eight
-- and rounded down, e.g. 521 => 65
pubkey.x INTEGER, -- The X co-ordinate of the public key point
pubkey.y INTEGER, -- The Y co-ordinate of the public key point
secret.k INTEGER, -- The secret key scalar
}
The encryption works by finding the X9.63 shared secret and hashing it. The hash is then simply XOR'ed against the message [which must be at most the size
of the hash digest]. The format of the encrypted text is as follows
ECCEncrypted ::= SEQUENCE {
hashOID OBJECT IDENTIFIER, -- The OID of the hash used
pubkey OCTET STRING , -- Encapsulation of a random ECCPublicKey
skey OCTET STRING -- The encrypted text (which the hash was XOR'ed against)
}
% $Source: /cvs/libtom/libtomcrypt/notes/tech0006.txt,v $
% $Revision: 1.2 $
% $Date: 2005/06/18 02:26:27 $

View File

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

View File

@ -618,12 +618,11 @@ int ctr_done(symmetric_CTR *ctr);
int find_cipher(const char *name);
int find_cipher_any(const char *name, int blocklen, int keylen);
int find_cipher_id(unsigned char ID);
int register_cipher(const struct ltc_cipher_descriptor *cipher);
int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
int cipher_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_cipher_mutex);
/* $Source$ */
/* $Revision$ */

View File

@ -229,6 +229,28 @@
#endif
/* THREAD management */
#ifdef LTC_PTHREAD
#include <pthread.h>
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
#else
/* default no functions */
#define LTC_MUTEX_GLOBAL(x)
#define LTC_MUTEX_PROTO(x)
#define LTC_MUTEX_LOCK(x)
#define LTC_MUTEX_UNLOCK(x)
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -279,6 +279,8 @@ int register_hash(const struct ltc_hash_descriptor *hash);
int unregister_hash(const struct ltc_hash_descriptor *hash);
int hash_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_hash_mutex);
int hash_memory(int hash,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);

View File

@ -259,7 +259,9 @@ enum {
LTC_ASN1_OBJECT_IDENTIFIER,
LTC_ASN1_IA5_STRING,
LTC_ASN1_PRINTABLE_STRING,
LTC_ASN1_UTCTIME,
LTC_ASN1_CHOICE,
LTC_ASN1_SEQUENCE
};
@ -267,6 +269,7 @@ typedef struct {
int type;
void *data;
unsigned long size;
int used;
} ltc_asn1_list;
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
@ -276,6 +279,7 @@ typedef struct {
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
LTC_MACRO_list[LTC_MACRO_temp].data = (Data); \
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
} while (0);
/* SEQUENCE */
@ -344,6 +348,32 @@ 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);
/* CHOICE */
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list *list, unsigned long outlen);
/* UTCTime */
typedef struct {
unsigned YY, /* year */
MM, /* month */
DD, /* day */
hh, /* hour */
mm, /* minute */
ss, /* second */
off_dir, /* timezone offset direction 0 == +, 1 == - */
off_hh, /* timezone offset hours */
off_mm; /* timezone offset minutes */
} ltc_utctime;
int der_encode_utctime(ltc_utctime *utctime,
unsigned char *out, unsigned long *outlen);
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
ltc_utctime *out);
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
#endif
/* $Source$ */

View File

@ -178,6 +178,7 @@ int find_prng(const char *name);
int register_prng(const struct ltc_prng_descriptor *prng);
int unregister_prng(const struct ltc_prng_descriptor *prng);
int prng_is_valid(int idx);
LTC_MUTEX_PROTO(ltc_prng_mutex);
/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
* might not work on all platforms as planned

View File

@ -301,6 +301,9 @@ const char *crypt_build_settings =
#endif
#if defined(LTC_NO_TABLES)
" LTC_NO_TABLES "
#endif
#if defined(LTC_PTHREAD)
" LTC_PTHREAD "
#endif
"\n"
"\n\n\n"

View File

@ -19,6 +19,8 @@ struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_cipher_mutex);
/* $Source$ */
/* $Revision$ */

View File

@ -22,9 +22,12 @@
*/
int cipher_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_INVALID_CIPHER;
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_OK;
}

View File

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

View File

@ -31,14 +31,17 @@ int find_cipher_any(const char *name, int blocklen, int keylen)
x = find_cipher(name);
if (x != -1) return x;
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name == NULL) {
continue;
}
if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}

View File

@ -23,11 +23,15 @@
int find_cipher_id(unsigned char ID)
{
int x;
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].ID == ID) {
return (cipher_descriptor[x].name == NULL) ? -1 : x;
x = (cipher_descriptor[x].name == NULL) ? -1 : x;
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}

View File

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

View File

@ -28,6 +28,7 @@
x = find_hash(name);
if (x != -1) return x;
LTC_MUTEX_LOCK(&ltc_hash_mutex);
y = MAXBLOCKSIZE+1;
z = -1;
for (x = 0; x < TAB_SIZE; x++) {
@ -39,6 +40,7 @@
y = hash_descriptor[x].hashsize;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return z;
}

View File

@ -23,11 +23,15 @@
int find_hash_id(unsigned char ID)
{
int x;
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].ID == ID) {
return (hash_descriptor[x].name == NULL) ? -1 : x;
}
if (hash_descriptor[x].ID == ID) {
x = (hash_descriptor[x].name == NULL) ? -1 : x;
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}

View File

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

View File

@ -19,6 +19,9 @@ struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_hash_mutex);
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -22,9 +22,12 @@
*/
int hash_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_hash_mutex);
if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_INVALID_HASH;
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_OK;
}

View File

@ -18,6 +18,9 @@ struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_prng_mutex);
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -22,9 +22,12 @@
*/
int prng_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_prng_mutex);
if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_INVALID_PRNG;
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_OK;
}

View File

@ -27,8 +27,10 @@ int register_cipher(const struct ltc_cipher_descriptor *cipher)
LTC_ARGCHK(cipher != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
@ -37,11 +39,13 @@ int register_cipher(const struct ltc_cipher_descriptor *cipher)
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name == NULL) {
XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}

View File

@ -27,8 +27,10 @@ int register_hash(const struct ltc_hash_descriptor *hash)
LTC_ARGCHK(hash != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (memcmp(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
@ -37,11 +39,13 @@ int register_hash(const struct ltc_hash_descriptor *hash)
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name == NULL) {
XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}

View File

@ -27,8 +27,10 @@ int register_prng(const struct ltc_prng_descriptor *prng)
LTC_ARGCHK(prng != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (memcmp(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
@ -37,11 +39,13 @@ int register_prng(const struct ltc_prng_descriptor *prng)
for (x = 0; x < TAB_SIZE; x++) {
if (prng_descriptor[x].name == NULL) {
XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return -1;
}

View File

@ -27,13 +27,16 @@ int unregister_cipher(const struct ltc_cipher_descriptor *cipher)
LTC_ARGCHK(cipher != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (memcmp(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
cipher_descriptor[x].name = NULL;
cipher_descriptor[x].ID = 255;
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_ERROR;
}

View File

@ -27,12 +27,15 @@ int unregister_hash(const struct ltc_hash_descriptor *hash)
LTC_ARGCHK(hash != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (memcmp(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
hash_descriptor[x].name = NULL;
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_ERROR;
}

View File

@ -25,14 +25,17 @@ int unregister_prng(const struct ltc_prng_descriptor *prng)
int x;
LTC_ARGCHK(prng != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (memcmp(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) {
prng_descriptor[x].name = NULL;
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_ERROR;
}

View File

@ -0,0 +1,168 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#include "tomcrypt.h"
/**
@file der_decode_choice.c
ASN.1 DER, decode a CHOICE, Tom St Denis
*/
#ifdef LTC_DER
/**
Decode a CHOICE
@param in The DER encoded input
@param inlen [in/out] The size of the input and resulting size of read type
@param list The list of items to decode
@param outlen The number of items in the list
@return CRYPT_OK on success
*/
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list *list, unsigned long outlen)
{
unsigned long size, x, z;
void *data;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(list != NULL);
/* get blk size */
if (*inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* set all of the "used" flags to zero */
for (x = 0; x < outlen; x++) {
list[x].used = 0;
}
/* now scan until we have a winner */
for (x = 0; x < outlen; x++) {
size = list[x].size;
data = list[x].data;
switch (list[x].type) {
case LTC_ASN1_INTEGER:
if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
if (der_length_integer(data, &z) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_SHORT_INTEGER:
if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
if (der_length_short_integer(size, &z) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_BIT_STRING:
if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_bit_string(size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_OCTET_STRING:
if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_octet_string(size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_NULL:
if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
*inlen = 2;
return CRYPT_OK;
}
break;
case LTC_ASN1_OBJECT_IDENTIFIER:
if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_IA5_STRING:
if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_PRINTABLE_STRING:
if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_UTCTIME:
z = *inlen;
if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
break;
case LTC_ASN1_SEQUENCE:
if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
if (der_length_sequence(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
}
break;
default:
return CRYPT_INVALID_ARG;
}
}
return CRYPT_INVALID_PACKET;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -185,6 +185,15 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
inlen -= z;
break;
case LTC_ASN1_UTCTIME:
z = inlen;
if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
inlen -= z;
break;
case LTC_ASN1_SEQUENCE:
z = inlen;
if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
@ -197,6 +206,16 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
inlen -= z;
break;
case LTC_ASN1_CHOICE:
z = inlen;
if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
inlen -= z;
break;
default:
err = CRYPT_INVALID_ARG;
goto LBL_ERR;

View File

@ -50,7 +50,9 @@ 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_UTCTIME:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_CHOICE:
++x;
break;
@ -92,7 +94,9 @@ 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_UTCTIME:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_CHOICE:
list[x].type = type;
list[x].size = size;
list[x++].data = data;

View File

@ -103,6 +103,13 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
y += x;
break;
case LTC_ASN1_UTCTIME:
if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_SEQUENCE:
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
@ -241,6 +248,15 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
*outlen -= z;
break;
case LTC_ASN1_UTCTIME:
z = *outlen;
if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_SEQUENCE:
z = *outlen;
if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) {

View File

@ -51,6 +51,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_UTCTIME:
case LTC_ASN1_SEQUENCE:
++x;
break;
@ -93,6 +94,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_UTCTIME:
case LTC_ASN1_SEQUENCE:
list[x].type = type;
list[x].size = size;

View File

@ -0,0 +1,120 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#include "tomcrypt.h"
/**
@file der_decode_utctime.c
ASN.1 DER, decode a UTCTIME, Tom St Denis
*/
#ifdef LTC_DER
static int char_to_int(unsigned char x)
{
switch (x) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
}
return 100;
}
#define DECODE_V(y, max) \
y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
if (y >= max) return CRYPT_INVALID_PACKET; \
x += 2;
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
ltc_utctime *out)
{
unsigned char buf[32];
unsigned long x;
int y;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(out != NULL);
/* check header */
if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
return CRYPT_INVALID_PACKET;
}
/* decode the string */
for (x = 0; x < in[1]; x++) {
y = der_ia5_value_decode(in[x+2]);
if (y == -1) {
return CRYPT_INVALID_PACKET;
}
buf[x] = y;
}
*inlen = 2 + x;
/* possible encodings are
YYMMDDhhmmZ
YYMMDDhhmm+hh'mm'
YYMMDDhhmm-hh'mm'
YYMMDDhhmmssZ
YYMMDDhhmmss+hh'mm'
YYMMDDhhmmss-hh'mm'
So let's do a trivial decode upto [including] mm
*/
x = 0;
DECODE_V(out->YY, 100);
DECODE_V(out->MM, 13);
DECODE_V(out->DD, 32);
DECODE_V(out->hh, 24);
DECODE_V(out->mm, 60);
/* clear timezone and seconds info */
out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
/* now is it Z, +, - or 0-9 */
if (buf[x] == 'Z') {
return CRYPT_OK;
} else if (buf[x] == '+' || buf[x] == '-') {
out->off_dir = (buf[x++] == '+') ? 0 : 1;
DECODE_V(out->off_hh, 24);
DECODE_V(out->off_mm, 60);
return CRYPT_OK;
}
/* decode seconds */
DECODE_V(out->ss, 60);
/* now is it Z, +, - */
if (buf[x] == 'Z') {
return CRYPT_OK;
} else if (buf[x] == '+' || buf[x] == '-') {
out->off_dir = (buf[x++] == '+') ? 0 : 1;
DECODE_V(out->off_hh, 24);
DECODE_V(out->off_mm, 60);
return CRYPT_OK;
} else {
return CRYPT_INVALID_PACKET;
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,80 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#include "tomcrypt.h"
/**
@file der_encode_utctime.c
ASN.1 DER, encode a UTCTIME, Tom St Denis
*/
#ifdef LTC_DER
static const char *baseten = "0123456789";
#define STORE_V(y) \
out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
out[x++] = der_ia5_char_encode(baseten[y % 10]);
/**
Gets length of DER encoding of UTCTIME
@param outlen [out] The length of the DER encoding
@return CRYPT_OK if successful
*/
int der_encode_utctime(ltc_utctime *utctime,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, tmplen;
int err;
LTC_ARGCHK(utctime != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) {
return err;
}
if (tmplen > *outlen) {
return CRYPT_BUFFER_OVERFLOW;
}
/* store header */
out[0] = 0x17;
/* store values */
x = 2;
STORE_V(utctime->YY);
STORE_V(utctime->MM);
STORE_V(utctime->DD);
STORE_V(utctime->hh);
STORE_V(utctime->mm);
STORE_V(utctime->ss);
if (utctime->off_mm || utctime->off_hh) {
out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+');
STORE_V(utctime->off_hh);
STORE_V(utctime->off_mm);
} else {
out[x++] = der_ia5_char_encode('Z');
}
/* store length */
out[1] = x - 2;
/* all good let's return */
*outlen = x;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -0,0 +1,45 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#include "tomcrypt.h"
/**
@file der_length_utctime.c
ASN.1 DER, get length of UTCTIME, Tom St Denis
*/
#ifdef LTC_DER
/**
Gets length of DER encoding of UTCTIME
@param outlen [out] The length of the DER encoding
@return CRYPT_OK if successful
*/
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen)
{
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(utctime != NULL);
if (utctime->off_hh == 0 && utctime->off_mm == 0) {
/* we encode as YYMMDDhhmmssZ */
*outlen = 2 + 13;
} else {
/* we encode as YYMMDDhhmmss{+|-}hh'mm' */
*outlen = 2 + 17;
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

View File

@ -160,7 +160,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
/* copy message */
*outlen = (modulus_len - hLen - 1) - x;
XMEMCPY(out, DB + x, modulus_len - hLen - 1);
XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x);
x += modulus_len - hLen - 1;
/* valid packet */

View File

@ -86,6 +86,12 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
err = CRYPT_BUFFER_OVERFLOW;
goto done;
}
/* this should never happen ... */
if (mp_unsigned_bin_size(&tmp) > mp_unsigned_bin_size(&key->N)) {
err = CRYPT_ERROR;
goto done;
}
*outlen = x;
/* convert it */

View File

@ -10,6 +10,64 @@ int der_tests(void)
#else
static int der_choice_test(void)
{
ltc_asn1_list types[7], host[1];
unsigned char bitbuf[10], octetbuf[10], ia5buf[10], printbuf[10], outbuf[256];
unsigned long integer, oidbuf[10], outlen, inlen, x, y;
mp_int mpinteger;
ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
/* setup variables */
for (x = 0; x < sizeof(bitbuf); x++) { bitbuf[x] = x & 1; }
for (x = 0; x < sizeof(octetbuf); x++) { octetbuf[x] = x; }
for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; }
for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; }
integer = 1;
for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; }
DO(mpi_to_ltc_error(mp_init(&mpinteger)));
for (x = 0; x < 14; x++) {
/* setup list */
LTC_SET_ASN1(types, 0, LTC_ASN1_PRINTABLE_STRING, printbuf, sizeof(printbuf));
LTC_SET_ASN1(types, 1, LTC_ASN1_BIT_STRING, bitbuf, sizeof(bitbuf));
LTC_SET_ASN1(types, 2, LTC_ASN1_OCTET_STRING, octetbuf, sizeof(octetbuf));
LTC_SET_ASN1(types, 3, LTC_ASN1_IA5_STRING, ia5buf, sizeof(ia5buf));
if (x > 7) {
LTC_SET_ASN1(types, 4, LTC_ASN1_SHORT_INTEGER, &integer, 1);
} else {
LTC_SET_ASN1(types, 4, LTC_ASN1_INTEGER, &mpinteger, 1);
}
LTC_SET_ASN1(types, 5, LTC_ASN1_OBJECT_IDENTIFIER, oidbuf, sizeof(oidbuf)/sizeof(oidbuf[0]));
LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1);
LTC_SET_ASN1(host, 0, LTC_ASN1_CHOICE, types, 7);
/* encode */
outlen = sizeof(outbuf);
DO(der_encode_sequence(&types[x>6?x-7:x], 1, outbuf, &outlen));
/* decode it */
inlen = outlen;
DO(der_decode_sequence(outbuf, inlen, &host, 1));
for (y = 0; y < 7; y++) {
if (types[y].used && y != (x>6?x-7:x)) {
fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to one\n", y, x);
return 1;
}
if (!types[y].used && y == (x>6?x-7:x)) {
fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to zero\n", y, x);
return 1;
}
}
}
mp_clear(&mpinteger);
return 0;
}
int der_tests(void)
{
unsigned long x, y, z, zz, oid[2][32];
@ -27,6 +85,13 @@ int der_tests(void)
static const unsigned char rsa_printable_der[] = { 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55,
0x73, 0x65, 0x72, 0x20, 0x31 };
static const ltc_utctime rsa_time1 = { 91, 5, 6, 16, 45, 40, 1, 7, 0 };
static const ltc_utctime rsa_time2 = { 91, 5, 6, 23, 45, 40, 0, 0, 0 };
ltc_utctime tmp_time;
static const unsigned char rsa_time1_der[] = { 0x17, 0x11, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x36, 0x34, 0x35, 0x34, 0x30, 0x2D, 0x30, 0x37, 0x30, 0x30 };
static const unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a };
DO(mpi_to_ltc_error(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL)));
for (zz = 0; zz < 16; zz++) {
for (z = 0; z < 1024; z++) {
@ -199,6 +264,11 @@ int der_tests(void)
fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der));
return 1;
}
DO(der_length_ia5_string(rsa_ia5, strlen(rsa_ia5), &y));
if (y != x) {
fprintf(stderr, "IA5 length failed to match: %lu, %lu\n", x, y);
return 1;
}
y = sizeof(buf[1]);
DO(der_decode_ia5_string(buf[0], x, buf[1], &y));
if (y != strlen(rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen(rsa_ia5))) {
@ -213,6 +283,11 @@ int der_tests(void)
fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der));
return 1;
}
DO(der_length_printable_string(rsa_printable, strlen(rsa_printable), &y));
if (y != x) {
fprintf(stderr, "printable length failed to match: %lu, %lu\n", x, y);
return 1;
}
y = sizeof(buf[1]);
DO(der_decode_printable_string(buf[0], x, buf[1], &y));
if (y != strlen(rsa_printable) || memcmp(buf[1], rsa_printable, strlen(rsa_printable))) {
@ -220,7 +295,72 @@ int der_tests(void)
return 1;
}
return 0;
/* Test UTC time */
x = sizeof(buf[0]);
DO(der_encode_utctime(&rsa_time1, buf[0], &x));
if (x != sizeof(rsa_time1_der) || memcmp(buf[0], rsa_time1_der, x)) {
fprintf(stderr, "UTCTIME encode of rsa_time1 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der));
fprintf(stderr, "\n\n");
for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n");
return 1;
}
DO(der_length_utctime(&rsa_time1, &y));
if (y != x) {
fprintf(stderr, "UTCTIME length failed to match for rsa_time1: %lu, %lu\n", x, y);
return 1;
}
DO(der_decode_utctime(buf[0], &y, &tmp_time));
if (y != x || memcmp(&rsa_time1, &tmp_time, sizeof(ltc_utctime))) {
fprintf(stderr, "UTCTIME decode failed for rsa_time1: %lu %lu\n", x, y);
fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n",
tmp_time.YY,
tmp_time.MM,
tmp_time.DD,
tmp_time.hh,
tmp_time.mm,
tmp_time.ss,
tmp_time.off_dir,
tmp_time.off_mm,
tmp_time.off_hh);
return 1;
}
x = sizeof(buf[0]);
DO(der_encode_utctime(&rsa_time2, buf[0], &x));
if (x != sizeof(rsa_time2_der) || memcmp(buf[0], rsa_time2_der, x)) {
fprintf(stderr, "UTCTIME encode of rsa_time2 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der));
fprintf(stderr, "\n\n");
for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n");
return 1;
}
DO(der_length_utctime(&rsa_time2, &y));
if (y != x) {
fprintf(stderr, "UTCTIME length failed to match for rsa_time2: %lu, %lu\n", x, y);
return 1;
}
DO(der_decode_utctime(buf[0], &y, &tmp_time));
if (y != x || memcmp(&rsa_time2, &tmp_time, sizeof(ltc_utctime))) {
fprintf(stderr, "UTCTIME decode failed for rsa_time2: %lu %lu\n", x, y);
fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n",
tmp_time.YY,
tmp_time.MM,
tmp_time.DD,
tmp_time.hh,
tmp_time.mm,
tmp_time.ss,
tmp_time.off_dir,
tmp_time.off_mm,
tmp_time.off_hh);
return 1;
}
return der_choice_test();
}
#endif