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  | # This could be handy for archiving the generated documentation or  | ||||||
| # if some version control system is used. | # if some version control system is used. | ||||||
| 
 | 
 | ||||||
| PROJECT_NUMBER         = 1.06 | PROJECT_NUMBER         = 1.07 | ||||||
| 
 | 
 | ||||||
| # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)  | # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)  | ||||||
| # base path where the generated documentation will be put.  | # base path where the generated documentation will be put.  | ||||||
|  | |||||||
							
								
								
									
										37
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								TODO
									
									
									
									
									
								
							| @ -1,6 +1,43 @@ | |||||||
| For 1.07 | For 1.07 | ||||||
| 
 | 
 | ||||||
|  |                  | ||||||
| 1. [3 hours]    ASN.1 SET and T61String [punishment, add UTF8 to the list!] | 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 | August 1st, 2005 | ||||||
| v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson] | 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] |       -- 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 | 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) |        -- Deprecated LTMSSE and removed it (to be replaced with TFM later on) | ||||||
|        -- Stefan Arentz pointed out that mp_s_rmap should be extern |        -- 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] |           "test" makefile and minor issues in Yarrow and Sober [just cosmetics really] | ||||||
|        -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword  |        -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword  | ||||||
|           so changed the PRNG api to use "pexport" and "pimport" |           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. |           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 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 |        -- 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 |        -- Merged in LibTomMath for kicks | ||||||
|        -- Changed the build process so that by default "mycrypt_custom.h" is included and provided |        -- Changed the build process so that by default "mycrypt_custom.h" is included and provided | ||||||
|           The makefile doesn't include any build options anymore |           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. | v0.01  -- We will call this the first version. | ||||||
| 
 | 
 | ||||||
| /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ | /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ | ||||||
| /* $Revision: 1.123 $ */ | /* $Revision: 1.151 $ */ | ||||||
| /* $Date: 2005/08/01 16:50:34 $ */ | /* $Date: 2005/11/17 22:04:00 $ */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										303
									
								
								crypt.tex
									
									
									
									
									
								
							
							
						
						
									
										303
									
								
								crypt.tex
									
									
									
									
									
								
							| @ -47,7 +47,7 @@ | |||||||
| \def\gap{\vspace{0.5ex}} | \def\gap{\vspace{0.5ex}} | ||||||
| \makeindex | \makeindex | ||||||
| \begin{document} | \begin{document} | ||||||
| \title{LibTomCrypt \\ Version 1.06} | \title{LibTomCrypt \\ Version 1.07} | ||||||
| \author{Tom St Denis \\ | \author{Tom St Denis \\ | ||||||
| \\ | \\ | ||||||
| tomstdenis@gmail.com \\ | tomstdenis@gmail.com \\ | ||||||
| @ -236,8 +236,7 @@ int main(void) { | |||||||
| } | } | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| 
 | 
 | ||||||
| The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and  | The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'' and ``ctype.h''. | ||||||
| ``ltc\_tommath.h'' (the bignum library routines). |  | ||||||
| 
 | 
 | ||||||
| \section{Macros} | \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 | To encrypt or decrypt a block in ECB mode there are these two function classes | ||||||
| \index{Cipher Encrypt} \index{Cipher Decrypt} | \index{Cipher Encrypt} \index{Cipher Decrypt} | ||||||
| \begin{verbatim} | \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); |                      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); |                      symmetric_key *skey); | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on | 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  | 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  | 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 | cipher against test vectors\footnote{As published in their design papers.} call the self-test function | ||||||
|   |   | ||||||
| \subsection{Self--Testing} | \subsection{Self--Testing} | ||||||
| @ -496,39 +496,47 @@ struct _cipher_descriptor { | |||||||
|         block_length,  |         block_length,  | ||||||
|         default_rounds; |         default_rounds; | ||||||
|    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); | ||||||
|    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); | ||||||
|    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); | ||||||
|    int (*test)(void); |    int  (*test)(void); | ||||||
|    void (*done)(symmetric_key *skey);       |    void (*done)(symmetric_key *skey);       | ||||||
|    int  (*keysize)(int *keysize); |    int  (*keysize)(int *keysize); | ||||||
| 
 | 
 | ||||||
|    void (*accel_ecb_encrypt)(const unsigned char *pt,  |    int (*accel_ecb_encrypt)(const unsigned char *pt,  | ||||||
|                                    unsigned char *ct,  |                                    unsigned char *ct,  | ||||||
|                                    unsigned long blocks, symmetric_key *skey); |                                    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 char *pt,  | ||||||
|                                    unsigned long blocks, symmetric_key *skey); |                                    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 char *ct,  | ||||||
|                                    unsigned long blocks, unsigned char *IV,  |                                    unsigned long blocks, unsigned char *IV,  | ||||||
|                                    symmetric_key *skey); |                                    symmetric_key *skey); | ||||||
|    void (*accel_cbc_decrypt)(const unsigned char *ct,  |    int (*accel_cbc_decrypt)(const unsigned char *ct,  | ||||||
|                                    unsigned char *pt,  |                                    unsigned char *pt,  | ||||||
|                                    unsigned long blocks, unsigned char *IV,  |                                    unsigned long blocks, unsigned char *IV,  | ||||||
|                                    symmetric_key *skey); |                                    symmetric_key *skey); | ||||||
|    void (*accel_ctr_encrypt)(const unsigned char *pt,  |    int (*accel_ctr_encrypt)(const unsigned char *pt,  | ||||||
|                                    unsigned char *ct,  |                                    unsigned char *ct,  | ||||||
|                                    unsigned long blocks, unsigned char *IV,  |                                    unsigned long blocks, unsigned char *IV,  | ||||||
|                                    int mode, symmetric_key *skey); |                                    int mode, symmetric_key *skey); | ||||||
|    void (*accel_ccm_memory)( |    int (*accel_ccm_memory)( | ||||||
|        const unsigned char *key,    unsigned long keylen, |        const unsigned char *key,    unsigned long keylen, | ||||||
|  |        symmetric_key       *uskey, | ||||||
|        const unsigned char *nonce,  unsigned long noncelen, |        const unsigned char *nonce,  unsigned long noncelen, | ||||||
|        const unsigned char *header, unsigned long headerlen, |        const unsigned char *header, unsigned long headerlen, | ||||||
|              unsigned char *pt,     unsigned long ptlen, |              unsigned char *pt,     unsigned long ptlen, | ||||||
|              unsigned char *ct, |              unsigned char *ct, | ||||||
|              unsigned char *tag,    unsigned long *taglen, |              unsigned char *tag,    unsigned long *taglen, | ||||||
|                        int  direction); |                        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{verbatim} | ||||||
| \end{small} | \end{small} | ||||||
| @ -1200,6 +1208,7 @@ function that performs the protocol. | |||||||
| \begin{verbatim} | \begin{verbatim} | ||||||
| int ccm_memory(int cipher, | int ccm_memory(int cipher, | ||||||
|     const unsigned char *key,    unsigned long keylen, |     const unsigned char *key,    unsigned long keylen, | ||||||
|  |     symmetric_key       *uskey, | ||||||
|     const unsigned char *nonce,  unsigned long noncelen, |     const unsigned char *nonce,  unsigned long noncelen, | ||||||
|     const unsigned char *header, unsigned long headerlen, |     const unsigned char *header, unsigned long headerlen, | ||||||
|           unsigned char *pt,     unsigned long ptlen, |           unsigned char *pt,     unsigned long ptlen, | ||||||
| @ -1209,9 +1218,15 @@ int ccm_memory(int cipher, | |||||||
| \end{verbatim} | \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  | 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 | 16--byte block size for CCM.   | ||||||
| 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 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 | 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  | 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  | 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.   | $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 | Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key | ||||||
| algorithms. | algorithms. | ||||||
| 
 | 
 | ||||||
| \index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()} | \index{ecc\_encrypt\_key()} | ||||||
| \begin{verbatim} | \begin{verbatim} | ||||||
| int ecc_encrypt_key(const unsigned char *in,   unsigned long  inlen, | int ecc_encrypt_key(const unsigned char *in,   unsigned long  inlen, | ||||||
|                           unsigned char *out,  unsigned long *outlen,  |                           unsigned char *out,  unsigned long *outlen,  | ||||||
|                           prng_state *prng, int wprng, int hash,  |                           prng_state *prng, int wprng, int hash,  | ||||||
|                           ecc_key *key); |                           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, | int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||||
|                           unsigned char *out, unsigned long *outlen,  |                           unsigned char *out, unsigned long *outlen,  | ||||||
|                           ecc_key *key); |                           ecc_key *key); | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| 
 | 
 | ||||||
| Where ``in'' is an input symmetric key of no more than 64 bytes.  Essentially these routines created a random public key | This function will decrypt an encrypted payload.  The ``key'' provided must be the private key corresponding to the 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 | used during encryption.  If the wrong key is provided the function won't specifically return an error code.  It is important | ||||||
| data is placed in ``out'' by ``ecc\_encrypt\_key()''.   The hash chosen must produce a message digest at least as large | to use some form of challenge response in that case (e.g. compute a MAC of a known string). | ||||||
| as the symmetric key you are trying to share. |  | ||||||
| 
 | 
 | ||||||
| \subsection{Encrypt Packet Format} | \subsection{Encrypt Encryption Format} | ||||||
| 
 | 
 | ||||||
| The packet format for the encrypted keys is the following ASN.1 SEQUENCE: | The packet format for the encrypted keys is the following ASN.1 SEQUENCE: | ||||||
| 
 | 
 | ||||||
| @ -2935,30 +2961,40 @@ ECCEncrypt ::= SEQUENCE { | |||||||
| } | } | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| 
 | 
 | ||||||
|  | \section{ECC DSA Signatures} | ||||||
|  | 
 | ||||||
| There are also functions to sign and verify the hash of a message. | 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} | \begin{verbatim} | ||||||
| int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, | int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, | ||||||
|                         unsigned char *out, unsigned long *outlen, |                         unsigned char *out, unsigned long *outlen, | ||||||
|                         prng_state *prng, int wprng, ecc_key *key); |                         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, | int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, | ||||||
|                     const unsigned char *hash, unsigned long hashlen,  |                     const unsigned char *hash, unsigned long hashlen,  | ||||||
|                           int *stat, ecc_key *key); |                           int *stat, ecc_key *key); | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| 
 | 
 | ||||||
| The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.   | This function will verify the EC-DSA signature in ``sig'' of length ``siglen'' against the message digest ``hash''.   | ||||||
| The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''.  It sets ``stat'' | It will store a non--zero value in ``stat'' if the signature is valid.  Note that the function will not return | ||||||
| to non-zero if the signature passes or zero if it fails. | 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} | \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} | \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 | 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 | 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 | 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  | The library will not warn you if you make this mistake so it is important to check yourself before using the  | ||||||
| signatures. | 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). | 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} | \section{Signatures} | ||||||
|  | \subsection{Signature Generation} | ||||||
| To generate a DSA signature call the following function | To generate a DSA signature call the following function | ||||||
| 
 | 
 | ||||||
| \index{dsa\_sign\_hash()} | \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 | 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. | 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 | To verify a hash created with that function use the following function | ||||||
| 
 | 
 | ||||||
| \index{dsa\_verify\_hash()}  | \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''.   | 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$.   | 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} | \section{Import and Export} | ||||||
| 
 | 
 | ||||||
| To export a DSA key so that it can be transported use the following function | To export a DSA key so that it can be transported use the following function | ||||||
| @ -3137,13 +3204,16 @@ in the same manner as the other data types except they use list of objects known | |||||||
| \index{ltc\_asn1\_list structure} | \index{ltc\_asn1\_list structure} | ||||||
| \begin{verbatim} | \begin{verbatim} | ||||||
| typedef struct { | typedef struct { | ||||||
|    int           type; |    int                    type; | ||||||
|    void         *data; |    void                  *data; | ||||||
|    unsigned long size; |    unsigned long          size; | ||||||
|    int           used; |    int                    used; | ||||||
|  |    struct ltc_asn1_list_ *prev,  *next,  | ||||||
|  |                          *child, *parent; | ||||||
| } ltc_asn1_list; | } ltc_asn1_list; | ||||||
| \end{verbatim} | \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  | 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 | ``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 | 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  | 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. | 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} | \section{Password Based Cryptography} | ||||||
| \subsection{PKCS \#5} | \subsection{PKCS \#5} | ||||||
| \index{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  | 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. | 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} | \subsection{IGNORE\_SPEED} | ||||||
| \index{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 | 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. | All four can be used to create custom install locations depending on the nature of the OS and file system in use. | ||||||
| 
 | 
 | ||||||
| \begin{verbatim} | \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} | \end{verbatim} | ||||||
| 
 | 
 | ||||||
| This will build the library and install it to the directories under ``/home/tom/project/''.  e.g. | 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.   | that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time.   | ||||||
| 
 | 
 | ||||||
| \begin{verbatim} | \begin{verbatim} | ||||||
| CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared | CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install | ||||||
| \end{verbatim} | \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). | 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  | ||||||
| Note that unlike the static build there is no ``install'' target.  The default action of this make script is to install the library. | shared build process requires libtool to be installed. | ||||||
| 
 |  | ||||||
| The shared build process requires libtool to be installed. |  | ||||||
| 
 | 
 | ||||||
