added libtomcrypt-1.07
This commit is contained in:
		
							parent
							
								
									72412f6dac
								
							
						
					
					
						commit
						4a1a5796de
					
				
							
								
								
									
										2
									
								
								Doxyfile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								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.06 | ||||
| PROJECT_NUMBER         = 1.07 | ||||
| 
 | ||||
| # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)  | ||||
| # base path where the generated documentation will be put.  | ||||
|  | ||||
							
								
								
									
										37
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								TODO
									
									
									
									
									
								
							| @ -1,6 +1,43 @@ | ||||
| For 1.07 | ||||
| 
 | ||||
|                  | ||||
| 1. [3 hours]    ASN.1 SET and T61String [punishment, add UTF8 to the list!] | ||||
| 
 | ||||
| 4. [short]      Make parameters in descriptors common, e.g. cipher.block_length => cipher.block_size, hash.blocksize => hash.block_size | ||||
| 
 | ||||
| DONE | ||||
| ---- | ||||
| 
 | ||||
| 0. [important]  Make ciphers enc/dec routines return int [for accel].  Make the ciphers themselves return CRYPT_OK [default] *AND* make | ||||
|                 all dependent code check the returns  | ||||
|                 [x] gcm | ||||
|                 [x] ccm | ||||
|                 [x] yarrow | ||||
|                 [x] fortuna | ||||
|                 [x] eax | ||||
|                 [x] ocb | ||||
|                 [x] omac | ||||
|                 [x] pmac | ||||
|                 [x] pelican | ||||
|                 [x] ctr | ||||
|                 [x] cbc | ||||
|                 [x] ecb | ||||
|                 [x] cfb | ||||
|                 [x] ofb | ||||
| 
 | ||||
| 2. [many]       ASN.1 flexidecoder.  Basically decode and construct a list of decoded ASN.1 types on the fly. | ||||
|                 This will allow easy decoding of things like X.509 as their orders can be "screwed up". | ||||
|                 The concept is simple, just read the ID byte and use a linked list.  I'll do this after step #1. | ||||
| 
 | ||||
| 3. [short]      Make the cipher/hash accelerators return int [not void] to signal errors.  Whoops | ||||
| 
 | ||||
| 5. [short]      Swap arguments of MGF1 around so hash_idx is first | ||||
| 
 | ||||
| 6. [longish]    Re-write parts of the ECC api, re-factor the code, convert to w-NAF, add FP support, add ecc point verifier | ||||
| 
 | ||||
| 7. [shortish]   Provide DH for the DSA code e.g. dsa_encrypt_key() | ||||
| 
 | ||||
| 8. [worthit]    Move the ECC code for point mul and what not as symbols that the TFM/LTM descriptors link in.  Means a change to the hierarchy.  This allows | ||||
|                 code that uses ECC plugins to simply ignore this code [e.g. save space] | ||||
| 
 | ||||
| 9. [short]      Document the flexi decoder and how it relates to the other DER routines | ||||
|  | ||||
							
								
								
									
										49
									
								
								changes
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								changes
									
									
									
									
									
								
							| @ -1,3 +1,44 @@ | ||||
| November 18th, 2005 | ||||
| v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly.  That's because as of a few releases ago | ||||
|          I added support to set the mode of the counter at init time | ||||
|       -- Fixed some "testprof" make issues | ||||
|       -- Added RSA keygen to the math descriptors | ||||
|       -- Fixed install_test target ... oops | ||||
|       -- made the "ranlib" program renamable useful for cross-compiling | ||||
|       -- Made the cipher accelerators return error codes.  :-) | ||||
|       -- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets | ||||
|       -- Added "Katja" public key crypto.  It's based on the recent N = p^2q work by Katja.  I added OAEP padding | ||||
|          to it.  Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly | ||||
|          analyzed.   It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also | ||||
|          some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible. | ||||
|       -- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya  :-) | ||||
|       -- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER | ||||
|       -- Cleaned up the LIBTEST_S definitions in both GNU makefiles.  A few minor touchups as well. | ||||
|       -- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this.   | ||||
|       -- der_decode_choice() would fail to mark a NULL as "used" when decoding.  Fixed | ||||
|       -- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-) | ||||
|       -- Added mp_neg() to the math descriptors. | ||||
|       -- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent) | ||||
|       -- Made the math descriptors buildable when RSA has been undefined | ||||
|       -- ECC timing demo now capable of detecting which curves have been defined | ||||
|       -- Refactored the ECC code so it's easier to maintain.  (note: the form of this code hasn't really changed since I first added ECC ... :-/) | ||||
|       -- Updated the documentation w.r.t. ECC and the accelerators to keep it current | ||||
|       -- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error. | ||||
|       -- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes) | ||||
|       -- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters) | ||||
|       -- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead! | ||||
|       -- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used) | ||||
|       -- ECC code now ALWAYS uses the accelerator interface.  This allows people who use the accelerators to not have the stock | ||||
|          ECC point add/dbl/mul code linked in.  Yeah space savings! Rah Rah Rah. | ||||
|       -- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at | ||||
|          build time (e.g. LTC_PTHREAD == pthreads) | ||||
|       -- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock) | ||||
|       -- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-) | ||||
|       -- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that] | ||||
|       -- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD] | ||||
|       -- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing | ||||
|          their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask) | ||||
| 
 | ||||
| August 1st, 2005 | ||||
| v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson] | ||||
|       -- Added fourth ARGCHK type which outputs to stderr and continues.  Useful if you trap sigsegv.   [Valient Gough] | ||||
| @ -234,7 +275,7 @@ October 29th, 2004 | ||||
| v0.99  -- Merged in the latest version of LTM which includes all of the recent bug fixes | ||||
|        -- Deprecated LTMSSE and removed it (to be replaced with TFM later on) | ||||
|        -- Stefan Arentz pointed out that mp_s_rmap should be extern | ||||
|        -- Kristian Gjøsteen pointed out that there are typos in the  | ||||
|        -- Kristian Gj?steen pointed out that there are typos in the  | ||||
|           "test" makefile and minor issues in Yarrow and Sober [just cosmetics really] | ||||
|        -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword  | ||||
|           so changed the PRNG api to use "pexport" and "pimport" | ||||
| @ -613,7 +654,7 @@ v0.81  -- Merged in new makefile from Clay Culver and Mike Frysinger | ||||
|           as much as possible.  This sped the routine up quite a bit. | ||||
|        -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed. | ||||
|        -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format | ||||
|           (fix due to Mika Boström) | ||||
|           (fix due to Mika Bostr?m) | ||||
|        -- Merged in LibTomMath for kicks | ||||
|        -- Changed the build process so that by default "mycrypt_custom.h" is included and provided | ||||
|           The makefile doesn't include any build options anymore | ||||
| @ -1342,6 +1383,6 @@ v0.02  -- Changed RC5 to only allow 12 to 24 rounds | ||||
| v0.01  -- We will call this the first version. | ||||
| 
 | ||||
| /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ | ||||
| /* $Revision: 1.123 $ */ | ||||
| /* $Date: 2005/08/01 16:50:34 $ */ | ||||
| /* $Revision: 1.151 $ */ | ||||
| /* $Date: 2005/11/17 22:04:00 $ */ | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										293
									
								
								crypt.tex
									
									
									
									
									
								
							
							
						
						
									
										293
									
								
								crypt.tex
									
									
									
									
									
								
							| @ -47,7 +47,7 @@ | ||||
| \def\gap{\vspace{0.5ex}} | ||||
| \makeindex | ||||
| \begin{document} | ||||
| \title{LibTomCrypt \\ Version 1.06} | ||||
| \title{LibTomCrypt \\ Version 1.07} | ||||
| \author{Tom St Denis \\ | ||||
| \\ | ||||
| tomstdenis@gmail.com \\ | ||||
| @ -236,8 +236,7 @@ int main(void) { | ||||
| } | ||||
| \end{verbatim} | ||||
| 
 | ||||
| The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and  | ||||
| ``ltc\_tommath.h'' (the bignum library routines). | ||||
| The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'' and ``ctype.h''. | ||||
| 
 | ||||
| \section{Macros} | ||||
| 
 | ||||
| @ -363,16 +362,17 @@ done with a key you can simply discard it (e.g. they can be on the stack). | ||||
| To encrypt or decrypt a block in ECB mode there are these two function classes | ||||
| \index{Cipher Encrypt} \index{Cipher Decrypt} | ||||
| \begin{verbatim} | ||||
| void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct, | ||||
| int XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct, | ||||
|                      symmetric_key *skey); | ||||
| 
 | ||||
| void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt, | ||||
| int XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt, | ||||
|                      symmetric_key *skey); | ||||
| \end{verbatim} | ||||
| These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on | ||||
| which cipher you are using.} and store the result where you want it.  It is possible that the input and output buffer are  | ||||
| the same buffer.  For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and  | ||||
| ``ct''\footnote{ct stands for ciphertext.} is the output.  For the decryption function it's the opposite.  To test a particular  | ||||
| ``ct''\footnote{ct stands for ciphertext.} is the output.  For the decryption function it's the opposite.  They both | ||||
| return \textbf{CRYPT\_OK} on success.  To test a particular  | ||||
| cipher against test vectors\footnote{As published in their design papers.} call the self-test function | ||||
|   | ||||
| \subsection{Self--Testing} | ||||
| @ -496,39 +496,47 @@ struct _cipher_descriptor { | ||||
|         block_length,  | ||||
|         default_rounds; | ||||
|    int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
|    void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
|    void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
|    int  (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
|    int  (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
|    int  (*test)(void); | ||||
|    void (*done)(symmetric_key *skey);       | ||||
|    int  (*keysize)(int *keysize); | ||||
| 
 | ||||
|    void (*accel_ecb_encrypt)(const unsigned char *pt,  | ||||
|    int (*accel_ecb_encrypt)(const unsigned char *pt,  | ||||
|                                    unsigned char *ct,  | ||||
|                                    unsigned long blocks, symmetric_key *skey); | ||||
|    void (*accel_ecb_decrypt)(const unsigned char *ct,  | ||||
|    int (*accel_ecb_decrypt)(const unsigned char *ct,  | ||||
|                                    unsigned char *pt,  | ||||
|                                    unsigned long blocks, symmetric_key *skey); | ||||
|    void (*accel_cbc_encrypt)(const unsigned char *pt,  | ||||
|    int (*accel_cbc_encrypt)(const unsigned char *pt,  | ||||
|                                    unsigned char *ct,  | ||||
|                                    unsigned long blocks, unsigned char *IV,  | ||||
|                                    symmetric_key *skey); | ||||
|    void (*accel_cbc_decrypt)(const unsigned char *ct,  | ||||
|    int (*accel_cbc_decrypt)(const unsigned char *ct,  | ||||
|                                    unsigned char *pt,  | ||||
|                                    unsigned long blocks, unsigned char *IV,  | ||||
|                                    symmetric_key *skey); | ||||
|    void (*accel_ctr_encrypt)(const unsigned char *pt,  | ||||
|    int (*accel_ctr_encrypt)(const unsigned char *pt,  | ||||
|                                    unsigned char *ct,  | ||||
|                                    unsigned long blocks, unsigned char *IV,  | ||||
|                                    int mode, symmetric_key *skey); | ||||
|    void (*accel_ccm_memory)( | ||||
|    int (*accel_ccm_memory)( | ||||
|        const unsigned char *key,    unsigned long keylen, | ||||
|        symmetric_key       *uskey, | ||||
|        const unsigned char *nonce,  unsigned long noncelen, | ||||
|        const unsigned char *header, unsigned long headerlen, | ||||
|              unsigned char *pt,     unsigned long ptlen, | ||||
|              unsigned char *ct, | ||||
|              unsigned char *tag,    unsigned long *taglen, | ||||
|                        int  direction); | ||||
| 
 | ||||
|    int (*accel_gcm_memory)( | ||||
|        const unsigned char *key,    unsigned long keylen, | ||||
|        const unsigned char *IV,     unsigned long IVlen, | ||||
|        const unsigned char *adata,  unsigned long adatalen, | ||||
|              unsigned char *pt,     unsigned long ptlen, | ||||
|              unsigned char *ct, | ||||
|              unsigned char *tag,    unsigned long *taglen, | ||||
|                        int direction); | ||||
| }; | ||||
| \end{verbatim} | ||||
| \end{small} | ||||
| @ -1200,6 +1208,7 @@ function that performs the protocol. | ||||
| \begin{verbatim} | ||||
| int ccm_memory(int cipher, | ||||
|     const unsigned char *key,    unsigned long keylen, | ||||
|     symmetric_key       *uskey, | ||||
|     const unsigned char *nonce,  unsigned long noncelen, | ||||
|     const unsigned char *header, unsigned long headerlen, | ||||
|           unsigned char *pt,     unsigned long ptlen, | ||||
| @ -1209,9 +1218,15 @@ int ccm_memory(int cipher, | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This performs the ``CCM'' operation on the data.  The ``cipher'' variable indicates which cipher in the descriptor table to use.  It must have a  | ||||
| 16--byte block size for CCM.  The key is ``key'' with a length of ``keylen'' octets.  The nonce or salt is ``nonce'' of | ||||
| length ``noncelen'' octets.  The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header'' | ||||
| of length ``headerlen'' octets.  The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}).   | ||||
| 16--byte block size for CCM.   | ||||
| 
 | ||||
| The key can be specified in one of two fashions.  First it can be passed as an array of octets in ``key'' of length ``keylen''.  Alternatively, | ||||
| it can be passed in as a previously scheduled key in ``uskey''.  The latter fashion saves time when the same key is used for multiple packets.  If | ||||
| ``uskey'' is not \textbf{NULL} then ``key'' may be \textbf{NULL} (and vice-versa).  | ||||
| 
 | ||||
| The nonce or salt is ``nonce'' of length ``noncelen'' octets.  The header is meta--data you want to send with the message but not have  | ||||
| encrypted, it is stored in ``header'' of length ``headerlen'' octets.  The header can be zero octets long (if $headerlen = 0$ then  | ||||
| you can pass ``header'' as \textbf{NULL}).   | ||||
| 
 | ||||
| The plaintext is stored in ``pt'' and the ciphertext in ``ct''.  The length of both are expected to be equal and is passed in as ``ptlen''.  It is | ||||
| allowable that $pt = ct$.  The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or  | ||||
| @ -2902,28 +2917,39 @@ int ecc_shared_secret(ecc_key *private_key, | ||||
| The ``private\_key'' is your own key and ``public\_key'' is the key the other user sent you.   Note that this function stores only the  | ||||
| $x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH.   | ||||
| 
 | ||||
| \section{ECC Packet} | ||||
| \section{ECC Diffie-Hellman Encryption} | ||||
| Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key | ||||
| algorithms. | ||||
| 
 | ||||
| \index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()} | ||||
| \index{ecc\_encrypt\_key()} | ||||
| \begin{verbatim} | ||||
| int ecc_encrypt_key(const unsigned char *in,   unsigned long  inlen, | ||||
|                           unsigned char *out,  unsigned long *outlen,  | ||||
|                           prng_state *prng, int wprng, int hash,  | ||||
|                           ecc_key *key); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| Where ``in'' is an input symmetric key of no more than 64 bytes.  This function creates a random public key | ||||
| and computes the hash of the shared secret.  The message digest is then XOR'ed against the symmetric key.  All of the required | ||||
| data is placed in ``out'' by ``ecc\_encrypt\_key()''.   The hash chosen must produce a message digest at least as large | ||||
| as the symmetric key you are trying to share. | ||||
| 
 | ||||
| The data is encrypted to the public ECC ``key'' such that only the holder of the private key can decrypt the payload.  If you want | ||||
| to have multiple recipients you will have to call this function for each public ECC key you want to encrypt to. | ||||
| 
 | ||||
| 
 | ||||
| \index{ecc\_decrypt\_key()} | ||||
| \begin{verbatim} | ||||
| int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||
|                           unsigned char *out, unsigned long *outlen,  | ||||
|                           ecc_key *key); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| Where ``in'' is an input symmetric key of no more than 64 bytes.  Essentially these routines created a random public key | ||||
| and find the hash of the shared secret.  The message digest is than XOR'ed against the symmetric key.  All of the required | ||||
| data is placed in ``out'' by ``ecc\_encrypt\_key()''.   The hash chosen must produce a message digest at least as large | ||||
| as the symmetric key you are trying to share. | ||||
| This function will decrypt an encrypted payload.  The ``key'' provided must be the private key corresponding to the public key | ||||
| used during encryption.  If the wrong key is provided the function won't specifically return an error code.  It is important | ||||
| to use some form of challenge response in that case (e.g. compute a MAC of a known string). | ||||
| 
 | ||||
| \subsection{Encrypt Packet Format} | ||||
| \subsection{Encrypt Encryption Format} | ||||
| 
 | ||||
| The packet format for the encrypted keys is the following ASN.1 SEQUENCE: | ||||
| 
 | ||||
| @ -2935,30 +2961,40 @@ ECCEncrypt ::= SEQUENCE { | ||||
| } | ||||
| \end{verbatim} | ||||
| 
 | ||||
| \section{ECC DSA Signatures} | ||||
| 
 | ||||
| There are also functions to sign and verify the hash of a message. | ||||
| \index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()} | ||||
| \index{ecc\_sign\_hash()} | ||||
| \begin{verbatim} | ||||
| int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, | ||||
|                         unsigned char *out, unsigned long *outlen, | ||||
|                         prng_state *prng, int wprng, ecc_key *key); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This function will EC--DSA sign the message digest stored in the buffer ``in'' of length inlen octets.  The signature | ||||
| will be stored in the ``out'' buffer of length ``outlen''.  The function requires a properly seeded PRNG and  | ||||
| the ECC ``key'' provided must be a private key. | ||||
| 
 | ||||
| \index{ecc\_verify\_hash()} | ||||
| \begin{verbatim} | ||||
| int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, | ||||
|                     const unsigned char *hash, unsigned long hashlen,  | ||||
|                           int *stat, ecc_key *key); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.   | ||||
| The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''.  It sets ``stat'' | ||||
| to non-zero if the signature passes or zero if it fails. | ||||
| This function will verify the EC-DSA signature in ``sig'' of length ``siglen'' against the message digest ``hash''.   | ||||
| It will store a non--zero value in ``stat'' if the signature is valid.  Note that the function will not return | ||||
| an error if the signature is invalid.  It will if the actual signature payload is an invalid format.  They ECC ``key'' | ||||
| must be the public (or private) ECC key corresponding to the key that performed the signature. | ||||
| 
 | ||||
| \subsection{Signature Format} | ||||
| The signature code is an implementation of X9.62 EC-DSA and the output is comformant for GF(p) curves. | ||||
| The signature code is an implementation of X9.62 EC--DSA and the output is comformant for GF(p) curves. | ||||
| 
 | ||||
| \section{ECC Keysizes} | ||||
| With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems.  The math will still work | ||||
| and in effect the signature will still work.  With ECC keys the strength of the signature is limited by the size of | ||||
| the hash or the size of they key, whichever is smaller.  For example, if you sign with SHA256 and an ECC-192 key in effect | ||||
| you have 192-bits of security.   | ||||
| you have 96-bits of security.   | ||||
| 
 | ||||
| The library will not warn you if you make this mistake so it is important to check yourself before using the  | ||||
| signatures. | ||||
| @ -3077,6 +3113,7 @@ This will test ``key'' and store the result in ``stat''.  If the result is $stat | ||||
| and should not be used at all.  If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned). | ||||
| 
 | ||||
| \section{Signatures} | ||||
| \subsection{Signature Generation} | ||||
| To generate a DSA signature call the following function | ||||
| 
 | ||||
| \index{dsa\_sign\_hash()} | ||||
| @ -3090,6 +3127,7 @@ Which will sign the data in ``in'' of length ``inlen'' bytes.  The signature is | ||||
| of the signature in ``outlen''.  If the signature is longer than the size you initially specify in ``outlen'' nothing | ||||
| is stored and the function returns an error code.  The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion. | ||||
| 
 | ||||
| \subsection{Signature Verification} | ||||
| To verify a hash created with that function use the following function | ||||
| 
 | ||||
| \index{dsa\_verify\_hash()}  | ||||
| @ -3101,6 +3139,35 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, | ||||
| Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''.   | ||||
| It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$.   | ||||
| 
 | ||||
| \section{DSA Encrypt and Decrypt} | ||||
| As of version 1.07 the DSA keys can be used to encrypt and decrypt small payloads.  It works similar to the ECC encryption where | ||||
| a shared key is computed and the hash of the shared key xor'ed against the plaintext forms the ciphertext. | ||||
| 
 | ||||
| \subsection{DSA Encryption} | ||||
| This function will encrypt a small payload with a recipients public DSA key. | ||||
| 
 | ||||
| \index{dsa\_encrypt\_key()} | ||||
| \begin{verbatim} | ||||
| int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen, | ||||
|                           unsigned char *out,  unsigned long *outlen,  | ||||
|                           prng_state *prng, int wprng, int hash,  | ||||
|                           dsa_key *key); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This will encrypt the payload in ``in'' of length ``inlen'' and store the ciphertext in the output buffer ``out''.  The | ||||
| length of the ciphertext ``outlen'' must be originally set to the length of the output buffer.  The DSA ``key'' can be  | ||||
| a public key. | ||||
| 
 | ||||
| \subsection{DSA Decryption} | ||||
| 
 | ||||
| \index{dsa\_decrypt\_key()} | ||||
| \begin{verbatim}                       | ||||
| int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||
|                           unsigned char *out, unsigned long *outlen,  | ||||
|                           dsa_key *key); | ||||
| \end{verbatim} | ||||
| This will decrypt the ciphertext ``in'' of length ``inlen'' and store the original payload in ``out'' of length ``outlen''.  The DSA ``key'' must be a private key. | ||||
| 
 | ||||
| \section{Import and Export} | ||||
| 
 | ||||
| To export a DSA key so that it can be transported use the following function | ||||
| @ -3141,9 +3208,12 @@ typedef struct { | ||||
|    void                  *data; | ||||
|    unsigned long          size; | ||||
|    int                    used; | ||||
|    struct ltc_asn1_list_ *prev,  *next,  | ||||
|                          *child, *parent; | ||||
| } ltc_asn1_list; | ||||
| \end{verbatim} | ||||
| 
 | ||||
| \index{LTC\_SET\_ASN1 macro} | ||||
| The ``type'' field is one of the following ASN.1 field definitions.  The ``data'' pointer is a void pointer to the data to be encoded (or the destination) and the  | ||||
| ``size'' field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type).  The ``used'' field is primarily for the CHOICE decoder | ||||
| and reflects if the particular member of a list was the decoded data type.  To help build the lists in an orderly fashion the macro | ||||
| @ -3468,6 +3538,45 @@ This will decode the input in the ``in'' field of length ``inlen''.  It uses the | ||||
| The ``inlen'' field will be updated with the length of the decoded data type as well as the respective entry in the ``list'' field will have the ``used'' flag  | ||||
| set to non--zero to reflect it was the data type decoded. | ||||
| 
 | ||||
| \subsection{ASN.1 Flexi Decoder} | ||||
| The ASN.1 ``flexi'' decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing | ||||
| the structure of the data.  Where der\_decode\_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely | ||||
| free form. | ||||
| 
 | ||||
| The flexi decoder uses the same ``ltc\_asn1\_list'' but instead of being stored in an array it uses the linked list pointers ``prev'', ``next'', ``parent''  | ||||
| and ``child''.  The list works as a ``doubly-linked list'' structure where decoded items at the same level are sibblings (using next and prev) and items | ||||
| encoded in a SEQUENCE are stored as a child element. | ||||
| 
 | ||||
| When a SEQUENCE has been encountered a SEQUENCE item is added as a sibbling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child pointer points to a new list | ||||
| of items contained within the sequence\footnote{The same will be true for the SET data type when I eventually support it.}. | ||||
| 
 | ||||
| \index{der\_decode\_sequence\_flexi()} | ||||
| \begin{verbatim} | ||||
| int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen,  | ||||
|                                      ltc_asn1_list **out); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This will decode items in the ``in'' buffer of max input length ``inlen'' and store the newly created pointer to the list in ``out''.  This function allocates | ||||
| all required memory for the decoding.  It stores the number of octets read back into ``inlen''. | ||||
| 
 | ||||
| The function will terminate when either it hits an invalid ASN.1 type octet or it reads ``inlen'' octets.  An early terminate is a soft error and returns | ||||
| normally.  The decoded list ``out'' will point to the very first element of the list (e.g. both parent and prev pointers will be \textbf{NULL}).   | ||||
| 
 | ||||
| An invalid decoding will terminate the process and free the allocated memory automatically.   | ||||
| 
 | ||||
| \textbf{Note} that the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly.  You will have to first  | ||||
| have to convert the list by first storing all of the sibblings in an array then storing all the children as sub-lists of a sequence using the ``.data''  | ||||
| pointer.  Currently no function in LibTomCrypt provides this ability. | ||||
| 
 | ||||
| To free the list use the following function. | ||||
| 
 | ||||
| \index{der\_sequence\_free()} | ||||
| \begin{verbatim} | ||||
| void der_sequence_free(ltc_asn1_list *in); | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This will free all of the memory allocated by der\_decode\_sequence\_flexi(). | ||||
| 
 | ||||
| \section{Password Based Cryptography} | ||||
| \subsection{PKCS \#5} | ||||
| \index{PKCS \#5} | ||||
| @ -3729,6 +3838,26 @@ libraries.  One for LibTomMath and one for TomsFastMath. | ||||
| All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process.  Most of the  | ||||
| settings can be overwritten from the command line which makes custom installation a breeze. | ||||
| 
 | ||||
| \index{MAKE} | ||||
| \index{CC} | ||||
| \index{AR} | ||||
| \subsection{MAKE, CC and AR} | ||||
| The MAKE, CC and AR flags can all be overwritten.  They default to ``make'', ``\$CC'' and ``\$AR'' respectively.   | ||||
| 
 | ||||
| Changing MAKE allows you to change what program will be invoked to handle sub--directories.  E.g. | ||||
| 
 | ||||
| \begin{verbatim} | ||||
| MAKE=gmake gmake install | ||||
| \end{verbatim} | ||||
| 
 | ||||
| Will build and install the libraries with the ``gmake'' tool.  Similarly | ||||
| 
 | ||||
| \begin{verbatim} | ||||
| CC=arm-gcc AR=arm-ar make  | ||||
| \end{verbatim} | ||||
| 
 | ||||
| Will build the library using ``arm--gcc'' as the compiler and ``arm--ar'' as the archiver. | ||||
| 
 | ||||
| \subsection{IGNORE\_SPEED} | ||||
| \index{IGNORE\_SPEED} | ||||
| When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new | ||||
| @ -3758,7 +3887,8 @@ directory which defaults to ``/usr/lib''.  \textbf{INCPATH} is the prefix for th | ||||
| All four can be used to create custom install locations depending on the nature of the OS and file system in use. | ||||
| 
 | ||||
| \begin{verbatim} | ||||
| make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include DATAPATH=/home/tom/project/docs install | ||||
| make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include \ | ||||
|      DATAPATH=/home/tom/project/docs install | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This will build the library and install it to the directories under ``/home/tom/project/''.  e.g. | ||||
| @ -3848,13 +3978,11 @@ LibTomCrypt can also be built as a shared library through the ``makefile.shared' | ||||
| that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time.   | ||||
| 
 | ||||
| \begin{verbatim} | ||||
| CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared | ||||
| CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install | ||||
| \end{verbatim} | ||||
| 
 | ||||
| This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well). | ||||
| Note that unlike the static build there is no ``install'' target.  The default action of this make script is to install the library. | ||||
| 
 | ||||
| The shared build process requires libtool to be installed. | ||||
| This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well).  The  | ||||
| shared build process requires libtool to be installed. | ||||
| 
 | ||||
