diff --git a/Doxyfile b/Doxyfile index d42b778..9e2eccc 100644 --- a/Doxyfile +++ b/Doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = LibTomCrypt # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 1.02 +PROJECT_NUMBER = 1.03 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/TODO b/TODO index 8b13789..c93ef6f 100644 --- a/TODO +++ b/TODO @@ -1 +1,9 @@ +Things ideal for 1.04 + +- ASN.1 SET and UTCtime +- 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!] +- Look into other ECC point muls and consider a "precomp" interface diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..6867c2a --- /dev/null +++ b/build.sh @@ -0,0 +1,20 @@ +#!/bin/bash +echo "$1 ($2, $3)..." +make clean 1>/dev/null 2>/dev/null +echo -n "building..." +CFLAGS="$2 $CFLAGS" make -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1) +echo -n "testing..." +if [ -a test ] && [ -f test ] && [ -x test ]; then + ((./test >test_std.txt 2>test_err.txt && ./tv_gen > tv.txt) && echo "$1 test passed." && echo "y" > testok.txt) || (echo "$1 test failed" && cat test_err.txt && exit 1) + if find *_tv.txt -type f 1>/dev/null 2>/dev/null ; then + for f in *_tv.txt; do if (diff $f notes/$f) then true; else (echo "tv_gen $f failed" && rm -f testok.txt && exit 1); fi; done + fi +fi +if [ -a testok.txt ] && [ -f testok.txt ]; then + exit 0 +fi +exit 1 + +# $Source: /cvs/libtom/libtomcrypt/build.sh,v $ +# $Revision: 1.4 $ +# $Date: 2005/05/05 14:49:27 $ diff --git a/changes b/changes index 54480cf..5e56f67 100644 --- a/changes +++ b/changes @@ -1,3 +1,58 @@ +June 9th, 2005 +v1.03 + -- Users may want to note that on a P4/GCC3.4 platform "-fno-regmove" greatly accelerates the ciphers/hashes. + -------------------------------------------------------------------------------------------------------------- + -- Made it install the testing library in the icc/static makefiles + -- Found bug in ccm_memory.c which would fail to compile when LTC_CLEAN_STACK was enabled + -- Simon Johnson proposed I do a fully automated test suite. Hence "testme.sh" was born + -- Added LTC_NO_TEST which forces test vectors off (regardless of what tomcrypt_custom.h has) + -- Added LTC_NO_TABLES which disables large tables (where possible, regardless of what tomcrypt_custom.h has) + -- New test script found a bug in twofish.c when TABLES was disabled. Yeah testing! + -- Added a LTC_FAST specific test to the testing software. + -- Updated test driver to actually halt on errors and just print them out (useful for say... automated testing...) + -- Added bounds checking to Pelican MAC + -- Added BIT and OCTET STRING to the ASN.1 side of things. + -- Pekka Riikonen pointed out that my ctr_start() function should accept the counter mode. + -- Cleaned up warnings in testprof + -- Removed redundant mu and point mapping in ecc_verify_hash() so it should be a bit faster now + -- Pekka pointed out that the AES key structure was using 32 bytes more than it ought to. + -- Added quick defines to remove entire classes of algorithms. This makes it easier if you want to build with just + one algorithm (say AES or SHA-256). Defines are LTC_NO_CIPHERS, LTC_NO_MODES, LTC_NO_HASHES, LTC_NO_MACS, + LTC_NO_PRNGS, LTC_NO_PK, LTC_NO_PKCS + -- As part of the move for ECC to X9.62 I've changed the signature algorithm to EC DSA. No API changes. + -- Pekka helped me clean up the PKCS #1 v2.1 [OAEP/PSS] code + -- Wrote new DER SEQUENCE coder/decoder + -- RSA, DSA and ECDSA now use the DER SEQUENCE code (saves a lot of code!) + -- DSA output is now a DER SEQUENCE (so not compatible with previous releases). + -- Added Technote #5 which shows how to build LTC on an AMD64 to have a variety of algorithms in only ~80KB of code. + -- Changed temp variable in LOAD/STORE macros to "ulong32" for 32-bit ops. Makes it safer on Big endian platforms + -- Added INSTALL_GROUP and INSTALL_USER which you can specify on the build to override the default USER/GROUP the library + is to be installed as + -- Removed "testprof" from the default build. + -- Added IA5, NULL and Object Identifier to the list of ASN.1 DER supported types + -- The "no_oops" target (part of zipup) now scans for non-cvs files. This helps prevent temp/scratch files from appearing in releases ;-) + -- Added DERs for missing hashes, but just the OID not the PKCS #1 v1.5 additions. + -- Removed PKCS #1 v1.5 from the tree since it's taking up space and you ought to use v2.1 anyways + -- Kevin Kenny pointed out a few stray // comments + -- INTEGER code properly supports negatives and zero padding [Pekka!] + -- Sorted asn1/der/ directory ... less of a mess now ;-) + -- Added PRINTABLE STRING type + -- Removed ECC-160 as it wasn't a standard curve + -- Made ecc_shared_secret() ANSI X9.63 compliant + -- Changed "printf" to "fprintf(stderr, " in the testbench... ;-) + -- Optimized the GCM table creation. On 1KB packets [with key switching] the new GCM is 12.7x faster than before. + -- Changed OID representation for hashes to be just a list of unsigned longs (so you can compare against them nicely after decoding a sequence) + -- ECC code now uses Montgomery reduction ... it's even faster [ECC-256 make key down from 37.4M to 4.6M cycles on an Athlon64] + -- Added SHORT_INTEGER so users can easily store DER encoded INTEGER types without using the bignum math library + -- Fixed OMAC code so that with LTC_FAST it doesn't require that LTC_FAST_TYPE divides 16 [it has to divide the block size instead] + -- ECC key export is now a simple [and documented] SEQUENCE, the "encrypt_key" also uses a new SEQUENCE format. + -- Thanks goes to the following testers + Michael Brown - Solaris 10/uSPARCII + Richard Outerbridge - MacOS + Martin Carpenter - Solaris 8/uSPARCII [Thanks for cleaning up the scripts] + Greg Rose - ... SunOS 5.8/SPARC [... what's with the SPARCS?] + Matt Johnston - MacOS X [Thanks for pointing out GCC 4 problems with -Os] + April 19th, 2005 v1.02 -- Added LTC_TEST support to gcm_test() @@ -1243,3 +1298,8 @@ v0.02 -- Changed RC5 to only allow 12 to 24 rounds -- Added more to the manual. v0.01 -- We will call this the first version. + +/* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ +/* $Revision: 1.92 $ */ +/* $Date: 2005/06/09 01:06:59 $ */ + diff --git a/crypt.tex b/crypt.tex index c785e83..9e17fe2 100644 --- a/crypt.tex +++ b/crypt.tex @@ -47,7 +47,7 @@ \def\gap{\vspace{0.5ex}} \makeindex \begin{document} -\title{LibTomCrypt \\ Version 1.02} +\title{LibTomCrypt \\ Version 1.03} \author{Tom St Denis \\ \\ tomstdenis@gmail.com \\ @@ -57,7 +57,7 @@ http://libtomcrypt.org This text and source code library are both hereby placed in the public domain. This book has been formatted for A4 paper using the \LaTeX{} {\em book} macro package. -\vspace{10cm} +\vspace{15cm} \begin{flushright}Open Source. Open Academia. Open Minds. @@ -771,13 +771,19 @@ other modes. \index{OFB Mode} \index{CFB Mode} The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required to -use that mode. They have identical setup routines (except ECB mode for obvious reasons): +use that mode. They have identical setup routines (except CTR and ECB mode): \index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()} \begin{verbatim} int XXX_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_XXX *XXX); +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr); + int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb); \end{verbatim} @@ -789,7 +795,12 @@ of the cipher you choose. It is important that the IV be random for each uniqu parameters ``key'', ``keylen'' and ``num\_rounds'' are the same as in the XXX\_setup() function call. The final parameter is a pointer to the structure you want to hold the information for the mode of operation. -Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. + +In the case of CTR mode there is an additional parameter ``ctr\_mode'' which specifies the mode that the counter is to be used in. +If \textbf{CTR\_COUNTER\_LITTLE\_ENDIAN} was specified then the counter will be treated as a little endian value. Otherwise, if +\textbf{CTR\_COUNTER\_BIG\_ENDIAN} was specified the counter will be treated as a big endian value. + +The routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code. \subsection{Encryption and Decryption} To actually encrypt or decrypt the following routines are provided: @@ -867,6 +878,7 @@ int main(void) key, /* the secret key */ 16, /* length of secret key (16 bytes, 128 bits) */ 0, /* 0 == default # of rounds */ + CTR_COUNTER_LITTLE_ENDIAN, /* Little endian counter */ &ctr) /* where to store initialized CTR state */ ) != CRYPT_OK) { printf("ctr_start error: %s\n", error_to_string(err)); @@ -1349,7 +1361,7 @@ int send_packet(const unsigned char *pt, unsigned long ptlen, } /* process the plaintext */ - if ((err = gcm_add_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) { + if ((err = gcm_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) { return err; } @@ -1359,6 +1371,8 @@ int send_packet(const unsigned char *pt, unsigned long ptlen, return err; } + /* ... send a header describing the lengths ... */ + /* depending on the protocol and how IV is generated you may have to send it too... */ send(socket, iv, ivlen, 0); @@ -2452,8 +2466,8 @@ int main(void) \section{Introduction} RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography. In the specifications are -padding algorithms for encryption and signatures. The standard includes ``v1.5'' and ``v2.0'' algorithms. -To simplify matters a little the v2.0 encryption and signature padding algorithms are called OAEP and PSS +padding algorithms for encryption and signatures. The standard includes the ``v2.1'' algorithms. +To simplify matters a little the v2.1 encryption and signature padding algorithms are called OAEP and PSS respectively. \section{PKCS \#1 Encryption} @@ -2509,33 +2523,6 @@ If the function succeeds it decodes the OAEP encoded message into ``out'' of len $1$ in ``res''. If the packet is invalid it stores $0$ in ``res'' and if the function fails for another reason it returns an error code. -\subsection{PKCS \#1 v1.5 Encoding} - -\index{pkcs\_1\_v15\_es\_encode()} -\begin{verbatim} -int pkcs_1_v15_es_encode(const unsigned char *msg, unsigned long msglen, - unsigned long modulus_bitlen, - prng_state *prng, int prng_idx, - unsigned char *out, unsigned long *outlen); -\end{verbatim} - -This will PKCS v1.5 encode the data in ``msg'' of length ``msglen''. Pass the length (in bits) of your -RSA modulus in ``modulus\_bitlen''. The encoded data will be stored in ``out'' of length ``outlen''. - -\subsection{PKCS \#1 v1.5 Decoding} -\index{pkcs\_1\_v15\_es\_decode()} -\begin{verbatim} -int pkcs_1_v15_es_decode(const unsigned char *msg, unsigned long msglen, - unsigned long modulus_bitlen, - unsigned char *out, unsigned long outlen, - int *res); -\end{verbatim} - -This will PKCS v1.5 decode the message in ``msg'' of length ``msglen''. It will store the output in ``out''. Note -that the length of the output ``outlen'' is a constant. This decoder cannot determine the original message -length. If the data in ``msg'' is a valid packet then a $1$ is stored in ``res'', otherwise a $0$ is -stored. - \section{PKCS \#1 Digital Signatures} \subsection{PSS Encoding} @@ -2577,34 +2564,6 @@ it is set to zero. The rest of the parameters are as in the PSS encode call. It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work. -\subsection{PKCS \#1 v1.5 Encoding} - -\index{pkcs\_1\_v15\_sa\_encode()} -\begin{verbatim} -int pkcs_1_v15_sa_encode(const unsigned char *msghash, unsigned long msghashlen, - int hash_idx, unsigned long modulus_bitlen, - unsigned char *out, unsigned long *outlen); -\end{verbatim} - -This will PKCS \#1 v1.5 signature encode the message hash ``msghash'' of length ``msghashlen''. You have -to tell this routine which hash produced the message hash in ``hash\_idx''. The encoded hash is stored -in ``out'' of length ``outlen''. - -\subsection{PKCS \#1 v1.5 Decoding} - -\index{pkcs\_1\_v15\_sa\_decode()} -\begin{verbatim} -int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - int hash_idx, unsigned long modulus_bitlen, - int *res); -\end{verbatim} - -This will PKCS \#1 v1.5 signature decode the data in ``sig'' of length ``siglen'' and compare the extracted -hash against ``msghash'' of length ``msghashlen''. You have to tell this routine which hash produced the -message digest in ``hash\_idx''. If the packet is valid and the hashes match ``res'' is set to $1$. Otherwise, -it is set to $0$. - \section{RSA Operations} \subsection{Background} @@ -2698,15 +2657,14 @@ to pkcs\_1\_oaep\_encode(). int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, - prng_state *prng, int prng_idx, - int hash_idx, int *res, + int hash_idx, int *stat, rsa_key *key); \end{verbatim} This function will RSA decrypt ``in'' of length ``inlen'' then OAEP depad the resulting data and store it in ``out'' of length ``outlen''. The ``lparam'' and ``lparamlen'' are the same parameters you would pass to pkcs\_1\_oaep\_decode(). -If the RSA decrypted data isn't a valid OAEP packet then ``res'' is set to $0$. Otherwise, it is set to $1$. +If the RSA decrypted data isn't a valid OAEP packet then ``stat'' is set to $0$. Otherwise, it is set to $1$. \subsection{RSA Hash Signatures} Similar to RSA key encryption RSA is also used to ``digitally sign'' message digests (hashes). To facilitate this @@ -2729,7 +2687,6 @@ the output is stored in ``out'' of length ``outlen''. \begin{verbatim} int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *msghash, unsigned long msghashlen, - prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key); \end{verbatim} @@ -2799,8 +2756,6 @@ int main(void) &l2, /* plaintext length */ "TestApp", /* lparam for this program */ 7, /* lparam is 7 bytes long */ - NULL, /* PRNG state */ - prng_idx, /* prng idx */ hash_idx, /* hash idx */ &res, /* validity of data */ &key) /* our RSA key */ @@ -3060,6 +3015,34 @@ provided are very close to $p$ that is $\vert \vert \phi(\beta) \vert \vert \app range in order from $\approx 2^{192}$ points to $\approx 2^{521}$. According to the source document any key size greater than or equal to 256-bits is sufficient for long term security. +\section{Key Format} +LibTomCrypt uses it's own format for ECC public and private keys. While ANSI X9.62 partially specifies key formats (it covers public keys) it does it in a less +than ideally simple manner. In the case of LibTomCrypt it is meant \textbf{solely} for NIST $GF(p)$ curves. The format of the keys is as follows: + +\begin{small} +\begin{verbatim} +ECCPublicKey ::= SEQUENCE { + flags BIT STRING(2), -- public/private flag (always zero), + -- compressed point + 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 +} + +ECCPrivateKey ::= SEQUENCE { + flags BIT STRING(2), -- public/private flag (always one), + -- compressed point + 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 + secret.k INTEGER, -- The secret key scalar +} +\end{verbatim} +\end{small} + +The first flags bit denotes whether the key is public (zero) or private (one). The compressed point bit is equal to zero if $(x^3 - 3x + b)^{(p+1)/4} \mbox{ mod }p$ is +congruent to the keys $y$ co-ordinate. The bit is one if the $y$ co-ordinate is the negative of the computed square root. + \section{Core Functions} Like the DH routines there is a key structure ``ecc\_key'' used by the functions. There is a function to make a key: @@ -3129,11 +3112,23 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, ecc_key *key); \end{verbatim} -Where ``in'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key +Where ``in'' is an input symmetric key of no more than 64 bytes. Essentially these routines created a random public key and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the required data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large as the symmetric key you are trying to share. +\subsection{Encrypt Packet Format} + +The packet format for the encrypted keys is the following ASN.1 SEQUENCE: + +\begin{verbatim} +ECCEncrypt ::= SEQUENCE { + hashID OBJECT IDENTIFIER, -- OID of hash used + pubkey OCTET STRING , -- Encapsulated ECCPublicKey (see above) + skey OCTET STRING -- xor of plaintext and "hash of shared secret" +} +\end{verbatim} + There are also functions to sign and verify the hash of a message. \index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()} \begin{verbatim} @@ -3150,6 +3145,8 @@ The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``in The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''. It sets ``stat'' to non-zero if the signature passes or zero if it fails. +\subsection{Signature Format} +The signature code is an implementation of X9.62 EC-DSA and the output is comformant for GF(p) curves. \section{ECC Keysizes} With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems. The math will still work @@ -3170,6 +3167,38 @@ would require at least 256 bytes where as the DSA signature would require only a The API for the DSA is essentially the same as the other PK algorithms. Except in the case of DSA no encryption or decryption routines are provided. +\section{Key Format} +Since no useful public standard for DSA key storage was presented to me during the course of this development I made my own ASN.1 SEQUENCE which I document +now so that others can interoperate with this library. + +\begin{verbatim} +DSAPublicKey ::= SEQUENCE { + publicFlags BIT STRING(1), -- must be 0 + g INTEGER , -- base generator, check that g^q mod p == 1 + -- and that 1 < g < p - 1 + p INTEGER , -- prime modulus + q INTEGER , -- order of sub-group (must be prime) + y INTEGER , -- public key, specifically, g^x mod p, + -- check that y^q mod p == 1 + -- and that 1 < y < p - 1 +} + +DSAPrivateKey ::= SEQUENCE { + publicFlags BIT STRING(1), -- must be 1 + g INTEGER , -- base generator, check that g^q mod p == 1 + -- and that 1 < g < p - 1 + p INTEGER , -- prime modulus + q INTEGER , -- order of sub-group (must be prime) + y INTEGER , -- public key, specifically, g^x mod p, + -- check that y^q mod p == 1 + -- and that 1 < y < p - 1 + x INTEGER -- private key +} +\end{verbatim} + +The leading BIT STRING has a single bit in it which is zero for public keys and one for private keys. This makes the structure uniquely decodable and easy +to work with. + \section{Key Generation} To make a DSA key you must call the following function \begin{verbatim} @@ -3291,79 +3320,289 @@ This will import the DSA key from the buffer ``in'' of length ``inlen'' to the ` will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()). \chapter{Standards Support} -\section{DER Support} -DER or ``Distinguished Encoding Rules'' is a subset of the ASN.1 encoding rules that is fully deterministic and -ideal for cryptography. In particular ASN.1 specifies an INTEGER type for storing arbitrary sized integers. DER -further limits the ASN.1 specifications to a deterministic encoding. +\section{ASN.1 Formats} +LibTomCrypt supports a variety of ASN.1 data types encoded with the Distinguished Encoding Rules (DER) suitable for various cryptographic protocols. The data types +are all provided with three basic functions with \textit{similar} prototypes. One function has been dedicated to calculate the length in octets of a given +format and two functions have been dedicated to encoding and decoding the format. -\subsection{Storing INTEGER types} -\index{der\_encode\_integer()} -\begin{alltt} -int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen); -\end{alltt} +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 +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 -This will store the integer in ``num'' to the output buffer ``out'' of length ``outlen''. It only stores -non--negative numbers. It stores the number of octets used back in ``outlen''. +\index{ltc\_asn1\_list structure} +\begin{verbatim} +typedef struct { + int type; + void *data; + unsigned long size; +} ltc_asn1_list; +\end{verbatim} -\subsection{Reading INTEGER types} -\index{der\_decode\_integer()} -\begin{alltt} -int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num); -\end{alltt} -This will decode the DER encoded INTEGER in ``in'' of length ``inlen'' and store the resulting integer -in ``num''. It will store the bytes read in ``inlen'' which is handy if you have to parse multiple -data items out of a binary packet. +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 +``LTC\_SET\_ASN1(list, index, Type, Data, Size)'' has been provided. -\subsection{INTEGER length} -\index{der\_length\_integer()} -\begin{alltt} -int der_length_integer(mp_int *num, unsigned long *len); -\end{alltt} -This will determine the length of the DER encoding of the integer ``num'' and store it in ``len''. +It will assign to the ``index''th position in the ``list'' the tripplet (Type, Data, Size). An example usage would be: -\subsection{Multiple INTEGER types} -To simplify the DER encoding/decoding there are two functions two handle multple types at once. +\begin{small} +\begin{verbatim} +... +ltc_asn1_list sequence[3]; +unsigned long three=3; -\index{der\_put\_multi\_integer()} -\index{der\_get\_multi\_integer()} -\begin{alltt} -int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, mp_int *num, ...); -int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, mp_int *num, ...); -\end{alltt} +LTC_SET_ASN1(sequence, 0, LTC_ASN1_IA5_STRING, "hello", 5); +LTC_SET_ASN1(sequence, 1, LTC_ASN1_SHORT_INTEGER, &three, 1); +LTC_SET_ASN1(sequence, 2, LTC_ASN1_NULL, NULL, 0); +\end{verbatim} +\end{small} -These will handle multiple encodings/decodings at once. They work like their single operand counterparts -except they handle a \textbf{NULL} terminated list of operands. +The macro is relatively safe with respect to modifying variables, for instance the following code is equivalent. + +\begin{small} +\begin{verbatim} +... +ltc_asn1_list sequence[3]; +unsigned long three=3; +int x=0; +LTC_SET_ASN1(sequence, x++, LTC_ASN1_IA5_STRING, "hello", 5); +LTC_SET_ASN1(sequence, x++, LTC_ASN1_SHORT_INTEGER, &three, 1); +LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL, NULL, 0); +\end{verbatim} +\end{small} + +\begin{figure}[here] +\begin{center} +\begin{small} +\begin{tabular}{|l|l|} +\hline \textbf{Definition} & \textbf{ASN.1 Type} \\ +\hline LTC\_ASN1\_EOL & End of a ASN.1 list structure. \\ +\hline LTC\_ASN1\_INTEGER & INTEGER (uses mp\_int) \\ +\hline LTC\_ASN1\_SHORT\_INTEGER & INTEGER (32--bit using unsigned long) \\ +\hline LTC\_ASN1\_BIT\_STRING & BIT STRING (one bit per char) \\ +\hline LTC\_ASN1\_OCTET\_STRING & OCTET STRING (one octet per char) \\ +\hline LTC\_ASN1\_NULL & NULL \\ +\hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER (words are in unsigned long) \\ +\hline LTC\_ASN1\_IA5\_STRING & IA5 STRING (one octet per char) \\ +\hline LTC\_ASN1\_PRINTABLE\_STRING & PRINTABLE STIRNG (one octet per char) \\ +\hline LTC\_ASN1\_SEQUENCE & SEQUENCE OF \\ +\hline +\end{tabular} +\caption{List of ASN.1 Supported Types} +\end{small} +\end{center} +\end{figure} + +\subsection{SEQUENCE Type} +The SEQUENCE data type is a collection of other ASN.1 data types encapsulated with a small header which is a useful way of sending multiple data types in one packet. + +\subsubsection{SEUQNECE Encoding} +To encode a sequence a \textbf{ltc\_asn1\_list} array must be initialized with the members of the sequence and their respective pointers. The encoding is performed +with the following function. + +\index{der\_encode\_sequence()} +\begin{verbatim} +int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +\end{verbatim} +This encodes a sequence of items pointed to by ``list'' where the list has ``inlen'' items in it. The SEQUENCE will be encoded to ``out'' and of length ``outlen''. The +function will terminate when it reads all the items out of the list (upto ``inlen'') or it encounters an item in the list with a type of \textbf{LTC\_ASN1\_EOL}. + +The ``data'' pointer in the list would be the same pointer you would pass to the respective ASN.1 encoder (e.g. der\_encode\_bit\_string()) and it is simply passed on +verbatim to the dependent encoder. The list can contain other SEQUENCE or SET types which enables you to have nested SEQUENCE and SET definitions. In these cases +the ``data'' pointer is simply a pointer to another \textbf{ltc\_asn1\_list}. + +\subsubsection{SEQUENCE Decoding} + +\index{der\_decode\_sequence()} + +Decoding a SEQUENCE is similar to encoding. You set up an array of \textbf{ltc\_asn1\_list} where in this case the ``size'' member is the maximum size +(in certain cases). For types such as IA5 STRING, BIT STRING, OCTET STRING (etc) the ``size'' field is updated after successful decoding to reflect how many +units of the respective type has been loaded. \begin{verbatim} -#include -int main(void) -{ - mp_int a, b, c, d; - unsigned char buffer[1000]; - unsigned long len; - int err; - - /* init a,b,c,d with some values ... */ - - /* ok we want to store them now... */ - len = sizeof(buffer); - if ((err = der_put_multi_integer(buffer, &len, - &a, &b, &c, &d, NULL)) != CRYPT_OK) { - // error - } - printf("I stored %lu bytes in buf\n", len); - - /* ok say we want to get them back for fun */ - /* len set previously...otherwise set it to the size of the packet */ - if ((err = der_get_multi_integer(buffer, &len, - &a, &b, &c, &d, NULL)) != CRYPT_OK) { - // error - } - printf("I read %lu bytes from buf\n", len); -} +int der_decode_sequence(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen); \end{verbatim} + +This will decode upto ``outlen'' items from the input buffer ``in'' of length ``inlen'' octets. The function will stop (gracefully) when it runs out of items to decode. +It will fail (for among other reasons) when it runs out of input bytes to read, a data type is invalid or a heap failure occured. + +For the following types the ``size'' field will be updated to reflect the number of units read of the given type. +\begin{enumerate} + \item BIT STRING + \item OCTET STRING + \item OBJECT IDENTIFIER + \item IA5 STRING + \item PRINTABLE STRING +\end{enumerate} + +\subsubsection{SEQUENCE Length} + +The length of a SEQUENCE can be determined with the following function. + +\index{der\_length\_sequence()} +\begin{verbatim} +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen); +\end{verbatim} + +This will get the encoding size for the given ``list'' of length ``inlen'' and store it in ``outlen''. + +\subsubsection{SEQUENCE Multiple Argument Lists} + +For small or simple sequences an encoding or decoding can be performed with one of the following two functions. + +\index{der\_encode\_sequence\_multi()} +\index{der\_decode\_sequence\_multi()} + +\begin{verbatim} +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); +\end{verbatim} + +These either encode or decode (respectively) a SEQUENCE data type where the items in the sequence are specified after the length parameter. + +The list of items are specified as a triple of the form ``(type, size, data)'' where ``type'' is an \textbf{int}, ``size'' is a \textbf{unsigned long} +and ``data'' is \textbf{void} pointer. The list of items must be terminated with an item with the type \textbf{LTC\_ASN1\_EOL}. + +It's ideal that you cast the ``size'' values to unsigned long to ensure that the proper data type is passed to the function. Constants such as ``1'' without +a cast or prototype are of type \textbf{int} by default. Appending \textit{UL} or prepending \textit{(unsigned long)} is enough to cast it to the correct type. + +\subsubsection{ASN.1 INTEGER} + +To encode or decode INTEGER data types use the following functions. + +\index{der\_encode\_integer()} +\index{der\_decode\_integer()} +\index{der\_length\_integer()} +\begin{verbatim} +int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen); +int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num); +int der_length_integer(mp_int *num, unsigned long *len); +\end{verbatim} + +These will encode or decode a signed INTEGER data type using the ``mp\_int'' data type to store the large INTEGER. To encode smaller values without allocating +an mp\_int to store the value the ``short'' INTEGER functions were made available. + +\index{der\_encode\_short\_integer()} +\index{der\_decode\_short\_integer()} +\index{der\_length\_short\_integer()} +\begin{verbatim} +int der_encode_short_integer(unsigned long num, + unsigned char *out, unsigned long *outlen); + +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, + unsigned long *num); + +int der_length_short_integer(unsigned long num, unsigned long *outlen); +\end{verbatim} + +These will encode or decode an unsigned \textbf{unsigned long} type (only reads upto 32--bits). For values in the range $0 \dots 2^{32} - 1$ the integer +and short integer functions can encode and decode each others outputs. + +\subsubsection{ASN.1 BIT STRING} + +\index{der\_encode\_bit\_string()} +\index{der\_decode\_bit\_string()} +\index{der\_length\_bit\_string()} +\begin{verbatim} +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_length_bit_string(unsigned long nbits, unsigned long *outlen); +\end{verbatim} + +These will encode or decode a BIT STRING data type. The bits are passed in (or read out) using one \textbf{char} per bit. A non--zero value will be interpretted +as a one bit and a zero value a zero bit. + +\subsubsection{ASN.1 OCTET STRING} + +\index{der\_encode\_octet\_string()} +\index{der\_decode\_octet\_string()} +\index{der\_length\_octet\_string()} +\begin{verbatim} +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_length_octet_string(unsigned long noctets, unsigned long *outlen); +\end{verbatim} + +These will encode or decode an OCTET STRING data type. The octets are stored using one \textbf{char} each. + +\subsubsection{ASN.1 OBJECT IDENTIFIER} + +\index{der\_encode\_object\_identifier()} +\index{der\_decode\_object\_identifier()} +\index{der\_length\_object\_identifier()} +\begin{verbatim} +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen); + +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen); + +int der_length_object_identifier(unsigned long *words, unsigned long nwords, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an OBJECT IDENTIFIER object. The words of the OID are stored in individual \textbf{unsigned long} elements and must be in the range +$0 \ldots 2^{32} - 1$. + +\subsubsection{ASN.1 IA5 STRING} + +\index{der\_encode\_ia5\_string()} +\index{der\_decode\_ia5\_string()} +\index{der\_length\_ia5\_string()} +\begin{verbatim} +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an IA5 STRING. The characters are read or stored in individual \textbf{char} elements. This functions performs internal character +to numerical conversions based on the conventions of the compiler being used. For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on +say a SPARC machine. Internally these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided +that the build platform honours the runtime platforms character conventions. + +If you're worried try building the test suite and running it. It has hard coded test vectors to ensure it is operating properly. + +\subsubsection{ASN.1 PRINTABLE STRING} + +\index{der\_encode\_printable\_string()} +\index{der\_decode\_printable\_string()} +\index{der\_length\_printable\_string()} +\begin{verbatim} +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, + unsigned long *outlen); +\end{verbatim} + +These will encode or decode an PRINTABLE STRING. The characters are read or stored in individual \textbf{char} elements. This functions performs internal character +to numerical conversions based on the conventions of the compiler being used. For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on +say a SPARC machine. Internally these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided +that the build platform honours the runtime platforms character conventions. + +If you're worried try building the test suite and running it. It has hard coded test vectors to ensure it is operating properly. + + \section{Password Based Cryptography} \subsection{PKCS \#5} +\index{PKCS \#5} In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5 is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented for completeness. Algorithm Two is a bit more modern and more flexible to work with. @@ -3436,7 +3675,6 @@ int main(void) \} \end{alltt} - \chapter{Miscellaneous} \section{Base64 Encoding and Decoding} The library provides functions to encode and decode a RFC1521 base64 coding scheme. This means that it can decode what it @@ -4030,8 +4268,8 @@ To initialize a cipher (for ECB mode) the function setup() was provided. It acc can specify the number of rounds they want through ``num\_rounds'' where $num\_rounds = 0$ means use the default. The destination of a scheduled key is stored in ``skey''. -This is where things get tricky. Currently there is no provision to allocate memory during initialization since there is no ``cipher done'' function. So you have -to either use an existing member of the symmetric\_key union or alias your own structure over top of it provided symmetric\_key is not smaller. +Inside the ``symmetric\_key'' union there is a ``void *data'' which you can use to allocate data if you need a data structure that doesn't fit with the existing +ones provided. Just make sure in your ``done()'' function that you free the allocated memory. \subsection{Single block ECB} To process a single block in ECB mode the ecb\_encrypt() and ecb\_decrypt() functions were provided. The plaintext and ciphertext buffers are allowed to overlap so you @@ -4062,7 +4300,8 @@ updated by the function before returning. \subsubsection{Accelerated CTR} This function is meant for accelerated CTR encryption. It is accessible through the accel\_ctr\_encrypt pointer. The ``blocks'' value is the number of complete blocks to process. The ``IV'' is the CTR counter vector. It is an input upon calling this function and must be -updated by the function before returning. The ``mode'' value indicates whether the counter is big ($mode = 1$) or little ($mode = 0$) endian. +updated by the function before returning. The ``mode'' value indicates whether the counter is big (mode = CTR\_COUNTER\_BIG\_ENDIAN) or +little (mode = CTR\_COUNTER\_LITTLE\_ENDIAN) endian. This function (and the way it's called) differs from the other two since ctr\_encrypt() allows any size input plaintext. The accelerator will only be called if the following conditions are met. @@ -4101,10 +4340,10 @@ struct ltc_hash_descriptor { unsigned long hashsize; /** Input block size in octets */ unsigned long blocksize; - /** ASN.1 DER identifier */ - unsigned char DER[64]; + /** ASN.1 OID */ + unsigned long OID[16]; /** Length of DER encoding */ - unsigned long DERlen; + unsigned long OIDlen; /** Init a hash state @param hash The hash to initialize @return CRYPT_OK if successful @@ -4144,8 +4383,8 @@ The ``hashsize'' variable indicates the length of the output in octets. The `blocksize'' variable indicates the length of input (in octets) that the hash processes in a given invokation. -\subsection{DER Identifier} -This is the DER identifier (including the SEQUENCE header). This is used solely for PKCS \#1 style signatures. +\subsection{OID Identifier} +This is the universal ASN.1 Object Identifier for the hash. \subsection{Initialization} The init function initializes the hash and prepares it to process message bytes. @@ -4251,3 +4490,7 @@ but should at least maintain the same level of state entropy. \input{crypt.ind} \end{document} + +% $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $ +% $Revision: 1.32 $ +% $Date: 2005/06/09 00:36:17 $ diff --git a/demos/encrypt.c b/demos/encrypt.c index 67627f7..1f4d746 100644 --- a/demos/encrypt.c +++ b/demos/encrypt.c @@ -235,3 +235,7 @@ int main(int argc, char *argv[]) } return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/demos/hashsum.c b/demos/hashsum.c index 23946cc..4e9b0fb 100644 --- a/demos/hashsum.c +++ b/demos/hashsum.c @@ -113,3 +113,7 @@ void register_algs(void) #endif } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/demos/multi.c b/demos/multi.c index fdc8dc6..33d17a2 100644 --- a/demos/multi.c +++ b/demos/multi.c @@ -104,3 +104,7 @@ int main(void) return EXIT_SUCCESS; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/demos/small.c b/demos/small.c index bc9793b..f320424 100644 --- a/demos/small.c +++ b/demos/small.c @@ -8,3 +8,7 @@ int main(void) register_hash(&sha256_desc); return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/demos/test.c b/demos/test.c index 290861d..b1e3966 100644 --- a/demos/test.c +++ b/demos/test.c @@ -2,18 +2,23 @@ int main(void) { + int x; reg_algs(); printf("build == \n%s\n", crypt_build_settings); - printf("\ncipher_test..."); fflush(stdout); printf(cipher_hash_test() ? "failed" : "passed"); - printf("\nmodes_test..."); fflush(stdout); printf(modes_test() ? "failed" : "passed"); - printf("\nmac_test..."); fflush(stdout); printf(mac_test() ? "failed" : "passed"); - printf("\npkcs_1_test..."); fflush(stdout); printf(pkcs_1_test() ? "failed" : "passed"); - printf("\nstore_test..."); fflush(stdout); printf(store_test() ? "failed" : "passed"); - printf("\nrsa_test..."); fflush(stdout); printf(rsa_test() ? "failed" : "passed"); - printf("\necc_test..."); fflush(stdout); printf(ecc_tests() ? "failed" : "passed"); - printf("\ndsa_test..."); fflush(stdout); printf(dsa_test() ? "failed" : "passed"); - printf("\ndh_test..."); fflush(stdout); printf(dh_tests() ? "failed" : "passed"); - printf("\nder_test..."); fflush(stdout); printf(der_tests() ? "failed" : "passed"); - + printf("\nstore_test...."); fflush(stdout); x = store_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\ncipher_test..."); fflush(stdout); x = cipher_hash_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nmodes_test...."); fflush(stdout); x = modes_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\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("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\nrsa_test......"); fflush(stdout); x = rsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\ndsa_test......"); fflush(stdout); x = dsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\ndh_test......."); fflush(stdout); x = dh_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); + printf("\n"); return EXIT_SUCCESS; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/demos/timing.c b/demos/timing.c index 54c0462..444d08d 100644 --- a/demos/timing.c +++ b/demos/timing.c @@ -17,7 +17,10 @@ time_sqr(); time_rsa(); time_ecc(); time_dh(); - return EXIT_SUCCESS; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/demos/tv_gen.c b/demos/tv_gen.c index c37d1af..e8ef4e5 100644 --- a/demos/tv_gen.c +++ b/demos/tv_gen.c @@ -664,3 +664,7 @@ int main(void) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/doc/crypt.pdf b/doc/crypt.pdf index 9eb60c6..a50ea92 100644 Binary files a/doc/crypt.pdf and b/doc/crypt.pdf differ diff --git a/doc/footer.html b/doc/footer.html index fe5338c..a1895ac 100644 --- a/doc/footer.html +++ b/doc/footer.html @@ -2,3 +2,9 @@ Code by Tom
Docs using doxygen + + diff --git a/doc/header.html b/doc/header.html index 426d4e3..231475d 100644 --- a/doc/header.html +++ b/doc/header.html @@ -4,3 +4,9 @@ + + diff --git a/genlist.sh b/genlist.sh index 73daa1d..832e8e7 100644 --- a/genlist.sh +++ b/genlist.sh @@ -4,3 +4,7 @@ export a=`echo -n "src/ciphers/aes/aes_enc.o *(MPIOBJECT) " ; find . -type f | s perl ./parsenames.pl OBJECTS "$a" export a=`find . -type f | grep [.]/src | grep [.]h | sed -e 'se\./ee' | xargs` perl ./parsenames.pl HEADERS "$a" + +# $Source: /cvs/libtom/libtomcrypt/genlist.sh,v $ +# $Revision: 1.3 $ +# $Date: 2005/05/05 14:49:27 $ diff --git a/makefile b/makefile index b38aa17..d3681f2 100644 --- a/makefile +++ b/makefile @@ -4,7 +4,7 @@ # Modified by Clay Culver # The version -VERSION=1.02 +VERSION=1.03 # Compiler and Linker Names #CC=gcc @@ -21,6 +21,8 @@ CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wn #CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ # -Wmissing-declarations -Wpointer-arith +ifndef IGNORE_SPEED + # optimize for SPEED CFLAGS += -O3 -funroll-loops @@ -30,6 +32,8 @@ CFLAGS += -fomit-frame-pointer # optimize for SIZE #CFLAGS += -Os -DLTC_SMALL_CODE +endif + # older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros # define this to help #CFLAGS += -DLTC_NO_ROLC @@ -58,13 +62,24 @@ INCPATH=/usr/include DATAPATH=/usr/share/doc/libtomcrypt/pdf #Who do we install as? +ifdef INSTALL_USER +USER=$(INSTALL_USER) +else USER=root +endif + +ifdef INSTALL_GROUP +GROUP=$(INSTALL_GROUP) +else GROUP=wheel +endif #List of objects to compile. #Leave MPI built-in or force developer to link against libtommath? +ifndef IGNORE_MPI MPIOBJECT=src/misc/mpi/mpi.o +endif OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o src/ciphers/anubis.o \ src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o \ @@ -115,29 +130,40 @@ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ -src/modes/ofb/ofb_start.o src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ -src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ -src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ +src/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/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ +src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \ -src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ -src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \ -src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ +src/pk/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 \ -src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ -src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ -src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \ +src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h src/headers/tommath_class.h \ +src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_misc.h \ +src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h TESTOBJECTS=demos/test.o HASHOBJECTS=demos/hashsum.o @@ -171,7 +197,7 @@ src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. -library: $(LIBTEST) $(LIBNAME) +library: $(LIBNAME) $(LIBTEST): cd testprof ; CFLAGS="$(CFLAGS)" make @@ -193,15 +219,15 @@ small: library $(SMALLOBJECTS) $(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN) tv_gen: library $(TVS) - $(CC) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) + $(CC) $(TVS) $(LIBNAME) -o $(TV) multi: library $(MULTIS) $(CC) $(MULTIS) $(LIBNAME) -o $(MULTI) -timing: library $(TIMINGS) - $(CC) $(TIMINGS) $(LIBTEST) $(LIBNAME) -o $(TIMING) +timing: library $(LIBTEST) $(TIMINGS) + $(CC) $(TIMINGS) $(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) -test: library $(TESTS) +test: library $(LIBTEST) $(TESTS) $(CC) $(TESTS) $(LIBTEST) $(LIBNAME) -o $(TEST) @@ -216,11 +242,17 @@ install: library docs install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH) -install_lib: library +install_test: $(LIBTEST) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) - install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) - install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) + install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH) + +profile: + CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov + ./timing + rm -f timing `find . -type f | grep [.][ao] | xargs` + CFLAGS="$(CFLAGS) -fprofile-use" make timing EXTRALIBS=-lgcov + #This rule cleans the source tree of all compiled code, not including the pdf #documentation. @@ -242,6 +274,7 @@ clean: rm -f $(TV) $(PROF) $(SMALL) $(CRYPT) $(HASHSUM) $(MULTI) $(TIMING) $(TEST) rm -rf doc/doxygen rm -f doc/*.pdf + rm -f *.txt #build the doxy files (requires Doxygen, tetex and patience) doxy: @@ -274,6 +307,8 @@ docdvi: crypt.tex #zipup the project (take that!) no_oops: clean cd .. ; cvs commit + echo Scanning for scratch/dirty files + find . -type f | grep -v CVS | xargs -n 1 bash mess.sh zipup: no_oops docs cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ @@ -283,3 +318,8 @@ zipup: no_oops docs zip -9r crypt-$(VERSION).zip libtomcrypt-$(VERSION) ; \ gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip ; \ mv -fv crypt* ~ ; rm -rf libtomcrypt-$(VERSION) + + +# $Source: /cvs/libtom/libtomcrypt/makefile,v $ +# $Revision: 1.67 $ +# $Date: 2005/06/09 00:39:26 $ diff --git a/makefile.icc b/makefile.icc index 41848dc..e7fcc1a 100644 --- a/makefile.icc +++ b/makefile.icc @@ -22,7 +22,7 @@ CC=icc #ARFLAGS=r # Compilation flags. Note the += does not write over the user's CFLAGS! -CFLAGS += -c -I./src/headers/ -DINTEL_CC +CFLAGS += -c -Isrc/headers/ -Itestprof/ -DINTEL_CC #The default rule for make builds the libtomcrypt library. default:library @@ -41,7 +41,13 @@ default:library # B - Blend of P4 and PM [mobile] # # Default to just generic max opts +ifdef LTC_SMALL +CFLAGS += -O2 -xP -ip +endif + +ifndef IGNORE_SPEED CFLAGS += -O3 -xP -ip +endif # want to see stuff? #CFLAGS += -opt_report @@ -122,29 +128,40 @@ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ -src/modes/ofb/ofb_start.o src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ -src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ -src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ +src/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/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ +src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \ -src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ -src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \ -src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ +src/pk/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 \ -src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ -src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ -src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \ +src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h src/headers/tommath_class.h \ +src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_misc.h \ +src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #ciphers come in two flavours... enc+dec and enc aes_enc.o: aes.c aes_tab.c @@ -214,4 +231,9 @@ install: library install -d -g root -o root $(DESTDIR)$(LIBPATH) install -d -g root -o root $(DESTDIR)$(INCPATH) install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) + install -g root -o root $(LIBTEST) $(DESTDIR)$(LIBPATH) install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) + +# $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $ +# $Revision: 1.32 $ +# $Date: 2005/05/23 03:12:44 $ diff --git a/makefile.msvc b/makefile.msvc index 16d4b8d..9db1e8f 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -57,29 +57,42 @@ src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj src/modes/ctr/ctr_start. src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj src/modes/ecb/ecb_encrypt.obj \ src/modes/ecb/ecb_start.obj src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj \ src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj \ -src/modes/ofb/ofb_start.obj src/pk/asn1/der/der_decode_integer.obj src/pk/asn1/der/der_encode_integer.obj \ -src/pk/asn1/der/der_get_multi_integer.obj src/pk/asn1/der/der_length_integer.obj \ -src/pk/asn1/der/der_put_multi_integer.obj src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \ -src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj \ +src/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/object_identifier/der_decode_object_identifier.obj \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ +src/pk/asn1/der/octet/der_decode_octet_string.obj src/pk/asn1/der/octet/der_encode_octet_string.obj \ +src/pk/asn1/der/octet/der_length_octet_string.obj \ +src/pk/asn1/der/printable_string/der_decode_printable_string.obj \ +src/pk/asn1/der/printable_string/der_encode_printable_string.obj \ +src/pk/asn1/der/printable_string/der_length_printable_string.obj \ +src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ +src/pk/asn1/der/sequence/der_encode_sequence.obj src/pk/asn1/der/sequence/der_encode_sequence_multi.obj \ +src/pk/asn1/der/sequence/der_length_sequence.obj \ +src/pk/asn1/der/short_integer/der_decode_short_integer.obj \ +src/pk/asn1/der/short_integer/der_encode_short_integer.obj \ +src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/dh/dh.obj src/pk/dsa/dsa_export.obj \ +src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_sign_hash.obj \ src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj src/pk/packet_store_header.obj \ src/pk/packet_valid_header.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ -src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v15_es_decode.obj \ -src/pk/pkcs1/pkcs_1_v15_es_encode.obj src/pk/pkcs1/pkcs_1_v15_sa_decode.obj \ -src/pk/pkcs1/pkcs_1_v15_sa_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \ -src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \ -src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_v15_decrypt_key.obj \ -src/pk/rsa/rsa_v15_encrypt_key.obj src/pk/rsa/rsa_v15_sign_hash.obj src/pk/rsa/rsa_v15_verify_hash.obj \ +src/pk/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 \ -src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ -src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ -src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \ +src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h src/headers/tommath_class.h \ +src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_misc.h \ +src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h + + #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c @@ -102,3 +115,7 @@ test: demos/test.c library 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 $ diff --git a/makefile.shared b/makefile.shared index 207ceea..aa653da 100644 --- a/makefile.shared +++ b/makefile.shared @@ -6,7 +6,7 @@ # Tom St Denis # The version -VERSION=0:102 +VERSION=0:103 # Compiler and Linker Names CC=libtool --mode=compile gcc @@ -18,14 +18,18 @@ CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow #CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ # -Wmissing-declarations -Wpointer-arith +ifndef IGNORE_SPEED + # optimize for SPEED -CFLAGS += -O3 -funroll-all-loops +CFLAGS += -O3 -funroll-loops # add -fomit-frame-pointer. hinders debugging! CFLAGS += -fomit-frame-pointer # optimize for SIZE -#CFLAGS += -Os +#CFLAGS += -Os -DLTC_SMALL_CODE + +endif # compile for DEBUGING (required for ccmalloc checking!!!) #CFLAGS += -g3 @@ -45,7 +49,6 @@ TV=tv_gen TEST=test TIMING=timing - #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. #DATAPATH-The directory to install the pdf docs. @@ -55,16 +58,27 @@ INCPATH=/usr/include DATAPATH=/usr/share/doc/libtomcrypt/pdf #Who do we install as? +ifdef INSTALL_USER +USER=$(INSTALL_USER) +else USER=root -GROUP=wheel +endif + +ifdef INSTALL_GROUP +GROUP=$(INSTALL_GROUP) +else +GROUP=wheel +endif #List of objects to compile. #Leave MPI built-in or force developer to link against libtommath? +ifndef IGNORE_MPI MPIOBJECT=src/misc/mpi/mpi.o - +else #If you don't want mpi.o then add this -#MPISHARED=$(LIBPATH)/libtommath.la +MPISHARED=$(LIBPATH)/libtommath.la +endif OBJECTS=src/ciphers/aes/aes_enc.o $(MPIOBJECT) src/ciphers/aes/aes.o src/ciphers/anubis.o \ src/ciphers/blowfish.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/khazad.o src/ciphers/noekeon.o \ @@ -115,29 +129,40 @@ src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o \ src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \ src/modes/ecb/ecb_start.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \ src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \ -src/modes/ofb/ofb_start.o src/pk/asn1/der/der_decode_integer.o src/pk/asn1/der/der_encode_integer.o \ -src/pk/asn1/der/der_get_multi_integer.o src/pk/asn1/der/der_length_integer.o \ -src/pk/asn1/der/der_put_multi_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ -src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ +src/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/object_identifier/der_decode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ +src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ +src/pk/asn1/der/octet/der_length_octet_string.o \ +src/pk/asn1/der/printable_string/der_decode_printable_string.o \ +src/pk/asn1/der/printable_string/der_encode_printable_string.o \ +src/pk/asn1/der/printable_string/der_length_printable_string.o \ +src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \ +src/pk/asn1/der/sequence/der_length_sequence.o \ +src/pk/asn1/der/short_integer/der_decode_short_integer.o \ +src/pk/asn1/der/short_integer/der_encode_short_integer.o \ +src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/dh/dh.o src/pk/dsa/dsa_export.o \ +src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o src/pk/packet_store_header.o \ src/pk/packet_valid_header.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ -src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v15_es_decode.o \ -src/pk/pkcs1/pkcs_1_v15_es_encode.o src/pk/pkcs1/pkcs_1_v15_sa_decode.o \ -src/pk/pkcs1/pkcs_1_v15_sa_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ -src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ -src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_v15_decrypt_key.o \ -src/pk/rsa/rsa_v15_encrypt_key.o src/pk/rsa/rsa_v15_sign_hash.o src/pk/rsa/rsa_v15_verify_hash.o \ +src/pk/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 \ -src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h \ -src/headers/tommath_class.h src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h \ -src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ -src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h +HEADERS=src/headers/tommath_superclass.h src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h \ +src/headers/tomcrypt_macros.h src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h \ +src/headers/tomcrypt_cipher.h src/headers/tomcrypt_pk.h src/headers/tommath_class.h \ +src/headers/ltc_tommath.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_misc.h \ +src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h TESTOBJECTS=demos/test.o HASHOBJECTS=demos/hashsum.o @@ -164,7 +189,7 @@ src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. -library: $(LIBTEST) $(LIBNAME) +library: $(LIBNAME) $(LIBTEST): cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBNAME=$(LIBTEST) make -f makefile.shared @@ -180,19 +205,22 @@ $(LIBNAME): $(OBJECTS) #This rule makes the hash program included with libtomcrypt hashsum: library gcc $(CFLAGS) demos/hashsum.c -o hashsum.o - gcc -o hashsum hashsum.o -ltomcrypt_prof -ltomcrypt $(MPISHARED) + gcc -o hashsum hashsum.o -ltomcrypt $(MPISHARED) #makes the crypt program crypt: library gcc $(CFLAGS) demos/encrypt.c -o encrypt.o - gcc -o crypt encrypt.o -ltomcrypt_prof -ltomcrypt $(MPISHARED) + gcc -o crypt encrypt.o -ltomcrypt $(MPISHARED) tv_gen: library $(TVS) - gcc -o tv_gen $(TVS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) + gcc -o tv_gen $(TVS) -ltomcrypt $(MPISHARED) -test: library $(TESTS) +test: library $(LIBTEST) $(TESTS) gcc -o $(TEST) $(TESTS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) -timing: library $(TIMINGS) +timing: library $(LIBTEST) $(TIMINGS) gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(MPISHARED) +# $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $ +# $Revision: 1.16 $ +# $Date: 2005/06/08 23:37:40 $ diff --git a/mess.sh b/mess.sh new file mode 100644 index 0000000..bf639ce --- /dev/null +++ b/mess.sh @@ -0,0 +1,4 @@ +#!/bin/bash +if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here" ; exit 1; fi + + diff --git a/notes/etc/saferp_optimizer.c b/notes/etc/saferp_optimizer.c index 664661a..feb58bc 100644 --- a/notes/etc/saferp_optimizer.c +++ b/notes/etc/saferp_optimizer.c @@ -171,3 +171,7 @@ printf(" }\n}\n\n"); return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/notes/etc/whirlgen.c b/notes/etc/whirlgen.c index 2880d3f..f64650b 100644 --- a/notes/etc/whirlgen.c +++ b/notes/etc/whirlgen.c @@ -89,3 +89,7 @@ int main(void) } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/notes/etc/whirltest.c b/notes/etc/whirltest.c index 9184f77..cf2e87c 100644 --- a/notes/etc/whirltest.c +++ b/notes/etc/whirltest.c @@ -13,3 +13,7 @@ int main(void) } } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/notes/tech0005.txt b/notes/tech0005.txt new file mode 100644 index 0000000..8f393d5 --- /dev/null +++ b/notes/tech0005.txt @@ -0,0 +1,18 @@ +Tech Note 0005 +Minimizing Code Space +Tom St Denis + +Introduction +------------ + +Tweaking... + +You can disable whole classes of algorithms on the command line with the LTC_NO_* defines. From there you can manually turn on what you want to enable. + +The following build with GCC 3.4.3 on an AMD64 box gets you AES, CTR mode, SHA-256, HMAC, Yarrow, full RSA PKCS #1, PKCS #5, ASN.1 DER and MPI in +roughly 80KB of code. + +CFLAGS="-DSC_RSA_1 -DLTC_NO_CIPHERS -DLTC_NO_HASHES -DLTC_NO_PRNGS -DLTC_NO_MACS -DLTC_NO_MODES -DLTC_NO_PK -DRIJNDAEL -DCTR -DSHA256 \ +-DHMAC -DYARROW -DMRSA -DMPI -Os -fomit-frame-pointer" make IGNORE_SPEED=1 + +Neato eh? diff --git a/parsenames.pl b/parsenames.pl index d6466c5..761f036 100644 --- a/parsenames.pl +++ b/parsenames.pl @@ -20,3 +20,7 @@ foreach my $obj (@a) { if ($ARGV[0] eq "HEADERS") { print "testprof/tomcrypt_test.h"; } print "\n\n"; + +# $Source: /cvs/libtom/libtomcrypt/parsenames.pl,v $ +# $Revision: 1.3 $ +# $Date: 2005/05/05 14:49:27 $ diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..b652110 --- /dev/null +++ b/run.sh @@ -0,0 +1,35 @@ +#!/bin/bash +bash build.sh " $1" "$2 -O2" "$3 IGNORE_SPEED=1" +if [ -a testok.txt ] && [ -f testok.txt ]; then + echo +else + echo + echo "Test failed" + exit 1 +fi + +rm -f testok.txt +bash build.sh " $1" "$2 -Os" " $3 IGNORE_SPEED=1 LTC_SMALL=1" +if [ -a testok.txt ] && [ -f testok.txt ]; then + echo +else + echo + echo "Test failed" + exit 1 +fi + +rm -f testok.txt +bash build.sh " $1" " $2" " $3" +if [ -a testok.txt ] && [ -f testok.txt ]; then + echo +else + echo + echo "Test failed" + exit 1 +fi + +exit 0 + +# $Source: /cvs/libtom/libtomcrypt/run.sh,v $ +# $Revision: 1.13 $ +# $Date: 2005/05/11 18:59:53 $ diff --git a/src/ciphers/aes/aes.c b/src/ciphers/aes/aes.c index e698efd..584cd1e 100644 --- a/src/ciphers/aes/aes.c +++ b/src/ciphers/aes/aes.c @@ -127,7 +127,7 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s #endif LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); - + if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } @@ -747,3 +747,7 @@ int ECB_KS(int *keysize) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/aes/aes_tab.c b/src/ciphers/aes/aes_tab.c index 0ad1dfe..ee639d8 100644 --- a/src/ciphers/aes/aes_tab.c +++ b/src/ciphers/aes/aes_tab.c @@ -1018,3 +1018,7 @@ static const ulong32 rcon[] = { 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/anubis.c b/src/ciphers/anubis.c index 7e2af60..84f7ae1 100644 --- a/src/ciphers/anubis.c +++ b/src/ciphers/anubis.c @@ -1548,3 +1548,7 @@ int anubis_keysize(int *keysize) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/blowfish.c b/src/ciphers/blowfish.c index 2f0385d..44189b2 100644 --- a/src/ciphers/blowfish.c +++ b/src/ciphers/blowfish.c @@ -581,3 +581,7 @@ int blowfish_keysize(int *keysize) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/cast5.c b/src/ciphers/cast5.c index 2b8e4a5..654b6ef 100644 --- a/src/ciphers/cast5.c +++ b/src/ciphers/cast5.c @@ -709,3 +709,7 @@ int cast5_keysize(int *keysize) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/des.c b/src/ciphers/des.c index d42c5fa..4d3629b 100644 --- a/src/ciphers/des.c +++ b/src/ciphers/des.c @@ -1888,3 +1888,7 @@ int des3_keysize(int *keysize) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/khazad.c b/src/ciphers/khazad.c index 4626923..d8e6902 100644 --- a/src/ciphers/khazad.c +++ b/src/ciphers/khazad.c @@ -845,3 +845,7 @@ int khazad_keysize(int *keysize) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/noekeon.c b/src/ciphers/noekeon.c index 194cdbe..0a54a22 100644 --- a/src/ciphers/noekeon.c +++ b/src/ciphers/noekeon.c @@ -290,3 +290,7 @@ int noekeon_keysize(int *keysize) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 6382941..47b7276 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -348,3 +348,7 @@ int rc2_keysize(int *keysize) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/rc5.c b/src/ciphers/rc5.c index 32f666f..070ff5a 100644 --- a/src/ciphers/rc5.c +++ b/src/ciphers/rc5.c @@ -308,3 +308,7 @@ int rc5_keysize(int *keysize) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/rc6.c b/src/ciphers/rc6.c index 996c015..7a4558e 100644 --- a/src/ciphers/rc6.c +++ b/src/ciphers/rc6.c @@ -337,3 +337,7 @@ int rc6_keysize(int *keysize) #endif /*RC6*/ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/safer/safer.c b/src/ciphers/safer/safer.c index e6e073a..6c27679 100644 --- a/src/ciphers/safer/safer.c +++ b/src/ciphers/safer/safer.c @@ -481,3 +481,7 @@ int safer_sk128_test(void) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/safer/safer_tab.c b/src/ciphers/safer/safer_tab.c index f63ba6c..6c9abe9 100644 --- a/src/ciphers/safer/safer_tab.c +++ b/src/ciphers/safer/safer_tab.c @@ -62,3 +62,7 @@ const unsigned char safer_lbox[256] = { #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/safer/saferp.c b/src/ciphers/safer/saferp.c index 17112f4..8474784 100644 --- a/src/ciphers/safer/saferp.c +++ b/src/ciphers/safer/saferp.c @@ -549,3 +549,7 @@ int saferp_keysize(int *keysize) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/skipjack.c b/src/ciphers/skipjack.c index e2431af..7635042 100644 --- a/src/ciphers/skipjack.c +++ b/src/ciphers/skipjack.c @@ -329,3 +329,7 @@ int skipjack_keysize(int *keysize) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/twofish/twofish.c b/src/ciphers/twofish/twofish.c index 7dbe9b7..bd71d03 100644 --- a/src/ciphers/twofish/twofish.c +++ b/src/ciphers/twofish/twofish.c @@ -576,7 +576,7 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k b = RORc(b ^ (t2 + t1 + k[3]), 1); t2 = g1_func(b, skey); - t1 = g_func(a, key) + t2; + t1 = g_func(a, skey) + t2; c = ROLc(c, 1) ^ (t1 + k[0]); d = RORc(d ^ (t2 + t1 + k[1]), 1); k -= 4; @@ -700,3 +700,7 @@ int twofish_keysize(int *keysize) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/twofish/twofish_tab.c b/src/ciphers/twofish/twofish_tab.c index 0bffade..b3d0272 100644 --- a/src/ciphers/twofish/twofish_tab.c +++ b/src/ciphers/twofish/twofish_tab.c @@ -490,3 +490,7 @@ static const ulong32 rs_tab7[256] = { #endif /* TWOFISH_ALL_TABLES */ #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/ciphers/xtea.c b/src/ciphers/xtea.c index 98546df..2712f87 100644 --- a/src/ciphers/xtea.c +++ b/src/ciphers/xtea.c @@ -201,3 +201,7 @@ int xtea_keysize(int *keysize) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ccm/ccm_memory.c b/src/encauth/ccm/ccm_memory.c index 34a254d..abca36a 100644 --- a/src/encauth/ccm/ccm_memory.c +++ b/src/encauth/ccm/ccm_memory.c @@ -293,7 +293,6 @@ int ccm_memory(int cipher, #ifdef LTC_CLEAN_STACK zeromem(skey, sizeof(*skey)); - zeromem(B, sizeof(B)); zeromem(PAD, sizeof(PAD)); zeromem(CTRPAD, sizeof(CTRPAD)); #endif @@ -304,3 +303,7 @@ int ccm_memory(int cipher, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ccm/ccm_test.c b/src/encauth/ccm/ccm_test.c index ee78523..fb8e9a1 100644 --- a/src/encauth/ccm/ccm_test.c +++ b/src/encauth/ccm/ccm_test.c @@ -168,3 +168,7 @@ int ccm_test(void) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_addheader.c b/src/encauth/eax/eax_addheader.c index 3004025..8323258 100644 --- a/src/encauth/eax/eax_addheader.c +++ b/src/encauth/eax/eax_addheader.c @@ -32,3 +32,7 @@ int eax_addheader(eax_state *eax, const unsigned char *header, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_decrypt.c b/src/encauth/eax/eax_decrypt.c index 8711d2d..c7af001 100644 --- a/src/encauth/eax/eax_decrypt.c +++ b/src/encauth/eax/eax_decrypt.c @@ -44,3 +44,7 @@ int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_decrypt_verify_memory.c b/src/encauth/eax/eax_decrypt_verify_memory.c index 3fcab46..34fba82 100644 --- a/src/encauth/eax/eax_decrypt_verify_memory.c +++ b/src/encauth/eax/eax_decrypt_verify_memory.c @@ -102,3 +102,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_done.c b/src/encauth/eax/eax_done.c index 1d43651..50b0957 100644 --- a/src/encauth/eax/eax_done.c +++ b/src/encauth/eax/eax_done.c @@ -88,3 +88,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_encrypt.c b/src/encauth/eax/eax_encrypt.c index da23a8c..19014e3 100644 --- a/src/encauth/eax/eax_encrypt.c +++ b/src/encauth/eax/eax_encrypt.c @@ -45,3 +45,7 @@ int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_encrypt_authenticate_memory.c b/src/encauth/eax/eax_encrypt_authenticate_memory.c index 8a601cf..67c1ee2 100644 --- a/src/encauth/eax/eax_encrypt_authenticate_memory.c +++ b/src/encauth/eax/eax_encrypt_authenticate_memory.c @@ -76,3 +76,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_init.c b/src/encauth/eax/eax_init.c index 5a20db0..517f239 100644 --- a/src/encauth/eax/eax_init.c +++ b/src/encauth/eax/eax_init.c @@ -108,11 +108,9 @@ int eax_init(eax_state *eax, int cipher, /* note we don't finish the headeromac, this allows us to add more header later */ /* setup the CTR mode */ - if ((err = ctr_start(cipher, eax->N, key, keylen, 0, &eax->ctr)) != CRYPT_OK) { + if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) { goto LBL_ERR; } - /* use big-endian counter */ - eax->ctr.mode = 1; /* setup the OMAC for the ciphertext */ if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { @@ -140,3 +138,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/eax/eax_test.c b/src/encauth/eax/eax_test.c index 777dea1..879d43e 100644 --- a/src/encauth/eax/eax_test.c +++ b/src/encauth/eax/eax_test.c @@ -276,3 +276,7 @@ int eax_test(void) } #endif /* EAX_MODE */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_add_aad.c b/src/encauth/gcm/gcm_add_aad.c index cdcc0d9..585dd87 100644 --- a/src/encauth/gcm/gcm_add_aad.c +++ b/src/encauth/gcm/gcm_add_aad.c @@ -27,8 +27,11 @@ int gcm_add_aad(gcm_state *gcm, const unsigned char *adata, unsigned long adatalen) { - unsigned long x, y; + unsigned long x; int err; +#ifdef LTC_FAST + unsigned long y; +#endif LTC_ARGCHK(gcm != NULL); if (adatalen > 0) { @@ -115,3 +118,7 @@ int gcm_add_aad(gcm_state *gcm, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_add_iv.c b/src/encauth/gcm/gcm_add_iv.c index 7faf4c0..7b7633f 100644 --- a/src/encauth/gcm/gcm_add_iv.c +++ b/src/encauth/gcm/gcm_add_iv.c @@ -88,3 +88,7 @@ int gcm_add_iv(gcm_state *gcm, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_done.c b/src/encauth/gcm/gcm_done.c index 8b3a6dd..c0656f5 100644 --- a/src/encauth/gcm/gcm_done.c +++ b/src/encauth/gcm/gcm_done.c @@ -75,3 +75,7 @@ int gcm_done(gcm_state *gcm, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_gf_mult.c b/src/encauth/gcm/gcm_gf_mult.c index a870c91..f48e664 100644 --- a/src/encauth/gcm/gcm_gf_mult.c +++ b/src/encauth/gcm/gcm_gf_mult.c @@ -31,6 +31,7 @@ static void gcm_rightshift(unsigned char *a) static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static const unsigned char poly[] = { 0x00, 0xE1 }; + /** GCM GF multiplier (internal use only) @param a First value @@ -87,3 +88,7 @@ void gcm_mult_h(gcm_state *gcm, unsigned char *I) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_init.c b/src/encauth/gcm/gcm_init.c index 35a5ab8..417532f 100644 --- a/src/encauth/gcm/gcm_init.c +++ b/src/encauth/gcm/gcm_init.c @@ -17,6 +17,46 @@ #ifdef GCM_MODE +#ifdef GCM_TABLES + +/* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the + * lower 16 bits are not zero'ed I removed the upper 14 bytes */ +static const unsigned char gcm_shift_table[256*2] = { +0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e, +0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e, +0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e, +0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e, +0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e, +0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e, +0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e, +0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e, +0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce, +0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde, +0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee, +0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe, +0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e, +0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e, +0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae, +0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe, +0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e, +0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e, +0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e, +0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e, +0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e, +0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e, +0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e, +0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e, +0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce, +0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde, +0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee, +0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe, +0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e, +0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e, +0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae, +0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe }; + +#endif + /** Initialize a GCM state @param gcm The GCM state to initialize @@ -31,7 +71,7 @@ int gcm_init(gcm_state *gcm, int cipher, int err; unsigned char B[16]; #ifdef GCM_TABLES - int x, y; + int x, y, z, t; #endif LTC_ARGCHK(gcm != NULL); @@ -72,17 +112,34 @@ int gcm_init(gcm_state *gcm, int cipher, #ifdef GCM_TABLES /* setup tables */ + + /* generate the first table as it has no shifting (from which we make the other tables) */ zeromem(B, 16); - for (x = 0; x < 16; x++) { - for (y = 0; y < 256; y++) { - B[x] = y; - gcm_gf_mult(gcm->H, B, &gcm->PC[x][y][0]); - } - B[x] = 0; + for (y = 0; y < 256; y++) { + B[0] = y; + gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]); } + + /* now generate the rest of the tables based the previous table */ + for (x = 1; x < 16; x++) { + for (y = 0; y < 256; y++) { + /* now shift it right by 8 bits */ + t = gcm->PC[x-1][y][15]; + for (z = 15; z > 0; z--) { + gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1]; + } + gcm->PC[x][y][0] = gcm_shift_table[t<<1]; + gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; + } + } + #endif return CRYPT_OK; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_memory.c b/src/encauth/gcm/gcm_memory.c index e062413..47b7206 100644 --- a/src/encauth/gcm/gcm_memory.c +++ b/src/encauth/gcm/gcm_memory.c @@ -87,3 +87,7 @@ LTC_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_process.c b/src/encauth/gcm/gcm_process.c index 577967b..a24eefb 100644 --- a/src/encauth/gcm/gcm_process.c +++ b/src/encauth/gcm/gcm_process.c @@ -141,3 +141,7 @@ int gcm_process(gcm_state *gcm, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_reset.c b/src/encauth/gcm/gcm_reset.c index e73bf66..affdc1b 100644 --- a/src/encauth/gcm/gcm_reset.c +++ b/src/encauth/gcm/gcm_reset.c @@ -38,3 +38,7 @@ int gcm_reset(gcm_state *gcm) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/gcm/gcm_test.c b/src/encauth/gcm/gcm_test.c index bc6ad7e..3e45705 100644 --- a/src/encauth/gcm/gcm_test.c +++ b/src/encauth/gcm/gcm_test.c @@ -281,7 +281,6 @@ int gcm_test(void) }; int idx, err; unsigned long x, y; - gcm_state gcm; unsigned char out[2][64], T[2][16]; /* find aes */ @@ -363,3 +362,7 @@ int gcm_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_decrypt.c b/src/encauth/ocb/ocb_decrypt.c index d3bf480..9551aa7 100644 --- a/src/encauth/ocb/ocb_decrypt.c +++ b/src/encauth/ocb/ocb_decrypt.c @@ -71,3 +71,7 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_decrypt_verify_memory.c b/src/encauth/ocb/ocb_decrypt_verify_memory.c index 378a8af..d33550a 100644 --- a/src/encauth/ocb/ocb_decrypt_verify_memory.c +++ b/src/encauth/ocb/ocb_decrypt_verify_memory.c @@ -80,3 +80,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_done_decrypt.c b/src/encauth/ocb/ocb_done_decrypt.c index 9f8b1b9..a28909c 100644 --- a/src/encauth/ocb/ocb_done_decrypt.c +++ b/src/encauth/ocb/ocb_done_decrypt.c @@ -74,3 +74,7 @@ LBL_ERR: #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_done_encrypt.c b/src/encauth/ocb/ocb_done_encrypt.c index 1a07569..10062fe 100644 --- a/src/encauth/ocb/ocb_done_encrypt.c +++ b/src/encauth/ocb/ocb_done_encrypt.c @@ -40,3 +40,7 @@ int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptle #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_encrypt.c b/src/encauth/ocb/ocb_encrypt.c index ba39c60..a3356c6 100644 --- a/src/encauth/ocb/ocb_encrypt.c +++ b/src/encauth/ocb/ocb_encrypt.c @@ -64,3 +64,7 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c b/src/encauth/ocb/ocb_encrypt_authenticate_memory.c index bcc9cfb..e963267 100644 --- a/src/encauth/ocb/ocb_encrypt_authenticate_memory.c +++ b/src/encauth/ocb/ocb_encrypt_authenticate_memory.c @@ -78,3 +78,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_init.c b/src/encauth/ocb/ocb_init.c index 57e04af..84f113a 100644 --- a/src/encauth/ocb/ocb_init.c +++ b/src/encauth/ocb/ocb_init.c @@ -127,3 +127,7 @@ int ocb_init(ocb_state *ocb, int cipher, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_ntz.c b/src/encauth/ocb/ocb_ntz.c index 4ffe7e8..3862579 100644 --- a/src/encauth/ocb/ocb_ntz.c +++ b/src/encauth/ocb/ocb_ntz.c @@ -36,3 +36,7 @@ int ocb_ntz(unsigned long x) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_shift_xor.c b/src/encauth/ocb/ocb_shift_xor.c index b63b022..2b9364b 100644 --- a/src/encauth/ocb/ocb_shift_xor.c +++ b/src/encauth/ocb/ocb_shift_xor.c @@ -33,3 +33,7 @@ void ocb_shift_xor(ocb_state *ocb, unsigned char *Z) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/ocb_test.c b/src/encauth/ocb/ocb_test.c index d6cb14b..a6ac51b 100644 --- a/src/encauth/ocb/ocb_test.c +++ b/src/encauth/ocb/ocb_test.c @@ -231,3 +231,7 @@ int ocb_test(void) -- hard to stream [you can't emit ciphertext until full block] -- The setup is somewhat complicated... */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/encauth/ocb/s_ocb_done.c b/src/encauth/ocb/s_ocb_done.c index 6f6e63d..4a0d5be 100644 --- a/src/encauth/ocb/s_ocb_done.c +++ b/src/encauth/ocb/s_ocb_done.c @@ -138,3 +138,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/chc/chc.c b/src/hashes/chc/chc.c index 67dd090..cb7fde4 100644 --- a/src/hashes/chc/chc.c +++ b/src/hashes/chc/chc.c @@ -291,3 +291,7 @@ int chc_test(void) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/helper/hash_file.c b/src/hashes/helper/hash_file.c index 78c290a..8354d8d 100644 --- a/src/hashes/helper/hash_file.c +++ b/src/hashes/helper/hash_file.c @@ -51,3 +51,7 @@ int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *ou #endif } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/helper/hash_filehandle.c b/src/hashes/helper/hash_filehandle.c index c02c5a7..db85063 100644 --- a/src/hashes/helper/hash_filehandle.c +++ b/src/hashes/helper/hash_filehandle.c @@ -64,3 +64,7 @@ int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outle #endif } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/helper/hash_memory.c b/src/hashes/helper/hash_memory.c index 9786948..37eaf19 100644 --- a/src/hashes/helper/hash_memory.c +++ b/src/hashes/helper/hash_memory.c @@ -62,3 +62,7 @@ LBL_ERR: return err; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/helper/hash_memory_multi.c b/src/hashes/helper/hash_memory_multi.c index ce22283..bd23d61 100644 --- a/src/hashes/helper/hash_memory_multi.c +++ b/src/hashes/helper/hash_memory_multi.c @@ -80,3 +80,7 @@ LBL_ERR: va_end(args); return err; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/md2.c b/src/hashes/md2.c index 5381771..82640b6 100644 --- a/src/hashes/md2.c +++ b/src/hashes/md2.c @@ -24,11 +24,9 @@ const struct ltc_hash_descriptor md2_desc = 16, 16, - /* DER encoding */ - { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, - 0x04, 0x10 }, - 18, + /* OID */ + { 1, 2, 840, 113549, 2, 2, }, + 6, &md2_init, &md2_process, @@ -246,3 +244,7 @@ int md2_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/md4.c b/src/hashes/md4.c index 477f5b0..790729a 100644 --- a/src/hashes/md4.c +++ b/src/hashes/md4.c @@ -24,9 +24,9 @@ const struct ltc_hash_descriptor md4_desc = 16, 64, - /* DER encoding (not yet supported) */ - { 0x00 }, - 0, + /* OID */ + { 1, 2, 840, 113549, 2, 4, }, + 6, &md4_init, &md4_process, @@ -300,3 +300,7 @@ int md4_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/md5.c b/src/hashes/md5.c index e2e5c74..6595076 100644 --- a/src/hashes/md5.c +++ b/src/hashes/md5.c @@ -25,11 +25,9 @@ const struct ltc_hash_descriptor md5_desc = 16, 64, - /* DER identifier */ - { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, - 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, - 0x04, 0x10 }, - 18, + /* OID */ + { 1, 2, 840, 113549, 2, 5, }, + 6, &md5_init, &md5_process, @@ -363,3 +361,7 @@ int md5_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/rmd128.c b/src/hashes/rmd128.c index 1c304a1..d4f90e2 100644 --- a/src/hashes/rmd128.c +++ b/src/hashes/rmd128.c @@ -30,9 +30,9 @@ const struct ltc_hash_descriptor rmd128_desc = 16, 64, - /* DER identifier (not supported) */ - { 0x00 }, - 0, + /* OID */ + { 1, 0, 10118, 3, 0, 50 }, + 6, &rmd128_init, &rmd128_process, @@ -403,3 +403,7 @@ int rmd128_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/rmd160.c b/src/hashes/rmd160.c index a617152..bdd1265 100644 --- a/src/hashes/rmd160.c +++ b/src/hashes/rmd160.c @@ -30,10 +30,9 @@ const struct ltc_hash_descriptor rmd160_desc = 20, 64, - /* DER identifier */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, - 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }, - 15, + /* OID */ + { 1, 3, 36, 3, 2, 1, }, + 6, &rmd160_init, &rmd160_process, @@ -463,3 +462,7 @@ int rmd160_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/sha1.c b/src/hashes/sha1.c index 267729b..b297c99 100644 --- a/src/hashes/sha1.c +++ b/src/hashes/sha1.c @@ -25,10 +25,9 @@ const struct ltc_hash_descriptor sha1_desc = 20, 64, - /* DER identifier */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, - 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 }, - 15, + /* OID */ + { 1, 3, 14, 3, 2, 26, }, + 6, &sha1_init, &sha1_process, @@ -282,3 +281,7 @@ int sha1_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/sha2/sha224.c b/src/hashes/sha2/sha224.c index 8c0dcde..639c5ec 100644 --- a/src/hashes/sha2/sha224.c +++ b/src/hashes/sha2/sha224.c @@ -20,9 +20,9 @@ const struct ltc_hash_descriptor sha224_desc = 28, 64, - /* DER identifier (not supported) */ - { 0x00 }, - 0, + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, + 9, &sha224_init, &sha256_process, @@ -118,3 +118,7 @@ int sha224_test(void) #endif } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/sha2/sha256.c b/src/hashes/sha2/sha256.c index 85eba2a..59c211e 100644 --- a/src/hashes/sha2/sha256.c +++ b/src/hashes/sha2/sha256.c @@ -24,11 +24,9 @@ const struct ltc_hash_descriptor sha256_desc = 32, 64, - /* DER identifier */ - { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, - 0x00, 0x04, 0x20 }, - 19, + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, + 9, &sha256_init, &sha256_process, @@ -335,3 +333,7 @@ int sha256_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/sha2/sha384.c b/src/hashes/sha2/sha384.c index 912145c..78bda80 100644 --- a/src/hashes/sha2/sha384.c +++ b/src/hashes/sha2/sha384.c @@ -20,11 +20,9 @@ const struct ltc_hash_descriptor sha384_desc = 48, 128, - /* DER identifier */ - { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, - 0x00, 0x04, 0x30 }, - 19, + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 2, }, + 9, &sha384_init, &sha512_process, @@ -130,3 +128,7 @@ int sha384_test(void) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/sha2/sha512.c b/src/hashes/sha2/sha512.c index 3238f2b..346a1b0 100644 --- a/src/hashes/sha2/sha512.c +++ b/src/hashes/sha2/sha512.c @@ -24,11 +24,9 @@ const struct ltc_hash_descriptor sha512_desc = 64, 128, - /* DER identifier */ - { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, - 0x00, 0x04, 0x40 }, - 19, + /* OID */ + { 2, 16, 840, 1, 101, 3, 4, 2, 3, }, + 9, &sha512_init, &sha512_process, @@ -314,3 +312,7 @@ int sha512_test(void) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/tiger.c b/src/hashes/tiger.c index a1cd888..978cd71 100644 --- a/src/hashes/tiger.c +++ b/src/hashes/tiger.c @@ -25,11 +25,9 @@ const struct ltc_hash_descriptor tiger_desc = 24, 64, - /* DER identifier */ - { 0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, - 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, - 0x00, 0x04, 0x18 }, - 19, + /* OID */ + { 1, 3, 6, 1, 4, 1, 11591, 12, 2, }, + 9, &tiger_init, &tiger_process, @@ -809,3 +807,7 @@ Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFG + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/whirl/whirl.c b/src/hashes/whirl/whirl.c index ff0b436..3cd946e 100644 --- a/src/hashes/whirl/whirl.c +++ b/src/hashes/whirl/whirl.c @@ -25,9 +25,9 @@ const struct ltc_hash_descriptor whirlpool_desc = 64, 64, - /* DER encoding (not yet supported) */ - { 0x00 }, - 0, + /* OID */ + { 1, 0, 10118, 3, 0, 55 }, + 6, &whirlpool_init, &whirlpool_process, @@ -307,3 +307,7 @@ int whirlpool_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/hashes/whirl/whirltab.c b/src/hashes/whirl/whirltab.c index fb99bea..d38ef7c 100644 --- a/src/hashes/whirl/whirltab.c +++ b/src/hashes/whirl/whirltab.c @@ -577,3 +577,7 @@ CONST64(0xca2dbf07ad5a8333), CONST64(0x6302aa71c81949d9), }; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/ltc_tommath.h b/src/headers/ltc_tommath.h index 05212e5..07d439e 100644 --- a/src/headers/ltc_tommath.h +++ b/src/headers/ltc_tommath.h @@ -575,3 +575,7 @@ extern const char *mp_s_rmap; #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt.h b/src/headers/tomcrypt.h index 0d34c74..a5c1548 100644 --- a/src/headers/tomcrypt.h +++ b/src/headers/tomcrypt.h @@ -16,8 +16,8 @@ extern "C" { #endif /* version */ -#define CRYPT 0x0102 -#define SCRYPT "1.02" +#define CRYPT 0x0103 +#define SCRYPT "1.03" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 128 @@ -79,3 +79,7 @@ enum { #endif /* TOMCRYPT_H_ */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_argchk.h b/src/headers/tomcrypt_argchk.h index 5c8759d..8de8af3 100644 --- a/src/headers/tomcrypt_argchk.h +++ b/src/headers/tomcrypt_argchk.h @@ -19,3 +19,7 @@ void crypt_argchk(char *v, char *s, int d); #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_cfg.h b/src/headers/tomcrypt_cfg.h index a0022d1..3b198fe 100644 --- a/src/headers/tomcrypt_cfg.h +++ b/src/headers/tomcrypt_cfg.h @@ -106,3 +106,7 @@ int XMEMCMP(const void *s1, const void *s2, size_t n); #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index af184c2..d162a2a 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -32,7 +32,7 @@ struct saferp_key { #ifdef RIJNDAEL struct rijndael_key { - ulong32 eK[64], dK[64]; + ulong32 eK[60], dK[60]; int Nr; }; #endif @@ -599,8 +599,15 @@ int cbc_done(symmetric_CBC *cbc); #endif #ifdef CTR -int ctr_start(int cipher, const unsigned char *IV, const unsigned char *key, - int keylen, int num_rounds, symmetric_CTR *ctr); + +#define CTR_COUNTER_LITTLE_ENDIAN 0 +#define CTR_COUNTER_BIG_ENDIAN 1 + +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr); int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); @@ -617,3 +624,7 @@ int unregister_cipher(const struct ltc_cipher_descriptor *cipher); int cipher_is_valid(int idx); + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h index d786f0b..abf5bc2 100644 --- a/src/headers/tomcrypt_custom.h +++ b/src/headers/tomcrypt_custom.h @@ -1,6 +1,3 @@ -/* This header is meant to be included before mycrypt.h in projects where - * you don't want to throw all the defines in a makefile. - */ #ifndef TOMCRYPT_CUSTOM_H_ #define TOMCRYPT_CUSTOM_H_ @@ -20,7 +17,9 @@ /* #define LTC_SMALL_CODE */ /* Enable self-test test vector checking */ -#define LTC_TEST +#ifndef LTC_NO_TEST + #define LTC_TEST +#endif /* clean the stack of functions which put private information on stack */ /* #define LTC_CLEAN_STACK */ @@ -38,6 +37,8 @@ /* #define LTC_NO_BSWAP */ /* ---> Symmetric Block Ciphers <--- */ +#ifndef LTC_NO_CIPHERS + #define BLOWFISH #define RC2 #define RC5 @@ -48,8 +49,12 @@ /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ #define TWOFISH -#define TWOFISH_TABLES -/* #define TWOFISH_ALL_TABLES */ +#ifndef LTC_NO_TABLES + #define TWOFISH_TABLES + /* #define TWOFISH_ALL_TABLES */ +#else + #define TWOFISH_SMALL +#endif /* #define TWOFISH_SMALL */ /* DES includes EDE triple-DES */ #define DES @@ -61,15 +66,23 @@ #define ANUBIS #define ANUBIS_TWEAK +#endif /* LTC_NO_CIPHERS */ + /* ---> Block Cipher Modes of Operation <--- */ +#ifndef LTC_NO_MODES + #define CFB #define OFB #define ECB #define CBC #define CTR +#endif /* LTC_NO_MODES */ + /* ---> One-Way Hash Functions <--- */ +#ifndef LTC_NO_HASHES + #define CHC_HASH #define WHIRLPOOL #define SHA512 @@ -84,7 +97,11 @@ #define RIPEMD128 #define RIPEMD160 +#endif /* LTC_NO_HASHES */ + /* ---> MAC functions <--- */ +#ifndef LTC_NO_MACS + #define HMAC #define OMAC #define PMAC @@ -95,6 +112,7 @@ #endif /* ---> Encrypt + Authenticate Modes <--- */ + #define EAX_MODE #if defined(EAX_MODE) && !(defined(CTR) && defined(OMAC)) #error EAX_MODE requires CTR and OMAC mode @@ -104,13 +122,20 @@ #define CCM_MODE #define GCM_MODE + /* Use 64KiB tables */ -#define GCM_TABLES +#ifndef LTC_NO_TABLES + #define GCM_TABLES +#endif + +#endif /* LTC_NO_MACS */ /* Various tidbits of modern neatoness */ #define BASE64 /* --> Pseudo Random Number Generators <--- */ +#ifndef LTC_NO_PRNGS + /* Yarrow */ #define YARROW /* which descriptor of AES to use? */ @@ -142,7 +167,11 @@ /* try /dev/urandom before trying /dev/random */ #define TRY_URANDOM_FIRST +#endif /* LTC_NO_PRNGS */ + /* ---> Public Key Crypto <--- */ +#ifndef LTC_NO_PK + #define MRSA /* Digital Signature Algorithm */ @@ -168,7 +197,6 @@ /* ECC */ #define MECC /* Supported Key Sizes */ -#define ECC160 #define ECC192 #define ECC224 #define ECC256 @@ -178,7 +206,11 @@ /* Include the MPI functionality? (required by the PK algorithms) */ #define MPI +#endif /* LTC_NO_PK */ + /* PKCS #1 (RSA) and #5 (Password Handling) stuff */ +#ifndef LTC_NO_PKCS + #define PKCS_1 #define PKCS_5 @@ -192,5 +224,11 @@ #error RSA/DSA requires ASN.1 DER functionality, make sure LTC_DER is enabled #endif +#endif /* LTC_NO_PKCS */ + #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_hash.h b/src/headers/tomcrypt_hash.h index d295a59..f92f2d6 100644 --- a/src/headers/tomcrypt_hash.h +++ b/src/headers/tomcrypt_hash.h @@ -132,10 +132,11 @@ extern struct ltc_hash_descriptor { unsigned long hashsize; /** Input block size in octets */ unsigned long blocksize; - /** ASN.1 DER identifier */ - unsigned char DER[64]; + /** ASN.1 OID */ + unsigned long OID[16]; /** Length of DER encoding */ - unsigned long DERlen; + unsigned long OIDlen; + /** Init a hash state @param hash The hash to initialize @return CRYPT_OK if successful @@ -292,29 +293,29 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) { \ unsigned long n; \ int err; \ - LTC_ARGCHK(md != NULL); \ - LTC_ARGCHK(in != NULL); \ + LTC_ARGCHK(md != NULL); \ + LTC_ARGCHK(in != NULL); \ if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ return CRYPT_INVALID_ARG; \ } \ - while (inlen > 0) { \ - if (md-> state_var .curlen == 0 && inlen >= block_size) { \ - if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ - return err; \ - } \ + while (inlen > 0) { \ + if (md-> state_var .curlen == 0 && inlen >= block_size) { \ + if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ + return err; \ + } \ md-> state_var .length += block_size * 8; \ - in += block_size; \ - inlen -= block_size; \ + in += block_size; \ + inlen -= block_size; \ } else { \ - n = MIN(inlen, (block_size - md-> state_var .curlen)); \ - memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ + n = MIN(inlen, (block_size - md-> state_var .curlen)); \ + memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ md-> state_var .curlen += n; \ - in += n; \ - inlen -= n; \ + in += n; \ + inlen -= n; \ if (md-> state_var .curlen == block_size) { \ - if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) {\ - return err; \ - } \ + if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ + return err; \ + } \ md-> state_var .length += 8*block_size; \ md-> state_var .curlen = 0; \ } \ @@ -322,3 +323,7 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) } \ return CRYPT_OK; \ } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h index 6b5e1ce..0ffbd45 100644 --- a/src/headers/tomcrypt_mac.h +++ b/src/headers/tomcrypt_mac.h @@ -295,3 +295,7 @@ int pelican_memory(const unsigned char *key, unsigned long keylen, unsigned char *out); #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_macros.h b/src/headers/tomcrypt_macros.h index f083984..b0d1533 100644 --- a/src/headers/tomcrypt_macros.h +++ b/src/headers/tomcrypt_macros.h @@ -132,7 +132,7 @@ asm __volatile__ ( \ #ifdef ENDIAN_32BITWORD #define STORE32L(x, y) \ - { unsigned long __t = (x); memcpy(y, &__t, 4); } + { ulong32 __t = (x); memcpy(y, &__t, 4); } #define LOAD32L(x, y) \ memcpy(&(x), y, 4); @@ -152,7 +152,7 @@ asm __volatile__ ( \ #else /* 64-bit words then */ #define STORE32L(x, y) \ - { unsigned long __t = (x); memcpy(y, &__t, 4); } + { ulong32 __t = (x); memcpy(y, &__t, 4); } #define LOAD32L(x, y) \ { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } @@ -193,7 +193,7 @@ asm __volatile__ ( \ #ifdef ENDIAN_32BITWORD #define STORE32H(x, y) \ - { unsigned long __t = (x); memcpy(y, &__t, 4); } + { ulong32 __t = (x); memcpy(y, &__t, 4); } #define LOAD32H(x, y) \ memcpy(&(x), y, 4); @@ -213,7 +213,7 @@ asm __volatile__ ( \ #else /* 64-bit words then */ #define STORE32H(x, y) \ - { unsigned long __t = (x); memcpy(y, &__t, 4); } + { ulong32 __t = (x); memcpy(y, &__t, 4); } #define LOAD32H(x, y) \ { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } @@ -371,3 +371,7 @@ static inline unsigned long ROR64c(unsigned long word, const int i) #else #define byte(x, n) (((x) >> (8 * (n))) & 255) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_misc.h b/src/headers/tomcrypt_misc.h index bed5015..358e80e 100644 --- a/src/headers/tomcrypt_misc.h +++ b/src/headers/tomcrypt_misc.h @@ -15,3 +15,7 @@ const char *error_to_string(int err); int mpi_to_ltc_error(int err); extern const char *crypt_build_settings; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 065ca99..08b16ff 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -84,9 +84,6 @@ int packet_valid_header(unsigned char *src, int section, int subsection); #define MIN_RSA_SIZE 1024 #define MAX_RSA_SIZE 4096 -/* Stack required for temps (plus padding) */ -// #define RSA_STACK (8 + (MAX_RSA_SIZE/8)) - typedef struct Rsa_key { int type; mp_int e, d, N, p, q, qP, dP, dQ; @@ -123,26 +120,6 @@ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key); -/* these use PKCS #1 v1.5 padding */ -int rsa_v15_encrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int prng_idx, - rsa_key *key); - -int rsa_v15_decrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long outlen, - int *stat, rsa_key *key); - -int rsa_v15_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *siglen, - int hash_idx, rsa_key *key); - -int rsa_v15_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int hash_idx, int *stat, - rsa_key *key); - - /* PKCS #1 import/export */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); @@ -244,10 +221,19 @@ typedef struct { int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); void dsa_free(dsa_key *key); + +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + mp_int *r, mp_int *s, + prng_state *prng, int wprng, dsa_key *key); + int dsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, dsa_key *key); +int dsa_verify_hash_raw( mp_int *r, mp_int *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, dsa_key *key); @@ -262,9 +248,104 @@ int dsa_verify_key(dsa_key *key, int *stat); #ifdef LTC_DER /* DER handling */ + +enum { + LTC_ASN1_EOL, + LTC_ASN1_INTEGER, + LTC_ASN1_SHORT_INTEGER, + LTC_ASN1_BIT_STRING, + LTC_ASN1_OCTET_STRING, + LTC_ASN1_NULL, + LTC_ASN1_OBJECT_IDENTIFIER, + LTC_ASN1_IA5_STRING, + LTC_ASN1_PRINTABLE_STRING, + + LTC_ASN1_SEQUENCE +}; + +typedef struct { + int type; + void *data; + unsigned long size; +} ltc_asn1_list; + +#define LTC_SET_ASN1(list, index, Type, Data, Size) \ + do { \ + int LTC_MACRO_temp = (index); \ + ltc_asn1_list *LTC_MACRO_list = (list); \ + LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ + LTC_MACRO_list[LTC_MACRO_temp].data = (Data); \ + LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ + } while (0); + +/* SEQUENCE */ +int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_sequence(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen); + +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen); + +/* VA list handy helpers */ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); + +/* INTEGER */ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen); -int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num); +int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num); int der_length_integer(mp_int *num, unsigned long *len); -int der_put_multi_integer(unsigned char *dst, unsigned long *outlen, mp_int *num, ...); -int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, mp_int *num, ...); + +/* INTEGER -- handy for 0..2^32-1 values */ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); +int der_length_short_integer(unsigned long num, unsigned long *outlen); + +/* BIT STRING */ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_bit_string(unsigned long nbits, unsigned long *outlen); + +/* OCTET STRING */ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_octet_string(unsigned long noctets, unsigned long *outlen); + +/* OBJECT IDENTIFIER */ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen); +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen); +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); +unsigned long der_object_identifier_bits(unsigned long x); + +/* IA5 STRING */ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_ia5_char_encode(int c); +int der_ia5_value_decode(int v); + +/* Printable STRING */ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_printable_char_encode(int c); +int der_printable_value_decode(int v); + #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_pkcs.h b/src/headers/tomcrypt_pkcs.h index 9fd0581..b44544a 100644 --- a/src/headers/tomcrypt_pkcs.h +++ b/src/headers/tomcrypt_pkcs.h @@ -10,7 +10,7 @@ int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out); int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen); -/* *** v2.0 padding */ +/* *** v2.1 padding */ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, prng_state *prng, @@ -34,32 +34,6 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, int hash_idx, unsigned long modulus_bitlen, int *res); -/* *** v1.5 padding */ -/* encryption padding */ -int pkcs_1_v15_es_encode(const unsigned char *msg, unsigned long msglen, - unsigned long modulus_bitlen, - prng_state *prng, int prng_idx, - unsigned char *out, unsigned long *outlen); - -/* note "outlen" is fixed, you have to tell this decoder how big - * the original message was. Unlike the OAEP decoder it cannot auto-detect it. - */ -int pkcs_1_v15_es_decode(const unsigned char *msg, unsigned long msglen, - unsigned long modulus_bitlen, - unsigned char *out, unsigned long outlen, - int *res); - -/* signature padding */ -int pkcs_1_v15_sa_encode(const unsigned char *msghash, unsigned long msghashlen, - int hash_idx, unsigned long modulus_bitlen, - unsigned char *out, unsigned long *outlen); - -int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - int hash_idx, unsigned long modulus_bitlen, - int *res); - - #endif /* PKCS_1 */ /* ===> PKCS #5 -- Password Based Cryptography <=== */ @@ -78,3 +52,7 @@ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, unsigned char *out, unsigned long *outlen); #endif /* PKCS_5 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tomcrypt_prng.h b/src/headers/tomcrypt_prng.h index 2ae5749..a257f4c 100644 --- a/src/headers/tomcrypt_prng.h +++ b/src/headers/tomcrypt_prng.h @@ -188,3 +188,7 @@ unsigned long rng_get_bytes(unsigned char *out, int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tommath_class.h b/src/headers/tommath_class.h index 6d05b7b..653e311 100644 --- a/src/headers/tommath_class.h +++ b/src/headers/tommath_class.h @@ -992,3 +992,7 @@ #else #define LTM_LAST #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/headers/tommath_superclass.h b/src/headers/tommath_superclass.h index b50ecb0..eb8b862 100644 --- a/src/headers/tommath_superclass.h +++ b/src/headers/tommath_superclass.h @@ -1,10 +1,14 @@ /* super class file for PK algos */ /* default ... include all MPI */ +#ifndef SC_RSA_1 + #define LTM_ALL +#endif + /* RSA only (does not support DH/DSA/ECC) */ -// #define SC_RSA_1 +/* #define SC_RSA_1 */ /* For reference.... On an Athlon64 optimizing for speed... @@ -70,3 +74,7 @@ #endif #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_done.c b/src/mac/hmac/hmac_done.c index fdf20be..3803ab4 100644 --- a/src/mac/hmac/hmac_done.c +++ b/src/mac/hmac/hmac_done.c @@ -103,3 +103,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_file.c b/src/mac/hmac/hmac_file.c index edbb6a6..b7b3914 100644 --- a/src/mac/hmac/hmac_file.c +++ b/src/mac/hmac/hmac_file.c @@ -87,3 +87,7 @@ int hmac_file(int hash, const char *fname, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_init.c b/src/mac/hmac/hmac_init.c index d060a5b..e5d7f90 100644 --- a/src/mac/hmac/hmac_init.c +++ b/src/mac/hmac/hmac_init.c @@ -106,3 +106,7 @@ done: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_memory.c b/src/mac/hmac/hmac_memory.c index 036ee36..2a84745 100644 --- a/src/mac/hmac/hmac_memory.c +++ b/src/mac/hmac/hmac_memory.c @@ -71,3 +71,7 @@ LBL_ERR: #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_memory_multi.c b/src/mac/hmac/hmac_memory_multi.c index 4a5b9be..13f0e43 100644 --- a/src/mac/hmac/hmac_memory_multi.c +++ b/src/mac/hmac/hmac_memory_multi.c @@ -86,3 +86,7 @@ LBL_ERR: #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_process.c b/src/mac/hmac/hmac_process.c index 30e64c3..dd4a3b2 100644 --- a/src/mac/hmac/hmac_process.c +++ b/src/mac/hmac/hmac_process.c @@ -37,3 +37,7 @@ int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/hmac/hmac_test.c b/src/mac/hmac/hmac_test.c index 0d542d4..44c6156 100644 --- a/src/mac/hmac/hmac_test.c +++ b/src/mac/hmac/hmac_test.c @@ -310,3 +310,7 @@ Key First" #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_done.c b/src/mac/omac/omac_done.c index 0a91a14..7291884 100644 --- a/src/mac/omac/omac_done.c +++ b/src/mac/omac/omac_done.c @@ -78,3 +78,7 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_file.c b/src/mac/omac/omac_file.c index 1e3d2f6..4f0cdc0 100644 --- a/src/mac/omac/omac_file.c +++ b/src/mac/omac/omac_file.c @@ -77,3 +77,7 @@ int omac_file(int cipher, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_init.c b/src/mac/omac/omac_init.c index d39219d..dc0678b 100644 --- a/src/mac/omac/omac_init.c +++ b/src/mac/omac/omac_init.c @@ -39,7 +39,7 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l } #ifdef LTC_FAST - if (16 % sizeof(LTC_FAST_TYPE)) { + if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif @@ -93,3 +93,7 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_memory.c b/src/mac/omac/omac_memory.c index 51d0ce2..ff3315a 100644 --- a/src/mac/omac/omac_memory.c +++ b/src/mac/omac/omac_memory.c @@ -69,3 +69,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_memory_multi.c b/src/mac/omac/omac_memory_multi.c index 76e4eb0..5278fe8 100644 --- a/src/mac/omac/omac_memory_multi.c +++ b/src/mac/omac/omac_memory_multi.c @@ -84,3 +84,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_process.c b/src/mac/omac/omac_process.c index 6b603f7..6491165 100644 --- a/src/mac/omac/omac_process.c +++ b/src/mac/omac/omac_process.c @@ -27,7 +27,8 @@ */ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) { - int err, n, x; + unsigned long n, x; + int err; LTC_ARGCHK(omac != NULL); LTC_ARGCHK(in != NULL); @@ -57,7 +58,7 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) while (inlen != 0) { /* ok if the block is full we xor in prev, encrypt and replace prev */ if (omac->buflen == omac->blklen) { - for (x = 0; x < omac->blklen; x++) { + for (x = 0; x < (unsigned long)omac->blklen; x++) { omac->block[x] ^= omac->prev[x]; } cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key); @@ -77,3 +78,7 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/omac/omac_test.c b/src/mac/omac/omac_test.c index 42e42bd..da9a2de 100644 --- a/src/mac/omac/omac_test.c +++ b/src/mac/omac/omac_test.c @@ -104,3 +104,7 @@ int omac_test(void) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pelican/pelican.c b/src/mac/pelican/pelican.c index fb7ce58..45ed7e8 100644 --- a/src/mac/pelican/pelican.c +++ b/src/mac/pelican/pelican.c @@ -102,6 +102,12 @@ int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned lon LTC_ARGCHK(pelmac != NULL); LTC_ARGCHK(in != NULL); + + /* check range */ + if (pelmac->buflen < 0 || pelmac->buflen > 15) { + return CRYPT_INVALID_ARG; + } + #ifdef LTC_FAST if (pelmac->buflen == 0) { while (inlen & ~15) { @@ -136,6 +142,12 @@ int pelican_done(pelican_state *pelmac, unsigned char *out) { LTC_ARGCHK(pelmac != NULL); LTC_ARGCHK(out != NULL); + + /* check range */ + if (pelmac->buflen < 0 || pelmac->buflen > 16) { + return CRYPT_INVALID_ARG; + } + if (pelmac->buflen == 16) { four_rounds(pelmac); pelmac->buflen = 0; @@ -147,3 +159,7 @@ int pelican_done(pelican_state *pelmac, unsigned char *out) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pelican/pelican_memory.c b/src/mac/pelican/pelican_memory.c index 9e0fc7b..1924031 100644 --- a/src/mac/pelican/pelican_memory.c +++ b/src/mac/pelican/pelican_memory.c @@ -53,3 +53,7 @@ int pelican_memory(const unsigned char *key, unsigned long keylen, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pelican/pelican_test.c b/src/mac/pelican/pelican_test.c index e694f61..9024803 100644 --- a/src/mac/pelican/pelican_test.c +++ b/src/mac/pelican/pelican_test.c @@ -114,3 +114,7 @@ int pelican_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_done.c b/src/mac/pmac/pmac_done.c index 610e433..f6a08ce 100644 --- a/src/mac/pmac/pmac_done.c +++ b/src/mac/pmac/pmac_done.c @@ -66,3 +66,7 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_file.c b/src/mac/pmac/pmac_file.c index 5b7dd24..79cc2e2 100644 --- a/src/mac/pmac/pmac_file.c +++ b/src/mac/pmac/pmac_file.c @@ -78,3 +78,7 @@ int pmac_file(int cipher, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_init.c b/src/mac/pmac/pmac_init.c index a02b20c..1b21e50 100644 --- a/src/mac/pmac/pmac_init.c +++ b/src/mac/pmac/pmac_init.c @@ -138,3 +138,7 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_memory.c b/src/mac/pmac/pmac_memory.c index a04cd78..88036ec 100644 --- a/src/mac/pmac/pmac_memory.c +++ b/src/mac/pmac/pmac_memory.c @@ -68,3 +68,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_memory_multi.c b/src/mac/pmac/pmac_memory_multi.c index 289d2e0..bc42b8c 100644 --- a/src/mac/pmac/pmac_memory_multi.c +++ b/src/mac/pmac/pmac_memory_multi.c @@ -83,3 +83,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_ntz.c b/src/mac/pmac/pmac_ntz.c index 97f0a15..2c16648 100644 --- a/src/mac/pmac/pmac_ntz.c +++ b/src/mac/pmac/pmac_ntz.c @@ -33,3 +33,7 @@ int pmac_ntz(unsigned long x) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_process.c b/src/mac/pmac/pmac_process.c index 5cee5ec..81fbc8c 100644 --- a/src/mac/pmac/pmac_process.c +++ b/src/mac/pmac/pmac_process.c @@ -90,3 +90,7 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_shift_xor.c b/src/mac/pmac/pmac_shift_xor.c index 18c6141..f0c367e 100644 --- a/src/mac/pmac/pmac_shift_xor.c +++ b/src/mac/pmac/pmac_shift_xor.c @@ -38,3 +38,7 @@ void pmac_shift_xor(pmac_state *pmac) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/mac/pmac/pmac_test.c b/src/mac/pmac/pmac_test.c index 6c610f9..30f606c 100644 --- a/src/mac/pmac/pmac_test.c +++ b/src/mac/pmac/pmac_test.c @@ -159,3 +159,7 @@ int pmac_test(void) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/base64/base64_decode.c b/src/misc/base64/base64_decode.c index ac6db57..320f201 100644 --- a/src/misc/base64/base64_decode.c +++ b/src/misc/base64/base64_decode.c @@ -98,3 +98,7 @@ int base64_decode(const unsigned char *in, unsigned long inlen, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/base64/base64_encode.c b/src/misc/base64/base64_encode.c index 047980c..6173cb9 100644 --- a/src/misc/base64/base64_encode.c +++ b/src/misc/base64/base64_encode.c @@ -74,3 +74,7 @@ int base64_encode(const unsigned char *in, unsigned long inlen, #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/burn_stack.c b/src/misc/burn_stack.c index 3bc69ab..c7edc03 100644 --- a/src/misc/burn_stack.c +++ b/src/misc/burn_stack.c @@ -28,3 +28,7 @@ void burn_stack(unsigned long len) } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c index 83f1414..99c07a8 100644 --- a/src/misc/crypt/crypt.c +++ b/src/misc/crypt/crypt.c @@ -295,8 +295,18 @@ const char *crypt_build_settings = #endif #if defined(LTC_NO_ASM) " LTC_NO_ASM " +#endif +#if defined(LTC_NO_TEST) + " LTC_NO_TEST " +#endif +#if defined(LTC_NO_TABLES) + " LTC_NO_TABLES " #endif "\n" "\n\n\n" ; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_argchk.c b/src/misc/crypt/crypt_argchk.c index d345c8d..2ba8a85 100644 --- a/src/misc/crypt/crypt_argchk.c +++ b/src/misc/crypt/crypt_argchk.c @@ -24,3 +24,7 @@ void crypt_argchk(char *v, char *s, int d) (void)raise(SIGABRT); } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_cipher_descriptor.c b/src/misc/crypt/crypt_cipher_descriptor.c index e274449..a255ec6 100644 --- a/src/misc/crypt/crypt_cipher_descriptor.c +++ b/src/misc/crypt/crypt_cipher_descriptor.c @@ -19,3 +19,7 @@ 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 } }; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_cipher_is_valid.c b/src/misc/crypt/crypt_cipher_is_valid.c index b179402..d5db7bc 100644 --- a/src/misc/crypt/crypt_cipher_is_valid.c +++ b/src/misc/crypt/crypt_cipher_is_valid.c @@ -27,3 +27,7 @@ int cipher_is_valid(int idx) } return CRYPT_OK; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_cipher.c b/src/misc/crypt/crypt_find_cipher.c index b83109c..230b908 100644 --- a/src/misc/crypt/crypt_find_cipher.c +++ b/src/misc/crypt/crypt_find_cipher.c @@ -32,3 +32,7 @@ int find_cipher(const char *name) return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_cipher_any.c b/src/misc/crypt/crypt_find_cipher_any.c index 42e59c0..fe669f3 100644 --- a/src/misc/crypt/crypt_find_cipher_any.c +++ b/src/misc/crypt/crypt_find_cipher_any.c @@ -41,3 +41,7 @@ int find_cipher_any(const char *name, int blocklen, int keylen) } return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_cipher_id.c b/src/misc/crypt/crypt_find_cipher_id.c index 986baf5..766fb01 100644 --- a/src/misc/crypt/crypt_find_cipher_id.c +++ b/src/misc/crypt/crypt_find_cipher_id.c @@ -30,3 +30,7 @@ int find_cipher_id(unsigned char ID) } return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_hash.c b/src/misc/crypt/crypt_find_hash.c index d66201c..c580103 100644 --- a/src/misc/crypt/crypt_find_hash.c +++ b/src/misc/crypt/crypt_find_hash.c @@ -31,3 +31,7 @@ int find_hash(const char *name) } return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_hash_any.c b/src/misc/crypt/crypt_find_hash_any.c index 0d6d430..98c277e 100644 --- a/src/misc/crypt/crypt_find_hash_any.c +++ b/src/misc/crypt/crypt_find_hash_any.c @@ -41,3 +41,7 @@ } return z; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_hash_id.c b/src/misc/crypt/crypt_find_hash_id.c index 8628d53..7c23864 100644 --- a/src/misc/crypt/crypt_find_hash_id.c +++ b/src/misc/crypt/crypt_find_hash_id.c @@ -30,3 +30,7 @@ int find_hash_id(unsigned char ID) } return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_find_prng.c b/src/misc/crypt/crypt_find_prng.c index c01a023..554083e 100644 --- a/src/misc/crypt/crypt_find_prng.c +++ b/src/misc/crypt/crypt_find_prng.c @@ -32,3 +32,7 @@ int find_prng(const char *name) return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_hash_descriptor.c b/src/misc/crypt/crypt_hash_descriptor.c index cbd6d03..969ff83 100644 --- a/src/misc/crypt/crypt_hash_descriptor.c +++ b/src/misc/crypt/crypt_hash_descriptor.c @@ -18,3 +18,7 @@ struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { { NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL } }; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_hash_is_valid.c b/src/misc/crypt/crypt_hash_is_valid.c index c9784b8..103f71b 100644 --- a/src/misc/crypt/crypt_hash_is_valid.c +++ b/src/misc/crypt/crypt_hash_is_valid.c @@ -27,3 +27,7 @@ int hash_is_valid(int idx) } return CRYPT_OK; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_prng_descriptor.c b/src/misc/crypt/crypt_prng_descriptor.c index 8a99510..8b8ad34 100644 --- a/src/misc/crypt/crypt_prng_descriptor.c +++ b/src/misc/crypt/crypt_prng_descriptor.c @@ -17,3 +17,7 @@ struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_prng_is_valid.c b/src/misc/crypt/crypt_prng_is_valid.c index 7795bbb..f8ccbcf 100644 --- a/src/misc/crypt/crypt_prng_is_valid.c +++ b/src/misc/crypt/crypt_prng_is_valid.c @@ -27,3 +27,7 @@ int prng_is_valid(int idx) } return CRYPT_OK; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_register_cipher.c b/src/misc/crypt/crypt_register_cipher.c index 74349e6..4fea824 100644 --- a/src/misc/crypt/crypt_register_cipher.c +++ b/src/misc/crypt/crypt_register_cipher.c @@ -44,3 +44,7 @@ int register_cipher(const struct ltc_cipher_descriptor *cipher) /* no spot */ return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_register_hash.c b/src/misc/crypt/crypt_register_hash.c index d5cf5b8..3ece4f7 100644 --- a/src/misc/crypt/crypt_register_hash.c +++ b/src/misc/crypt/crypt_register_hash.c @@ -44,3 +44,7 @@ int register_hash(const struct ltc_hash_descriptor *hash) /* no spot */ return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_register_prng.c b/src/misc/crypt/crypt_register_prng.c index 6a1be77..59eb456 100644 --- a/src/misc/crypt/crypt_register_prng.c +++ b/src/misc/crypt/crypt_register_prng.c @@ -44,3 +44,7 @@ int register_prng(const struct ltc_prng_descriptor *prng) /* no spot */ return -1; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_unregister_cipher.c b/src/misc/crypt/crypt_unregister_cipher.c index 0511de5..f8fdac9 100644 --- a/src/misc/crypt/crypt_unregister_cipher.c +++ b/src/misc/crypt/crypt_unregister_cipher.c @@ -36,3 +36,7 @@ int unregister_cipher(const struct ltc_cipher_descriptor *cipher) } return CRYPT_ERROR; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_unregister_hash.c b/src/misc/crypt/crypt_unregister_hash.c index 25e36f2..51f3eac 100644 --- a/src/misc/crypt/crypt_unregister_hash.c +++ b/src/misc/crypt/crypt_unregister_hash.c @@ -35,3 +35,7 @@ int unregister_hash(const struct ltc_hash_descriptor *hash) } return CRYPT_ERROR; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/crypt/crypt_unregister_prng.c b/src/misc/crypt/crypt_unregister_prng.c index 55cc554..5e90832 100644 --- a/src/misc/crypt/crypt_unregister_prng.c +++ b/src/misc/crypt/crypt_unregister_prng.c @@ -35,3 +35,7 @@ int unregister_prng(const struct ltc_prng_descriptor *prng) } return CRYPT_ERROR; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/error_to_string.c b/src/misc/error_to_string.c index 3a325a2..4958b5d 100644 --- a/src/misc/error_to_string.c +++ b/src/misc/error_to_string.c @@ -68,3 +68,7 @@ const char *error_to_string(int err) } } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/mpi/is_prime.c b/src/misc/mpi/is_prime.c index f58391f..2fb7be5 100644 --- a/src/misc/mpi/is_prime.c +++ b/src/misc/mpi/is_prime.c @@ -30,3 +30,7 @@ int is_prime(mp_int *N, int *result) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/mpi/mpi.c b/src/misc/mpi/mpi.c index ba3a7ed..8348650 100644 --- a/src/misc/mpi/mpi.c +++ b/src/misc/mpi/mpi.c @@ -9042,3 +9042,7 @@ int KARATSUBA_MUL_CUTOFF = 74, /* Min. number of digits before Karatsub /* EOF */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/mpi/mpi_to_ltc_error.c b/src/misc/mpi/mpi_to_ltc_error.c index 3a4ea17..c0a55f2 100644 --- a/src/misc/mpi/mpi_to_ltc_error.c +++ b/src/misc/mpi/mpi_to_ltc_error.c @@ -42,3 +42,7 @@ int mpi_to_ltc_error(int err) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/mpi/rand_prime.c b/src/misc/mpi/rand_prime.c index 97ddf73..90d9ac1 100644 --- a/src/misc/mpi/rand_prime.c +++ b/src/misc/mpi/rand_prime.c @@ -64,3 +64,7 @@ int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/pkcs5/pkcs_5_1.c b/src/misc/pkcs5/pkcs_5_1.c index ec47372..fd1a80f 100644 --- a/src/misc/pkcs5/pkcs_5_1.c +++ b/src/misc/pkcs5/pkcs_5_1.c @@ -100,3 +100,7 @@ LBL_ERR: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/pkcs5/pkcs_5_2.c b/src/misc/pkcs5/pkcs_5_2.c index aac811b..aad0ae3 100644 --- a/src/misc/pkcs5/pkcs_5_2.c +++ b/src/misc/pkcs5/pkcs_5_2.c @@ -123,3 +123,7 @@ LBL_ERR: #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/misc/zeromem.c b/src/misc/zeromem.c index c640bb4..9145f82 100644 --- a/src/misc/zeromem.c +++ b/src/misc/zeromem.c @@ -28,3 +28,7 @@ void zeromem(void *out, size_t outlen) *mem++ = 0; } } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cbc/cbc_decrypt.c b/src/modes/cbc/cbc_decrypt.c index c79631c..509c4b3 100644 --- a/src/modes/cbc/cbc_decrypt.c +++ b/src/modes/cbc/cbc_decrypt.c @@ -89,3 +89,7 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cbc/cbc_done.c b/src/modes/cbc/cbc_done.c index daa9110..8efe10a 100644 --- a/src/modes/cbc/cbc_done.c +++ b/src/modes/cbc/cbc_done.c @@ -36,3 +36,7 @@ int cbc_done(symmetric_CBC *cbc) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cbc/cbc_encrypt.c b/src/modes/cbc/cbc_encrypt.c index 00ca05f..3266488 100644 --- a/src/modes/cbc/cbc_encrypt.c +++ b/src/modes/cbc/cbc_encrypt.c @@ -90,3 +90,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cbc/cbc_getiv.c b/src/modes/cbc/cbc_getiv.c index 0f5c3e4..952a75e 100644 --- a/src/modes/cbc/cbc_getiv.c +++ b/src/modes/cbc/cbc_getiv.c @@ -39,3 +39,7 @@ int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cbc/cbc_setiv.c b/src/modes/cbc/cbc_setiv.c index f2e8b31..7dcae1f 100644 --- a/src/modes/cbc/cbc_setiv.c +++ b/src/modes/cbc/cbc_setiv.c @@ -38,3 +38,7 @@ int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cbc/cbc_start.c b/src/modes/cbc/cbc_start.c index 680faab..79c7555 100644 --- a/src/modes/cbc/cbc_start.c +++ b/src/modes/cbc/cbc_start.c @@ -56,3 +56,7 @@ int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cfb/cfb_decrypt.c b/src/modes/cfb/cfb_decrypt.c index 8b78898..6675df1 100644 --- a/src/modes/cfb/cfb_decrypt.c +++ b/src/modes/cfb/cfb_decrypt.c @@ -59,3 +59,7 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cfb/cfb_done.c b/src/modes/cfb/cfb_done.c index 04e775c..804a7be 100644 --- a/src/modes/cfb/cfb_done.c +++ b/src/modes/cfb/cfb_done.c @@ -36,3 +36,7 @@ int cfb_done(symmetric_CFB *cfb) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cfb/cfb_encrypt.c b/src/modes/cfb/cfb_encrypt.c index b960368..681d8cd 100644 --- a/src/modes/cfb/cfb_encrypt.c +++ b/src/modes/cfb/cfb_encrypt.c @@ -57,3 +57,7 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cfb/cfb_getiv.c b/src/modes/cfb/cfb_getiv.c index e59c1e4..73d1a82 100644 --- a/src/modes/cfb/cfb_getiv.c +++ b/src/modes/cfb/cfb_getiv.c @@ -39,3 +39,7 @@ int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cfb/cfb_setiv.c b/src/modes/cfb/cfb_setiv.c index e475ad9..4eedaa8 100644 --- a/src/modes/cfb/cfb_setiv.c +++ b/src/modes/cfb/cfb_setiv.c @@ -47,3 +47,7 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/cfb/cfb_start.c b/src/modes/cfb/cfb_start.c index 7157fc3..e07fc0c 100644 --- a/src/modes/cfb/cfb_start.c +++ b/src/modes/cfb/cfb_start.c @@ -61,3 +61,7 @@ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ctr/ctr_decrypt.c b/src/modes/ctr/ctr_decrypt.c index daa78a8..8e5c6f7 100644 --- a/src/modes/ctr/ctr_decrypt.c +++ b/src/modes/ctr/ctr_decrypt.c @@ -36,3 +36,7 @@ int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ctr/ctr_done.c b/src/modes/ctr/ctr_done.c index 88508ba..b87baad 100644 --- a/src/modes/ctr/ctr_done.c +++ b/src/modes/ctr/ctr_done.c @@ -36,3 +36,7 @@ int ctr_done(symmetric_CTR *ctr) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ctr/ctr_encrypt.c b/src/modes/ctr/ctr_encrypt.c index a96b806..cf46216 100644 --- a/src/modes/ctr/ctr_encrypt.c +++ b/src/modes/ctr/ctr_encrypt.c @@ -60,7 +60,7 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s /* is the pad empty? */ if (ctr->padlen == ctr->blocklen) { /* increment counter */ - if (ctr->mode == 0) { + if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { /* little-endian */ for (x = 0; x < ctr->blocklen; x++) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; @@ -102,3 +102,7 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ctr/ctr_getiv.c b/src/modes/ctr/ctr_getiv.c index 3997033..10cdf8e 100644 --- a/src/modes/ctr/ctr_getiv.c +++ b/src/modes/ctr/ctr_getiv.c @@ -39,3 +39,7 @@ int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ctr/ctr_setiv.c b/src/modes/ctr/ctr_setiv.c index 2aab190..e533b6e 100644 --- a/src/modes/ctr/ctr_setiv.c +++ b/src/modes/ctr/ctr_setiv.c @@ -52,3 +52,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ctr/ctr_start.c b/src/modes/ctr/ctr_start.c index db8c464..47431d2 100644 --- a/src/modes/ctr/ctr_start.c +++ b/src/modes/ctr/ctr_start.c @@ -21,19 +21,23 @@ /** Initialize a CTR context @param cipher The index of the cipher desired - @param count The initial vector + @param IV The initial vector @param key The secret key @param keylen The length of the secret key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) + @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN) @param ctr The CTR state to initialize @return CRYPT_OK if successful */ -int ctr_start(int cipher, const unsigned char *count, const unsigned char *key, int keylen, - int num_rounds, symmetric_CTR *ctr) +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr) { int x, err; - LTC_ARGCHK(count != NULL); + LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ctr != NULL); @@ -51,12 +55,16 @@ int ctr_start(int cipher, const unsigned char *count, const unsigned char *key, ctr->blocklen = cipher_descriptor[cipher].block_length; ctr->cipher = cipher; ctr->padlen = 0; - ctr->mode = 0; + ctr->mode = ctr_mode; for (x = 0; x < ctr->blocklen; x++) { - ctr->ctr[x] = count[x]; + ctr->ctr[x] = IV[x]; } cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); return CRYPT_OK; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ecb/ecb_decrypt.c b/src/modes/ecb/ecb_decrypt.c index 8db4d37..97eeb70 100644 --- a/src/modes/ecb/ecb_decrypt.c +++ b/src/modes/ecb/ecb_decrypt.c @@ -53,3 +53,7 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ecb/ecb_done.c b/src/modes/ecb/ecb_done.c index 31a42fa..a52be38 100644 --- a/src/modes/ecb/ecb_done.c +++ b/src/modes/ecb/ecb_done.c @@ -18,7 +18,7 @@ #ifdef ECB /** Terminate the chain - @param rcb The ECB chain to terminate + @param ecb The ECB chain to terminate @return CRYPT_OK on success */ int ecb_done(symmetric_ECB *ecb) @@ -36,3 +36,7 @@ int ecb_done(symmetric_ECB *ecb) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ecb/ecb_encrypt.c b/src/modes/ecb/ecb_encrypt.c index dc045e9..74adb0b 100644 --- a/src/modes/ecb/ecb_encrypt.c +++ b/src/modes/ecb/ecb_encrypt.c @@ -53,3 +53,7 @@ int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ecb/ecb_start.c b/src/modes/ecb/ecb_start.c index a8b6d45..0bae3fe 100644 --- a/src/modes/ecb/ecb_start.c +++ b/src/modes/ecb/ecb_start.c @@ -42,3 +42,7 @@ int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ofb/ofb_decrypt.c b/src/modes/ofb/ofb_decrypt.c index f725410..c69caba 100644 --- a/src/modes/ofb/ofb_decrypt.c +++ b/src/modes/ofb/ofb_decrypt.c @@ -37,3 +37,7 @@ int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ofb/ofb_done.c b/src/modes/ofb/ofb_done.c index ff72ddc..169832f 100644 --- a/src/modes/ofb/ofb_done.c +++ b/src/modes/ofb/ofb_done.c @@ -36,3 +36,7 @@ int ofb_done(symmetric_OFB *ofb) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ofb/ofb_encrypt.c b/src/modes/ofb/ofb_encrypt.c index 4409ac8..78e254d 100644 --- a/src/modes/ofb/ofb_encrypt.c +++ b/src/modes/ofb/ofb_encrypt.c @@ -52,3 +52,7 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ofb/ofb_getiv.c b/src/modes/ofb/ofb_getiv.c index eb8ef1e..4cb75fd 100644 --- a/src/modes/ofb/ofb_getiv.c +++ b/src/modes/ofb/ofb_getiv.c @@ -39,3 +39,7 @@ int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ofb/ofb_setiv.c b/src/modes/ofb/ofb_setiv.c index 96b3f1c..bf42222 100644 --- a/src/modes/ofb/ofb_setiv.c +++ b/src/modes/ofb/ofb_setiv.c @@ -47,3 +47,7 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/modes/ofb/ofb_start.c b/src/modes/ofb/ofb_start.c index 977e6a3..9a40a44 100644 --- a/src/modes/ofb/ofb_start.c +++ b/src/modes/ofb/ofb_start.c @@ -54,3 +54,7 @@ int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/bit/der_decode_bit_string.c b/src/pk/asn1/der/bit/der_decode_bit_string.c new file mode 100644 index 0000000..133d743 --- /dev/null +++ b/src/pk/asn1/der/bit/der_decode_bit_string.c @@ -0,0 +1,101 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The DER encoded BIT STRING + @param inlen The size of the DER BIT STRING + @param out [out] The array of bits stored (one per char) + @param outlen [in/out] The number of bits stored + @return CRYPT_OK if successful +*/ +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long dlen, blen, x, y; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* packet must be at least 4 bytes */ + if (inlen < 4) { + return CRYPT_INVALID_ARG; + } + + /* check for 0x03 */ + if ((in[0]&0x1F) != 0x03) { + return CRYPT_INVALID_PACKET; + } + + /* offset in the data */ + x = 1; + + /* get the length of the data */ + if (in[x] & 0x80) { + /* long format get number of length bytes */ + y = in[x++] & 127; + + /* invalid if 0 or > 2 */ + if (y == 0 || y > 2) { + return CRYPT_INVALID_PACKET; + } + + /* read the data len */ + dlen = 0; + while (y--) { + dlen = (dlen << 8) | (unsigned long)in[x++]; + } + } else { + /* short format */ + dlen = in[x++] & 127; + } + + /* is the data len too long or too short? */ + if ((dlen == 0) || (dlen + x > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* get padding count */ + blen = ((dlen - 1) << 3) - (in[x++] & 7); + + /* too many bits? */ + if (blen > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode/store the bits */ + for (y = 0; y < blen; y++) { + out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; + if ((y & 7) == 7) { + ++x; + } + } + + /* we done */ + *outlen = blen; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/bit/der_encode_bit_string.c b/src/pk/asn1/der/bit/der_encode_bit_string.c new file mode 100644 index 0000000..497b317 --- /dev/null +++ b/src/pk/asn1/der/bit/der_encode_bit_string.c @@ -0,0 +1,87 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_bit_string.c + ASN.1 DER, encode a BIT STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a BIT STRING + @param in The array of bits to store (one per char) + @param inlen The number of bits tostore + @param out [out] The destination for the DER encoded BIT STRING + @param outlen [in/out] The max size and resulting size of the DER BIT STRING + @return CRYPT_OK if successful +*/ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, buf; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* avoid overflows */ + if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* store header (include bit padding count in length) */ + x = 0; + y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; + + out[x++] = 0x03; + if (y < 128) { + out[x++] = y; + } else if (y < 256) { + out[x++] = 0x81; + out[x++] = y; + } else if (y < 65536) { + out[x++] = 0x82; + out[x++] = (y>>8)&255; + out[x++] = y&255; + } + + /* store number of zero padding bits */ + out[x++] = (8 - inlen) & 7; + + /* store the bits in big endian format */ + for (y = buf = 0; y < inlen; y++) { + buf |= (in[y] ? 1 : 0) << (7 - (y & 7)); + if ((y & 7) == 7) { + out[x++] = buf; + buf = 0; + } + } + /* store last byte */ + if (inlen & 7) { + out[x++] = buf; + } + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/bit/der_length_bit_string.c b/src/pk/asn1/der/bit/der_length_bit_string.c new file mode 100644 index 0000000..bf3a614 --- /dev/null +++ b/src/pk/asn1/der/bit/der_length_bit_string.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_bit_string.c + ASN.1 DER, get length of BIT STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of BIT STRING + @param nbits The number of bits in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_bit_string(unsigned long nbits, unsigned long *outlen) +{ + unsigned long nbytes; + LTC_ARGCHK(outlen != NULL); + + /* get the number of the bytes */ + nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; + + if (nbytes < 128) { + /* 03 LL PP DD DD DD ... */ + *outlen = 2 + nbytes; + } else if (nbytes < 256) { + /* 03 81 LL PP DD DD DD ... */ + *outlen = 3 + nbytes; + } else if (nbytes < 65536) { + /* 03 82 LL LL PP DD DD DD ... */ + *outlen = 4 + nbytes; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/der_get_multi_integer.c b/src/pk/asn1/der/der_get_multi_integer.c deleted file mode 100644 index 75ae0bc..0000000 --- a/src/pk/asn1/der/der_get_multi_integer.c +++ /dev/null @@ -1,67 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include -#include "tomcrypt.h" - -/** - @file der_get_multi_integer.c - ASN.1 DER, read multiple integers, Tom St Denis -*/ - - -#ifdef LTC_DER - -/* will read multiple DER INTEGER encoded mp_ints from src - * of upto [inlen] bytes. It will store the number of bytes - * read back into [inlen]. - */ -/** - Read multiple mp_int integers one after another - @param src The DER encoded integers - @param inlen [in] The length of the src buffer, [out] the amount of bytes read - @param num The first mp_int to decode - @param ... A NULL terminated list of mp_ints to decode - @return CRYPT_OK if successful -*/ -int der_get_multi_integer(const unsigned char *src, unsigned long *inlen, - mp_int *num, ...) -{ - va_list args; - mp_int *next; - unsigned long wrote, len; - int err; - - LTC_ARGCHK(src != NULL); - LTC_ARGCHK(inlen != NULL); - - /* setup va list */ - next = num; - len = *inlen; - wrote = 0; - va_start(args, num); - - while (next != NULL) { - if ((err = der_decode_integer(src, inlen, next)) != CRYPT_OK) { - va_end(args); - return err; - } - wrote += *inlen; - src += *inlen; - len -= *inlen; - *inlen = len; - next = va_arg(args, mp_int*); - } - va_end(args); - *inlen = wrote; - return CRYPT_OK; -} - -#endif diff --git a/src/pk/asn1/der/der_put_multi_integer.c b/src/pk/asn1/der/der_put_multi_integer.c deleted file mode 100644 index af2ca88..0000000 --- a/src/pk/asn1/der/der_put_multi_integer.c +++ /dev/null @@ -1,67 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include -#include "tomcrypt.h" - -/** - @file der_put_multi_integer.c - ASN.1 DER, store multiple integers, Tom St Denis -*/ - - -#ifdef LTC_DER - -/* store multiple mp_ints in DER INTEGER format to the out, will not - * overflow the length you give it [outlen] and store the number of - * bytes used in [outlen] - */ -/** - Store multiple mp_int integers one after another - @param out [out] The destination for the DER encoded integers - @param outlen [in/out] The max size and resulting size of the DER encoded integers - @param num The first mp_int to encode - @param ... A NULL terminated list of mp_ints to encode - @return CRYPT_OK if successful -*/ -int der_put_multi_integer(unsigned char *out, unsigned long *outlen, - mp_int *num, ...) -{ - va_list args; - mp_int *next; - unsigned long wrote, len; - int err; - - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* setup va list */ - next = num; - len = *outlen; - wrote = 0; - va_start(args, num); - - while (next != NULL) { - if ((err = der_encode_integer(next, out, outlen)) != CRYPT_OK) { - va_end(args); - return err; - } - wrote += *outlen; - out += *outlen; - len -= *outlen; - *outlen = len; - next = va_arg(args, mp_int*); - } - va_end(args); - *outlen = wrote; - return CRYPT_OK; -} - -#endif diff --git a/src/pk/asn1/der/ia5/der_decode_ia5_string.c b/src/pk/asn1/der/ia5/der_decode_ia5_string.c new file mode 100644 index 0000000..3f9870d --- /dev/null +++ b/src/pk/asn1/der/ia5/der_decode_ia5_string.c @@ -0,0 +1,95 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a IA5 STRING + @param in The DER encoded IA5 STRING + @param inlen The size of the DER IA5 STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x16 */ + if ((in[0] & 0x1F) != 0x16) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_ia5_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/ia5/der_encode_ia5_string.c b/src/pk/asn1/der/ia5/der_encode_ia5_string.c new file mode 100644 index 0000000..bf25b20 --- /dev/null +++ b/src/pk/asn1/der/ia5/der_encode_ia5_string.c @@ -0,0 +1,84 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_ia5_string.c + ASN.1 DER, encode a IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an IA5 STRING + @param in The array of IA5 to store (one per char) + @param inlen The number of IA5 to store + @param out [out] The destination for the DER encoded IA5 STRING + @param outlen [in/out] The max size and resulting size of the DER IA5 STRING + @return CRYPT_OK if successful +*/ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x16; + if (inlen < 128) { + out[x++] = inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (inlen>>16)&255; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_ia5_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/ia5/der_length_ia5_string.c b/src/pk/asn1/der/ia5/der_length_ia5_string.c new file mode 100644 index 0000000..40e6b97 --- /dev/null +++ b/src/pk/asn1/der/ia5/der_length_ia5_string.c @@ -0,0 +1,194 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_ia5_string.c + ASN.1 DER, get length of IA5 STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} ia5_table[] = { +{ '\0', 0 }, +{ '\a', 7 }, +{ '\b', 8 }, +{ '\t', 9 }, +{ '\n', 10 }, +{ '\f', 12 }, +{ '\r', 13 }, +{ ' ', 32 }, +{ '!', 33 }, +{ '"', 34 }, +{ '#', 35 }, +{ '$', 36 }, +{ '%', 37 }, +{ '&', 38 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '*', 42 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ ';', 59 }, +{ '<', 60 }, +{ '=', 61 }, +{ '>', 62 }, +{ '?', 63 }, +{ '@', 64 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ '[', 91 }, +{ '\\', 92 }, +{ ']', 93 }, +{ '^', 94 }, +{ '_', 95 }, +{ '`', 96 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +{ '{', 123 }, +{ '|', 124 }, +{ '}', 125 }, +{ '~', 126 } +}; + +int der_ia5_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].code == c) { + return ia5_table[x].value; + } + } + return -1; +} + +int der_ia5_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { + if (ia5_table[x].value == v) { + return ia5_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of IA5 STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_ia5_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/der_decode_integer.c b/src/pk/asn1/der/integer/der_decode_integer.c similarity index 54% rename from src/pk/asn1/der/der_decode_integer.c rename to src/pk/asn1/der/integer/der_decode_integer.c index b798bd4..c8d6999 100644 --- a/src/pk/asn1/der/der_decode_integer.c +++ b/src/pk/asn1/der/integer/der_decode_integer.c @@ -18,81 +18,93 @@ #ifdef LTC_DER -/* decodes a DER INTEGER in [in]. You have to tell this function - * how many bytes are available [inlen]. It will then attempt to - * read the INTEGER. If all goes well it stores the number of bytes - * read in [inlen] and the number in [num]. - */ /** Read a mp_int integer @param in The DER encoded data - @param inlen [in] Size of the in data, [out] number of bytes read + @param inlen Size of DER encoded data @param num The first mp_int to decode @return CRYPT_OK if successful */ -int der_decode_integer(const unsigned char *in, unsigned long *inlen, mp_int *num) +int der_decode_integer(const unsigned char *in, unsigned long inlen, mp_int *num) { - unsigned long tmplen, y, z; + unsigned long x, y, z; + int err; LTC_ARGCHK(num != NULL); LTC_ARGCHK(in != NULL); - LTC_ARGCHK(inlen != NULL); - - /* save copy of max output size */ - tmplen = *inlen; - *inlen = 0; /* min DER INTEGER is 0x02 01 00 == 0 */ - if (tmplen < (1 + 1 + 1)) { + if (inlen < (1 + 1 + 1)) { return CRYPT_INVALID_PACKET; } - /* ok expect 0x02 when we AND with 0011 1111 [3F] */ - if ((*in++ & 0x3F) != 0x02) { + /* ok expect 0x02 when we AND with 0001 1111 [1F] */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { return CRYPT_INVALID_PACKET; } - ++(*inlen); /* now decode the len stuff */ - z = *in++; - ++(*inlen); + z = in[x++]; if ((z & 0x80) == 0x00) { /* short form */ /* will it overflow? */ - if (*inlen + z > tmplen) { + if (x + z > inlen) { return CRYPT_INVALID_PACKET; } /* no so read it */ - (*inlen) += z; - return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, z)); + if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, z))) != CRYPT_OK) { + return err; + } } else { /* long form */ z &= 0x7F; /* will number of length bytes overflow? (or > 4) */ - if (((*inlen + z) > tmplen) || (z > 4)) { + if (((x + z) > inlen) || (z > 4) || (z == 0)) { return CRYPT_INVALID_PACKET; } /* now read it in */ y = 0; while (z--) { - y = ((unsigned long)(*in++)) | (y << 8); - ++(*inlen); + y = ((unsigned long)(in[x++])) | (y << 8); } /* now will reading y bytes overrun? */ - if ((*inlen + y) > tmplen) { + if ((x + y) > inlen) { return CRYPT_INVALID_PACKET; } /* no so read it */ - (*inlen) += y; - return mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in, y)); + if ((err = mpi_to_ltc_error(mp_read_unsigned_bin(num, (unsigned char *)in + x, y))) != CRYPT_OK) { + return err; + } } + + /* see if it's negative */ + if (in[x] & 0x80) { + mp_int tmp; + if (mp_init(&tmp) != MP_OKAY) { + return CRYPT_MEM; + } + + if (mp_2expt(&tmp, mp_count_bits(num)) != MP_OKAY || mp_sub(num, &tmp, num) != MP_OKAY) { + mp_clear(&tmp); + return CRYPT_MEM; + } + mp_clear(&tmp); + } + + return CRYPT_OK; + } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/der_encode_integer.c b/src/pk/asn1/der/integer/der_encode_integer.c similarity index 55% rename from src/pk/asn1/der/der_encode_integer.c rename to src/pk/asn1/der/integer/der_encode_integer.c index c5c5267..2b44fe5 100644 --- a/src/pk/asn1/der/der_encode_integer.c +++ b/src/pk/asn1/der/integer/der_encode_integer.c @@ -28,7 +28,7 @@ */ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) { - unsigned long tmplen, x, y, z; + unsigned long tmplen, y; int err, leading_zero; LTC_ARGCHK(num != NULL); @@ -44,48 +44,43 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) return CRYPT_BUFFER_OVERFLOW; } - /* we only need a leading zero if the msb of the first byte is one */ - if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) { - leading_zero = 1; + if (mp_cmp_d(num, 0) != MP_LT) { + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ + y = mp_unsigned_bin_size(num) + leading_zero; } else { leading_zero = 0; - } + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + y = y >> 3; - /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ - y = mp_unsigned_bin_size(num) + leading_zero; + } /* now store initial data */ *out++ = 0x02; if (y < 128) { /* short form */ *out++ = (unsigned char)y; + } else if (y < 256) { + *out++ = 0x81; + *out++ = y; + } else if (y < 65536UL) { + *out++ = 0x82; + *out++ = (y>>8)&255; + *out++ = y; + } else if (y < 16777216UL) { + *out++ = 0x83; + *out++ = (y>>16)&255; + *out++ = (y>>8)&255; + *out++ = y; } else { - /* long form (relies on y != 0) */ - - /* get length of length... ;-) */ - x = y; - z = 0; - while (x) { - ++z; - x >>= 8; - } - - /* store length of length */ - *out++ = 0x80 | ((unsigned char)z); - - /* now store length */ - - /* first shift length up so msbyte != 0 */ - x = y; - while ((x & 0xFF000000) == 0) { - x <<= 8; - } - - /* now store length */ - while (z--) { - *out++ = (unsigned char)((x >> 24) & 0xFF); - x <<= 8; - } + return CRYPT_INVALID_ARG; } /* now store msbyte of zero if num is non-zero */ @@ -94,11 +89,31 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) } /* if it's not zero store it as big endian */ - if (mp_iszero(num) == MP_NO) { + if (mp_cmp_d(num, 0) == MP_GT) { /* now store the mpint */ if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) { return mpi_to_ltc_error(err); } + } else if (mp_iszero(num) != MP_YES) { + mp_int tmp; + /* negative */ + if (mp_init(&tmp) != MP_OKAY) { + return CRYPT_MEM; + } + + /* 2^roundup and subtract */ + y = mp_count_bits(num); + y = y + (8 - (y & 7)); + if (mp_2expt(&tmp, y) != MP_OKAY || mp_add(&tmp, num, &tmp) != MP_OKAY) { + mp_clear(&tmp); + return CRYPT_MEM; + } + + if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { + mp_clear(&tmp); + return mpi_to_ltc_error(err); + } + mp_clear(&tmp); } /* we good */ @@ -107,3 +122,7 @@ int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/der_length_integer.c b/src/pk/asn1/der/integer/der_length_integer.c similarity index 60% rename from src/pk/asn1/der/der_length_integer.c rename to src/pk/asn1/der/integer/der_length_integer.c index f86738a..4d9960e 100644 --- a/src/pk/asn1/der/der_length_integer.c +++ b/src/pk/asn1/der/integer/der_length_integer.c @@ -31,25 +31,33 @@ int der_length_integer(mp_int *num, unsigned long *outlen) LTC_ARGCHK(num != NULL); LTC_ARGCHK(outlen != NULL); - /* we only need a leading zero if the msb of the first byte is one */ - if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) { - leading_zero = 1; + if (mp_cmp_d(num, 0) != MP_LT) { + /* positive */ + + /* we only need a leading zero if the msb of the first byte is one */ + if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { + leading_zero = 1; + } else { + leading_zero = 0; + } + + /* size for bignum */ + z = len = leading_zero + mp_unsigned_bin_size(num); } else { + /* it's negative */ + /* find power of 2 that is a multiple of eight and greater than count bits */ leading_zero = 0; + z = mp_count_bits(num); + z = z + (8 - (z & 7)); + len = z = z >> 3; } - /* size for bignum */ - z = len = leading_zero + mp_unsigned_bin_size(num); - - /* we need a 0x02 */ - ++len; - /* now we need a length */ if (z < 128) { /* short form */ ++len; } else { - /* long form (relies on z != 0) */ + /* long form (relies on z != 0), assumes length bytes < 128 */ ++len; while (z) { @@ -58,8 +66,16 @@ int der_length_integer(mp_int *num, unsigned long *outlen) } } + /* we need a 0x02 to indicate it's INTEGER */ + ++len; + + /* return length */ *outlen = len; return CRYPT_OK; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c new file mode 100644 index 0000000..7c6db26 --- /dev/null +++ b/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -0,0 +1,99 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_object_identifier.c + ASN.1 DER, Decode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Decode OID data and store the array of integers in words + @param in The OID DER encoded data + @param inlen The length of the OID data + @param words [out] The destination of the OID words + @param outlen [in/out] The number of OID words + @return CRYPT_OK if successful +*/ +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen) +{ + unsigned long x, y, t, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + /* header is at least 3 bytes */ + if (inlen < 3) { + return CRYPT_INVALID_PACKET; + } + + /* must be room for at least two words */ + if (*outlen < 2) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* decode the packet header */ + x = 0; + if ((in[x++] & 0x1F) != 0x06) { + return CRYPT_INVALID_PACKET; + } + + /* get the length */ + if (in[x] < 128) { + len = in[x++]; + } else { + if (in[x] < 0x81 || in[x] > 0x82) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + len = 0; + while (y--) { + len = (len << 8) | (unsigned long)in[x++]; + } + } + + if (len < 1 || (len + x) > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* decode word1 and word2 */ + --len; + t = in[x++]; + words[0] = t/40; + words[1] = t%40; + + /* decode rest */ + y = 2; + t = 0; + while (len--) { + t = (t << 7) | (in[x] & 0x7F); + if (!(in[x++] & 0x80)) { + /* store t */ + if (y >= *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + words[y++] = t; + t = 0; + } + } + + *outlen = y; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c new file mode 100644 index 0000000..4247d78 --- /dev/null +++ b/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c @@ -0,0 +1,103 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_object_identifier.c + ASN.1 DER, Encode Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Encode an OID + @param words The words to encode (upto 32-bits each) + @param nwords The number of words in the OID + @param out [out] Destination of OID data + @param outlen [in/out] The max and resulting size of the OID + @return CRYPT_OK if successful +*/ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen) +{ + unsigned long i, x, y, z, t, mask; + int err; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* check length */ + if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { + return err; + } + if (x > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* compute length to store OID data */ + z = 1; + for (y = 2; y < nwords; y++) { + t = der_object_identifier_bits(words[y]); + z += t/7 + ((t%7) ? 1 : 0); + } + + /* store header + length */ + x = 0; + out[x++] = 0x06; + if (z < 128) { + out[x++] = z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (z>>8)&255; + out[x++] = z&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store first byte */ + out[x++] = words[0] * 40 + words[1]; + + for (i = 2; i < nwords; i++) { + /* store 7 bit words in little endian */ + t = words[i] & 0xFFFFFFFF; + if (t) { + y = x; + mask = 0; + while (t) { + out[x++] = (t & 0x7F) | mask; + t >>= 7; + mask |= 0x80; /* upper bit is set on all but the last byte */ + } + /* now swap bytes y...x-1 */ + z = x - 1; + while (y < z) { + t = out[y]; out[y] = out[z]; out[z] = t; + ++y; + --z; + } + } else { + /* zero word */ + out[x++] = 0x00; + } + } + + *outlen = x; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/object_identifier/der_length_object_identifier.c b/src/pk/asn1/der/object_identifier/der_length_object_identifier.c new file mode 100644 index 0000000..5c07bc2 --- /dev/null +++ b/src/pk/asn1/der/object_identifier/der_length_object_identifier.c @@ -0,0 +1,84 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_object_identifier.c + ASN.1 DER, get length of Object Identifier, Tom St Denis +*/ + +#ifdef LTC_DER + +unsigned long der_object_identifier_bits(unsigned long x) +{ + unsigned long c; + x &= 0xFFFFFFFF; + c = 0; + while (x) { + ++c; + x >>= 1; + } + return c; +} + + +/** + Gets length of DER encoding of Object Identifier + @param nwords The number of OID words + @param words The actual OID words to get the size of + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) +{ + unsigned long y, z, t; + + LTC_ARGCHK(words != NULL); + LTC_ARGCHK(outlen != NULL); + + + /* must be >= 2 words */ + if (nwords < 2) { + return CRYPT_INVALID_ARG; + } + + /* word1 = 0,1,2 and word2 0..39 */ + if (words[0] > 2 || words[1] > 39) { + return CRYPT_INVALID_ARG; + } + + /* leading byte of first two words */ + z = 1; + for (y = 2; y < nwords; y++) { + t = der_object_identifier_bits(words[y]); + z += t/7 + ((t%7) ? 1 : 0); + } + + /* now depending on the length our length encoding changes */ + if (z < 128) { + z += 2; + } else if (z < 256) { + z += 3; + } else if (z < 65536UL) { + z += 4; + } else { + return CRYPT_INVALID_ARG; + } + + *outlen = z; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/octet/der_decode_octet_string.c b/src/pk/asn1/der/octet/der_decode_octet_string.c new file mode 100644 index 0000000..185e6de --- /dev/null +++ b/src/pk/asn1/der/octet/der_decode_octet_string.c @@ -0,0 +1,90 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a OCTET STRING + @param in The DER encoded OCTET STRING + @param inlen The size of the DER OCTET STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x04 */ + if ((in[0] & 0x1F) != 0x04) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + out[y] = in[x++]; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/octet/der_encode_octet_string.c b/src/pk/asn1/der/octet/der_encode_octet_string.c new file mode 100644 index 0000000..bd882b6 --- /dev/null +++ b/src/pk/asn1/der/octet/der_encode_octet_string.c @@ -0,0 +1,85 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_octet_string.c + ASN.1 DER, encode a OCTET STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store an OCTET STRING + @param in The array of OCTETS to store (one per char) + @param inlen The number of OCTETS to store + @param out [out] The destination for the DER encoded OCTET STRING + @param outlen [in/out] The max size and resulting size of the DER OCTET STRING + @return CRYPT_OK if successful +*/ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x04; + if (inlen < 128) { + out[x++] = inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (inlen>>16)&255; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = in[y]; + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/octet/der_length_octet_string.c b/src/pk/asn1/der/octet/der_length_octet_string.c new file mode 100644 index 0000000..7287454 --- /dev/null +++ b/src/pk/asn1/der/octet/der_length_octet_string.c @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_octet_string.c + ASN.1 DER, get length of OCTET STRING, Tom St Denis +*/ + +#ifdef LTC_DER +/** + Gets length of DER encoding of OCTET STRING + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_octet_string(unsigned long noctets, unsigned long *outlen) +{ + LTC_ARGCHK(outlen != NULL); + + if (noctets < 128) { + /* 04 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 04 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 04 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 04 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/printable_string/der_decode_printable_string.c b/src/pk/asn1/der/printable_string/der_decode_printable_string.c new file mode 100644 index 0000000..e967740 --- /dev/null +++ b/src/pk/asn1/der/printable_string/der_decode_printable_string.c @@ -0,0 +1,95 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Store a printable STRING + @param in The DER encoded printable STRING + @param inlen The size of the DER printable STRING + @param out [out] The array of octets stored (one per char) + @param outlen [in/out] The number of octets stored + @return CRYPT_OK if successful +*/ +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int t; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* must have header at least */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check for 0x13 */ + if ((in[0] & 0x1F) != 0x13) { + return CRYPT_INVALID_PACKET; + } + x = 1; + + /* decode the length */ + if (in[x] & 0x80) { + /* valid # of bytes in length are 1,2,3 */ + y = in[x] & 0x7F; + if ((y == 0) || (y > 3) || ((x + y) > inlen)) { + return CRYPT_INVALID_PACKET; + } + + /* read the length in */ + len = 0; + ++x; + while (y--) { + len = (len << 8) | in[x++]; + } + } else { + len = in[x++] & 0x7F; + } + + /* is it too long? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + if (len + x > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read the data */ + for (y = 0; y < len; y++) { + t = der_printable_value_decode(in[x++]); + if (t == -1) { + return CRYPT_INVALID_ARG; + } + out[y] = t; + } + + *outlen = y; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/printable_string/der_encode_printable_string.c b/src/pk/asn1/der/printable_string/der_encode_printable_string.c new file mode 100644 index 0000000..82bab8e --- /dev/null +++ b/src/pk/asn1/der/printable_string/der_encode_printable_string.c @@ -0,0 +1,84 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_printable_string.c + ASN.1 DER, encode a printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Store an printable STRING + @param in The array of printable to store (one per char) + @param inlen The number of printable to store + @param out [out] The destination for the DER encoded printable STRING + @param outlen [in/out] The max size and resulting size of the DER printable STRING + @return CRYPT_OK if successful +*/ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + unsigned long x, y, len; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get the size */ + if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { + return err; + } + + /* too big? */ + if (len > *outlen) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* encode the header+len */ + x = 0; + out[x++] = 0x13; + if (inlen < 128) { + out[x++] = inlen; + } else if (inlen < 256) { + out[x++] = 0x81; + out[x++] = inlen; + } else if (inlen < 65536UL) { + out[x++] = 0x82; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else if (inlen < 16777216UL) { + out[x++] = 0x83; + out[x++] = (inlen>>16)&255; + out[x++] = (inlen>>8)&255; + out[x++] = inlen&255; + } else { + return CRYPT_INVALID_ARG; + } + + /* store octets */ + for (y = 0; y < inlen; y++) { + out[x++] = der_printable_char_encode(in[y]); + } + + /* retun length */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/printable_string/der_length_printable_string.c b/src/pk/asn1/der/printable_string/der_length_printable_string.c new file mode 100644 index 0000000..b8aaab3 --- /dev/null +++ b/src/pk/asn1/der/printable_string/der_length_printable_string.c @@ -0,0 +1,166 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_printable_string.c + ASN.1 DER, get length of Printable STRING, Tom St Denis +*/ + +#ifdef LTC_DER + +static const struct { + int code, value; +} printable_table[] = { +{ ' ', 32 }, +{ '\'', 39 }, +{ '(', 40 }, +{ ')', 41 }, +{ '+', 43 }, +{ ',', 44 }, +{ '-', 45 }, +{ '.', 46 }, +{ '/', 47 }, +{ '0', 48 }, +{ '1', 49 }, +{ '2', 50 }, +{ '3', 51 }, +{ '4', 52 }, +{ '5', 53 }, +{ '6', 54 }, +{ '7', 55 }, +{ '8', 56 }, +{ '9', 57 }, +{ ':', 58 }, +{ '=', 61 }, +{ '?', 63 }, +{ 'A', 65 }, +{ 'B', 66 }, +{ 'C', 67 }, +{ 'D', 68 }, +{ 'E', 69 }, +{ 'F', 70 }, +{ 'G', 71 }, +{ 'H', 72 }, +{ 'I', 73 }, +{ 'J', 74 }, +{ 'K', 75 }, +{ 'L', 76 }, +{ 'M', 77 }, +{ 'N', 78 }, +{ 'O', 79 }, +{ 'P', 80 }, +{ 'Q', 81 }, +{ 'R', 82 }, +{ 'S', 83 }, +{ 'T', 84 }, +{ 'U', 85 }, +{ 'V', 86 }, +{ 'W', 87 }, +{ 'X', 88 }, +{ 'Y', 89 }, +{ 'Z', 90 }, +{ 'a', 97 }, +{ 'b', 98 }, +{ 'c', 99 }, +{ 'd', 100 }, +{ 'e', 101 }, +{ 'f', 102 }, +{ 'g', 103 }, +{ 'h', 104 }, +{ 'i', 105 }, +{ 'j', 106 }, +{ 'k', 107 }, +{ 'l', 108 }, +{ 'm', 109 }, +{ 'n', 110 }, +{ 'o', 111 }, +{ 'p', 112 }, +{ 'q', 113 }, +{ 'r', 114 }, +{ 's', 115 }, +{ 't', 116 }, +{ 'u', 117 }, +{ 'v', 118 }, +{ 'w', 119 }, +{ 'x', 120 }, +{ 'y', 121 }, +{ 'z', 122 }, +}; + +int der_printable_char_encode(int c) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].code == c) { + return printable_table[x].value; + } + } + return -1; +} + +int der_printable_value_decode(int v) +{ + int x; + for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { + if (printable_table[x].value == v) { + return printable_table[x].code; + } + } + return -1; +} + +/** + Gets length of DER encoding of Printable STRING + @param octets The values you want to encode + @param noctets The number of octets in the string to encode + @param outlen [out] The length of the DER encoding for the given string + @return CRYPT_OK if successful +*/ +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) +{ + unsigned long x; + + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(octets != NULL); + + /* scan string for validity */ + for (x = 0; x < noctets; x++) { + if (der_printable_char_encode(octets[x]) == -1) { + return CRYPT_INVALID_ARG; + } + } + + if (noctets < 128) { + /* 16 LL DD DD DD ... */ + *outlen = 2 + noctets; + } else if (noctets < 256) { + /* 16 81 LL DD DD DD ... */ + *outlen = 3 + noctets; + } else if (noctets < 65536UL) { + /* 16 82 LL LL DD DD DD ... */ + *outlen = 4 + noctets; + } else if (noctets < 16777216UL) { + /* 16 83 LL LL LL DD DD DD ... */ + *outlen = 5 + noctets; + } else { + return CRYPT_INVALID_ARG; + } + + return CRYPT_OK; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/sequence/der_decode_sequence.c b/src/pk/asn1/der/sequence/der_decode_sequence.c new file mode 100644 index 0000000..7228497 --- /dev/null +++ b/src/pk/asn1/der/sequence/der_decode_sequence.c @@ -0,0 +1,215 @@ +/* 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" +#include + + +/** + @file der_decode_sequence.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Decode a SEQUENCE + @param in The DER encoded input + @param inlen The size of the input + @param list The list of items to decode + @param outlen The number of items in the list + @return CRYPT_OK on success +*/ +int der_decode_sequence(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen) +{ + int err, type; + unsigned long size, x, y, z, i, blksize; + void *data; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(list != NULL); + + /* get blk size */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* sequence type? */ + x = 0; + if (in[x++] != 0x30) { + return CRYPT_INVALID_PACKET; + } + + if (in[x] < 128) { + blksize = in[x++]; + } else if (in[x] & 0x80) { + if (in[x] < 0x81 || in[x] > 0x83) { + return CRYPT_INVALID_PACKET; + } + y = in[x++] & 0x7F; + + /* would reading the len bytes overrun? */ + if (x + y > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read len */ + blksize = 0; + while (y--) { + blksize = (blksize << 8) | (unsigned long)in[x++]; + } + } + + /* would this blksize overflow? */ + if (x + blksize > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* ok read data */ + inlen = blksize; + for (i = 0; i < outlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + z = inlen; + if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_integer(data, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + + case LTC_ASN1_SHORT_INTEGER: + z = inlen; + if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_short_integer(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_BIT_STRING: + z = inlen; + if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_OCTET_STRING: + z = inlen; + if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_NULL: + if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { + err = CRYPT_INVALID_PACKET; + goto LBL_ERR; + } + x += 2; + inlen -= 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = inlen; + if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_IA5_STRING: + z = inlen; + if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + + case LTC_ASN1_PRINTABLE_STRING: + z = inlen; + if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { + goto LBL_ERR; + } + list[i].size = size; + if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + case LTC_ASN1_SEQUENCE: + z = inlen; + if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { + goto LBL_ERR; + } + if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + inlen -= z; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/sequence/der_decode_sequence_multi.c b/src/pk/asn1/der/sequence/der_decode_sequence_multi.c new file mode 100644 index 0000000..539f310 --- /dev/null +++ b/src/pk/asn1/der/sequence/der_decode_sequence_multi.c @@ -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" +#include + + +/** + @file der_decode_sequence_multi.c + ASN.1 DER, decode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(in != NULL); + + /* get size of output that will be required */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_SEQUENCE: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, inlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_SEQUENCE: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_decode_sequence(in, inlen, list, x); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/sequence/der_encode_sequence.c b/src/pk/asn1/der/sequence/der_encode_sequence.c new file mode 100644 index 0000000..6f86a4a --- /dev/null +++ b/src/pk/asn1/der/sequence/der_encode_sequence.c @@ -0,0 +1,265 @@ +/* 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" +#include + + +/** + @file der_encode_sequence.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Encode a SEQUENCE + @param list The list of items to encode + @param inlen The number of items in the list + @param out [out] The destination + @param outlen [in/out] The size of the output + @return CRYPT_OK on success +*/ +int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* too big ? */ + if (*outlen < y) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; + } + + /* store header */ + x = 0; + out[x++] = 0x30; + if (z < 128) { + out[x++] = z; + } else if (z < 256) { + out[x++] = 0x81; + out[x++] = z; + } else if (z < 65536UL) { + out[x++] = 0x82; + out[x++] = (z>>8UL)&255; + out[x++] = z&255; + } else if (z < 16777216UL) { + out[x++] = 0x83; + out[x++] = (z>>16UL)&255; + out[x++] = (z>>8UL)&255; + out[x++] = z&255; + } + + /* store data */ + *outlen -= x; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + z = *outlen; + if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SHORT_INTEGER: + z = *outlen; + if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_BIT_STRING: + z = *outlen; + if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_OCTET_STRING: + z = *outlen; + if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_NULL: + out[x++] = 0x05; + out[x++] = 0x00; + *outlen -= 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + z = *outlen; + if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_IA5_STRING: + z = *outlen; + if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_PRINTABLE_STRING: + z = *outlen; + if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + case LTC_ASN1_SEQUENCE: + z = *outlen; + if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) { + goto LBL_ERR; + } + x += z; + *outlen -= z; + break; + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + *outlen = x; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/src/pk/asn1/der/sequence/der_encode_sequence_multi.c b/src/pk/asn1/der/sequence/der_encode_sequence_multi.c new file mode 100644 index 0000000..1b7fccb --- /dev/null +++ b/src/pk/asn1/der/sequence/der_encode_sequence_multi.c @@ -0,0 +1,121 @@ +/* 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" +#include + + +/** + @file der_encode_sequence_multi.c + ASN.1 DER, encode a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) +{ + int err, type; + unsigned long size, x; + void *data; + va_list args; + ltc_asn1_list *list; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_SEQUENCE: + ++x; + break; + + default: + va_end(args); + return CRYPT_INVALID_ARG; + } + } + va_end(args); + + /* allocate structure for x elements */ + if (x == 0) { + return CRYPT_NOP; + } + + list = XCALLOC(sizeof(*list), x); + if (list == NULL) { + return CRYPT_MEM; + } + + /* fill in the structure */ + va_start(args, outlen); + x = 0; + for (;;) { + type = va_arg(args, int); + size = va_arg(args, unsigned long); + data = va_arg(args, void*); + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + case LTC_ASN1_SHORT_INTEGER: + case LTC_ASN1_BIT_STRING: + case LTC_ASN1_OCTET_STRING: + case LTC_ASN1_NULL: + case LTC_ASN1_OBJECT_IDENTIFIER: + case LTC_ASN1_IA5_STRING: + case LTC_ASN1_PRINTABLE_STRING: + case LTC_ASN1_SEQUENCE: + list[x].type = type; + list[x].size = size; + list[x++].data = data; + break; + + default: + va_end(args); + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + va_end(args); + + err = der_encode_sequence(list, x, out, outlen); +LBL_ERR: + XFREE(list); + return err; +} + +#endif + + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/sequence/der_length_sequence.c b/src/pk/asn1/der/sequence/der_length_sequence.c new file mode 100644 index 0000000..9120451 --- /dev/null +++ b/src/pk/asn1/der/sequence/der_length_sequence.c @@ -0,0 +1,144 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" +#include + + +/** + @file der_length_sequence.c + ASN.1 DER, length a SEQUENCE, Tom St Denis +*/ + +#ifdef LTC_DER + +/** + Get the length of a DER sequence + @param list The sequences of items in the SEQUENCE + @param inlen The number of items + @param outlen [out] The length required in octets to store it + @return CRYPT_OK on success +*/ +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen) +{ + int err, type; + unsigned long size, x, y, z, i; + void *data; + + LTC_ARGCHK(list != NULL); + LTC_ARGCHK(outlen != NULL); + + /* get size of output that will be required */ + y = 0; + for (i = 0; i < inlen; i++) { + type = list[i].type; + size = list[i].size; + data = list[i].data; + + if (type == LTC_ASN1_EOL) { + break; + } + + switch (type) { + case LTC_ASN1_INTEGER: + if ((err = der_length_integer(data, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SHORT_INTEGER: + if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_BIT_STRING: + if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_OCTET_STRING: + if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_NULL: + y += 2; + break; + + case LTC_ASN1_OBJECT_IDENTIFIER: + if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_IA5_STRING: + if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_PRINTABLE_STRING: + if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + case LTC_ASN1_SEQUENCE: + if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { + goto LBL_ERR; + } + y += x; + break; + + + default: + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + } + + /* calc header size */ + z = y; + if (y < 128) { + y += 2; + } else if (y < 256) { + /* 0x30 0x81 LL */ + y += 3; + } else if (y < 65536UL) { + /* 0x30 0x82 LL LL */ + y += 4; + } else if (y < 16777216UL) { + /* 0x30 0x83 LL LL LL */ + y += 5; + } else { + err = CRYPT_INVALID_ARG; + goto LBL_ERR; + } + + /* store size */ + *outlen = y; + err = CRYPT_OK; + +LBL_ERR: + return err; +} + +#endif diff --git a/src/pk/asn1/der/short_integer/der_decode_short_integer.c b/src/pk/asn1/der/short_integer/der_decode_short_integer.c new file mode 100644 index 0000000..6e731e1 --- /dev/null +++ b/src/pk/asn1/der/short_integer/der_decode_short_integer.c @@ -0,0 +1,68 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_decode_short_integer.c + ASN.1 DER, decode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/** + Read a mp_int integer + @param in The DER encoded data + @param inlen Size of data + @param num [out] The integer to decode + @return CRYPT_OK if successful +*/ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) +{ + unsigned long len, x, y; + + LTC_ARGCHK(num != NULL); + LTC_ARGCHK(in != NULL); + + /* check length */ + if (inlen < 2) { + return CRYPT_INVALID_PACKET; + } + + /* check header */ + x = 0; + if ((in[x++] & 0x1F) != 0x02) { + return CRYPT_INVALID_PACKET; + } + + /* get the packet len */ + len = in[x++]; + + if (x + len > inlen) { + return CRYPT_INVALID_PACKET; + } + + /* read number */ + y = 0; + while (len--) { + y = (y<<8) | (unsigned long)in[x++]; + } + *num = y; + + return CRYPT_OK; + +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/short_integer/der_encode_short_integer.c b/src/pk/asn1/der/short_integer/der_encode_short_integer.c new file mode 100644 index 0000000..51f45f7 --- /dev/null +++ b/src/pk/asn1/der/short_integer/der_encode_short_integer.c @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_encode_short_integer.c + ASN.1 DER, encode an integer, Tom St Denis +*/ + + +#ifdef LTC_DER + +/* Exports a positive integer as DER format (upto 32-bits in size) */ +/** + Store a mp_int integer + @param num The integer to encode + @param out [out] The destination for the DER encoded integers + @param outlen [in/out] The max size and resulting size of the DER encoded integers + @return CRYPT_OK if successful +*/ +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) +{ + unsigned long len, x, y, z; + int err; + + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* find out how big this will be */ + if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) { + return err; + } + + if (*outlen < len) { + return CRYPT_BUFFER_OVERFLOW; + } + + /* get len of output */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* see if msb is set */ + z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* adjust the number so the msB is non-zero */ + for (x = 0; (z <= 4) && (x < (4 - z)); x++) { + num <<= 8; + } + + /* store header */ + x = 0; + out[x++] = 0x02; + out[x++] = z; + + /* if 31st bit is set output a leading zero and decrement count */ + if (z == 5) { + out[x++] = 0; + --z; + } + + /* store values */ + for (y = 0; y < z; y++) { + out[x++] = (num >> 24) & 0xFF; + num <<= 8; + } + + /* we good */ + *outlen = x; + + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/asn1/der/short_integer/der_length_short_integer.c b/src/pk/asn1/der/short_integer/der_length_short_integer.c new file mode 100644 index 0000000..4d7f4ab --- /dev/null +++ b/src/pk/asn1/der/short_integer/der_length_short_integer.c @@ -0,0 +1,69 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ +#include "tomcrypt.h" + +/** + @file der_length_short_integer.c + ASN.1 DER, get length of encoding, Tom St Denis +*/ + + +#ifdef LTC_DER +/** + Gets length of DER encoding of num + @param num The integer to get the size of + @param outlen [out] The length of the DER encoding for the given integer + @return CRYPT_OK if successful +*/ +int der_length_short_integer(unsigned long num, unsigned long *outlen) +{ + unsigned long z, y, len; + + LTC_ARGCHK(outlen != NULL); + + /* force to 32 bits */ + num &= 0xFFFFFFFFUL; + + /* get the number of bytes */ + z = 0; + y = num; + while (y) { + ++z; + y >>= 8; + } + + /* handle zero */ + if (z == 0) { + z = 1; + } + + /* we need a 0x02 to indicate it's INTEGER */ + len = 1; + + /* length byte */ + ++len; + + /* bytes in value */ + len += z; + + /* see if msb is set */ + len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; + + /* return length */ + *outlen = len; + return CRYPT_OK; +} + +#endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dh/dh.c b/src/pk/dh/dh.c index c2085a6..9782f4f 100644 --- a/src/pk/dh/dh.c +++ b/src/pk/dh/dh.c @@ -518,3 +518,7 @@ done: #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dh/dh_sys.c b/src/pk/dh/dh_sys.c index 801f85a..a6614d7 100644 --- a/src/pk/dh/dh_sys.c +++ b/src/pk/dh/dh_sys.c @@ -493,3 +493,7 @@ done: return err; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_export.c b/src/pk/dsa/dsa_export.c index 773023e..ee785b7 100644 --- a/src/pk/dsa/dsa_export.c +++ b/src/pk/dsa/dsa_export.c @@ -27,18 +27,13 @@ */ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) { - unsigned long y, z; - int err; + unsigned char flags[1]; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* can we store the static header? */ - if (*outlen < (PACKET_SIZE + 1 + 2)) { - return CRYPT_BUFFER_OVERFLOW; - } - if (type == PK_PRIVATE && key->type != PK_PRIVATE) { return CRYPT_PK_TYPE_MISMATCH; } @@ -47,29 +42,31 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key return CRYPT_INVALID_ARG; } - /* store header */ - packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY); - y = PACKET_SIZE; + flags[0] = (type != PK_PUBLIC) ? 1 : 0; - /* store g, p, q, qord */ - out[y++] = type; - out[y++] = (key->qord>>8)&255; - out[y++] = key->qord & 255; - - OUTPUT_BIGNUM(&key->g,out,y,z); - OUTPUT_BIGNUM(&key->p,out,y,z); - OUTPUT_BIGNUM(&key->q,out,y,z); - - /* public exponent */ - OUTPUT_BIGNUM(&key->y,out,y,z); - if (type == PK_PRIVATE) { - OUTPUT_BIGNUM(&key->x,out,y,z); + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, &key->g, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->y, + LTC_ASN1_INTEGER, 1UL, &key->x, + LTC_ASN1_EOL, 0UL, NULL); + } else { + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, &key->g, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->y, + LTC_ASN1_EOL, 0UL, NULL); } - - *outlen = y; - return CRYPT_OK; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_free.c b/src/pk/dsa/dsa_free.c index 862a2dd..0bde19f 100644 --- a/src/pk/dsa/dsa_free.c +++ b/src/pk/dsa/dsa_free.c @@ -28,3 +28,7 @@ void dsa_free(dsa_key *key) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_import.c b/src/pk/dsa/dsa_import.c index 6de56e3..b2e1776 100644 --- a/src/pk/dsa/dsa_import.c +++ b/src/pk/dsa/dsa_import.c @@ -26,46 +26,64 @@ */ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { - unsigned long x, y; + unsigned char flags[1]; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); - /* check length */ - if ((1+2+PACKET_SIZE) > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* check type */ - if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DSA, PACKET_SUB_KEY)) != CRYPT_OK) { - return err; - } - y = PACKET_SIZE; - /* init key */ if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != MP_OKAY) { return CRYPT_MEM; } - /* read type/qord */ - key->type = in[y++]; - key->qord = ((unsigned)in[y]<<8)|((unsigned)in[y+1]); - y += 2; - - /* input publics */ - INPUT_BIGNUM(&key->g,in,x,y, inlen); - INPUT_BIGNUM(&key->p,in,x,y, inlen); - INPUT_BIGNUM(&key->q,in,x,y, inlen); - INPUT_BIGNUM(&key->y,in,x,y, inlen); - if (key->type == PK_PRIVATE) { - INPUT_BIGNUM(&key->x,in,x,y, inlen); + /* get key type */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; } - return CRYPT_OK; + if (flags[0] == 1) { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, &key->g, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->y, + LTC_ASN1_INTEGER, 1UL, &key->x, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + key->type = PK_PRIVATE; + } else { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 1UL, flags, + LTC_ASN1_INTEGER, 1UL, &key->g, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->y, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + key->type = PK_PUBLIC; + } + key->qord = mp_unsigned_bin_size(&key->q); + + if (key->qord >= MDSA_MAX_GROUP || key->qord <= 15 || + key->qord >= mp_unsigned_bin_size(&key->p) || (mp_unsigned_bin_size(&key->p) - key->qord) >= MDSA_DELTA) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + return CRYPT_OK; error: mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL); return err; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_make_key.c b/src/pk/dsa/dsa_make_key.c index 60683a0..a43da12 100644 --- a/src/pk/dsa/dsa_make_key.c +++ b/src/pk/dsa/dsa_make_key.c @@ -140,3 +140,7 @@ done: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_sign_hash.c b/src/pk/dsa/dsa_sign_hash.c index da92a82..05e11ca 100644 --- a/src/pk/dsa/dsa_sign_hash.c +++ b/src/pk/dsa/dsa_sign_hash.c @@ -21,26 +21,25 @@ Sign a hash with DSA @param in The hash to sign @param inlen The length of the hash to sign - @param out [out] Where to store the signature - @param outlen [in/out] The max size and resulting size of the signature + @param r The "r" integer of the signature (caller must initialize with mp_init() first) + @param s The "s" integer of the signature (caller must initialize with mp_init() first) @param prng An active PRNG state @param wprng The index of the PRNG desired @param key A private DSA key @return CRYPT_OK if successful */ -int dsa_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, dsa_key *key) +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + mp_int *r, mp_int *s, + prng_state *prng, int wprng, dsa_key *key) { - mp_int k, kinv, tmp, r, s; + mp_int k, kinv, tmp; unsigned char *buf; int err; - unsigned long out1, out2; - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(key != NULL); if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; @@ -60,7 +59,7 @@ int dsa_sign_hash(const unsigned char *in, unsigned long inlen, } /* Init our temps */ - if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY) { goto error; } + if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != MP_OKAY) { goto error; } retry: @@ -85,37 +84,26 @@ retry: if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY) { goto error; } /* now find r = g^k mod p mod q */ - if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY) { goto error; } - if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&key->g, &k, &key->p, r)) != MP_OKAY) { goto error; } + if ((err = mp_mod(r, &key->q, r)) != MP_OKAY) { goto error; } - if (mp_iszero(&r) == MP_YES) { goto retry; } + if (mp_iszero(r) == MP_YES) { goto retry; } /* now find s = (in + xr)/k mod q */ if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; } - if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY) { goto error; } - if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY) { goto error; } - if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&key->x, r, s)) != MP_OKAY) { goto error; } + if ((err = mp_add(s, &tmp, s)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(s, &kinv, &key->q, s)) != MP_OKAY) { goto error; } - if (mp_iszero(&s) == MP_YES) { goto retry; } + if (mp_iszero(s) == MP_YES) { goto retry; } - /* now store em both */ - - /* first check that we have enough room */ - if ((err = der_length_integer(&s, &out1)) != CRYPT_OK) { goto LBL_ERR; } - if ((err = der_length_integer(&r, &out2)) != CRYPT_OK) { goto LBL_ERR; } - if (*outlen < (out1+out2)) { - err = CRYPT_BUFFER_OVERFLOW; - goto LBL_ERR; - } - - /* store ints */ - err = der_put_multi_integer(out, outlen, &r, &s, NULL); + err = CRYPT_OK; goto LBL_ERR; error: err = mpi_to_ltc_error(err); LBL_ERR: - mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL); + mp_clear_multi(&k, &kinv, &tmp, NULL); #ifdef LTC_CLEAN_STACK zeromem(buf, MDSA_MAX_GROUP); #endif @@ -123,4 +111,49 @@ LBL_ERR: return err; } +/** + Sign a hash with DSA + @param in The hash to sign + @param inlen The length of the hash to sign + @param out [out] Where to store the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param key A private DSA key + @return CRYPT_OK if successful +*/ +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key) +{ + mp_int r, s; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + LTC_ARGCHK(key != NULL); + + if (mp_init_multi(&r, &s, NULL) != MP_OKAY) { + return CRYPT_MEM; + } + + if ((err = dsa_sign_hash_raw(in, inlen, &r, &s, prng, wprng, key)) != CRYPT_OK) { + goto LBL_ERR; + } + + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, &r, + LTC_ASN1_INTEGER, 1UL, &s, + LTC_ASN1_EOL, 0UL, NULL); + +LBL_ERR: + mp_clear_multi(&r, &s, NULL); + return err; +} + #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_verify_hash.c b/src/pk/dsa/dsa_verify_hash.c index 140f0e2..1d7ed56 100644 --- a/src/pk/dsa/dsa_verify_hash.c +++ b/src/pk/dsa/dsa_verify_hash.c @@ -18,6 +18,71 @@ #ifdef MDSA +/** + Verify a DSA signature + @param r DSA "r" parameter + @param s DSA "s" parameter + @param hash The hash that was signed + @param hashlen The length of the hash that was signed + @param stat [out] The result of the signature verification, 1==valid, 0==invalid + @param key The corresponding public DH key + @return CRYPT_OK if successful (even if the signature is invalid) +*/ +int dsa_verify_hash_raw( mp_int *r, mp_int *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key) +{ + mp_int w, v, u1, u2; + int err; + + LTC_ARGCHK(r != NULL); + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(stat != NULL); + LTC_ARGCHK(key != NULL); + + /* default to invalid signature */ + *stat = 0; + + /* init our variables */ + if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != MP_OKAY) { + return mpi_to_ltc_error(err); + } + + /* neither r or s can be null or >q*/ + if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES || mp_cmp(r, &key->q) != MP_LT || mp_cmp(s, &key->q) != MP_LT) { + err = CRYPT_INVALID_PACKET; + goto done; + } + + /* w = 1/s mod q */ + if ((err = mp_invmod(s, &key->q, &w)) != MP_OKAY) { goto error; } + + /* u1 = m * w mod q */ + if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY) { goto error; } + + /* u2 = r*w mod q */ + if ((err = mp_mulmod(r, &w, &key->q, &u2)) != MP_OKAY) { goto error; } + + /* v = g^u1 * y^u2 mod p mod q */ + if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY) { goto error; } + if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY) { goto error; } + + /* if r = v then we're set */ + if (mp_cmp(r, &v) == MP_EQ) { + *stat = 1; + } + + err = CRYPT_OK; + goto done; + +error : err = mpi_to_ltc_error(err); +done : mp_clear_multi(&w, &v, &u1, &u2, NULL); + return err; +} + /** Verify a DSA signature @param sig The signature @@ -32,59 +97,32 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, dsa_key *key) { - mp_int r, s, w, v, u1, u2; - int err; + int err; + mp_int r, s; - LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(hash != NULL); - LTC_ARGCHK(stat != NULL); - LTC_ARGCHK(key != NULL); - - /* default to invalid signature */ - *stat = 0; - - /* init our variables */ - if ((err = mp_init_multi(&r, &s, &w, &v, &u1, &u2, NULL)) != MP_OKAY) { - return mpi_to_ltc_error(err); + if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) { + return CRYPT_MEM; } - /* read in r followed by s */ - if ((err = der_get_multi_integer(sig, &siglen, &r, &s, NULL)) != CRYPT_OK) { goto done; } - - /* neither r or s can be null */ - if (mp_iszero(&r) == MP_YES || mp_iszero(&s) == MP_YES) { - err = CRYPT_INVALID_PACKET; - goto done; - } - - /* w = 1/s mod q */ - if ((err = mp_invmod(&s, &key->q, &w)) != MP_OKAY) { goto error; } - - /* u1 = m * w mod q */ - if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error; } - if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY) { goto error; } - - /* u2 = r*w mod q */ - if ((err = mp_mulmod(&r, &w, &key->q, &u2)) != MP_OKAY) { goto error; } - - /* v = g^u1 * y^u2 mod p mod q */ - if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY) { goto error; } - if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY) { goto error; } - if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY) { goto error; } - if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY) { goto error; } - - /* if r = v then we're set */ - if (mp_cmp(&r, &v) == MP_EQ) { - *stat = 1; + /* decode the sequence */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, &r, + LTC_ASN1_INTEGER, 1UL, &s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto LBL_ERR; } - err = CRYPT_OK; - goto done; + /* do the op */ + err = dsa_verify_hash_raw(&r, &s, hash, hashlen, stat, key); -error : err = mpi_to_ltc_error(err); -done : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL); +LBL_ERR: + mp_clear_multi(&r, &s, NULL); return err; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/dsa/dsa_verify_key.c b/src/pk/dsa/dsa_verify_key.c index 3e84261..8eed7f1 100644 --- a/src/pk/dsa/dsa_verify_key.c +++ b/src/pk/dsa/dsa_verify_key.c @@ -96,3 +96,7 @@ done : mp_clear_multi(&tmp, &tmp2, NULL); return err; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/ecc/ecc.c b/src/pk/ecc/ecc.c index b5e088b..605b0fb 100644 --- a/src/pk/ecc/ecc.c +++ b/src/pk/ecc/ecc.c @@ -24,7 +24,7 @@ #ifdef MECC /* size of our temp buffers for exported keys */ -#define ECC_BUF_SIZE 160 +#define ECC_BUF_SIZE 256 /* max private key size */ #define ECC_MAXSIZE 66 @@ -34,22 +34,6 @@ static const struct { int size; char *name, *prime, *B, *order, *Gx, *Gy; } sets[] = { -#ifdef ECC160 -{ - 20, - "ECC-160", - /* prime */ - "G00000000000000000000000007", - /* B */ - "1oUV2vOaSlWbxr6", - /* order */ - "G0000000000004sCQUtDxaqDUN5", - /* Gx */ - "jpqOf1BHus6Yd/pyhyVpP", - /* Gy */ - "D/wykuuIFfr+vPyx7kQEPu8MixO", -}, -#endif #ifdef ECC192 { 24, @@ -165,70 +149,6 @@ static const struct { } }; -#if 0 - -/* you plug in a prime and B value and it finds a pseudo-random base point */ -void ecc_find_base(void) -{ - static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951"; - static char *order = "26959946667150639794667015087019637467111563745054605861463538557247"; - static char *b = "9538957348957353489587"; - mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y; - char buf[4096]; - int i; - - mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL); - mp_read_radix(&p, prime, 10); - mp_read_radix(&r, order, 10); - mp_read_radix(&B, b, 10); - - /* get (p+1)/4 */ - mp_add_d(&p, 1, &pp); - mp_div_2(&pp, &pp); - mp_div_2(&pp, &pp); - - buf[0] = 0; - do { - printf("."); fflush(stdout); - /* make a random value of x */ - for (i = 0; i < 16; i++) buf[i+1] = rand() & 255; - mp_read_raw(&x, buf, 17); - mp_copy(&x, &tx); - - /* now compute x^3 - 3x + b */ - mp_expt_d(&x, 3, &tmp1); - mp_mul_d(&x, 3, &tmp2); - mp_sub(&tmp1, &tmp2, &tmp1); - mp_add(&tmp1, &B, &tmp1); - mp_mod(&tmp1, &p, &tmp1); - - /* now compute sqrt via x^((p+1)/4) */ - mp_exptmod(&tmp1, &pp, &p, &tmp2); - mp_copy(&tmp2, &ty); - - /* now square it */ - mp_sqrmod(&tmp2, &p, &tmp2); - - /* tmp2 should equal tmp1 */ - } while (mp_cmp(&tmp1, &tmp2)); - - /* now output values in way that libtomcrypt wants */ - mp_todecimal(&p, buf); - printf("\n\np==%s\n", buf); - mp_tohex(&B, buf); - printf("b==%s\n", buf); - mp_todecimal(&r, buf); - printf("r==%s\n", buf); - mp_tohex(&tx, buf); - printf("Gx==%s\n", buf); - mp_tohex(&ty, buf); - printf("Gy==%s\n", buf); - - mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL); -} - -#endif - static int is_valid_idx(int n) { int x; @@ -263,7 +183,7 @@ static void del_point(ecc_point *p) } } -static int ecc_map(ecc_point *P, mp_int *modulus, mp_int *mu) +static int ecc_map(ecc_point *P, mp_int *modulus, mp_digit mp) { mp_int t1, t2; int err; @@ -272,20 +192,23 @@ static int ecc_map(ecc_point *P, mp_int *modulus, mp_int *mu) return CRYPT_MEM; } + /* first map z back to normal */ + if ((err = mp_montgomery_reduce(&P->z, modulus, mp)) != MP_OKAY) { goto error; } + /* get 1/z */ - if ((err = mp_invmod(&P->z, modulus, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_invmod(&P->z, modulus, &t1)) != MP_OKAY) { goto error; } /* get 1/z^2 and 1/z^3 */ - if ((err = mp_sqr(&t1, &t2)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } - if ((err = mp_mul(&t1, &t2, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_sqr(&t1, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&t2, modulus, &t2)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&t1, &t2, &t1)) != MP_OKAY) { goto error; } + if ((err = mp_mod(&t1, modulus, &t1)) != MP_OKAY) { goto error; } /* multiply against x/y */ - if ((err = mp_mul(&P->x, &t2, &P->x)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&P->x, modulus, mu)) != MP_OKAY) { goto error; } - if ((err = mp_mul(&P->y, &t1, &P->y)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&P->y, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&P->x, &t2, &P->x)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&P->x, modulus, mp)) != MP_OKAY) { goto error; } + if ((err = mp_mul(&P->y, &t1, &P->y)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&P->y, modulus, mp)) != MP_OKAY) { goto error; } mp_set(&P->z, 1); err = CRYPT_OK; @@ -298,9 +221,8 @@ done: } - /* double a point R = 2P, R can be P*/ -static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) +static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_digit mp) { mp_int t1, t2; int err; @@ -315,10 +237,10 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) /* t1 = Z * Z */ if ((err = mp_sqr(&R->z, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* Z = Y * Z */ if ((err = mp_mul(&R->z, &R->y, &R->z)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&R->z, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&R->z, modulus, mp)) != MP_OKAY) { goto error; } /* Z = 2Z */ if ((err = mp_mul_2(&R->z, &R->z)) != MP_OKAY) { goto error; } if (mp_cmp(&R->z, modulus) != MP_LT) { @@ -337,7 +259,7 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) } /* T2 = T1 * T2 */ if ((err = mp_mul(&t1, &t2, &t2)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = 2T2 */ if ((err = mp_mul_2(&t2, &t1)) != MP_OKAY) { goto error; } if (mp_cmp(&t1, modulus) != MP_LT) { @@ -356,10 +278,10 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) } /* Y = Y * Y */ if ((err = mp_sqr(&R->y, &R->y)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&R->y, modulus, mp)) != MP_OKAY) { goto error; } /* T2 = Y * Y */ if ((err = mp_sqr(&R->y, &t2)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY) { goto error; } /* T2 = T2/2 */ if (mp_isodd(&t2)) { if ((err = mp_add(&t2, modulus, &t2)) != MP_OKAY) { goto error; } @@ -367,11 +289,11 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) if ((err = mp_div_2(&t2, &t2)) != MP_OKAY) { goto error; } /* Y = Y * X */ if ((err = mp_mul(&R->y, &R->x, &R->y)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&R->y, modulus, mp)) != MP_OKAY) { goto error; } /* X = T1 * T1 */ if ((err = mp_sqr(&t1, &R->x)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&R->x, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&R->x, modulus, mp)) != MP_OKAY) { goto error; } /* X = X - Y */ if ((err = mp_sub(&R->x, &R->y, &R->x)) != MP_OKAY) { goto error; } if (mp_cmp_d(&R->x, 0) == MP_LT) { @@ -390,7 +312,7 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu) } /* Y = Y * T1 */ if ((err = mp_mul(&R->y, &t1, &R->y)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&R->y, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&R->y, modulus, mp)) != MP_OKAY) { goto error; } /* Y = Y - T2 */ if ((err = mp_sub(&R->y, &t2, &R->y)) != MP_OKAY) { goto error; } if (mp_cmp_d(&R->y, 0) == MP_LT) { @@ -407,7 +329,7 @@ done: } /* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */ -static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu) +static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_digit mp) { mp_int t1, t2, x, y, z; int err; @@ -420,34 +342,31 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, if ((err = mp_copy(&P->y, &y)) != MP_OKAY) { goto error; } if ((err = mp_copy(&P->z, &z)) != MP_OKAY) { goto error; } - /* if Z' != 1 */ - if (mp_cmp_d(&Q->z, 1) != MP_EQ) { /* T1 = Z' * Z' */ if ((err = mp_sqr(&Q->z, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* X = X * T1 */ if ((err = mp_mul(&t1, &x, &x)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&x, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = Z' * T1 */ if ((err = mp_mul(&Q->z, &t1, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* Y = Y * T1 */ if ((err = mp_mul(&t1, &y, &y)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&y, modulus, mu)) != MP_OKAY) { goto error; } - } + if ((err = mp_montgomery_reduce(&y, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = Z*Z */ if ((err = mp_sqr(&z, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* T2 = X' * T1 */ if ((err = mp_mul(&Q->x, &t1, &t2)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = Z * T1 */ if ((err = mp_mul(&z, &t1, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = Y' * T1 */ if ((err = mp_mul(&Q->y, &t1, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* Y = Y - T1 */ if ((err = mp_sub(&y, &t1, &y)) != MP_OKAY) { goto error; } @@ -484,28 +403,28 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, if (mp_cmp_d(&Q->z, 1) != MP_EQ) { /* Z = Z * Z' */ if ((err = mp_mul(&z, &Q->z, &z)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&z, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&z, modulus, mp)) != MP_OKAY) { goto error; } } /* Z = Z * X */ if ((err = mp_mul(&z, &x, &z)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&z, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&z, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = T1 * X */ if ((err = mp_mul(&t1, &x, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* X = X * X */ if ((err = mp_sqr(&x, &x)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&x, modulus, mp)) != MP_OKAY) { goto error; } /* T2 = T2 * x */ if ((err = mp_mul(&t2, &x, &t2)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY) { goto error; } /* T1 = T1 * X */ if ((err = mp_mul(&t1, &x, &t1)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t1, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t1, modulus, mp)) != MP_OKAY) { goto error; } /* X = Y*Y */ if ((err = mp_sqr(&y, &x)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&x, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&x, modulus, mp)) != MP_OKAY) { goto error; } /* X = X - T2 */ if ((err = mp_sub(&x, &t2, &x)) != MP_OKAY) { goto error; } if (mp_cmp_d(&x, 0) == MP_LT) { @@ -524,7 +443,7 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, } /* T2 = T2 * Y */ if ((err = mp_mul(&t2, &y, &t2)) != MP_OKAY) { goto error; } - if ((err = mp_reduce(&t2, modulus, mu)) != MP_OKAY) { goto error; } + if ((err = mp_montgomery_reduce(&t2, modulus, mp)) != MP_OKAY) { goto error; } /* Y = T2 - T1 */ if ((err = mp_sub(&t2, &t1, &y)) != MP_OKAY) { goto error; } if (mp_cmp_d(&y, 0) == MP_LT) { @@ -553,22 +472,25 @@ done: #define WINSIZE 4 /* perform R = kG where k == integer and G == ecc_point */ -static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) +static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus, int map) { ecc_point *tG, *M[8]; int i, j, err; mp_int mu; - mp_digit buf; + mp_digit buf, mp; int first, bitbuf, bitcpy, bitcnt, mode, digidx; - /* init barrett reduction */ - if ((err = mp_init(&mu)) != MP_OKAY) { - return mpi_to_ltc_error(err); - } - if ((err = mp_reduce_setup(&mu, modulus)) != MP_OKAY) { + /* init montgomery reduction */ + if ((err = mp_montgomery_setup(modulus, &mp)) != MP_OKAY) { + return CRYPT_INVALID_ARG; + } + if ((err = mp_init(&mu)) != MP_OKAY) { + return CRYPT_MEM; + } + if ((err = mp_montgomery_calc_normalization(&mu, modulus)) != MP_OKAY) { mp_clear(&mu); - return mpi_to_ltc_error(err); - } + return CRYPT_INVALID_ARG; + } /* alloc ram for window temps */ for (i = 0; i < 8; i++) { @@ -586,20 +508,21 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) tG = new_point(); if (tG == NULL) { err = CRYPT_MEM; goto done; } - /* tG = G */ - if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY) { goto error; } - if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY) { goto error; } - if ((err = mp_copy(&G->z, &tG->z)) != MP_OKAY) { goto error; } + /* tG = G and convert to montgomery */ + if ((err = mp_mulmod(&G->x, &mu, modulus, &tG->x)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&G->y, &mu, modulus, &tG->y)) != MP_OKAY) { goto error; } + if ((err = mp_mulmod(&G->z, &mu, modulus, &tG->z)) != MP_OKAY) { goto error; } + mp_clear(&mu); /* calc the M tab, which holds kG for k==8..15 */ /* M[0] == 8G */ - if ((err = dbl_point(G, M[0], modulus, &mu)) != CRYPT_OK) { goto done; } - if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; } - if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } /* now find (8+k)G for k=1..7 */ for (j = 9; j < 16; j++) { - if ((err = add_point(M[j-9], G, M[j-8], modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = add_point(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; } } /* setup sliding window */ @@ -621,7 +544,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) bitcnt = (int) DIGIT_BIT; } - /* grab the next msb from the multiplicand */ + /* grab the next msb from the ltiplicand */ i = (buf >> (DIGIT_BIT - 1)) & 1; buf <<= 1; @@ -632,7 +555,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) /* if the bit is zero and mode == 1 then we double */ if (mode == 1 && i == 0) { - if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(R, R, modulus, mp)) != CRYPT_OK) { goto done; } continue; } @@ -653,11 +576,11 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) /* ok window is filled so double as required and add */ /* double first */ for (j = 0; j < WINSIZE; j++) { - if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(R, R, modulus, mp)) != CRYPT_OK) { goto done; } } /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ - if ((err = add_point(R, M[bitbuf-8], R, modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = add_point(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; } } /* empty window and reset */ bitcpy = bitbuf = 0; @@ -671,7 +594,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) for (j = 0; j < bitcpy; j++) { /* only double if we have had at least one add first */ if (first == 0) { - if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = dbl_point(R, R, modulus, mp)) != CRYPT_OK) { goto done; } } bitbuf <<= 1; @@ -684,14 +607,19 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus) first = 0; } else { /* then add */ - if ((err = add_point(R, tG, R, modulus, &mu)) != CRYPT_OK) { goto done; } + if ((err = add_point(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; } } } } } /* map R back from projective space */ - err = ecc_map(R, modulus, &mu); + if (map) { + err = ecc_map(R, modulus, mp); + } else { + err = CRYPT_OK; + } + goto done; error: err = mpi_to_ltc_error(err); @@ -700,7 +628,6 @@ done: for (i = 0; i < 8; i++) { del_point(M[i]); } - mp_clear(&mu); return err; } @@ -756,7 +683,7 @@ int ecc_test(void) /* then we should have G == (order + 1)G */ if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY) { goto error; } - if ((err = ecc_mulmod(&order, G, GG, &modulus)) != CRYPT_OK) { goto done; } + if ((err = ecc_mulmod(&order, G, GG, &modulus, 1)) != CRYPT_OK) { goto done; } if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) { err = CRYPT_FAIL_TESTVECTOR; goto done; @@ -855,7 +782,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; } /* make the public key */ - if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime)) != CRYPT_OK) { goto LBL_ERR; } + if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime, 1)) != CRYPT_OK) { goto LBL_ERR; } key->type = PK_PRIVATE; /* shrink key */ @@ -985,46 +912,50 @@ done: */ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) { - unsigned long y, z; - int cp, err; + int cp, err; + unsigned char flags[2]; + unsigned long key_size; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); - /* can we store the static header? */ - if (*outlen < (PACKET_SIZE + 3)) { - return CRYPT_BUFFER_OVERFLOW; - } - /* type valid? */ if (key->type != PK_PRIVATE && type == PK_PRIVATE) { return CRYPT_PK_TYPE_MISMATCH; } - /* output type and magic byte */ - y = PACKET_SIZE; - out[y++] = (unsigned char)type; - out[y++] = (unsigned char)sets[key->idx].size; + if (is_valid_idx(key->idx) == 0) { + return CRYPT_INVALID_ARG; + } - /* output x coordinate */ - OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z); - - /* compress y and output it */ + /* compress the y part */ if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) { return err; } - out[y++] = (unsigned char)cp; + flags[1] = cp; + + /* we store the NIST byte size */ + key_size = sets[key->idx].size; if (type == PK_PRIVATE) { - OUTPUT_BIGNUM(&key->k, out, y, z); + flags[0] = 1; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, &key->k, + LTC_ASN1_EOL, 0UL, NULL); + } else { + flags[0] = 0; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_EOL, 0UL, NULL); } - /* store header */ - packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_KEY); - *outlen = y; - - return CRYPT_OK; + return err; } /** @@ -1036,72 +967,66 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key */ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) { - unsigned long x, y, s; - int err; + unsigned long key_size; + unsigned char flags[2]; + int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); - /* check length */ - if ((3+PACKET_SIZE) > inlen) { - return CRYPT_INVALID_PACKET; - } - - /* check type */ - if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) { - return err; - } - /* init key */ if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != MP_OKAY) { return CRYPT_MEM; } - y = PACKET_SIZE; - key->type = (int)in[y++]; - s = (unsigned long)in[y++]; - - for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++); - if (sets[x].size == 0) { - err = CRYPT_INVALID_KEYSIZE; + /* find out what type of key it is */ + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 2UL, &flags, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } - key->idx = (int)x; - /* type check both values */ - if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) { + + if (flags[0] == 1) { + /* private key */ + key->type = PK_PRIVATE; + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_INTEGER, 1UL, &key->k, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + } else { + /* public key */ + /* private key */ + key->type = PK_PUBLIC; + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_BIT_STRING, 2UL, flags, + LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, + LTC_ASN1_INTEGER, 1UL, &key->pubkey.x, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto error; + } + } + + /* find the idx */ + for (key->idx = 0; sets[key->idx].size && (unsigned long)sets[key->idx].size != key_size; ++key->idx); + if (sets[key->idx].size == 0) { err = CRYPT_INVALID_PACKET; goto error; } - /* is the key idx valid? */ - if (is_valid_idx(key->idx) != 1) { - err = CRYPT_INVALID_PACKET; + /* compute y */ + if ((err = expand_y_point(&key->pubkey, key->idx, flags[1])) != CRYPT_OK) { goto error; } - /* load x coordinate */ - INPUT_BIGNUM(&key->pubkey.x, in, x, y, inlen); - - /* load y */ - x = (unsigned long)in[y++]; - if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) { - goto error; - } - - if (key->type == PK_PRIVATE) { - /* load private key */ - INPUT_BIGNUM(&key->k, in, x, y, inlen); - } - - /* eliminate private key if public */ - if (key->type == PK_PUBLIC) { - mp_clear(&key->k); - } - - /* z is always 1 */ + /* set z */ mp_set(&key->pubkey.z, 1); + /* we're good */ return CRYPT_OK; error: mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); @@ -1112,14 +1037,14 @@ error: Create an ECC shared secret between two keys @param private_key The private ECC key @param public_key The public key - @param out [out] Destination of the shared secret + @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) @param outlen [in/out] The max size and resulting size of the shared secret @return CRYPT_OK if successful */ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, unsigned char *out, unsigned long *outlen) { - unsigned long x, y; + unsigned long x; ecc_point *result; mp_int prime; int err; @@ -1134,6 +1059,10 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, return CRYPT_PK_NOT_PRIVATE; } + if (is_valid_idx(private_key->idx) == 0) { + return CRYPT_INVALID_ARG; + } + if (private_key->idx != public_key->idx) { return CRYPT_PK_TYPE_MISMATCH; } @@ -1149,21 +1078,19 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, return mpi_to_ltc_error(err); } - if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; } - if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; } + if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; } + if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime, 1)) != CRYPT_OK) { goto done1; } - x = (unsigned long)mp_unsigned_bin_size(&result->x); - y = (unsigned long)mp_unsigned_bin_size(&result->y); - - if (*outlen < (x+y)) { + x = (unsigned long)mp_unsigned_bin_size(&prime); + if (*outlen < x) { err = CRYPT_BUFFER_OVERFLOW; goto done1; } - *outlen = x+y; - if ((err = mp_to_unsigned_bin(&result->x, out)) != MP_OKAY) { goto error; } - if ((err = mp_to_unsigned_bin(&result->y, out+x)) != MP_OKAY) { goto error; } + zeromem(out, x); + if ((err = mp_to_unsigned_bin(&result->x, out + (x - mp_unsigned_bin_size(&result->x)))) != MP_OKAY) { goto error; } - err = CRYPT_OK; + err = CRYPT_OK; + *outlen = x; goto done1; error: err = mpi_to_ltc_error(err); @@ -1192,3 +1119,7 @@ int ecc_get_size(ecc_key *key) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/ecc/ecc_sys.c b/src/pk/ecc/ecc_sys.c index d5576f6..3cdc241 100644 --- a/src/pk/ecc/ecc_sys.c +++ b/src/pk/ecc/ecc_sys.c @@ -33,7 +33,7 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, { unsigned char *pub_expt, *ecc_shared, *skey; ecc_key pubkey; - unsigned long x, y, z, hashsize, pubkeysize; + unsigned long x, y, pubkeysize; int err; LTC_ARGCHK(in != NULL); @@ -82,53 +82,29 @@ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, goto LBL_ERR; } - /* now check if the out buffer is big enough */ - if (*outlen < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) { - ecc_free(&pubkey); - err = CRYPT_BUFFER_OVERFLOW; - goto LBL_ERR; - } - /* make random key */ - hashsize = hash_descriptor[hash].hashsize; - x = ECC_BUF_SIZE; + x = ECC_BUF_SIZE; if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { ecc_free(&pubkey); goto LBL_ERR; } ecc_free(&pubkey); - z = MAXBLOCKSIZE; - if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) { + y = MAXBLOCKSIZE; + if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) { goto LBL_ERR; } - /* store header */ - packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY); - - /* output header */ - y = PACKET_SIZE; - - /* size of hash name and the name itself */ - out[y++] = hash_descriptor[hash].ID; - - /* length of ECC pubkey and the key itself */ - STORE32L(pubkeysize, out+y); - y += 4; - - for (x = 0; x < pubkeysize; x++, y++) { - out[y] = pub_expt[x]; + /* Encrypt key */ + for (x = 0; x < inlen; x++) { + skey[x] ^= in[x]; } - STORE32L(inlen, out+y); - y += 4; + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, + LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt, + LTC_ASN1_OCTET_STRING, inlen, skey, + LTC_ASN1_EOL, 0UL, NULL); - /* Encrypt/Store the encrypted key */ - for (x = 0; x < inlen; x++, y++) { - out[y] = skey[x] ^ in[x]; - } - *outlen = y; - - err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK /* clean up */ @@ -157,10 +133,11 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, ecc_key *key) { - unsigned char *shared_secret, *skey; - unsigned long x, y, z, hashsize, keysize; + unsigned char *ecc_shared, *skey, *pub_expt; + unsigned long x, y, hashOID[32]; int hash, err; ecc_key pubkey; + ltc_asn1_list decode[3]; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); @@ -172,98 +149,93 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, return CRYPT_PK_NOT_PRIVATE; } - /* correct length ? */ - if (inlen < PACKET_SIZE+1+4+4) { - return CRYPT_INVALID_PACKET; - } else { - inlen -= PACKET_SIZE+1+4+4; - } - - /* is header correct? */ - if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { + /* decode to find out hash */ + LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); + + if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { return err; } + for (hash = 0; hash_descriptor[hash].name != NULL && + (hash_descriptor[hash].OIDlen != decode[0].size || + memcmp(hash_descriptor[hash].OID, hashOID, sizeof(unsigned long)*decode[0].size)); hash++); - /* now lets get the hash name */ - y = PACKET_SIZE; - hash = find_hash_id(in[y++]); - if (hash == -1) { - return CRYPT_INVALID_HASH; - } - - /* common values */ - hashsize = hash_descriptor[hash].hashsize; - - /* get public key */ - LOAD32L(x, in+y); - if (inlen < x) { + if (hash_descriptor[hash].name == NULL) { return CRYPT_INVALID_PACKET; - } else { - inlen -= x; } - y += 4; - if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) { - return err; - } - y += x; + + /* we now have the hash! */ /* allocate memory */ - shared_secret = XMALLOC(ECC_BUF_SIZE); - skey = XMALLOC(MAXBLOCKSIZE); - if (shared_secret == NULL || skey == NULL) { - if (shared_secret != NULL) { - XFREE(shared_secret); + pub_expt = XMALLOC(ECC_BUF_SIZE); + ecc_shared = XMALLOC(ECC_BUF_SIZE); + skey = XMALLOC(MAXBLOCKSIZE); + if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { + if (pub_expt != NULL) { + XFREE(pub_expt); + } + if (ecc_shared != NULL) { + XFREE(ecc_shared); } if (skey != NULL) { XFREE(skey); } - ecc_free(&pubkey); return CRYPT_MEM; } + LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE); + LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); + + /* read the structure in now */ + if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { + goto LBL_ERR; + } + + /* import ECC key from packet */ + if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) { + goto LBL_ERR; + } /* make shared key */ x = ECC_BUF_SIZE; - if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) { + if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) { ecc_free(&pubkey); goto LBL_ERR; } ecc_free(&pubkey); - z = MAXBLOCKSIZE; - if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) { + y = MAXBLOCKSIZE; + if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) { goto LBL_ERR; } - LOAD32L(keysize, in+y); - if (inlen < keysize) { + /* ensure the hash of the shared secret is at least as big as the encrypt itself */ + if (decode[2].size > y) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; - } else { - inlen -= keysize; } - y += 4; - if (*outlen < keysize) { - err = CRYPT_BUFFER_OVERFLOW; - goto LBL_ERR; + /* avoid buffer overflow */ + if (*outlen < decode[2].size) { + err = CRYPT_BUFFER_OVERFLOW; + goto LBL_ERR; } /* Decrypt the key */ - for (x = 0; x < keysize; x++, y++) { - out[x] = skey[x] ^ in[y]; + for (x = 0; x < decode[2].size; x++) { + out[x] = skey[x] ^ ecc_shared[x]; } - - *outlen = keysize; + *outlen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK - zeromem(shared_secret, ECC_BUF_SIZE); - zeromem(skey, MAXBLOCKSIZE); + zeromem(pub_expt, ECC_BUF_SIZE); + zeromem(ecc_shared, ECC_BUF_SIZE); + zeromem(skey, MAXBLOCKSIZE); #endif + XFREE(pub_expt); + XFREE(ecc_shared); XFREE(skey); - XFREE(shared_secret); return err; } @@ -284,9 +256,7 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen, prng_state *prng, int wprng, ecc_key *key) { ecc_key pubkey; - mp_int b, p; - unsigned char *epubkey, *er; - unsigned long x, y, pubkeysize, rsize; + mp_int r, s, e, p; int err; LTC_ARGCHK(in != NULL); @@ -308,116 +278,65 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen, return err; } - /* make up a key and export the public copy */ - if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { - return err; - } - - /* allocate ram */ - epubkey = XMALLOC(ECC_BUF_SIZE); - er = XMALLOC(ECC_BUF_SIZE); - if (epubkey == NULL || er == NULL) { - if (epubkey != NULL) { - XFREE(epubkey); - } - if (er != NULL) { - XFREE(er); - } - ecc_free(&pubkey); - return CRYPT_MEM; - } - - pubkeysize = ECC_BUF_SIZE; - if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { - ecc_free(&pubkey); - goto LBL_ERR; - } - - /* get the hash and load it as a bignum into 'b' */ + /* get the hash and load it as a bignum into 'e' */ /* init the bignums */ - if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { + if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != MP_OKAY) { ecc_free(&pubkey); err = mpi_to_ltc_error(err); goto LBL_ERR; } if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; } - if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } + if ((err = mp_read_unsigned_bin(&e, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; } - /* find b = (m - x)/k */ - if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY) { goto error; } /* k = 1/k */ - if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY) { goto error; } /* b = m - x */ - if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY) { goto error; } /* b = (m - x)/k */ + /* make up a key and export the public copy */ + for (;;) { + if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { + return err; + } - /* export it */ - rsize = (unsigned long)mp_unsigned_bin_size(&b); - if (rsize > ECC_BUF_SIZE) { - err = CRYPT_BUFFER_OVERFLOW; - goto error; - } - if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY) { goto error; } + /* find r = x1 mod n */ + if ((err = mp_mod(&pubkey.pubkey.x, &p, &r)) != MP_OKAY) { goto error; } - /* now lets check the outlen before we write */ - if (*outlen < (12 + rsize + pubkeysize)) { - err = CRYPT_BUFFER_OVERFLOW; - goto LBL_ERR; + if (mp_iszero(&r)) { + ecc_free(&pubkey); + } else { + /* find s = (e + xr)/k */ + if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY) { goto error; } /* k = 1/k */ + if ((err = mp_mulmod(&key->k, &r, &p, &s)) != MP_OKAY) { goto error; } /* s = xr */ + if ((err = mp_addmod(&e, &s, &p, &s)) != MP_OKAY) { goto error; } /* s = e + xr */ + if ((err = mp_mulmod(&s, &pubkey.k, &p, &s)) != MP_OKAY) { goto error; } /* s = (e + xr)/k */ + + if (mp_iszero(&s)) { + ecc_free(&pubkey); + } else { + break; + } + } } - /* lets output */ - y = PACKET_SIZE; - - /* size of public key */ - STORE32L(pubkeysize, out+y); - y += 4; - - /* copy the public key */ - for (x = 0; x < pubkeysize; x++, y++) { - out[y] = epubkey[x]; - } - - /* size of 'r' */ - STORE32L(rsize, out+y); - y += 4; - - /* copy r */ - for (x = 0; x < rsize; x++, y++) { - out[y] = er[x]; - } - - /* store header */ - packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED); - *outlen = y; - - /* all ok */ - err = CRYPT_OK; + /* store as SEQUENCE { r, s -- integer } */ + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, &r, + LTC_ASN1_INTEGER, 1UL, &s, + LTC_ASN1_EOL, 0UL, NULL); goto LBL_ERR; error: err = mpi_to_ltc_error(err); LBL_ERR: - mp_clear_multi(&b, &p, NULL); + mp_clear_multi(&r, &s, &p, &e, NULL); ecc_free(&pubkey); -#ifdef LTC_CLEAN_STACK - zeromem(er, ECC_BUF_SIZE); - zeromem(epubkey, ECC_BUF_SIZE); -#endif - - XFREE(epubkey); - XFREE(er); return err; } -/* verify that mG = (bA + Y) +/* verify * - * The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the - * public key Y = xG can verify it. - * - * b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it] - * A = kG therefore bA == ((m-x)/k)kG == (m-x)G - * - * Adding Y = xG to the bA gives us (m-x)G + xG == mG - * - * The user given only xG, kG and b cannot determine k or x which means they can't find the private key. - * + * w = s^-1 mod n + * u1 = xw + * u2 = rw + * X = u1*G + u2*Q + * v = X_x1 mod n + * accept if v == r */ /** @@ -434,10 +353,9 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key) { - ecc_point *mG; - ecc_key pubkey; - mp_int b, p, m, mu; - unsigned long x, y; + ecc_point *mG, *mQ; + mp_int r, s, v, w, u1, u2, e, p, m; + mp_digit mp; int err; LTC_ARGCHK(sig != NULL); @@ -448,89 +366,81 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, /* default to invalid signature */ *stat = 0; - if (siglen < PACKET_SIZE+4+4) { - return CRYPT_INVALID_PACKET; - } else { - siglen -= PACKET_SIZE+4+4; + /* is the IDX valid ? */ + if (is_valid_idx(key->idx) != 1) { + return CRYPT_PK_INVALID_TYPE; } - /* is the message format correct? */ - if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) { - return err; - } - - /* get hash name */ - y = PACKET_SIZE; - - /* get size of public key */ - LOAD32L(x, sig+y); - if (siglen < x) { - return CRYPT_INVALID_PACKET; - } else { - siglen -= x; - } - y += 4; - - /* load the public key */ - if ((err = ecc_import((unsigned char*)sig+y, x, &pubkey)) != CRYPT_OK) { - return err; - } - y += x; - - /* load size of 'b' */ - LOAD32L(x, sig+y); - if (siglen < x) { - return CRYPT_INVALID_PACKET; - } else { - siglen -= x; - } - y += 4; - - /* init values */ - if ((err = mp_init_multi(&b, &m, &p, &mu, NULL)) != MP_OKAY) { - ecc_free(&pubkey); - return mpi_to_ltc_error(err); - } - - mG = new_point(); - if (mG == NULL) { - mp_clear_multi(&b, &m, &p, &mu, NULL); - ecc_free(&pubkey); + /* allocate ints */ + if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != MP_OKAY) { return CRYPT_MEM; - } + } - /* load b */ - if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x)) != MP_OKAY) { goto error; } - y += x; + /* allocate points */ + mG = new_point(); + mQ = new_point(); + if (mQ == NULL || mG == NULL) { + err = CRYPT_MEM; + goto done; + } - /* get m in binary a bignum */ - if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)hashlen)) != MP_OKAY) { goto error; } - - /* load prime */ - if ((err = mp_read_radix(&p, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } - - /* calculate barrett stuff */ - mp_set(&mu, 1); - mp_lshd(&mu, 2 * USED(&p)); - if ((err = mp_div(&mu, &p, &mu, NULL)) != MP_OKAY) { goto error; } + /* parse header */ + if ((err = der_decode_sequence_multi(sig, siglen, + LTC_ASN1_INTEGER, 1UL, &r, + LTC_ASN1_INTEGER, 1UL, &s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { + goto done; + } - /* get bA */ - if ((err = ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p)) != CRYPT_OK) { goto done; } - - /* get bA + Y */ - if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } + /* get the order */ + if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; } - /* we have to transform it */ - if ((err = ecc_map(&pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; } + /* get the modulus */ + if ((err = mp_read_radix(&m, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; } - /* get mG */ + /* check for zero */ + if (mp_iszero(&r) || mp_iszero(&s) || mp_cmp(&r, &p) != MP_LT || mp_cmp(&s, &p) != MP_LT) { + err = CRYPT_INVALID_PACKET; + goto done; + } + + /* read hash */ + if ((err = mp_read_unsigned_bin(&e, (unsigned char *)hash, (int)hashlen)) != MP_OKAY) { goto error; } + + /* w = s^-1 mod n */ + if ((err = mp_invmod(&s, &p, &w)) != MP_OKAY) { goto error; } + + /* u1 = ew */ + if ((err = mp_mulmod(&e, &w, &p, &u1)) != MP_OKAY) { goto error; } + + /* u2 = rw */ + if ((err = mp_mulmod(&r, &w, &p, &u2)) != MP_OKAY) { goto error; } + + /* find mG = u1*G */ if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; } if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; } - mp_set(&mG->z, 1); - if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK) { goto done; } + mp_set(&mG->z, 1); + if ((err = ecc_mulmod(&u1, mG, mG, &m, 0)) != CRYPT_OK) { goto done; } - /* compare mG to bA + Y */ - if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) { + /* find mQ = u2*Q */ + if ((err = mp_copy(&key->pubkey.x, &mQ->x)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&key->pubkey.y, &mQ->y)) != MP_OKAY) { goto error; } + if ((err = mp_copy(&key->pubkey.z, &mQ->z)) != MP_OKAY) { goto error; } + if ((err = ecc_mulmod(&u2, mQ, mQ, &m, 0)) != CRYPT_OK) { goto done; } + + /* find the montgomery mp */ + if ((err = mp_montgomery_setup(&m, &mp)) != MP_OKAY) { goto error; } + /* add them */ + if ((err = add_point(mQ, mG, mG, &m, mp)) != CRYPT_OK) { goto done; } + + /* reduce */ + if ((err = ecc_map(mG, &m, mp)) != CRYPT_OK) { goto done; } + + /* v = X_x1 mod n */ + if ((err = mp_mod(&mG->x, &p, &v)) != CRYPT_OK) { goto done; } + + /* does v == r */ + if (mp_cmp(&v, &r) == MP_EQ) { *stat = 1; } @@ -541,8 +451,12 @@ error: err = mpi_to_ltc_error(err); done: del_point(mG); - ecc_free(&pubkey); - mp_clear_multi(&p, &m, &b, &mu, NULL); + del_point(mQ); + mp_clear_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL); return err; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/packet_store_header.c b/src/pk/packet_store_header.c index a2442cc..ca09a76 100644 --- a/src/pk/packet_store_header.c +++ b/src/pk/packet_store_header.c @@ -27,3 +27,7 @@ void packet_store_header(unsigned char *dst, int section, int subsection) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/packet_valid_header.c b/src/pk/packet_valid_header.c index b2eb9c9..8ac8375 100644 --- a/src/pk/packet_valid_header.c +++ b/src/pk/packet_valid_header.c @@ -35,3 +35,7 @@ int packet_valid_header(unsigned char *src, int section, int subsection) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_i2osp.c b/src/pk/pkcs1/pkcs_1_i2osp.c index 7f13626..8ec251d 100644 --- a/src/pk/pkcs1/pkcs_1_i2osp.c +++ b/src/pk/pkcs1/pkcs_1_i2osp.c @@ -49,3 +49,7 @@ int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out) #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_mgf1.c b/src/pk/pkcs1/pkcs_1_mgf1.c index 0fe177f..233d7bc 100644 --- a/src/pk/pkcs1/pkcs_1_mgf1.c +++ b/src/pk/pkcs1/pkcs_1_mgf1.c @@ -102,3 +102,7 @@ LBL_ERR: } #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_oaep_decode.c b/src/pk/pkcs1/pkcs_1_oaep_decode.c index 82862c1..fd368e6 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_decode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_decode.c @@ -63,7 +63,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, /* allocate ram for DB/mask/salt of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); - seed = XMALLOC(modulus_len); + seed = XMALLOC(hLen); if (DB == NULL || mask == NULL || seed == NULL) { if (DB != NULL) { XFREE(DB); @@ -92,14 +92,13 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, } /* now read the masked seed */ - for (x = 1, y = 0; y < hLen; y++) { - seed[y] = msg[x++]; - } + x = 1; + XMEMCPY(seed, msg + x, hLen); + x += hLen; /* now read the masked DB */ - for (y = 0; y < modulus_len - hLen - 1; y++) { - DB[y] = msg[x++]; - } + XMEMCPY(DB, msg + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; /* compute MGF1 of maskedDB (hLen) */ if ((err = pkcs_1_mgf1(DB, modulus_len - hLen - 1, hash_idx, mask, hLen)) != CRYPT_OK) { @@ -161,9 +160,8 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, /* copy message */ *outlen = (modulus_len - hLen - 1) - x; - for (y = 0; x != (modulus_len - hLen - 1); ) { - out[y++] = DB[x++]; - } + XMEMCPY(out, DB + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; /* valid packet */ *res = 1; @@ -172,7 +170,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(DB, modulus_len); - zeromem(seed, modulus_len); + zeromem(seed, hLen); zeromem(mask, modulus_len); #endif @@ -184,3 +182,7 @@ LBL_ERR: } #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_oaep_encode.c b/src/pk/pkcs1/pkcs_1_oaep_encode.c index 7afea60..525158c 100644 --- a/src/pk/pkcs1/pkcs_1_oaep_encode.c +++ b/src/pk/pkcs1/pkcs_1_oaep_encode.c @@ -66,7 +66,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, /* allocate ram for DB/mask/salt of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); - seed = XMALLOC(modulus_len); + seed = XMALLOC(hLen); if (DB == NULL || mask == NULL || seed == NULL) { if (DB != NULL) { XFREE(DB); @@ -97,16 +97,15 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, /* append PS then 0x01 (to lhash) */ x = hLen; y = modulus_len - msglen - 2*hLen - 2; - while (y--) { - DB[x++] = 0x00; - } + XMEMSET(DB+x, 0, y); + x += y; + + /* 0x01 byte */ DB[x++] = 0x01; - /* message */ - y = msglen; - while (y--) { - DB[x++] = *msg++; - } + /* message (length = msglen) */ + XMEMCPY(DB+x, msg, msglen); + x += msglen; /* now choose a random seed */ if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { @@ -143,19 +142,18 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, /* start output which is 0x00 || maskedSeed || maskedDB */ x = 0; out[x++] = 0x00; - for (y = 0; y < hLen; y++) { - out[x++] = seed[y]; - } - for (y = 0; y < modulus_len - hLen - 1; y++) { - out[x++] = DB[y]; - } + XMEMCPY(out+x, seed, hLen); + x += hLen; + XMEMCPY(out+x, DB, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; + *outlen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(DB, modulus_len); - zeromem(seed, modulus_len); + zeromem(seed, hLen); zeromem(mask, modulus_len); #endif @@ -168,3 +166,7 @@ LBL_ERR: #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_os2ip.c b/src/pk/pkcs1/pkcs_1_os2ip.c index db6b58c..42627ca 100644 --- a/src/pk/pkcs1/pkcs_1_os2ip.c +++ b/src/pk/pkcs1/pkcs_1_os2ip.c @@ -35,3 +35,7 @@ int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen) #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_pss_decode.c b/src/pk/pkcs1/pkcs_1_pss_decode.c index a19e7d8..98c7160 100644 --- a/src/pk/pkcs1/pkcs_1_pss_decode.c +++ b/src/pk/pkcs1/pkcs_1_pss_decode.c @@ -87,14 +87,13 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, } /* copy out the DB */ - for (x = 0; x < modulus_len - hLen - 1; x++) { - DB[x] = sig[x]; - } + x = 0; + XMEMCPY(DB, sig + x, modulus_len - hLen - 1); + x += modulus_len - hLen - 1; /* copy out the hash */ - for (y = 0; y < hLen; y++) { - hash[y] = sig[x++]; - } + XMEMCPY(hash, sig + x, hLen); + x += hLen; /* check the MSB */ if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) { @@ -172,3 +171,7 @@ LBL_ERR: } #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_pss_encode.c b/src/pk/pkcs1/pkcs_1_pss_encode.c index 58a03d5..a086e38 100644 --- a/src/pk/pkcs1/pkcs_1_pss_encode.c +++ b/src/pk/pkcs1/pkcs_1_pss_encode.c @@ -110,13 +110,12 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, } /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ - for (x = 0; x < (modulus_len - saltlen - hLen - 2); x++) { - DB[x] = 0x00; - } + x = 0; + XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2); + x += modulus_len - saltlen - hLen - 2; DB[x++] = 0x01; - for (y = 0; y < saltlen; y++) { - DB[x++] = salt[y]; - } + XMEMCPY(DB + x, salt, saltlen); + x += saltlen; /* generate mask of length modulus_len - hLen - 1 from hash */ if ((err = pkcs_1_mgf1(hash, hLen, hash_idx, mask, modulus_len - hLen - 1)) != CRYPT_OK) { @@ -134,14 +133,15 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, goto LBL_ERR; } - /* DB */ - for (y = x = 0; x < modulus_len - hLen - 1; x++) { - out[y++] = DB[x]; - } + /* DB len = modulus_len - hLen - 1 */ + y = 0; + XMEMCPY(out + y, DB, modulus_len - hLen - 1); + y += modulus_len - hLen - 1; + /* hash */ - for (x = 0; x < hLen; x++) { - out[y++] = hash[x]; - } + XMEMCPY(out + y, hash, hLen); + y += hLen; + /* 0xBC */ out[y] = 0xBC; @@ -168,3 +168,7 @@ LBL_ERR: } #endif /* PKCS_1 */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/pkcs1/pkcs_1_v15_es_decode.c b/src/pk/pkcs1/pkcs_1_v15_es_decode.c deleted file mode 100644 index fc54845..0000000 --- a/src/pk/pkcs1/pkcs_1_v15_es_decode.c +++ /dev/null @@ -1,74 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file pkcs_1_v15_es_decode.c - PKCS #1 v1.5 Encryption Padding, Tom St Denis -*/ - -#ifdef PKCS_1 - -/** - PKCS #1 v1.5 Encryption Decoding - @param msg The padded data - @param msglen The length of the padded data (octets) - @param modulus_bitlen The bit length of the RSA modulus - @param out [out] Where to store the decoded data - @param outlen The length of the decoded data - @param res [out] Result of the decoding, 1==valid, 0==invalid - @return CRYPT_OK if successful -*/ -int pkcs_1_v15_es_decode(const unsigned char *msg, unsigned long msglen, - unsigned long modulus_bitlen, - unsigned char *out, unsigned long outlen, - int *res) -{ - unsigned long x, modulus_bytelen; - - LTC_ARGCHK(msg != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(res != NULL); - - /* default to failed */ - *res = 0; - - modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); - - /* must be at least modulus_bytelen bytes long */ - if (msglen != modulus_bytelen) { - return CRYPT_INVALID_ARG; - } - - /* should start with 0x00 0x02 */ - if (msg[0] != 0x00 || msg[1] != 0x02) { - return CRYPT_OK; - } - - /* skip over PS */ - x = 2 + (modulus_bytelen - outlen - 3); - - /* should be 0x00 */ - if (msg[x++] != 0x00) { - return CRYPT_OK; - } - - /* the message is left */ - if (x + outlen > modulus_bytelen) { - return CRYPT_PK_INVALID_SIZE; - } - XMEMCPY(out, msg + x, outlen); - *res = 1; - return CRYPT_OK; -} - -#endif - diff --git a/src/pk/pkcs1/pkcs_1_v15_es_encode.c b/src/pk/pkcs1/pkcs_1_v15_es_encode.c deleted file mode 100644 index b6ac429..0000000 --- a/src/pk/pkcs1/pkcs_1_v15_es_encode.c +++ /dev/null @@ -1,69 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file pkcs_1_v15_es_encode.c - v1.5 Encryption Padding for PKCS #1, Tom St Denis -*/ - -#ifdef PKCS_1 - -/** - PKCS #1 v1.5 Encryption Padding - @param msg The data to encode - @param msglen The length of the data (octets) - @param modulus_bitlen The bit length of the RSA modulus - @param prng An active PRNG - @param prng_idx The index of the PRNG desired - @param out [out] The destination of the padding - @param outlen [in/out] The max size and resulting size of the padding - @return CRYPT_OK if successful -*/ -int pkcs_1_v15_es_encode(const unsigned char *msg, unsigned long msglen, - unsigned long modulus_bitlen, - prng_state *prng, int prng_idx, - unsigned char *out, unsigned long *outlen) -{ - unsigned long modulus_bytelen, x, y; - - LTC_ARGCHK(msg != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - /* get modulus len */ - modulus_bytelen = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); - if (modulus_bytelen < 12) { - return CRYPT_INVALID_ARG; - } - - /* verify length */ - if (msglen > (modulus_bytelen - 11) || *outlen < modulus_bytelen) { - return CRYPT_PK_INVALID_SIZE; - } - - /* 0x00 0x02 PS 0x00 M */ - x = 0; - out[x++] = 0x00; - out[x++] = 0x02; - y = modulus_bytelen - msglen - 3; - if (prng_descriptor[prng_idx].read(out+x, y, prng) != y) { - return CRYPT_ERROR_READPRNG; - } - x += y; - out[x++] = 0x00; - XMEMCPY(out+x, msg, msglen); - *outlen = modulus_bytelen; - - return CRYPT_OK; -} - -#endif /* PKCS_1 */ diff --git a/src/pk/pkcs1/pkcs_1_v15_sa_decode.c b/src/pk/pkcs1/pkcs_1_v15_sa_decode.c deleted file mode 100644 index 7cad021..0000000 --- a/src/pk/pkcs1/pkcs_1_v15_sa_decode.c +++ /dev/null @@ -1,91 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file pkcs_1_v15_sa_decode.c - PKCS #1 v1.5 Signature Padding, Tom St Denis -*/ - -#ifdef PKCS_1 - -/** - Perform PKCS #1 v1.5 Signature Decoding - @param msghash The hash that was signed - @param msghashlen The length of the hash - @param sig The signature [padded data] - @param siglen The length of the signature - @param hash_idx The index of the hash used - @param modulus_bitlen The bit length of the RSA modulus - @param res [out] Result of comparison, 1==valid, 0==invalid - @return CRYPT_OK if successful -*/ -int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen, - const unsigned char *sig, unsigned long siglen, - int hash_idx, unsigned long modulus_bitlen, - int *res) -{ - unsigned long x, y, modulus_bytelen, derlen; - int err; - - LTC_ARGCHK(msghash != NULL); - LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(res != NULL); - - /* default to invalid */ - *res = 0; - - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - - /* get derlen */ - derlen = hash_descriptor[hash_idx].DERlen; - - /* get modulus len */ - modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); - - /* valid sizes? */ - if ((msghashlen + 3 + derlen > modulus_bytelen) || (siglen != modulus_bytelen)) { - return CRYPT_PK_INVALID_SIZE; - } - - /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */ - x = 0; - if (sig[x++] != 0x00 || sig[x++] != 0x01) { - return CRYPT_OK; - } - - /* now follows (modulus_bytelen - 3 - derlen - msghashlen) 0xFF bytes */ - for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) { - if (sig[x++] != 0xFF) { - return CRYPT_OK; - } - } - - if (sig[x++] != 0x00) { - return CRYPT_OK; - } - - for (y = 0; y < derlen; y++) { - if (sig[x++] != hash_descriptor[hash_idx].DER[y]) { - return CRYPT_OK; - } - } - - if (memcmp(msghash, sig+x, msghashlen) == 0) { - *res = 1; - } - return CRYPT_OK; -} - -#endif diff --git a/src/pk/pkcs1/pkcs_1_v15_sa_encode.c b/src/pk/pkcs1/pkcs_1_v15_sa_encode.c deleted file mode 100644 index 60c77ef..0000000 --- a/src/pk/pkcs1/pkcs_1_v15_sa_encode.c +++ /dev/null @@ -1,84 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file pkcs_1_v15_sa_encode.c - PKCS #1 v1.5 Signature Padding, Tom St Denis -*/ - -#ifdef PKCS_1 - -/** - Perform PKCS #1 v1.5 Signature Padding - @param msghash The hash you wish to incorporate in the padding - @param msghashlen The length of the hash - @param hash_idx The index of the hash used - @param modulus_bitlen The length of the RSA modulus that will sign this (bits) - @param out [out] Where to store the padded data - @param outlen [in/out] Max size and resulting size of the padded data - @return CRYPT_OK if successful -*/ -int pkcs_1_v15_sa_encode(const unsigned char *msghash, unsigned long msghashlen, - int hash_idx, unsigned long modulus_bitlen, - unsigned char *out, unsigned long *outlen) -{ - unsigned long derlen, modulus_bytelen, x, y; - int err; - - LTC_ARGCHK(msghash != NULL) - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - - /* hack, to detect any hash without a DER OID */ - if (hash_descriptor[hash_idx].DERlen == 0) { - return CRYPT_INVALID_ARG; - } - - /* get modulus len */ - modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); - - /* get der len ok? Forgive my lame German accent.... */ - derlen = hash_descriptor[hash_idx].DERlen; - - /* valid sizes? */ - if (msghashlen + 3 + derlen > modulus_bytelen) { - return CRYPT_PK_INVALID_SIZE; - } - - if (*outlen < modulus_bytelen) { - return CRYPT_BUFFER_OVERFLOW; - } - - /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */ - x = 0; - out[x++] = 0x00; - out[x++] = 0x01; - for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) { - out[x++] = 0xFF; - } - out[x++] = 0x00; - for (y = 0; y < derlen; y++) { - out[x++] = hash_descriptor[hash_idx].DER[y]; - } - for (y = 0; y < msghashlen; y++) { - out[x++] = msghash[y]; - } - - *outlen = modulus_bytelen; - return CRYPT_OK; -} - -#endif /* PKCS_1 */ diff --git a/src/pk/rsa/rsa_decrypt_key.c b/src/pk/rsa/rsa_decrypt_key.c index 3117715..ba2a076 100644 --- a/src/pk/rsa/rsa_decrypt_key.c +++ b/src/pk/rsa/rsa_decrypt_key.c @@ -87,3 +87,7 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_encrypt_key.c b/src/pk/rsa/rsa_encrypt_key.c index 891b43e..88efb3d 100644 --- a/src/pk/rsa/rsa_encrypt_key.c +++ b/src/pk/rsa/rsa_encrypt_key.c @@ -74,3 +74,7 @@ int rsa_encrypt_key(const unsigned char *in, unsigned long inlen, } #endif /* MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_export.c b/src/pk/rsa/rsa_export.c index 951be70..f7f42bf 100644 --- a/src/pk/rsa/rsa_export.c +++ b/src/pk/rsa/rsa_export.c @@ -27,7 +27,8 @@ */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) { - int err, x; + int err; + unsigned long zero=0; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); @@ -37,62 +38,39 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { return CRYPT_PK_INVALID_TYPE; } - if (*outlen < 4) { - return CRYPT_BUFFER_OVERFLOW; - } - - /* Mental Note: push space for the header 0x30 0x82 LL LL (LL = length of packet EXcluding 4 bytes) - * we assume LL > 255 which is true since the smallest RSA key has a 128-byte modulus (1024-bit) - */ - *outlen -= 4; if (type == PK_PRIVATE) { /* private key */ - mp_int zero; - - /* first INTEGER == 0 to signify two-prime RSA */ - if ((err = mp_init(&zero)) != MP_OKAY) { - return mpi_to_ltc_error(err); - } - /* output is Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p */ - if ((err = der_put_multi_integer( - out+4, outlen, &zero, &key->N, &key->e, - &key->d, &key->p, &key->q, &key->dP, - &key->dQ, &key->qP, NULL)) != CRYPT_OK) { - mp_clear(&zero); + if ((err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_SHORT_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_INTEGER, 1UL, &key->e, + LTC_ASN1_INTEGER, 1UL, &key->d, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->dP, + LTC_ASN1_INTEGER, 1UL, &key->dQ, + LTC_ASN1_INTEGER, 1UL, &key->qP, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { return err; } /* clear zero and return */ - mp_clear(&zero); + return CRYPT_OK; } else { /* public key */ - if ((err = der_put_multi_integer(out+4, outlen, &key->N, &key->e, NULL)) != CRYPT_OK) { - return err; - } + return der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_INTEGER, 1UL, &key->e, + LTC_ASN1_EOL, 0UL, NULL); } - - /* store the header */ - out[0] = 0x30; - if (*outlen < 256) { - /* shift the output up one byte if the header is only 3 bytes */ - for (x = 0; x < *outlen; x++) { - out[x+3] = out[x+4]; - } - out[1] = 0x81; - out[2] = (*outlen & 255); - *outlen += 3; - } else { - out[1] = 0x82; - out[2] = (*outlen >> 8) & 255; - out[3] = (*outlen & 255); - *outlen += 4; - } - return err; } #endif /* MRSA */ +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_exptmod.c b/src/pk/rsa/rsa_exptmod.c index fda6cbb..b7bfebd 100644 --- a/src/pk/rsa/rsa_exptmod.c +++ b/src/pk/rsa/rsa_exptmod.c @@ -103,3 +103,7 @@ done: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_free.c b/src/pk/rsa/rsa_free.c index 85ade97..a611460 100644 --- a/src/pk/rsa/rsa_free.c +++ b/src/pk/rsa/rsa_free.c @@ -29,3 +29,7 @@ void rsa_free(rsa_key *key) } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_import.c b/src/pk/rsa/rsa_import.c index 5408df0..d89ed97 100644 --- a/src/pk/rsa/rsa_import.c +++ b/src/pk/rsa/rsa_import.c @@ -18,7 +18,7 @@ #ifdef MRSA /** - Import an RSAPublicKey or RSAPrivateKey [two-prime only, defined in PKCS #1 v2.1] + Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1] @param in The packet to import from @param inlen It's length (octets) @param key [out] Destination for newly imported key @@ -26,65 +26,39 @@ */ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { - unsigned long x, y; - int err; + int err; + mp_int zero; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); /* init key */ - if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, - &key->p, &key->q, NULL)) != MP_OKAY) { + if ((err = mp_init_multi(&zero, &key->e, &key->d, &key->N, &key->dQ, + &key->dP, &key->qP, &key->p, &key->q, NULL)) != MP_OKAY) { return mpi_to_ltc_error(err); } - /* check the header */ - if (inlen < 4) { - return CRYPT_INVALID_PACKET; - } - - /* should be 0x30 0x8{1|2} LL LL */ - if ((in[0] != 0x30) || ((in[1] != 0x81) && (in[1] != 0x82))) { - return CRYPT_INVALID_PACKET; - } - - /* ok all the ASN.1 params are fine so far, let's move up */ - x = ((unsigned long)in[2]); - y = 0; - if ((in[1] & ~0x80) == 2) { - x = (x << 8) + ((unsigned long)in[3]) + 1; - in += 1; - y = 1; - } - in += 3; /* advance input */ - x += 3; /* size of packet according to header */ - y += 3; /* used input */ - - if (x != inlen) { - return CRYPT_INVALID_PACKET; - } - - /* decrement inlen by the header size */ - inlen -= y; - - /* read first number, it's either N or 0 [0 == private key] */ - x = inlen; - if ((err = der_get_multi_integer(in, &x, &key->N, NULL)) != CRYPT_OK) { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } - /* advance */ - inlen -= x; - in += x; - if (mp_cmp_d(&key->N, 0) == MP_EQ) { /* it's a private key */ - if ((err = der_get_multi_integer(in, &inlen, &key->N, &key->e, - &key->d, &key->p, &key->q, &key->dP, - &key->dQ, &key->qP, NULL)) != CRYPT_OK) { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, &zero, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_INTEGER, 1UL, &key->e, + LTC_ASN1_INTEGER, 1UL, &key->d, + LTC_ASN1_INTEGER, 1UL, &key->p, + LTC_ASN1_INTEGER, 1UL, &key->q, + LTC_ASN1_INTEGER, 1UL, &key->dP, + LTC_ASN1_INTEGER, 1UL, &key->dQ, + LTC_ASN1_INTEGER, 1UL, &key->qP, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } - key->type = PK_PRIVATE; } else if (mp_cmp_d(&key->N, 1) == MP_EQ) { /* we don't support multi-prime RSA */ @@ -92,21 +66,27 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) goto LBL_ERR; } else { /* it's a public key and we lack e */ - if ((err = der_get_multi_integer(in, &inlen, &key->e, NULL)) != CRYPT_OK) { + if ((err = der_decode_sequence_multi(in, inlen, + LTC_ASN1_INTEGER, 1UL, &key->N, + LTC_ASN1_INTEGER, 1UL, &key->e, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } /* free up some ram */ mp_clear_multi(&key->p, &key->q, &key->qP, &key->dP, &key->dQ, NULL); - key->type = PK_PUBLIC; } return CRYPT_OK; LBL_ERR: - mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, + mp_clear_multi(&zero, &key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL); return err; } #endif /* MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_make_key.c b/src/pk/rsa/rsa_make_key.c index 9d49e3c..34a94d3 100644 --- a/src/pk/rsa/rsa_make_key.c +++ b/src/pk/rsa/rsa_make_key.c @@ -119,3 +119,7 @@ done: } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_sign_hash.c b/src/pk/rsa/rsa_sign_hash.c index b86ad64..010ee3c 100644 --- a/src/pk/rsa/rsa_sign_hash.c +++ b/src/pk/rsa/rsa_sign_hash.c @@ -73,3 +73,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen, } #endif /* MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/pk/rsa/rsa_v15_decrypt_key.c b/src/pk/rsa/rsa_v15_decrypt_key.c deleted file mode 100644 index eb5fe7d..0000000 --- a/src/pk/rsa/rsa_v15_decrypt_key.c +++ /dev/null @@ -1,73 +0,0 @@ - /* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file rsa_v15_decrypt_key.c - RSA PKCS v1.5 Decryption, Tom St Denis -*/ - -#ifdef MRSA - -/** - RSA decrypt then PKCS #1 v1.5 depad - @param in The ciphertext - @param inlen The length of the ciphertext (octets) - @param out [out] The plaintext - @param outlen The length of the plaintext (you have to tell this function as it's not part of PKCS #1 v1.0 padding!) - @param stat [out] Status of decryption, 1==valid, 0==invalid - @param key The corresponding private RSA key - @return CRYPT_OK if successful (even if invalid) -*/ -int rsa_v15_decrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long outlen, - int *stat, rsa_key *key) -{ - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - unsigned char *tmp; - - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(stat != NULL); - - /* default to invalid */ - *stat = 0; - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits(&(key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size(&(key->N)); - if (modulus_bytelen != inlen) { - return CRYPT_INVALID_PACKET; - } - - /* allocate ram */ - tmp = XMALLOC(inlen); - if (tmp == NULL) { - return CRYPT_MEM; - } - - /* rsa decode the packet */ - x = inlen; - if ((err = rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { - XFREE(tmp); - return err; - } - - /* PKCS #1 v1.5 depad */ - err = pkcs_1_v15_es_decode(tmp, x, modulus_bitlen, out, outlen, stat); - XFREE(tmp); - return err; -} - -#endif diff --git a/src/pk/rsa/rsa_v15_encrypt_key.c b/src/pk/rsa/rsa_v15_encrypt_key.c deleted file mode 100644 index d422f67..0000000 --- a/src/pk/rsa/rsa_v15_encrypt_key.c +++ /dev/null @@ -1,68 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file rsa_v15_encrypt_key.c - RSA PKCS v1.5 Encryption, Tom St Denis -*/ - -#ifdef MRSA - -/** - PKCS #1 v1.5 pad then encrypt - @param in The plaintext - @param inlen The length of the plaintext (octets) - @param out [out] The ciphertext - @param outlen [in/out] The max size and resulting size of the ciphertext - @param prng An active PRNG - @param prng_idx The index of the desired PRNG - @param key The public RSA key - @return CRYPT_OK if successful -*/ -int rsa_v15_encrypt_key(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int prng_idx, - rsa_key *key) -{ - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(key != NULL); - - /* valid prng? */ - if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { - return err; - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits(&(key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size(&(key->N)); - if (modulus_bytelen > *outlen) { - return CRYPT_BUFFER_OVERFLOW; - } - - /* pad it */ - x = *outlen; - if ((err = pkcs_1_v15_es_encode(in, inlen, modulus_bitlen, prng, prng_idx, out, &x)) != CRYPT_OK) { - return err; - } - - /* encrypt it */ - return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key); -} - -#endif diff --git a/src/pk/rsa/rsa_v15_sign_hash.c b/src/pk/rsa/rsa_v15_sign_hash.c deleted file mode 100644 index 7e9b350..0000000 --- a/src/pk/rsa/rsa_v15_sign_hash.c +++ /dev/null @@ -1,66 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file rsa_v15_sign_hash.c - RSA PKCS v1.5 Signature, Tom St Denis -*/ - -#ifdef MRSA - -/** - PKCS #1 v1.5 pad then sign - @param in The hash to sign - @param inlen The length of the message hash (octets) - @param out [out] The signature - @param siglen [in/out] The max size and resulting size of the signature - @param hash_idx The index of the hash desired - @param key The private RSA key to perform the signature with - @return CRYPT_OK if successful -*/ -int rsa_v15_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *siglen, - int hash_idx, rsa_key *key) -{ - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(siglen != NULL); - LTC_ARGCHK(key != NULL); - - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits(&(key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size(&(key->N)); - if (modulus_bytelen > *siglen) { - return CRYPT_BUFFER_OVERFLOW; - } - - /* PKCS #1 v1.5 pad the key */ - x = *siglen; - if ((err = pkcs_1_v15_sa_encode(in, inlen, hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { - return err; - } - - /* RSA encode it */ - return rsa_exptmod(out, x, out, siglen, PK_PRIVATE, key); -} - -#endif diff --git a/src/pk/rsa/rsa_v15_verify_hash.c b/src/pk/rsa/rsa_v15_verify_hash.c deleted file mode 100644 index e742cba..0000000 --- a/src/pk/rsa/rsa_v15_verify_hash.c +++ /dev/null @@ -1,81 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ -#include "tomcrypt.h" - -/** - @file rsa_v15_verify_hash.c - RSA PKCS v1.5 Signature verification, Tom St Denis -*/ - -#ifdef MRSA - -/** - RSA de-sign then PKCS v1.5 signature depad - @param sig The signature data - @param siglen The length of the signature (octets) - @param hash The hash of the message that was signed - @param hashlen The length of the hash of the message that was signed (octets) - @param hash_idx The index of the desired hash - @param stat [out] The result of the signature comparison, 1==valid, 0==invalid - @param key The corresponding public RSA key that performed the signature - @return CRYPT_OK if successful (even if the signature is invalid) -*/ -int rsa_v15_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int hash_idx, int *stat, - rsa_key *key) -{ - unsigned long modulus_bitlen, modulus_bytelen, x; - int err; - unsigned char *tmpbuf; - - LTC_ARGCHK(hash != NULL); - LTC_ARGCHK(sig != NULL); - LTC_ARGCHK(stat != NULL); - LTC_ARGCHK(key != NULL); - - /* default to invalid */ - *stat = 0; - - /* valid hash ? */ - if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { - return err; - } - - /* get modulus len in bits */ - modulus_bitlen = mp_count_bits(&(key->N)); - - /* outlen must be at least the size of the modulus */ - modulus_bytelen = mp_unsigned_bin_size(&(key->N)); - if (modulus_bytelen != siglen) { - return CRYPT_INVALID_PACKET; - } - - /* allocate temp buffer for decoded sig */ - tmpbuf = XMALLOC(siglen); - if (tmpbuf == NULL) { - return CRYPT_MEM; - } - - /* RSA decode it */ - x = siglen; - if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { - XFREE(tmpbuf); - return err; - } - - /* PSS decode it */ - err = pkcs_1_v15_sa_decode(hash, hashlen, tmpbuf, x, hash_idx, modulus_bitlen, stat); - XFREE(tmpbuf); - return err; -} - -#endif diff --git a/src/pk/rsa/rsa_verify_hash.c b/src/pk/rsa/rsa_verify_hash.c index 7072083..ab5b2f8 100644 --- a/src/pk/rsa/rsa_verify_hash.c +++ b/src/pk/rsa/rsa_verify_hash.c @@ -80,3 +80,7 @@ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, } #endif /* MRSA */ + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/fortuna.c b/src/prngs/fortuna.c index 4548a90..cdb67bf 100644 --- a/src/prngs/fortuna.c +++ b/src/prngs/fortuna.c @@ -384,3 +384,7 @@ int fortuna_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/rc4.c b/src/prngs/rc4.c index 750c38b..feddf1c 100644 --- a/src/prngs/rc4.c +++ b/src/prngs/rc4.c @@ -258,3 +258,7 @@ int rc4_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/rng_get_bytes.c b/src/prngs/rng_get_bytes.c index 8519e0a..bd0972c 100644 --- a/src/prngs/rng_get_bytes.c +++ b/src/prngs/rng_get_bytes.c @@ -138,3 +138,7 @@ unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, #endif return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/rng_make_prng.c b/src/prngs/rng_make_prng.c index 94132e7..ce410e6 100644 --- a/src/prngs/rng_make_prng.c +++ b/src/prngs/rng_make_prng.c @@ -63,3 +63,7 @@ int rng_make_prng(int bits, int wprng, prng_state *prng, return CRYPT_OK; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/sober128.c b/src/prngs/sober128.c index 48667bd..f509474 100644 --- a/src/prngs/sober128.c +++ b/src/prngs/sober128.c @@ -489,3 +489,7 @@ int sober128_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/sober128tab.c b/src/prngs/sober128tab.c index e25e271..a5754c7 100644 --- a/src/prngs/sober128tab.c +++ b/src/prngs/sober128tab.c @@ -156,3 +156,7 @@ static const ulong32 Sbox[256] = { 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8, 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40, }; + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/sprng.c b/src/prngs/sprng.c index dce8347..dc82667 100644 --- a/src/prngs/sprng.c +++ b/src/prngs/sprng.c @@ -130,3 +130,7 @@ int sprng_test(void) + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/src/prngs/yarrow.c b/src/prngs/yarrow.c index 1582856..4abaf73 100644 --- a/src/prngs/yarrow.c +++ b/src/prngs/yarrow.c @@ -186,6 +186,7 @@ int yarrow_ready(prng_state *prng) prng->yarrow.pool, /* IV */ prng->yarrow.pool, ks, /* KEY and key size */ 0, /* number of rounds */ + CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ &prng->yarrow.ctr)) != CRYPT_OK) { return err; } @@ -310,3 +311,7 @@ int yarrow_test(void) #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testbuild.sh b/testbuild.sh new file mode 100644 index 0000000..a17c677 --- /dev/null +++ b/testbuild.sh @@ -0,0 +1,11 @@ +#!/bin/bash +echo "$1 (Build Only, $2, $3)..." +make clean 1>/dev/null 2>/dev/null +echo -n "building..." +touch testok.txt +CFLAGS="$2" make -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && rm -f testok.txt && exit 1) +if find testok.txt -type f 1>/dev/null 2>/dev/null ; then + echo "successful" + exit 0 +fi +exit 1 diff --git a/testme.sh b/testme.sh new file mode 100644 index 0000000..da0f97b --- /dev/null +++ b/testme.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +# date +echo "date="`date` + +# output version +echo "Testing verion" `grep "^VERSION=" makefile | sed "s/.*=//"` +#grep "VERSION=" makefile | perl -e "@a = split('=', <>); print @a[1];"` + +# get uname +echo "uname="`uname -a` +echo + +# stock build +bash run.sh "STOCK" " " $1 || exit 1 + +# SMALL code +bash run.sh "SMALL" "-DLTC_SMALL_CODE" $1 || exit 1 + +# NOTABLES +bash run.sh "NOTABLES" "-DLTC_NO_TABLES" $1 || exit 1 + +# SMALL+NOTABLES +bash run.sh "SMALL+NOTABLES" "-DLTC_SMALL_CODE -DLTC_NO_TABLES" $1 || exit 1 + +# CLEANSTACK +bash run.sh "CLEANSTACK" "-DLTC_CLEAN_STACK" $1 || exit 1 + +# CLEANSTACK + SMALL +bash run.sh "CLEANSTACK+SMALL" "-DLTC_SMALL_CODE -DLTC_CLEAN_STACK" $1 || exit 1 + +# CLEANSTACK + NOTABLES +bash run.sh "CLEANSTACK+NOTABLES" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK" $1 || exit 1 + +# CLEANSTACK + NOTABLES + SMALL +bash run.sh "CLEANSTACK+NOTABLES+SMALL" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK -DLTC_SMALL_CODE" $1 || exit 1 + +# NO_FAST +bash run.sh "NO_FAST" "-DLTC_NO_FAST" $1 || exit 1 + +# NO_ASM +bash run.sh "NO_ASM" "-DLTC_NO_ASM" $1 || exit 1 + +# test build with no testing +bash testbuild.sh "NOTEST" "-DLTC_NO_TEST" $1 || exit 1 + +# test build with no file routines +bash testbuild.sh "NOFILE" "-DLTC_NO_FILE" $1 || exit 1 + +# $Source: /cvs/libtom/libtomcrypt/testme.sh,v $ +# $Revision: 1.16 $ +# $Date: 2005/05/11 18:59:53 $ diff --git a/testprof/base64_test.c b/testprof/base64_test.c index e93ebef..5ce55dd 100644 --- a/testprof/base64_test.c +++ b/testprof/base64_test.c @@ -12,9 +12,13 @@ int base64_test(void) l2 = sizeof(tmp); DO(base64_decode(out, l1, tmp, &l2)); if (l2 != x || memcmp(tmp, in, x)) { - printf("base64 failed %lu %lu %lu", x, l1, l2); + fprintf(stderr, "base64 failed %lu %lu %lu", x, l1, l2); return 1; } } return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/cipher_hash_test.c b/testprof/cipher_hash_test.c index d2f3bfc..666d913 100644 --- a/testprof/cipher_hash_test.c +++ b/testprof/cipher_hash_test.c @@ -39,3 +39,7 @@ int cipher_hash_test(void) return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/der_tests.c b/testprof/der_tests.c index fe8eb00..95f3348 100644 --- a/testprof/der_tests.c +++ b/testprof/der_tests.c @@ -4,7 +4,7 @@ int der_tests(void) { - printf("NOP"); + fprintf(stderr, "NOP"); return 0; } @@ -12,83 +12,219 @@ int der_tests(void) int der_tests(void) { - unsigned long x, y, z, zz; - unsigned char buf[2][4096]; + unsigned long x, y, z, zz, oid[2][32]; + unsigned char buf[3][2048]; mp_int a, b, c, d, e, f, g; + static const unsigned char rsa_oid_der[] = { 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d }; + static const unsigned long rsa_oid[] = { 1, 2, 840, 113549 }; + + static const unsigned char rsa_ia5[] = "test1@rsa.com"; + static const unsigned char rsa_ia5_der[] = { 0x16, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, + 0x40, 0x72, 0x73, 0x61, 0x2e, 0x63, 0x6f, 0x6d }; + + static const unsigned char rsa_printable[] = "Test User 1"; + static const unsigned char rsa_printable_der[] = { 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, + 0x73, 0x65, 0x72, 0x20, 0x31 }; + DO(mpi_to_ltc_error(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL))); for (zz = 0; zz < 16; zz++) { for (z = 0; z < 1024; z++) { if (yarrow_read(buf[0], z, &yarrow_prng) != z) { - printf("Failed to read %lu bytes from yarrow\n", z); + fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z); return 1; } DO(mpi_to_ltc_error(mp_read_unsigned_bin(&a, buf[0], z))); + if (mp_iszero(&a) == MP_NO) { a.sign = buf[0][0] & 1 ? MP_ZPOS : MP_NEG; } x = sizeof(buf[0]); DO(der_encode_integer(&a, buf[0], &x)); - y = x; + DO(der_length_integer(&a, &y)); + if (y != x) { fprintf(stderr, "DER INTEGER size mismatch\n"); return 1; } mp_zero(&b); - DO(der_decode_integer(buf[0], &y, &b)); + DO(der_decode_integer(buf[0], y, &b)); if (y != x || mp_cmp(&a, &b) != MP_EQ) { - printf("%lu: %lu vs %lu\n", z, x, y); + fprintf(stderr, "%lu: %lu vs %lu\n", z, x, y); #ifdef BN_MP_TORADIX_C mp_todecimal(&a, buf[0]); mp_todecimal(&b, buf[1]); - printf("a == %s\nb == %s\n", buf[0], buf[1]); + fprintf(stderr, "a == %s\nb == %s\n", buf[0], buf[1]); #endif mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); return 1; } } } - -/* test the multi */ - mp_set(&a, 1); - x = sizeof(buf[0]); - DO(der_put_multi_integer(buf[0], &x, &a, NULL)); - y = x; - mp_zero(&a); - DO(der_get_multi_integer(buf[0], &y, &a, NULL)); - if (x != y || mp_cmp_d(&a, 1)) { - printf("%lu, %lu, %d\n", x, y, mp_cmp_d(&a, 1)); - mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); - return 1; - } +/* test short integer */ + for (zz = 0; zz < 256; zz++) { + for (z = 1; z < 4; z++) { + if (yarrow_read(buf[0], z, &yarrow_prng) != z) { + fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z); + return 1; + } + /* encode with normal */ + DO(mpi_to_ltc_error(mp_read_unsigned_bin(&a, buf[0], z))); - mp_set(&a, 1); - mp_set(&b, 2); - x = sizeof(buf[0]); - DO(der_put_multi_integer(buf[0], &x, &a, &b, NULL)); - y = x; - mp_zero(&a); - mp_zero(&b); - DO(der_get_multi_integer(buf[0], &y, &a, &b, NULL)); - if (x != y || mp_cmp_d(&a, 1) || mp_cmp_d(&b, 2)) { - printf("%lu, %lu, %d, %d\n", x, y, mp_cmp_d(&a, 1), mp_cmp_d(&b, 2)); - mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); - return 1; - } - - mp_set(&a, 1); - mp_set(&b, 2); - mp_set(&c, 3); - x = sizeof(buf[0]); - DO(der_put_multi_integer(buf[0], &x, &a, &b, &c, NULL)); - y = x; - mp_zero(&a); - mp_zero(&b); - mp_zero(&c); - DO(der_get_multi_integer(buf[0], &y, &a, &b, &c, NULL)); - if (x != y || mp_cmp_d(&a, 1) || mp_cmp_d(&b, 2) || mp_cmp_d(&c, 3)) { - printf("%lu, %lu, %d, %d, %d\n", x, y, mp_cmp_d(&a, 1), mp_cmp_d(&b, 2), mp_cmp_d(&c, 3)); - mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); - return 1; - } + x = sizeof(buf[0]); + DO(der_encode_integer(&a, buf[0], &x)); + /* encode with short */ + y = sizeof(buf[1]); + DO(der_encode_short_integer(mp_get_int(&a), buf[1], &y)); + if (x != y || memcmp(buf[0], buf[1], x)) { + fprintf(stderr, "DER INTEGER short encoding failed, %lu, %lu\n", x, y); + for (z = 0; z < x; z++) fprintf(stderr, "%02x ", buf[0][z]); fprintf(stderr, "\n"); + for (z = 0; z < y; z++) fprintf(stderr, "%02x ", buf[1][z]); fprintf(stderr, "\n"); + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 1; + } + /* decode it */ + x = 0; + DO(der_decode_short_integer(buf[1], y, &x)); + if (x != mp_get_int(&a)) { + fprintf(stderr, "DER INTEGER short decoding failed, %lu, %lu\n", x, mp_get_int(&a)); + mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + return 1; + } + } + } mp_clear_multi(&a, &b, &c, &d, &e, &f, &g, NULL); + + +/* Test bit string */ + for (zz = 1; zz < 1536; zz++) { + yarrow_read(buf[0], zz, &yarrow_prng); + for (z = 0; z < zz; z++) { + buf[0][z] &= 0x01; + } + x = sizeof(buf[1]); + DO(der_encode_bit_string(buf[0], zz, buf[1], &x)); + DO(der_length_bit_string(zz, &y)); + if (y != x) { + fprintf(stderr, "\nDER BIT STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y); + return 1; + } + + y = sizeof(buf[2]); + DO(der_decode_bit_string(buf[1], x, buf[2], &y)); + if (y != zz || memcmp(buf[0], buf[2], zz)) { + fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz)); + return 1; + } + } + +/* Test octet string */ + for (zz = 1; zz < 1536; zz++) { + yarrow_read(buf[0], zz, &yarrow_prng); + x = sizeof(buf[1]); + DO(der_encode_octet_string(buf[0], zz, buf[1], &x)); + DO(der_length_octet_string(zz, &y)); + if (y != x) { + fprintf(stderr, "\nDER OCTET STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y); + return 1; + } + y = sizeof(buf[2]); + DO(der_decode_octet_string(buf[1], x, buf[2], &y)); + if (y != zz || memcmp(buf[0], buf[2], zz)) { + fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz)); + return 1; + } + } + +/* test OID */ + x = sizeof(buf[0]); + DO(der_encode_object_identifier(rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x)); + if (x != sizeof(rsa_oid_der) || memcmp(rsa_oid_der, buf[0], x)) { + fprintf(stderr, "rsa_oid_der encode failed to match, %lu, ", x); + for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); + fprintf(stderr, "\n"); + return 1; + } + + y = sizeof(oid[0])/sizeof(oid[0][0]); + DO(der_decode_object_identifier(buf[0], x, oid[0], &y)); + if (y != sizeof(rsa_oid)/sizeof(rsa_oid[0]) || memcmp(rsa_oid, oid[0], sizeof(rsa_oid))) { + fprintf(stderr, "rsa_oid_der decode failed to match, %lu, ", y); + for (z = 0; z < y; z++) fprintf(stderr, "%lu ", oid[0][z]); + fprintf(stderr, "\n"); + return 1; + } + + /* do random strings */ + for (zz = 0; zz < 5000; zz++) { + /* pick a random number of words */ + yarrow_read(buf[0], 4, &yarrow_prng); + LOAD32L(z, buf[0]); + z = 2 + (z % ((sizeof(oid[0])/sizeof(oid[0][0])) - 2)); + + /* fill them in */ + oid[0][0] = buf[0][0] % 3; + oid[0][1] = buf[0][1] % 40; + + for (y = 2; y < z; y++) { + yarrow_read(buf[0], 4, &yarrow_prng); + LOAD32L(oid[0][y], buf[0]); + } + + /* encode it */ + x = sizeof(buf[0]); + DO(der_encode_object_identifier(oid[0], z, buf[0], &x)); + DO(der_length_object_identifier(oid[0], z, &y)); + if (x != y) { + fprintf(stderr, "Random OID %lu test failed, length mismatch: %lu, %lu\n", z, x, y); + for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); + return 1; + } + + /* decode it */ + y = sizeof(oid[0])/sizeof(oid[0][0]); + DO(der_decode_object_identifier(buf[0], x, oid[1], &y)); + if (y != z) { + fprintf(stderr, "Random OID %lu test failed, decode length mismatch: %lu, %lu\n", z, x, y); + return 1; + } + if (memcmp(oid[0], oid[1], sizeof(oid[0][0]) * z)) { + fprintf(stderr, "Random OID %lu test failed, decoded values wrong\n", z); + for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); fprintf(stderr, "\n\n Got \n\n"); + for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[1][x]); + return 1; + } + } + +/* IA5 string */ + x = sizeof(buf[0]); + DO(der_encode_ia5_string(rsa_ia5, strlen(rsa_ia5), buf[0], &x)); + if (x != sizeof(rsa_ia5_der) || memcmp(buf[0], rsa_ia5_der, x)) { + fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der)); + return 1; + } + y = sizeof(buf[1]); + DO(der_decode_ia5_string(buf[0], x, buf[1], &y)); + if (y != strlen(rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen(rsa_ia5))) { + fprintf(stderr, "DER IA5 failed test vector\n"); + return 1; + } + +/* Printable string */ + x = sizeof(buf[0]); + DO(der_encode_printable_string(rsa_printable, strlen(rsa_printable), buf[0], &x)); + if (x != sizeof(rsa_printable_der) || memcmp(buf[0], rsa_printable_der, x)) { + fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der)); + return 1; + } + y = sizeof(buf[1]); + DO(der_decode_printable_string(buf[0], x, buf[1], &y)); + if (y != strlen(rsa_printable) || memcmp(buf[1], rsa_printable, strlen(rsa_printable))) { + fprintf(stderr, "DER printable failed test vector\n"); + return 1; + } + return 0; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/dh_tests.c b/testprof/dh_tests.c index feb74ac..e644b06 100644 --- a/testprof/dh_tests.c +++ b/testprof/dh_tests.c @@ -22,11 +22,11 @@ int dh_tests (void) y = 4096; DO(dh_shared_secret (&userb, &usera, buf[1], &y)); if (y != x) { - printf ("DH Shared keys are not same size.\n"); + fprintf(stderr, "DH Shared keys are not same size.\n"); return 1; } if (memcmp (buf[0], buf[1], x)) { - printf ("DH Shared keys not same contents.\n"); + fprintf(stderr, "DH Shared keys not same contents.\n"); return 1; } @@ -41,11 +41,11 @@ int dh_tests (void) DO(dh_shared_secret (&usera, &userb, buf[2], &z)); if (z != x) { - printf ("failed. Size don't match?\n"); + fprintf(stderr, "failed. Size don't match?\n"); return 1; } if (memcmp (buf[0], buf[2], x)) { - printf ("Failed. Content didn't match.\n"); + fprintf(stderr, "Failed. Content didn't match.\n"); return 1; } dh_free (&usera); @@ -62,12 +62,12 @@ int dh_tests (void) x = sizeof (buf[0]); DO(dh_decrypt_key (buf[1], y, buf[0], &x, &usera)); if (x != 16) { - printf ("Failed (length)\n"); + fprintf(stderr, "Failed (length)\n"); return 1; } for (x = 0; x < 16; x++) if (buf[0][x] != x) { - printf ("Failed (contents)\n"); + fprintf(stderr, "Failed (contents)\n"); return 1; } @@ -81,7 +81,7 @@ int dh_tests (void) buf[0][0] ^= 1; DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera)); if (!(stat == 1 && stat2 == 0)) { - printf("dh_sign/verify_hash %d %d", stat, stat2); + fprintf(stderr, "dh_sign/verify_hash %d %d", stat, stat2); return 1; } dh_free (&usera); @@ -92,8 +92,12 @@ int dh_tests (void) int dh_tests(void) { - printf("NOP"); + fprintf(stderr, "NOP"); return 0; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/dsa_test.c b/testprof/dsa_test.c index cd2e89a..6724feb 100644 --- a/testprof/dsa_test.c +++ b/testprof/dsa_test.c @@ -14,7 +14,7 @@ int dsa_test(void) /* verify it */ DO(dsa_verify_key(&key, &stat1)); - if (stat1 == 0) { printf("dsa_verify_key "); return 1; } + if (stat1 == 0) { fprintf(stderr, "dsa_verify_key "); return 1; } /* sign the message */ x = sizeof(out); @@ -27,7 +27,7 @@ int dsa_test(void) msg[0] ^= 1; DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key)); msg[0] ^= 1; - if (!(stat1 == 1 && stat2 == 0)) { printf("dsa_verify %d %d", stat1, stat2); return 1; } + if (!(stat1 == 1 && stat2 == 0)) { fprintf(stderr, "dsa_verify %d %d", stat1, stat2); return 1; } /* test exporting it */ x = sizeof(out2); @@ -36,16 +36,17 @@ int dsa_test(void) /* verify a signature with it */ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)); - if (stat1 == 0) { printf("dsa_verify (import private) %d ", stat1); return 1; } + if (stat1 == 0) { fprintf(stderr, "dsa_verify (import private) %d ", stat1); return 1; } dsa_free(&key2); /* export as public now */ x = sizeof(out2); DO(dsa_export(out2, &x, PK_PUBLIC, &key)); + DO(dsa_import(out2, x, &key2)); /* verify a signature with it */ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)); - if (stat1 == 0) { printf("dsa_verify (import public) %d ", stat1); return 1; } + if (stat1 == 0) { fprintf(stderr, "dsa_verify (import public) %d ", stat1); return 1; } dsa_free(&key2); dsa_free(&key); @@ -56,8 +57,12 @@ int dsa_test(void) int dsa_test(void) { - printf("NOP"); + fprintf(stderr, "NOP"); return 0; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/ecc_test.c b/testprof/ecc_test.c index 0b37ba2..4ec3e8a 100644 --- a/testprof/ecc_test.c +++ b/testprof/ecc_test.c @@ -2,102 +2,123 @@ #ifdef MECC +static int sizes[] = { +#ifdef ECC192 +24, +#endif +#ifdef ECC224 +28, +#endif +#ifdef ECC256 +32, +#endif +#ifdef ECC384 +48, +#endif +#ifdef ECC512 +65 +#endif +}; + int ecc_tests (void) { unsigned char buf[4][4096]; - unsigned long x, y, z; + unsigned long x, y, z, s; int stat, stat2; ecc_key usera, userb, pubKey, privKey; DO(ecc_test ()); - /* make up two keys */ - DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &usera)); - DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &userb)); + for (s = 0; s < (int)(sizeof(sizes)/sizeof(sizes[0])); s++) { + /* make up two keys */ + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb)); - /* make the shared secret */ - x = 4096; - DO(ecc_shared_secret (&usera, &userb, buf[0], &x)); + /* make the shared secret */ + x = 4096; + DO(ecc_shared_secret (&usera, &userb, buf[0], &x)); - y = 4096; - DO(ecc_shared_secret (&userb, &usera, buf[1], &y)); + y = 4096; + DO(ecc_shared_secret (&userb, &usera, buf[1], &y)); - if (y != x) { - printf ("ecc Shared keys are not same size."); - return 1; + if (y != x) { + fprintf(stderr, "ecc Shared keys are not same size."); + return 1; + } + + if (memcmp (buf[0], buf[1], x)) { + fprintf(stderr, "ecc Shared keys not same contents."); + return 1; + } + + /* now export userb */ + y = 4096; + DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb)); + ecc_free (&userb); + + /* import and make the shared secret again */ + DO(ecc_import (buf[1], y, &userb)); + + z = 4096; + DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); + + if (z != x) { + fprintf(stderr, "failed. Size don't match?"); + return 1; + } + if (memcmp (buf[0], buf[2], x)) { + fprintf(stderr, "Failed. Content didn't match."); + return 1; + } + ecc_free (&usera); + ecc_free (&userb); + + /* test encrypt_key */ + DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); + + /* export key */ + x = sizeof(buf[0]); + DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera)); + DO(ecc_import(buf[0], x, &pubKey)); + x = sizeof(buf[0]); + DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera)); + DO(ecc_import(buf[0], x, &privKey)); + + for (x = 0; x < 32; x++) { + buf[0][x] = x; + } + y = sizeof (buf[1]); + DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); + zeromem (buf[0], sizeof (buf[0])); + x = sizeof (buf[0]); + DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey)); + if (x != 32) { + fprintf(stderr, "Failed (length)"); + return 1; + } + for (x = 0; x < 32; x++) { + if (buf[0][x] != x) { + fprintf(stderr, "Failed (contents)"); + return 1; + } + } + /* test sign_hash */ + for (x = 0; x < 16; x++) { + buf[0][x] = x; + } + x = sizeof (buf[1]); + DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); + DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); + buf[0][0] ^= 1; + DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); + if (!(stat == 1 && stat2 == 0)) { + fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2); + return 1; + } + ecc_free (&usera); + ecc_free (&pubKey); + ecc_free (&privKey); } - - if (memcmp (buf[0], buf[1], x)) { - printf ("ecc Shared keys not same contents."); - return 1; - } - - /* now export userb */ - y = 4096; - DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb)); - ecc_free (&userb); - - /* import and make the shared secret again */ - DO(ecc_import (buf[1], y, &userb)); - - z = 4096; - DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); - - if (z != x) { - printf ("failed. Size don't match?"); - return 1; - } - if (memcmp (buf[0], buf[2], x)) { - printf ("Failed. Content didn't match."); - return 1; - } - ecc_free (&usera); - ecc_free (&userb); - -/* test encrypt_key */ - DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), 65, &usera)); - -/* export key */ - x = sizeof(buf[0]); - DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera)); - DO(ecc_import(buf[0], x, &pubKey)); - x = sizeof(buf[0]); - DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera)); - DO(ecc_import(buf[0], x, &privKey)); - - for (x = 0; x < 32; x++) { - buf[0][x] = x; - } - y = sizeof (buf[1]); - DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); - zeromem (buf[0], sizeof (buf[0])); - x = sizeof (buf[0]); - DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey)); - if (x != 32) { - printf ("Failed (length)"); - return 1; - } - for (x = 0; x < 32; x++) - if (buf[0][x] != x) { - printf ("Failed (contents)"); - return 1; - } -/* test sign_hash */ - for (x = 0; x < 16; x++) { - buf[0][x] = x; - } - x = sizeof (buf[1]); - DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); - DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); - buf[0][0] ^= 1; - DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); - if (!(stat == 1 && stat2 == 0)) { - printf("ecc_verify_hash failed %d, %d, ", stat, stat2); - return 1; - } - ecc_free (&usera); - ecc_free (&pubKey); - ecc_free (&privKey); return 0; } @@ -105,8 +126,12 @@ int ecc_tests (void) int ecc_tests(void) { - printf("NOP"); + fprintf(stderr, "NOP"); return 0; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/mac_test.c b/testprof/mac_test.c index b076d7b..e22a72a 100644 --- a/testprof/mac_test.c +++ b/testprof/mac_test.c @@ -29,3 +29,7 @@ int mac_test(void) #endif return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/makefile.icc b/testprof/makefile.icc index c9226fb..ff87660 100644 --- a/testprof/makefile.icc +++ b/testprof/makefile.icc @@ -1,4 +1,4 @@ -CFLAGS += -I../src/headers -I./ -O3 -xP -ip +CFLAGS += -I../src/headers -I./ CC=icc OBJECTS = base64_test.o cipher_hash_test.o der_tests.o dh_tests.o \ diff --git a/testprof/modes_test.c b/testprof/modes_test.c index 46beb8a..da25f85 100644 --- a/testprof/modes_test.c +++ b/testprof/modes_test.c @@ -19,7 +19,7 @@ int modes_test(void) /* get idx of AES handy */ cipher_idx = find_cipher("aes"); if (cipher_idx == -1) { - printf("test requires AES"); + fprintf(stderr, "test requires AES"); return 1; } @@ -30,7 +30,7 @@ int modes_test(void) l = sizeof(iv2); DO(cbc_getiv(iv2, &l, &cbc)); if (l != 16 || memcmp(iv2, iv, 16)) { - printf("cbc_getiv failed"); + fprintf(stderr, "cbc_getiv failed"); return 1; } DO(cbc_encrypt(pt, ct, 64, &cbc)); @@ -40,7 +40,7 @@ int modes_test(void) zeromem(tmp, sizeof(tmp)); DO(cbc_decrypt(ct, tmp, 64, &cbc)); if (memcmp(tmp, pt, 64) != 0) { - printf("CBC failed"); + fprintf(stderr, "CBC failed"); return 1; } #endif @@ -53,7 +53,7 @@ int modes_test(void) DO(cfb_getiv(iv2, &l, &cfb)); /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */ if (l != 16) { - printf("cfb_getiv failed"); + fprintf(stderr, "cfb_getiv failed"); return 1; } DO(cfb_encrypt(pt, ct, 64, &cfb)); @@ -63,7 +63,7 @@ int modes_test(void) zeromem(tmp, sizeof(tmp)); DO(cfb_decrypt(ct, tmp, 64, &cfb)); if (memcmp(tmp, pt, 64) != 0) { - printf("CFB failed"); + fprintf(stderr, "CFB failed"); return 1; } #endif @@ -75,7 +75,7 @@ int modes_test(void) l = sizeof(iv2); DO(ofb_getiv(iv2, &l, &ofb)); if (l != 16 || memcmp(iv2, iv, 16)) { - printf("ofb_getiv failed"); + fprintf(stderr, "ofb_getiv failed"); return 1; } DO(ofb_encrypt(pt, ct, 64, &ofb)); @@ -85,7 +85,7 @@ int modes_test(void) zeromem(tmp, sizeof(tmp)); DO(ofb_decrypt(ct, tmp, 64, &ofb)); if (memcmp(tmp, pt, 64) != 0) { - printf("OFB failed"); + fprintf(stderr, "OFB failed"); return 1; } #endif @@ -93,11 +93,11 @@ int modes_test(void) #ifdef CTR /* test CTR mode */ /* encode the block */ - DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr)); + DO(ctr_start(cipher_idx, iv, key, 16, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr)); l = sizeof(iv2); DO(ctr_getiv(iv2, &l, &ctr)); if (l != 16 || memcmp(iv2, iv, 16)) { - printf("ctr_getiv failed"); + fprintf(stderr, "ctr_getiv failed"); return 1; } DO(ctr_encrypt(pt, ct, 57, &ctr)); @@ -107,10 +107,14 @@ int modes_test(void) zeromem(tmp, sizeof(tmp)); DO(ctr_decrypt(ct, tmp, 57, &ctr)); if (memcmp(tmp, pt, 57) != 0) { - printf("CTR failed"); + fprintf(stderr, "CTR failed"); return 1; } #endif return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/pkcs_1_test.c b/testprof/pkcs_1_test.c index 40cf630..aabf30b 100644 --- a/testprof/pkcs_1_test.c +++ b/testprof/pkcs_1_test.c @@ -14,7 +14,7 @@ int pkcs_1_test(void) prng_idx = find_prng("yarrow"); if (hash_idx == -1 || prng_idx == -1) { - printf("pkcs_1 tests require sha1/yarrow"); + fprintf(stderr, "pkcs_1 tests require sha1/yarrow"); return 1; } @@ -29,30 +29,6 @@ int pkcs_1_test(void) /* random modulus len (v1.5 must be multiple of 8 though arbitrary sizes seem to work) */ modlen = 800 + 8 * (abs(rand()) % 28); - /* PKCS v1.5 testing (encryption) */ - l1 = sizeof(buf[1]); - DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &yarrow_prng, prng_idx, buf[1], &l1)); - DO(pkcs_1_v15_es_decode(buf[1], l1, modlen, buf[2], l3, &res1)); - if (res1 != 1 || memcmp(buf[0], buf[2], l3)) { - printf("pkcs v1.5 encrypt failed %d, %lu, %lu ", res1, l1, l3); - return 1; - } - - /* PKCS v1.5 testing (signatures) */ - l1 = sizeof(buf[1]); - DO(pkcs_1_v15_sa_encode(buf[0], l3, hash_idx, modlen, buf[1], &l1)); - DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res1)); - buf[0][i1 = abs(rand()) % l3] ^= 1; - DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res2)); - buf[0][i1] ^= 1; - buf[1][i2 = abs(rand()) % l1] ^= 1; - DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res3)); - - if (!(res1 == 1 && res2 == 0 && res3 == 0)) { - printf("pkcs v1.5 sign failed %d %d %d ", res1, res2, res3); - return 1; - } - /* pick a random lparam len [0..16] */ lparamlen = abs(rand()) % 17; @@ -71,16 +47,16 @@ int pkcs_1_test(void) DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1)); if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { - printf("Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); - printf("ORIGINAL:\n"); + fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); + fprintf(stderr, "ORIGINAL:\n"); for (x = 0; x < l3; x++) { - printf("%02x ", buf[0][x]); + fprintf(stderr, "%02x ", buf[0][x]); } - printf("\nRESULT:\n"); + fprintf(stderr, "\nRESULT:\n"); for (x = 0; x < l2; x++) { - printf("%02x ", buf[2][x]); + fprintf(stderr, "%02x ", buf[2][x]); } - printf("\n\n"); + fprintf(stderr, "\n\n"); return 1; } @@ -97,7 +73,7 @@ int pkcs_1_test(void) DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3)); if (!(res1 == 1 && res2 == 0 && res3 == 0)) { - printf("PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen); + fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen); return 1; } } @@ -108,9 +84,13 @@ int pkcs_1_test(void) int pkcs_1_test(void) { - printf("NOP"); + fprintf(stderr, "NOP"); return 0; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/rsa_test.c b/testprof/rsa_test.c index f114e49..f2893ee 100644 --- a/testprof/rsa_test.c +++ b/testprof/rsa_test.c @@ -4,18 +4,125 @@ #define RSA_MSGSIZE 78 +/* These are test keys [see file test.key] that I use to test my import/export against */ +static const unsigned char openssl_private_rsa[] = { + 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, + 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, + 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, + 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, + 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, + 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, + 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, + 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, + 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x81, 0x00, 0xc8, 0x62, 0xb9, 0xea, 0xde, 0x44, 0x53, 0x1d, 0x56, 0x97, 0xd9, 0x97, + 0x9e, 0x1a, 0xcf, 0x30, 0x1e, 0x0a, 0x88, 0x45, 0x86, 0x29, 0x30, 0xa3, 0x4d, 0x9f, 0x61, 0x65, + 0x73, 0xe0, 0xd6, 0x87, 0x8f, 0xb6, 0xf3, 0x06, 0xa3, 0x82, 0xdc, 0x7c, 0xac, 0xfe, 0x9b, 0x28, + 0x9a, 0xae, 0xfd, 0xfb, 0xfe, 0x2f, 0x0e, 0xd8, 0x97, 0x04, 0xe3, 0xbb, 0x1f, 0xd1, 0xec, 0x0d, + 0xba, 0xa3, 0x49, 0x7f, 0x47, 0xac, 0x8a, 0x44, 0x04, 0x7e, 0x86, 0xb7, 0x39, 0x42, 0x3f, 0xad, + 0x1e, 0xb7, 0x0e, 0xa5, 0x51, 0xf4, 0x40, 0x63, 0x1e, 0xfd, 0xbd, 0xea, 0x9f, 0x41, 0x9f, 0xa8, + 0x90, 0x1d, 0x6f, 0x0a, 0x5a, 0x95, 0x13, 0x11, 0x0d, 0x80, 0xaf, 0x5f, 0x64, 0x98, 0x8a, 0x2c, + 0x78, 0x68, 0x65, 0xb0, 0x2b, 0x8b, 0xa2, 0x53, 0x87, 0xca, 0xf1, 0x64, 0x04, 0xab, 0xf2, 0x7b, + 0xdb, 0x83, 0xc8, 0x81, 0x02, 0x41, 0x00, 0xf7, 0xbe, 0x5e, 0x23, 0xc3, 0x32, 0x3f, 0xbf, 0x8b, + 0x8e, 0x3a, 0xee, 0xfc, 0xfc, 0xcb, 0xe5, 0xf7, 0xf1, 0x0b, 0xbc, 0x42, 0x82, 0xae, 0xd5, 0x7a, + 0x3e, 0xca, 0xf7, 0xd5, 0x69, 0x3f, 0x64, 0x25, 0xa2, 0x1f, 0xb7, 0x75, 0x75, 0x05, 0x92, 0x42, + 0xeb, 0xb8, 0xf1, 0xf3, 0x0a, 0x05, 0xe3, 0x94, 0xd1, 0x55, 0x78, 0x35, 0xa0, 0x36, 0xa0, 0x9b, + 0x7c, 0x92, 0x84, 0x6c, 0xdd, 0xdc, 0x4d, 0x02, 0x41, 0x00, 0xd6, 0x86, 0x0e, 0x85, 0x42, 0x0b, + 0x04, 0x08, 0x84, 0x21, 0x60, 0xf0, 0x0e, 0x0d, 0x88, 0xfd, 0x1e, 0x36, 0x10, 0x65, 0x4f, 0x1e, + 0x53, 0xb4, 0x08, 0x72, 0x80, 0x5c, 0x3f, 0x59, 0x66, 0x17, 0xe6, 0x98, 0xf2, 0xe9, 0x6c, 0x7a, + 0x06, 0x4c, 0xac, 0x76, 0x3d, 0xed, 0x8c, 0xa1, 0xce, 0xad, 0x1b, 0xbd, 0xb4, 0x7d, 0x28, 0xbc, + 0xe3, 0x0e, 0x38, 0x8d, 0x99, 0xd8, 0x05, 0xb5, 0xa3, 0x71, 0x02, 0x40, 0x6d, 0xeb, 0xc3, 0x2d, + 0x2e, 0xf0, 0x5e, 0xa4, 0x88, 0x31, 0x05, 0x29, 0x00, 0x8a, 0xd1, 0x95, 0x29, 0x9b, 0x83, 0xcf, + 0x75, 0xdb, 0x31, 0xe3, 0x7a, 0x27, 0xde, 0x3a, 0x74, 0x30, 0x0c, 0x76, 0x4c, 0xd4, 0x50, 0x2a, + 0x40, 0x2d, 0x39, 0xd9, 0x99, 0x63, 0xa9, 0x5d, 0x80, 0xae, 0x53, 0xca, 0x94, 0x3f, 0x05, 0x23, + 0x1e, 0xf8, 0x05, 0x04, 0xe1, 0xb8, 0x35, 0xf2, 0x17, 0xb3, 0xa0, 0x89, 0x02, 0x41, 0x00, 0xab, + 0x90, 0x88, 0xfa, 0x60, 0x08, 0x29, 0x50, 0x9a, 0x43, 0x8b, 0xa0, 0x50, 0xcc, 0xd8, 0x5a, 0xfe, + 0x97, 0x64, 0x63, 0x71, 0x74, 0x22, 0xa3, 0x20, 0x02, 0x5a, 0xcf, 0xeb, 0xc6, 0x16, 0x95, 0x54, + 0xd1, 0xcb, 0xab, 0x8d, 0x1a, 0xc6, 0x00, 0xfa, 0x08, 0x92, 0x9c, 0x71, 0xd5, 0x52, 0x52, 0x35, + 0x96, 0x71, 0x4b, 0x8b, 0x92, 0x0c, 0xd0, 0xe9, 0xbf, 0xad, 0x63, 0x0b, 0xa5, 0xe9, 0xb1, 0x02, + 0x41, 0x00, 0xdc, 0xcc, 0x27, 0xc8, 0xe4, 0xdc, 0x62, 0x48, 0xd5, 0x9b, 0xaf, 0xf5, 0xab, 0x60, + 0xf6, 0x21, 0xfd, 0x53, 0xe2, 0xb7, 0x5d, 0x09, 0xc9, 0x1a, 0xa1, 0x04, 0xa9, 0xfc, 0x61, 0x2c, + 0x5d, 0x04, 0x58, 0x3a, 0x5a, 0x39, 0xf1, 0x4a, 0x21, 0x56, 0x67, 0xfd, 0xcc, 0x20, 0xa3, 0x8f, + 0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e, 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17, + 0x4a, 0x9f, }; + + +/*** NOTE: OpenSSL seems to have more to their public key format. I've stripped the extra headers... */ +static const unsigned char openssl_public_rsa[] = { + 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, + 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, + 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, + 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, + 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, + 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, + 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, + 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, + 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, + 0x00, 0x01, }; + +static int rsa_compat_test(void) +{ + rsa_key key; + unsigned char buf[1024]; + unsigned long len; + + /* try reading the key */ + DO(rsa_import(openssl_private_rsa, sizeof(openssl_private_rsa), &key)); + + /* now try to export private/public and compare */ + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PRIVATE, &key)); + if (len != sizeof(openssl_private_rsa) || memcmp(buf, openssl_private_rsa, len)) { + fprintf(stderr, "RSA private export failed to match OpenSSL output, %lu, %lu\n", len, sizeof(openssl_private_rsa)); + + +{ +int x; +printf("\n\n"); +for (x = 0; x < len; ) { if (buf[x] == openssl_private_rsa[x]) printf("-- "); else printf("%02x ", buf[x]^openssl_private_rsa[x]); if (!(++x & 15)) printf("\n"); } +} +printf("\n\n"); + + return 1; + } + + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PUBLIC, &key)); + if (len != sizeof(openssl_public_rsa) || memcmp(buf, openssl_public_rsa, len)) { + fprintf(stderr, "RSA(private) public export failed to match OpenSSL output\n"); + return 1; + } + rsa_free(&key); + + /* try reading the public key */ + DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); + len = sizeof(buf); + DO(rsa_export(buf, &len, PK_PUBLIC, &key)); + if (len != sizeof(openssl_public_rsa) || memcmp(buf, openssl_public_rsa, len)) { + fprintf(stderr, "RSA(public) public export failed to match OpenSSL output\n"); + return 1; + } + rsa_free(&key); + + return 0; +} + int rsa_test(void) { unsigned char in[1024], out[1024], tmp[1024]; rsa_key key, privKey, pubKey; - int hash_idx, prng_idx, stat, stat2, cnt; - unsigned long rsa_msgsize, len, len2; + int hash_idx, prng_idx, stat, stat2; + unsigned long rsa_msgsize, len, len2, cnt; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; + + if (rsa_compat_test() != 0) { + return 1; + } hash_idx = find_hash("sha1"); prng_idx = find_prng("yarrow"); if (hash_idx == -1 || prng_idx == -1) { - printf("rsa_test requires SHA1 and yarrow"); + fprintf(stderr, "rsa_test requires SHA1 and yarrow"); return 1; } @@ -23,32 +130,32 @@ int rsa_test(void) for (cnt = 0; cnt < 10; cnt++) { DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key)); if (mp_count_bits(&key.N) != 1024) { - printf("rsa_1024 key modulus has %d bits\n", mp_count_bits(&key.N)); + fprintf(stderr, "rsa_1024 key modulus has %d bits\n", mp_count_bits(&key.N)); len = mp_unsigned_bin_size(&key.N); mp_to_unsigned_bin(&key.N, tmp); -printf("N == \n"); + fprintf(stderr, "N == \n"); for (cnt = 0; cnt < len; ) { - printf("%02x ", tmp[cnt]); - if (!(++cnt & 15)) printf("\n"); + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(&key.p); mp_to_unsigned_bin(&key.p, tmp); -printf("p == \n"); + fprintf(stderr, "p == \n"); for (cnt = 0; cnt < len; ) { - printf("%02x ", tmp[cnt]); - if (!(++cnt & 15)) printf("\n"); + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(&key.q); mp_to_unsigned_bin(&key.q, tmp); -printf("\nq == \n"); + fprintf(stderr, "\nq == \n"); for (cnt = 0; cnt < len; ) { - printf("%02x ", tmp[cnt]); - if (!(++cnt & 15)) printf("\n"); + fprintf(stderr, "%02x ", tmp[cnt]); + if (!(++cnt & 15)) fprintf(stderr, "\n"); } -printf("\n"); + fprintf(stderr, "\n"); return 1; @@ -57,38 +164,7 @@ printf("\n"); rsa_free(&key); } } - - /* test PKCS #1 v1.5 */ - for (cnt = 0; cnt < 4; cnt++) { - for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) { - /* make a random key/msg */ - yarrow_read(in, rsa_msgsize, &yarrow_prng); - - len = sizeof(out); - len2 = rsa_msgsize; - - /* encrypt */ - DO(rsa_v15_encrypt_key(in, rsa_msgsize, out, &len, &yarrow_prng, prng_idx, &key)); - DO(rsa_v15_decrypt_key(out, len, tmp, rsa_msgsize, &stat, &key)); - if (stat != 1 || memcmp(tmp, in, rsa_msgsize)) { - printf("PKCS #1 v1.5 encrypt/decrypt failure (rsa_msgsize: %lu, stat: %d)\n", rsa_msgsize, stat); - return 1; - } - } - } - - /* signature */ - len = sizeof(out); - DO(rsa_v15_sign_hash(in, 20, out, &len, hash_idx, &key)); - in[1] ^= 1; - DO(rsa_v15_verify_hash(out, len, in, 20, hash_idx, &stat, &key)); - in[1] ^= 1; - DO(rsa_v15_verify_hash(out, len, in, 20, hash_idx, &stat2, &key)); - if (!(stat == 0 && stat2 == 1)) { - printf("PKCS #1 v1.5 sign/verify failure (stat %d, stat2 %d)\n", stat, stat2); - return 1; - } - + /* encrypt the key (without lparam) */ for (cnt = 0; cnt < 4; cnt++) { for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { @@ -105,35 +181,35 @@ printf("\n"); /* change a byte back */ out[8] ^= 1; if (len2 != rsa_msgsize) { - printf("\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); + fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } len2 = rsa_msgsize; DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_decrypt_key failed"); + fprintf(stderr, "rsa_decrypt_key failed"); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { unsigned long x; - printf("\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2); - printf("Original contents: \n"); + fprintf(stderr, "\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2); + fprintf(stderr, "Original contents: \n"); for (x = 0; x < rsa_msgsize; ) { - printf("%02x ", in[x]); + fprintf(stderr, "%02x ", in[x]); if (!(++x % 16)) { - printf("\n"); + fprintf(stderr, "\n"); } } - printf("\n"); - printf("Output contents: \n"); + fprintf(stderr, "\n"); + fprintf(stderr, "Output contents: \n"); for (x = 0; x < rsa_msgsize; ) { - printf("%02x ", out[x]); + fprintf(stderr, "%02x ", out[x]); if (!(++x % 16)) { - printf("\n"); + fprintf(stderr, "\n"); } } - printf("\n"); + fprintf(stderr, "\n"); return 1; } } @@ -148,7 +224,7 @@ printf("\n"); out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); if (len2 != rsa_msgsize) { - printf("\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); + fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } /* change a byte back */ @@ -157,11 +233,11 @@ printf("\n"); len2 = rsa_msgsize; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_decrypt_key failed"); + fprintf(stderr, "rsa_decrypt_key failed"); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { - printf("rsa_decrypt_key mismatch len %lu", len2); + fprintf(stderr, "rsa_decrypt_key mismatch len %lu", len2); return 1; } } @@ -185,7 +261,7 @@ printf("\n"); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); + fprintf(stderr, "rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); @@ -201,7 +277,7 @@ printf("\n"); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); + fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); @@ -217,7 +293,7 @@ printf("\n"); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); + fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); @@ -233,7 +309,7 @@ printf("\n"); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { - printf("rsa_verify_hash (salted) failed, %d, %d", stat, stat2); + fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); @@ -251,8 +327,12 @@ printf("\n"); int rsa_test(void) { - printf("NOP"); + fprintf(stderr, "NOP"); return 0; } #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/store_test.c b/testprof/store_test.c index 41b2f92..71666ba 100644 --- a/testprof/store_test.c +++ b/testprof/store_test.c @@ -3,13 +3,17 @@ /* Test store/load macros with offsets */ int store_test(void) { - unsigned char buf[24]; + unsigned char buf[256]; int y; ulong32 L, L1; ulong64 LL, LL1; +#ifdef LTC_FAST + int x, z; +#endif - L = 0x12345678UL; for (y = 0; y < 4; y++) { + L = 0x12345678UL; + L1 = 0; STORE32L(L, buf + y); LOAD32L(L1, buf + y); if (L1 != L) { @@ -24,8 +28,9 @@ int store_test(void) } } - LL = CONST64 (0x01020304050607); for (y = 0; y < 8; y++) { + LL = CONST64 (0x01020304050607); + LL1 = 0; STORE64L(LL, buf + y); LOAD64L(LL1, buf + y); if (LL1 != LL) { @@ -40,5 +45,34 @@ int store_test(void) } } +/* test LTC_FAST */ +#ifdef LTC_FAST + y = 16; + + for (z = 0; z < y; z++) { + /* fill y bytes with random */ + yarrow_read(buf+z, y, &yarrow_prng); + yarrow_read(buf+z+y, y, &yarrow_prng); + + /* now XOR it byte for byte */ + for (x = 0; x < y; x++) { + buf[2*y+z+x] = buf[z+x] ^ buf[z+y+x]; + } + + /* now XOR it word for word */ + for (x = 0; x < y; x += sizeof(LTC_FAST_TYPE)) { + *((LTC_FAST_TYPE*)(&buf[3*y+z+x])) = *((LTC_FAST_TYPE*)(&buf[z+x])) ^ *((LTC_FAST_TYPE*)(&buf[z+y+x])); + } + + if (memcmp(&buf[2*y+z], &buf[3*y+z], y)) { + fprintf(stderr, "\nLTC_FAST failed at offset %d\n", z); + return 1; + } + } +#endif return 0; } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/test.c b/testprof/test.c index 9f6df71..721a992 100644 --- a/testprof/test.c +++ b/testprof/test.c @@ -7,3 +7,7 @@ void run_cmd(int res, int line, char *file, char *cmd) exit(EXIT_FAILURE); } } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/test.key b/testprof/test.key new file mode 100644 index 0000000..e4996c3 --- /dev/null +++ b/testprof/test.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97bfYUtlmXl +P3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7kEY5BaHxh +E9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE/QIDAQAB +AoGBAMhiuereRFMdVpfZl54azzAeCohFhikwo02fYWVz4NaHj7bzBqOC3Hys/pso +mq79+/4vDtiXBOO7H9HsDbqjSX9HrIpEBH6GtzlCP60etw6lUfRAYx79veqfQZ+o +kB1vClqVExENgK9fZJiKLHhoZbAri6JTh8rxZASr8nvbg8iBAkEA975eI8MyP7+L +jjru/PzL5ffxC7xCgq7Vej7K99VpP2Qloh+3dXUFkkLruPHzCgXjlNFVeDWgNqCb +fJKEbN3cTQJBANaGDoVCCwQIhCFg8A4NiP0eNhBlTx5TtAhygFw/WWYX5pjy6Wx6 +Bkysdj3tjKHOrRu9tH0ovOMOOI2Z2AW1o3ECQG3rwy0u8F6kiDEFKQCK0ZUpm4PP +ddsx43on3jp0MAx2TNRQKkAtOdmZY6ldgK5TypQ/BSMe+AUE4bg18hezoIkCQQCr +kIj6YAgpUJpDi6BQzNha/pdkY3F0IqMgAlrP68YWlVTRy6uNGsYA+giSnHHVUlI1 +lnFLi5IM0Om/rWMLpemxAkEA3MwnyOTcYkjVm6/1q2D2If1T4rddCckaoQSp/GEs +XQRYOlo58UohVmf9zCCjj3gYWnk9Lo5+hgrmqDPBBBdKnw== +-----END RSA PRIVATE KEY----- diff --git a/testprof/tomcrypt_test.h b/testprof/tomcrypt_test.h index fc28430..6503b7c 100644 --- a/testprof/tomcrypt_test.h +++ b/testprof/tomcrypt_test.h @@ -71,3 +71,7 @@ void time_encmacs(void); #endif + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */ diff --git a/testprof/x86_prof.c b/testprof/x86_prof.c index bcc25f4..7fbe8e1 100644 --- a/testprof/x86_prof.c +++ b/testprof/x86_prof.c @@ -21,10 +21,10 @@ void tally_results(int type) // qsort the results qsort(results, no_results, sizeof(struct list), &sorter); - printf("\n"); + fprintf(stderr, "\n"); if (type == 0) { for (x = 0; x < no_results; x++) { - printf("%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1); + fprintf(stderr, "%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1); } } else if (type == 1) { for (x = 0; x < no_results; x++) { @@ -42,7 +42,7 @@ void tally_results(int type) /* RDTSC from Scott Duplichan */ ulong64 rdtsc (void) { - #if defined __GNUC__ + #if defined __GNUC__ && !defined(LTC_NO_ASM) #ifdef INTEL_CC ulong64 a; asm ( " rdtsc ":"=A"(a)); @@ -62,11 +62,11 @@ ulong64 rdtsc (void) #endif // Microsoft and Intel Windows compilers - #elif defined _M_IX86 + #elif defined _M_IX86 && !defined(LTC_NO_ASM) __asm rdtsc - #elif defined _M_AMD64 + #elif defined _M_AMD64 && !defined(LTC_NO_ASM) return __rdtsc (); - #elif defined _M_IA64 + #elif defined _M_IA64 && !defined(LTC_NO_ASM) #if defined __INTEL_COMPILER #include #endif @@ -104,7 +104,7 @@ void init_timer(void) c2 = (t2 > c2) ? t2 : c2; } skew = c2 - c1; - printf("Clock Skew: %lu\n", (unsigned long)skew); + fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew); } void reg_algs(void) @@ -199,7 +199,7 @@ void reg_algs(void) #ifdef CHC_HASH register_hash(&chc_desc); if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { - printf("chc_register error: %s\n", error_to_string(err)); + fprintf(stderr, "chc_register error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } #endif @@ -231,7 +231,7 @@ int time_keysched(void) int (*func) (const unsigned char *, int , int , symmetric_key *); unsigned char key[MAXBLOCKSIZE]; - printf ("\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n"); + fprintf(stderr, "\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { #define DO1(k) func(k, kl, 0, &skey); @@ -249,7 +249,7 @@ int time_keysched(void) t1 = c1 - skew; results[no_results].spd1 = results[no_results].avg = t1; results[no_results++].id = x; - printf("."); fflush(stdout); + fprintf(stderr, "."); fflush(stdout); #undef DO1 } @@ -266,7 +266,7 @@ int time_cipher(void) unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; - printf ("\n\nECB Time Trials for the Symmetric Ciphers:\n"); + fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb); @@ -318,7 +318,7 @@ int time_cipher(void) results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; - printf("."); fflush(stdout); + fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 @@ -337,7 +337,7 @@ int time_cipher2(void) unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; - printf ("\n\nCBC Time Trials for the Symmetric Ciphers:\n"); + fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc); @@ -389,7 +389,7 @@ int time_cipher2(void) results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; - printf("."); fflush(stdout); + fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 @@ -399,7 +399,7 @@ int time_cipher2(void) return 0; } #else -int time_cipher2(void) { printf("NO CBC\n"); return 0; } +int time_cipher2(void) { fprintf(stderr, "NO CBC\n"); return 0; } #endif #ifdef CTR @@ -411,10 +411,10 @@ int time_cipher3(void) unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; - printf ("\n\nCTR Time Trials for the Symmetric Ciphers:\n"); + fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { - ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &ctr); + ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr); /* sanity check on cipher */ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { @@ -463,7 +463,7 @@ int time_cipher3(void) results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; - printf("."); fflush(stdout); + fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 @@ -473,7 +473,7 @@ int time_cipher3(void) return 0; } #else -int time_cipher3(void) { printf("NO CTR\n"); return 0; } +int time_cipher3(void) { fprintf(stderr, "NO CTR\n"); return 0; } #endif int time_hash(void) @@ -485,7 +485,7 @@ int time_hash(void) unsigned char pt[MAXBLOCKSIZE]; - printf ("\n\nHASH Time Trials for:\n"); + fprintf(stderr, "\n\nHASH Time Trials for:\n"); no_results = 0; for (x = 0; hash_descriptor[x].name != NULL; x++) { @@ -518,7 +518,7 @@ int time_hash(void) results[no_results].id = x; results[no_results].spd1 = results[no_results].avg = t1; ++no_results; - printf("."); fflush(stdout); + fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 } @@ -534,7 +534,7 @@ void time_mult(void) unsigned long x, y; mp_int a, b, c; - printf("Timing Multiplying:\n"); + fprintf(stderr, "Timing Multiplying:\n"); mp_init_multi(&a,&b,&c,NULL); for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) { mp_rand(&a, x); @@ -551,7 +551,7 @@ void time_mult(void) t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } - printf("%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); + fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); } mp_clear_multi(&a,&b,&c,NULL); @@ -565,7 +565,7 @@ void time_sqr(void) unsigned long x, y; mp_int a, b; - printf("Timing Squaring:\n"); + fprintf(stderr, "Timing Squaring:\n"); mp_init_multi(&a,&b,NULL); for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) { mp_rand(&a, x); @@ -581,7 +581,7 @@ void time_sqr(void) t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } - printf("%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); + fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); } mp_clear_multi(&a,&b,NULL); @@ -589,8 +589,8 @@ void time_sqr(void) #undef DO2 } #else -void time_mult(void) { printf("NO MULT\n"); } -void time_sqr(void) { printf("NO SQR\n"); } +void time_mult(void) { fprintf(stderr, "NO MULT\n"); } +void time_sqr(void) { fprintf(stderr, "NO SQR\n"); } #endif void time_prng(void) @@ -601,7 +601,7 @@ void time_prng(void) unsigned long x, y; int err; - printf("Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n"); + fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n"); for (x = 0; prng_descriptor[x].name != NULL; x++) { /* sanity check on prng */ @@ -616,7 +616,7 @@ void time_prng(void) prng_descriptor[x].ready(&tprng); t2 = -1; -#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { printf("\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); } +#define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { fprintf(stderr, "\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); } #define DO2 DO1 DO1 for (y = 0; y < 10000; y++) { t_start(); @@ -625,7 +625,7 @@ void time_prng(void) t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } - printf("%20s: %5llu ", prng_descriptor[x].name, t2>>12); + fprintf(stderr, "%20s: %5llu ", prng_descriptor[x].name, t2>>12); #undef DO2 #undef DO1 @@ -638,7 +638,7 @@ void time_prng(void) t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } - printf("%5llu\n", t2); + fprintf(stderr, "%5llu\n", t2); #undef DO2 #undef DO1 @@ -672,7 +672,7 @@ void time_rsa(void) } } t2 >>= 4; - printf("RSA-%lu make_key took %15llu cycles\n", x, t2); + fprintf(stderr, "RSA-%lu make_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 16; y++) { @@ -689,7 +689,7 @@ void time_rsa(void) t2 += t1; } t2 >>= 4; - printf("RSA-%lu encrypt_key took %15llu cycles\n", x, t2); + fprintf(stderr, "RSA-%lu encrypt_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 16; y++) { @@ -705,14 +705,14 @@ void time_rsa(void) t2 += t1; } t2 >>= 4; - printf("RSA-%lu decrypt_key took %15llu cycles\n", x, t2); + fprintf(stderr, "RSA-%lu decrypt_key took %15llu cycles\n", x, t2); rsa_free(&key); } } #else -void time_rsa(void) { printf("NO RSA\n"); } +void time_rsa(void) { fprintf(stderr, "NO RSA\n"); } #endif #ifdef MECC @@ -743,7 +743,7 @@ void time_ecc(void) } } t2 >>= 4; - printf("ECC-%lu make_key took %15llu cycles\n", x*8, t2); + fprintf(stderr, "ECC-%lu make_key took %15llu cycles\n", x*8, t2); t2 = 0; for (y = 0; y < 16; y++) { @@ -759,12 +759,12 @@ void time_ecc(void) t2 += t1; } t2 >>= 4; - printf("ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2); + fprintf(stderr, "ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2); ecc_free(&key); } } #else -void time_ecc(void) { printf("NO ECC\n"); } +void time_ecc(void) { fprintf(stderr, "NO ECC\n"); } #endif #ifdef MDH @@ -795,7 +795,7 @@ void time_dh(void) } } t2 >>= 4; - printf("DH-%4lu make_key took %15llu cycles\n", x*8, t2); + fprintf(stderr, "DH-%4lu make_key took %15llu cycles\n", x*8, t2); t2 = 0; for (y = 0; y < 16; y++) { @@ -811,12 +811,12 @@ void time_dh(void) t2 += t1; } t2 >>= 4; - printf("DH-%4lu encrypt_key took %15llu cycles\n", x*8, t2); + fprintf(stderr, "DH-%4lu encrypt_key took %15llu cycles\n", x*8, t2); dh_free(&key); } } #else -void time_dh(void) { printf("NO DH\n"); } +void time_dh(void) { fprintf(stderr, "NO DH\n"); } #endif void time_macs_(unsigned long MAC_SIZE) @@ -826,7 +826,7 @@ void time_macs_(unsigned long MAC_SIZE) unsigned long x, z; int err, cipher_idx, hash_idx; - printf("\nMAC Timings (cycles/byte on %dKB blocks):\n", MAC_SIZE); + fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); buf = XMALLOC(MAC_SIZE*1024); if (buf == NULL) { @@ -853,7 +853,7 @@ void time_macs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("OMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "OMAC-AES\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef PMAC @@ -869,7 +869,7 @@ void time_macs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("PMAC-AES\t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "PMAC-AES\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef PELICAN @@ -885,7 +885,7 @@ void time_macs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("PELICAN \t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "PELICAN \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef HMAC @@ -901,7 +901,7 @@ void time_macs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("HMAC-MD5\t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "HMAC-MD5\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif XFREE(buf); @@ -921,7 +921,7 @@ void time_encmacs_(unsigned long MAC_SIZE) unsigned long x, z; int err, cipher_idx; - printf("\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %dKB blocks):\n", MAC_SIZE); + fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); buf = XMALLOC(MAC_SIZE*1024); if (buf == NULL) { @@ -948,7 +948,7 @@ void time_encmacs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("EAX \t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "EAX \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef OCB_MODE @@ -964,7 +964,7 @@ void time_encmacs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("OCB \t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "OCB \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef CCM_MODE @@ -980,7 +980,7 @@ void time_encmacs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("CCM \t\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "CCM \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef GCM_MODE @@ -996,12 +996,12 @@ void time_encmacs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("GCM (no-precomp)\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "GCM (no-precomp)\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); { gcm_state gcm; - if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { printf("gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } + if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t2 = -1; for (x = 0; x < 10000; x++) { t_start(); @@ -1031,7 +1031,7 @@ void time_encmacs_(unsigned long MAC_SIZE) t1 = t_read() - t1; if (t1 < t2) t2 = t1; } - printf("GCM (precomp)\t%9llu\n", t2/(MAC_SIZE*1024)); + fprintf(stderr, "GCM (precomp)\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); } #endif @@ -1044,3 +1044,7 @@ void time_encmacs(void) time_encmacs_(4); time_encmacs_(32); } + +/* $Source$ */ +/* $Revision$ */ +/* $Date$ */