| \section{tomcrypt\_cfg.h} | \section{tomcrypt\_cfg.h} | ||||||
| The file ``tomcrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour  | 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 |       @param skey        [out] The destination of the scheduled key | ||||||
|       @return CRYPT_OK if successful |       @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    int  (*setup)(const unsigned char *key, int keylen,  |    int  (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | ||||||
|                  int num_rounds, symmetric_key *skey); |  | ||||||
|    /** Encrypt a block |    /** Encrypt a block | ||||||
|       @param pt      The plaintext |       @param pt      The plaintext | ||||||
|       @param ct      [out] The ciphertext |       @param ct      [out] The ciphertext | ||||||
|       @param skey    The scheduled key |       @param skey    The scheduled key | ||||||
|  |       @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*ecb_encrypt)(const unsigned char *pt,  |    int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); | ||||||
|                              unsigned char *ct, symmetric_key *skey); |  | ||||||
|    /** Decrypt a block |    /** Decrypt a block | ||||||
|       @param ct      The ciphertext |       @param ct      The ciphertext | ||||||
|       @param pt      [out] The plaintext |       @param pt      [out] The plaintext | ||||||
|       @param skey    The scheduled key |       @param skey    The scheduled key | ||||||
|  |       @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*ecb_decrypt)(const unsigned char *ct,  |    int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
|                              unsigned char *pt, symmetric_key *skey); |  | ||||||
|    /** Test the block cipher |    /** Test the block cipher | ||||||
|        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled | ||||||
|    */ |    */ | ||||||
|    int (*test)(void); |    int (*test)(void); | ||||||
|  | 
 | ||||||
|  |    /** Terminate the context  | ||||||
|  |       @param skey    The scheduled key | ||||||
|  |    */ | ||||||
|  |    void (*done)(symmetric_key *skey);       | ||||||
|  | 
 | ||||||
|    /** Determine a key size |    /** Determine a key size | ||||||
|        @param keysize    [in/out] The size of the key desired and the suggested size |        @param keysize    [in/out] The size of the key desired and the suggested size | ||||||
|        @return CRYPT_OK if successful |        @return CRYPT_OK if successful | ||||||
| @ -4057,20 +4190,20 @@ struct ltc_cipher_descriptor { | |||||||
|        @param ct      Ciphertext |        @param ct      Ciphertext | ||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param skey    The scheduled key context |        @param skey    The scheduled key context | ||||||
|  |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_ecb_encrypt)(const unsigned char *pt,  |    int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct,  | ||||||
|                                    unsigned char *ct, unsigned long blocks,  |                                   unsigned long blocks, symmetric_key *skey); | ||||||
|                              symmetric_key *skey); |  | ||||||
| 
 | 
 | ||||||
|    /** Accelerated ECB decryption  |    /** Accelerated ECB decryption  | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
|        @param ct      Ciphertext |        @param ct      Ciphertext | ||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param skey    The scheduled key context |        @param skey    The scheduled key context | ||||||
|  |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_ecb_decrypt)(const unsigned char *ct,  |    int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt,  | ||||||
|                                    unsigned char *pt, unsigned long blocks,  |                                   unsigned long blocks, symmetric_key *skey); | ||||||
|                              symmetric_key *skey); |  | ||||||
| 
 | 
 | ||||||
|    /** Accelerated CBC encryption  |    /** Accelerated CBC encryption  | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
| @ -4078,10 +4211,11 @@ struct ltc_cipher_descriptor { | |||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param IV      The initial value (input/output) |        @param IV      The initial value (input/output) | ||||||
|        @param skey    The scheduled key context |        @param skey    The scheduled key context | ||||||
|  |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_cbc_encrypt)(const unsigned char *pt,  |    int (*accel_cbc_encrypt)(const unsigned char *pt,    unsigned char *ct,  | ||||||
|                                    unsigned char *ct, unsigned long blocks,  |                                   unsigned long blocks, unsigned char *IV,  | ||||||
|                                    unsigned char *IV, symmetric_key *skey); |                                   symmetric_key *skey); | ||||||
| 
 | 
 | ||||||
|    /** Accelerated CBC decryption  |    /** Accelerated CBC decryption  | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
| @ -4089,10 +4223,11 @@ struct ltc_cipher_descriptor { | |||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param IV      The initial value (input/output) |        @param IV      The initial value (input/output) | ||||||
|        @param skey    The scheduled key context |        @param skey    The scheduled key context | ||||||
|  |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_cbc_decrypt)(const unsigned char *ct,  |    int (*accel_cbc_decrypt)(const unsigned char *ct,    unsigned char *pt,  | ||||||
|                                    unsigned char *pt, unsigned long blocks,  |                                   unsigned long blocks, unsigned char *IV,  | ||||||
|                                    unsigned char *IV, symmetric_key *skey); |                                   symmetric_key *skey); | ||||||
| 
 | 
 | ||||||
|    /** Accelerated CTR encryption  |    /** Accelerated CTR encryption  | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
| @ -4101,14 +4236,16 @@ struct ltc_cipher_descriptor { | |||||||
|        @param IV      The initial value (input/output) |        @param IV      The initial value (input/output) | ||||||
|        @param mode    little or big endian counter (mode=0 or mode=1) |        @param mode    little or big endian counter (mode=0 or mode=1) | ||||||
|        @param skey    The scheduled key context |        @param skey    The scheduled key context | ||||||
|  |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_ctr_encrypt)(const unsigned char *pt,  |    int (*accel_ctr_encrypt)(const unsigned char *pt,    unsigned char *ct, | ||||||
|                                    unsigned char *ct, unsigned long blocks,  |                                   unsigned long blocks, unsigned char *IV,  | ||||||
|                                    unsigned char *IV, int mode, symmetric_key *skey); |                                   int mode, symmetric_key *skey); | ||||||
| 
 | 
 | ||||||
|    /** Accelerated CCM packet (one-shot) |    /** Accelerated CCM packet (one-shot) | ||||||
|        @param key        The secret key to use |        @param key        The secret key to use | ||||||
|        @param keylen     The length of the secret key (octets) |        @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 nonce      The session nonce [use once] | ||||||
|        @param noncelen   The length of the nonce |        @param noncelen   The length of the nonce | ||||||
|        @param header     The header for the session |        @param header     The header for the session | ||||||
| @ -4121,8 +4258,9 @@ struct ltc_cipher_descriptor { | |||||||
|        @param direction  Encrypt or Decrypt direction (0 or 1) |        @param direction  Encrypt or Decrypt direction (0 or 1) | ||||||
|        @return CRYPT_OK if successful |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_ccm_memory)( |    int (*accel_ccm_memory)( | ||||||
|        const unsigned char *key,    unsigned long keylen, |        const unsigned char *key,    unsigned long keylen, | ||||||
|  |        symmetric_key       *uskey, | ||||||
|        const unsigned char *nonce,  unsigned long noncelen, |        const unsigned char *nonce,  unsigned long noncelen, | ||||||
|        const unsigned char *header, unsigned long headerlen, |        const unsigned char *header, unsigned long headerlen, | ||||||
|              unsigned char *pt,     unsigned long ptlen, |              unsigned char *pt,     unsigned long ptlen, | ||||||
| @ -4143,8 +4281,9 @@ struct ltc_cipher_descriptor { | |||||||
|        @param tag               [out] The MAC tag |        @param tag               [out] The MAC tag | ||||||
|        @param taglen            [in/out] The MAC tag length |        @param taglen            [in/out] The MAC tag length | ||||||
|        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) |        @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 *key,    unsigned long keylen, | ||||||
|        const unsigned char *IV,     unsigned long IVlen, |        const unsigned char *IV,     unsigned long IVlen, | ||||||
|        const unsigned char *adata,  unsigned long adatalen, |        const unsigned char *adata,  unsigned long adatalen, | ||||||
| @ -4152,7 +4291,6 @@ struct ltc_cipher_descriptor { | |||||||
|              unsigned char *ct,  |              unsigned char *ct,  | ||||||
|              unsigned char *tag,    unsigned long *taglen, |              unsigned char *tag,    unsigned long *taglen, | ||||||
|                        int direction); |                        int direction); | ||||||
| 
 |  | ||||||
| }; | }; | ||||||
| \end{verbatim} | \end{verbatim} | ||||||
| \end{small} | \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. | The accelerator will only be used to encrypt whole blocks.  Partial blocks are always handled in software. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Accelerated CCM} | \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 | 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 | ||||||
| be called prior to this.  This function must handle scheduling the key provided on its own. | 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} | \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 | 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); |    int (*add)(void *a, void *b, void *c); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|    /** add two integers  |    /** add two integers  | ||||||
|      @param a   The first source integer |      @param a   The first source integer | ||||||
|      @param b   The second source integer (single digit of upto bits_per_digit in length) |      @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) ---- */ | /* ---- (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 |    /** RSA exponentiation | ||||||
|       @param in       The octet array representing the base |       @param in       The octet array representing the base | ||||||
|       @param inlen    The length of the input |       @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} | \end{document} | ||||||
| 
 | 
 | ||||||
| % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $    | % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $    | ||||||
| % $Revision: 1.45 $    | % $Revision: 1.55 $    | ||||||
| % $Date: 2005/08/01 16:59:29 $  | % $Date: 2005/11/18 01:45:03 $  | ||||||
|  | |||||||
| @ -170,7 +170,7 @@ int main(int argc, char *argv[]) | |||||||
|          exit(-1); |          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)); |          printf("ctr_start error: %s\n",error_to_string(errno)); | ||||||
|          exit(-1); |          exit(-1); | ||||||
|       } |       } | ||||||
| @ -212,7 +212,7 @@ int main(int argc, char *argv[]) | |||||||
|          exit(-1); |          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)); |          printf("ctr_start error: %s\n",error_to_string(errno)); | ||||||
|          exit(-1); |          exit(-1); | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -22,8 +22,9 @@ int main(void) | |||||||
|    printf("\nmac_test......"); fflush(stdout); x = mac_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); |    printf("\nmac_test......"); fflush(stdout); x = mac_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); | ||||||
|    printf("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test();      printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); |    printf("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test();      printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); | ||||||
|    printf("\nrsa_test......"); fflush(stdout); x = rsa_test();         printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); |    printf("\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("\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("\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"); |    printf("\n"); | ||||||
|    return EXIT_SUCCESS; |    return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,7 +14,6 @@ reg_algs(); | |||||||
|    extern ltc_math_descriptor EXT_MATH_LIB; |    extern ltc_math_descriptor EXT_MATH_LIB; | ||||||
|    ltc_mp = EXT_MATH_LIB; |    ltc_mp = EXT_MATH_LIB; | ||||||
| #endif | #endif | ||||||
| 
 |  | ||||||
| time_keysched(); | time_keysched(); | ||||||
| time_cipher(); | time_cipher(); | ||||||
| time_cipher2(); | time_cipher2(); | ||||||
| @ -27,6 +26,9 @@ time_mult(); | |||||||
| time_sqr(); | time_sqr(); | ||||||
| time_rsa(); | time_rsa(); | ||||||
| time_ecc(); | time_ecc(); | ||||||
|  | #ifdef USE_LTM | ||||||
|  | time_katja(); | ||||||
|  | #endif | ||||||
| return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -551,7 +551,7 @@ void ccm_gen(void) | |||||||
|             plaintext[z] = (unsigned char)(z & 255); |             plaintext[z] = (unsigned char)(z & 255); | ||||||
|          } |          } | ||||||
|          len = sizeof(tag); |          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)); |             printf("Error CCM'ing: %s\n", error_to_string(err)); | ||||||
|             exit(EXIT_FAILURE); |             exit(EXIT_FAILURE); | ||||||
|          } |          } | ||||||
| @ -682,7 +682,7 @@ void ecc_gen(void) | |||||||
|         mp_set(G->z, 1);   |         mp_set(G->z, 1);   | ||||||
| 
 | 
 | ||||||
|         while (mp_cmp(k, order) == LTC_MP_LT) { |         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(k,    str); fprintf(out, "%s, ", str); | ||||||
|             mp_tohex(R->x, str); fprintf(out, "%s, ", str); |             mp_tohex(R->x, str); fprintf(out, "%s, ", str); | ||||||
|             mp_tohex(R->y, str); fprintf(out, "%s\n", 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
 | # Modified by Clay Culver
 | ||||||
| 
 | 
 | ||||||
| # The version
 | # The version
 | ||||||
| VERSION=1.06 | VERSION=1.07 | ||||||
| 
 | 
 | ||||||
| # Compiler and Linker Names
 | # Compiler and Linker Names
 | ||||||
| #CC=gcc
 | #CC=gcc
 | ||||||
| @ -14,12 +14,23 @@ VERSION=1.06 | |||||||
| #AR=ar
 | #AR=ar
 | ||||||
| #ARFLAGS=r
 | #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!
 | # 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 | 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)
 | # additional warnings (newer GCC 3.4 and higher)
 | ||||||
| #CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
 | ifdef GCC_34 | ||||||
| #		  -Wmissing-declarations -Wpointer-arith 
 | CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
 | ||||||
|  | 		  -Wmissing-declarations -Wpointer-arith  | ||||||
|  | endif | ||||||
| 
 | 
 | ||||||
| ifndef IGNORE_SPEED | ifndef IGNORE_SPEED | ||||||
| 
 | 
 | ||||||
| @ -47,8 +58,8 @@ ifndef LIBNAME | |||||||
| endif | endif | ||||||
| ifndef LIBTEST | ifndef LIBTEST | ||||||
|    LIBTEST=libtomcrypt_prof.a |    LIBTEST=libtomcrypt_prof.a | ||||||
|    LIBTEST_S=$(LIBTEST) |  | ||||||
| endif | endif | ||||||
|  | LIBTEST_S=$(LIBTEST) | ||||||
| 
 | 
 | ||||||
| HASH=hashsum | HASH=hashsum | ||||||
| CRYPT=encrypt | 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_decode_printable_string.o \ | ||||||
| src/pk/asn1/der/printable_string/der_encode_printable_string.o \ | src/pk/asn1/der/printable_string/der_encode_printable_string.o \ | ||||||
| src/pk/asn1/der/printable_string/der_length_printable_string.o \ | src/pk/asn1/der/printable_string/der_length_printable_string.o \ | ||||||
| src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.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_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.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_length_sequence.o \ | src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ | ||||||
| src/pk/asn1/der/short_integer/der_decode_short_integer.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_encode_short_integer.o \ | ||||||
| src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | ||||||
| src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | ||||||
| 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/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/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/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \ | src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.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/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/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.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/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ | src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ | ||||||
| src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ | src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ | ||||||
| src/prngs/sprng.o src/prngs/yarrow.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 \
 | HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 | ||||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | src/headers/tomcrypt_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/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/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c | ||||||
| src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c | src/hashes/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/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 | 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) | library: $(LIBNAME) | ||||||
| 
 | 
 | ||||||
| testprof/$(LIBTEST):  | testprof/$(LIBTEST):  | ||||||
| 	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) make  | 	cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE)  | ||||||
| 
 | 
 | ||||||
| $(LIBNAME): $(OBJECTS) | $(LIBNAME): $(OBJECTS) | ||||||
| 	$(AR) $(ARFLAGS) $@ $(OBJECTS)  | 	$(AR) $(ARFLAGS) $@ $(OBJECTS)  | ||||||
| 	ranlib $(LIBNAME) | 	$(RANLIB) $@ | ||||||
| 
 | 
 | ||||||
| #This rule makes the hash program included with libtomcrypt
 | #This rule makes the hash program included with libtomcrypt
 | ||||||
| hashsum: library $(HASHOBJECTS) | hashsum: library $(HASHOBJECTS) | ||||||
| @ -242,28 +260,33 @@ timing: library testprof/$(LIBTEST) $(TIMINGS) | |||||||
| test: library testprof/$(LIBTEST) $(TESTS) | test: library testprof/$(LIBTEST) $(TESTS) | ||||||
| 	$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) | 	$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #This rule installs the library and the header files. This must be run
 | #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
 | #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.
 | #directories and to set the owner and group to root.
 | ||||||
|  | ifndef NODOCS | ||||||
| install: library docs | install: library docs | ||||||
|  | else | ||||||
|  | install: library | ||||||
|  | endif | ||||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) | 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) | ||||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | ||||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) | 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) | ||||||
| 	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) | 	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) | ||||||
| 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) | 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) | ||||||
|  | ifndef NODOCS | ||||||
| 	install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH) | 	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)$(LIBPATH) | ||||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | 	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: | profile: | ||||||
| 	CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov | 	CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" | ||||||
| 	./timing | 	./timing | ||||||
| 	rm -f timing `find . -type f | grep [.][ao] | xargs` | 	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
 | #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)
 | #build the doxy files (requires Doxygen, tetex and patience)
 | ||||||
| doxy: | doxy: | ||||||
| 	doxygen | 	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 | 	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
 | #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 $ 
 | # $Source: /cvs/libtom/libtomcrypt/makefile,v $ 
 | ||||||
| # $Revision: 1.86 $ 
 | # $Revision: 1.103 $ 
 | ||||||
| # $Date: 2005/07/30 04:54:20 $ 
 | # $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_decode_printable_string.o \ | ||||||
| src/pk/asn1/der/printable_string/der_encode_printable_string.o \ | src/pk/asn1/der/printable_string/der_encode_printable_string.o \ | ||||||
| src/pk/asn1/der/printable_string/der_length_printable_string.o \ | src/pk/asn1/der/printable_string/der_length_printable_string.o \ | ||||||
| src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.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_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.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_length_sequence.o \ | src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ | ||||||
| src/pk/asn1/der/short_integer/der_decode_short_integer.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_encode_short_integer.o \ | ||||||
| src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | ||||||
| src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | ||||||
| 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/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/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/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \ | src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.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/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/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.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/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ | src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ | ||||||
| src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ | src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ | ||||||
| src/prngs/sprng.o src/prngs/yarrow.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 \ | HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ | ||||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | src/headers/tomcrypt_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/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/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c | ||||||
| src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c | src/hashes/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/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 | 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) | 	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) | ||||||
| 
 | 
 | ||||||
| # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $    | # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $    | ||||||
| # $Revision: 1.39 $    | # $Revision: 1.44 $    | ||||||
| # $Date: 2005/07/30 23:38:39 $  | # $Date: 2005/11/18 01:46:22 $  | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| #MSVC Makefile [tested with MSVC 6.00 with SP5] | #MSVC Makefile [tested with MSVC 6.00 with SP5] | ||||||
| # | # | ||||||
| #Tom St Denis | #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 \ | OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \ | ||||||
| src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \ | src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \ | ||||||
| @ -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_decode_printable_string.obj \ | ||||||
| src/pk/asn1/der/printable_string/der_encode_printable_string.obj \ | src/pk/asn1/der/printable_string/der_encode_printable_string.obj \ | ||||||
| src/pk/asn1/der/printable_string/der_length_printable_string.obj \ | src/pk/asn1/der/printable_string/der_length_printable_string.obj \ | ||||||
| src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_multi.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_encode_sequence.obj src/pk/asn1/der/sequence/der_encode_sequence_multi.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_length_sequence.obj \ | src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \ | ||||||
| src/pk/asn1/der/short_integer/der_decode_short_integer.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_encode_short_integer.obj \ | ||||||
| src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \ | src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \ | ||||||
| src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \ | src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \ | ||||||
| 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/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/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/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \ | src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.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/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/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.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/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \ | src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \ | ||||||
| src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \ | src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \ | ||||||
| src/prngs/sprng.obj src/prngs/yarrow.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 \ | HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ | ||||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | src/headers/tomcrypt_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) | 	cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) | ||||||
| 
 | 
 | ||||||
| # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $    | # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $    | ||||||
| # $Revision: 1.17 $    | # $Revision: 1.24 $    | ||||||
| # $Date: 2005/07/30 23:42:57 $  | # $Date: 2005/11/18 01:46:22 $  | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -6,11 +6,16 @@ | |||||||
| # Tom St Denis | # Tom St Denis | ||||||
| 
 | 
 | ||||||
| # The version | # The version | ||||||
| VERSION=0:106 | VERSION=0:107 | ||||||
| 
 | 
 | ||||||
| # Compiler and Linker Names | # Compiler and Linker Names | ||||||
| CC=libtool --mode=compile gcc  | CC=libtool --mode=compile gcc  | ||||||
| 
 | 
 | ||||||
|  | # ranlib tools | ||||||
|  | ifndef RANLIB | ||||||
|  |    RANLIB=ranlib | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| # Compilation flags. Note the += does not write over the user's CFLAGS! | # Compilation flags. Note the += does not write over the user's CFLAGS! | ||||||
| CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE | CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE | ||||||
| 
 | 
 | ||||||
| @ -39,8 +44,10 @@ endif | |||||||
| #CFLAGS += -DLTC_NO_ROLC | #CFLAGS += -DLTC_NO_ROLC | ||||||
| 
 | 
 | ||||||
| #Output filenames for various targets. | #Output filenames for various targets. | ||||||
| ifndef LIBTEST | ifndef LIBTEST_S | ||||||
|    LIBTEST_S=libtomcrypt_prof.a |    LIBTEST_S=libtomcrypt_prof.a | ||||||
|  | endif | ||||||
|  | ifndef LIBTEST | ||||||
|    LIBTEST=libtomcrypt_prof.la |    LIBTEST=libtomcrypt_prof.la | ||||||
| endif | endif | ||||||
| ifndef LIBNAME | 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_decode_printable_string.o \ | ||||||
| src/pk/asn1/der/printable_string/der_encode_printable_string.o \ | src/pk/asn1/der/printable_string/der_encode_printable_string.o \ | ||||||
| src/pk/asn1/der/printable_string/der_length_printable_string.o \ | src/pk/asn1/der/printable_string/der_length_printable_string.o \ | ||||||
| src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.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_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.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_length_sequence.o \ | src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ | ||||||
| src/pk/asn1/der/short_integer/der_decode_short_integer.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_encode_short_integer.o \ | ||||||
| src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ | ||||||
| src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ | ||||||
| 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/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/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/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \ | src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.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/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/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.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/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ | src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ | ||||||
| src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ | src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ | ||||||
| src/prngs/sprng.o src/prngs/yarrow.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 \ | HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ | ||||||
| src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ | src/headers/tomcrypt_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/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/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c | ||||||
| src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c | src/hashes/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/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 | src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c | ||||||
| 
 | 
 | ||||||
| @ -205,10 +219,13 @@ library: $(LIBNAME) | |||||||
| testprof/$(LIBTEST): | testprof/$(LIBTEST): | ||||||
| 	cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared | 	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 "[.]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 | 	libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la | ||||||
| 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | 	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) | ||||||
| 	install -g $(GROUP) -o $(USER) $(HEADERS) $(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) | 	gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) | ||||||
| 
 | 
 | ||||||
| # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $    | # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $    | ||||||
| # $Revision: 1.25 $    | # $Revision: 1.36 $    | ||||||
| # $Date: 2005/07/30 04:54:20 $  | # $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 pt The input plaintext (16 bytes) | ||||||
|   @param ct The output ciphertext (16 bytes) |   @param ct The output ciphertext (16 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; |     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)]) ^  |         (Te4_0[byte(t2, 0)]) ^  | ||||||
|         rk[3]; |         rk[3]; | ||||||
|     STORE32H(s3, ct+12); |     STORE32H(s3, ct+12); | ||||||
|  | 
 | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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); |    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 ct The input ciphertext (16 bytes) | ||||||
|   @param pt The output plaintext (16 bytes) |   @param pt The output plaintext (16 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; |     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) ^ |         (Td4[byte(t0, 0)] & 0x000000ff) ^ | ||||||
|         rk[3]; |         rk[3]; | ||||||
|     STORE32H(s3, pt+12); |     STORE32H(s3, pt+12); | ||||||
|  | 
 | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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); |    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1134,13 +1134,15 @@ static void anubis_crypt(const unsigned char *plaintext, unsigned char *cipherte | |||||||
|   @param pt The input plaintext (16 bytes) |   @param pt The input plaintext (16 bytes) | ||||||
|   @param ct The output ciphertext (16 bytes) |   @param ct The output ciphertext (16 bytes) | ||||||
|   @param skey The key as scheduled |   @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(pt   != NULL); | ||||||
|    LTC_ARGCHK(ct   != NULL); |    LTC_ARGCHK(ct   != NULL); | ||||||
|    LTC_ARGCHK(skey != NULL); |    LTC_ARGCHK(skey != NULL); | ||||||
|    anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); |    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 ct The input ciphertext (16 bytes) | ||||||
|   @param pt The output plaintext (16 bytes) |   @param pt The output plaintext (16 bytes) | ||||||
|   @param skey The key as scheduled  |   @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(pt   != NULL); | ||||||
|    LTC_ARGCHK(ct   != NULL); |    LTC_ARGCHK(ct   != NULL); | ||||||
|    LTC_ARGCHK(skey != NULL); |    LTC_ARGCHK(skey != NULL); | ||||||
|    anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); |    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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 L, R; |    ulong32 L, R; | ||||||
| @ -428,13 +429,16 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ | |||||||
|    /* store */ |    /* store */ | ||||||
|    STORE32H(R, &ct[0]); |    STORE32H(R, &ct[0]); | ||||||
|    STORE32H(L, &ct[4]); |    STORE32H(L, &ct[4]); | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |     burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||||
|  |     return err; | ||||||
| } | } | ||||||
| #endif | #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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 L, R; |    ulong32 L, R; | ||||||
| @ -486,13 +491,15 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ | |||||||
|    /* store */ |    /* store */ | ||||||
|    STORE32H(L, &pt[0]); |    STORE32H(L, &pt[0]); | ||||||
|    STORE32H(R, &pt[4]); |    STORE32H(R, &pt[4]); | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |     burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||||
|  |     return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -536,9 +536,9 @@ INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) | |||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 R, L; |    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(R,&ct[0]); | ||||||
|    STORE32H(L,&ct[4]); |    STORE32H(L,&ct[4]); | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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); |    burn_stack(sizeof(ulong32)*3); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -587,9 +589,9 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | |||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 R, L; |    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]); |    L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); | ||||||
|    STORE32H(L,&pt[0]); |    STORE32H(L,&pt[0]); | ||||||
|    STORE32H(R,&pt[4]); |    STORE32H(R,&pt[4]); | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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); |    burn_stack(sizeof(ulong32)*3); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @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]; |     ulong32 work[2]; | ||||||
|     LTC_ARGCHK(pt   != NULL); |     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); |     desfunc(work, skey->des.ek); | ||||||
|     STORE32H(work[0],ct+0); |     STORE32H(work[0],ct+0); | ||||||
|     STORE32H(work[1],ct+4); |     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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @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]; |     ulong32 work[2]; | ||||||
|     LTC_ARGCHK(pt   != NULL); |     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); |     desfunc(work, skey->des.dk); | ||||||
|     STORE32H(work[0],pt+0); |     STORE32H(work[0],pt+0); | ||||||
|     STORE32H(work[1],pt+4);   |     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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @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]; |     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]); |     desfunc(work, skey->des3.ek[2]); | ||||||
|     STORE32H(work[0],ct+0); |     STORE32H(work[0],ct+0); | ||||||
|     STORE32H(work[1],ct+4); |     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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @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]; |     ulong32 work[2]; | ||||||
|     LTC_ARGCHK(pt   != NULL); |     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]); |     desfunc(work, skey->des3.dk[2]); | ||||||
|     STORE32H(work[0],pt+0); |     STORE32H(work[0],pt+0); | ||||||
|     STORE32H(work[1],pt+4); |     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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @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(pt   != NULL); | ||||||
|    LTC_ARGCHK(ct   != NULL); |    LTC_ARGCHK(ct   != NULL); | ||||||
|    LTC_ARGCHK(skey != NULL); |    LTC_ARGCHK(skey != NULL); | ||||||
|    khazad_crypt(pt, ct, skey->khazad.roundKeyEnc); |    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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @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(pt   != NULL); | ||||||
|    LTC_ARGCHK(ct   != NULL); |    LTC_ARGCHK(ct   != NULL); | ||||||
|    LTC_ARGCHK(skey != NULL); |    LTC_ARGCHK(skey != NULL); | ||||||
|    khazad_crypt(ct, pt, skey->khazad.roundKeyDec); |    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 pt The input plaintext (16 bytes) | ||||||
|   @param ct The output ciphertext (16 bytes) |   @param ct The output ciphertext (16 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 a,b,c,d,temp; |    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(a,&ct[0]); STORE32H(b,&ct[4]); | ||||||
|    STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); |    STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 5 + sizeof(int)); | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| #endif | #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 ct The input ciphertext (16 bytes) | ||||||
|   @param pt The output plaintext (16 bytes) |   @param pt The output plaintext (16 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 a,b,c,d, temp; |    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]; |    a ^= RC[0]; | ||||||
|    STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); |    STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); | ||||||
|    STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); |    STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 5 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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, |                             unsigned char *ct, | ||||||
|                             symmetric_key *skey) |                             symmetric_key *skey) | ||||||
| #else | #else | ||||||
| void rc2_ecb_encrypt( const unsigned char *pt, | int rc2_ecb_encrypt( const unsigned char *pt, | ||||||
|                             unsigned char *ct, |                             unsigned char *ct, | ||||||
|                             symmetric_key *skey) |                             symmetric_key *skey) | ||||||
| #endif | #endif | ||||||
| @ -179,15 +180,18 @@ void rc2_ecb_encrypt( const unsigned char *pt, | |||||||
|     ct[5] = (unsigned char)(x54 >> 8); |     ct[5] = (unsigned char)(x54 >> 8); | ||||||
|     ct[6] = (unsigned char)x76; |     ct[6] = (unsigned char)x76; | ||||||
|     ct[7] = (unsigned char)(x76 >> 8); |     ct[7] = (unsigned char)(x76 >> 8); | ||||||
|  |   | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #ifdef LTC_CLEAN_STACK | ||||||
| void rc2_ecb_encrypt( const unsigned char *pt, | int rc2_ecb_encrypt( const unsigned char *pt, | ||||||
|                             unsigned char *ct, |                             unsigned char *ct, | ||||||
|                             symmetric_key *skey) |                             symmetric_key *skey) | ||||||
| { | { | ||||||
|     _rc2_ecb_encrypt(pt, ct, skey); |     int err = _rc2_ecb_encrypt(pt, ct, skey); | ||||||
|     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); |     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); | ||||||
|  |     return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -199,13 +203,14 @@ void rc2_ecb_encrypt( const unsigned char *pt, | |||||||
|   @param ct The input ciphertext (8 bytes) |   @param ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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, |                             unsigned char *pt, | ||||||
|                             symmetric_key *skey) |                             symmetric_key *skey) | ||||||
| #else | #else | ||||||
| void rc2_ecb_decrypt( const unsigned char *ct, | int rc2_ecb_decrypt( const unsigned char *ct, | ||||||
|                             unsigned char *pt, |                             unsigned char *pt, | ||||||
|                             symmetric_key *skey) |                             symmetric_key *skey) | ||||||
| #endif | #endif | ||||||
| @ -254,15 +259,18 @@ void rc2_ecb_decrypt( const unsigned char *ct, | |||||||
|     pt[5] = (unsigned char)(x54 >> 8); |     pt[5] = (unsigned char)(x54 >> 8); | ||||||
|     pt[6] = (unsigned char)x76; |     pt[6] = (unsigned char)x76; | ||||||
|     pt[7] = (unsigned char)(x76 >> 8); |     pt[7] = (unsigned char)(x76 >> 8); | ||||||
|  | 
 | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #ifdef LTC_CLEAN_STACK | ||||||
| void rc2_ecb_decrypt( const unsigned char *ct, | int rc2_ecb_decrypt( const unsigned char *ct, | ||||||
|                             unsigned char *pt, |                             unsigned char *pt, | ||||||
|                             symmetric_key *skey) |                             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)); |     burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); | ||||||
|  |     return err; | ||||||
| } | } | ||||||
| #endif | #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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 A, B, *K; |    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(A, &ct[0]); | ||||||
|    STORE32L(B, &ct[4]); |    STORE32L(B, &ct[4]); | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 A, B, *K; |    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]; |    B -= skey->rc5.K[1]; | ||||||
|    STORE32L(A, &pt[0]); |    STORE32L(A, &pt[0]); | ||||||
|    STORE32L(B, &pt[4]); |    STORE32L(B, &pt[4]); | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 2 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 |   @param skey The key as scheduled | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 a,b,c,d,t,u, *K; |    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]; |    a += skey->rc6.K[42]; | ||||||
|    c += skey->rc6.K[43]; |    c += skey->rc6.K[43]; | ||||||
|    STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); |    STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 6 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -172,9 +174,9 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key * | |||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    ulong32 a,b,c,d,t,u, *K; |    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]; |    b -= skey->rc6.K[0]; | ||||||
|    d -= skey->rc6.K[1]; |    d -= skey->rc6.K[1]; | ||||||
|    STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); |    STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 6 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -246,11 +246,11 @@ int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symme | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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, |                              unsigned char *block_out, | ||||||
|                              symmetric_key *skey) |                              symmetric_key *skey) | ||||||
| #else | #else | ||||||
| void safer_ecb_encrypt(const unsigned char *block_in, | int safer_ecb_encrypt(const unsigned char *block_in, | ||||||
|                              unsigned char *block_out, |                              unsigned char *block_out, | ||||||
|                              symmetric_key *skey) |                              symmetric_key *skey) | ||||||
| #endif | #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[2] = c & 0xFF; block_out[3] = d & 0xFF; | ||||||
|     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; |     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | ||||||
|     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; |     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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, |                              unsigned char *block_out, | ||||||
|                              symmetric_key *skey) |                              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 *)); |     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); | ||||||
|  |     return err; | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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, |                              unsigned char *block_out, | ||||||
|                              symmetric_key *skey) |                              symmetric_key *skey) | ||||||
| #else | #else | ||||||
| void safer_ecb_decrypt(const unsigned char *block_in, | int safer_ecb_decrypt(const unsigned char *block_in, | ||||||
|                              unsigned char *block_out, |                              unsigned char *block_out, | ||||||
|                              symmetric_key *skey) |                              symmetric_key *skey) | ||||||
| #endif | #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[2] = c & 0xFF; block_out[3] = d & 0xFF; | ||||||
|     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; |     block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | ||||||
|     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; |     block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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, |                              unsigned char *block_out, | ||||||
|                              symmetric_key *skey) |                              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 *)); |     burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); | ||||||
|  |     return err; | ||||||
| } | } | ||||||
| #endif | #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 pt The input plaintext (16 bytes) | ||||||
|   @param ct The output ciphertext (16 bytes) |   @param ct The output ciphertext (16 bytes) | ||||||
|   @param skey The key as scheduled |   @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]; |    unsigned char b[16]; | ||||||
|    int x; |    int x; | ||||||
| @ -384,6 +385,7 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke | |||||||
| #ifdef LTC_CLEAN_STACK | #ifdef LTC_CLEAN_STACK | ||||||
|    zeromem(b, sizeof(b)); |    zeromem(b, sizeof(b)); | ||||||
| #endif | #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 ct The input ciphertext (16 bytes) | ||||||
|   @param pt The output plaintext (16 bytes) |   @param pt The output plaintext (16 bytes) | ||||||
|   @param skey The key as scheduled  |   @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]; |    unsigned char b[16]; | ||||||
|    int x; |    int x; | ||||||
| @ -446,6 +449,7 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke | |||||||
| #ifdef LTC_CLEAN_STACK | #ifdef LTC_CLEAN_STACK | ||||||
|    zeromem(b, sizeof(b)); |    zeromem(b, sizeof(b)); | ||||||
| #endif | #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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    unsigned w1,w2,w3,w4,tmp,tmp1; |    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[2] = (w2>>8)&255; ct[3] = w2&255; | ||||||
|    ct[4] = (w3>>8)&255; ct[5] = w3&255; |    ct[4] = (w3>>8)&255; ct[5] = w3&255; | ||||||
|    ct[6] = (w4>>8)&255; ct[7] = w4&255; |    ct[6] = (w4>>8)&255; ct[7] = w4&255; | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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); |    burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|    unsigned w1,w2,w3,w4,tmp; |    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[2] = (w2>>8)&255; pt[3] = w2&255; | ||||||
|    pt[4] = (w3>>8)&255; pt[5] = w3&255; |    pt[4] = (w3>>8)&255; pt[5] = w3&255; | ||||||
|    pt[6] = (w4>>8)&255; pt[7] = w4&255; |    pt[6] = (w4>>8)&255; pt[7] = w4&255; | ||||||
|  | 
 | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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); |    burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 pt The input plaintext (16 bytes) | ||||||