| \section{tomcrypt\_cfg.h} | ||||
| The file ``tomcrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour  | ||||
| @ -4025,26 +4153,31 @@ struct ltc_cipher_descriptor { | ||||
|       @param skey        [out] The destination of the scheduled key | ||||
|       @return CRYPT_OK if successful | ||||
|    */ | ||||
|    int  (*setup)(const unsigned char *key, int keylen,  | ||||
|                  int num_rounds, symmetric_key *skey); | ||||
|    int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
|    /** Encrypt a block | ||||
|       @param pt      The plaintext | ||||
|       @param ct      [out] The ciphertext | ||||
|       @param skey    The scheduled key | ||||
|       @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*ecb_encrypt)(const unsigned char *pt,  | ||||
|                              unsigned char *ct, symmetric_key *skey); | ||||
|    int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
|    /** Decrypt a block | ||||
|       @param ct      The ciphertext | ||||
|       @param pt      [out] The plaintext | ||||
|       @param skey    The scheduled key | ||||
|       @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*ecb_decrypt)(const unsigned char *ct,  | ||||
|                              unsigned char *pt, symmetric_key *skey); | ||||
|    int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
|    /** Test the block cipher | ||||
|        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled | ||||
|    */ | ||||
|    int (*test)(void); | ||||
| 
 | ||||
|    /** Terminate the context  | ||||
|       @param skey    The scheduled key | ||||
|    */ | ||||
|    void (*done)(symmetric_key *skey);       | ||||
| 
 | ||||
|    /** Determine a key size | ||||
|        @param keysize    [in/out] The size of the key desired and the suggested size | ||||
|        @return CRYPT_OK if successful | ||||
| @ -4057,20 +4190,20 @@ struct ltc_cipher_descriptor { | ||||
|        @param ct      Ciphertext | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ecb_encrypt)(const unsigned char *pt,  | ||||
|                                    unsigned char *ct, unsigned long blocks,  | ||||
|                              symmetric_key *skey); | ||||
|    int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct,  | ||||
|                                   unsigned long blocks, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated ECB decryption  | ||||
|        @param pt      Plaintext | ||||
|        @param ct      Ciphertext | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ecb_decrypt)(const unsigned char *ct,  | ||||
|                                    unsigned char *pt, unsigned long blocks,  | ||||
|                              symmetric_key *skey); | ||||
|    int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt,  | ||||
|                                   unsigned long blocks, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CBC encryption  | ||||
|        @param pt      Plaintext | ||||
| @ -4078,10 +4211,11 @@ struct ltc_cipher_descriptor { | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param IV      The initial value (input/output) | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_cbc_encrypt)(const unsigned char *pt,  | ||||
|                                    unsigned char *ct, unsigned long blocks,  | ||||
|                                    unsigned char *IV, symmetric_key *skey); | ||||
|    int (*accel_cbc_encrypt)(const unsigned char *pt,    unsigned char *ct,  | ||||
|                                   unsigned long blocks, unsigned char *IV,  | ||||
|                                   symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CBC decryption  | ||||
|        @param pt      Plaintext | ||||
| @ -4089,10 +4223,11 @@ struct ltc_cipher_descriptor { | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param IV      The initial value (input/output) | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_cbc_decrypt)(const unsigned char *ct,  | ||||
|                                    unsigned char *pt, unsigned long blocks,  | ||||
|                                    unsigned char *IV, symmetric_key *skey); | ||||
|    int (*accel_cbc_decrypt)(const unsigned char *ct,    unsigned char *pt,  | ||||
|                                   unsigned long blocks, unsigned char *IV,  | ||||
|                                   symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CTR encryption  | ||||
|        @param pt      Plaintext | ||||
| @ -4101,14 +4236,16 @@ struct ltc_cipher_descriptor { | ||||
|        @param IV      The initial value (input/output) | ||||
|        @param mode    little or big endian counter (mode=0 or mode=1) | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ctr_encrypt)(const unsigned char *pt,  | ||||
|                                    unsigned char *ct, unsigned long blocks,  | ||||
|                                    unsigned char *IV, int mode, symmetric_key *skey); | ||||
|    int (*accel_ctr_encrypt)(const unsigned char *pt,    unsigned char *ct, | ||||
|                                   unsigned long blocks, unsigned char *IV,  | ||||
|                                   int mode, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CCM packet (one-shot) | ||||
|        @param key        The secret key to use | ||||
|        @param keylen     The length of the secret key (octets) | ||||
|        @param uskey      A previously scheduled key [optional can be NULL] | ||||
|        @param nonce      The session nonce [use once] | ||||
|        @param noncelen   The length of the nonce | ||||
|        @param header     The header for the session | ||||
| @ -4121,8 +4258,9 @@ struct ltc_cipher_descriptor { | ||||
|        @param direction  Encrypt or Decrypt direction (0 or 1) | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ccm_memory)( | ||||
|    int (*accel_ccm_memory)( | ||||
|        const unsigned char *key,    unsigned long keylen, | ||||
|        symmetric_key       *uskey, | ||||
|        const unsigned char *nonce,  unsigned long noncelen, | ||||
|        const unsigned char *header, unsigned long headerlen, | ||||
|              unsigned char *pt,     unsigned long ptlen, | ||||
| @ -4143,8 +4281,9 @@ struct ltc_cipher_descriptor { | ||||
|        @param tag               [out] The MAC tag | ||||
|        @param taglen            [in/out] The MAC tag length | ||||
|        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) | ||||
|        @return CRYPT_OK on success | ||||
|    */ | ||||
|    void (*accel_gcm_memory)( | ||||
|    int (*accel_gcm_memory)( | ||||
|        const unsigned char *key,    unsigned long keylen, | ||||
|        const unsigned char *IV,     unsigned long IVlen, | ||||
|        const unsigned char *adata,  unsigned long adatalen, | ||||
| @ -4152,7 +4291,6 @@ struct ltc_cipher_descriptor { | ||||
|              unsigned char *ct,  | ||||
|              unsigned char *tag,    unsigned long *taglen, | ||||
|                        int direction); | ||||
| 
 | ||||
| }; | ||||
| \end{verbatim} | ||||
| \end{small} | ||||
| @ -4231,8 +4369,22 @@ buffer provided) before encrypting it to create the pad. | ||||
| The accelerator will only be used to encrypt whole blocks.  Partial blocks are always handled in software. | ||||
| 
 | ||||
| \subsubsection{Accelerated CCM} | ||||
| This function is meant for accelerated CCM encryption or decryption.  It processes the entire packet in one call.  Note that the setup() function will not | ||||
| be called prior to this.  This function must handle scheduling the key provided on its own. | ||||
| This function is meant for accelerated CCM encryption or decryption.  It processes the entire packet in one call.  You can optimize the work flow somewhat | ||||
| by allowing the caller to call the setup() function first to schedule the key if your accelerator cannot do the key schedule on the fly (for instance).  This  | ||||
| function MUST support both key passing methods. | ||||
| 
 | ||||
| \begin{center} | ||||
| \begin{small} | ||||
| \begin{tabular}{|r|r|l|} | ||||
| \hline \textbf{key} & \textbf{uskey} & \textbf{Source of key} \\ | ||||
| \hline NULL         & NULL           & Error, not supported \\ | ||||
| \hline non-NULL     & NULL           & Use key, do a key schedule \\ | ||||
| \hline NULL         & non-NULL       & Use uskey, key schedule not required \\ | ||||
| \hline non-NULL     & non-NULL       & Use uskey, key schedule not required \\ | ||||
| \hline | ||||
| \end{tabular} | ||||
| \end{small} | ||||
| \end{center} | ||||
| 
 | ||||
| \subsubsection{Accelerated GCM} | ||||
| This function is meant for accelerated GCM encryption or decryption.  It processes the entire packet in one call.  Note that the setup() function will not | ||||
| @ -4560,7 +4712,6 @@ typedef struct { | ||||
|    */ | ||||
|    int (*add)(void *a, void *b, void *c); | ||||
| 
 | ||||
| 
 | ||||
|    /** add two integers  | ||||
|      @param a   The first source integer | ||||
|      @param b   The second source integer (single digit of upto bits_per_digit in length) | ||||
| @ -4748,6 +4899,16 @@ typedef struct { | ||||
| 
 | ||||
| /* ---- (optional) rsa optimized math (for internal CRT) ---- */ | ||||
| 
 | ||||
|    /** RSA Key Generation  | ||||
|        @param prng     An active PRNG state | ||||
|        @param wprng    The index of the PRNG desired | ||||
|        @param size     The size of the modulus (key size) desired (octets) | ||||
|        @param e        The "e" value (public key).  e==65537 is a good choice | ||||
|        @param key      [out] Destination of a newly created private key pair | ||||
|        @return CRYPT_OK if successful, upon error all allocated ram is freed | ||||
|     */ | ||||
|     int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); | ||||
| 
 | ||||
|    /** RSA exponentiation | ||||
|       @param in       The octet array representing the base | ||||
|       @param inlen    The length of the input | ||||
| @ -4851,5 +5012,5 @@ Since the function is given the entire RSA key (for private keys only) CRT is po | ||||
| \end{document} | ||||
| 
 | ||||
| % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $    | ||||
| % $Revision: 1.45 $    | ||||
| % $Date: 2005/08/01 16:59:29 $  | ||||
| % $Revision: 1.55 $    | ||||
| % $Date: 2005/11/18 01:45:03 $  | ||||
|  | ||||
| @ -170,7 +170,7 @@ int main(int argc, char *argv[]) | ||||
|          exit(-1); | ||||
|       } | ||||
|     | ||||
|       if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) { | ||||
|       if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { | ||||
|          printf("ctr_start error: %s\n",error_to_string(errno)); | ||||
|          exit(-1); | ||||
|       } | ||||
| @ -212,7 +212,7 @@ int main(int argc, char *argv[]) | ||||
|          exit(-1); | ||||
|       } | ||||
| 
 | ||||
|       if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) { | ||||
|       if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { | ||||
|          printf("ctr_start error: %s\n",error_to_string(errno)); | ||||
|          exit(-1); | ||||
|       } | ||||
|  | ||||
| @ -24,6 +24,7 @@ int main(void) | ||||
|    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("\nkatja_test...."); fflush(stdout); x = katja_test();       printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); | ||||
|    printf("\n"); | ||||
|    return EXIT_SUCCESS; | ||||
| } | ||||
|  | ||||
| @ -14,7 +14,6 @@ reg_algs(); | ||||
|    extern ltc_math_descriptor EXT_MATH_LIB; | ||||
|    ltc_mp = EXT_MATH_LIB; | ||||
| #endif | ||||
| 
 | ||||
| time_keysched(); | ||||
| time_cipher(); | ||||
| time_cipher2(); | ||||
| @ -27,6 +26,9 @@ time_mult(); | ||||
| time_sqr(); | ||||
| time_rsa(); | ||||
| time_ecc(); | ||||
| #ifdef USE_LTM | ||||
| time_katja(); | ||||
| #endif | ||||
| return EXIT_SUCCESS; | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -551,7 +551,7 @@ void ccm_gen(void) | ||||
|             plaintext[z] = (unsigned char)(z & 255); | ||||
|          } | ||||
|          len = sizeof(tag); | ||||
|          if ((err = ccm_memory(x, key, kl, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) { | ||||
|          if ((err = ccm_memory(x, key, kl, NULL, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) { | ||||
|             printf("Error CCM'ing: %s\n", error_to_string(err)); | ||||
|             exit(EXIT_FAILURE); | ||||
|          } | ||||
| @ -682,7 +682,7 @@ void ecc_gen(void) | ||||
|         mp_set(G->z, 1);   | ||||
| 
 | ||||
|         while (mp_cmp(k, order) == LTC_MP_LT) { | ||||
|             ltc_ecc_mulmod(k, G, R, modulus, 1); | ||||
|             ltc_mp.ecc_ptmul(k, G, R, modulus, 1); | ||||
|             mp_tohex(k,    str); fprintf(out, "%s, ", str); | ||||
|             mp_tohex(R->x, str); fprintf(out, "%s, ", str); | ||||
|             mp_tohex(R->y, str); fprintf(out, "%s\n", str); | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								doc/crypt.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								doc/crypt.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										80
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								makefile
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
| # Modified by Clay Culver
 | ||||
| 
 | ||||
| # The version
 | ||||
| VERSION=1.06 | ||||
| VERSION=1.07 | ||||
| 
 | ||||
| # Compiler and Linker Names
 | ||||
| #CC=gcc
 | ||||
| @ -14,12 +14,23 @@ VERSION=1.06 | ||||
| #AR=ar
 | ||||
| #ARFLAGS=r
 | ||||
| 
 | ||||
| ifndef MAKE | ||||
|   MAKE=make | ||||
| endif | ||||
| 
 | ||||
| # ranlib tools
 | ||||
| ifndef RANLIB | ||||
|    RANLIB=ranlib | ||||
| endif | ||||
| 
 | ||||
| # Compilation flags. Note the += does not write over the user's CFLAGS!
 | ||||
| CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter -DLTC_SOURCE | ||||
| 
 | ||||
| # additional warnings (newer GCC 3.4 and higher)
 | ||||
| #CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
 | ||||
| #		  -Wmissing-declarations -Wpointer-arith 
 | ||||
| ifdef GCC_34 | ||||
| CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
 | ||||
| 		  -Wmissing-declarations -Wpointer-arith  | ||||
| endif | ||||
| 
 | ||||
| ifndef IGNORE_SPEED | ||||
| 
 | ||||
| @ -47,8 +58,8 @@ ifndef LIBNAME | ||||
| endif | ||||
| ifndef LIBTEST | ||||
|    LIBTEST=libtomcrypt_prof.a | ||||
|    LIBTEST_S=$(LIBTEST) | ||||
| endif | ||||
| LIBTEST_S=$(LIBTEST) | ||||
| 
 | ||||
| HASH=hashsum | ||||
| CRYPT=encrypt | ||||
| @ -154,22 +165,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \ | ||||
| src/pk/asn1/der/printable_string/der_decode_printable_string.o \ | ||||
| src/pk/asn1/der/printable_string/der_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/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ | ||||
| src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \ | ||||
| src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ | ||||
| src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ | ||||
| src/pk/asn1/der/short_integer/der_encode_short_integer.o \ | ||||
| src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | ||||
| src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | ||||
| src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ | ||||
| src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ | ||||
| src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \ | ||||
| src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \ | ||||
| src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \ | ||||
| src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ | ||||
| src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ | ||||
| src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ | ||||
| src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ | ||||
| src/prngs/sprng.o src/prngs/yarrow.o  | ||||
| src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \ | ||||
| src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \ | ||||
| src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \ | ||||
| src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \ | ||||
| src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ | ||||
| src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ | ||||
| src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ | ||||
| src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ | ||||
| src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ | ||||
| src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \ | ||||
| src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \ | ||||
| src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ | ||||
| src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ | ||||
| src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o  | ||||
| 
 | ||||
| HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 | ||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | ||||
| @ -203,8 +223,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c | ||||
| src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c | ||||
| src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c | ||||
| src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c | ||||
| src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c | ||||
| src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c | ||||
| src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c | ||||
| src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c | ||||
| 
 | ||||
| @ -212,11 +230,11 @@ src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c | ||||
| library: $(LIBNAME) | ||||
| 
 | ||||
| testprof/$(LIBTEST):  | ||||
| 	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) make  | ||||
| 	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE)  | ||||
| 
 | ||||
| $(LIBNAME): $(OBJECTS) | ||||
| 	$(AR) $(ARFLAGS) $@ $(OBJECTS)  | ||||
| 	ranlib $(LIBNAME) | ||||
| 	$(RANLIB) $@ | ||||
| 
 | ||||
| #This rule makes the hash program included with libtomcrypt
 | ||||
| hashsum: library $(HASHOBJECTS) | ||||
| @ -242,28 +260,33 @@ timing: library testprof/$(LIBTEST) $(TIMINGS) | ||||
| test: library testprof/$(LIBTEST) $(TESTS) | ||||
| 	$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) | ||||
| 
 | ||||
| 
 | ||||
| #This rule installs the library and the header files. This must be run
 | ||||
| #as root in order to have a high enough permission to write to the correct
 | ||||
| #directories and to set the owner and group to root.
 | ||||
| ifndef NODOCS | ||||
| install: library docs | ||||
| else | ||||
| install: library | ||||
| endif | ||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) | ||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | ||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) | ||||
| 	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) | ||||
| 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) | ||||
| ifndef NODOCS | ||||
| 	install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH) | ||||
| endif | ||||
| 
 | ||||
| install_test: $(LIBTEST) | ||||
| install_test: testprof/$(LIBTEST) | ||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) | ||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | ||||
| 	install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH) | ||||
| 	install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH) | ||||
| 
 | ||||
| profile: | ||||
| 	CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov | ||||
| 	CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" | ||||
| 	./timing | ||||
| 	rm -f timing `find . -type f | grep [.][ao] | xargs` | ||||
| 	CFLAGS="$(CFLAGS) -fprofile-use" make timing EXTRALIBS=-lgcov | ||||
| 	CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" | ||||
| 
 | ||||
| 
 | ||||
| #This rule cleans the source tree of all compiled code, not including the pdf
 | ||||
| @ -291,7 +314,7 @@ clean: | ||||
| #build the doxy files (requires Doxygen, tetex and patience)
 | ||||
| doxy: | ||||
| 	doxygen | ||||
| 	cd doc/doxygen/latex ; make ; mv -f refman.pdf ../../. | ||||
| 	cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../. | ||||
| 	echo The huge doxygen PDF should be available as doc/refman.pdf | ||||
| 	 | ||||
| #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
 | ||||
| @ -333,6 +356,5 @@ zipup: no_oops docs | ||||
| 
 | ||||
| 
 | ||||
| # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
 | ||||
| # $Revision: 1.86 $ 
 | ||||
| # $Date: 2005/07/30 04:54:20 $ 
 | ||||
| 
 | ||||
| # $Revision: 1.103 $ 
 | ||||
| # $Date: 2005/11/18 01:46:22 $ 
 | ||||
|  | ||||
							
								
								
									
										39
									
								
								makefile.icc
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								makefile.icc
									
									
									
									
									
								
							| @ -152,22 +152,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \ | ||||
| src/pk/asn1/der/printable_string/der_decode_printable_string.o \ | ||||
| src/pk/asn1/der/printable_string/der_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/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ | ||||
| src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \ | ||||
| src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ | ||||
| src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ | ||||
| src/pk/asn1/der/short_integer/der_encode_short_integer.o \ | ||||
| src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | ||||
| src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | ||||
| src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ | ||||
| src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ | ||||
| src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \ | ||||
| src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \ | ||||
| src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \ | ||||
| src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ | ||||
| src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ | ||||
| src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ | ||||
| src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ | ||||
| src/prngs/sprng.o src/prngs/yarrow.o  | ||||
| src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \ | ||||
| src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \ | ||||
| src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \ | ||||
| src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \ | ||||
| src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ | ||||
| src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ | ||||
| src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ | ||||
| src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ | ||||
| src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ | ||||
| src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \ | ||||
| src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \ | ||||
| src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ | ||||
| src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ | ||||
| src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o  | ||||
| 
 | ||||
| HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ | ||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | ||||
| @ -207,8 +216,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c | ||||
| src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c | ||||
| src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c | ||||
| src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c | ||||
| src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c | ||||
| src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c | ||||
| src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c | ||||
| src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c | ||||
| 
 | ||||
| @ -254,5 +261,5 @@ install: library | ||||
| 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) | ||||
| 
 | ||||
| # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $    | ||||
| # $Revision: 1.39 $    | ||||
| # $Date: 2005/07/30 23:38:39 $  | ||||
| # $Revision: 1.44 $    | ||||
| # $Date: 2005/11/18 01:46:22 $  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #MSVC Makefile [tested with MSVC 6.00 with SP5] | ||||
| # | ||||
| #Tom St Denis | ||||
| CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ | ||||
| CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF) | ||||
| 
 | ||||
| OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \ | ||||
| src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \ | ||||
| @ -67,22 +67,31 @@ src/pk/asn1/der/octet/der_length_octet_string.obj \ | ||||
| src/pk/asn1/der/printable_string/der_decode_printable_string.obj \ | ||||
| src/pk/asn1/der/printable_string/der_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/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ | ||||
| src/pk/asn1/der/sequence/der_decode_sequence_multi.obj src/pk/asn1/der/sequence/der_encode_sequence.obj \ | ||||
| src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \ | ||||
| src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \ | ||||
| src/pk/asn1/der/short_integer/der_encode_short_integer.obj \ | ||||
| src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \ | ||||
| src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \ | ||||
| src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj \ | ||||
| src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \ | ||||
| src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_shared_secret.obj \ | ||||
| src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj \ | ||||
| src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \ | ||||
| src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \ | ||||
| src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \ | ||||
| src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \ | ||||
| src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \ | ||||
| src/prngs/sprng.obj src/prngs/yarrow.obj  | ||||
| src/pk/ecc/ecc_decrypt_key.obj src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_free.obj \ | ||||
| src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.obj \ | ||||
| src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj \ | ||||
| src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ltc_ecc_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj \ | ||||
| src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \ | ||||
| src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \ | ||||
| src/pk/katja/katja_decrypt_key.obj src/pk/katja/katja_encrypt_key.obj src/pk/katja/katja_export.obj \ | ||||
| src/pk/katja/katja_exptmod.obj src/pk/katja/katja_free.obj src/pk/katja/katja_import.obj \ | ||||
| src/pk/katja/katja_make_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ | ||||
| src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj \ | ||||
| src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj \ | ||||
| src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj \ | ||||
| src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \ | ||||
| src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj  | ||||
| 
 | ||||
| HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ | ||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | ||||
| @ -115,5 +124,6 @@ timing: demos/timing.c library | ||||
| 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) | ||||
| 
 | ||||
| # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $    | ||||
| # $Revision: 1.17 $    | ||||
| # $Date: 2005/07/30 23:42:57 $  | ||||
| # $Revision: 1.24 $    | ||||
| # $Date: 2005/11/18 01:46:22 $  | ||||
| 
 | ||||
|  | ||||
| @ -6,11 +6,16 @@ | ||||
| # Tom St Denis | ||||
| 
 | ||||
| # The version | ||||
| VERSION=0:106 | ||||
| VERSION=0:107 | ||||
| 
 | ||||
| # Compiler and Linker Names | ||||
| CC=libtool --mode=compile gcc  | ||||
| 
 | ||||
| # ranlib tools | ||||
| ifndef RANLIB | ||||
|    RANLIB=ranlib | ||||
| endif | ||||
| 
 | ||||
| # Compilation flags. Note the += does not write over the user's CFLAGS! | ||||
| CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE | ||||
| 
 | ||||
| @ -39,8 +44,10 @@ endif | ||||
| #CFLAGS += -DLTC_NO_ROLC | ||||
| 
 | ||||
| #Output filenames for various targets. | ||||
| ifndef LIBTEST | ||||
| ifndef LIBTEST_S | ||||
|    LIBTEST_S=libtomcrypt_prof.a | ||||
| endif | ||||
| ifndef LIBTEST | ||||
|    LIBTEST=libtomcrypt_prof.la | ||||
| endif | ||||
| ifndef LIBNAME | ||||
| @ -152,22 +159,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \ | ||||
| src/pk/asn1/der/printable_string/der_decode_printable_string.o \ | ||||
| src/pk/asn1/der/printable_string/der_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/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ | ||||
| src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \ | ||||
| src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ | ||||
| src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ | ||||
| src/pk/asn1/der/short_integer/der_encode_short_integer.o \ | ||||
| src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | ||||
| src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | ||||
| src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \ | ||||
| src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \ | ||||
| src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \ | ||||
| src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \ | ||||
| src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \ | ||||
| src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ | ||||
| src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ | ||||
| src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ | ||||
| src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ | ||||
| src/prngs/sprng.o src/prngs/yarrow.o  | ||||
| src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \ | ||||
| src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \ | ||||
| src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \ | ||||
| src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \ | ||||
| src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ | ||||
| src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ | ||||
| src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ | ||||
| src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ | ||||
| src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ | ||||
| src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ | ||||
| src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \ | ||||
| src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \ | ||||
| src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \ | ||||
| src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \ | ||||
| src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o  | ||||
| 
 | ||||
| HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ | ||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | ||||
| @ -194,8 +210,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c | ||||
| src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c | ||||
| src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c | ||||
| src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c | ||||
| src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c | ||||
| src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c | ||||
| src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c | ||||
| src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c | ||||
| 
 | ||||
| @ -205,10 +219,13 @@ library: $(LIBNAME) | ||||
| testprof/$(LIBTEST): | ||||
| 	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared | ||||
| 
 | ||||
| $(LIBNAME): $(OBJECTS) | ||||
| objs: $(OBJECTS) | ||||
| 
 | ||||
| $(LIBNAME): $(OBJECTS) testprof/$(LIBTEST) | ||||
| 	libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION) | ||||
| 	libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | grep "src/" | xargs`  $(EXTRALIBS) -o $(LIBNAME_S) | ||||
| 	ranlib $(LIBNAME_S) | ||||
| 
 | ||||
| install: $(LIBNAME) | ||||
| 	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared install | ||||
| 	libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la | ||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | ||||
| 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) | ||||
| @ -233,5 +250,6 @@ timing: library testprof/$(LIBTEST) $(TIMINGS) | ||||
| 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) | ||||
| 
 | ||||
| # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $    | ||||
| # $Revision: 1.25 $    | ||||
| # $Date: 2005/07/30 04:54:20 $  | ||||
| # $Revision: 1.36 $    | ||||
| # $Date: 2005/11/18 01:46:22 $  | ||||
| 
 | ||||
|  | ||||
| @ -281,11 +281,12 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s | ||||
|   @param pt The input plaintext (16 bytes) | ||||
|   @param ct The output ciphertext (16 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)  | ||||
| static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)  | ||||
| #else | ||||
| void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | ||||
| @ -440,13 +441,16 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
|         (Te4_0[byte(t2, 0)]) ^  | ||||
|         rk[3]; | ||||
|     STORE32H(s3, ct+12); | ||||
| 
 | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)  | ||||
| int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)  | ||||
| { | ||||
|    _rijndael_ecb_encrypt(pt, ct, skey); | ||||
|    int err = _rijndael_ecb_encrypt(pt, ct, skey); | ||||
|    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -457,11 +461,12 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
|   @param ct The input ciphertext (16 bytes) | ||||
|   @param pt The output plaintext (16 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)  | ||||
| static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)  | ||||
| #else | ||||
| void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | ||||
| @ -615,14 +620,17 @@ void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
|         (Td4[byte(t0, 0)] & 0x000000ff) ^ | ||||
|         rk[3]; | ||||
|     STORE32H(s3, pt+12); | ||||
| 
 | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)  | ||||
| int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)  | ||||
| { | ||||
|    _rijndael_ecb_decrypt(ct, pt, skey); | ||||
|    int err = _rijndael_ecb_decrypt(ct, pt, skey); | ||||
|    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -1134,13 +1134,15 @@ static void anubis_crypt(const unsigned char *plaintext, unsigned char *cipherte | ||||
|   @param pt The input plaintext (16 bytes) | ||||
|   @param ct The output ciphertext (16 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    LTC_ARGCHK(pt   != NULL); | ||||
|    LTC_ARGCHK(ct   != NULL); | ||||
|    LTC_ARGCHK(skey != NULL); | ||||
|    anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -1148,13 +1150,15 @@ void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke | ||||
|   @param ct The input ciphertext (16 bytes) | ||||
|   @param pt The output plaintext (16 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    LTC_ARGCHK(pt   != NULL); | ||||
|    LTC_ARGCHK(ct   != NULL); | ||||
|    LTC_ARGCHK(skey != NULL); | ||||
|    anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
| @ -385,11 +385,12 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 L, R; | ||||
| @ -428,13 +429,16 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ | ||||
|    /* store */ | ||||
|    STORE32H(R, &ct[0]); | ||||
|    STORE32H(L, &ct[4]); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|     _blowfish_ecb_encrypt(pt, ct, skey); | ||||
|     int err = _blowfish_ecb_encrypt(pt, ct, skey); | ||||
|     burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -443,11 +447,12 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 L, R; | ||||
| @ -486,13 +491,15 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ | ||||
|    /* store */ | ||||
|    STORE32H(L, &pt[0]); | ||||
|    STORE32H(R, &pt[4]); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|     _blowfish_ecb_decrypt(ct, pt, skey); | ||||
|     int err = _blowfish_ecb_decrypt(ct, pt, skey); | ||||
|     burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -536,9 +536,9 @@ INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) | ||||
|   @param skey The key as scheduled | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 R, L; | ||||
| @ -569,14 +569,16 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | ||||
|    } | ||||
|    STORE32H(R,&ct[0]); | ||||
|    STORE32H(L,&ct[4]); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    _cast5_ecb_encrypt(pt,ct,skey); | ||||
|    int err =_cast5_ecb_encrypt(pt,ct,skey); | ||||
|    burn_stack(sizeof(ulong32)*3); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -587,9 +589,9 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | ||||
|   @param skey The key as scheduled  | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 R, L; | ||||
| @ -620,13 +622,16 @@ void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key | ||||
|    L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); | ||||
|    STORE32H(L,&pt[0]); | ||||
|    STORE32H(R,&pt[4]); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    _cast5_ecb_decrypt(ct,pt,skey); | ||||
|    int err = _cast5_ecb_decrypt(ct,pt,skey); | ||||
|    burn_stack(sizeof(ulong32)*3); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -1582,8 +1582,9 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|     ulong32 work[2]; | ||||
|     LTC_ARGCHK(pt   != NULL); | ||||
| @ -1594,6 +1595,7 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | ||||
|     desfunc(work, skey->des.ek); | ||||
|     STORE32H(work[0],ct+0); | ||||
|     STORE32H(work[1],ct+4); | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -1601,8 +1603,9 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|     ulong32 work[2]; | ||||
|     LTC_ARGCHK(pt   != NULL); | ||||
| @ -1613,6 +1616,7 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key * | ||||
|     desfunc(work, skey->des.dk); | ||||
|     STORE32H(work[0],pt+0); | ||||
|     STORE32H(work[1],pt+4);   | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -1620,8 +1624,9 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key * | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|     ulong32 work[2]; | ||||
|      | ||||
| @ -1635,6 +1640,7 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | ||||
|     desfunc(work, skey->des3.ek[2]); | ||||
|     STORE32H(work[0],ct+0); | ||||
|     STORE32H(work[1],ct+4); | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -1642,8 +1648,9 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|     ulong32 work[2]; | ||||
|     LTC_ARGCHK(pt   != NULL); | ||||
| @ -1656,6 +1663,7 @@ void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key | ||||
|     desfunc(work, skey->des3.dk[2]); | ||||
|     STORE32H(work[0],pt+0); | ||||
|     STORE32H(work[1],pt+4); | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
| @ -741,13 +741,15 @@ static void khazad_crypt(const unsigned char *plaintext, unsigned char *cipherte | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    LTC_ARGCHK(pt   != NULL); | ||||
|    LTC_ARGCHK(ct   != NULL); | ||||
|    LTC_ARGCHK(skey != NULL); | ||||
|    khazad_crypt(pt, ct, skey->khazad.roundKeyEnc); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -755,13 +757,15 @@ void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    LTC_ARGCHK(pt   != NULL); | ||||
|    LTC_ARGCHK(ct   != NULL); | ||||
|    LTC_ARGCHK(skey != NULL); | ||||
|    khazad_crypt(ct, pt, skey->khazad.roundKeyDec); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
| @ -107,11 +107,12 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri | ||||
|   @param pt The input plaintext (16 bytes) | ||||
|   @param ct The output ciphertext (16 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 a,b,c,d,temp; | ||||
| @ -142,13 +143,16 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k | ||||
|     | ||||
|    STORE32H(a,&ct[0]); STORE32H(b,&ct[4]); | ||||
|    STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    _noekeon_ecb_encrypt(pt, ct, skey); | ||||
|    int err = _noekeon_ecb_encrypt(pt, ct, skey); | ||||
|    burn_stack(sizeof(ulong32) * 5 + sizeof(int)); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -157,11 +161,12 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k | ||||
|   @param ct The input ciphertext (16 bytes) | ||||
|   @param pt The output plaintext (16 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 a,b,c,d, temp; | ||||
| @ -192,13 +197,15 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k | ||||
|    a ^= RC[0]; | ||||
|    STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); | ||||
|    STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    _noekeon_ecb_decrypt(ct, pt, skey); | ||||
|    int err = _noekeon_ecb_decrypt(ct, pt, skey); | ||||
|    burn_stack(sizeof(ulong32) * 5 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -125,13 +125,14 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rc2_ecb_encrypt( const unsigned char *pt, | ||||
| static int _rc2_ecb_encrypt( const unsigned char *pt, | ||||
|                             unsigned char *ct, | ||||
|                             symmetric_key *skey) | ||||
| #else | ||||
| void rc2_ecb_encrypt( const unsigned char *pt, | ||||
| int rc2_ecb_encrypt( const unsigned char *pt, | ||||
|                             unsigned char *ct, | ||||
|                             symmetric_key *skey) | ||||
| #endif | ||||
| @ -179,15 +180,18 @@ void rc2_ecb_encrypt( const unsigned char *pt, | ||||
|     ct[5] = (unsigned char)(x54 >> 8); | ||||
|     ct[6] = (unsigned char)x76; | ||||
|     ct[7] = (unsigned char)(x76 >> 8); | ||||
|   | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void rc2_ecb_encrypt( const unsigned char *pt, | ||||
| int rc2_ecb_encrypt( const unsigned char *pt, | ||||
|                             unsigned char *ct, | ||||
|                             symmetric_key *skey) | ||||
| { | ||||
|     _rc2_ecb_encrypt(pt, ct, skey); | ||||
|     int err = _rc2_ecb_encrypt(pt, ct, skey); | ||||
|     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -199,13 +203,14 @@ void rc2_ecb_encrypt( const unsigned char *pt, | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rc2_ecb_decrypt( const unsigned char *ct, | ||||
| static int _rc2_ecb_decrypt( const unsigned char *ct, | ||||
|                             unsigned char *pt, | ||||
|                             symmetric_key *skey) | ||||
| #else | ||||
| void rc2_ecb_decrypt( const unsigned char *ct, | ||||
| int rc2_ecb_decrypt( const unsigned char *ct, | ||||
|                             unsigned char *pt, | ||||
|                             symmetric_key *skey) | ||||
| #endif | ||||
| @ -254,15 +259,18 @@ void rc2_ecb_decrypt( const unsigned char *ct, | ||||
|     pt[5] = (unsigned char)(x54 >> 8); | ||||
|     pt[6] = (unsigned char)x76; | ||||
|     pt[7] = (unsigned char)(x76 >> 8); | ||||
| 
 | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void rc2_ecb_decrypt( const unsigned char *ct, | ||||
| int rc2_ecb_decrypt( const unsigned char *ct, | ||||
|                             unsigned char *pt, | ||||
|                             symmetric_key *skey) | ||||
| { | ||||
|     _rc2_ecb_decrypt(ct, pt, skey); | ||||
|     int err = _rc2_ecb_decrypt(ct, pt, skey); | ||||
|     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -123,11 +123,12 @@ int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 A, B, *K; | ||||
| @ -159,13 +160,16 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | ||||
|    } | ||||
|    STORE32L(A, &ct[0]); | ||||
|    STORE32L(B, &ct[4]); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    _rc5_ecb_encrypt(pt, ct, skey); | ||||
|    int err = _rc5_ecb_encrypt(pt, ct, skey); | ||||
|    burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -174,11 +178,12 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 A, B, *K; | ||||
| @ -211,13 +216,16 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key * | ||||
|    B -= skey->rc5.K[1]; | ||||
|    STORE32L(A, &pt[0]); | ||||
|    STORE32L(B, &pt[4]); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    _rc5_ecb_decrypt(ct, pt, skey); | ||||
|    int err = _rc5_ecb_decrypt(ct, pt, skey); | ||||
|    burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -120,9 +120,9 @@ int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke | ||||
|   @param skey The key as scheduled | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 a,b,c,d,t,u, *K; | ||||
| @ -155,13 +155,15 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | ||||
|    a += skey->rc6.K[42]; | ||||
|    c += skey->rc6.K[43]; | ||||
|    STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    _rc6_ecb_encrypt(pt, ct, skey); | ||||
|    int err = _rc6_ecb_encrypt(pt, ct, skey); | ||||
|    burn_stack(sizeof(ulong32) * 6 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -172,9 +174,9 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | ||||
|   @param skey The key as scheduled  | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    ulong32 a,b,c,d,t,u, *K; | ||||
| @ -208,13 +210,16 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key * | ||||
|    b -= skey->rc6.K[0]; | ||||
|    d -= skey->rc6.K[1]; | ||||
|    STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    _rc6_ecb_decrypt(ct, pt, skey); | ||||
|    int err = _rc6_ecb_decrypt(ct, pt, skey); | ||||
|    burn_stack(sizeof(ulong32) * 6 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -246,11 +246,11 @@ int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symme | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _safer_ecb_encrypt(const unsigned char *block_in, | ||||
| static int _safer_ecb_encrypt(const unsigned char *block_in, | ||||
|                              unsigned char *block_out, | ||||
|                              symmetric_key *skey) | ||||
| #else | ||||
| void safer_ecb_encrypt(const unsigned char *block_in, | ||||
| int safer_ecb_encrypt(const unsigned char *block_in, | ||||
|                              unsigned char *block_out, | ||||
|                              symmetric_key *skey) | ||||
| #endif | ||||
| @ -285,24 +285,26 @@ void safer_ecb_encrypt(const unsigned char *block_in, | ||||
|     block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; | ||||
|     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | ||||
|     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void safer_ecb_encrypt(const unsigned char *block_in, | ||||
| int safer_ecb_encrypt(const unsigned char *block_in, | ||||
|                              unsigned char *block_out, | ||||
|                              symmetric_key *skey) | ||||
| { | ||||
|     _safer_ecb_encrypt(block_in, block_out, skey); | ||||
|     int err = _safer_ecb_encrypt(block_in, block_out, skey); | ||||
|     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _safer_ecb_decrypt(const unsigned char *block_in, | ||||
| static int _safer_ecb_decrypt(const unsigned char *block_in, | ||||
|                              unsigned char *block_out, | ||||
|                              symmetric_key *skey) | ||||
| #else | ||||
| void safer_ecb_decrypt(const unsigned char *block_in, | ||||
| int safer_ecb_decrypt(const unsigned char *block_in, | ||||
|                              unsigned char *block_out, | ||||
|                              symmetric_key *skey) | ||||
| #endif | ||||
| @ -338,15 +340,17 @@ void safer_ecb_decrypt(const unsigned char *block_in, | ||||
|     block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; | ||||
|     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | ||||
|     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void safer_ecb_decrypt(const unsigned char *block_in, | ||||
| int safer_ecb_decrypt(const unsigned char *block_in, | ||||
|                              unsigned char *block_out, | ||||
|                              symmetric_key *skey) | ||||
| { | ||||
|     _safer_ecb_decrypt(block_in, block_out, skey); | ||||
|     int err = _safer_ecb_decrypt(block_in, block_out, skey); | ||||
|     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -329,8 +329,9 @@ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric | ||||
|   @param pt The input plaintext (16 bytes) | ||||
|   @param ct The output ciphertext (16 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    unsigned char b[16]; | ||||
|    int x; | ||||
| @ -384,6 +385,7 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|    zeromem(b, sizeof(b)); | ||||
| #endif | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -391,8 +393,9 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke | ||||
|   @param ct The input ciphertext (16 bytes) | ||||
|   @param pt The output plaintext (16 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    unsigned char b[16]; | ||||
|    int x; | ||||
| @ -446,6 +449,7 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|    zeromem(b, sizeof(b)); | ||||
| #endif | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
| @ -138,11 +138,12 @@ static unsigned ig_func(unsigned w, int *kp, unsigned char *key) | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    unsigned w1,w2,w3,w4,tmp,tmp1; | ||||
| @ -183,13 +184,16 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ | ||||
|    ct[2] = (w2>>8)&255; ct[3] = w2&255; | ||||
|    ct[4] = (w3>>8)&255; ct[5] = w3&255; | ||||
|    ct[6] = (w4>>8)&255; ct[7] = w4&255; | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    _skipjack_ecb_encrypt(pt, ct, skey); | ||||
|    int err = _skipjack_ecb_encrypt(pt, ct, skey); | ||||
|    burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -198,11 +202,12 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|    unsigned w1,w2,w3,w4,tmp; | ||||
| @ -247,13 +252,16 @@ void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ | ||||
|    pt[2] = (w2>>8)&255; pt[3] = w2&255; | ||||
|    pt[4] = (w3>>8)&255; pt[5] = w3&255; | ||||
|    pt[6] = (w4>>8)&255; pt[7] = w4&255; | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    _skipjack_ecb_decrypt(ct, pt, skey); | ||||
|    int err = _skipjack_ecb_decrypt(ct, pt, skey); | ||||
|    burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -465,11 +465,12 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri | ||||
|   @param pt The input plaintext (16 bytes) | ||||
|   @param ct The output ciphertext (16 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #else | ||||
| void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; | ||||
| @ -519,13 +520,16 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k | ||||
|     /* store output */ | ||||
|     STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); | ||||
|     STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); | ||||
| 
 | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    _twofish_ecb_encrypt(pt, ct, skey); | ||||
|    int err = _twofish_ecb_encrypt(pt, ct, skey); | ||||
|    burn_stack(sizeof(ulong32) * 10 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| @ -534,11 +538,12 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k | ||||
|   @param ct The input ciphertext (16 bytes) | ||||
|   @param pt The output plaintext (16 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #else | ||||
| void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| #endif | ||||
| { | ||||
|     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; | ||||
| @ -591,13 +596,15 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k | ||||
|     /* store */ | ||||
|     STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); | ||||
|     STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); | ||||
|     return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LTC_CLEAN_STACK | ||||
| void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    _twofish_ecb_decrypt(ct, pt, skey); | ||||
|    int err =_twofish_ecb_decrypt(ct, pt, skey); | ||||
|    burn_stack(sizeof(ulong32) * 10 + sizeof(int)); | ||||
|    return err; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -71,8 +71,9 @@ int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k | ||||
|   @param pt The input plaintext (8 bytes) | ||||
|   @param ct The output ciphertext (8 bytes) | ||||
|   @param skey The key as scheduled | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) | ||||
| { | ||||
|    unsigned long y, z; | ||||
|    int r; | ||||
| @ -98,6 +99,7 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | ||||
|    } | ||||
|    STORE32L(y, &ct[0]); | ||||
|    STORE32L(z, &ct[4]); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| @ -105,8 +107,9 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | ||||
|   @param ct The input ciphertext (8 bytes) | ||||
|   @param pt The output plaintext (8 bytes) | ||||
|   @param skey The key as scheduled  | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) | ||||
| { | ||||
|    unsigned long y, z; | ||||
|    int r; | ||||
| @ -132,6 +135,7 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key | ||||
|    } | ||||
|    STORE32L(y, &pt[0]); | ||||
|    STORE32L(z, &pt[4]); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | ||||
| @ -22,6 +22,7 @@ | ||||
|    @param cipher     The index of the cipher desired | ||||
|    @param key        The secret key to use | ||||
|    @param keylen     The length of the secret key (octets) | ||||
|    @param uskey      A previously scheduled key [optional can be NULL] | ||||
|    @param nonce      The session nonce [use once] | ||||
|    @param noncelen   The length of the nonce | ||||
|    @param header     The header for the session | ||||
| @ -36,6 +37,7 @@ | ||||
| */ | ||||
| int ccm_memory(int cipher, | ||||
|     const unsigned char *key,    unsigned long keylen, | ||||
|     symmetric_key       *uskey, | ||||
|     const unsigned char *nonce,  unsigned long noncelen, | ||||
|     const unsigned char *header, unsigned long headerlen, | ||||
|           unsigned char *pt,     unsigned long ptlen, | ||||
| @ -48,7 +50,9 @@ int ccm_memory(int cipher, | ||||
|    int            err; | ||||
|    unsigned long  len, L, x, y, z, CTRlen; | ||||
| 
 | ||||
|    if (uskey == NULL) { | ||||
|       LTC_ARGCHK(key    != NULL); | ||||
|    } | ||||
|    LTC_ARGCHK(nonce  != NULL); | ||||
|    if (headerlen > 0) { | ||||
|       LTC_ARGCHK(header != NULL); | ||||
| @ -85,15 +89,15 @@ int ccm_memory(int cipher, | ||||
| 
 | ||||
|    /* is there an accelerator? */ | ||||
|    if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { | ||||
|        cipher_descriptor[cipher].accel_ccm_memory( | ||||
|        return cipher_descriptor[cipher].accel_ccm_memory( | ||||
|            key,    keylen, | ||||
|            uskey, | ||||
|            nonce,  noncelen, | ||||
|            header, headerlen, | ||||
|            pt,     ptlen, | ||||
|            ct,  | ||||
|            tag,    taglen, | ||||
|            direction); | ||||
|       return CRYPT_OK; | ||||
|    } | ||||
| 
 | ||||
|    /* let's get the L value */ | ||||
| @ -114,6 +118,7 @@ int ccm_memory(int cipher, | ||||
|    } | ||||
| 
 | ||||
|    /* allocate mem for the symmetric key */ | ||||
|    if (uskey == NULL) { | ||||
|       skey = XMALLOC(sizeof(*skey)); | ||||
|       if (skey == NULL) { | ||||
|          return CRYPT_MEM; | ||||
| @ -124,6 +129,9 @@ int ccm_memory(int cipher, | ||||
|          XFREE(skey); | ||||
|          return err; | ||||
|       } | ||||
|    } else { | ||||
|       skey = uskey; | ||||
|    } | ||||
| 
 | ||||
|    /* form B_0 == flags | Nonce N | l(m) */ | ||||
|    x = 0; | ||||
| @ -154,7 +162,9 @@ int ccm_memory(int cipher, | ||||
|    } | ||||
| 
 | ||||
|    /* encrypt PAD */ | ||||
|    cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|        goto error; | ||||
|    } | ||||
| 
 | ||||
|    /* handle header */ | ||||
|    if (headerlen > 0) { | ||||
| @ -177,7 +187,9 @@ int ccm_memory(int cipher, | ||||
|       for (y = 0; y < headerlen; y++) { | ||||
|           if (x == 16) { | ||||
|              /* full block so let's encrypt it */ | ||||
|              cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|              if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|                 goto error; | ||||
|              } | ||||
|              x = 0; | ||||
|           } | ||||
|           PAD[x++] ^= header[y]; | ||||
| @ -185,7 +197,9 @@ int ccm_memory(int cipher, | ||||
| 
 | ||||
|       /* remainder? */ | ||||
|       if (x != 0) { | ||||
|          cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|          if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|             goto error; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
| @ -219,14 +233,18 @@ int ccm_memory(int cipher, | ||||
|                     ctr[z] = (ctr[z] + 1) & 255; | ||||
|                     if (ctr[z]) break; | ||||
|                 } | ||||
|                 cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); | ||||
|                 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | ||||
|                    goto error; | ||||
|                 } | ||||
| 
 | ||||
|                 /* xor the PT against the pad first */ | ||||
|                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { | ||||
|                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z])); | ||||
|                     *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); | ||||
|                 } | ||||
|                 cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|                 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|                    goto error; | ||||
|                 } | ||||
|              } | ||||
|          } else { | ||||
|              for (; y < (ptlen & ~15); y += 16) { | ||||
| @ -235,14 +253,18 @@ int ccm_memory(int cipher, | ||||
|                     ctr[z] = (ctr[z] + 1) & 255; | ||||
|                     if (ctr[z]) break; | ||||
|                 } | ||||
|                 cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); | ||||
|                 if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | ||||
|                    goto error; | ||||
|                 } | ||||
| 
 | ||||
|                 /* xor the PT against the pad last */ | ||||
|                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { | ||||
|                     *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); | ||||
|                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z])); | ||||
|                 } | ||||
|                 cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|                 if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|                    goto error; | ||||
|                 } | ||||
|              } | ||||
|          } | ||||
|      } | ||||
| @ -255,7 +277,9 @@ int ccm_memory(int cipher, | ||||
|                  ctr[z] = (ctr[z] + 1) & 255; | ||||
|                  if (ctr[z]) break; | ||||
|              } | ||||
|              cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); | ||||
|              if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | ||||
|                 goto error; | ||||
|              } | ||||
|              CTRlen = 0; | ||||
|           } | ||||
| 
 | ||||
| @ -269,21 +293,30 @@ int ccm_memory(int cipher, | ||||
|           } | ||||
| 
 | ||||
|           if (x == 16) { | ||||
|              cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|              if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|                 goto error; | ||||
|              } | ||||
|              x = 0; | ||||
|           } | ||||
|           PAD[x++] ^= b; | ||||
|       } | ||||
|               | ||||
|       if (x != 0) { | ||||
|          cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey); | ||||
|          if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { | ||||
|             goto error; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    /* setup CTR for the TAG */ | ||||
|    ctr[14] = ctr[15] = 0x00; | ||||
|    cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { | ||||
|       goto error; | ||||
|    } | ||||
| 
 | ||||
|    if (skey != uskey) { | ||||
|       cipher_descriptor[cipher].done(skey); | ||||
|    } | ||||
| 
 | ||||
|    /* store the TAG */ | ||||
|    for (x = 0; x < 16 && x < *taglen; x++) { | ||||
| @ -296,10 +329,12 @@ int ccm_memory(int cipher, | ||||
|    zeromem(PAD,    sizeof(PAD)); | ||||
|    zeromem(CTRPAD, sizeof(CTRPAD)); | ||||
| #endif | ||||
| 
 | ||||
| error: | ||||
|    if (skey != uskey) { | ||||
|       XFREE(skey); | ||||
|    } | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -116,6 +116,7 @@ int ccm_test(void) | ||||
|   unsigned long taglen, x; | ||||
|   unsigned char buf[64], buf2[64], tag2[16], tag[16]; | ||||
|   int           err, idx; | ||||
|   symmetric_key skey; | ||||
| 
 | ||||
|   idx = find_cipher("aes"); | ||||
|   if (idx == -1) { | ||||
| @ -127,8 +128,13 @@ int ccm_test(void) | ||||
| 
 | ||||
|   for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { | ||||
|       taglen = tests[x].taglen; | ||||
|       if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) { | ||||
|          return err; | ||||
|       } | ||||
|        | ||||
|       if ((err = ccm_memory(idx, | ||||
|                             tests[x].key, 16, | ||||
|                             &skey, | ||||
|                             tests[x].nonce, tests[x].noncelen, | ||||
|                             tests[x].header, tests[x].headerlen, | ||||
|                             (unsigned char*)tests[x].pt, tests[x].ptlen, | ||||
| @ -146,6 +152,7 @@ int ccm_test(void) | ||||
| 
 | ||||
|       if ((err = ccm_memory(idx, | ||||
|                             tests[x].key, 16, | ||||
|                             NULL, | ||||
|                             tests[x].nonce, tests[x].noncelen, | ||||
|                             tests[x].header, tests[x].headerlen, | ||||
|                             buf2, tests[x].ptlen, | ||||
| @ -160,8 +167,7 @@ int ccm_test(void) | ||||
|       if (memcmp(tag2, tests[x].tag, tests[x].taglen)) { | ||||
|          return CRYPT_FAIL_TESTVECTOR; | ||||
|       } | ||||
|   | ||||
| 
 | ||||
|       cipher_descriptor[idx].done(&skey); | ||||
|   } | ||||
|   return CRYPT_OK; | ||||
| #endif | ||||
|  | ||||
| @ -62,7 +62,9 @@ int gcm_done(gcm_state *gcm, | ||||
|    gcm_mult_h(gcm, gcm->X); | ||||
| 
 | ||||
|    /* encrypt original counter */ | ||||
|    cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K); | ||||
|    if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    for (x = 0; x < 16 && x < *taglen; x++) { | ||||
|        tag[x] = gcm->buf[x] ^ gcm->X[x]; | ||||
|    } | ||||
|  | ||||
| @ -98,7 +98,9 @@ int gcm_init(gcm_state *gcm, int cipher, | ||||
| 
 | ||||
|    /* H = E(0) */ | ||||
|    zeromem(B, 16); | ||||
|    cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* setup state */ | ||||
|    zeromem(gcm->buf, sizeof(gcm->buf)); | ||||
|  | ||||
| @ -51,6 +51,7 @@ int gcm_memory(      int           cipher, | ||||
|     } | ||||
|   | ||||
|     if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { | ||||
|        return  | ||||
|          cipher_descriptor[cipher].accel_gcm_memory | ||||
|                                           (key,   keylen, | ||||
|                                            IV,    IVlen, | ||||
| @ -59,7 +60,6 @@ int gcm_memory(      int           cipher, | ||||
|                                            ct, | ||||
|                                            tag,   taglen, | ||||
|                                            direction); | ||||
|        return CRYPT_OK; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -62,7 +62,9 @@ int gcm_process(gcm_state *gcm, | ||||
|           if (++gcm->Y[y]) { break; } | ||||
|       } | ||||
|       /* encrypt the counter */ | ||||
|       cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);      | ||||
|       if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { | ||||
|          return err; | ||||
|       } | ||||
| 
 | ||||
|       gcm->buflen = 0; | ||||
|       gcm->mode   = GCM_MODE_TEXT; | ||||
| @ -89,7 +91,9 @@ int gcm_process(gcm_state *gcm, | ||||
|              for (y = 15; y >= 12; y--) { | ||||
|                  if (++gcm->Y[y]) { break; } | ||||
|              } | ||||
|              cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); | ||||
|              if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { | ||||
|                 return err; | ||||
|              } | ||||
|          } | ||||
|       } else { | ||||
|          for (x = 0; x < (ptlen & ~15); x += 16) { | ||||
| @ -105,7 +109,9 @@ int gcm_process(gcm_state *gcm, | ||||
|              for (y = 15; y >= 12; y--) { | ||||
|                  if (++gcm->Y[y]) { break; } | ||||
|              } | ||||
|              cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); | ||||
|              if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { | ||||
|                 return err; | ||||
|              } | ||||
|          } | ||||
|      } | ||||
|    } | ||||
| @ -121,7 +127,9 @@ int gcm_process(gcm_state *gcm, | ||||
|           for (y = 15; y >= 12; y--) { | ||||
|               if (++gcm->Y[y]) { break; } | ||||
|           } | ||||
|           cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K); | ||||
|           if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|           gcm->buflen = 0; | ||||
|        } | ||||
| 
 | ||||
|  | ||||
| @ -51,7 +51,9 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) | ||||
|    for (x = 0; x < ocb->block_len; x++) { | ||||
|        tmp[x] = ct[x] ^ Z[x]; | ||||
|    } | ||||
|    cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key); | ||||
|    if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    for (x = 0; x < ocb->block_len; x++) { | ||||
|        pt[x] ^= Z[x]; | ||||
|    } | ||||
|  | ||||
| @ -51,7 +51,9 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) | ||||
|    for (x = 0; x < ocb->block_len; x++) { | ||||
|        tmp[x] = pt[x] ^ Z[x]; | ||||
|    } | ||||
|    cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key); | ||||
|    if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    for (x = 0; x < ocb->block_len; x++) { | ||||
|        ct[x] ^= Z[x]; | ||||
|    } | ||||
|  | ||||
| @ -76,13 +76,17 @@ int ocb_init(ocb_state *ocb, int cipher, | ||||
|   | ||||
|    /* find L = E[0] */ | ||||
|    zeromem(ocb->L, ocb->block_len); | ||||
|    cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* find R = E[N xor L] */ | ||||
|    for (x = 0; x < ocb->block_len; x++) { | ||||
|        ocb->R[x] = ocb->L[x] ^ nonce[x]; | ||||
|    } | ||||
|    cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* find Ls[i] = L << i for i == 0..31 */ | ||||
|    XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); | ||||
|  | ||||
| @ -84,7 +84,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, | ||||
|    } | ||||
| 
 | ||||
|    /* Y[m] = E(X[m])) */ | ||||
|    cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key); | ||||
|    if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) { | ||||
|       goto error; | ||||
|    } | ||||
| 
 | ||||
|    if (mode == 1) { | ||||
|       /* decrypt mode, so let's xor it first */ | ||||
| @ -113,7 +115,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, | ||||
|    } | ||||
|     | ||||
|    /* encrypt checksum, er... tag!! */ | ||||
|    cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key); | ||||
|    if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) { | ||||
|       goto error; | ||||
|    } | ||||
|    cipher_descriptor[ocb->cipher].done(&ocb->key); | ||||
| 
 | ||||
|    /* now store it */ | ||||
| @ -128,12 +132,12 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, | ||||
|    zeromem(Z, MAXBLOCKSIZE); | ||||
|    zeromem(ocb, sizeof(*ocb)); | ||||
| #endif | ||||
|     | ||||
| error:    | ||||
|    XFREE(X); | ||||
|    XFREE(Y); | ||||
|    XFREE(Z); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -16,8 +16,8 @@ extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /* version */ | ||||
| #define CRYPT   0x0106 | ||||
| #define SCRYPT  "1.06" | ||||
| #define CRYPT   0x0107 | ||||
| #define SCRYPT  "1.07" | ||||
| 
 | ||||
| /* max size of either a cipher/hash block or symmetric key [largest of the two] */ | ||||
| #define MAXBLOCKSIZE  128 | ||||
|  | ||||
| @ -54,6 +54,14 @@ int   XMEMCMP(const void *s1, const void *s2, size_t n); | ||||
|    #define LTC_FAST_TYPE    unsigned long | ||||
| #endif | ||||
| 
 | ||||
| /* detect PPC32 */ | ||||
| #if defined(LTC_PPC32) | ||||
|    #define ENDIAN_BIG | ||||
|    #define ENDIAN_32BITWORD | ||||
|    #define LTC_FAST | ||||
|    #define LTC_FAST_TYPE    unsigned long | ||||
| #endif    | ||||
| 
 | ||||
| /* detect sparc and sparc64 */ | ||||
| #if defined(__sparc__) | ||||
|   #define ENDIAN_BIG | ||||
|  | ||||
| @ -263,14 +263,16 @@ extern struct ltc_cipher_descriptor { | ||||
|       @param pt      The plaintext | ||||
|       @param ct      [out] The ciphertext | ||||
|       @param skey    The scheduled key | ||||
|       @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
|    int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
|    /** Decrypt a block
 | ||||
|       @param ct      The ciphertext | ||||
|       @param pt      [out] The plaintext | ||||
|       @param skey    The scheduled key | ||||
|       @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
|    int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
|    /** Test the block cipher
 | ||||
|        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled | ||||
|    */ | ||||
| @ -293,16 +295,18 @@ extern struct ltc_cipher_descriptor { | ||||
|        @param ct      Ciphertext | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); | ||||
|    int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated ECB decryption 
 | ||||
|        @param pt      Plaintext | ||||
|        @param ct      Ciphertext | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); | ||||
|    int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CBC encryption 
 | ||||
|        @param pt      Plaintext | ||||
| @ -310,8 +314,9 @@ extern struct ltc_cipher_descriptor { | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param IV      The initial value (input/output) | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); | ||||
|    int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CBC decryption 
 | ||||
|        @param pt      Plaintext | ||||
| @ -319,8 +324,9 @@ extern struct ltc_cipher_descriptor { | ||||
|        @param blocks  The number of complete blocks to process | ||||
|        @param IV      The initial value (input/output) | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); | ||||
|    int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CTR encryption 
 | ||||
|        @param pt      Plaintext | ||||
| @ -329,12 +335,14 @@ extern struct ltc_cipher_descriptor { | ||||
|        @param IV      The initial value (input/output) | ||||
|        @param mode    little or big endian counter (mode=0 or mode=1) | ||||
|        @param skey    The scheduled key context | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); | ||||
|    int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); | ||||
| 
 | ||||
|    /** Accelerated CCM packet (one-shot)
 | ||||
|        @param key        The secret key to use | ||||
|        @param keylen     The length of the secret key (octets) | ||||
|        @param uskey      A previously scheduled key [optional can be NULL] | ||||
|        @param nonce      The session nonce [use once] | ||||
|        @param noncelen   The length of the nonce | ||||
|        @param header     The header for the session | ||||
| @ -347,8 +355,9 @@ extern struct ltc_cipher_descriptor { | ||||
|        @param direction  Encrypt or Decrypt direction (0 or 1) | ||||
|        @return CRYPT_OK if successful | ||||
|    */ | ||||
|    void (*accel_ccm_memory)( | ||||
|    int (*accel_ccm_memory)( | ||||
|        const unsigned char *key,    unsigned long keylen, | ||||
|        symmetric_key       *uskey, | ||||
|        const unsigned char *nonce,  unsigned long noncelen, | ||||
|        const unsigned char *header, unsigned long headerlen, | ||||
|              unsigned char *pt,     unsigned long ptlen, | ||||
| @ -369,8 +378,9 @@ extern struct ltc_cipher_descriptor { | ||||
|        @param tag               [out] The MAC tag | ||||
|        @param taglen            [in/out] The MAC tag length | ||||
|        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) | ||||
|        @return CRYPT_OK on success | ||||
|    */ | ||||
|    void (*accel_gcm_memory)( | ||||
|    int (*accel_gcm_memory)( | ||||
|        const unsigned char *key,    unsigned long keylen, | ||||
|        const unsigned char *IV,     unsigned long IVlen, | ||||
|        const unsigned char *adata,  unsigned long adatalen, | ||||
| @ -382,8 +392,8 @@ extern struct ltc_cipher_descriptor { | ||||
| 
 | ||||
| #ifdef BLOWFISH | ||||
| int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int blowfish_test(void); | ||||
| void blowfish_done(symmetric_key *skey); | ||||
| int blowfish_keysize(int *keysize); | ||||
| @ -392,8 +402,8 @@ extern const struct ltc_cipher_descriptor blowfish_desc; | ||||
| 
 | ||||
| #ifdef RC5 | ||||
| int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rc5_test(void); | ||||
| void rc5_done(symmetric_key *skey); | ||||
| int rc5_keysize(int *keysize); | ||||
| @ -402,8 +412,8 @@ extern const struct ltc_cipher_descriptor rc5_desc; | ||||
| 
 | ||||
| #ifdef RC6 | ||||
| int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rc6_test(void); | ||||
| void rc6_done(symmetric_key *skey); | ||||
| int rc6_keysize(int *keysize); | ||||
| @ -412,8 +422,8 @@ extern const struct ltc_cipher_descriptor rc6_desc; | ||||
| 
 | ||||
| #ifdef RC2 | ||||
| int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rc2_test(void); | ||||
| void rc2_done(symmetric_key *skey); | ||||
| int rc2_keysize(int *keysize); | ||||
| @ -422,8 +432,8 @@ extern const struct ltc_cipher_descriptor rc2_desc; | ||||
| 
 | ||||
| #ifdef SAFERP | ||||
| int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int saferp_test(void); | ||||
| void saferp_done(symmetric_key *skey); | ||||
| int saferp_keysize(int *keysize); | ||||
| @ -435,8 +445,8 @@ int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmet | ||||
| int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); | ||||
| void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); | ||||
| int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); | ||||
| int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); | ||||
| int safer_k64_test(void); | ||||
| int safer_sk64_test(void); | ||||
| int safer_sk128_test(void); | ||||
| @ -461,13 +471,13 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer | ||||
| #define aes_enc_keysize         rijndael_enc_keysize | ||||
| 
 | ||||
| int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int rijndael_test(void); | ||||
| void rijndael_done(symmetric_key *skey); | ||||
| int rijndael_keysize(int *keysize); | ||||
| int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void rijndael_enc_done(symmetric_key *skey); | ||||
| int rijndael_enc_keysize(int *keysize); | ||||
| extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; | ||||
| @ -476,8 +486,8 @@ extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; | ||||
| 
 | ||||
| #ifdef XTEA | ||||
| int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int xtea_test(void); | ||||
| void xtea_done(symmetric_key *skey); | ||||
| int xtea_keysize(int *keysize); | ||||
| @ -486,8 +496,8 @@ extern const struct ltc_cipher_descriptor xtea_desc; | ||||
| 
 | ||||
| #ifdef TWOFISH | ||||
| int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int twofish_test(void); | ||||
| void twofish_done(symmetric_key *skey); | ||||
| int twofish_keysize(int *keysize); | ||||
| @ -496,14 +506,14 @@ extern const struct ltc_cipher_descriptor twofish_desc; | ||||
| 
 | ||||
| #ifdef DES | ||||
| int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int des_test(void); | ||||
| void des_done(symmetric_key *skey); | ||||
| int des_keysize(int *keysize); | ||||
| int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int des3_test(void); | ||||
| void des3_done(symmetric_key *skey); | ||||
| int des3_keysize(int *keysize); | ||||
| @ -512,8 +522,8 @@ extern const struct ltc_cipher_descriptor des_desc, des3_desc; | ||||
| 
 | ||||
| #ifdef CAST5 | ||||
| int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int cast5_test(void); | ||||
| void cast5_done(symmetric_key *skey); | ||||
| int cast5_keysize(int *keysize); | ||||
| @ -522,8 +532,8 @@ extern const struct ltc_cipher_descriptor cast5_desc; | ||||
| 
 | ||||
| #ifdef NOEKEON | ||||
| int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int noekeon_test(void); | ||||
| void noekeon_done(symmetric_key *skey); | ||||
| int noekeon_keysize(int *keysize); | ||||
| @ -532,8 +542,8 @@ extern const struct ltc_cipher_descriptor noekeon_desc; | ||||
| 
 | ||||
| #ifdef SKIPJACK | ||||
| int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int skipjack_test(void); | ||||
| void skipjack_done(symmetric_key *skey); | ||||
| int skipjack_keysize(int *keysize); | ||||
| @ -542,8 +552,8 @@ extern const struct ltc_cipher_descriptor skipjack_desc; | ||||
| 
 | ||||
| #ifdef KHAZAD | ||||
| int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int khazad_test(void); | ||||
| void khazad_done(symmetric_key *skey); | ||||
| int khazad_keysize(int *keysize); | ||||
| @ -552,8 +562,8 @@ extern const struct ltc_cipher_descriptor khazad_desc; | ||||
| 
 | ||||
| #ifdef ANUBIS | ||||
| int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||
| void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||
| int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||
| int anubis_test(void); | ||||
| void anubis_done(symmetric_key *skey); | ||||
| int anubis_keysize(int *keysize); | ||||
|  | ||||
| @ -186,6 +186,9 @@ | ||||
| /* Include RSA support */ | ||||
| #define MRSA | ||||
| 
 | ||||
| /* Include Katja (an Rabin variant like RSA) */ | ||||
| // #define MKAT 
 | ||||
| 
 | ||||
| /* Digital Signature Algorithm */ | ||||
| #define MDSA | ||||
| /* Max diff between group and modulus size in bytes */ | ||||
| @ -200,11 +203,13 @@ | ||||
| /* #define LTC_ECC_TIMING_RESISTANT */ | ||||
| 
 | ||||
| /* Supported ECC Key Sizes */ | ||||
| #ifndef LTC_NO_CURVES | ||||
|    #define ECC192 | ||||
|    #define ECC224 | ||||
|    #define ECC256 | ||||
|    #define ECC384 | ||||
|    #define ECC521 | ||||
| #endif | ||||
| 
 | ||||
| /* Include the MPI functionality?  (required by the PK algorithms) */ | ||||
| #define MPI | ||||
| @ -240,6 +245,8 @@ | ||||
| 
 | ||||
| #define LTC_MUTEX_GLOBAL(x)   pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; | ||||
| #define LTC_MUTEX_PROTO(x)    extern pthread_mutex_t x; | ||||
| #define LTC_MUTEX_TYPE(x)     pthread_mutex_t x; | ||||
| #define LTC_MUTEX_INIT(x)     pthread_mutex_init(x, NULL); | ||||
| #define LTC_MUTEX_LOCK(x)     pthread_mutex_lock(x); | ||||
| #define LTC_MUTEX_UNLOCK(x)   pthread_mutex_unlock(x); | ||||
| 
 | ||||
| @ -248,6 +255,8 @@ | ||||
| /* default no functions */ | ||||
| #define LTC_MUTEX_GLOBAL(x) | ||||
| #define LTC_MUTEX_PROTO(x) | ||||
| #define LTC_MUTEX_TYPE(x) | ||||
| #define LTC_MUTEX_INIT(x) | ||||
| #define LTC_MUTEX_LOCK(x) | ||||
| #define LTC_MUTEX_UNLOCK(x) | ||||
| 
 | ||||
|  | ||||
| @ -200,6 +200,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, | ||||
| 
 | ||||
| int ccm_memory(int cipher, | ||||
|     const unsigned char *key,    unsigned long keylen, | ||||
|     symmetric_key       *uskey, | ||||
|     const unsigned char *nonce,  unsigned long noncelen, | ||||
|     const unsigned char *header, unsigned long headerlen, | ||||
|           unsigned char *pt,     unsigned long ptlen, | ||||
|  | ||||
| @ -285,6 +285,50 @@ static inline unsigned RORc(unsigned word, const int i) | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #elif defined(LTC_PPC32) | ||||
| 
 | ||||
| static inline unsigned ROL(unsigned word, int i) | ||||
| { | ||||
|    asm ("rotlw %0,%0,%2" | ||||
|       :"=r" (word) | ||||
|       :"0" (word),"r" (i)); | ||||
|    return word; | ||||
| } | ||||
| 
 | ||||
| static inline unsigned ROR(unsigned word, int i) | ||||
| { | ||||
|    asm ("rotlw %0,%0,%2" | ||||
|       :"=r" (word) | ||||
|       :"0" (word),"r" (32-i)); | ||||
|    return word; | ||||
| } | ||||
| 
 | ||||
| #ifndef LTC_NO_ROLC | ||||
| 
 | ||||
| static inline unsigned ROLc(unsigned word, const int i) | ||||
| { | ||||
|    asm ("rotlwi %0,%0,%2" | ||||
|       :"=r" (word) | ||||
|       :"0" (word),"I" (i)); | ||||
|    return word; | ||||
| } | ||||
| 
 | ||||
| static inline unsigned RORc(unsigned word, const int i) | ||||
| { | ||||
|    asm ("rotrwi %0,%0,%2" | ||||
|       :"=r" (word) | ||||
|       :"0" (word),"I" (i)); | ||||
|    return word; | ||||
| } | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #define ROLc ROL | ||||
| #define RORc ROR | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| /* rotates the hard way */ | ||||
|  | ||||
| @ -11,6 +11,10 @@ | ||||
|    typedef void ecc_point; | ||||
| #endif | ||||
| 
 | ||||
| #ifndef MRSA | ||||
|    typedef void rsa_key; | ||||
| #endif | ||||
| 
 | ||||
| /** math descriptor */ | ||||
| typedef struct { | ||||
|    /** Name of the math provider */ | ||||
| @ -42,6 +46,13 @@ typedef struct { | ||||
| 
 | ||||
| /* ---- data movement ---- */ | ||||
| 
 | ||||
|    /** negate
 | ||||
|       @param   src   The number to negate | ||||
|       @param   dst   The destination | ||||
|       @return CRYPT_OK on success | ||||
|    */ | ||||
|    int (*neg)(void *src, void *dst); | ||||
|     | ||||
|    /** copy 
 | ||||
|       @param   src   The number to copy from | ||||
|       @param   dst   The number to write to  | ||||
| @ -339,11 +350,22 @@ typedef struct { | ||||
| 
 | ||||
| /* ---- (optional) rsa optimized math (for internal CRT) ---- */ | ||||
| 
 | ||||
|    /** RSA Key Generation 
 | ||||
|        @param prng     An active PRNG state | ||||
|        @param wprng    The index of the PRNG desired | ||||
|        @param size     The size of the modulus (key size) desired (octets) | ||||
|        @param e        The "e" value (public key).  e==65537 is a good choice | ||||
|        @param key      [out] Destination of a newly created private key pair | ||||
|        @return CRYPT_OK if successful, upon error all allocated ram is freed | ||||
|     */ | ||||
|     int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); | ||||
|     | ||||
| 
 | ||||
|    /** RSA exponentiation
 | ||||
|       @param in       The octet array representing the base | ||||
|       @param inlen    The length of the input | ||||
|       @param out      The destination (to be stored in an octet array format) | ||||
|       @param outlen   The length of the output buffer and the resulting size (zero padded to the size of the modulus | ||||
|       @param outlen   The length of the output buffer and the resulting size (zero padded to the size of the modulus) | ||||
|       @param which    PK_PUBLIC for public RSA and PK_PRIVATE for private RSA | ||||
|       @param key      The RSA key to use  | ||||
|       @return CRYPT_OK on success | ||||
| @ -375,7 +397,9 @@ extern const ltc_math_descriptor tfm_desc; | ||||
| #define mp_init_multi                ltc_init_multi | ||||
| #define mp_clear(a)                  ltc_mp.deinit(a) | ||||
| #define mp_clear_multi               ltc_deinit_multi | ||||
| #define mp_init_copy(a, b)           ltc_mp.init_copy(a, b) | ||||
| 
 | ||||
| #define mp_neg(a, b)                 ltc_mp.neg(a, b) | ||||
| #define mp_copy(a, b)                ltc_mp.copy(a, b) | ||||
| 
 | ||||
| #define mp_set(a, b)                 ltc_mp.set_int(a, b) | ||||
|  | ||||
| @ -73,9 +73,70 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); | ||||
|                          | ||||
| #endif | ||||
| 
 | ||||
| /* ---- Katja ---- */ | ||||
| #ifdef MKAT | ||||
| 
 | ||||
| /* Min and Max KAT key sizes (in bits) */ | ||||
| #define MIN_KAT_SIZE 1024 | ||||
| #define MAX_KAT_SIZE 4096 | ||||
| 
 | ||||
| /** Katja PKCS style key */ | ||||
| typedef struct KAT_key { | ||||
|     /** Type of key, PK_PRIVATE or PK_PUBLIC */ | ||||
|     int type; | ||||
|     /** The private exponent */ | ||||
|     void *d;  | ||||
|     /** The modulus */ | ||||
|     void *N;  | ||||
|     /** The p factor of N */ | ||||
|     void *p;  | ||||
|     /** The q factor of N */ | ||||
|     void *q;  | ||||
|     /** The 1/q mod p CRT param */ | ||||
|     void *qP;  | ||||
|     /** The d mod (p - 1) CRT param */ | ||||
|     void *dP;  | ||||
|     /** The d mod (q - 1) CRT param */ | ||||
|     void *dQ; | ||||
|     /** The pq param */ | ||||
|     void *pq; | ||||
| } katja_key; | ||||
| 
 | ||||
| int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); | ||||
| 
 | ||||
| int katja_exptmod(const unsigned char *in,   unsigned long inlen, | ||||
|                         unsigned char *out,  unsigned long *outlen, int which, | ||||
|                         katja_key *key); | ||||
| 
 | ||||
| void katja_free(katja_key *key); | ||||
| 
 | ||||
| /* These use PKCS #1 v2.0 padding */ | ||||
| int katja_encrypt_key(const unsigned char *in,     unsigned long inlen, | ||||
|                             unsigned char *out,    unsigned long *outlen, | ||||
|                       const unsigned char *lparam, unsigned long lparamlen, | ||||
|                       prng_state *prng, int prng_idx, int hash_idx, katja_key *key); | ||||
|                                          | ||||
| int katja_decrypt_key(const unsigned char *in,       unsigned long inlen, | ||||
|                             unsigned char *out,      unsigned long *outlen,  | ||||
|                       const unsigned char *lparam,   unsigned long lparamlen, | ||||
|                             int            hash_idx, int *stat, | ||||
|                             katja_key       *key); | ||||
| 
 | ||||
| /* PKCS #1 import/export */ | ||||
| int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); | ||||
| int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); | ||||
|                          | ||||
| #endif | ||||
| 
 | ||||
| /* ---- ECC Routines ---- */ | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /* size of our temp buffers for exported keys */ | ||||
| #define ECC_BUF_SIZE 256 | ||||
| 
 | ||||
| /* max private key size */ | ||||
| #define ECC_MAXSIZE  66 | ||||
| 
 | ||||
| /** Structure defines a NIST GF(p) curve */ | ||||
| typedef struct { | ||||
|    /** The size of the curve in octets */ | ||||
| @ -104,8 +165,10 @@ typedef struct { | ||||
| typedef struct { | ||||
|     /** The x co-ordinate */ | ||||
|     void *x; | ||||
| 
 | ||||
|     /** The y co-ordinate */ | ||||
|     void *y; | ||||
| 
 | ||||
|     /** The z co-ordinate */ | ||||
|     void *z; | ||||
| } ecc_point; | ||||
| @ -114,10 +177,13 @@ typedef struct { | ||||
| typedef struct { | ||||
|     /** Type of key, PK_PRIVATE or PK_PUBLIC */ | ||||
|     int type; | ||||
| 
 | ||||
|     /** Index into the ltc_ecc_sets[] for the parameters of this curve */ | ||||
|     int idx; | ||||
| 
 | ||||
|     /** The public key */ | ||||
|     ecc_point pubkey; | ||||
| 
 | ||||
|     /** The private key */ | ||||
|     void *k; | ||||
| } ecc_key; | ||||
| @ -158,14 +224,19 @@ int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen, | ||||
| /* low level functions */ | ||||
| ecc_point *ltc_ecc_new_point(void); | ||||
| void       ltc_ecc_del_point(ecc_point *p); | ||||
| int        ltc_ecc_is_valid_idx(int n); | ||||
| 
 | ||||
| 
 | ||||
| /* point ops (mp == montgomery digit) */ | ||||
| /* R = 2P */ | ||||
| int ltc_ecc_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); | ||||
| int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); | ||||
| 
 | ||||
| /* R = P + Q */ | ||||
| int ltc_ecc_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); | ||||
| int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); | ||||
| 
 | ||||
| /* R = kG */ | ||||
| int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); | ||||
| 
 | ||||
| /* map P to affine from projective */ | ||||
| int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); | ||||
| 
 | ||||
| @ -177,16 +248,22 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); | ||||
| typedef struct { | ||||
|    /** The key type, PK_PRIVATE or PK_PUBLIC */ | ||||
|    int type;  | ||||
| 
 | ||||
|    /** The order of the sub-group used in octets */ | ||||
|    int qord; | ||||
| 
 | ||||
|    /** The generator  */ | ||||
|    void *g; | ||||
| 
 | ||||
|    /** The prime used to generate the sub-group */ | ||||
|    void *q; | ||||
| 
 | ||||
|    /** The large prime that generats the field the contains the sub-group */ | ||||
|    void *p; | ||||
| 
 | ||||
|    /** The private key */ | ||||
|    void *x; | ||||
| 
 | ||||
|    /** The public key */ | ||||
|    void *y; | ||||
| } dsa_key; | ||||
| @ -194,7 +271,6 @@ typedef struct { | ||||
| int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); | ||||
| void dsa_free(dsa_key *key); | ||||
| 
 | ||||
| 
 | ||||
| int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen, | ||||
|                                    void *r,   void *s, | ||||
|                                prng_state *prng, int wprng, dsa_key *key); | ||||
| @ -211,12 +287,24 @@ int dsa_verify_hash(const unsigned char *sig,  unsigned long siglen, | ||||
|                     const unsigned char *hash, unsigned long hashlen,  | ||||
|                           int           *stat, dsa_key       *key); | ||||
| 
 | ||||
| int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen, | ||||
|                           unsigned char *out,  unsigned long *outlen,  | ||||
|                           prng_state *prng, int wprng, int hash,  | ||||
|                           dsa_key *key); | ||||
|                        | ||||
| int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||
|                           unsigned char *out, unsigned long *outlen,  | ||||
|                           dsa_key *key); | ||||
|                            | ||||
| int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); | ||||
| 
 | ||||
| int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); | ||||
| 
 | ||||
| int dsa_verify_key(dsa_key *key, int *stat); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int dsa_shared_secret(void          *private_key, void *base, | ||||
|                       dsa_key       *public_key, | ||||
|                       unsigned char *out,         unsigned long *outlen); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LTC_DER | ||||
| @ -239,7 +327,7 @@ enum { | ||||
| }; | ||||
| 
 | ||||
| /** A LTC ASN.1 list type */ | ||||
| typedef struct { | ||||
| typedef struct ltc_asn1_list_ { | ||||
|    /** The LTC ASN.1 enumerated type identifier */ | ||||
|    int           type; | ||||
|    /** The data to encode or place for decoding */ | ||||
| @ -248,6 +336,8 @@ typedef struct { | ||||
|    unsigned long size; | ||||
|    /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ | ||||
|    int           used; | ||||
|    /** prev/next entry in the list */ | ||||
|    struct ltc_asn1_list_ *prev, *next, *child, *parent; | ||||
| } ltc_asn1_list; | ||||
| 
 | ||||
| #define LTC_SET_ASN1(list, index, Type, Data, Size)  \ | ||||
| @ -270,10 +360,16 @@ int der_decode_sequence(const unsigned char *in,   unsigned long  inlen, | ||||
| int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, | ||||
|                         unsigned long *outlen); | ||||
| 
 | ||||
| /* VA list handy helpers */ | ||||
| /* VA list handy helpers with triplets of <type, size, data> */ | ||||
| int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); | ||||
| int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); | ||||
| 
 | ||||