|   @param ct The output ciphertext (16 bytes) |   @param ct The output ciphertext (16 bytes) | ||||||
|   @param skey The key as scheduled |   @param skey The key as scheduled | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; |     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 */ |     /* store output */ | ||||||
|     STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); |     STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); | ||||||
|     STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); |     STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); | ||||||
|  | 
 | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 10 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 ct The input ciphertext (16 bytes) | ||||||
|   @param pt The output plaintext (16 bytes) |   @param pt The output plaintext (16 bytes) | ||||||
|   @param skey The key as scheduled  |   @param skey The key as scheduled  | ||||||
|  |   @return CRYPT_OK if successful | ||||||
| */ | */ | ||||||
| #ifdef LTC_CLEAN_STACK | #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 | #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 | #endif | ||||||
| { | { | ||||||
|     ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; |     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 */ |     /* store */ | ||||||
|     STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); |     STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); | ||||||
|     STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); |     STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); | ||||||
|  |     return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_CLEAN_STACK | #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)); |    burn_stack(sizeof(ulong32) * 10 + sizeof(int)); | ||||||
|  |    return err; | ||||||
| } | } | ||||||
| #endif | #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 pt The input plaintext (8 bytes) | ||||||
|   @param ct The output ciphertext (8 bytes) |   @param ct The output ciphertext (8 bytes) | ||||||
|   @param skey The key as scheduled |   @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; |    unsigned long y, z; | ||||||
|    int r; |    int r; | ||||||
| @ -98,6 +99,7 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key | |||||||
|    } |    } | ||||||
|    STORE32L(y, &ct[0]); |    STORE32L(y, &ct[0]); | ||||||
|    STORE32L(z, &ct[4]); |    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 ct The input ciphertext (8 bytes) | ||||||
|   @param pt The output plaintext (8 bytes) |   @param pt The output plaintext (8 bytes) | ||||||
|   @param skey The key as scheduled  |   @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; |    unsigned long y, z; | ||||||
|    int r; |    int r; | ||||||
| @ -132,6 +135,7 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key | |||||||
|    } |    } | ||||||
|    STORE32L(y, &pt[0]); |    STORE32L(y, &pt[0]); | ||||||
|    STORE32L(z, &pt[4]); |    STORE32L(z, &pt[4]); | ||||||
|  |    return CRYPT_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | |||||||
| @ -22,6 +22,7 @@ | |||||||
|    @param cipher     The index of the cipher desired |    @param cipher     The index of the cipher desired | ||||||
|    @param key        The secret key to use |    @param key        The secret key to use | ||||||
|    @param keylen     The length of the secret key (octets) |    @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 nonce      The session nonce [use once] | ||||||
|    @param noncelen   The length of the nonce |    @param noncelen   The length of the nonce | ||||||
|    @param header     The header for the session |    @param header     The header for the session | ||||||
| @ -36,6 +37,7 @@ | |||||||
| */ | */ | ||||||
| int ccm_memory(int cipher, | int ccm_memory(int cipher, | ||||||
|     const unsigned char *key,    unsigned long keylen, |     const unsigned char *key,    unsigned long keylen, | ||||||
|  |     symmetric_key       *uskey, | ||||||
|     const unsigned char *nonce,  unsigned long noncelen, |     const unsigned char *nonce,  unsigned long noncelen, | ||||||
|     const unsigned char *header, unsigned long headerlen, |     const unsigned char *header, unsigned long headerlen, | ||||||
|           unsigned char *pt,     unsigned long ptlen, |           unsigned char *pt,     unsigned long ptlen, | ||||||
| @ -48,7 +50,9 @@ int ccm_memory(int cipher, | |||||||
|    int            err; |    int            err; | ||||||
|    unsigned long  len, L, x, y, z, CTRlen; |    unsigned long  len, L, x, y, z, CTRlen; | ||||||
| 
 | 
 | ||||||
|    LTC_ARGCHK(key    != NULL); |    if (uskey == NULL) { | ||||||
|  |       LTC_ARGCHK(key    != NULL); | ||||||
|  |    } | ||||||
|    LTC_ARGCHK(nonce  != NULL); |    LTC_ARGCHK(nonce  != NULL); | ||||||
|    if (headerlen > 0) { |    if (headerlen > 0) { | ||||||
|       LTC_ARGCHK(header != NULL); |       LTC_ARGCHK(header != NULL); | ||||||
| @ -85,15 +89,15 @@ int ccm_memory(int cipher, | |||||||
| 
 | 
 | ||||||
|    /* is there an accelerator? */ |    /* is there an accelerator? */ | ||||||
|    if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { |    if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { | ||||||
|        cipher_descriptor[cipher].accel_ccm_memory( |        return cipher_descriptor[cipher].accel_ccm_memory( | ||||||
|            key,    keylen, |            key,    keylen, | ||||||
|  |            uskey, | ||||||
|            nonce,  noncelen, |            nonce,  noncelen, | ||||||
|            header, headerlen, |            header, headerlen, | ||||||
|            pt,     ptlen, |            pt,     ptlen, | ||||||
|            ct,  |            ct,  | ||||||
|            tag,    taglen, |            tag,    taglen, | ||||||
|            direction); |            direction); | ||||||
|       return CRYPT_OK; |  | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* let's get the L value */ |    /* let's get the L value */ | ||||||
| @ -114,15 +118,19 @@ int ccm_memory(int cipher, | |||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* allocate mem for the symmetric key */ |    /* allocate mem for the symmetric key */ | ||||||
|    skey = XMALLOC(sizeof(*skey)); |    if (uskey == NULL) { | ||||||
|    if (skey == NULL) { |       skey = XMALLOC(sizeof(*skey)); | ||||||
|       return CRYPT_MEM; |       if (skey == NULL) { | ||||||
|    } |          return CRYPT_MEM; | ||||||
|  |       } | ||||||
| 
 | 
 | ||||||
|    /* initialize the cipher */ |       /* initialize the cipher */ | ||||||
|    if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { |       if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { | ||||||
|       XFREE(skey); |          XFREE(skey); | ||||||
|       return err; |          return err; | ||||||
|  |       } | ||||||
|  |    } else { | ||||||
|  |       skey = uskey; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* form B_0 == flags | Nonce N | l(m) */ |    /* form B_0 == flags | Nonce N | l(m) */ | ||||||
| @ -154,7 +162,9 @@ int ccm_memory(int cipher, | |||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* encrypt PAD */ |    /* 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 */ |    /* handle header */ | ||||||
|    if (headerlen > 0) { |    if (headerlen > 0) { | ||||||
| @ -177,7 +187,9 @@ int ccm_memory(int cipher, | |||||||
|       for (y = 0; y < headerlen; y++) { |       for (y = 0; y < headerlen; y++) { | ||||||
|           if (x == 16) { |           if (x == 16) { | ||||||
|              /* full block so let's encrypt it */ |              /* 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; |              x = 0; | ||||||
|           } |           } | ||||||
|           PAD[x++] ^= header[y]; |           PAD[x++] ^= header[y]; | ||||||
| @ -185,7 +197,9 @@ int ccm_memory(int cipher, | |||||||
| 
 | 
 | ||||||
|       /* remainder? */ |       /* remainder? */ | ||||||
|       if (x != 0) { |       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; |                     ctr[z] = (ctr[z] + 1) & 255; | ||||||
|                     if (ctr[z]) break; |                     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 */ |                 /* xor the PT against the pad first */ | ||||||
|                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { |                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { | ||||||
|                     *((LTC_FAST_TYPE*)(&PAD[z]))  ^= *((LTC_FAST_TYPE*)(&pt[y+z])); |                     *((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])); |                     *((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 { |          } else { | ||||||
|              for (; y < (ptlen & ~15); y += 16) { |              for (; y < (ptlen & ~15); y += 16) { | ||||||
| @ -235,14 +253,18 @@ int ccm_memory(int cipher, | |||||||
|                     ctr[z] = (ctr[z] + 1) & 255; |                     ctr[z] = (ctr[z] + 1) & 255; | ||||||
|                     if (ctr[z]) break; |                     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 */ |                 /* xor the PT against the pad last */ | ||||||
|                 for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { |                 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*)(&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])); |                     *((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; |                  ctr[z] = (ctr[z] + 1) & 255; | ||||||
|                  if (ctr[z]) break; |                  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; |              CTRlen = 0; | ||||||
|           } |           } | ||||||
| 
 | 
 | ||||||
| @ -269,21 +293,30 @@ int ccm_memory(int cipher, | |||||||
|           } |           } | ||||||
| 
 | 
 | ||||||
|           if (x == 16) { |           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; |              x = 0; | ||||||
|           } |           } | ||||||
|           PAD[x++] ^= b; |           PAD[x++] ^= b; | ||||||
|       } |       } | ||||||
|               |               | ||||||
|       if (x != 0) { |       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 */ |    /* setup CTR for the TAG */ | ||||||
|    ctr[14] = ctr[15] = 0x00; |    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) { | ||||||
|    cipher_descriptor[cipher].done(skey); |       goto error; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (skey != uskey) { | ||||||
|  |       cipher_descriptor[cipher].done(skey); | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|    /* store the TAG */ |    /* store the TAG */ | ||||||
|    for (x = 0; x < 16 && x < *taglen; x++) { |    for (x = 0; x < 16 && x < *taglen; x++) { | ||||||
| @ -296,10 +329,12 @@ int ccm_memory(int cipher, | |||||||
|    zeromem(PAD,    sizeof(PAD)); |    zeromem(PAD,    sizeof(PAD)); | ||||||
|    zeromem(CTRPAD, sizeof(CTRPAD)); |    zeromem(CTRPAD, sizeof(CTRPAD)); | ||||||
| #endif | #endif | ||||||
|  | error: | ||||||
|  |    if (skey != uskey) { | ||||||
|  |       XFREE(skey); | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|    XFREE(skey); |    return err; | ||||||
| 
 |  | ||||||
|    return CRYPT_OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -116,6 +116,7 @@ int ccm_test(void) | |||||||
|   unsigned long taglen, x; |   unsigned long taglen, x; | ||||||
|   unsigned char buf[64], buf2[64], tag2[16], tag[16]; |   unsigned char buf[64], buf2[64], tag2[16], tag[16]; | ||||||
|   int           err, idx; |   int           err, idx; | ||||||
|  |   symmetric_key skey; | ||||||
| 
 | 
 | ||||||
|   idx = find_cipher("aes"); |   idx = find_cipher("aes"); | ||||||
|   if (idx == -1) { |   if (idx == -1) { | ||||||
| @ -127,8 +128,13 @@ int ccm_test(void) | |||||||
| 
 | 
 | ||||||
|   for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { |   for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { | ||||||
|       taglen = tests[x].taglen; |       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, |       if ((err = ccm_memory(idx, | ||||||
|                             tests[x].key, 16, |                             tests[x].key, 16, | ||||||
|  |                             &skey, | ||||||
|                             tests[x].nonce, tests[x].noncelen, |                             tests[x].nonce, tests[x].noncelen, | ||||||
|                             tests[x].header, tests[x].headerlen, |                             tests[x].header, tests[x].headerlen, | ||||||
|                             (unsigned char*)tests[x].pt, tests[x].ptlen, |                             (unsigned char*)tests[x].pt, tests[x].ptlen, | ||||||
| @ -146,6 +152,7 @@ int ccm_test(void) | |||||||
| 
 | 
 | ||||||
|       if ((err = ccm_memory(idx, |       if ((err = ccm_memory(idx, | ||||||
|                             tests[x].key, 16, |                             tests[x].key, 16, | ||||||
|  |                             NULL, | ||||||
|                             tests[x].nonce, tests[x].noncelen, |                             tests[x].nonce, tests[x].noncelen, | ||||||
|                             tests[x].header, tests[x].headerlen, |                             tests[x].header, tests[x].headerlen, | ||||||
|                             buf2, tests[x].ptlen, |                             buf2, tests[x].ptlen, | ||||||
| @ -154,14 +161,13 @@ int ccm_test(void) | |||||||
|          return err; |          return err; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|      if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) { |       if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) { | ||||||
|          return CRYPT_FAIL_TESTVECTOR; |          return CRYPT_FAIL_TESTVECTOR; | ||||||
|       } |       } | ||||||
|      if (memcmp(tag2, tests[x].tag, tests[x].taglen)) { |       if (memcmp(tag2, tests[x].tag, tests[x].taglen)) { | ||||||
|          return CRYPT_FAIL_TESTVECTOR; |          return CRYPT_FAIL_TESTVECTOR; | ||||||
|      } |       } | ||||||
|   |       cipher_descriptor[idx].done(&skey); | ||||||
| 
 |  | ||||||
|   } |   } | ||||||
|   return CRYPT_OK; |   return CRYPT_OK; | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -62,7 +62,9 @@ int gcm_done(gcm_state *gcm, | |||||||
|    gcm_mult_h(gcm, gcm->X); |    gcm_mult_h(gcm, gcm->X); | ||||||
| 
 | 
 | ||||||
|    /* encrypt original counter */ |    /* 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++) { |    for (x = 0; x < 16 && x < *taglen; x++) { | ||||||
|        tag[x] = gcm->buf[x] ^ gcm->X[x]; |        tag[x] = gcm->buf[x] ^ gcm->X[x]; | ||||||
|    } |    } | ||||||
|  | |||||||
| @ -98,7 +98,9 @@ int gcm_init(gcm_state *gcm, int cipher, | |||||||
| 
 | 
 | ||||||
|    /* H = E(0) */ |    /* H = E(0) */ | ||||||
|    zeromem(B, 16); |    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 */ |    /* setup state */ | ||||||
|    zeromem(gcm->buf, sizeof(gcm->buf)); |    zeromem(gcm->buf, sizeof(gcm->buf)); | ||||||
|  | |||||||
| @ -51,7 +51,8 @@ int gcm_memory(      int           cipher, | |||||||
|     } |     } | ||||||
|   |   | ||||||
|     if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { |     if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { | ||||||
|        cipher_descriptor[cipher].accel_gcm_memory |        return  | ||||||
|  |          cipher_descriptor[cipher].accel_gcm_memory | ||||||
|                                           (key,   keylen, |                                           (key,   keylen, | ||||||
|                                            IV,    IVlen, |                                            IV,    IVlen, | ||||||
|                                            adata, adatalen, |                                            adata, adatalen, | ||||||
| @ -59,7 +60,6 @@ int gcm_memory(      int           cipher, | |||||||
|                                            ct, |                                            ct, | ||||||
|                                            tag,   taglen, |                                            tag,   taglen, | ||||||
|                                            direction); |                                            direction); | ||||||
|        return CRYPT_OK; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -62,7 +62,9 @@ int gcm_process(gcm_state *gcm, | |||||||
|           if (++gcm->Y[y]) { break; } |           if (++gcm->Y[y]) { break; } | ||||||
|       } |       } | ||||||
|       /* encrypt the counter */ |       /* 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->buflen = 0; | ||||||
|       gcm->mode   = GCM_MODE_TEXT; |       gcm->mode   = GCM_MODE_TEXT; | ||||||
| @ -89,7 +91,9 @@ int gcm_process(gcm_state *gcm, | |||||||
|              for (y = 15; y >= 12; y--) { |              for (y = 15; y >= 12; y--) { | ||||||
|                  if (++gcm->Y[y]) { break; } |                  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 { |       } else { | ||||||
|          for (x = 0; x < (ptlen & ~15); x += 16) { |          for (x = 0; x < (ptlen & ~15); x += 16) { | ||||||
| @ -105,7 +109,9 @@ int gcm_process(gcm_state *gcm, | |||||||
|              for (y = 15; y >= 12; y--) { |              for (y = 15; y >= 12; y--) { | ||||||
|                  if (++gcm->Y[y]) { break; } |                  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--) { |           for (y = 15; y >= 12; y--) { | ||||||
|               if (++gcm->Y[y]) { break; } |               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; |           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++) { |    for (x = 0; x < ocb->block_len; x++) { | ||||||
|        tmp[x] = ct[x] ^ Z[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++) { |    for (x = 0; x < ocb->block_len; x++) { | ||||||
|        pt[x] ^= Z[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++) { |    for (x = 0; x < ocb->block_len; x++) { | ||||||
|        tmp[x] = pt[x] ^ Z[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++) { |    for (x = 0; x < ocb->block_len; x++) { | ||||||
|        ct[x] ^= Z[x]; |        ct[x] ^= Z[x]; | ||||||
|    } |    } | ||||||
|  | |||||||
| @ -76,13 +76,17 @@ int ocb_init(ocb_state *ocb, int cipher, | |||||||
|   |   | ||||||
|    /* find L = E[0] */ |    /* find L = E[0] */ | ||||||
|    zeromem(ocb->L, ocb->block_len); |    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] */ |    /* find R = E[N xor L] */ | ||||||
|    for (x = 0; x < ocb->block_len; x++) { |    for (x = 0; x < ocb->block_len; x++) { | ||||||
|        ocb->R[x] = ocb->L[x] ^ nonce[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 */ |    /* find Ls[i] = L << i for i == 0..31 */ | ||||||
|    XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); |    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])) */ |    /* 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) { |    if (mode == 1) { | ||||||
|       /* decrypt mode, so let's xor it first */ |       /* 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!! */ |    /* 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); |    cipher_descriptor[ocb->cipher].done(&ocb->key); | ||||||
| 
 | 
 | ||||||
|    /* now store it */ |    /* 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(Z, MAXBLOCKSIZE); | ||||||
|    zeromem(ocb, sizeof(*ocb)); |    zeromem(ocb, sizeof(*ocb)); | ||||||
| #endif | #endif | ||||||
|     | error:    | ||||||
|    XFREE(X); |    XFREE(X); | ||||||
|    XFREE(Y); |    XFREE(Y); | ||||||
|    XFREE(Z); |    XFREE(Z); | ||||||
| 
 | 
 | ||||||
|    return CRYPT_OK; |    return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -16,8 +16,8 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /* version */ | /* version */ | ||||||
| #define CRYPT   0x0106 | #define CRYPT   0x0107 | ||||||
| #define SCRYPT  "1.06" | #define SCRYPT  "1.07" | ||||||
| 
 | 
 | ||||||
| /* max size of either a cipher/hash block or symmetric key [largest of the two] */ | /* max size of either a cipher/hash block or symmetric key [largest of the two] */ | ||||||
| #define MAXBLOCKSIZE  128 | #define MAXBLOCKSIZE  128 | ||||||
|  | |||||||
| @ -54,6 +54,14 @@ int   XMEMCMP(const void *s1, const void *s2, size_t n); | |||||||
|    #define LTC_FAST_TYPE    unsigned long |    #define LTC_FAST_TYPE    unsigned long | ||||||
| #endif | #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 */ | /* detect sparc and sparc64 */ | ||||||
| #if defined(__sparc__) | #if defined(__sparc__) | ||||||
|   #define ENDIAN_BIG |   #define ENDIAN_BIG | ||||||
|  | |||||||
| @ -263,14 +263,16 @@ extern struct ltc_cipher_descriptor { | |||||||
|       @param pt      The plaintext |       @param pt      The plaintext | ||||||
|       @param ct      [out] The ciphertext |       @param ct      [out] The ciphertext | ||||||
|       @param skey    The scheduled key |       @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
 |    /** Decrypt a block
 | ||||||
|       @param ct      The ciphertext |       @param ct      The ciphertext | ||||||
|       @param pt      [out] The plaintext |       @param pt      [out] The plaintext | ||||||
|       @param skey    The scheduled key |       @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
 |    /** Test the block cipher
 | ||||||
|        @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |        @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 ct      Ciphertext | ||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param skey    The scheduled key context |        @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 
 |    /** Accelerated ECB decryption 
 | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
|        @param ct      Ciphertext |        @param ct      Ciphertext | ||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param skey    The scheduled key context |        @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 
 |    /** Accelerated CBC encryption 
 | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
| @ -310,8 +314,9 @@ extern struct ltc_cipher_descriptor { | |||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param IV      The initial value (input/output) |        @param IV      The initial value (input/output) | ||||||
|        @param skey    The scheduled key context |        @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 
 |    /** Accelerated CBC decryption 
 | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
| @ -319,8 +324,9 @@ extern struct ltc_cipher_descriptor { | |||||||
|        @param blocks  The number of complete blocks to process |        @param blocks  The number of complete blocks to process | ||||||
|        @param IV      The initial value (input/output) |        @param IV      The initial value (input/output) | ||||||
|        @param skey    The scheduled key context |        @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 
 |    /** Accelerated CTR encryption 
 | ||||||
|        @param pt      Plaintext |        @param pt      Plaintext | ||||||
| @ -329,12 +335,14 @@ extern struct ltc_cipher_descriptor { | |||||||
|        @param IV      The initial value (input/output) |        @param IV      The initial value (input/output) | ||||||
|        @param mode    little or big endian counter (mode=0 or mode=1) |        @param mode    little or big endian counter (mode=0 or mode=1) | ||||||
|        @param skey    The scheduled key context |        @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)
 |    /** Accelerated CCM packet (one-shot)
 | ||||||
|        @param key        The secret key to use |        @param key        The secret key to use | ||||||
|        @param keylen     The length of the secret key (octets) |        @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 nonce      The session nonce [use once] | ||||||
|        @param noncelen   The length of the nonce |        @param noncelen   The length of the nonce | ||||||
|        @param header     The header for the session |        @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) |        @param direction  Encrypt or Decrypt direction (0 or 1) | ||||||
|        @return CRYPT_OK if successful |        @return CRYPT_OK if successful | ||||||
|    */ |    */ | ||||||
|    void (*accel_ccm_memory)( |    int (*accel_ccm_memory)( | ||||||
|        const unsigned char *key,    unsigned long keylen, |        const unsigned char *key,    unsigned long keylen, | ||||||
|  |        symmetric_key       *uskey, | ||||||
|        const unsigned char *nonce,  unsigned long noncelen, |        const unsigned char *nonce,  unsigned long noncelen, | ||||||
|        const unsigned char *header, unsigned long headerlen, |        const unsigned char *header, unsigned long headerlen, | ||||||
|              unsigned char *pt,     unsigned long ptlen, |              unsigned char *pt,     unsigned long ptlen, | ||||||
| @ -369,8 +378,9 @@ extern struct ltc_cipher_descriptor { | |||||||
|        @param tag               [out] The MAC tag |        @param tag               [out] The MAC tag | ||||||
|        @param taglen            [in/out] The MAC tag length |        @param taglen            [in/out] The MAC tag length | ||||||
|        @param direction         Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) |        @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 *key,    unsigned long keylen, | ||||||
|        const unsigned char *IV,     unsigned long IVlen, |        const unsigned char *IV,     unsigned long IVlen, | ||||||
|        const unsigned char *adata,  unsigned long adatalen, |        const unsigned char *adata,  unsigned long adatalen, | ||||||
| @ -382,8 +392,8 @@ extern struct ltc_cipher_descriptor { | |||||||
| 
 | 
 | ||||||
| #ifdef BLOWFISH | #ifdef BLOWFISH | ||||||
| int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int blowfish_test(void); | int blowfish_test(void); | ||||||
| void blowfish_done(symmetric_key *skey); | void blowfish_done(symmetric_key *skey); | ||||||
| int blowfish_keysize(int *keysize); | int blowfish_keysize(int *keysize); | ||||||
| @ -392,8 +402,8 @@ extern const struct ltc_cipher_descriptor blowfish_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef RC5 | #ifdef RC5 | ||||||
| int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int rc5_test(void); | int rc5_test(void); | ||||||
| void rc5_done(symmetric_key *skey); | void rc5_done(symmetric_key *skey); | ||||||
| int rc5_keysize(int *keysize); | int rc5_keysize(int *keysize); | ||||||
| @ -402,8 +412,8 @@ extern const struct ltc_cipher_descriptor rc5_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef RC6 | #ifdef RC6 | ||||||
| int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int rc6_test(void); | int rc6_test(void); | ||||||
| void rc6_done(symmetric_key *skey); | void rc6_done(symmetric_key *skey); | ||||||
| int rc6_keysize(int *keysize); | int rc6_keysize(int *keysize); | ||||||
| @ -412,8 +422,8 @@ extern const struct ltc_cipher_descriptor rc6_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef RC2 | #ifdef RC2 | ||||||
| int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int rc2_test(void); | int rc2_test(void); | ||||||
| void rc2_done(symmetric_key *skey); | void rc2_done(symmetric_key *skey); | ||||||
| int rc2_keysize(int *keysize); | int rc2_keysize(int *keysize); | ||||||
| @ -422,8 +432,8 @@ extern const struct ltc_cipher_descriptor rc2_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef SAFERP | #ifdef SAFERP | ||||||
| int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int saferp_test(void); | int saferp_test(void); | ||||||
| void saferp_done(symmetric_key *skey); | void saferp_done(symmetric_key *skey); | ||||||
| int saferp_keysize(int *keysize); | 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_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_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); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); | ||||||
| int safer_k64_test(void); | int safer_k64_test(void); | ||||||
| int safer_sk64_test(void); | int safer_sk64_test(void); | ||||||
| int safer_sk128_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 | #define aes_enc_keysize         rijndael_enc_keysize | ||||||
| 
 | 
 | ||||||
| int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int rijndael_test(void); | int rijndael_test(void); | ||||||
| void rijndael_done(symmetric_key *skey); | void rijndael_done(symmetric_key *skey); | ||||||
| int rijndael_keysize(int *keysize); | int rijndael_keysize(int *keysize); | ||||||
| int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | void rijndael_enc_done(symmetric_key *skey); | ||||||
| int rijndael_enc_keysize(int *keysize); | int rijndael_enc_keysize(int *keysize); | ||||||
| extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; | 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 | #ifdef XTEA | ||||||
| int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int xtea_test(void); | int xtea_test(void); | ||||||
| void xtea_done(symmetric_key *skey); | void xtea_done(symmetric_key *skey); | ||||||
| int xtea_keysize(int *keysize); | int xtea_keysize(int *keysize); | ||||||
| @ -486,8 +496,8 @@ extern const struct ltc_cipher_descriptor xtea_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef TWOFISH | #ifdef TWOFISH | ||||||
| int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int twofish_test(void); | int twofish_test(void); | ||||||
| void twofish_done(symmetric_key *skey); | void twofish_done(symmetric_key *skey); | ||||||
| int twofish_keysize(int *keysize); | int twofish_keysize(int *keysize); | ||||||
| @ -496,14 +506,14 @@ extern const struct ltc_cipher_descriptor twofish_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef DES | #ifdef DES | ||||||
| int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int des_test(void); | int des_test(void); | ||||||
| void des_done(symmetric_key *skey); | void des_done(symmetric_key *skey); | ||||||
| int des_keysize(int *keysize); | int des_keysize(int *keysize); | ||||||
| int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int des3_test(void); | int des3_test(void); | ||||||
| void des3_done(symmetric_key *skey); | void des3_done(symmetric_key *skey); | ||||||
| int des3_keysize(int *keysize); | int des3_keysize(int *keysize); | ||||||
| @ -512,8 +522,8 @@ extern const struct ltc_cipher_descriptor des_desc, des3_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef CAST5 | #ifdef CAST5 | ||||||
| int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int cast5_test(void); | int cast5_test(void); | ||||||
| void cast5_done(symmetric_key *skey); | void cast5_done(symmetric_key *skey); | ||||||
| int cast5_keysize(int *keysize); | int cast5_keysize(int *keysize); | ||||||
| @ -522,8 +532,8 @@ extern const struct ltc_cipher_descriptor cast5_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef NOEKEON | #ifdef NOEKEON | ||||||
| int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int noekeon_test(void); | int noekeon_test(void); | ||||||
| void noekeon_done(symmetric_key *skey); | void noekeon_done(symmetric_key *skey); | ||||||
| int noekeon_keysize(int *keysize); | int noekeon_keysize(int *keysize); | ||||||
| @ -532,8 +542,8 @@ extern const struct ltc_cipher_descriptor noekeon_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef SKIPJACK | #ifdef SKIPJACK | ||||||
| int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int skipjack_test(void); | int skipjack_test(void); | ||||||
| void skipjack_done(symmetric_key *skey); | void skipjack_done(symmetric_key *skey); | ||||||
| int skipjack_keysize(int *keysize); | int skipjack_keysize(int *keysize); | ||||||
| @ -542,8 +552,8 @@ extern const struct ltc_cipher_descriptor skipjack_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef KHAZAD | #ifdef KHAZAD | ||||||
| int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int khazad_test(void); | int khazad_test(void); | ||||||
| void khazad_done(symmetric_key *skey); | void khazad_done(symmetric_key *skey); | ||||||
| int khazad_keysize(int *keysize); | int khazad_keysize(int *keysize); | ||||||
| @ -552,8 +562,8 @@ extern const struct ltc_cipher_descriptor khazad_desc; | |||||||
| 
 | 
 | ||||||
| #ifdef ANUBIS | #ifdef ANUBIS | ||||||
| int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); | 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); | int 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); | ||||||
| int anubis_test(void); | int anubis_test(void); | ||||||
| void anubis_done(symmetric_key *skey); | void anubis_done(symmetric_key *skey); | ||||||
| int anubis_keysize(int *keysize); | int anubis_keysize(int *keysize); | ||||||
|  | |||||||
| @ -186,6 +186,9 @@ | |||||||
| /* Include RSA support */ | /* Include RSA support */ | ||||||
| #define MRSA | #define MRSA | ||||||
| 
 | 
 | ||||||
|  | /* Include Katja (an Rabin variant like RSA) */ | ||||||
|  | // #define MKAT 
 | ||||||
|  | 
 | ||||||
| /* Digital Signature Algorithm */ | /* Digital Signature Algorithm */ | ||||||
| #define MDSA | #define MDSA | ||||||
| /* Max diff between group and modulus size in bytes */ | /* Max diff between group and modulus size in bytes */ | ||||||
| @ -200,11 +203,13 @@ | |||||||
| /* #define LTC_ECC_TIMING_RESISTANT */ | /* #define LTC_ECC_TIMING_RESISTANT */ | ||||||
| 
 | 
 | ||||||
| /* Supported ECC Key Sizes */ | /* Supported ECC Key Sizes */ | ||||||
| #define ECC192 | #ifndef LTC_NO_CURVES | ||||||
| #define ECC224 |    #define ECC192 | ||||||
| #define ECC256 |    #define ECC224 | ||||||
| #define ECC384 |    #define ECC256 | ||||||
| #define ECC521 |    #define ECC384 | ||||||
|  |    #define ECC521 | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| /* Include the MPI functionality?  (required by the PK algorithms) */ | /* Include the MPI functionality?  (required by the PK algorithms) */ | ||||||
| #define MPI | #define MPI | ||||||
| @ -240,6 +245,8 @@ | |||||||
| 
 | 
 | ||||||
| #define LTC_MUTEX_GLOBAL(x)   pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; | #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_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_LOCK(x)     pthread_mutex_lock(x); | ||||||
| #define LTC_MUTEX_UNLOCK(x)   pthread_mutex_unlock(x); | #define LTC_MUTEX_UNLOCK(x)   pthread_mutex_unlock(x); | ||||||
| 
 | 
 | ||||||
| @ -248,6 +255,8 @@ | |||||||
| /* default no functions */ | /* default no functions */ | ||||||
| #define LTC_MUTEX_GLOBAL(x) | #define LTC_MUTEX_GLOBAL(x) | ||||||
| #define LTC_MUTEX_PROTO(x) | #define LTC_MUTEX_PROTO(x) | ||||||
|  | #define LTC_MUTEX_TYPE(x) | ||||||
|  | #define LTC_MUTEX_INIT(x) | ||||||
| #define LTC_MUTEX_LOCK(x) | #define LTC_MUTEX_LOCK(x) | ||||||
| #define LTC_MUTEX_UNLOCK(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, | int ccm_memory(int cipher, | ||||||
|     const unsigned char *key,    unsigned long keylen, |     const unsigned char *key,    unsigned long keylen, | ||||||
|  |     symmetric_key       *uskey, | ||||||
|     const unsigned char *nonce,  unsigned long noncelen, |     const unsigned char *nonce,  unsigned long noncelen, | ||||||
|     const unsigned char *header, unsigned long headerlen, |     const unsigned char *header, unsigned long headerlen, | ||||||
|           unsigned char *pt,     unsigned long ptlen, |           unsigned char *pt,     unsigned long ptlen, | ||||||
|  | |||||||
| @ -285,6 +285,50 @@ static inline unsigned RORc(unsigned word, const int i) | |||||||
| 
 | 
 | ||||||
| #endif | #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 | #else | ||||||
| 
 | 
 | ||||||
| /* rotates the hard way */ | /* rotates the hard way */ | ||||||
|  | |||||||
| @ -11,6 +11,10 @@ | |||||||
|    typedef void ecc_point; |    typedef void ecc_point; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifndef MRSA | ||||||
|  |    typedef void rsa_key; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /** math descriptor */ | /** math descriptor */ | ||||||
| typedef struct { | typedef struct { | ||||||
|    /** Name of the math provider */ |    /** Name of the math provider */ | ||||||
| @ -42,6 +46,13 @@ typedef struct { | |||||||
| 
 | 
 | ||||||
| /* ---- data movement ---- */ | /* ---- 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 
 |    /** copy 
 | ||||||
|       @param   src   The number to copy from |       @param   src   The number to copy from | ||||||
|       @param   dst   The number to write to  |       @param   dst   The number to write to  | ||||||
| @ -339,11 +350,22 @@ typedef struct { | |||||||
| 
 | 
 | ||||||
| /* ---- (optional) rsa optimized math (for internal CRT) ---- */ | /* ---- (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
 |    /** RSA exponentiation
 | ||||||
|       @param in       The octet array representing the base |       @param in       The octet array representing the base | ||||||
|       @param inlen    The length of the input |       @param inlen    The length of the input | ||||||
|       @param out      The destination (to be stored in an octet array format) |       @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 which    PK_PUBLIC for public RSA and PK_PRIVATE for private RSA | ||||||
|       @param key      The RSA key to use  |       @param key      The RSA key to use  | ||||||
|       @return CRYPT_OK on success |       @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_init_multi                ltc_init_multi | ||||||
| #define mp_clear(a)                  ltc_mp.deinit(a) | #define mp_clear(a)                  ltc_mp.deinit(a) | ||||||
| #define mp_clear_multi               ltc_deinit_multi | #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_copy(a, b)                ltc_mp.copy(a, b) | ||||||
| 
 | 
 | ||||||
| #define mp_set(a, b)                 ltc_mp.set_int(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 | #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 ---- */ | /* ---- ECC Routines ---- */ | ||||||
| #ifdef MECC | #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 */ | /** Structure defines a NIST GF(p) curve */ | ||||||
| typedef struct { | typedef struct { | ||||||
|    /** The size of the curve in octets */ |    /** The size of the curve in octets */ | ||||||
| @ -104,8 +165,10 @@ typedef struct { | |||||||
| typedef struct { | typedef struct { | ||||||
|     /** The x co-ordinate */ |     /** The x co-ordinate */ | ||||||
|     void *x; |     void *x; | ||||||
|  | 
 | ||||||
|     /** The y co-ordinate */ |     /** The y co-ordinate */ | ||||||
|     void *y; |     void *y; | ||||||
|  | 
 | ||||||
|     /** The z co-ordinate */ |     /** The z co-ordinate */ | ||||||
|     void *z; |     void *z; | ||||||
| } ecc_point; | } ecc_point; | ||||||
| @ -114,10 +177,13 @@ typedef struct { | |||||||
| typedef struct { | typedef struct { | ||||||
|     /** Type of key, PK_PRIVATE or PK_PUBLIC */ |     /** Type of key, PK_PRIVATE or PK_PUBLIC */ | ||||||
|     int type; |     int type; | ||||||
|  | 
 | ||||||
|     /** Index into the ltc_ecc_sets[] for the parameters of this curve */ |     /** Index into the ltc_ecc_sets[] for the parameters of this curve */ | ||||||
|     int idx; |     int idx; | ||||||
|  | 
 | ||||||
|     /** The public key */ |     /** The public key */ | ||||||
|     ecc_point pubkey; |     ecc_point pubkey; | ||||||
|  | 
 | ||||||
|     /** The private key */ |     /** The private key */ | ||||||
|     void *k; |     void *k; | ||||||
| } ecc_key; | } ecc_key; | ||||||
| @ -125,47 +191,52 @@ typedef struct { | |||||||
| /** the ECC params provided */ | /** the ECC params provided */ | ||||||
| extern const ltc_ecc_set_type ltc_ecc_sets[]; | extern const ltc_ecc_set_type ltc_ecc_sets[]; | ||||||
| 
 | 
 | ||||||
| int ecc_test(void); | int  ecc_test(void); | ||||||
| void ecc_sizes(int *low, int *high); | void ecc_sizes(int *low, int *high); | ||||||
| int ecc_get_size(ecc_key *key); | int  ecc_get_size(ecc_key *key); | ||||||
| 
 | 
 | ||||||
| int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); | int  ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); | ||||||
| void ecc_free(ecc_key *key); | void ecc_free(ecc_key *key); | ||||||
| 
 | 
 | ||||||
| int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | int  ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | ||||||
| int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); | int  ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); | ||||||
| 
 | 
 | ||||||
| int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,  | int  ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,  | ||||||
|                       unsigned char *out, unsigned long *outlen); |                        unsigned char *out, unsigned long *outlen); | ||||||
| 
 | 
 | ||||||
| int ecc_encrypt_key(const unsigned char *in,   unsigned long inlen, | int  ecc_encrypt_key(const unsigned char *in,   unsigned long inlen, | ||||||
|                           unsigned char *out,  unsigned long *outlen,  |                            unsigned char *out,  unsigned long *outlen,  | ||||||
|                           prng_state *prng, int wprng, int hash,  |                            prng_state *prng, int wprng, int hash,  | ||||||
|                           ecc_key *key); |                            ecc_key *key); | ||||||
| 
 | 
 | ||||||
| int ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen, | int  ecc_decrypt_key(const unsigned char *in,  unsigned long  inlen, | ||||||
|                           unsigned char *out, unsigned long *outlen,  |                            unsigned char *out, unsigned long *outlen,  | ||||||
|                           ecc_key *key); |                            ecc_key *key); | ||||||
| 
 | 
 | ||||||
| int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,  | int  ecc_sign_hash(const unsigned char *in,  unsigned long inlen,  | ||||||
|                         unsigned char *out, unsigned long *outlen,  |                          unsigned char *out, unsigned long *outlen,  | ||||||
|                         prng_state *prng, int wprng, ecc_key *key); |                          prng_state *prng, int wprng, ecc_key *key); | ||||||
| 
 | 
 | ||||||
| int ecc_verify_hash(const unsigned char *sig,  unsigned long siglen, | int  ecc_verify_hash(const unsigned char *sig,  unsigned long siglen, | ||||||
|                     const unsigned char *hash, unsigned long hashlen,  |                      const unsigned char *hash, unsigned long hashlen,  | ||||||
|                     int *stat, ecc_key *key); |                      int *stat, ecc_key *key); | ||||||
| 
 | 
 | ||||||
| /* low level functions */ | /* low level functions */ | ||||||
| ecc_point *ltc_ecc_new_point(void); | ecc_point *ltc_ecc_new_point(void); | ||||||
| void       ltc_ecc_del_point(ecc_point *p); | void       ltc_ecc_del_point(ecc_point *p); | ||||||
|  | int        ltc_ecc_is_valid_idx(int n); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* point ops (mp == montgomery digit) */ | /* point ops (mp == montgomery digit) */ | ||||||
| /* R = 2P */ | /* 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 */ | /* 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 */ | /* R = kG */ | ||||||
| int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); | ||||||
|  | 
 | ||||||
| /* map P to affine from projective */ | /* map P to affine from projective */ | ||||||
| int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); | 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 { | typedef struct { | ||||||
|    /** The key type, PK_PRIVATE or PK_PUBLIC */ |    /** The key type, PK_PRIVATE or PK_PUBLIC */ | ||||||
|    int type;  |    int type;  | ||||||
|  | 
 | ||||||
|    /** The order of the sub-group used in octets */ |    /** The order of the sub-group used in octets */ | ||||||
|    int qord; |    int qord; | ||||||
|  | 
 | ||||||
|    /** The generator  */ |    /** The generator  */ | ||||||
|    void *g; |    void *g; | ||||||
|  | 
 | ||||||
|    /** The prime used to generate the sub-group */ |    /** The prime used to generate the sub-group */ | ||||||
|    void *q; |    void *q; | ||||||
|  | 
 | ||||||
|    /** The large prime that generats the field the contains the sub-group */ |    /** The large prime that generats the field the contains the sub-group */ | ||||||
|    void *p; |    void *p; | ||||||
|  | 
 | ||||||
|    /** The private key */ |    /** The private key */ | ||||||
|    void *x; |    void *x; | ||||||
|  | 
 | ||||||
|    /** The public key */ |    /** The public key */ | ||||||
|    void *y; |    void *y; | ||||||
| } dsa_key; | } 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); | int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); | ||||||
| void dsa_free(dsa_key *key); | void dsa_free(dsa_key *key); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen, | int dsa_sign_hash_raw(const unsigned char *in,  unsigned long inlen, | ||||||
|                                    void *r,   void *s, |                                    void *r,   void *s, | ||||||
|                                prng_state *prng, int wprng, dsa_key *key); |                                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,  |                     const unsigned char *hash, unsigned long hashlen,  | ||||||
|                           int           *stat, dsa_key       *key); |                           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_import(const unsigned char *in, unsigned long inlen, dsa_key *key); | ||||||
| 
 |  | ||||||
| int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); | int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); | ||||||
| 
 |  | ||||||
| int dsa_verify_key(dsa_key *key, int *stat); | int dsa_verify_key(dsa_key *key, int *stat); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | int dsa_shared_secret(void          *private_key, void *base, | ||||||
|  |                       dsa_key       *public_key, | ||||||
|  |                       unsigned char *out,         unsigned long *outlen); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef LTC_DER | #ifdef LTC_DER | ||||||
| @ -239,7 +327,7 @@ enum { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** A LTC ASN.1 list type */ | /** A LTC ASN.1 list type */ | ||||||
| typedef struct { | typedef struct ltc_asn1_list_ { | ||||||
|    /** The LTC ASN.1 enumerated type identifier */ |    /** The LTC ASN.1 enumerated type identifier */ | ||||||
|    int           type; |    int           type; | ||||||
|    /** The data to encode or place for decoding */ |    /** The data to encode or place for decoding */ | ||||||
| @ -248,6 +336,8 @@ typedef struct { | |||||||
|    unsigned long size; |    unsigned long size; | ||||||
|    /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ |    /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ | ||||||
|    int           used; |    int           used; | ||||||
|  |    /** prev/next entry in the list */ | ||||||
|  |    struct ltc_asn1_list_ *prev, *next, *child, *parent; | ||||||
| } ltc_asn1_list; | } ltc_asn1_list; | ||||||
| 
 | 
 | ||||||
| #define LTC_SET_ASN1(list, index, Type, Data, Size)  \ | #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, | int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, | ||||||
|                         unsigned long *outlen); |                         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_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); | ||||||
| int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); | int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); | ||||||
| 
 | 
 | ||||||
|  | /* handle unknown list decoder */ | ||||||
|  | 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 */ | /* INTEGER */ | ||||||
| int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); | 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); | int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ | |||||||
| /* ===> PKCS #1 -- RSA Cryptography <=== */ | /* ===> PKCS #1 -- RSA Cryptography <=== */ | ||||||
| #ifdef PKCS_1 | #ifdef PKCS_1 | ||||||
| 
 | 
 | ||||||
| int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen, | int pkcs_1_mgf1(      int            hash_idx, | ||||||
|                       int            hash_idx, |                 const unsigned char *seed, unsigned long seedlen, | ||||||
|                       unsigned char *mask, unsigned long masklen); |                       unsigned char *mask, unsigned long masklen); | ||||||
| 
 | 
 | ||||||
| int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); | int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ struct yarrow_prng { | |||||||
|     int                   cipher, hash; |     int                   cipher, hash; | ||||||
|     unsigned char         pool[MAXBLOCKSIZE]; |     unsigned char         pool[MAXBLOCKSIZE]; | ||||||
|     symmetric_CTR         ctr; |     symmetric_CTR         ctr; | ||||||
|  |     LTC_MUTEX_TYPE(prng_lock) | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -28,6 +29,7 @@ struct fortuna_prng { | |||||||
|                   wd;             |                   wd;             | ||||||
| 
 | 
 | ||||||
|     ulong64       reset_cnt;  /* number of times we have reset */ |     ulong64       reset_cnt;  /* number of times we have reset */ | ||||||
|  |     LTC_MUTEX_TYPE(prng_lock) | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -61,7 +61,9 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) | |||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* encrypt it */ |    /* 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); |    cipher_descriptor[omac->cipher_idx].done(&omac->key); | ||||||
|   |   | ||||||
|    /* output it */ |    /* 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) */ |    /* first calc L which is Ek(0) */ | ||||||
|    zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); |    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! */ |    /* now do the mults, whoopy! */ | ||||||
|    for (x = 0; x < 2; x++) { |    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])); |               *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); | ||||||
|           } |           } | ||||||
|           in += 16; |           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; |       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++) { |           for (x = 0; x < (unsigned long)omac->blklen; x++) { | ||||||
|               omac->block[x] ^= omac->prev[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; |           omac->buflen = 0; | ||||||
|        } |        } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -49,7 +49,9 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) | |||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* encrypt it */ |    /* 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); |    cipher_descriptor[state->cipher_idx].done(&state->key); | ||||||
| 
 | 
 | ||||||
|    /* store it */ |    /* store it */ | ||||||
|  | |||||||
| @ -87,7 +87,9 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l | |||||||
| 
 | 
 | ||||||
|    /* find L = E[0] */ |    /* find L = E[0] */ | ||||||
|    zeromem(L, pmac->block_len); |    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 */ |    /* find Ls[i] = L << i for i == 0..31 */ | ||||||
|    XMEMCPY(pmac->Ls[0], L, pmac->block_len); |    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->block,    sizeof(pmac->block)); | ||||||
|     zeromem(pmac->Li,       sizeof(pmac->Li)); |     zeromem(pmac->Li,       sizeof(pmac->Li)); | ||||||
|     zeromem(pmac->checksum, sizeof(pmac->checksum)); |     zeromem(pmac->checksum, sizeof(pmac->checksum)); | ||||||
| 
 |     err = CRYPT_OK; | ||||||
|  | error: | ||||||
| #ifdef LTC_CLEAN_STACK | #ifdef LTC_CLEAN_STACK | ||||||
|     zeromem(L, pmac->block_len); |     zeromem(L, pmac->block_len); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     XFREE(L); |     XFREE(L); | ||||||
| 
 | 
 | ||||||
|     return CRYPT_OK; |     return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #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)) { |           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])); |               *((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)) { |           for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { | ||||||
|               *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y])); |               *((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++) { |           for (x = 0; x < (unsigned long)pmac->block_len; x++) { | ||||||
|                Z[x] = pmac->Li[x] ^ pmac->block[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++) { |           for (x = 0; x < (unsigned long)pmac->block_len; x++) { | ||||||
|               pmac->checksum[x] ^= Z[x]; |               pmac->checksum[x] ^= Z[x]; | ||||||
|           } |           } | ||||||
|  | |||||||
| @ -65,6 +65,13 @@ static void deinit(void *a) | |||||||
|    XFREE(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) | static int copy(void *a, void *b) | ||||||
| { | { | ||||||
|    LTC_ARGCHK(a != NULL); |    LTC_ARGCHK(a != NULL); | ||||||
| @ -379,6 +386,7 @@ const ltc_math_descriptor ltm_desc = { | |||||||
|    &init_copy, |    &init_copy, | ||||||
|    &deinit, |    &deinit, | ||||||
| 
 | 
 | ||||||
|  |    &neg, | ||||||
|    ©, |    ©, | ||||||
| 
 | 
 | ||||||
|    &set_int, |    &set_int, | ||||||
| @ -420,10 +428,11 @@ const ltc_math_descriptor ltm_desc = { | |||||||
|    &exptmod, |    &exptmod, | ||||||
|    &isprime, |    &isprime, | ||||||
| 
 | 
 | ||||||
|    NULL, |    <c_ecc_mulmod, | ||||||
|    NULL, |    <c_ecc_projective_add_point, | ||||||
|    NULL, |    <c_ecc_map, | ||||||
| 
 | 
 | ||||||
|  |    NULL, | ||||||
|    NULL |    NULL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -34,6 +34,7 @@ int ltc_init_multi(void **a, ...) | |||||||
|           va_end(clean_list); |           va_end(clean_list); | ||||||
|           return CRYPT_MEM; |           return CRYPT_MEM; | ||||||
|        } |        } | ||||||
|  |        ++np; | ||||||
|        cur = va_arg(args, void**); |        cur = va_arg(args, void**); | ||||||
|    } |    } | ||||||
|    va_end(args); |    va_end(args); | ||||||
|  | |||||||
| @ -59,6 +59,14 @@ static void deinit(void *a) | |||||||
|    XFREE(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) | static int copy(void *a, void *b) | ||||||
| { | { | ||||||
|    LTC_ARGCHK(a != NULL); |    LTC_ARGCHK(a != NULL); | ||||||
| @ -390,6 +398,7 @@ const ltc_math_descriptor tfm_desc = { | |||||||
|    &init_copy, |    &init_copy, | ||||||
|    &deinit, |    &deinit, | ||||||
| 
 | 
 | ||||||
|  |    &neg, | ||||||
|    ©, |    ©, | ||||||
| 
 | 
 | ||||||
|    &set_int, |    &set_int, | ||||||
| @ -431,10 +440,11 @@ const ltc_math_descriptor tfm_desc = { | |||||||
|    &exptmod, |    &exptmod, | ||||||
|    &isprime, |    &isprime, | ||||||
| 
 | 
 | ||||||
|    NULL, |    <c_ecc_mulmod, | ||||||
|    NULL, |    <c_ecc_projective_add_point, | ||||||
|    NULL, |    <c_ecc_map, | ||||||
| 
 | 
 | ||||||
|  |    NULL, | ||||||
|    NULL |    NULL | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -229,15 +229,18 @@ const char *crypt_build_settings = | |||||||
| #if defined(MDSA) | #if defined(MDSA) | ||||||
|     "   DSA\n" |     "   DSA\n" | ||||||
| #endif | #endif | ||||||
|  | #if defined(MKAT) | ||||||
|  |     "   Katja\n" | ||||||
|  | #endif     | ||||||
| 
 | 
 | ||||||
|     "\nCompiler:\n" |     "\nCompiler:\n" | ||||||
| #if defined(WIN32) | #if defined(WIN32) | ||||||
|     "   WIN32 platform detected.\n" |     "   WIN32 platform detected.\n" | ||||||
| #endif | #endif | ||||||
| #if defined(LBL_CYGWIN__) | #if defined(__CYGWIN__) | ||||||
|     "   CYGWIN Detected.\n" |     "   CYGWIN Detected.\n" | ||||||
| #endif | #endif | ||||||
| #if defined(LBL_DJGPP__) | #if defined(__DJGPP__) | ||||||
|     "   DJGPP Detected.\n" |     "   DJGPP Detected.\n" | ||||||
| #endif | #endif | ||||||
| #if defined(_MSC_VER) | #if defined(_MSC_VER) | ||||||
| @ -249,9 +252,12 @@ const char *crypt_build_settings = | |||||||
| #if defined(INTEL_CC) | #if defined(INTEL_CC) | ||||||
|     "   Intel C Compiler detected.\n" |     "   Intel C Compiler detected.\n" | ||||||
| #endif | #endif | ||||||
| #if defined(LBL_x86_64__) | #if defined(__x86_64__) | ||||||
|     "   x86-64 detected.\n" |     "   x86-64 detected.\n" | ||||||
| #endif | #endif | ||||||
|  | #if defined(LTC_PPC32) | ||||||
|  |     "   LTC_PPC32 defined \n" | ||||||
|  | #endif     | ||||||
| 
 | 
 | ||||||
|     "\nVarious others: " |     "\nVarious others: " | ||||||
| #if defined(BASE64) | #if defined(BASE64) | ||||||
|  | |||||||
| @ -59,11 +59,13 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s | |||||||
| #endif | #endif | ||||||
|     |     | ||||||
|    if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { |    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 { |    } else { | ||||||
|       while (len) { |       while (len) { | ||||||
|          /* decrypt */ |          /* 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 */ |          /* xor IV against plaintext */ | ||||||
|          #if defined(LTC_FAST) |          #if defined(LTC_FAST) | ||||||
|  | |||||||
| @ -53,7 +53,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|    if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { |    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 { |    } else { | ||||||
|       while (len) { |       while (len) { | ||||||
|          /* xor IV against plaintext */ |          /* xor IV against plaintext */ | ||||||
| @ -68,7 +68,9 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | |||||||
| 	 #endif | 	 #endif | ||||||
| 
 | 
 | ||||||
|          /* encrypt */ |          /* 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 */ |         /* store IV [ciphertext] for a future block */ | ||||||
|          #if defined(LTC_FAST) |          #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) { |    while (len-- > 0) { | ||||||
|        if (cfb->padlen == cfb->blocklen) { |        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->padlen = 0; | ||||||
|        } |        } | ||||||
|        cfb->pad[cfb->padlen] = *ct; |        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) { |    while (len-- > 0) { | ||||||
|        if (cfb->padlen == cfb->blocklen) { |        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->padlen = 0; | ||||||
|        } |        } | ||||||
|        cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); |        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 */ |    /* force next block */ | ||||||
|    cfb->padlen = 0; |    cfb->padlen = 0; | ||||||
|    cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); |    return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); | ||||||
| 
 |  | ||||||
|    return CRYPT_OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif  | #endif  | ||||||
|  | |||||||
| @ -54,10 +54,8 @@ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, | |||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /* encrypt the IV */ |    /* encrypt the IV */ | ||||||
|    cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); |  | ||||||
|    cfb->padlen = 0; |    cfb->padlen = 0; | ||||||
| 
 |    return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); | ||||||
|    return CRYPT_OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #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 */ |    /* 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)) { |    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; |       len %= ctr->blocklen; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
| @ -79,7 +81,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s | |||||||
|          } |          } | ||||||
| 
 | 
 | ||||||
|          /* encrypt it */ |          /* 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; |          ctr->padlen = 0; | ||||||
|       } |       } | ||||||
| #ifdef LTC_FAST | #ifdef LTC_FAST | ||||||
|  | |||||||
| @ -45,9 +45,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) | |||||||
|     |     | ||||||
|    /* force next block */ |    /* force next block */ | ||||||
|    ctr->padlen = 0; |    ctr->padlen = 0; | ||||||
|    cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); |    return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); | ||||||
|     |  | ||||||
|    return CRYPT_OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif  | #endif  | ||||||
|  | |||||||
| @ -59,8 +59,7 @@ int ctr_start(               int   cipher, | |||||||
|    for (x = 0; x < ctr->blocklen; x++) { |    for (x = 0; x < ctr->blocklen; x++) { | ||||||
|        ctr->ctr[x] = IV[x]; |        ctr->ctr[x] = IV[x]; | ||||||
|    } |    } | ||||||
|    cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); |    return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); | ||||||
|    return CRYPT_OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -40,10 +40,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s | |||||||
| 
 | 
 | ||||||
|    /* check for accel */ |    /* check for accel */ | ||||||
|    if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { |    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 { |    } else { | ||||||
|       while (len) { |       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; |          pt  += cipher_descriptor[ecb->cipher].block_length; | ||||||
|          ct  += cipher_descriptor[ecb->cipher].block_length; |          ct  += cipher_descriptor[ecb->cipher].block_length; | ||||||
|          len -= 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 */ |    /* check for accel */ | ||||||
|    if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { |    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 { |    } else { | ||||||
|       while (len) { |       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; |          pt  += cipher_descriptor[ecb->cipher].block_length; | ||||||
|          ct  += cipher_descriptor[ecb->cipher].block_length; |          ct  += cipher_descriptor[ecb->cipher].block_length; | ||||||
|          len -= 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) { |    while (len-- > 0) { | ||||||
|        if (ofb->padlen == ofb->blocklen) { |        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; |           ofb->padlen = 0; | ||||||
|        } |        } | ||||||
|        *ct++ = *pt++ ^ ofb->IV[ofb->padlen++]; |        *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 */ |    /* force next block */ | ||||||
|    ofb->padlen = 0; |    ofb->padlen = 0; | ||||||
|    cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); |    return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); | ||||||
|    return CRYPT_OK; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif  | #endif  | ||||||
|  | |||||||
| @ -51,7 +51,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen, | |||||||
|    /* get the length of the data */ |    /* get the length of the data */ | ||||||
|    if (in[x] & 0x80) { |    if (in[x] & 0x80) { | ||||||
|       /* long format get number of length bytes */ |       /* long format get number of length bytes */ | ||||||
|       y = in[x++] & 127; |       y = in[x++] & 0x7F; | ||||||
| 
 | 
 | ||||||
|       /* invalid if 0 or > 2 */ |       /* invalid if 0 or > 2 */ | ||||||
|       if (y == 0 || y > 2) { |       if (y == 0 || y > 2) { | ||||||
| @ -65,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in,  unsigned long inlen, | |||||||
|       } |       } | ||||||
|    } else { |    } else { | ||||||
|       /* short format */ |       /* short format */ | ||||||
|       dlen = in[x++] & 127; |       dlen = in[x++] & 0x7F; | ||||||
|    } |    } | ||||||
|    |    | ||||||
|    /* is the data len too long or too short? */ |    /* 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: |            case LTC_ASN1_NULL: | ||||||
|                if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { |                if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { | ||||||
|                   *inlen = 2; |                   *inlen = 2; | ||||||
|  |                   list[x].used   = 1; | ||||||
|                   return CRYPT_OK; |                   return CRYPT_OK; | ||||||
|                } |                } | ||||||
|                break; |                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; |                y += x; | ||||||
|                break; |                break; | ||||||
| 
 | 
 | ||||||
|  |            case LTC_ASN1_UTCTIME: | ||||||
|  |                if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { | ||||||
|  |                   goto LBL_ERR; | ||||||
|  |                } | ||||||
|  |                y += x; | ||||||
|  |                break; | ||||||
|  | 
 | ||||||
|            case LTC_ASN1_SEQUENCE: |            case LTC_ASN1_SEQUENCE: | ||||||
|                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { |                if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { | ||||||
|                   goto LBL_ERR; |                   goto LBL_ERR; | ||||||
|  | |||||||
							
								
								
									
										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(in  != NULL); | ||||||
|    LTC_ARGCHK(key != NULL); |    LTC_ARGCHK(key != NULL); | ||||||
|  |    LTC_ARGCHK(ltc_mp.name != NULL); | ||||||
| 
 | 
 | ||||||
|    /* init key */ |    /* init key */ | ||||||
|    if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) { |    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; |    unsigned char *buf; | ||||||
| 
 | 
 | ||||||
|    LTC_ARGCHK(key  != NULL); |    LTC_ARGCHK(key  != NULL); | ||||||
|  |    LTC_ARGCHK(ltc_mp.name != NULL); | ||||||
| 
 | 
 | ||||||
|    /* check prng */ |    /* check prng */ | ||||||
|    if ((err = prng_is_valid(wprng)) != CRYPT_OK) { |    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