| /* handle unknown list decoder */ | ||||
| int  der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); | ||||
| void der_free_sequence_flexi(ltc_asn1_list *list); | ||||
| 
 | ||||
| void der_sequence_free(ltc_asn1_list *in); | ||||
| 
 | ||||
| /* INTEGER */ | ||||
| int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); | ||||
| int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); | ||||
|  | ||||
| @ -3,8 +3,8 @@ | ||||
| /* ===> PKCS #1 -- RSA Cryptography <=== */ | ||||
| #ifdef PKCS_1 | ||||
| 
 | ||||
| int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, | ||||
|                       int            hash_idx, | ||||
| int pkcs_1_mgf1(      int            hash_idx, | ||||
|                 const unsigned char *seed, unsigned long seedlen, | ||||
|                       unsigned char *mask, unsigned long masklen); | ||||
| 
 | ||||
| int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); | ||||
|  | ||||
| @ -4,6 +4,7 @@ struct yarrow_prng { | ||||
|     int                   cipher, hash; | ||||
|     unsigned char         pool[MAXBLOCKSIZE]; | ||||
|     symmetric_CTR         ctr; | ||||
|     LTC_MUTEX_TYPE(prng_lock) | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| @ -28,6 +29,7 @@ struct fortuna_prng { | ||||
|                   wd;             | ||||
| 
 | ||||
|     ulong64       reset_cnt;  /* number of times we have reset */ | ||||
|     LTC_MUTEX_TYPE(prng_lock) | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
|  | ||||
| @ -61,7 +61,9 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) | ||||
|    } | ||||
| 
 | ||||
|    /* encrypt it */ | ||||
|    cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key); | ||||
|    if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    cipher_descriptor[omac->cipher_idx].done(&omac->key); | ||||
|   | ||||
|    /* output it */ | ||||
|  | ||||
| @ -63,7 +63,9 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l | ||||
| 
 | ||||
|    /* first calc L which is Ek(0) */ | ||||
|    zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); | ||||
|    cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* now do the mults, whoopy! */ | ||||
|    for (x = 0; x < 2; x++) { | ||||
|  | ||||
| @ -49,7 +49,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) | ||||
|               *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); | ||||
|           } | ||||
|           in += 16; | ||||
|           cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key); | ||||
|           if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|       } | ||||
|       inlen -= x; | ||||
|     } | ||||
| @ -61,7 +63,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) | ||||
|           for (x = 0; x < (unsigned long)omac->blklen; x++) { | ||||
|               omac->block[x] ^= omac->prev[x]; | ||||
|           } | ||||
|           cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key); | ||||
|           if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|           omac->buflen = 0; | ||||
|        } | ||||
| 
 | ||||
|  | ||||
| @ -49,7 +49,9 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) | ||||
|    } | ||||
| 
 | ||||
|    /* encrypt it */ | ||||
|    cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key); | ||||
|    if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    cipher_descriptor[state->cipher_idx].done(&state->key); | ||||
| 
 | ||||
|    /* store it */ | ||||
|  | ||||
| @ -87,7 +87,9 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l | ||||
| 
 | ||||
|    /* find L = E[0] */ | ||||
|    zeromem(L, pmac->block_len); | ||||
|    cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key); | ||||
|    if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) { | ||||
|       goto error; | ||||
|    } | ||||
| 
 | ||||
|    /* find Ls[i] = L << i for i == 0..31 */ | ||||
|    XMEMCPY(pmac->Ls[0], L, pmac->block_len); | ||||
| @ -127,14 +129,15 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l | ||||
|     zeromem(pmac->block,    sizeof(pmac->block)); | ||||
|     zeromem(pmac->Li,       sizeof(pmac->Li)); | ||||
|     zeromem(pmac->checksum, sizeof(pmac->checksum)); | ||||
| 
 | ||||
|     err = CRYPT_OK; | ||||
| error: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|     zeromem(L, pmac->block_len); | ||||
| #endif | ||||
| 
 | ||||
|     XFREE(L); | ||||
| 
 | ||||
|     return CRYPT_OK; | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -50,7 +50,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) | ||||
|           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { | ||||
|               *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y])); | ||||
|           } | ||||
|           cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key); | ||||
|           if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { | ||||
|               *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y])); | ||||
|           } | ||||
| @ -67,7 +69,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) | ||||
|           for (x = 0; x < (unsigned long)pmac->block_len; x++) { | ||||
|                Z[x] = pmac->Li[x] ^ pmac->block[x]; | ||||
|           } | ||||
|           cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key); | ||||
|           if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|            } | ||||
|           for (x = 0; x < (unsigned long)pmac->block_len; x++) { | ||||
|               pmac->checksum[x] ^= Z[x]; | ||||
|           } | ||||
|  | ||||
| @ -65,6 +65,13 @@ static void deinit(void *a) | ||||
|    XFREE(a); | ||||
| } | ||||
| 
 | ||||
| static int neg(void *a, void *b) | ||||
| { | ||||
|    LTC_ARGCHK(a != NULL); | ||||
|    LTC_ARGCHK(b != NULL); | ||||
|    return mpi_to_ltc_error(mp_neg(a, b)); | ||||
| } | ||||
| 
 | ||||
| static int copy(void *a, void *b) | ||||
| { | ||||
|    LTC_ARGCHK(a != NULL); | ||||
| @ -379,6 +386,7 @@ const ltc_math_descriptor ltm_desc = { | ||||
|    &init_copy, | ||||
|    &deinit, | ||||
| 
 | ||||
|    &neg, | ||||
|    ©, | ||||
| 
 | ||||
|    &set_int, | ||||
| @ -420,10 +428,11 @@ const ltc_math_descriptor ltm_desc = { | ||||
|    &exptmod, | ||||
|    &isprime, | ||||
| 
 | ||||
|    NULL, | ||||
|    NULL, | ||||
|    NULL, | ||||
|    <c_ecc_mulmod, | ||||
|    <c_ecc_projective_add_point, | ||||
|    <c_ecc_map, | ||||
| 
 | ||||
|    NULL, | ||||
|    NULL | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -34,6 +34,7 @@ int ltc_init_multi(void **a, ...) | ||||
|           va_end(clean_list); | ||||
|           return CRYPT_MEM; | ||||
|        } | ||||
|        ++np; | ||||
|        cur = va_arg(args, void**); | ||||
|    } | ||||
|    va_end(args); | ||||
|  | ||||
| @ -59,6 +59,14 @@ static void deinit(void *a) | ||||
|    XFREE(a); | ||||
| } | ||||
| 
 | ||||
| static int neg(void *a, void *b) | ||||
| { | ||||
|    LTC_ARGCHK(a != NULL); | ||||
|    LTC_ARGCHK(b != NULL); | ||||
|    fp_neg(((fp_int*)a), ((fp_int*)b)); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| static int copy(void *a, void *b) | ||||
| { | ||||
|    LTC_ARGCHK(a != NULL); | ||||
| @ -390,6 +398,7 @@ const ltc_math_descriptor tfm_desc = { | ||||
|    &init_copy, | ||||
|    &deinit, | ||||
| 
 | ||||
|    &neg, | ||||
|    ©, | ||||
| 
 | ||||
|    &set_int, | ||||
| @ -431,10 +440,11 @@ const ltc_math_descriptor tfm_desc = { | ||||
|    &exptmod, | ||||
|    &isprime, | ||||
| 
 | ||||
|    NULL, | ||||
|    NULL, | ||||
|    NULL, | ||||
|    <c_ecc_mulmod, | ||||
|    <c_ecc_projective_add_point, | ||||
|    <c_ecc_map, | ||||
| 
 | ||||
|    NULL, | ||||
|    NULL | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -229,15 +229,18 @@ const char *crypt_build_settings = | ||||
| #if defined(MDSA) | ||||
|     "   DSA\n" | ||||
| #endif | ||||
| #if defined(MKAT) | ||||
|     "   Katja\n" | ||||
| #endif     | ||||
| 
 | ||||
|     "\nCompiler:\n" | ||||
| #if defined(WIN32) | ||||
|     "   WIN32 platform detected.\n" | ||||
| #endif | ||||
| #if defined(LBL_CYGWIN__) | ||||
| #if defined(__CYGWIN__) | ||||
|     "   CYGWIN Detected.\n" | ||||
| #endif | ||||
| #if defined(LBL_DJGPP__) | ||||
| #if defined(__DJGPP__) | ||||
|     "   DJGPP Detected.\n" | ||||
| #endif | ||||
| #if defined(_MSC_VER) | ||||
| @ -249,9 +252,12 @@ const char *crypt_build_settings = | ||||
| #if defined(INTEL_CC) | ||||
|     "   Intel C Compiler detected.\n" | ||||
| #endif | ||||
| #if defined(LBL_x86_64__) | ||||
| #if defined(__x86_64__) | ||||
|     "   x86-64 detected.\n" | ||||
| #endif | ||||
| #if defined(LTC_PPC32) | ||||
|     "   LTC_PPC32 defined \n" | ||||
| #endif     | ||||
| 
 | ||||
|     "\nVarious others: " | ||||
| #if defined(BASE64) | ||||
|  | ||||
| @ -59,11 +59,13 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s | ||||
| #endif | ||||
|     | ||||
|    if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { | ||||
|       cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); | ||||
|       return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); | ||||
|    } else { | ||||
|       while (len) { | ||||
|          /* decrypt */ | ||||
|          cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key); | ||||
|          if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { | ||||
|             return err; | ||||
|          } | ||||
| 
 | ||||
|          /* xor IV against plaintext */ | ||||
|          #if defined(LTC_FAST) | ||||
|  | ||||
| @ -53,7 +53,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
| #endif | ||||
| 
 | ||||
|    if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { | ||||
|       cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); | ||||
|       return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); | ||||
|    } else { | ||||
|       while (len) { | ||||
|          /* xor IV against plaintext */ | ||||
| @ -68,7 +68,9 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
| 	 #endif | ||||
| 
 | ||||
|          /* encrypt */ | ||||
|          cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key); | ||||
|          if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { | ||||
|             return err; | ||||
|          } | ||||
| 
 | ||||
|         /* store IV [ciphertext] for a future block */ | ||||
|          #if defined(LTC_FAST) | ||||
|  | ||||
| @ -45,7 +45,9 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s | ||||
| 
 | ||||
|    while (len-- > 0) { | ||||
|        if (cfb->padlen == cfb->blocklen) { | ||||
|           cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); | ||||
|           if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|           cfb->padlen = 0; | ||||
|        } | ||||
|        cfb->pad[cfb->padlen] = *ct; | ||||
|  | ||||
| @ -45,7 +45,9 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
| 
 | ||||
|    while (len-- > 0) { | ||||
|        if (cfb->padlen == cfb->blocklen) { | ||||
|           cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key); | ||||
|           if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|           cfb->padlen = 0; | ||||
|        } | ||||
|        cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); | ||||
|  | ||||
| @ -40,9 +40,7 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) | ||||
|        | ||||
|    /* force next block */ | ||||
|    cfb->padlen = 0; | ||||
|    cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
|    return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); | ||||
| } | ||||
| 
 | ||||
| #endif  | ||||
|  | ||||
| @ -54,10 +54,8 @@ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, | ||||
|    } | ||||
| 
 | ||||
|    /* encrypt the IV */ | ||||
|    cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); | ||||
|    cfb->padlen = 0; | ||||
| 
 | ||||
|    return CRYPT_OK; | ||||
|    return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -52,7 +52,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
|     | ||||
|    /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ | ||||
|    if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { | ||||
|       cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key); | ||||
|       if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { | ||||
|          return err; | ||||
|       } | ||||
|       len %= ctr->blocklen; | ||||
|    } | ||||
| 
 | ||||
| @ -79,7 +81,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
|          } | ||||
| 
 | ||||
|          /* encrypt it */ | ||||
|          cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | ||||
|          if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { | ||||
|             return err; | ||||
|          } | ||||
|          ctr->padlen = 0; | ||||
|       } | ||||
| #ifdef LTC_FAST | ||||
|  | ||||
| @ -45,9 +45,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) | ||||
|     | ||||
|    /* force next block */ | ||||
|    ctr->padlen = 0; | ||||
|    cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); | ||||
|     | ||||
|    return CRYPT_OK; | ||||
|    return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); | ||||
| } | ||||
| 
 | ||||
| #endif  | ||||
|  | ||||
| @ -59,8 +59,7 @@ int ctr_start(               int   cipher, | ||||
|    for (x = 0; x < ctr->blocklen; x++) { | ||||
|        ctr->ctr[x] = IV[x]; | ||||
|    } | ||||
|    cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | ||||
|    return CRYPT_OK; | ||||
|    return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -40,10 +40,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s | ||||
| 
 | ||||
|    /* check for accel */ | ||||
|    if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { | ||||
|       cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); | ||||
|       return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); | ||||
|    } else { | ||||
|       while (len) { | ||||
|          cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); | ||||
|          if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) { | ||||
|             return err; | ||||
|          } | ||||
|          pt  += cipher_descriptor[ecb->cipher].block_length; | ||||
|          ct  += cipher_descriptor[ecb->cipher].block_length; | ||||
|          len -= cipher_descriptor[ecb->cipher].block_length; | ||||
|  | ||||
| @ -40,10 +40,12 @@ int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
| 
 | ||||
|    /* check for accel */ | ||||
|    if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { | ||||
|       cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); | ||||
|       return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); | ||||
|    } else { | ||||
|       while (len) { | ||||
|          cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key); | ||||
|          if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) { | ||||
|             return err; | ||||
|          } | ||||
|          pt  += cipher_descriptor[ecb->cipher].block_length; | ||||
|          ct  += cipher_descriptor[ecb->cipher].block_length; | ||||
|          len -= cipher_descriptor[ecb->cipher].block_length; | ||||
|  | ||||
| @ -43,7 +43,9 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | ||||
|     | ||||
|    while (len-- > 0) { | ||||
|        if (ofb->padlen == ofb->blocklen) { | ||||
|           cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key); | ||||
|           if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) { | ||||
|              return err; | ||||
|           } | ||||
|           ofb->padlen = 0; | ||||
|        } | ||||
|        *ct++ = *pt++ ^ ofb->IV[ofb->padlen++]; | ||||
|  | ||||
| @ -41,8 +41,7 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb) | ||||
| 
 | ||||
|    /* force next block */ | ||||
|    ofb->padlen = 0; | ||||
|    cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); | ||||
|    return CRYPT_OK; | ||||
|    return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); | ||||
| } | ||||
| 
 | ||||
| #endif  | ||||
|  | ||||
| @ -51,7 +51,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen, | ||||
|    /* get the length of the data */ | ||||
|    if (in[x] & 0x80) { | ||||
|       /* long format get number of length bytes */ | ||||
|       y = in[x++] & 127; | ||||
|       y = in[x++] & 0x7F; | ||||
| 
 | ||||
|       /* invalid if 0 or > 2 */ | ||||
|       if (y == 0 || y > 2) { | ||||
| @ -65,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen, | ||||
|       } | ||||
|    } else { | ||||
|       /* short format */ | ||||
|       dlen = in[x++] & 127; | ||||
|       dlen = in[x++] & 0x7F; | ||||
|    } | ||||
|    | ||||
|    /* is the data len too long or too short? */ | ||||
|  | ||||
| @ -96,6 +96,7 @@ int der_decode_choice(const unsigned char *in,   unsigned long *inlen, | ||||
|            case LTC_ASN1_NULL: | ||||
|                if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { | ||||
|                   *inlen = 2; | ||||
|                   list[x].used   = 1; | ||||
|                   return CRYPT_OK; | ||||
|                } | ||||
|                break; | ||||
|  | ||||
							
								
								
									
										352
									
								
								src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										352
									
								
								src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,352 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file der_decode_sequence_flexi.c | ||||
|   ASN.1 DER, decode a SEQUENCE with a flexi parser, Tom St Denis | ||||
| */ | ||||
| 
 | ||||
| #ifdef LTC_DER | ||||
| 
 | ||||
| static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) | ||||
| { | ||||
|    unsigned long x, y, z; | ||||
| 
 | ||||
|    y = 0; | ||||
| 
 | ||||
|    /* skip type and read len */ | ||||
|    if (inlen < 2) { | ||||
|       return 0xFFFFFFFF; | ||||
|    } | ||||
|    ++in; ++y; | ||||
|     | ||||
|    /* read len */ | ||||
|    x = *in++; ++y; | ||||
|     | ||||
|    /* <128 means literal */ | ||||
|    if (x < 128) { | ||||
|       return x+y; | ||||
|    } | ||||
|    x     &= 0x7F; /* the lower 7 bits are the length of the length */ | ||||
|    inlen -= 2; | ||||
|     | ||||
|    /* len means len of len! */ | ||||
|    if (x == 0 || x > 4 || x > inlen) { | ||||
|       return 0xFFFFFFFF; | ||||
|    } | ||||
|     | ||||
|    y += x; | ||||
|    z = 0; | ||||
|    while (x--) {    | ||||
|       z = (z<<8) | ((unsigned long)*in); | ||||
|       ++in; | ||||
|    } | ||||
|    return z+y; | ||||
| } | ||||
| 
 | ||||
| /** 
 | ||||
|    ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. | ||||
|    @param in      The input buffer | ||||
|    @param inlen   [in/out] The length of the input buffer and on output the amount of decoded data  | ||||
|    @param out     [out] A pointer to the linked list | ||||
|    @return CRYPT_OK on success. | ||||
| */    | ||||
| int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) | ||||
| { | ||||
|    ltc_asn1_list *l; | ||||
|    unsigned long err, type, len, totlen, x, y; | ||||
|    void          *realloc_tmp; | ||||
|     | ||||
|    LTC_ARGCHK(in    != NULL); | ||||
|    LTC_ARGCHK(inlen != NULL); | ||||
|    LTC_ARGCHK(out   != NULL); | ||||
| 
 | ||||
|    l = NULL; | ||||
|    totlen = 0; | ||||
|     | ||||
|    /* scan the input and and get lengths and what not */ | ||||
|    while (*inlen) {      | ||||
|       /* read the type byte */ | ||||
|       type = *in; | ||||
| 
 | ||||
|       /* fetch length */ | ||||
|       len = fetch_length(in, *inlen); | ||||
|       if (len > *inlen) { | ||||
|          err = CRYPT_INVALID_PACKET; | ||||
|          goto error; | ||||
|       } | ||||
| 
 | ||||
|       /* alloc new link */ | ||||
|       if (l == NULL) { | ||||
|          l = XCALLOC(1, sizeof(*l)); | ||||
|          if (l == NULL) { | ||||
|             err = CRYPT_MEM; | ||||
|             goto error; | ||||
|          } | ||||
|       } else { | ||||
|          l->next = XCALLOC(1, sizeof(*l)); | ||||
|          if (l->next == NULL) { | ||||
|             err = CRYPT_MEM; | ||||
|             goto error; | ||||
|          } | ||||
|          l->next->prev = l; | ||||
|          l = l->next; | ||||
|       } | ||||
| 
 | ||||
|       /* now switch on type */ | ||||
|       switch (type) { | ||||
|          case 0x02: /* INTEGER */ | ||||
|              /* init field */ | ||||
|              l->type = LTC_ASN1_INTEGER; | ||||
|              l->size = 1; | ||||
|              if ((err = mp_init(&l->data)) != CRYPT_OK) { | ||||
|                  goto error; | ||||
|              } | ||||
|               | ||||
|              /* decode field */ | ||||
|              if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { | ||||
|                  goto error; | ||||
|              } | ||||
|               | ||||
|              /* calc length of object */ | ||||
|              if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { | ||||
|                  goto error; | ||||
|              } | ||||
|              break; | ||||
| 
 | ||||
|          case 0x03: /* BIT */ | ||||
|             /* init field */ | ||||
|             l->type = LTC_ASN1_BIT_STRING; | ||||
|             l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char.  */ | ||||
| 
 | ||||
|             if ((l->data = XCALLOC(1, l->size)) == NULL) { | ||||
|                err = CRYPT_MEM; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|          case 0x04: /* OCTET */ | ||||
| 
 | ||||
|             /* init field */ | ||||
|             l->type = LTC_ASN1_OCTET_STRING; | ||||
|             l->size = len; | ||||
| 
 | ||||
|             if ((l->data = XCALLOC(1, l->size)) == NULL) { | ||||
|                err = CRYPT_MEM; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|             break; | ||||
| 
 | ||||
|          case 0x05: /* NULL */ | ||||
|           | ||||
|             /* valid NULL is 0x05 0x00 */ | ||||
|             if (in[0] != 0x05 || in[1] != 0x00) { | ||||
|                err = CRYPT_INVALID_PACKET; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             /* simple to store ;-) */ | ||||
|             l->type = LTC_ASN1_NULL; | ||||
|             l->data = NULL; | ||||
|             l->size = 0; | ||||
|             len     = 2; | ||||
|              | ||||
|             break; | ||||
|           | ||||
|          case 0x06: /* OID */ | ||||
|           | ||||
|             /* init field */ | ||||
|             l->type = LTC_ASN1_OBJECT_IDENTIFIER; | ||||
|             l->size = len; | ||||
| 
 | ||||
|             if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { | ||||
|                err = CRYPT_MEM; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             /* resize it to save a bunch of mem */ | ||||
|             if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { | ||||
|                /* out of heap but this is not an error */ | ||||
|                break; | ||||
|             } | ||||
|             l->data = realloc_tmp; | ||||
|             break; | ||||
|           | ||||
| 
 | ||||
|          case 0x13: /* PRINTABLE */ | ||||
|           | ||||
|             /* init field */ | ||||
|             l->type = LTC_ASN1_PRINTABLE_STRING; | ||||
|             l->size = len; | ||||
| 
 | ||||
|             if ((l->data = XCALLOC(1, l->size)) == NULL) { | ||||
|                err = CRYPT_MEM; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|             break; | ||||
|           | ||||
|          case 0x16: /* IA5 */ | ||||
|           | ||||
|             /* init field */ | ||||
|             l->type = LTC_ASN1_IA5_STRING; | ||||
|             l->size = len; | ||||
| 
 | ||||
|             if ((l->data = XCALLOC(1, l->size)) == NULL) { | ||||
|                err = CRYPT_MEM; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|             break; | ||||
|           | ||||
|          case 0x17: /* UTC TIME */ | ||||
|           | ||||
|             /* init field */ | ||||
|             l->type = LTC_ASN1_UTCTIME; | ||||
|             l->size = 1; | ||||
| 
 | ||||
|             if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { | ||||
|                err = CRYPT_MEM; | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             len = *inlen; | ||||
|             if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|              | ||||
|             if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { | ||||
|                goto error; | ||||
|             } | ||||
|             break; | ||||
|           | ||||
|          case 0x30: /* SEQUENCE */ | ||||
|           | ||||
|              /* init field */ | ||||
|              l->type = LTC_ASN1_SEQUENCE; | ||||
|               | ||||
|              /* we have to decode the SEQUENCE header and get it's length */ | ||||
|               | ||||
|                 /* move past type */ | ||||
|                 ++in; --(*inlen); | ||||
|                  | ||||
|                 /* read length byte */ | ||||
|                 x = *in++; --(*inlen); | ||||
|                  | ||||
|                 /* smallest SEQUENCE header */ | ||||
|                 y = 2; | ||||
|                  | ||||
|                 /* now if it's > 127 the next bytes are the length of the length */ | ||||
|                 if (x > 128) { | ||||
|                    x      &= 0x7F; | ||||
|                    in     += x; | ||||
|                    *inlen -= x; | ||||
|                     | ||||
|                    /* update sequence header len */ | ||||
|                    y      += x; | ||||
|                 } | ||||
|               | ||||
|              /* Sequence elements go as child */ | ||||
|              len = *inlen; | ||||
|              if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { | ||||
|                 goto error; | ||||
|              } | ||||
|               | ||||
|              /* len update */ | ||||
|              totlen += y; | ||||
|               | ||||
|              /* link them up y0 */ | ||||
|              l->child->parent = l; | ||||
|               | ||||
|              break; | ||||
|          default: | ||||
|            /* invalid byte ... this is a soft error */ | ||||
|            /* remove link */ | ||||
|            l       = l->prev; | ||||
|            XFREE(l->next); | ||||
|            l->next = NULL; | ||||
|            goto outside; | ||||
|       } | ||||
|        | ||||
|       /* advance pointers */ | ||||
|       totlen  += len; | ||||
|       in      += len; | ||||
|       *inlen  -= len; | ||||
|    } | ||||
|     | ||||
| outside:    | ||||
| 
 | ||||
|    /* rewind l please */ | ||||
|    while (l->prev != NULL || l->parent != NULL) { | ||||
|       if (l->parent != NULL) { | ||||
|          l = l->parent; | ||||
|       } else { | ||||
|          l = l->prev; | ||||
|       } | ||||
|    } | ||||
|     | ||||
|    /* return */ | ||||
|    *out   = l; | ||||
|    *inlen = totlen; | ||||
|    return CRYPT_OK; | ||||
| 
 | ||||
| error: | ||||
|    /* free list */ | ||||
|    der_sequence_free(l); | ||||
| 
 | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| @ -101,6 +101,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, | ||||
|                y += x; | ||||
|                break; | ||||
| 
 | ||||
|            case LTC_ASN1_UTCTIME: | ||||
|                if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { | ||||
|                   goto LBL_ERR; | ||||
|                } | ||||
|                y += x; | ||||
|                break; | ||||
| 
 | ||||
|            case LTC_ASN1_SEQUENCE: | ||||
|                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { | ||||
|                   goto LBL_ERR; | ||||
|  | ||||
							
								
								
									
										63
									
								
								src/pk/asn1/der/sequence/der_sequence_free.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/pk/asn1/der/sequence/der_sequence_free.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file der_sequence_free.c | ||||
|   ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis | ||||
| */ | ||||
| 
 | ||||
| #ifdef LTC_DER | ||||
| 
 | ||||
| /**
 | ||||
|   Free memory allocated by der_decode_sequence_flexi() | ||||
|   @param in     The list to free | ||||
| */   | ||||
| void der_sequence_free(ltc_asn1_list *in) | ||||
| { | ||||
|    ltc_asn1_list *l; | ||||
|     | ||||
|    /* walk to the start of the chain */ | ||||
|    while (in->prev != NULL || in->parent != NULL) { | ||||
|       if (in->parent != NULL) { | ||||
|           in = in->parent; | ||||
|       } else { | ||||
|           in = in->prev; | ||||
|       } | ||||
|    } | ||||
|     | ||||
|    /* now walk the list and free stuff */ | ||||
|    while (in != NULL) { | ||||
|       /* is there a child? */ | ||||
|       if (in->child) { | ||||
|          /* disconnect */ | ||||
|          in->child->parent = NULL; | ||||
|          der_sequence_free(in->child); | ||||
|       } | ||||
|        | ||||
|       switch (in->type) {  | ||||
|          case LTC_ASN1_SEQUENCE: break; | ||||
|          case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; | ||||
|          default               : if (in->data != NULL) { XFREE(in->data);    } | ||||
|       } | ||||
|        | ||||
|       /* move to next and free current */ | ||||
|       l = in->next; | ||||
|       free(in); | ||||
|       in = l; | ||||
|    }      | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
							
								
								
									
										138
									
								
								src/pk/dsa/dsa_decrypt_key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/pk/dsa/dsa_decrypt_key.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,138 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file dsa_decrypt_key.c | ||||
|   DSA Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Decrypt an DSA encrypted key | ||||
|   @param in       The ciphertext | ||||
|   @param inlen    The length of the ciphertext (octets) | ||||
|   @param out      [out] The plaintext | ||||
|   @param outlen   [in/out] The max size and resulting size of the plaintext | ||||
|   @param key      The corresponding private DSA key | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int dsa_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||
|                           unsigned char *out, unsigned long *outlen,  | ||||
|                           dsa_key *key) | ||||
| { | ||||
|    unsigned char  *skey, *expt; | ||||
|    void           *g_pub; | ||||
|    unsigned long  x, y, hashOID[32]; | ||||
|    int            hash, err; | ||||
|    ltc_asn1_list  decode[3]; | ||||
| 
 | ||||
|    LTC_ARGCHK(in     != NULL); | ||||
|    LTC_ARGCHK(out    != NULL); | ||||
|    LTC_ARGCHK(outlen != NULL); | ||||
|    LTC_ARGCHK(key    != NULL); | ||||
| 
 | ||||
|    /* right key type? */ | ||||
|    if (key->type != PK_PRIVATE) { | ||||
|       return CRYPT_PK_NOT_PRIVATE; | ||||
|    } | ||||
|     | ||||
|    /* decode to find out hash */ | ||||
|    LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); | ||||
|   | ||||
|    if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    hash = find_hash_oid(hashOID, decode[0].size);                    | ||||
|    if (hash_is_valid(hash) != CRYPT_OK) { | ||||
|       return CRYPT_INVALID_PACKET; | ||||
|    } | ||||
| 
 | ||||
|    /* we now have the hash! */ | ||||
|     | ||||
|    if ((err = mp_init(&g_pub)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* allocate memory */ | ||||
|    expt   = XMALLOC(mp_unsigned_bin_size(key->p) + 1); | ||||
|    skey   = XMALLOC(MAXBLOCKSIZE); | ||||
|    if (expt == NULL || skey == NULL) { | ||||
|       if (expt != NULL) { | ||||
|          XFREE(expt); | ||||
|       } | ||||
|       if (skey != NULL) { | ||||
|          XFREE(skey); | ||||
|       } | ||||
|       mp_clear(g_pub); | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
|     | ||||
|    LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER,          g_pub,      1UL); | ||||
|    LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE); | ||||
| 
 | ||||
|    /* read the structure in now */ | ||||
|    if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* make shared key */ | ||||
|    x = mp_unsigned_bin_size(key->p) + 1; | ||||
|    if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE); | ||||
|    if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* ensure the hash of the shared secret is at least as big as the encrypt itself */ | ||||
|    if (decode[2].size > y) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* avoid buffer overflow */ | ||||
|    if (*outlen < decode[2].size) { | ||||
|       err = CRYPT_BUFFER_OVERFLOW; | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* Decrypt the key */ | ||||
|    for (x = 0; x < decode[2].size; x++) { | ||||
|      out[x] = expt[x] ^ skey[x]; | ||||
|    } | ||||
|    *outlen = x; | ||||
| 
 | ||||
|    err = CRYPT_OK; | ||||
| LBL_ERR: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|    zeromem(expt,   mp_unsigned_bin_size(key->p) + 1); | ||||
|    zeromem(skey,   MAXBLOCKSIZE); | ||||
| #endif | ||||
| 
 | ||||
|    XFREE(expt); | ||||
|    XFREE(skey); | ||||
|     | ||||
|    mp_clear(g_pub); | ||||
| 
 | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										136
									
								
								src/pk/dsa/dsa_encrypt_key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/pk/dsa/dsa_encrypt_key.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,136 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file dsa_encrypt_key.c | ||||
|   DSA Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MDSA | ||||
| 
 | ||||
| /**
 | ||||
|   Encrypt a symmetric key with DSA | ||||
|   @param in         The symmetric key you want to encrypt | ||||
|   @param inlen      The length of the key to encrypt (octets) | ||||
|   @param out        [out] The destination for the ciphertext | ||||
|   @param outlen     [in/out] The max size and resulting size of the ciphertext | ||||
|   @param prng       An active PRNG state | ||||
|   @param wprng      The index of the PRNG you wish to use  | ||||
|   @param hash       The index of the hash you want to use  | ||||
|   @param key        The DSA key you want to encrypt to | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int dsa_encrypt_key(const unsigned char *in,   unsigned long inlen, | ||||
|                           unsigned char *out,  unsigned long *outlen,  | ||||
|                           prng_state *prng, int wprng, int hash,  | ||||
|                           dsa_key *key) | ||||
| { | ||||
|     unsigned char *expt, *skey; | ||||
|     void          *g_pub, *g_priv; | ||||
|     unsigned long  x, y; | ||||
|     int            err; | ||||
| 
 | ||||
|     LTC_ARGCHK(in      != NULL); | ||||
|     LTC_ARGCHK(out     != NULL); | ||||
|     LTC_ARGCHK(outlen  != NULL); | ||||
|     LTC_ARGCHK(key     != NULL); | ||||
| 
 | ||||
|     /* check that wprng/cipher/hash are not invalid */ | ||||
|     if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     if ((err = hash_is_valid(hash)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     if (inlen > hash_descriptor[hash].hashsize) { | ||||
|        return CRYPT_INVALID_HASH; | ||||
|     } | ||||
| 
 | ||||
|     /* make a random key and export the public copy */ | ||||
|     if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
|     | ||||
|     expt       = XMALLOC(mp_unsigned_bin_size(key->p) + 1); | ||||
|     skey       = XMALLOC(MAXBLOCKSIZE); | ||||
|     if (expt == NULL  || skey == NULL) { | ||||
|        if (expt != NULL) { | ||||
|           XFREE(expt); | ||||
|        } | ||||
|        if (skey != NULL) { | ||||
|           XFREE(skey); | ||||
|        } | ||||
|        mp_clear_multi(g_pub, g_priv, NULL); | ||||
|        return CRYPT_MEM; | ||||
|     } | ||||
|      | ||||
|     /* make a random x, g^x pair */ | ||||
|     x = mp_unsigned_bin_size(key->q); | ||||
|     if (prng_descriptor[wprng].read(expt, x, prng) != x) { | ||||
|        err = CRYPT_ERROR_READPRNG; | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* load x */ | ||||
|     if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) { | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* compute y */ | ||||
|     if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* make random key */ | ||||
|     x        = mp_unsigned_bin_size(key->p) + 1; | ||||
|     if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
| 
 | ||||
|     y = MAXBLOCKSIZE; | ||||
|     if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* Encrypt key */ | ||||
|     for (x = 0; x < inlen; x++) { | ||||
|       skey[x] ^= in[x]; | ||||
|     } | ||||
| 
 | ||||
|     err = der_encode_sequence_multi(out, outlen, | ||||
|                                     LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID, | ||||
|                                     LTC_ASN1_INTEGER,            1UL,                            g_pub, | ||||
|                                     LTC_ASN1_OCTET_STRING,       inlen,                          skey, | ||||
|                                     LTC_ASN1_EOL,                0UL,                            NULL); | ||||
| 
 | ||||
| LBL_ERR: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|     /* clean up */ | ||||
|     zeromem(expt,   mp_unsigned_bin_size(key->p) + 1); | ||||
|     zeromem(skey,   MAXBLOCKSIZE); | ||||
| #endif | ||||
| 
 | ||||
|     XFREE(skey); | ||||
|     XFREE(expt); | ||||
|      | ||||
|     mp_clear_multi(g_pub, g_priv, NULL); | ||||
| 
 | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
| @ -31,6 +31,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) | ||||
| 
 | ||||
|    LTC_ARGCHK(in  != NULL); | ||||
|    LTC_ARGCHK(key != NULL); | ||||
|    LTC_ARGCHK(ltc_mp.name != NULL); | ||||
| 
 | ||||
|    /* init key */ | ||||
|    if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) { | ||||
|  | ||||
| @ -33,6 +33,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, | ||||
|    unsigned char *buf; | ||||
| 
 | ||||
|    LTC_ARGCHK(key  != NULL); | ||||
|    LTC_ARGCHK(ltc_mp.name != NULL); | ||||
| 
 | ||||
|    /* check prng */ | ||||
|    if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|  | ||||
							
								
								
									
										71
									
								
								src/pk/dsa/dsa_shared_secret.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/pk/dsa/dsa_shared_secret.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file dsa_shared_secret.c | ||||
|   DSA Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MDSA | ||||
| 
 | ||||
| /**
 | ||||
|   Create a DSA shared secret between two keys | ||||
|   @param private_key      The private DSA key (the exponent) | ||||
|   @param base             The base of the exponentiation (allows this to be used for both encrypt and decrypt)  | ||||
|   @param public_key       The public key | ||||
|   @param out              [out] Destination of the shared secret | ||||
|   @param outlen           [in/out] The max size and resulting size of the shared secret | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int dsa_shared_secret(void          *private_key, void *base, | ||||
|                       dsa_key       *public_key, | ||||
|                       unsigned char *out,         unsigned long *outlen) | ||||
| { | ||||
|    unsigned long x; | ||||
|    void *res; | ||||
|    int err; | ||||
| 
 | ||||
|    LTC_ARGCHK(private_key != NULL); | ||||
|    LTC_ARGCHK(public_key  != NULL); | ||||
|    LTC_ARGCHK(out         != NULL); | ||||
|    LTC_ARGCHK(outlen      != NULL); | ||||
| 
 | ||||
|    /* make new point */ | ||||
|    if ((err = mp_init(&res)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) { | ||||
|       mp_clear(res); | ||||
|       return err; | ||||
|    } | ||||
|     | ||||
|    x = (unsigned long)mp_unsigned_bin_size(res); | ||||
|    if (*outlen < x) { | ||||
|       err = CRYPT_BUFFER_OVERFLOW; | ||||
|       goto done; | ||||
|    } | ||||
|    zeromem(out, x); | ||||
|    if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res))))   != CRYPT_OK)          { goto done; } | ||||
| 
 | ||||
|    err     = CRYPT_OK; | ||||
|    *outlen = x; | ||||
| done: | ||||
|    mp_clear(res); | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										1065
									
								
								src/pk/ecc/ecc.c
									
									
									
									
									
								
							
							
						
						
									
										1065
									
								
								src/pk/ecc/ecc.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										149
									
								
								src/pk/ecc/ecc_decrypt_key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/pk/ecc/ecc_decrypt_key.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_decrypt_key.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Decrypt an ECC encrypted key | ||||
|   @param in       The ciphertext | ||||
|   @param inlen    The length of the ciphertext (octets) | ||||
|   @param out      [out] The plaintext | ||||
|   @param outlen   [in/out] The max size and resulting size of the plaintext | ||||
|   @param key      The corresponding private ECC key | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||
|                           unsigned char *out, unsigned long *outlen,  | ||||
|                           ecc_key *key) | ||||
| { | ||||
|    unsigned char *ecc_shared, *skey, *pub_expt; | ||||
|    unsigned long  x, y, hashOID[32]; | ||||
|    int            hash, err; | ||||
|    ecc_key        pubkey; | ||||
|    ltc_asn1_list  decode[3]; | ||||
| 
 | ||||
|    LTC_ARGCHK(in     != NULL); | ||||
|    LTC_ARGCHK(out    != NULL); | ||||
|    LTC_ARGCHK(outlen != NULL); | ||||
|    LTC_ARGCHK(key    != NULL); | ||||
| 
 | ||||
|    /* right key type? */ | ||||
|    if (key->type != PK_PRIVATE) { | ||||
|       return CRYPT_PK_NOT_PRIVATE; | ||||
|    } | ||||
|     | ||||
|    /* decode to find out hash */ | ||||
|    LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); | ||||
|   | ||||
|    if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    hash = find_hash_oid(hashOID, decode[0].size);                    | ||||
|    if (hash_is_valid(hash) != CRYPT_OK) { | ||||
|       return CRYPT_INVALID_PACKET; | ||||
|    } | ||||
| 
 | ||||
|    /* we now have the hash! */ | ||||
| 
 | ||||
|    /* allocate memory */ | ||||
|    pub_expt   = XMALLOC(ECC_BUF_SIZE); | ||||
|    ecc_shared = XMALLOC(ECC_BUF_SIZE); | ||||
|    skey       = XMALLOC(MAXBLOCKSIZE); | ||||
|    if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { | ||||
|       if (pub_expt != NULL) { | ||||
|          XFREE(pub_expt); | ||||
|       } | ||||
|       if (ecc_shared != NULL) { | ||||
|          XFREE(ecc_shared); | ||||
|       } | ||||
|       if (skey != NULL) { | ||||
|          XFREE(skey); | ||||
|       } | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
|    LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING,      pub_expt,  ECC_BUF_SIZE); | ||||
|    LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE); | ||||
| 
 | ||||
|    /* read the structure in now */ | ||||
|    if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* import ECC key from packet */ | ||||
|    if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* make shared key */ | ||||
|    x = ECC_BUF_SIZE; | ||||
|    if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) { | ||||
|       ecc_free(&pubkey); | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
|    ecc_free(&pubkey); | ||||
| 
 | ||||
|    y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE); | ||||
|    if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* ensure the hash of the shared secret is at least as big as the encrypt itself */ | ||||
|    if (decode[2].size > y) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* avoid buffer overflow */ | ||||
|    if (*outlen < decode[2].size) { | ||||
|       err = CRYPT_BUFFER_OVERFLOW; | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* Decrypt the key */ | ||||
|    for (x = 0; x < decode[2].size; x++) { | ||||
|      out[x] = skey[x] ^ ecc_shared[x]; | ||||
|    } | ||||
|    *outlen = x; | ||||
| 
 | ||||
|    err = CRYPT_OK; | ||||
| LBL_ERR: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|    zeromem(pub_expt,   ECC_BUF_SIZE); | ||||
|    zeromem(ecc_shared, ECC_BUF_SIZE); | ||||
|    zeromem(skey,       MAXBLOCKSIZE); | ||||
| #endif | ||||
| 
 | ||||
|    XFREE(pub_expt); | ||||
|    XFREE(ecc_shared); | ||||
|    XFREE(skey); | ||||
| 
 | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										136
									
								
								src/pk/ecc/ecc_encrypt_key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/pk/ecc/ecc_encrypt_key.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,136 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_encrypt_key.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Encrypt a symmetric key with ECC  | ||||
|   @param in         The symmetric key you want to encrypt | ||||
|   @param inlen      The length of the key to encrypt (octets) | ||||
|   @param out        [out] The destination for the ciphertext | ||||
|   @param outlen     [in/out] The max size and resulting size of the ciphertext | ||||
|   @param prng       An active PRNG state | ||||
|   @param wprng      The index of the PRNG you wish to use  | ||||
|   @param hash       The index of the hash you want to use  | ||||
|   @param key        The ECC key you want to encrypt to | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen, | ||||
|                           unsigned char *out,  unsigned long *outlen,  | ||||
|                           prng_state *prng, int wprng, int hash,  | ||||
|                           ecc_key *key) | ||||
| { | ||||
|     unsigned char *pub_expt, *ecc_shared, *skey; | ||||
|     ecc_key        pubkey; | ||||
|     unsigned long  x, y, pubkeysize; | ||||
|     int            err; | ||||
| 
 | ||||
|     LTC_ARGCHK(in      != NULL); | ||||
|     LTC_ARGCHK(out     != NULL); | ||||
|     LTC_ARGCHK(outlen  != NULL); | ||||
|     LTC_ARGCHK(key     != NULL); | ||||
| 
 | ||||
|     /* check that wprng/cipher/hash are not invalid */ | ||||
|     if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     if ((err = hash_is_valid(hash)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     if (inlen > hash_descriptor[hash].hashsize) { | ||||
|        return CRYPT_INVALID_HASH; | ||||
|     } | ||||
| 
 | ||||
|     /* make a random key and export the public copy */ | ||||
|     if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     pub_expt   = XMALLOC(ECC_BUF_SIZE); | ||||
|     ecc_shared = XMALLOC(ECC_BUF_SIZE); | ||||
|     skey       = XMALLOC(MAXBLOCKSIZE); | ||||
|     if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { | ||||
|        if (pub_expt != NULL) { | ||||
|           XFREE(pub_expt); | ||||
|        } | ||||
|        if (ecc_shared != NULL) { | ||||
|           XFREE(ecc_shared); | ||||
|        } | ||||
|        if (skey != NULL) { | ||||
|           XFREE(skey); | ||||
|        } | ||||
|        ecc_free(&pubkey); | ||||
|        return CRYPT_MEM; | ||||
|     } | ||||
| 
 | ||||
|     pubkeysize = ECC_BUF_SIZE; | ||||
|     if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | ||||
|        ecc_free(&pubkey); | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* make random key */ | ||||
|     x        = ECC_BUF_SIZE; | ||||
|     if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { | ||||
|        ecc_free(&pubkey); | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|     ecc_free(&pubkey); | ||||
|     y = MAXBLOCKSIZE; | ||||
|     if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) { | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* Encrypt key */ | ||||
|     for (x = 0; x < inlen; x++) { | ||||
|       skey[x] ^= in[x]; | ||||
|     } | ||||
| 
 | ||||
|     err = der_encode_sequence_multi(out, outlen, | ||||
|                                     LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID, | ||||
|                                     LTC_ASN1_OCTET_STRING,       pubkeysize,                     pub_expt, | ||||
|                                     LTC_ASN1_OCTET_STRING,       inlen,                          skey, | ||||
|                                     LTC_ASN1_EOL,                0UL,                            NULL); | ||||
| 
 | ||||
| LBL_ERR: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|     /* clean up */ | ||||
|     zeromem(pub_expt,   ECC_BUF_SIZE); | ||||
|     zeromem(ecc_shared, ECC_BUF_SIZE); | ||||
|     zeromem(skey,       MAXBLOCKSIZE); | ||||
| #endif | ||||
| 
 | ||||
|     XFREE(skey); | ||||
|     XFREE(ecc_shared); | ||||
|     XFREE(pub_expt); | ||||
| 
 | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										82
									
								
								src/pk/ecc/ecc_export.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/pk/ecc/ecc_export.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_export.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Export an ECC key as a binary packet | ||||
|   @param out     [out] Destination for the key | ||||
|   @param outlen  [in/out] Max size and resulting size of the exported key | ||||
|   @param type    The type of key you want to export (PK_PRIVATE or PK_PUBLIC) | ||||
|   @param key     The key to export | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) | ||||
| { | ||||
|    int           err; | ||||
|    unsigned char flags[1]; | ||||
|    unsigned long key_size; | ||||
| 
 | ||||
|    LTC_ARGCHK(out    != NULL); | ||||
|    LTC_ARGCHK(outlen != NULL); | ||||
|    LTC_ARGCHK(key    != NULL); | ||||
|     | ||||
|    /* type valid? */ | ||||
|    if (key->type != PK_PRIVATE && type == PK_PRIVATE) { | ||||
|       return CRYPT_PK_TYPE_MISMATCH; | ||||
|    } | ||||
| 
 | ||||
|    if (ltc_ecc_is_valid_idx(key->idx) == 0) { | ||||
|       return CRYPT_INVALID_ARG; | ||||
|    } | ||||
| 
 | ||||
|    /* we store the NIST byte size */ | ||||
|    key_size = ltc_ecc_sets[key->idx].size; | ||||
| 
 | ||||
|    if (type == PK_PRIVATE) { | ||||
|        flags[0] = 1; | ||||
|        err = der_encode_sequence_multi(out, outlen, | ||||
|                                  LTC_ASN1_BIT_STRING,      1UL, flags, | ||||
|                                  LTC_ASN1_SHORT_INTEGER,   1UL, &key_size, | ||||
|                                  LTC_ASN1_INTEGER,         1UL, key->pubkey.x, | ||||
|                                  LTC_ASN1_INTEGER,         1UL, key->pubkey.y, | ||||
|                                  LTC_ASN1_INTEGER,         1UL, key->k, | ||||
|                                  LTC_ASN1_EOL,             0UL, NULL); | ||||
|    } else { | ||||
|        flags[0] = 0; | ||||
|        err = der_encode_sequence_multi(out, outlen, | ||||
|                                  LTC_ASN1_BIT_STRING,      1UL, flags, | ||||
|                                  LTC_ASN1_SHORT_INTEGER,   1UL, &key_size, | ||||
|                                  LTC_ASN1_INTEGER,         1UL, key->pubkey.x, | ||||
|                                  LTC_ASN1_INTEGER,         1UL, key->pubkey.y, | ||||
|                                  LTC_ASN1_EOL,             0UL, NULL); | ||||
|    } | ||||
| 
 | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										40
									
								
								src/pk/ecc/ecc_free.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/pk/ecc/ecc_free.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_free.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Free an ECC key from memory | ||||
|   @param key   The key you wish to free | ||||
| */ | ||||
| void ecc_free(ecc_key *key) | ||||
| { | ||||
|    LTC_ARGCHK(key != NULL); | ||||
|    mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										44
									
								
								src/pk/ecc/ecc_get_size.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/pk/ecc/ecc_get_size.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_get_size.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Get the size of an ECC key | ||||
|   @param key    The key to get the size of  | ||||
|   @return The size (octets) of the key or INT_MAX on error | ||||
| */ | ||||
| int ecc_get_size(ecc_key *key) | ||||
| { | ||||
|    LTC_ARGCHK(key != NULL); | ||||
|    if (ltc_ecc_is_valid_idx(key->idx)) | ||||
|       return ltc_ecc_sets[key->idx].size; | ||||
|    else | ||||
|       return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										155
									
								
								src/pk/ecc/ecc_import.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/pk/ecc/ecc_import.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_import.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| static int is_point(ecc_key *key) | ||||
| { | ||||
|    void *prime, *b, *t1, *t2; | ||||
|    int err; | ||||
|     | ||||
|    if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|     | ||||
|    /* load prime and b */ | ||||
|    if ((err = mp_read_radix(prime, ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)            { goto error; } | ||||
|    if ((err = mp_read_radix(b, ltc_ecc_sets[key->idx].B, 64)) != CRYPT_OK)                    { goto error; } | ||||
|     | ||||
|    /* compute y^2 */ | ||||
|    if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK)                                         { goto error; } | ||||
|     | ||||
|    /* compute x^3 */ | ||||
|    if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK)                                         { goto error; } | ||||
|    if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK)                                             { goto error; } | ||||
|    if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK)                                     { goto error; } | ||||
|     | ||||
|    /* compute y^2 - x^3 */ | ||||
|    if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK)                                                { goto error; } | ||||
|     | ||||
|    /* compute y^2 - x^3 + 3x */ | ||||
|    if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; } | ||||
|    if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; } | ||||
|    if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK)                                     { goto error; } | ||||
|    if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK)                                             { goto error; } | ||||
|    while (mp_cmp_d(t1, 0) == LTC_MP_LT) { | ||||
|       if ((err = mp_add(t1, prime, t1)) != CRYPT_OK)                                          { goto error; } | ||||
|    } | ||||
|    while (mp_cmp(t1, prime) != LTC_MP_LT) { | ||||
|       if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK)                                          { goto error; } | ||||
|    } | ||||
|     | ||||
|    /* compare to b */ | ||||
|    if (mp_cmp(t1, b) != LTC_MP_EQ) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|    } else { | ||||
|       err = CRYPT_OK; | ||||
|    } | ||||
|     | ||||
| error: | ||||
|    mp_clear_multi(prime, b, t1, t2, NULL); | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|   Import an ECC key from a binary packet | ||||
|   @param in      The packet to import | ||||
|   @param inlen   The length of the packet | ||||
|   @param key     [out] The destination of the import | ||||
|   @return CRYPT_OK if successful, upon error all allocated memory will be freed | ||||
| */ | ||||
| int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) | ||||
| { | ||||
|    unsigned long key_size; | ||||
|    unsigned char flags[1]; | ||||
|    int           err; | ||||
| 
 | ||||
|    LTC_ARGCHK(in  != NULL); | ||||
|    LTC_ARGCHK(key != NULL); | ||||
|    LTC_ARGCHK(ltc_mp.name != NULL); | ||||
| 
 | ||||
|    /* init key */ | ||||
|    if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    /* find out what type of key it is */ | ||||
|    if ((err = der_decode_sequence_multi(in, inlen,  | ||||
|                                   LTC_ASN1_BIT_STRING, 1UL, &flags, | ||||
|                                   LTC_ASN1_EOL,        0UL, NULL)) != CRYPT_OK) { | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
| 
 | ||||
|    if (flags[0] == 1) { | ||||
|       /* private key */ | ||||
|       key->type = PK_PRIVATE; | ||||
|       if ((err = der_decode_sequence_multi(in, inlen, | ||||
|                                      LTC_ASN1_BIT_STRING,      1UL, flags, | ||||
|                                      LTC_ASN1_SHORT_INTEGER,   1UL, &key_size, | ||||
|                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.x, | ||||
|                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.y, | ||||
|                                      LTC_ASN1_INTEGER,         1UL, key->k, | ||||
|                                      LTC_ASN1_EOL,             0UL, NULL)) != CRYPT_OK) { | ||||
|          goto done; | ||||
|       } | ||||
|    } else { | ||||
|       /* public key */ | ||||
|       key->type = PK_PUBLIC; | ||||
|       if ((err = der_decode_sequence_multi(in, inlen, | ||||
|                                      LTC_ASN1_BIT_STRING,      1UL, flags, | ||||
|                                      LTC_ASN1_SHORT_INTEGER,   1UL, &key_size, | ||||
|                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.x, | ||||
|                                      LTC_ASN1_INTEGER,         1UL, key->pubkey.y, | ||||
|                                      LTC_ASN1_EOL,             0UL, NULL)) != CRYPT_OK) { | ||||
|          goto done; | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    /* find the idx */ | ||||
|    for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx); | ||||
|    if (ltc_ecc_sets[key->idx].size == 0) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* set z */ | ||||
|    mp_set(key->pubkey.z, 1); | ||||
|     | ||||
|    /* is it a point on the curve?  */ | ||||
|    if ((err = is_point(key)) != CRYPT_OK) { | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* we're good */ | ||||
|    return CRYPT_OK; | ||||
| done: | ||||
|    mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										112
									
								
								src/pk/ecc/ecc_make_key.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								src/pk/ecc/ecc_make_key.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_make_key.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Make a new ECC key  | ||||
|   @param prng         An active PRNG state | ||||
|   @param wprng        The index of the PRNG you wish to use | ||||
|   @param keysize      The keysize for the new key (in octets from 20 to 65 bytes) | ||||
|   @param key          [out] Destination of the newly created key | ||||
|   @return CRYPT_OK if successful, upon error all allocated memory will be freed | ||||
| */ | ||||
| int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) | ||||
| { | ||||
|    int            x, err; | ||||
|    ecc_point     *base; | ||||
|    void          *prime; | ||||
|    unsigned char *buf; | ||||
| 
 | ||||
|    LTC_ARGCHK(key != NULL); | ||||
|    LTC_ARGCHK(ltc_mp.name != NULL); | ||||
| 
 | ||||
|    /* good prng? */ | ||||
|    if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* find key size */ | ||||
|    for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++); | ||||
|    keysize = ltc_ecc_sets[x].size; | ||||
| 
 | ||||
|    if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) { | ||||
|       return CRYPT_INVALID_KEYSIZE; | ||||
|    } | ||||
|    key->idx = x; | ||||
| 
 | ||||
|    /* allocate ram */ | ||||
|    base = NULL; | ||||
|    buf  = XMALLOC(ECC_MAXSIZE); | ||||
|    if (buf == NULL) { | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    /* make up random string */ | ||||
|    if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { | ||||
|       err = CRYPT_ERROR_READPRNG; | ||||
|       goto LBL_ERR2; | ||||
|    } | ||||
| 
 | ||||
|    /* setup the key variables */ | ||||
|    if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL)) != CRYPT_OK) { | ||||
|       goto done; | ||||
|    } | ||||
|    base = ltc_ecc_new_point(); | ||||
|    if (base == NULL) { | ||||
|       mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, NULL); | ||||
|       err = CRYPT_MEM; | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* read in the specs for this key */ | ||||
|    if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)      { goto done; } | ||||
|    if ((err = mp_read_radix(base->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK)       { goto done; } | ||||
|    if ((err = mp_read_radix(base->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK)       { goto done; } | ||||
|    mp_set(base->z, 1); | ||||
|    if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK)         { goto done; } | ||||
| 
 | ||||
|    /* make the public key */ | ||||
|    if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK)              { goto done; } | ||||
|    key->type = PK_PRIVATE; | ||||
| 
 | ||||
|    /* free up ram */ | ||||
|    err = CRYPT_OK; | ||||
| done: | ||||
|    ltc_ecc_del_point(base); | ||||
|    mp_clear(prime); | ||||
| LBL_ERR2: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|    zeromem(buf, ECC_MAXSIZE); | ||||
| #endif | ||||
| 
 | ||||
|    XFREE(buf); | ||||
| 
 | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										94
									
								
								src/pk/ecc/ecc_shared_secret.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/pk/ecc/ecc_shared_secret.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_shared_secret.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Create an ECC shared secret between two keys | ||||
|   @param private_key      The private ECC key | ||||
|   @param public_key       The public key | ||||
|   @param out              [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) | ||||
|   @param outlen           [in/out] The max size and resulting size of the shared secret | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, | ||||
|                       unsigned char *out, unsigned long *outlen) | ||||
| { | ||||
|    unsigned long x; | ||||
|    ecc_point *result; | ||||
|    void *prime; | ||||
|    int err; | ||||
| 
 | ||||
|    LTC_ARGCHK(private_key != NULL); | ||||
|    LTC_ARGCHK(public_key  != NULL); | ||||
|    LTC_ARGCHK(out         != NULL); | ||||
|    LTC_ARGCHK(outlen      != NULL); | ||||
| 
 | ||||
|    /* type valid? */ | ||||
|    if (private_key->type != PK_PRIVATE) { | ||||
|       return CRYPT_PK_NOT_PRIVATE; | ||||
|    } | ||||
| 
 | ||||
|    if (ltc_ecc_is_valid_idx(private_key->idx) == 0) { | ||||
|       return CRYPT_INVALID_ARG; | ||||
|    } | ||||
| 
 | ||||
|    if (private_key->idx != public_key->idx) { | ||||
|       return CRYPT_PK_TYPE_MISMATCH; | ||||
|    } | ||||
| 
 | ||||
|    /* make new point */ | ||||
|    result = ltc_ecc_new_point(); | ||||
|    if (result == NULL) { | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    if ((err = mp_init(&prime)) != CRYPT_OK) { | ||||
|       ltc_ecc_del_point(result); | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[private_key->idx].prime, 64)) != CRYPT_OK)                 { goto done; } | ||||
|    if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK)                { goto done; } | ||||
| 
 | ||||
|    x = (unsigned long)mp_unsigned_bin_size(prime); | ||||
|    if (*outlen < x) { | ||||
|       err = CRYPT_BUFFER_OVERFLOW; | ||||
|       goto done; | ||||
|    } | ||||
|    zeromem(out, x); | ||||
|    if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x))))   != CRYPT_OK)           { goto done; } | ||||
| 
 | ||||
|    err     = CRYPT_OK; | ||||
|    *outlen = x; | ||||
| done: | ||||
|    mp_clear(prime); | ||||
|    ltc_ecc_del_point(result); | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										118
									
								
								src/pk/ecc/ecc_sign_hash.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/pk/ecc/ecc_sign_hash.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_sign_hash.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Sign a message digest | ||||
|   @param in        The message digest to sign | ||||
|   @param inlen     The length of the digest | ||||
|   @param out       [out] The destination for the signature | ||||
|   @param outlen    [in/out] The max size and resulting size of the signature | ||||
|   @param prng      An active PRNG state | ||||
|   @param wprng     The index of the PRNG you wish to use | ||||
|   @param key       A private ECC key | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,  | ||||
|                         unsigned char *out, unsigned long *outlen,  | ||||
|                         prng_state *prng, int wprng, ecc_key *key) | ||||
| { | ||||
|    ecc_key       pubkey; | ||||
|    void          *r, *s, *e, *p; | ||||
|    int           err; | ||||
| 
 | ||||
|    LTC_ARGCHK(in     != NULL); | ||||
|    LTC_ARGCHK(out    != NULL); | ||||
|    LTC_ARGCHK(outlen != NULL); | ||||
|    LTC_ARGCHK(key    != NULL); | ||||
| 
 | ||||
|    /* is this a private key? */ | ||||
|    if (key->type != PK_PRIVATE) { | ||||
|       return CRYPT_PK_NOT_PRIVATE; | ||||
|    } | ||||
|     | ||||
|    /* is the IDX valid ?  */ | ||||
|    if (ltc_ecc_is_valid_idx(key->idx) != 1) { | ||||
|       return CRYPT_PK_INVALID_TYPE; | ||||
|    } | ||||
|     | ||||
|    if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* get the hash and load it as a bignum into 'e' */ | ||||
|    /* init the bignums */ | ||||
|    if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {  | ||||
|       ecc_free(&pubkey); | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
|    if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)        { goto error; } | ||||
|    if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)  { goto error; } | ||||
| 
 | ||||
|    /* make up a key and export the public copy */ | ||||
|    for (;;) { | ||||
|       if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { | ||||
|          return err; | ||||
|       } | ||||
| 
 | ||||
|       /* find r = x1 mod n */ | ||||
|       if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK)                           { goto error; } | ||||
| 
 | ||||
|       if (mp_iszero(r)) { | ||||
|          ecc_free(&pubkey); | ||||
|       } else {  | ||||
|         /* find s = (e + xr)/k */ | ||||
|         if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)            { goto error; } /* k = 1/k */ | ||||
|         if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)                  { goto error; } /* s = xr */ | ||||
|         if ((err = mp_add(e, s, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */ | ||||
|         if ((err = mp_mod(s, p, s)) != CRYPT_OK)                             { goto error; } /* s = e +  xr */ | ||||
|         if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK)                { goto error; } /* s = (e + xr)/k */ | ||||
| 
 | ||||
|         if (mp_iszero(s)) { | ||||
|            ecc_free(&pubkey); | ||||
|         } else { | ||||
|            break; | ||||
|         } | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    /* store as SEQUENCE { r, s -- integer } */ | ||||
|    err = der_encode_sequence_multi(out, outlen, | ||||
|                              LTC_ASN1_INTEGER, 1UL, r, | ||||
|                              LTC_ASN1_INTEGER, 1UL, s, | ||||
|                              LTC_ASN1_EOL, 0UL, NULL); | ||||
|    goto LBL_ERR; | ||||
| error: | ||||
| LBL_ERR: | ||||
|    mp_clear_multi(r, s, p, e, NULL); | ||||
|    ecc_free(&pubkey); | ||||
| 
 | ||||
|    return err;    | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										48
									
								
								src/pk/ecc/ecc_sizes.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/pk/ecc/ecc_sizes.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_sizes.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| void ecc_sizes(int *low, int *high) | ||||
| { | ||||
|  int i; | ||||
|  LTC_ARGCHK(low  != NULL); | ||||
|  LTC_ARGCHK(high != NULL); | ||||
| 
 | ||||
|  *low = INT_MAX; | ||||
|  *high = 0; | ||||
|  for (i = 0; ltc_ecc_sets[i].size != 0; i++) { | ||||
|      if (ltc_ecc_sets[i].size < *low)  { | ||||
|         *low  = ltc_ecc_sets[i].size; | ||||
|      } | ||||
|      if (ltc_ecc_sets[i].size > *high) { | ||||
|         *high = ltc_ecc_sets[i].size; | ||||
|      } | ||||
|  } | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
| @ -1,472 +0,0 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_sys.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */ | ||||
|    | ||||
| /**
 | ||||
|   Encrypt a symmetric key with ECC  | ||||
|   @param in         The symmetric key you want to encrypt | ||||
|   @param inlen      The length of the key to encrypt (octets) | ||||
|   @param out        [out] The destination for the ciphertext | ||||
|   @param outlen     [in/out] The max size and resulting size of the ciphertext | ||||
|   @param prng       An active PRNG state | ||||
|   @param wprng      The index of the PRNG you wish to use  | ||||
|   @param hash       The index of the hash you want to use  | ||||
|   @param key        The ECC key you want to encrypt to | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen, | ||||
|                           unsigned char *out,  unsigned long *outlen,  | ||||
|                           prng_state *prng, int wprng, int hash,  | ||||
|                           ecc_key *key) | ||||
| { | ||||
|     unsigned char *pub_expt, *ecc_shared, *skey; | ||||
|     ecc_key        pubkey; | ||||
|     unsigned long  x, y, pubkeysize; | ||||
|     int            err; | ||||
| 
 | ||||
|     LTC_ARGCHK(in      != NULL); | ||||
|     LTC_ARGCHK(out     != NULL); | ||||
|     LTC_ARGCHK(outlen  != NULL); | ||||
|     LTC_ARGCHK(key     != NULL); | ||||
| 
 | ||||
|     /* check that wprng/cipher/hash are not invalid */ | ||||
|     if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     if ((err = hash_is_valid(hash)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     if (inlen > hash_descriptor[hash].hashsize) { | ||||
|        return CRYPT_INVALID_HASH; | ||||
|     } | ||||
| 
 | ||||
|     /* make a random key and export the public copy */ | ||||
|     if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { | ||||
|        return err; | ||||
|     } | ||||
| 
 | ||||
|     pub_expt   = XMALLOC(ECC_BUF_SIZE); | ||||
|     ecc_shared = XMALLOC(ECC_BUF_SIZE); | ||||
|     skey       = XMALLOC(MAXBLOCKSIZE); | ||||
|     if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { | ||||
|        if (pub_expt != NULL) { | ||||
|           XFREE(pub_expt); | ||||
|        } | ||||
|        if (ecc_shared != NULL) { | ||||
|           XFREE(ecc_shared); | ||||
|        } | ||||
|        if (skey != NULL) { | ||||
|           XFREE(skey); | ||||
|        } | ||||
|        ecc_free(&pubkey); | ||||
|        return CRYPT_MEM; | ||||
|     } | ||||
| 
 | ||||
|     pubkeysize = ECC_BUF_SIZE; | ||||
|     if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | ||||
|        ecc_free(&pubkey); | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* make random key */ | ||||
|     x        = ECC_BUF_SIZE; | ||||
|     if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { | ||||
|        ecc_free(&pubkey); | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|     ecc_free(&pubkey); | ||||
|     y = MAXBLOCKSIZE; | ||||
|     if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) { | ||||
|        goto LBL_ERR; | ||||
|     } | ||||
|      | ||||
|     /* Encrypt key */ | ||||
|     for (x = 0; x < inlen; x++) { | ||||
|       skey[x] ^= in[x]; | ||||
|     } | ||||
| 
 | ||||
|     err = der_encode_sequence_multi(out, outlen, | ||||
|                                     LTC_ASN1_OBJECT_IDENTIFIER,  hash_descriptor[hash].OIDlen,   hash_descriptor[hash].OID, | ||||
|                                     LTC_ASN1_OCTET_STRING,       pubkeysize,                     pub_expt, | ||||
|                                     LTC_ASN1_OCTET_STRING,       inlen,                          skey, | ||||
|                                     LTC_ASN1_EOL,                0UL,                            NULL); | ||||
| 
 | ||||
| LBL_ERR: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|     /* clean up */ | ||||
|     zeromem(pub_expt,   ECC_BUF_SIZE); | ||||
|     zeromem(ecc_shared, ECC_BUF_SIZE); | ||||
|     zeromem(skey,       MAXBLOCKSIZE); | ||||
| #endif | ||||
| 
 | ||||
|     XFREE(skey); | ||||
|     XFREE(ecc_shared); | ||||
|     XFREE(pub_expt); | ||||
| 
 | ||||
|     return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|   Decrypt an ECC encrypted key | ||||
|   @param in       The ciphertext | ||||
|   @param inlen    The length of the ciphertext (octets) | ||||
|   @param out      [out] The plaintext | ||||
|   @param outlen   [in/out] The max size and resulting size of the plaintext | ||||
|   @param key      The corresponding private ECC key | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||
|                           unsigned char *out, unsigned long *outlen,  | ||||
|                           ecc_key *key) | ||||
| { | ||||
|    unsigned char *ecc_shared, *skey, *pub_expt; | ||||
|    unsigned long  x, y, hashOID[32]; | ||||
|    int            hash, err; | ||||
|    ecc_key        pubkey; | ||||
|    ltc_asn1_list  decode[3]; | ||||
| 
 | ||||
|    LTC_ARGCHK(in     != NULL); | ||||
|    LTC_ARGCHK(out    != NULL); | ||||
|    LTC_ARGCHK(outlen != NULL); | ||||
|    LTC_ARGCHK(key    != NULL); | ||||
| 
 | ||||
|    /* right key type? */ | ||||
|    if (key->type != PK_PRIVATE) { | ||||
|       return CRYPT_PK_NOT_PRIVATE; | ||||
|    } | ||||
|     | ||||
|    /* decode to find out hash */ | ||||
|    LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); | ||||
|   | ||||
|    if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    for (hash = 0; hash_descriptor[hash].name   != NULL             &&  | ||||
|                   (hash_descriptor[hash].OIDlen != decode[0].size   ||  | ||||
|                    memcmp(hash_descriptor[hash].OID, hashOID, sizeof(unsigned long)*decode[0].size)); hash++); | ||||
| 
 | ||||
|    if (hash_descriptor[hash].name == NULL) { | ||||
|       return CRYPT_INVALID_PACKET; | ||||
|    } | ||||
| 
 | ||||
|    /* we now have the hash! */ | ||||
| 
 | ||||
|    /* allocate memory */ | ||||
|    pub_expt   = XMALLOC(ECC_BUF_SIZE); | ||||
|    ecc_shared = XMALLOC(ECC_BUF_SIZE); | ||||
|    skey       = XMALLOC(MAXBLOCKSIZE); | ||||
|    if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { | ||||
|       if (pub_expt != NULL) { | ||||
|          XFREE(pub_expt); | ||||
|       } | ||||
|       if (ecc_shared != NULL) { | ||||
|          XFREE(ecc_shared); | ||||
|       } | ||||
|       if (skey != NULL) { | ||||
|          XFREE(skey); | ||||
|       } | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
|    LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING,      pub_expt,  ECC_BUF_SIZE); | ||||
|    LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING,      skey,      MAXBLOCKSIZE); | ||||
| 
 | ||||
|    /* read the structure in now */ | ||||
|    if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* import ECC key from packet */ | ||||
|    if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* make shared key */ | ||||
|    x = ECC_BUF_SIZE; | ||||
|    if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) { | ||||
|       ecc_free(&pubkey); | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
|    ecc_free(&pubkey); | ||||
| 
 | ||||
|    y = MAXBLOCKSIZE; | ||||
|    if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) { | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* ensure the hash of the shared secret is at least as big as the encrypt itself */ | ||||
|    if (decode[2].size > y) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* avoid buffer overflow */ | ||||
|    if (*outlen < decode[2].size) { | ||||
|       err = CRYPT_BUFFER_OVERFLOW; | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
| 
 | ||||
|    /* Decrypt the key */ | ||||
|    for (x = 0; x < decode[2].size; x++) { | ||||
|      out[x] = skey[x] ^ ecc_shared[x]; | ||||
|    } | ||||
|    *outlen = x; | ||||
| 
 | ||||
|    err = CRYPT_OK; | ||||
| LBL_ERR: | ||||
| #ifdef LTC_CLEAN_STACK | ||||
|    zeromem(pub_expt,   ECC_BUF_SIZE); | ||||
|    zeromem(ecc_shared, ECC_BUF_SIZE); | ||||
|    zeromem(skey,       MAXBLOCKSIZE); | ||||
| #endif | ||||
| 
 | ||||
|    XFREE(pub_expt); | ||||
|    XFREE(ecc_shared); | ||||
|    XFREE(skey); | ||||
| 
 | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|   Sign a message digest | ||||
|   @param in        The message digest to sign | ||||
|   @param inlen     The length of the digest | ||||
|   @param out       [out] The destination for the signature | ||||
|   @param outlen    [in/out] The max size and resulting size of the signature | ||||
|   @param prng      An active PRNG state | ||||
|   @param wprng     The index of the PRNG you wish to use | ||||
|   @param key       A private ECC key | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,  | ||||
|                         unsigned char *out, unsigned long *outlen,  | ||||
|                         prng_state *prng, int wprng, ecc_key *key) | ||||
| { | ||||
|    ecc_key       pubkey; | ||||
|    void          *r, *s, *e, *p; | ||||
|    int           err; | ||||
| 
 | ||||
|    LTC_ARGCHK(in     != NULL); | ||||
|    LTC_ARGCHK(out    != NULL); | ||||
|    LTC_ARGCHK(outlen != NULL); | ||||
|    LTC_ARGCHK(key    != NULL); | ||||
| 
 | ||||
|    /* is this a private key? */ | ||||
|    if (key->type != PK_PRIVATE) { | ||||
|       return CRYPT_PK_NOT_PRIVATE; | ||||
|    } | ||||
|     | ||||
|    /* is the IDX valid ?  */ | ||||
|    if (is_valid_idx(key->idx) != 1) { | ||||
|       return CRYPT_PK_INVALID_TYPE; | ||||
|    } | ||||
|     | ||||
|    if ((err = prng_is_valid(wprng)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    /* get the hash and load it as a bignum into 'e' */ | ||||
|    /* init the bignums */ | ||||
|    if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {  | ||||
|       ecc_free(&pubkey); | ||||
|       goto LBL_ERR; | ||||
|    } | ||||
|    if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)        { goto error; } | ||||
|    if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK)  { goto error; } | ||||
| 
 | ||||
|    /* make up a key and export the public copy */ | ||||
|    for (;;) { | ||||
|       if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) { | ||||
|          return err; | ||||
|       } | ||||
| 
 | ||||
|       /* find r = x1 mod n */ | ||||
|       if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK)                           { goto error; } | ||||
| 
 | ||||
|       if (mp_iszero(r)) { | ||||
|          ecc_free(&pubkey); | ||||
|       } else {  | ||||
|         /* find s = (e + xr)/k */ | ||||
|         if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK)            { goto error; } /* k = 1/k */ | ||||
|         if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK)                 { goto error; } /* s = xr */ | ||||
|         if ((err = mp_add(e, s, s)) != CRYPT_OK)                      { goto error; } /* s = e +  xr */ | ||||
|         if ((err = mp_mod(s, p, s)) != CRYPT_OK)                      { goto error; } /* s = e +  xr */ | ||||
|         if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK)               { goto error; } /* s = (e + xr)/k */ | ||||
| 
 | ||||
|         if (mp_iszero(s)) { | ||||
|            ecc_free(&pubkey); | ||||
|         } else { | ||||
|            break; | ||||
|         } | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    /* store as SEQUENCE { r, s -- integer } */ | ||||
|    err = der_encode_sequence_multi(out, outlen, | ||||
|                              LTC_ASN1_INTEGER, 1UL, r, | ||||
|                              LTC_ASN1_INTEGER, 1UL, s, | ||||
|                              LTC_ASN1_EOL, 0UL, NULL); | ||||
|    goto LBL_ERR; | ||||
| error: | ||||
| LBL_ERR: | ||||
|    mp_clear_multi(r, s, p, e, NULL); | ||||
|    ecc_free(&pubkey); | ||||
| 
 | ||||
|    return err;    | ||||
| } | ||||
| 
 | ||||
| /* verify 
 | ||||
|  * | ||||
|  * w  = s^-1 mod n | ||||
|  * u1 = xw  | ||||
|  * u2 = rw | ||||
|  * X = u1*G + u2*Q | ||||
|  * v = X_x1 mod n | ||||
|  * accept if v == r | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|    Verify an ECC signature | ||||
|    @param sig         The signature to verify | ||||
|    @param siglen      The length of the signature (octets) | ||||
|    @param hash        The hash (message digest) that was signed | ||||
|    @param hashlen     The length of the hash (octets) | ||||
|    @param stat        Result of signature, 1==valid, 0==invalid | ||||
|    @param key         The corresponding public ECC key | ||||
|    @return CRYPT_OK if successful (even if the signature is not valid) | ||||
| */ | ||||
| int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen, | ||||
|                     const unsigned char *hash, unsigned long hashlen,  | ||||
|                     int *stat, ecc_key *key) | ||||
| { | ||||
|    ecc_point    *mG, *mQ; | ||||
|    void          *r, *s, *v, *w, *u1, *u2, *e, *p, *m; | ||||
|    void          *mp; | ||||
|    int           err; | ||||
| 
 | ||||
|    LTC_ARGCHK(sig  != NULL); | ||||
|    LTC_ARGCHK(hash != NULL); | ||||
|    LTC_ARGCHK(stat != NULL); | ||||
|    LTC_ARGCHK(key  != NULL); | ||||
| 
 | ||||
|    /* default to invalid signature */ | ||||
|    *stat = 0; | ||||
|    mp    = NULL; | ||||
| 
 | ||||
|    /* is the IDX valid ?  */ | ||||
|    if (is_valid_idx(key->idx) != 1) { | ||||
|       return CRYPT_PK_INVALID_TYPE; | ||||
|    } | ||||
| 
 | ||||
|    /* allocate ints */ | ||||
|    if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) { | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    /* allocate points */ | ||||
|    mG = ltc_ecc_new_point(); | ||||
|    mQ = ltc_ecc_new_point(); | ||||
|    if (mQ  == NULL || mG == NULL) { | ||||
|       err = CRYPT_MEM; | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* parse header */ | ||||
|    if ((err = der_decode_sequence_multi(sig, siglen, | ||||
|                                   LTC_ASN1_INTEGER, 1UL, r, | ||||
|                                   LTC_ASN1_INTEGER, 1UL, s, | ||||
|                                   LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* get the order */ | ||||
|    if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)                  { goto error; } | ||||
| 
 | ||||
|    /* get the modulus */ | ||||
|    if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)                  { goto error; } | ||||
| 
 | ||||
|    /* check for zero */ | ||||
|    if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* read hash */ | ||||
|    if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK)                { goto error; } | ||||
| 
 | ||||
|    /*  w  = s^-1 mod n */ | ||||
|    if ((err = mp_invmod(s, p, w)) != CRYPT_OK)                                                          { goto error; } | ||||
| 
 | ||||
|    /* u1 = ew */ | ||||
|    if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK)                                                      { goto error; } | ||||
| 
 | ||||
|    /* u2 = rw */ | ||||
|    if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK)                                                      { goto error; } | ||||
| 
 | ||||
|    /* find mG = u1*G */ | ||||
|    if ((err = mp_read_radix(mG->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK)                 { goto error; } | ||||
|    if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK)                 { goto error; } | ||||
|    mp_set(mG->z, 1);   | ||||
|    if ((err = ltc_ecc_mulmod(u1, mG, mG, m, 0)) != CRYPT_OK)                                            { goto done; } | ||||
| 
 | ||||
|    /* find mQ = u2*Q */ | ||||
|    if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK)                                               { goto error; } | ||||
|    if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK)                                               { goto error; } | ||||
|    if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK)                                               { goto error; } | ||||
|    if ((err = ltc_ecc_mulmod(u2, mQ, mQ, m, 0)) != CRYPT_OK)                                            { goto done; } | ||||
|    | ||||
|    /* find the montgomery mp */ | ||||
|    if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK)                                                 { goto error; } | ||||
|    /* add them */ | ||||
|    if (ltc_mp.ecc_ptadd != NULL) { | ||||
|       if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK)                                      { goto done; } | ||||
|    } else { | ||||
|       if ((err = ltc_ecc_add_point(mQ, mG, mG, m, mp)) != CRYPT_OK)                                     { goto done; } | ||||
|    } | ||||
|     | ||||
|    /* reduce */ | ||||
|    if (ltc_mp.ecc_map != NULL) { | ||||
|       if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK)                                                { goto done; } | ||||
|    } else { | ||||
|       if ((err = ltc_ecc_map(mG, m, mp)) != CRYPT_OK)                                                   { goto done; } | ||||
|    } | ||||
| 
 | ||||
|    /* v = X_x1 mod n */ | ||||
|    if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK)                                                         { goto done; } | ||||
| 
 | ||||
|    /* does v == r */ | ||||
|    if (mp_cmp(v, r) == LTC_MP_EQ) { | ||||
|       *stat = 1; | ||||
|    } | ||||
| 
 | ||||
|    /* clear up and return */ | ||||
|    err = CRYPT_OK; | ||||
|    goto done; | ||||
| error: | ||||
| done: | ||||
|    ltc_ecc_del_point(mG); | ||||
|    ltc_ecc_del_point(mQ); | ||||
|    mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL); | ||||
|    if (mp != NULL) {  | ||||
|       mp_montgomery_free(mp); | ||||
|    } | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
							
								
								
									
										96
									
								
								src/pk/ecc/ecc_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/pk/ecc/ecc_test.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_test.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Perform on the ECC system | ||||
|   @return CRYPT_OK if successful | ||||
| */ | ||||
| int ecc_test(void) | ||||
| { | ||||
|    void     *modulus, *order; | ||||
|    ecc_point  *G, *GG; | ||||
|    int i, err, primality; | ||||
| 
 | ||||
|    if ((err = mp_init_multi(&modulus, &order, NULL)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    G   = ltc_ecc_new_point(); | ||||
|    GG  = ltc_ecc_new_point(); | ||||
|    if (G == NULL || GG == NULL) { | ||||
|       mp_clear_multi(modulus, order, NULL); | ||||
|       ltc_ecc_del_point(G); | ||||
|       ltc_ecc_del_point(GG); | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    for (i = 0; ltc_ecc_sets[i].size; i++) { | ||||
|        #if 0 | ||||
|           printf("Testing %d\n", ltc_ecc_sets[i].size); | ||||
|        #endif | ||||
|        if ((err = mp_read_radix(modulus, (char *)ltc_ecc_sets[i].prime, 64)) != CRYPT_OK)   { goto done; } | ||||
|        if ((err = mp_read_radix(order, (char *)ltc_ecc_sets[i].order, 64)) != CRYPT_OK)     { goto done; } | ||||
| 
 | ||||
|        /* is prime actually prime? */ | ||||
|        if ((err = mp_prime_is_prime(modulus, 8, &primality)) != CRYPT_OK)                   { goto done; } | ||||
|        if (primality == 0) { | ||||
|           err = CRYPT_FAIL_TESTVECTOR; | ||||
|           goto done; | ||||
|        } | ||||
| 
 | ||||
|        /* is order prime ? */ | ||||
|        if ((err = mp_prime_is_prime(order, 8, &primality)) != CRYPT_OK)                     { goto done; } | ||||
|        if (primality == 0) { | ||||
|           err = CRYPT_FAIL_TESTVECTOR; | ||||
|           goto done; | ||||
|        } | ||||
| 
 | ||||
|        if ((err = mp_read_radix(G->x, (char *)ltc_ecc_sets[i].Gx, 64)) != CRYPT_OK)         { goto done; } | ||||
|        if ((err = mp_read_radix(G->y, (char *)ltc_ecc_sets[i].Gy, 64)) != CRYPT_OK)         { goto done; } | ||||
|        mp_set(G->z, 1); | ||||
| 
 | ||||
|        /* then we should have G == (order + 1)G */ | ||||
|        if ((err = mp_add_d(order, 1, order)) != CRYPT_OK)                                   { goto done; } | ||||
|        if ((err = ltc_mp.ecc_ptmul(order, G, GG, modulus, 1)) != CRYPT_OK)                  { goto done; } | ||||
|        if (mp_cmp(G->x, GG->x) != LTC_MP_EQ || mp_cmp(G->y, GG->y) != LTC_MP_EQ) { | ||||
|           err = CRYPT_FAIL_TESTVECTOR; | ||||
|           goto done; | ||||
|        } | ||||
|    } | ||||
|    err = CRYPT_OK; | ||||
|    goto done; | ||||
| done: | ||||
|    ltc_ecc_del_point(GG); | ||||
|    ltc_ecc_del_point(G); | ||||
|    mp_clear_multi(order, modulus, NULL); | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										160
									
								
								src/pk/ecc/ecc_verify_hash.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/pk/ecc/ecc_verify_hash.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,160 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ecc_verify_hash.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /* verify 
 | ||||
|  * | ||||
|  * w  = s^-1 mod n | ||||
|  * u1 = xw  | ||||
|  * u2 = rw | ||||
|  * X = u1*G + u2*Q | ||||
|  * v = X_x1 mod n | ||||
|  * accept if v == r | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|    Verify an ECC signature | ||||
|    @param sig         The signature to verify | ||||
|    @param siglen      The length of the signature (octets) | ||||
|    @param hash        The hash (message digest) that was signed | ||||
|    @param hashlen     The length of the hash (octets) | ||||
|    @param stat        Result of signature, 1==valid, 0==invalid | ||||
|    @param key         The corresponding public ECC key | ||||
|    @return CRYPT_OK if successful (even if the signature is not valid) | ||||
| */ | ||||
| int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen, | ||||
|                     const unsigned char *hash, unsigned long hashlen,  | ||||
|                     int *stat, ecc_key *key) | ||||
| { | ||||
|    ecc_point    *mG, *mQ; | ||||
|    void          *r, *s, *v, *w, *u1, *u2, *e, *p, *m; | ||||
|    void          *mp; | ||||
|    int           err; | ||||
| 
 | ||||
|    LTC_ARGCHK(sig  != NULL); | ||||
|    LTC_ARGCHK(hash != NULL); | ||||
|    LTC_ARGCHK(stat != NULL); | ||||
|    LTC_ARGCHK(key  != NULL); | ||||
| 
 | ||||
|    /* default to invalid signature */ | ||||
|    *stat = 0; | ||||
|    mp    = NULL; | ||||
| 
 | ||||
|    /* is the IDX valid ?  */ | ||||
|    if (ltc_ecc_is_valid_idx(key->idx) != 1) { | ||||
|       return CRYPT_PK_INVALID_TYPE; | ||||
|    } | ||||
| 
 | ||||
|    /* allocate ints */ | ||||
|    if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) { | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    /* allocate points */ | ||||
|    mG = ltc_ecc_new_point(); | ||||
|    mQ = ltc_ecc_new_point(); | ||||
|    if (mQ  == NULL || mG == NULL) { | ||||
|       err = CRYPT_MEM; | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* parse header */ | ||||
|    if ((err = der_decode_sequence_multi(sig, siglen, | ||||
|                                   LTC_ASN1_INTEGER, 1UL, r, | ||||
|                                   LTC_ASN1_INTEGER, 1UL, s, | ||||
|                                   LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* get the order */ | ||||
|    if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK)                  { goto error; } | ||||
| 
 | ||||
|    /* get the modulus */ | ||||
|    if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK)                  { goto error; } | ||||
| 
 | ||||
|    /* check for zero */ | ||||
|    if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { | ||||
|       err = CRYPT_INVALID_PACKET; | ||||
|       goto done; | ||||
|    } | ||||
| 
 | ||||
|    /* read hash */ | ||||
|    if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK)                { goto error; } | ||||
| 
 | ||||
|    /*  w  = s^-1 mod n */ | ||||
|    if ((err = mp_invmod(s, p, w)) != CRYPT_OK)                                                          { goto error; } | ||||
| 
 | ||||
|    /* u1 = ew */ | ||||
|    if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK)                                                      { goto error; } | ||||
| 
 | ||||
|    /* u2 = rw */ | ||||
|    if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK)                                                      { goto error; } | ||||
| 
 | ||||
|    /* find mG = u1*G */ | ||||
|    if ((err = mp_read_radix(mG->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK)                 { goto error; } | ||||
|    if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK)                 { goto error; } | ||||
|    mp_set(mG->z, 1);   | ||||
|    if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK)                                          { goto done; } | ||||
| 
 | ||||
|    /* find mQ = u2*Q */ | ||||
|    if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK)                                               { goto error; } | ||||
|    if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK)                                               { goto error; } | ||||
|    if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK)                                               { goto error; } | ||||
|    if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK)                                          { goto done; } | ||||
|    | ||||
|    /* find the montgomery mp */ | ||||
|    if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK)                                                 { goto error; } | ||||
|    /* add them */ | ||||
|    if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK)                                         { goto done; } | ||||
|     | ||||
|    /* reduce */ | ||||
|    if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK)                                                   { goto done; } | ||||
| 
 | ||||
|    /* v = X_x1 mod n */ | ||||
|    if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK)                                                         { goto done; } | ||||
| 
 | ||||
|    /* does v == r */ | ||||
|    if (mp_cmp(v, r) == LTC_MP_EQ) { | ||||
|       *stat = 1; | ||||
|    } | ||||
| 
 | ||||
|    /* clear up and return */ | ||||
|    err = CRYPT_OK; | ||||
|    goto done; | ||||
| error: | ||||
| done: | ||||
|    ltc_ecc_del_point(mG); | ||||
|    ltc_ecc_del_point(mQ); | ||||
|    mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL); | ||||
|    if (mp != NULL) {  | ||||
|       mp_montgomery_free(mp); | ||||
|    } | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										45
									
								
								src/pk/ecc/ltc_ecc_is_valid_idx.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/pk/ecc/ltc_ecc_is_valid_idx.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ltc_ecc_is_valid_idx.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /** Returns whether an ECC idx is valid or not
 | ||||
|   @param n   The idx number to check | ||||
|   @return 1 if valid, 0 if not | ||||
| */   | ||||
| int ltc_ecc_is_valid_idx(int n) | ||||
| { | ||||
|    int x; | ||||
| 
 | ||||
|    for (x = 0; ltc_ecc_sets[x].size != 0; x++); | ||||
|    if ((n < 0) || (n >= x)) { | ||||
|       return 0; | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										77
									
								
								src/pk/ecc/ltc_ecc_map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/pk/ecc/ltc_ecc_map.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ltc_ecc_map.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|   Map a projective jacbobian point back to affine space | ||||
|   @param P        [in/out] The point to map | ||||
|   @param modulus  The modulus of the field the ECC curve is in | ||||
|   @param mp       The "b" value from montgomery_setup() | ||||
|   @return CRYPT_OK on success | ||||
| */ | ||||
| int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) | ||||
| { | ||||
|    void *t1, *t2; | ||||
|    int err; | ||||
| 
 | ||||
|    LTC_ARGCHK(P       != NULL); | ||||
|    LTC_ARGCHK(modulus != NULL); | ||||
|    LTC_ARGCHK(mp      != NULL); | ||||
| 
 | ||||
|    if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { | ||||
|       return CRYPT_MEM; | ||||
|    } | ||||
| 
 | ||||
|    /* first map z back to normal */ | ||||
|    if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK)           { goto done; } | ||||
| 
 | ||||
|    /* get 1/z */ | ||||
|    if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK)                      { goto done; } | ||||
|   | ||||
|    /* get 1/z^2 and 1/z^3 */ | ||||
|    if ((err = mp_sqr(t1, t2)) != CRYPT_OK)                                    { goto done; } | ||||
|    if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK)                           { goto done; } | ||||
|    if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK)                                { goto done; } | ||||
|    if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK)                           { goto done; } | ||||
| 
 | ||||
|    /* multiply against x/y */ | ||||
|    if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK)                            { goto done; } | ||||
|    if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK)           { goto done; } | ||||
|    if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK)                            { goto done; } | ||||
|    if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK)           { goto done; } | ||||
|    mp_set(P->z, 1); | ||||
| 
 | ||||
|    err = CRYPT_OK; | ||||
|    goto done; | ||||
| done: | ||||
|    mp_clear_multi(t1, t2, NULL); | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										213
									
								
								src/pk/ecc/ltc_ecc_mulmod.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								src/pk/ecc/ltc_ecc_mulmod.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,213 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ltc_ecc_mulmod.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| #ifndef LTC_ECC_TIMING_RESISTANT | ||||
| 
 | ||||
| /* size of sliding window, don't change this! */ | ||||
| #define WINSIZE 4 | ||||
| 
 | ||||
| /**
 | ||||
|    Perform a point multiplication  | ||||
|    @param k    The scalar to multiply by | ||||
|    @param G    The base point | ||||
|    @param R    [out] Destination for kG | ||||
|    @param modulus  The modulus of the field the ECC curve is in | ||||
|    @param map      Boolean whether to map back to affine or not (1==map, 0 == leave in projective) | ||||
|    @return CRYPT_OK on success | ||||
| */ | ||||
| int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) | ||||
| { | ||||
|    ecc_point *tG, *M[8]; | ||||
|    int        i, j, err; | ||||
|    void       *mu, *mp; | ||||
|    unsigned long buf; | ||||
|    int        first, bitbuf, bitcpy, bitcnt, mode, digidx; | ||||
| 
 | ||||
|    LTC_ARGCHK(k       != NULL); | ||||
|    LTC_ARGCHK(G       != NULL); | ||||
|    LTC_ARGCHK(R       != NULL); | ||||
|    LTC_ARGCHK(modulus != NULL); | ||||
| 
 | ||||
|    /* init montgomery reduction */ | ||||
|    if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    if ((err = mp_init(&mu)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { | ||||
|       mp_montgomery_free(mp); | ||||
|       mp_clear(mu); | ||||
|       return err; | ||||
|    } | ||||
|    | ||||
|   /* alloc ram for window temps */ | ||||
|   for (i = 0; i < 8; i++) { | ||||
|       M[i] = ltc_ecc_new_point(); | ||||
|       if (M[i] == NULL) { | ||||
|          for (j = 0; j < i; j++) { | ||||
|              ltc_ecc_del_point(M[j]); | ||||
|          } | ||||
|          mp_montgomery_free(mp); | ||||
|          mp_clear(mu); | ||||
|          return CRYPT_MEM; | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
|    /* make a copy of G incase R==G */ | ||||
|    tG = ltc_ecc_new_point(); | ||||
|    if (tG == NULL)                                                                   { err = CRYPT_MEM; goto done; } | ||||
| 
 | ||||
|    /* tG = G  and convert to montgomery */ | ||||
|    if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { | ||||
|       if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK)                                  { goto done; } | ||||
|       if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK)                                  { goto done; } | ||||
|       if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK)                                  { goto done; } | ||||
|    } else {       | ||||
|       if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK)                   { goto done; } | ||||
|       if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK)                   { goto done; } | ||||
|       if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK)                   { goto done; } | ||||
|    } | ||||
|    mp_clear(mu); | ||||
|     | ||||
|    /* calc the M tab, which holds kG for k==8..15 */ | ||||
|    /* M[0] == 8G */ | ||||
|    if ((err = ltc_ecc_projective_dbl_point(tG, M[0], modulus, mp)) != CRYPT_OK)               { goto done; } | ||||
|    if ((err = ltc_ecc_projective_dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK)               { goto done; } | ||||
|    if ((err = ltc_ecc_projective_dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK)               { goto done; } | ||||
| 
 | ||||
|    /* now find (8+k)G for k=1..7 */ | ||||
|    for (j = 9; j < 16; j++) { | ||||
|        if ((err = ltc_ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK)   { goto done; } | ||||
|    } | ||||
| 
 | ||||
|    /* setup sliding window */ | ||||
|    mode   = 0; | ||||
|    bitcnt = 1; | ||||
|    buf    = 0; | ||||
|    digidx = mp_get_digit_count(k) - 1; | ||||
|    bitcpy = bitbuf = 0; | ||||
|    first  = 1; | ||||
| 
 | ||||
|    /* perform ops */ | ||||
|    for (;;) { | ||||
|      /* grab next digit as required */ | ||||
|      if (--bitcnt == 0) { | ||||
|        if (digidx == -1) { | ||||
|           break; | ||||
|        } | ||||
|        buf    = mp_get_digit(k, digidx); | ||||
|        bitcnt = (int) MP_DIGIT_BIT; | ||||
|        --digidx; | ||||
|      } | ||||
| 
 | ||||
|      /* grab the next msb from the ltiplicand */ | ||||
|      i = (buf >> (MP_DIGIT_BIT - 1)) & 1; | ||||
|      buf <<= 1; | ||||
| 
 | ||||
|      /* skip leading zero bits */ | ||||
|      if (mode == 0 && i == 0) { | ||||
|         continue; | ||||
|      } | ||||
| 
 | ||||
|      /* if the bit is zero and mode == 1 then we double */ | ||||
|      if (mode == 1 && i == 0) { | ||||
|         if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK)                 { goto done; } | ||||
|         continue; | ||||
|      } | ||||
| 
 | ||||
|      /* else we add it to the window */ | ||||
|      bitbuf |= (i << (WINSIZE - ++bitcpy)); | ||||
|      mode = 2; | ||||
| 
 | ||||
|      if (bitcpy == WINSIZE) { | ||||
|        /* if this is the first window we do a simple copy */ | ||||
|        if (first == 1) { | ||||
|           /* R = kG [k = first window] */ | ||||
|           if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK)                     { goto done; } | ||||
|           if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK)                     { goto done; } | ||||
|           if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK)                     { goto done; } | ||||
|           first = 0; | ||||
|        } else { | ||||
|          /* normal window */ | ||||
|          /* ok window is filled so double as required and add  */ | ||||
|          /* double first */ | ||||
|          for (j = 0; j < WINSIZE; j++) { | ||||
|            if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK)             { goto done; } | ||||
|          } | ||||
| 
 | ||||
|          /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ | ||||
|          if ((err = ltc_ecc_projective_add_point(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK)  { goto done; } | ||||
|        } | ||||
|        /* empty window and reset */ | ||||
|        bitcpy = bitbuf = 0; | ||||
|        mode = 1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|    /* if bits remain then double/add */ | ||||
|    if (mode == 2 && bitcpy > 0) { | ||||
|      /* double then add */ | ||||
|      for (j = 0; j < bitcpy; j++) { | ||||
|        /* only double if we have had at least one add first */ | ||||
|        if (first == 0) { | ||||
|           if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK)             { goto done; } | ||||
|        } | ||||
| 
 | ||||
|        bitbuf <<= 1; | ||||
|        if ((bitbuf & (1 << WINSIZE)) != 0) { | ||||
|          if (first == 1){ | ||||
|             /* first add, so copy */ | ||||
|             if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK)                           { goto done; } | ||||
|             if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK)                           { goto done; } | ||||
|             if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK)                           { goto done; } | ||||
|             first = 0; | ||||
|          } else { | ||||
|             /* then add */ | ||||
|             if ((err = ltc_ecc_projective_add_point(R, tG, R, modulus, mp)) != CRYPT_OK)       { goto done; } | ||||
|          } | ||||
|        } | ||||
|      } | ||||
|    } | ||||
| 
 | ||||
|    /* map R back from projective space */ | ||||
|    if (map) { | ||||
|       err = ltc_ecc_map(R, modulus, mp); | ||||
|    } else { | ||||
|       err = CRYPT_OK; | ||||
|    } | ||||
| done: | ||||
|    mp_montgomery_free(mp); | ||||
|    ltc_ecc_del_point(tG); | ||||
|    for (i = 0; i < 8; i++) { | ||||
|        ltc_ecc_del_point(M[i]); | ||||
|    } | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #undef WINSIZE | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										162
									
								
								src/pk/ecc/ltc_ecc_mulmod_timing.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/pk/ecc/ltc_ecc_mulmod_timing.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ltc_ecc_mulmod_timing.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| #ifdef LTC_ECC_TIMING_RESISTANT | ||||
| 
 | ||||
| /**
 | ||||
|    Perform a point multiplication  (timing resistant) | ||||
|    @param k    The scalar to multiply by | ||||
|    @param G    The base point | ||||
|    @param R    [out] Destination for kG | ||||
|    @param modulus  The modulus of the field the ECC curve is in | ||||
|    @param map      Boolean whether to map back to affine or not (1==map, 0 == leave in projective) | ||||
|    @return CRYPT_OK on success | ||||
| */ | ||||
| int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) | ||||
| { | ||||
|    ecc_point *tG, *M[3]; | ||||
|    int        i, j, err; | ||||
|    void       *mu, *mp; | ||||
|    unsigned long buf; | ||||
|    int        first, bitbuf, bitcpy, bitcnt, mode, digidx; | ||||
| 
 | ||||
|    LTC_ARGCHK(k       != NULL); | ||||
|    LTC_ARGCHK(G       != NULL); | ||||
|    LTC_ARGCHK(R       != NULL); | ||||
|    LTC_ARGCHK(modulus != NULL); | ||||
| 
 | ||||
|    /* init montgomery reduction */ | ||||
|    if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    if ((err = mp_init(&mu)) != CRYPT_OK) { | ||||
|       return err; | ||||
|    } | ||||
|    if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { | ||||
|       mp_montgomery_free(mp); | ||||
|       mp_clear(mu); | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|   /* alloc ram for window temps */ | ||||
|   for (i = 0; i < 3; i++) { | ||||
|       M[i] = ltc_ecc_new_point(); | ||||
|       if (M[i] == NULL) { | ||||
|          for (j = 0; j < i; j++) { | ||||
|              ltc_ecc_del_point(M[j]); | ||||
|          } | ||||
|          mp_montgomery_free(mp); | ||||
|          mp_clear(mu); | ||||
|          return CRYPT_MEM; | ||||
|       } | ||||
|   } | ||||
| 
 | ||||
|    /* make a copy of G incase R==G */ | ||||
|    tG = ltc_ecc_new_point(); | ||||
|    if (tG == NULL)                                                                   { err = CRYPT_MEM; goto done; } | ||||
| 
 | ||||
|    /* tG = G  and convert to montgomery */ | ||||
|    if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK)                      { goto done; } | ||||
|    if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK)                      { goto done; } | ||||
|    if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK)                      { goto done; } | ||||
|    mp_clear(mu); | ||||
|     | ||||
|    /* calc the M tab, which holds kG for k==8..15 */ | ||||
|    /* M[0] == G */ | ||||
|    if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK)                                   { goto done; } | ||||
|    if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK)                                   { goto done; } | ||||
|    if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK)                                   { goto done; } | ||||
|    /* M[1] == 2G */ | ||||
|    if ((err = ltc_ecc_projective_dbl_point(tG, M[1], modulus, mp)) != CRYPT_OK)                  { goto done; } | ||||
| 
 | ||||
|    /* setup sliding window */ | ||||
|    mode   = 0; | ||||
|    bitcnt = 1; | ||||
|    buf    = 0; | ||||
|    digidx = mp_get_digit_count(k) - 1; | ||||
|    bitcpy = bitbuf = 0; | ||||
|    first  = 1; | ||||
| 
 | ||||
|    /* perform ops */ | ||||
|    for (;;) { | ||||
|      /* grab next digit as required */ | ||||
|       if (--bitcnt == 0) { | ||||
|          if (digidx == -1) { | ||||
|             break; | ||||
|          } | ||||
|          buf    = mp_get_digit(k, digidx); | ||||
|          bitcnt = (int) MP_DIGIT_BIT; | ||||
|          --digidx; | ||||
|       } | ||||
| 
 | ||||
|       /* grab the next msb from the ltiplicand */ | ||||
|       i = (buf >> (MP_DIGIT_BIT - 1)) & 1; | ||||
|       buf <<= 1; | ||||
| 
 | ||||
|       if (mode == 0 && i == 0) { | ||||
|          /* dummy operations */ | ||||
|          if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK)    { goto done; } | ||||
|          if ((err = ltc_ecc_projective_dbl_point(M[1], M[2], modulus, mp)) != CRYPT_OK)          { goto done; } | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       if (mode == 0 && i == 1) { | ||||
|          mode = 1; | ||||
|          /* dummy operations */ | ||||
|          if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK)    { goto done; } | ||||
|          if ((err = ltc_ecc_projective_dbl_point(M[1], M[2], modulus, mp)) != CRYPT_OK)          { goto done; } | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK)    { goto done; } | ||||
|       if ((err = ltc_ecc_projective_dbl_point(M[i], M[i], modulus, mp)) != CRYPT_OK)            { goto done; } | ||||
|    } | ||||
| 
 | ||||
|    /* copy result out */ | ||||
|    if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK)                                   { goto done; } | ||||
|    if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK)                                   { goto done; } | ||||
|    if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK)                                   { goto done; } | ||||
| 
 | ||||
|    /* map R back from projective space */ | ||||
|    if (map) { | ||||
|       err = ltc_ecc_map(R, modulus, mp); | ||||
|    } else { | ||||
|       err = CRYPT_OK; | ||||
|    } | ||||
| done: | ||||
|    mp_montgomery_free(mp); | ||||
|    ltc_ecc_del_point(tG); | ||||
|    for (i = 0; i < 3; i++) { | ||||
|        ltc_ecc_del_point(M[i]); | ||||
|    } | ||||
|    return err; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
							
								
								
									
										60
									
								
								src/pk/ecc/ltc_ecc_points.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/pk/ecc/ltc_ecc_points.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | ||||
| /* LibTomCrypt, modular cryptographic library -- Tom St Denis
 | ||||
|  * | ||||
|  * LibTomCrypt is a library that provides various cryptographic | ||||
|  * algorithms in a highly modular and flexible manner. | ||||
|  * | ||||
|  * The library is free for all purposes without any express | ||||
|  * guarantee it works. | ||||
|  * | ||||
|  * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
 | ||||
|  */ | ||||
| 
 | ||||
| /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
 | ||||
|  * | ||||
|  * All curves taken from NIST recommendation paper of July 1999 | ||||
|  * Available at http://csrc.nist.gov/cryptval/dss.htm
 | ||||
|  */ | ||||
| #include "tomcrypt.h" | ||||
| 
 | ||||
| /**
 | ||||
|   @file ltc_ecc_points.c | ||||
|   ECC Crypto, Tom St Denis | ||||
| */   | ||||
| 
 | ||||
| #ifdef MECC | ||||
| 
 | ||||
| /**
 | ||||
|    Allocate a new ECC point | ||||
|    @return A newly allocated point or NULL on error  | ||||
| */ | ||||
| ecc_point *ltc_ecc_new_point(void) | ||||
| { | ||||
|    ecc_point *p; | ||||
|    p = XMALLOC(sizeof(*p)); | ||||
|    if (p == NULL) { | ||||
|       return NULL; | ||||
|    } | ||||
|    if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) { | ||||
|       XFREE(p); | ||||
|       return NULL; | ||||
|    } | ||||
|    return p; | ||||
| } | ||||
| 
 | ||||
| /** Free an ECC point from memory
 | ||||
|   @param p   The point to free | ||||
| */ | ||||
| void ltc_ecc_del_point(ecc_point *p) | ||||
| { | ||||
|    /* prevents free'ing null arguments */ | ||||
|    if (p != NULL) { | ||||
|       mp_clear_multi(p->x, p->y, p->z, NULL); | ||||
|       XFREE(p); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| /* $Source$ */ | ||||
| /* $Revision$ */ | ||||
| /* $Date$ */ | ||||
| 
 | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user