added libtomcrypt-1.07

This commit is contained in:
Tom St Denis 2005-11-18 05:15:37 +00:00 committed by Steffen Jaeckel
parent 72412f6dac
commit 4a1a5796de
129 changed files with 5393 additions and 2013 deletions

View File

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

37
TODO
View File

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

49
changes
View File

@ -1,3 +1,44 @@
November 18th, 2005
v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly. That's because as of a few releases ago
I added support to set the mode of the counter at init time
-- Fixed some "testprof" make issues
-- Added RSA keygen to the math descriptors
-- Fixed install_test target ... oops
-- made the "ranlib" program renamable useful for cross-compiling
-- Made the cipher accelerators return error codes. :-)
-- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets
-- Added "Katja" public key crypto. It's based on the recent N = p^2q work by Katja. I added OAEP padding
to it. Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly
analyzed. It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also
some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible.
-- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya :-)
-- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER
-- Cleaned up the LIBTEST_S definitions in both GNU makefiles. A few minor touchups as well.
-- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this.
-- der_decode_choice() would fail to mark a NULL as "used" when decoding. Fixed
-- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-)
-- Added mp_neg() to the math descriptors.
-- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent)
-- Made the math descriptors buildable when RSA has been undefined
-- ECC timing demo now capable of detecting which curves have been defined
-- Refactored the ECC code so it's easier to maintain. (note: the form of this code hasn't really changed since I first added ECC ... :-/)
-- Updated the documentation w.r.t. ECC and the accelerators to keep it current
-- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error.
-- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes)
-- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters)
-- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead!
-- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used)
-- ECC code now ALWAYS uses the accelerator interface. This allows people who use the accelerators to not have the stock
ECC point add/dbl/mul code linked in. Yeah space savings! Rah Rah Rah.
-- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at
build time (e.g. LTC_PTHREAD == pthreads)
-- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock)
-- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-)
-- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that]
-- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD]
-- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing
their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask)
August 1st, 2005
v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson]
-- Added fourth ARGCHK type which outputs to stderr and continues. Useful if you trap sigsegv. [Valient Gough]
@ -234,7 +275,7 @@ October 29th, 2004
v0.99 -- Merged in the latest version of LTM which includes all of the recent bug fixes
-- Deprecated LTMSSE and removed it (to be replaced with TFM later on)
-- Stefan Arentz pointed out that mp_s_rmap should be extern
-- Kristian Gjøsteen pointed out that there are typos in the
-- Kristian Gj?steen pointed out that there are typos in the
"test" makefile and minor issues in Yarrow and Sober [just cosmetics really]
-- Matthew P. Cashdollar pointed out that "export" is a C++ keyword
so changed the PRNG api to use "pexport" and "pimport"
@ -613,7 +654,7 @@ v0.81 -- Merged in new makefile from Clay Culver and Mike Frysinger
as much as possible. This sped the routine up quite a bit.
-- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
-- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
(fix due to Mika Boström)
(fix due to Mika Bostr?m)
-- Merged in LibTomMath for kicks
-- Changed the build process so that by default "mycrypt_custom.h" is included and provided
The makefile doesn't include any build options anymore
@ -1342,6 +1383,6 @@ v0.02 -- Changed RC5 to only allow 12 to 24 rounds
v0.01 -- We will call this the first version.
/* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
/* $Revision: 1.123 $ */
/* $Date: 2005/08/01 16:50:34 $ */
/* $Revision: 1.151 $ */
/* $Date: 2005/11/17 22:04:00 $ */

303
crypt.tex
View File

@ -47,7 +47,7 @@
\def\gap{\vspace{0.5ex}}
\makeindex
\begin{document}
\title{LibTomCrypt \\ Version 1.06}
\title{LibTomCrypt \\ Version 1.07}
\author{Tom St Denis \\
\\
tomstdenis@gmail.com \\
@ -236,8 +236,7 @@ int main(void) {
}
\end{verbatim}
The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and
``ltc\_tommath.h'' (the bignum library routines).
The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'' and ``ctype.h''.
\section{Macros}
@ -363,16 +362,17 @@ done with a key you can simply discard it (e.g. they can be on the stack).
To encrypt or decrypt a block in ECB mode there are these two function classes
\index{Cipher Encrypt} \index{Cipher Decrypt}
\begin{verbatim}
void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
int XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
symmetric_key *skey);
void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
int XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
symmetric_key *skey);
\end{verbatim}
These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
which cipher you are using.} and store the result where you want it. It is possible that the input and output buffer are
the same buffer. For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and
``ct''\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. To test a particular
``ct''\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. They both
return \textbf{CRYPT\_OK} on success. To test a particular
cipher against test vectors\footnote{As published in their design papers.} call the self-test function
\subsection{Self--Testing}
@ -496,39 +496,47 @@ struct _cipher_descriptor {
block_length,
default_rounds;
int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int (*test)(void);
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int (*test)(void);
void (*done)(symmetric_key *skey);
int (*keysize)(int *keysize);
void (*accel_ecb_encrypt)(const unsigned char *pt,
int (*accel_ecb_encrypt)(const unsigned char *pt,
unsigned char *ct,
unsigned long blocks, symmetric_key *skey);
void (*accel_ecb_decrypt)(const unsigned char *ct,
int (*accel_ecb_decrypt)(const unsigned char *ct,
unsigned char *pt,
unsigned long blocks, symmetric_key *skey);
void (*accel_cbc_encrypt)(const unsigned char *pt,
int (*accel_cbc_encrypt)(const unsigned char *pt,
unsigned char *ct,
unsigned long blocks, unsigned char *IV,
symmetric_key *skey);
void (*accel_cbc_decrypt)(const unsigned char *ct,
int (*accel_cbc_decrypt)(const unsigned char *ct,
unsigned char *pt,
unsigned long blocks, unsigned char *IV,
symmetric_key *skey);
void (*accel_ctr_encrypt)(const unsigned char *pt,
int (*accel_ctr_encrypt)(const unsigned char *pt,
unsigned char *ct,
unsigned long blocks, unsigned char *IV,
int mode, symmetric_key *skey);
void (*accel_ccm_memory)(
int (*accel_ccm_memory)(
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
int (*accel_gcm_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
};
\end{verbatim}
\end{small}
@ -1200,6 +1208,7 @@ function that performs the protocol.
\begin{verbatim}
int ccm_memory(int cipher,
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
@ -1209,9 +1218,15 @@ int ccm_memory(int cipher,
\end{verbatim}
This performs the ``CCM'' operation on the data. The ``cipher'' variable indicates which cipher in the descriptor table to use. It must have a
16--byte block size for CCM. The key is ``key'' with a length of ``keylen'' octets. The nonce or salt is ``nonce'' of
length ``noncelen'' octets. The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header''
of length ``headerlen'' octets. The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}).
16--byte block size for CCM.
The key can be specified in one of two fashions. First it can be passed as an array of octets in ``key'' of length ``keylen''. Alternatively,
it can be passed in as a previously scheduled key in ``uskey''. The latter fashion saves time when the same key is used for multiple packets. If
``uskey'' is not \textbf{NULL} then ``key'' may be \textbf{NULL} (and vice-versa).
The nonce or salt is ``nonce'' of length ``noncelen'' octets. The header is meta--data you want to send with the message but not have
encrypted, it is stored in ``header'' of length ``headerlen'' octets. The header can be zero octets long (if $headerlen = 0$ then
you can pass ``header'' as \textbf{NULL}).
The plaintext is stored in ``pt'' and the ciphertext in ``ct''. The length of both are expected to be equal and is passed in as ``ptlen''. It is
allowable that $pt = ct$. The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or
@ -2902,28 +2917,39 @@ int ecc_shared_secret(ecc_key *private_key,
The ``private\_key'' is your own key and ``public\_key'' is the key the other user sent you. Note that this function stores only the
$x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH.
\section{ECC Packet}
\section{ECC Diffie-Hellman Encryption}
Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key
algorithms.
\index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()}
\index{ecc\_encrypt\_key()}
\begin{verbatim}
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
ecc_key *key);
\end{verbatim}
Where ``in'' is an input symmetric key of no more than 64 bytes. This function creates a random public key
and computes the hash of the shared secret. The message digest is then XOR'ed against the symmetric key. All of the required
data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large
as the symmetric key you are trying to share.
The data is encrypted to the public ECC ``key'' such that only the holder of the private key can decrypt the payload. If you want
to have multiple recipients you will have to call this function for each public ECC key you want to encrypt to.
\index{ecc\_decrypt\_key()}
\begin{verbatim}
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ecc_key *key);
\end{verbatim}
Where ``in'' is an input symmetric key of no more than 64 bytes. Essentially these routines created a random public key
and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the required
data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large
as the symmetric key you are trying to share.
This function will decrypt an encrypted payload. The ``key'' provided must be the private key corresponding to the public key
used during encryption. If the wrong key is provided the function won't specifically return an error code. It is important
to use some form of challenge response in that case (e.g. compute a MAC of a known string).
\subsection{Encrypt Packet Format}
\subsection{Encrypt Encryption Format}
The packet format for the encrypted keys is the following ASN.1 SEQUENCE:
@ -2935,30 +2961,40 @@ ECCEncrypt ::= SEQUENCE {
}
\end{verbatim}
\section{ECC DSA Signatures}
There are also functions to sign and verify the hash of a message.
\index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()}
\index{ecc\_sign\_hash()}
\begin{verbatim}
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, ecc_key *key);
\end{verbatim}
This function will EC--DSA sign the message digest stored in the buffer ``in'' of length inlen octets. The signature
will be stored in the ``out'' buffer of length ``outlen''. The function requires a properly seeded PRNG and
the ECC ``key'' provided must be a private key.
\index{ecc\_verify\_hash()}
\begin{verbatim}
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, ecc_key *key);
\end{verbatim}
The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.
The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''. It sets ``stat''
to non-zero if the signature passes or zero if it fails.
This function will verify the EC-DSA signature in ``sig'' of length ``siglen'' against the message digest ``hash''.
It will store a non--zero value in ``stat'' if the signature is valid. Note that the function will not return
an error if the signature is invalid. It will if the actual signature payload is an invalid format. They ECC ``key''
must be the public (or private) ECC key corresponding to the key that performed the signature.
\subsection{Signature Format}
The signature code is an implementation of X9.62 EC-DSA and the output is comformant for GF(p) curves.
The signature code is an implementation of X9.62 EC--DSA and the output is comformant for GF(p) curves.
\section{ECC Keysizes}
With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems. The math will still work
and in effect the signature will still work. With ECC keys the strength of the signature is limited by the size of
the hash or the size of they key, whichever is smaller. For example, if you sign with SHA256 and an ECC-192 key in effect
you have 192-bits of security.
you have 96-bits of security.
The library will not warn you if you make this mistake so it is important to check yourself before using the
signatures.
@ -3077,6 +3113,7 @@ This will test ``key'' and store the result in ``stat''. If the result is $stat
and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned).
\section{Signatures}
\subsection{Signature Generation}
To generate a DSA signature call the following function
\index{dsa\_sign\_hash()}
@ -3090,6 +3127,7 @@ Which will sign the data in ``in'' of length ``inlen'' bytes. The signature is
of the signature in ``outlen''. If the signature is longer than the size you initially specify in ``outlen'' nothing
is stored and the function returns an error code. The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion.
\subsection{Signature Verification}
To verify a hash created with that function use the following function
\index{dsa\_verify\_hash()}
@ -3101,6 +3139,35 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''.
It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$.
\section{DSA Encrypt and Decrypt}
As of version 1.07 the DSA keys can be used to encrypt and decrypt small payloads. It works similar to the ECC encryption where
a shared key is computed and the hash of the shared key xor'ed against the plaintext forms the ciphertext.
\subsection{DSA Encryption}
This function will encrypt a small payload with a recipients public DSA key.
\index{dsa\_encrypt\_key()}
\begin{verbatim}
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
dsa_key *key);
\end{verbatim}
This will encrypt the payload in ``in'' of length ``inlen'' and store the ciphertext in the output buffer ``out''. The
length of the ciphertext ``outlen'' must be originally set to the length of the output buffer. The DSA ``key'' can be
a public key.
\subsection{DSA Decryption}
\index{dsa\_decrypt\_key()}
\begin{verbatim}
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
dsa_key *key);
\end{verbatim}
This will decrypt the ciphertext ``in'' of length ``inlen'' and store the original payload in ``out'' of length ``outlen''. The DSA ``key'' must be a private key.
\section{Import and Export}
To export a DSA key so that it can be transported use the following function
@ -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}
\begin{verbatim}
typedef struct {
int type;
void *data;
unsigned long size;
int used;
int type;
void *data;
unsigned long size;
int used;
struct ltc_asn1_list_ *prev, *next,
*child, *parent;
} ltc_asn1_list;
\end{verbatim}
\index{LTC\_SET\_ASN1 macro}
The ``type'' field is one of the following ASN.1 field definitions. The ``data'' pointer is a void pointer to the data to be encoded (or the destination) and the
``size'' field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type). The ``used'' field is primarily for the CHOICE decoder
and reflects if the particular member of a list was the decoded data type. To help build the lists in an orderly fashion the macro
@ -3468,6 +3538,45 @@ This will decode the input in the ``in'' field of length ``inlen''. It uses the
The ``inlen'' field will be updated with the length of the decoded data type as well as the respective entry in the ``list'' field will have the ``used'' flag
set to non--zero to reflect it was the data type decoded.
\subsection{ASN.1 Flexi Decoder}
The ASN.1 ``flexi'' decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing
the structure of the data. Where der\_decode\_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely
free form.
The flexi decoder uses the same ``ltc\_asn1\_list'' but instead of being stored in an array it uses the linked list pointers ``prev'', ``next'', ``parent''
and ``child''. The list works as a ``doubly-linked list'' structure where decoded items at the same level are sibblings (using next and prev) and items
encoded in a SEQUENCE are stored as a child element.
When a SEQUENCE has been encountered a SEQUENCE item is added as a sibbling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child pointer points to a new list
of items contained within the sequence\footnote{The same will be true for the SET data type when I eventually support it.}.
\index{der\_decode\_sequence\_flexi()}
\begin{verbatim}
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list **out);
\end{verbatim}
This will decode items in the ``in'' buffer of max input length ``inlen'' and store the newly created pointer to the list in ``out''. This function allocates
all required memory for the decoding. It stores the number of octets read back into ``inlen''.
The function will terminate when either it hits an invalid ASN.1 type octet or it reads ``inlen'' octets. An early terminate is a soft error and returns
normally. The decoded list ``out'' will point to the very first element of the list (e.g. both parent and prev pointers will be \textbf{NULL}).
An invalid decoding will terminate the process and free the allocated memory automatically.
\textbf{Note} that the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly. You will have to first
have to convert the list by first storing all of the sibblings in an array then storing all the children as sub-lists of a sequence using the ``.data''
pointer. Currently no function in LibTomCrypt provides this ability.
To free the list use the following function.
\index{der\_sequence\_free()}
\begin{verbatim}
void der_sequence_free(ltc_asn1_list *in);
\end{verbatim}
This will free all of the memory allocated by der\_decode\_sequence\_flexi().
\section{Password Based Cryptography}
\subsection{PKCS \#5}
\index{PKCS \#5}
@ -3729,6 +3838,26 @@ libraries. One for LibTomMath and one for TomsFastMath.
All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process. Most of the
settings can be overwritten from the command line which makes custom installation a breeze.
\index{MAKE}
\index{CC}
\index{AR}
\subsection{MAKE, CC and AR}
The MAKE, CC and AR flags can all be overwritten. They default to ``make'', ``\$CC'' and ``\$AR'' respectively.
Changing MAKE allows you to change what program will be invoked to handle sub--directories. E.g.
\begin{verbatim}
MAKE=gmake gmake install
\end{verbatim}
Will build and install the libraries with the ``gmake'' tool. Similarly
\begin{verbatim}
CC=arm-gcc AR=arm-ar make
\end{verbatim}
Will build the library using ``arm--gcc'' as the compiler and ``arm--ar'' as the archiver.
\subsection{IGNORE\_SPEED}
\index{IGNORE\_SPEED}
When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new
@ -3758,7 +3887,8 @@ directory which defaults to ``/usr/lib''. \textbf{INCPATH} is the prefix for th
All four can be used to create custom install locations depending on the nature of the OS and file system in use.
\begin{verbatim}
make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include DATAPATH=/home/tom/project/docs install
make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include \
DATAPATH=/home/tom/project/docs install
\end{verbatim}
This will build the library and install it to the directories under ``/home/tom/project/''. e.g.
@ -3848,13 +3978,11 @@ LibTomCrypt can also be built as a shared library through the ``makefile.shared'
that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time.
\begin{verbatim}
CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared
CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install
\end{verbatim}
This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well).
Note that unlike the static build there is no ``install'' target. The default action of this make script is to install the library.
The shared build process requires libtool to be installed.
This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well). The
shared build process requires libtool to be installed.
\section{tomcrypt\_cfg.h}
The file ``tomcrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour
@ -4025,26 +4153,31 @@ struct ltc_cipher_descriptor {
@param skey [out] The destination of the scheduled key
@return CRYPT_OK if successful
*/
int (*setup)(const unsigned char *key, int keylen,
int num_rounds, symmetric_key *skey);
int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
/** Encrypt a block
@param pt The plaintext
@param ct [out] The ciphertext
@param skey The scheduled key
@return CRYPT_OK if successful
*/
void (*ecb_encrypt)(const unsigned char *pt,
unsigned char *ct, symmetric_key *skey);
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
/** Decrypt a block
@param ct The ciphertext
@param pt [out] The plaintext
@param skey The scheduled key
@return CRYPT_OK if successful
*/
void (*ecb_decrypt)(const unsigned char *ct,
unsigned char *pt, symmetric_key *skey);
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
/** Test the block cipher
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
int (*test)(void);
/** Terminate the context
@param skey The scheduled key
*/
void (*done)(symmetric_key *skey);
/** Determine a key size
@param keysize [in/out] The size of the key desired and the suggested size
@return CRYPT_OK if successful
@ -4057,20 +4190,20 @@ struct ltc_cipher_descriptor {
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_ecb_encrypt)(const unsigned char *pt,
unsigned char *ct, unsigned long blocks,
symmetric_key *skey);
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct,
unsigned long blocks, symmetric_key *skey);
/** Accelerated ECB decryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_ecb_decrypt)(const unsigned char *ct,
unsigned char *pt, unsigned long blocks,
symmetric_key *skey);
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt,
unsigned long blocks, symmetric_key *skey);
/** Accelerated CBC encryption
@param pt Plaintext
@ -4078,10 +4211,11 @@ struct ltc_cipher_descriptor {
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_cbc_encrypt)(const unsigned char *pt,
unsigned char *ct, unsigned long blocks,
unsigned char *IV, symmetric_key *skey);
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct,
unsigned long blocks, unsigned char *IV,
symmetric_key *skey);
/** Accelerated CBC decryption
@param pt Plaintext
@ -4089,10 +4223,11 @@ struct ltc_cipher_descriptor {
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_cbc_decrypt)(const unsigned char *ct,
unsigned char *pt, unsigned long blocks,
unsigned char *IV, symmetric_key *skey);
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt,
unsigned long blocks, unsigned char *IV,
symmetric_key *skey);
/** Accelerated CTR encryption
@param pt Plaintext
@ -4101,14 +4236,16 @@ struct ltc_cipher_descriptor {
@param IV The initial value (input/output)
@param mode little or big endian counter (mode=0 or mode=1)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_ctr_encrypt)(const unsigned char *pt,
unsigned char *ct, unsigned long blocks,
unsigned char *IV, int mode, symmetric_key *skey);
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct,
unsigned long blocks, unsigned char *IV,
int mode, symmetric_key *skey);
/** Accelerated CCM packet (one-shot)
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param uskey A previously scheduled key [optional can be NULL]
@param nonce The session nonce [use once]
@param noncelen The length of the nonce
@param header The header for the session
@ -4121,8 +4258,9 @@ struct ltc_cipher_descriptor {
@param direction Encrypt or Decrypt direction (0 or 1)
@return CRYPT_OK if successful
*/
void (*accel_ccm_memory)(
int (*accel_ccm_memory)(
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
@ -4143,8 +4281,9 @@ struct ltc_cipher_descriptor {
@param tag [out] The MAC tag
@param taglen [in/out] The MAC tag length
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
@return CRYPT_OK on success
*/
void (*accel_gcm_memory)(
int (*accel_gcm_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
@ -4152,7 +4291,6 @@ struct ltc_cipher_descriptor {
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction);
};
\end{verbatim}
\end{small}
@ -4231,8 +4369,22 @@ buffer provided) before encrypting it to create the pad.
The accelerator will only be used to encrypt whole blocks. Partial blocks are always handled in software.
\subsubsection{Accelerated CCM}
This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not
be called prior to this. This function must handle scheduling the key provided on its own.
This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. You can optimize the work flow somewhat
by allowing the caller to call the setup() function first to schedule the key if your accelerator cannot do the key schedule on the fly (for instance). This
function MUST support both key passing methods.
\begin{center}
\begin{small}
\begin{tabular}{|r|r|l|}
\hline \textbf{key} & \textbf{uskey} & \textbf{Source of key} \\
\hline NULL & NULL & Error, not supported \\
\hline non-NULL & NULL & Use key, do a key schedule \\
\hline NULL & non-NULL & Use uskey, key schedule not required \\
\hline non-NULL & non-NULL & Use uskey, key schedule not required \\
\hline
\end{tabular}
\end{small}
\end{center}
\subsubsection{Accelerated GCM}
This function is meant for accelerated GCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not
@ -4560,7 +4712,6 @@ typedef struct {
*/
int (*add)(void *a, void *b, void *c);
/** add two integers
@param a The first source integer
@param b The second source integer (single digit of upto bits_per_digit in length)
@ -4748,6 +4899,16 @@ typedef struct {
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
/** RSA Key Generation
@param prng An active PRNG state
@param wprng The index of the PRNG desired
@param size The size of the modulus (key size) desired (octets)
@param e The "e" value (public key). e==65537 is a good choice
@param key [out] Destination of a newly created private key pair
@return CRYPT_OK if successful, upon error all allocated ram is freed
*/
int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
/** RSA exponentiation
@param in The octet array representing the base
@param inlen The length of the input
@ -4851,5 +5012,5 @@ Since the function is given the entire RSA key (for private keys only) CRT is po
\end{document}
% $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $
% $Revision: 1.45 $
% $Date: 2005/08/01 16:59:29 $
% $Revision: 1.55 $
% $Date: 2005/11/18 01:45:03 $

View File

@ -170,7 +170,7 @@ int main(int argc, char *argv[])
exit(-1);
}
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
printf("ctr_start error: %s\n",error_to_string(errno));
exit(-1);
}
@ -212,7 +212,7 @@ int main(int argc, char *argv[])
exit(-1);
}
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
printf("ctr_start error: %s\n",error_to_string(errno));
exit(-1);
}

View File

@ -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("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nrsa_test......"); fflush(stdout); x = rsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\ndsa_test......"); fflush(stdout); x = dsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\nkatja_test...."); fflush(stdout); x = katja_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
printf("\n");
return EXIT_SUCCESS;
}

View File

@ -14,7 +14,6 @@ reg_algs();
extern ltc_math_descriptor EXT_MATH_LIB;
ltc_mp = EXT_MATH_LIB;
#endif
time_keysched();
time_cipher();
time_cipher2();
@ -27,6 +26,9 @@ time_mult();
time_sqr();
time_rsa();
time_ecc();
#ifdef USE_LTM
time_katja();
#endif
return EXIT_SUCCESS;
}

View File

@ -551,7 +551,7 @@ void ccm_gen(void)
plaintext[z] = (unsigned char)(z & 255);
}
len = sizeof(tag);
if ((err = ccm_memory(x, key, kl, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
if ((err = ccm_memory(x, key, kl, NULL, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
printf("Error CCM'ing: %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
@ -682,7 +682,7 @@ void ecc_gen(void)
mp_set(G->z, 1);
while (mp_cmp(k, order) == LTC_MP_LT) {
ltc_ecc_mulmod(k, G, R, modulus, 1);
ltc_mp.ecc_ptmul(k, G, R, modulus, 1);
mp_tohex(k, str); fprintf(out, "%s, ", str);
mp_tohex(R->x, str); fprintf(out, "%s, ", str);
mp_tohex(R->y, str); fprintf(out, "%s\n", str);

Binary file not shown.

View File

@ -4,7 +4,7 @@
# Modified by Clay Culver
# The version
VERSION=1.06
VERSION=1.07
# Compiler and Linker Names
#CC=gcc
@ -14,12 +14,23 @@ VERSION=1.06
#AR=ar
#ARFLAGS=r
ifndef MAKE
MAKE=make
endif
# ranlib tools
ifndef RANLIB
RANLIB=ranlib
endif
# Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter -DLTC_SOURCE
# additional warnings (newer GCC 3.4 and higher)
#CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
# -Wmissing-declarations -Wpointer-arith
ifdef GCC_34
CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
-Wmissing-declarations -Wpointer-arith
endif
ifndef IGNORE_SPEED
@ -47,8 +58,8 @@ ifndef LIBNAME
endif
ifndef LIBTEST
LIBTEST=libtomcrypt_prof.a
LIBTEST_S=$(LIBTEST)
endif
LIBTEST_S=$(LIBTEST)
HASH=hashsum
CRYPT=encrypt
@ -154,22 +165,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
src/pk/asn1/der/printable_string/der_length_printable_string.o \
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \
src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \
src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
src/prngs/sprng.o src/prngs/yarrow.o
src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@ -203,8 +223,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
@ -212,11 +230,11 @@ src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
library: $(LIBNAME)
testprof/$(LIBTEST):
cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) make
cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE)
$(LIBNAME): $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS)
ranlib $(LIBNAME)
$(RANLIB) $@
#This rule makes the hash program included with libtomcrypt
hashsum: library $(HASHOBJECTS)
@ -242,28 +260,33 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
test: library testprof/$(LIBTEST) $(TESTS)
$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST)
#This rule installs the library and the header files. This must be run
#as root in order to have a high enough permission to write to the correct
#directories and to set the owner and group to root.
ifndef NODOCS
install: library docs
else
install: library
endif
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
ifndef NODOCS
install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH)
endif
install_test: $(LIBTEST)
install_test: testprof/$(LIBTEST)
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH)
install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH)
profile:
CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov
CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
./timing
rm -f timing `find . -type f | grep [.][ao] | xargs`
CFLAGS="$(CFLAGS) -fprofile-use" make timing EXTRALIBS=-lgcov
CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
#This rule cleans the source tree of all compiled code, not including the pdf
@ -291,7 +314,7 @@ clean:
#build the doxy files (requires Doxygen, tetex and patience)
doxy:
doxygen
cd doc/doxygen/latex ; make ; mv -f refman.pdf ../../.
cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../.
echo The huge doxygen PDF should be available as doc/refman.pdf
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
@ -333,6 +356,5 @@ zipup: no_oops docs
# $Source: /cvs/libtom/libtomcrypt/makefile,v $
# $Revision: 1.86 $
# $Date: 2005/07/30 04:54:20 $
# $Revision: 1.103 $
# $Date: 2005/11/18 01:46:22 $

View File

@ -152,22 +152,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
src/pk/asn1/der/printable_string/der_length_printable_string.o \
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \
src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \
src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
src/prngs/sprng.o src/prngs/yarrow.o
src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@ -207,8 +216,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
@ -254,5 +261,5 @@ install: library
install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
# $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $
# $Revision: 1.39 $
# $Date: 2005/07/30 23:38:39 $
# $Revision: 1.44 $
# $Date: 2005/11/18 01:46:22 $

View File

@ -1,7 +1,7 @@
#MSVC Makefile [tested with MSVC 6.00 with SP5]
#
#Tom St Denis
CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@
CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF)
OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
@ -67,22 +67,31 @@ src/pk/asn1/der/octet/der_length_octet_string.obj \
src/pk/asn1/der/printable_string/der_decode_printable_string.obj \
src/pk/asn1/der/printable_string/der_encode_printable_string.obj \
src/pk/asn1/der/printable_string/der_length_printable_string.obj \
src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \
src/pk/asn1/der/sequence/der_encode_sequence.obj src/pk/asn1/der/sequence/der_encode_sequence_multi.obj \
src/pk/asn1/der/sequence/der_length_sequence.obj \
src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \
src/pk/asn1/der/sequence/der_decode_sequence_multi.obj src/pk/asn1/der/sequence/der_encode_sequence.obj \
src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \
src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj \
src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \
src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_shared_secret.obj \
src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj \
src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \
src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \
src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \
src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \
src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \
src/prngs/sprng.obj src/prngs/yarrow.obj
src/pk/ecc/ecc_decrypt_key.obj src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_free.obj \
src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.obj \
src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj \
src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ltc_ecc_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj \
src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \
src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \
src/pk/katja/katja_decrypt_key.obj src/pk/katja/katja_encrypt_key.obj src/pk/katja/katja_export.obj \
src/pk/katja/katja_exptmod.obj src/pk/katja/katja_free.obj src/pk/katja/katja_import.obj \
src/pk/katja/katja_make_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \
src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \
src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj \
src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj \
src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj \
src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \
src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@ -115,5 +124,6 @@ timing: demos/timing.c library
cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
# $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $
# $Revision: 1.17 $
# $Date: 2005/07/30 23:42:57 $
# $Revision: 1.24 $
# $Date: 2005/11/18 01:46:22 $

View File

@ -6,10 +6,15 @@
# Tom St Denis
# The version
VERSION=0:106
VERSION=0:107
# 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!
CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE
@ -39,8 +44,10 @@ endif
#CFLAGS += -DLTC_NO_ROLC
#Output filenames for various targets.
ifndef LIBTEST
ifndef LIBTEST_S
LIBTEST_S=libtomcrypt_prof.a
endif
ifndef LIBTEST
LIBTEST=libtomcrypt_prof.la
endif
ifndef LIBNAME
@ -152,22 +159,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
src/pk/asn1/der/printable_string/der_length_printable_string.o \
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \
src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \
src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
src/prngs/sprng.o src/prngs/yarrow.o
src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
@ -194,8 +210,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
@ -205,10 +219,13 @@ library: $(LIBNAME)
testprof/$(LIBTEST):
cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared
$(LIBNAME): $(OBJECTS)
objs: $(OBJECTS)
$(LIBNAME): $(OBJECTS) testprof/$(LIBTEST)
libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION)
libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME_S)
ranlib $(LIBNAME_S)
install: $(LIBNAME)
cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared install
libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
@ -233,5 +250,6 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
# $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $
# $Revision: 1.25 $
# $Date: 2005/07/30 04:54:20 $
# $Revision: 1.36 $
# $Date: 2005/11/18 01:46:22 $

View File

@ -281,11 +281,12 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@ -440,13 +441,16 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
(Te4_0[byte(t2, 0)]) ^
rk[3];
STORE32H(s3, ct+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_rijndael_ecb_encrypt(pt, ct, skey);
int err = _rijndael_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
@ -457,11 +461,12 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@ -615,14 +620,17 @@ void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
(Td4[byte(t0, 0)] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_rijndael_ecb_decrypt(ct, pt, skey);
int err = _rijndael_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif

View File

@ -1134,13 +1134,15 @@ static void anubis_crypt(const unsigned char *plaintext, unsigned char *cipherte
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
return CRYPT_OK;
}
/**
@ -1148,13 +1150,15 @@ void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);
return CRYPT_OK;
}
/**

View File

@ -385,11 +385,12 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 L, R;
@ -428,13 +429,16 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
/* store */
STORE32H(R, &ct[0]);
STORE32H(L, &ct[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_blowfish_ecb_encrypt(pt, ct, skey);
int err = _blowfish_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif
@ -443,11 +447,12 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 L, R;
@ -486,13 +491,15 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
/* store */
STORE32H(L, &pt[0]);
STORE32H(R, &pt[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_blowfish_ecb_decrypt(ct, pt, skey);
int err = _blowfish_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif

View File

@ -536,9 +536,9 @@ INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 R, L;
@ -569,14 +569,16 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
}
STORE32H(R,&ct[0]);
STORE32H(L,&ct[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_cast5_ecb_encrypt(pt,ct,skey);
int err =_cast5_ecb_encrypt(pt,ct,skey);
burn_stack(sizeof(ulong32)*3);
return err;
}
#endif
@ -587,9 +589,9 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 R, L;
@ -620,13 +622,16 @@ void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
STORE32H(L,&pt[0]);
STORE32H(R,&pt[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_cast5_ecb_decrypt(ct,pt,skey);
int err = _cast5_ecb_decrypt(ct,pt,skey);
burn_stack(sizeof(ulong32)*3);
return err;
}
#endif

View File

@ -1582,8 +1582,9 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong32 work[2];
LTC_ARGCHK(pt != NULL);
@ -1594,6 +1595,7 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
desfunc(work, skey->des.ek);
STORE32H(work[0],ct+0);
STORE32H(work[1],ct+4);
return CRYPT_OK;
}
/**
@ -1601,8 +1603,9 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong32 work[2];
LTC_ARGCHK(pt != NULL);
@ -1612,7 +1615,8 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
LOAD32H(work[1], ct+4);
desfunc(work, skey->des.dk);
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 ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong32 work[2];
@ -1635,6 +1640,7 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
desfunc(work, skey->des3.ek[2]);
STORE32H(work[0],ct+0);
STORE32H(work[1],ct+4);
return CRYPT_OK;
}
/**
@ -1642,8 +1648,9 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong32 work[2];
LTC_ARGCHK(pt != NULL);
@ -1656,6 +1663,7 @@ void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
desfunc(work, skey->des3.dk[2]);
STORE32H(work[0],pt+0);
STORE32H(work[1],pt+4);
return CRYPT_OK;
}
/**

View File

@ -741,13 +741,15 @@ static void khazad_crypt(const unsigned char *plaintext, unsigned char *cipherte
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
return CRYPT_OK;
}
/**
@ -755,13 +757,15 @@ void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
return CRYPT_OK;
}
/**

View File

@ -107,11 +107,12 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,temp;
@ -142,13 +143,16 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_noekeon_ecb_encrypt(pt, ct, skey);
int err = _noekeon_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
return CRYPT_OK;
}
#endif
@ -157,11 +161,12 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d, temp;
@ -192,13 +197,15 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
a ^= RC[0];
STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_noekeon_ecb_decrypt(ct, pt, skey);
int err = _noekeon_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
return err;
}
#endif

View File

@ -125,13 +125,14 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _rc2_ecb_encrypt( const unsigned char *pt,
static int _rc2_ecb_encrypt( const unsigned char *pt,
unsigned char *ct,
symmetric_key *skey)
#else
void rc2_ecb_encrypt( const unsigned char *pt,
int rc2_ecb_encrypt( const unsigned char *pt,
unsigned char *ct,
symmetric_key *skey)
#endif
@ -179,15 +180,18 @@ void rc2_ecb_encrypt( const unsigned char *pt,
ct[5] = (unsigned char)(x54 >> 8);
ct[6] = (unsigned char)x76;
ct[7] = (unsigned char)(x76 >> 8);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void rc2_ecb_encrypt( const unsigned char *pt,
int rc2_ecb_encrypt( const unsigned char *pt,
unsigned char *ct,
symmetric_key *skey)
{
_rc2_ecb_encrypt(pt, ct, skey);
int err = _rc2_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
return err;
}
#endif
@ -199,13 +203,14 @@ void rc2_ecb_encrypt( const unsigned char *pt,
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _rc2_ecb_decrypt( const unsigned char *ct,
static int _rc2_ecb_decrypt( const unsigned char *ct,
unsigned char *pt,
symmetric_key *skey)
#else
void rc2_ecb_decrypt( const unsigned char *ct,
int rc2_ecb_decrypt( const unsigned char *ct,
unsigned char *pt,
symmetric_key *skey)
#endif
@ -254,15 +259,18 @@ void rc2_ecb_decrypt( const unsigned char *ct,
pt[5] = (unsigned char)(x54 >> 8);
pt[6] = (unsigned char)x76;
pt[7] = (unsigned char)(x76 >> 8);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void rc2_ecb_decrypt( const unsigned char *ct,
int rc2_ecb_decrypt( const unsigned char *ct,
unsigned char *pt,
symmetric_key *skey)
{
_rc2_ecb_decrypt(ct, pt, skey);
int err = _rc2_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
return err;
}
#endif

View File

@ -123,11 +123,12 @@ int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 A, B, *K;
@ -159,13 +160,16 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
}
STORE32L(A, &ct[0]);
STORE32L(B, &ct[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_rc5_ecb_encrypt(pt, ct, skey);
int err = _rc5_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif
@ -174,11 +178,12 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 A, B, *K;
@ -211,13 +216,16 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
B -= skey->rc5.K[1];
STORE32L(A, &pt[0]);
STORE32L(B, &pt[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_rc5_ecb_decrypt(ct, pt, skey);
int err = _rc5_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif

View File

@ -120,9 +120,9 @@ int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,t,u, *K;
@ -155,13 +155,15 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
a += skey->rc6.K[42];
c += skey->rc6.K[43];
STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_rc6_ecb_encrypt(pt, ct, skey);
int err = _rc6_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 6 + sizeof(int));
return err;
}
#endif
@ -172,9 +174,9 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,t,u, *K;
@ -208,13 +210,16 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
b -= skey->rc6.K[0];
d -= skey->rc6.K[1];
STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_rc6_ecb_decrypt(ct, pt, skey);
int err = _rc6_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 6 + sizeof(int));
return err;
}
#endif

View File

@ -246,11 +246,11 @@ int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symme
}
#ifdef LTC_CLEAN_STACK
static void _safer_ecb_encrypt(const unsigned char *block_in,
static int _safer_ecb_encrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#else
void safer_ecb_encrypt(const unsigned char *block_in,
int safer_ecb_encrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#endif
@ -285,24 +285,26 @@ void safer_ecb_encrypt(const unsigned char *block_in,
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void safer_ecb_encrypt(const unsigned char *block_in,
int safer_ecb_encrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
{
_safer_ecb_encrypt(block_in, block_out, skey);
int err = _safer_ecb_encrypt(block_in, block_out, skey);
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
return err;
}
#endif
#ifdef LTC_CLEAN_STACK
static void _safer_ecb_decrypt(const unsigned char *block_in,
static int _safer_ecb_decrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#else
void safer_ecb_decrypt(const unsigned char *block_in,
int safer_ecb_decrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#endif
@ -338,15 +340,17 @@ void safer_ecb_decrypt(const unsigned char *block_in,
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void safer_ecb_decrypt(const unsigned char *block_in,
int safer_ecb_decrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
{
_safer_ecb_decrypt(block_in, block_out, skey);
int err = _safer_ecb_decrypt(block_in, block_out, skey);
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
return err;
}
#endif

View File

@ -329,8 +329,9 @@ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
unsigned char b[16];
int x;
@ -384,6 +385,7 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
#ifdef LTC_CLEAN_STACK
zeromem(b, sizeof(b));
#endif
return CRYPT_OK;
}
/**
@ -391,8 +393,9 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
unsigned char b[16];
int x;
@ -446,6 +449,7 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
#ifdef LTC_CLEAN_STACK
zeromem(b, sizeof(b));
#endif
return CRYPT_OK;
}
/**

View File

@ -138,11 +138,12 @@ static unsigned ig_func(unsigned w, int *kp, unsigned char *key)
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
unsigned w1,w2,w3,w4,tmp,tmp1;
@ -183,13 +184,16 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
ct[2] = (w2>>8)&255; ct[3] = w2&255;
ct[4] = (w3>>8)&255; ct[5] = w3&255;
ct[6] = (w4>>8)&255; ct[7] = w4&255;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_skipjack_ecb_encrypt(pt, ct, skey);
int err = _skipjack_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
return err;
}
#endif
@ -198,11 +202,12 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
unsigned w1,w2,w3,w4,tmp;
@ -247,13 +252,16 @@ void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
pt[2] = (w2>>8)&255; pt[3] = w2&255;
pt[4] = (w3>>8)&255; pt[5] = w3&255;
pt[6] = (w4>>8)&255; pt[7] = w4&255;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_skipjack_ecb_decrypt(ct, pt, skey);
int err = _skipjack_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
return err;
}
#endif

View File

@ -465,11 +465,12 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
@ -519,13 +520,16 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
/* store output */
STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_twofish_ecb_encrypt(pt, ct, skey);
int err = _twofish_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 10 + sizeof(int));
return err;
}
#endif
@ -534,11 +538,12 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
@ -591,13 +596,15 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
/* store */
STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_twofish_ecb_decrypt(ct, pt, skey);
int err =_twofish_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 10 + sizeof(int));
return err;
}
#endif

View File

@ -71,8 +71,9 @@ int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
unsigned long y, z;
int r;
@ -98,6 +99,7 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
}
STORE32L(y, &ct[0]);
STORE32L(z, &ct[4]);
return CRYPT_OK;
}
/**
@ -105,8 +107,9 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
unsigned long y, z;
int r;
@ -132,6 +135,7 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
}
STORE32L(y, &pt[0]);
STORE32L(z, &pt[4]);
return CRYPT_OK;
}
/**

View File

@ -22,6 +22,7 @@
@param cipher The index of the cipher desired
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param uskey A previously scheduled key [optional can be NULL]
@param nonce The session nonce [use once]
@param noncelen The length of the nonce
@param header The header for the session
@ -36,6 +37,7 @@
*/
int ccm_memory(int cipher,
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
@ -48,7 +50,9 @@ int ccm_memory(int cipher,
int err;
unsigned long len, L, x, y, z, CTRlen;
LTC_ARGCHK(key != NULL);
if (uskey == NULL) {
LTC_ARGCHK(key != NULL);
}
LTC_ARGCHK(nonce != NULL);
if (headerlen > 0) {
LTC_ARGCHK(header != NULL);
@ -85,15 +89,15 @@ int ccm_memory(int cipher,
/* is there an accelerator? */
if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
cipher_descriptor[cipher].accel_ccm_memory(
return cipher_descriptor[cipher].accel_ccm_memory(
key, keylen,
uskey,
nonce, noncelen,
header, headerlen,
pt, ptlen,
ct,
tag, taglen,
direction);
return CRYPT_OK;
}
/* let's get the L value */
@ -114,15 +118,19 @@ int ccm_memory(int cipher,
}
/* allocate mem for the symmetric key */
skey = XMALLOC(sizeof(*skey));
if (skey == NULL) {
return CRYPT_MEM;
}
if (uskey == NULL) {
skey = XMALLOC(sizeof(*skey));
if (skey == NULL) {
return CRYPT_MEM;
}
/* initialize the cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
XFREE(skey);
return err;
/* initialize the cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
XFREE(skey);
return err;
}
} else {
skey = uskey;
}
/* form B_0 == flags | Nonce N | l(m) */
@ -154,7 +162,9 @@ int ccm_memory(int cipher,
}
/* encrypt PAD */
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
/* handle header */
if (headerlen > 0) {
@ -177,7 +187,9 @@ int ccm_memory(int cipher,
for (y = 0; y < headerlen; y++) {
if (x == 16) {
/* full block so let's encrypt it */
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
x = 0;
}
PAD[x++] ^= header[y];
@ -185,7 +197,9 @@ int ccm_memory(int cipher,
/* remainder? */
if (x != 0) {
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
}
@ -219,14 +233,18 @@ int ccm_memory(int cipher,
ctr[z] = (ctr[z] + 1) & 255;
if (ctr[z]) break;
}
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
/* xor the PT against the pad first */
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
*((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
}
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
} else {
for (; y < (ptlen & ~15); y += 16) {
@ -235,14 +253,18 @@ int ccm_memory(int cipher,
ctr[z] = (ctr[z] + 1) & 255;
if (ctr[z]) break;
}
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
/* xor the PT against the pad last */
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
*((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
}
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
}
}
@ -255,7 +277,9 @@ int ccm_memory(int cipher,
ctr[z] = (ctr[z] + 1) & 255;
if (ctr[z]) break;
}
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
CTRlen = 0;
}
@ -269,21 +293,30 @@ int ccm_memory(int cipher,
}
if (x == 16) {
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
x = 0;
}
PAD[x++] ^= b;
}
if (x != 0) {
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
}
/* setup CTR for the TAG */
ctr[14] = ctr[15] = 0x00;
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
cipher_descriptor[cipher].done(skey);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
if (skey != uskey) {
cipher_descriptor[cipher].done(skey);
}
/* store the TAG */
for (x = 0; x < 16 && x < *taglen; x++) {
@ -296,10 +329,12 @@ int ccm_memory(int cipher,
zeromem(PAD, sizeof(PAD));
zeromem(CTRPAD, sizeof(CTRPAD));
#endif
error:
if (skey != uskey) {
XFREE(skey);
}
XFREE(skey);
return CRYPT_OK;
return err;
}
#endif

View File

@ -116,6 +116,7 @@ int ccm_test(void)
unsigned long taglen, x;
unsigned char buf[64], buf2[64], tag2[16], tag[16];
int err, idx;
symmetric_key skey;
idx = find_cipher("aes");
if (idx == -1) {
@ -127,8 +128,13 @@ int ccm_test(void)
for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
taglen = tests[x].taglen;
if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
return err;
}
if ((err = ccm_memory(idx,
tests[x].key, 16,
&skey,
tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen,
(unsigned char*)tests[x].pt, tests[x].ptlen,
@ -146,6 +152,7 @@ int ccm_test(void)
if ((err = ccm_memory(idx,
tests[x].key, 16,
NULL,
tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen,
buf2, tests[x].ptlen,
@ -154,14 +161,13 @@ int ccm_test(void)
return err;
}
if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) {
if (memcmp(buf2, tests[x].pt, tests[x].ptlen)) {
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;
}
}
cipher_descriptor[idx].done(&skey);
}
return CRYPT_OK;
#endif

View File

@ -62,7 +62,9 @@ int gcm_done(gcm_state *gcm,
gcm_mult_h(gcm, gcm->X);
/* encrypt original counter */
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K);
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
for (x = 0; x < 16 && x < *taglen; x++) {
tag[x] = gcm->buf[x] ^ gcm->X[x];
}

View File

@ -98,7 +98,9 @@ int gcm_init(gcm_state *gcm, int cipher,
/* H = E(0) */
zeromem(B, 16);
cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K);
if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
return err;
}
/* setup state */
zeromem(gcm->buf, sizeof(gcm->buf));

View File

@ -51,7 +51,8 @@ int gcm_memory( int cipher,
}
if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
cipher_descriptor[cipher].accel_gcm_memory
return
cipher_descriptor[cipher].accel_gcm_memory
(key, keylen,
IV, IVlen,
adata, adatalen,
@ -59,7 +60,6 @@ int gcm_memory( int cipher,
ct,
tag, taglen,
direction);
return CRYPT_OK;
}

View File

@ -62,7 +62,9 @@ int gcm_process(gcm_state *gcm,
if (++gcm->Y[y]) { break; }
}
/* encrypt the counter */
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
gcm->buflen = 0;
gcm->mode = GCM_MODE_TEXT;
@ -89,7 +91,9 @@ int gcm_process(gcm_state *gcm,
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y]) { break; }
}
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
}
} else {
for (x = 0; x < (ptlen & ~15); x += 16) {
@ -105,7 +109,9 @@ int gcm_process(gcm_state *gcm,
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y]) { break; }
}
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
}
}
}
@ -121,7 +127,9 @@ int gcm_process(gcm_state *gcm,
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y]) { break; }
}
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
gcm->buflen = 0;
}

View File

@ -51,7 +51,9 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
for (x = 0; x < ocb->block_len; x++) {
tmp[x] = ct[x] ^ Z[x];
}
cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key);
if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) {
return err;
}
for (x = 0; x < ocb->block_len; x++) {
pt[x] ^= Z[x];
}

View File

@ -51,7 +51,9 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
for (x = 0; x < ocb->block_len; x++) {
tmp[x] = pt[x] ^ Z[x];
}
cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key);
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) {
return err;
}
for (x = 0; x < ocb->block_len; x++) {
ct[x] ^= Z[x];
}

View File

@ -76,13 +76,17 @@ int ocb_init(ocb_state *ocb, int cipher,
/* find L = E[0] */
zeromem(ocb->L, ocb->block_len);
cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {
return err;
}
/* find R = E[N xor L] */
for (x = 0; x < ocb->block_len; x++) {
ocb->R[x] = ocb->L[x] ^ nonce[x];
}
cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {
return err;
}
/* find Ls[i] = L << i for i == 0..31 */
XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);

View File

@ -84,7 +84,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
}
/* Y[m] = E(X[m])) */
cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key);
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) {
goto error;
}
if (mode == 1) {
/* decrypt mode, so let's xor it first */
@ -113,7 +115,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
}
/* encrypt checksum, er... tag!! */
cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key);
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) {
goto error;
}
cipher_descriptor[ocb->cipher].done(&ocb->key);
/* now store it */
@ -128,12 +132,12 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
zeromem(Z, MAXBLOCKSIZE);
zeromem(ocb, sizeof(*ocb));
#endif
error:
XFREE(X);
XFREE(Y);
XFREE(Z);
return CRYPT_OK;
return err;
}
#endif

View File

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

View File

@ -54,6 +54,14 @@ int XMEMCMP(const void *s1, const void *s2, size_t n);
#define LTC_FAST_TYPE unsigned long
#endif
/* detect PPC32 */
#if defined(LTC_PPC32)
#define ENDIAN_BIG
#define ENDIAN_32BITWORD
#define LTC_FAST
#define LTC_FAST_TYPE unsigned long
#endif
/* detect sparc and sparc64 */
#if defined(__sparc__)
#define ENDIAN_BIG

View File

@ -263,14 +263,16 @@ extern struct ltc_cipher_descriptor {
@param pt The plaintext
@param ct [out] The ciphertext
@param skey The scheduled key
@return CRYPT_OK if successful
*/
void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
/** Decrypt a block
@param ct The ciphertext
@param pt [out] The plaintext
@param skey The scheduled key
@return CRYPT_OK if successful
*/
void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
/** Test the block cipher
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
@ -293,16 +295,18 @@ extern struct ltc_cipher_descriptor {
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
/** Accelerated ECB decryption
@param pt Plaintext
@param ct Ciphertext
@param blocks The number of complete blocks to process
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
/** Accelerated CBC encryption
@param pt Plaintext
@ -310,8 +314,9 @@ extern struct ltc_cipher_descriptor {
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
/** Accelerated CBC decryption
@param pt Plaintext
@ -319,8 +324,9 @@ extern struct ltc_cipher_descriptor {
@param blocks The number of complete blocks to process
@param IV The initial value (input/output)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
/** Accelerated CTR encryption
@param pt Plaintext
@ -329,12 +335,14 @@ extern struct ltc_cipher_descriptor {
@param IV The initial value (input/output)
@param mode little or big endian counter (mode=0 or mode=1)
@param skey The scheduled key context
@return CRYPT_OK if successful
*/
void (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
/** Accelerated CCM packet (one-shot)
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param uskey A previously scheduled key [optional can be NULL]
@param nonce The session nonce [use once]
@param noncelen The length of the nonce
@param header The header for the session
@ -347,8 +355,9 @@ extern struct ltc_cipher_descriptor {
@param direction Encrypt or Decrypt direction (0 or 1)
@return CRYPT_OK if successful
*/
void (*accel_ccm_memory)(
int (*accel_ccm_memory)(
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
@ -369,8 +378,9 @@ extern struct ltc_cipher_descriptor {
@param tag [out] The MAC tag
@param taglen [in/out] The MAC tag length
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
@return CRYPT_OK on success
*/
void (*accel_gcm_memory)(
int (*accel_gcm_memory)(
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
@ -382,8 +392,8 @@ extern struct ltc_cipher_descriptor {
#ifdef BLOWFISH
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int blowfish_test(void);
void blowfish_done(symmetric_key *skey);
int blowfish_keysize(int *keysize);
@ -392,8 +402,8 @@ extern const struct ltc_cipher_descriptor blowfish_desc;
#ifdef RC5
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc5_test(void);
void rc5_done(symmetric_key *skey);
int rc5_keysize(int *keysize);
@ -402,8 +412,8 @@ extern const struct ltc_cipher_descriptor rc5_desc;
#ifdef RC6
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc6_test(void);
void rc6_done(symmetric_key *skey);
int rc6_keysize(int *keysize);
@ -412,8 +422,8 @@ extern const struct ltc_cipher_descriptor rc6_desc;
#ifdef RC2
int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rc2_test(void);
void rc2_done(symmetric_key *skey);
int rc2_keysize(int *keysize);
@ -422,8 +432,8 @@ extern const struct ltc_cipher_descriptor rc2_desc;
#ifdef SAFERP
int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int saferp_test(void);
void saferp_done(symmetric_key *skey);
int saferp_keysize(int *keysize);
@ -435,8 +445,8 @@ int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmet
int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
int safer_k64_test(void);
int safer_sk64_test(void);
int safer_sk128_test(void);
@ -461,13 +471,13 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer
#define aes_enc_keysize rijndael_enc_keysize
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int rijndael_test(void);
void rijndael_done(symmetric_key *skey);
int rijndael_keysize(int *keysize);
int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void rijndael_enc_done(symmetric_key *skey);
int rijndael_enc_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
@ -476,8 +486,8 @@ extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
#ifdef XTEA
int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int xtea_test(void);
void xtea_done(symmetric_key *skey);
int xtea_keysize(int *keysize);
@ -486,8 +496,8 @@ extern const struct ltc_cipher_descriptor xtea_desc;
#ifdef TWOFISH
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int twofish_test(void);
void twofish_done(symmetric_key *skey);
int twofish_keysize(int *keysize);
@ -496,14 +506,14 @@ extern const struct ltc_cipher_descriptor twofish_desc;
#ifdef DES
int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int des_test(void);
void des_done(symmetric_key *skey);
int des_keysize(int *keysize);
int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int des3_test(void);
void des3_done(symmetric_key *skey);
int des3_keysize(int *keysize);
@ -512,8 +522,8 @@ extern const struct ltc_cipher_descriptor des_desc, des3_desc;
#ifdef CAST5
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int cast5_test(void);
void cast5_done(symmetric_key *skey);
int cast5_keysize(int *keysize);
@ -522,8 +532,8 @@ extern const struct ltc_cipher_descriptor cast5_desc;
#ifdef NOEKEON
int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int noekeon_test(void);
void noekeon_done(symmetric_key *skey);
int noekeon_keysize(int *keysize);
@ -532,8 +542,8 @@ extern const struct ltc_cipher_descriptor noekeon_desc;
#ifdef SKIPJACK
int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int skipjack_test(void);
void skipjack_done(symmetric_key *skey);
int skipjack_keysize(int *keysize);
@ -542,8 +552,8 @@ extern const struct ltc_cipher_descriptor skipjack_desc;
#ifdef KHAZAD
int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int khazad_test(void);
void khazad_done(symmetric_key *skey);
int khazad_keysize(int *keysize);
@ -552,8 +562,8 @@ extern const struct ltc_cipher_descriptor khazad_desc;
#ifdef ANUBIS
int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
int anubis_test(void);
void anubis_done(symmetric_key *skey);
int anubis_keysize(int *keysize);

View File

@ -186,6 +186,9 @@
/* Include RSA support */
#define MRSA
/* Include Katja (an Rabin variant like RSA) */
// #define MKAT
/* Digital Signature Algorithm */
#define MDSA
/* Max diff between group and modulus size in bytes */
@ -200,11 +203,13 @@
/* #define LTC_ECC_TIMING_RESISTANT */
/* Supported ECC Key Sizes */
#define ECC192
#define ECC224
#define ECC256
#define ECC384
#define ECC521
#ifndef LTC_NO_CURVES
#define ECC192
#define ECC224
#define ECC256
#define ECC384
#define ECC521
#endif
/* Include the MPI functionality? (required by the PK algorithms) */
#define MPI
@ -240,14 +245,18 @@
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
#define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL);
#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
#else
#else
/* default no functions */
#define LTC_MUTEX_GLOBAL(x)
#define LTC_MUTEX_PROTO(x)
#define LTC_MUTEX_TYPE(x)
#define LTC_MUTEX_INIT(x)
#define LTC_MUTEX_LOCK(x)
#define LTC_MUTEX_UNLOCK(x)

View File

@ -200,6 +200,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
int ccm_memory(int cipher,
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,

View File

@ -285,6 +285,50 @@ static inline unsigned RORc(unsigned word, const int i)
#endif
#elif defined(LTC_PPC32)
static inline unsigned ROL(unsigned word, int i)
{
asm ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (i));
return word;
}
static inline unsigned ROR(unsigned word, int i)
{
asm ("rotlw %0,%0,%2"
:"=r" (word)
:"0" (word),"r" (32-i));
return word;
}
#ifndef LTC_NO_ROLC
static inline unsigned ROLc(unsigned word, const int i)
{
asm ("rotlwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
static inline unsigned RORc(unsigned word, const int i)
{
asm ("rotrwi %0,%0,%2"
:"=r" (word)
:"0" (word),"I" (i));
return word;
}
#else
#define ROLc ROL
#define RORc ROR
#endif
#else
/* rotates the hard way */

View File

@ -11,6 +11,10 @@
typedef void ecc_point;
#endif
#ifndef MRSA
typedef void rsa_key;
#endif
/** math descriptor */
typedef struct {
/** Name of the math provider */
@ -42,6 +46,13 @@ typedef struct {
/* ---- data movement ---- */
/** negate
@param src The number to negate
@param dst The destination
@return CRYPT_OK on success
*/
int (*neg)(void *src, void *dst);
/** copy
@param src The number to copy from
@param dst The number to write to
@ -339,11 +350,22 @@ typedef struct {
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
/** RSA Key Generation
@param prng An active PRNG state
@param wprng The index of the PRNG desired
@param size The size of the modulus (key size) desired (octets)
@param e The "e" value (public key). e==65537 is a good choice
@param key [out] Destination of a newly created private key pair
@return CRYPT_OK if successful, upon error all allocated ram is freed
*/
int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
/** RSA exponentiation
@param in The octet array representing the base
@param inlen The length of the input
@param out The destination (to be stored in an octet array format)
@param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus
@param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus)
@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
@param key The RSA key to use
@return CRYPT_OK on success
@ -375,7 +397,9 @@ extern const ltc_math_descriptor tfm_desc;
#define mp_init_multi ltc_init_multi
#define mp_clear(a) ltc_mp.deinit(a)
#define mp_clear_multi ltc_deinit_multi
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
#define mp_neg(a, b) ltc_mp.neg(a, b)
#define mp_copy(a, b) ltc_mp.copy(a, b)
#define mp_set(a, b) ltc_mp.set_int(a, b)

View File

@ -73,9 +73,70 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
#endif
/* ---- Katja ---- */
#ifdef MKAT
/* Min and Max KAT key sizes (in bits) */
#define MIN_KAT_SIZE 1024
#define MAX_KAT_SIZE 4096
/** Katja PKCS style key */
typedef struct KAT_key {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** The private exponent */
void *d;
/** The modulus */
void *N;
/** The p factor of N */
void *p;
/** The q factor of N */
void *q;
/** The 1/q mod p CRT param */
void *qP;
/** The d mod (p - 1) CRT param */
void *dP;
/** The d mod (q - 1) CRT param */
void *dQ;
/** The pq param */
void *pq;
} katja_key;
int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
int katja_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
katja_key *key);
void katja_free(katja_key *key);
/* These use PKCS #1 v2.0 padding */
int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
int hash_idx, int *stat,
katja_key *key);
/* PKCS #1 import/export */
int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
#endif
/* ---- ECC Routines ---- */
#ifdef MECC
/* size of our temp buffers for exported keys */
#define ECC_BUF_SIZE 256
/* max private key size */
#define ECC_MAXSIZE 66
/** Structure defines a NIST GF(p) curve */
typedef struct {
/** The size of the curve in octets */
@ -104,8 +165,10 @@ typedef struct {
typedef struct {
/** The x co-ordinate */
void *x;
/** The y co-ordinate */
void *y;
/** The z co-ordinate */
void *z;
} ecc_point;
@ -114,10 +177,13 @@ typedef struct {
typedef struct {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
/** Index into the ltc_ecc_sets[] for the parameters of this curve */
int idx;
/** The public key */
ecc_point pubkey;
/** The private key */
void *k;
} ecc_key;
@ -125,47 +191,52 @@ typedef struct {
/** the ECC params provided */
extern const ltc_ecc_set_type ltc_ecc_sets[];
int ecc_test(void);
int ecc_test(void);
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);
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_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_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen);
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen);
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);
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);
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ecc_key *key);
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
ecc_key *key);
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);
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);
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, ecc_key *key);
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, ecc_key *key);
/* low level functions */
ecc_point *ltc_ecc_new_point(void);
void ltc_ecc_del_point(ecc_point *p);
int ltc_ecc_is_valid_idx(int n);
/* point ops (mp == montgomery digit) */
/* R = 2P */
int ltc_ecc_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
/* R = P + Q */
int ltc_ecc_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
/* R = kG */
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
/* map P to affine from projective */
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
@ -177,16 +248,22 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
typedef struct {
/** The key type, PK_PRIVATE or PK_PUBLIC */
int type;
/** The order of the sub-group used in octets */
int qord;
/** The generator */
void *g;
/** The prime used to generate the sub-group */
void *q;
/** The large prime that generats the field the contains the sub-group */
void *p;
/** The private key */
void *x;
/** The public key */
void *y;
} dsa_key;
@ -194,7 +271,6 @@ typedef struct {
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
void dsa_free(dsa_key *key);
int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
void *r, void *s,
prng_state *prng, int wprng, dsa_key *key);
@ -211,12 +287,24 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long hashlen,
int *stat, dsa_key *key);
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, int hash,
dsa_key *key);
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
dsa_key *key);
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
int dsa_verify_key(dsa_key *key, int *stat);
int dsa_shared_secret(void *private_key, void *base,
dsa_key *public_key,
unsigned char *out, unsigned long *outlen);
#endif
#ifdef LTC_DER
@ -239,7 +327,7 @@ enum {
};
/** A LTC ASN.1 list type */
typedef struct {
typedef struct ltc_asn1_list_ {
/** The LTC ASN.1 enumerated type identifier */
int type;
/** The data to encode or place for decoding */
@ -248,6 +336,8 @@ typedef struct {
unsigned long size;
/** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
int used;
/** prev/next entry in the list */
struct ltc_asn1_list_ *prev, *next, *child, *parent;
} ltc_asn1_list;
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
@ -270,10 +360,16 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen);
/* VA list handy helpers */
/* VA list handy helpers with triplets of <type, size, data> */
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
/* handle unknown list decoder */
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
void der_free_sequence_flexi(ltc_asn1_list *list);
void der_sequence_free(ltc_asn1_list *in);
/* INTEGER */
int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);

View File

@ -3,8 +3,8 @@
/* ===> PKCS #1 -- RSA Cryptography <=== */
#ifdef PKCS_1
int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
int hash_idx,
int pkcs_1_mgf1( int hash_idx,
const unsigned char *seed, unsigned long seedlen,
unsigned char *mask, unsigned long masklen);
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);

View File

@ -4,6 +4,7 @@ struct yarrow_prng {
int cipher, hash;
unsigned char pool[MAXBLOCKSIZE];
symmetric_CTR ctr;
LTC_MUTEX_TYPE(prng_lock)
};
#endif
@ -28,6 +29,7 @@ struct fortuna_prng {
wd;
ulong64 reset_cnt; /* number of times we have reset */
LTC_MUTEX_TYPE(prng_lock)
};
#endif

View File

@ -61,7 +61,9 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen)
}
/* encrypt it */
cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key);
if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) {
return err;
}
cipher_descriptor[omac->cipher_idx].done(&omac->key);
/* output it */

View File

@ -63,7 +63,9 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l
/* first calc L which is Ek(0) */
zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key);
if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) {
return err;
}
/* now do the mults, whoopy! */
for (x = 0; x < 2; x++) {

View File

@ -49,7 +49,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
*((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y]));
}
in += 16;
cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key);
if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
return err;
}
}
inlen -= x;
}
@ -61,7 +63,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
for (x = 0; x < (unsigned long)omac->blklen; x++) {
omac->block[x] ^= omac->prev[x];
}
cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key);
if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
return err;
}
omac->buflen = 0;
}

View File

@ -49,7 +49,9 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen)
}
/* encrypt it */
cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key);
if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) {
return err;
}
cipher_descriptor[state->cipher_idx].done(&state->key);
/* store it */

View File

@ -87,7 +87,9 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l
/* find L = E[0] */
zeromem(L, pmac->block_len);
cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key);
if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {
goto error;
}
/* find Ls[i] = L << i for i == 0..31 */
XMEMCPY(pmac->Ls[0], L, pmac->block_len);
@ -127,14 +129,15 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l
zeromem(pmac->block, sizeof(pmac->block));
zeromem(pmac->Li, sizeof(pmac->Li));
zeromem(pmac->checksum, sizeof(pmac->checksum));
err = CRYPT_OK;
error:
#ifdef LTC_CLEAN_STACK
zeromem(L, pmac->block_len);
#endif
XFREE(L);
return CRYPT_OK;
return err;
}
#endif

View File

@ -50,7 +50,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y]));
}
cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key);
if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
return err;
}
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y]));
}
@ -67,7 +69,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
for (x = 0; x < (unsigned long)pmac->block_len; x++) {
Z[x] = pmac->Li[x] ^ pmac->block[x];
}
cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key);
if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
return err;
}
for (x = 0; x < (unsigned long)pmac->block_len; x++) {
pmac->checksum[x] ^= Z[x];
}

View File

@ -65,6 +65,13 @@ static void deinit(void *a)
XFREE(a);
}
static int neg(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_neg(a, b));
}
static int copy(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
@ -379,6 +386,7 @@ const ltc_math_descriptor ltm_desc = {
&init_copy,
&deinit,
&neg,
&copy,
&set_int,
@ -420,10 +428,11 @@ const ltc_math_descriptor ltm_desc = {
&exptmod,
&isprime,
NULL,
NULL,
NULL,
&ltc_ecc_mulmod,
&ltc_ecc_projective_add_point,
&ltc_ecc_map,
NULL,
NULL
};

View File

@ -34,6 +34,7 @@ int ltc_init_multi(void **a, ...)
va_end(clean_list);
return CRYPT_MEM;
}
++np;
cur = va_arg(args, void**);
}
va_end(args);

View File

@ -59,6 +59,14 @@ static void deinit(void *a)
XFREE(a);
}
static int neg(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
fp_neg(((fp_int*)a), ((fp_int*)b));
return CRYPT_OK;
}
static int copy(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
@ -390,6 +398,7 @@ const ltc_math_descriptor tfm_desc = {
&init_copy,
&deinit,
&neg,
&copy,
&set_int,
@ -422,7 +431,7 @@ const ltc_math_descriptor tfm_desc = {
&mulmod,
&invmod,
&montgomery_setup,
&montgomery_normalization,
&montgomery_reduce,
@ -431,10 +440,11 @@ const ltc_math_descriptor tfm_desc = {
&exptmod,
&isprime,
NULL,
NULL,
NULL,
&ltc_ecc_mulmod,
&ltc_ecc_projective_add_point,
&ltc_ecc_map,
NULL,
NULL
};

View File

@ -229,15 +229,18 @@ const char *crypt_build_settings =
#if defined(MDSA)
" DSA\n"
#endif
#if defined(MKAT)
" Katja\n"
#endif
"\nCompiler:\n"
#if defined(WIN32)
" WIN32 platform detected.\n"
#endif
#if defined(LBL_CYGWIN__)
#if defined(__CYGWIN__)
" CYGWIN Detected.\n"
#endif
#if defined(LBL_DJGPP__)
#if defined(__DJGPP__)
" DJGPP Detected.\n"
#endif
#if defined(_MSC_VER)
@ -249,9 +252,12 @@ const char *crypt_build_settings =
#if defined(INTEL_CC)
" Intel C Compiler detected.\n"
#endif
#if defined(LBL_x86_64__)
#if defined(__x86_64__)
" x86-64 detected.\n"
#endif
#if defined(LTC_PPC32)
" LTC_PPC32 defined \n"
#endif
"\nVarious others: "
#if defined(BASE64)

View File

@ -59,11 +59,13 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
} else {
while (len) {
/* decrypt */
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
return err;
}
/* xor IV against plaintext */
#if defined(LTC_FAST)

View File

@ -53,7 +53,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
} else {
while (len) {
/* xor IV against plaintext */
@ -68,7 +68,9 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
#endif
/* encrypt */
cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key);
if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
return err;
}
/* store IV [ciphertext] for a future block */
#if defined(LTC_FAST)

View File

@ -45,7 +45,9 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
while (len-- > 0) {
if (cfb->padlen == cfb->blocklen) {
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
cfb->pad[cfb->padlen] = *ct;

View File

@ -45,7 +45,9 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
while (len-- > 0) {
if (cfb->padlen == cfb->blocklen) {
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);

View File

@ -40,9 +40,7 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
/* force next block */
cfb->padlen = 0;
cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
return CRYPT_OK;
return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
}
#endif

View File

@ -54,10 +54,8 @@ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
}
/* encrypt the IV */
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
cfb->padlen = 0;
return CRYPT_OK;
return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
}
#endif

View File

@ -52,7 +52,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key);
if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
return err;
}
len %= ctr->blocklen;
}
@ -79,7 +81,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
}
/* encrypt it */
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
return err;
}
ctr->padlen = 0;
}
#ifdef LTC_FAST

View File

@ -45,9 +45,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
/* force next block */
ctr->padlen = 0;
cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
return CRYPT_OK;
return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
}
#endif

View File

@ -59,8 +59,7 @@ int ctr_start( int cipher,
for (x = 0; x < ctr->blocklen; x++) {
ctr->ctr[x] = IV[x];
}
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
return CRYPT_OK;
return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
}
#endif

View File

@ -40,10 +40,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
/* check for accel */
if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
} else {
while (len) {
cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) {
return err;
}
pt += cipher_descriptor[ecb->cipher].block_length;
ct += cipher_descriptor[ecb->cipher].block_length;
len -= cipher_descriptor[ecb->cipher].block_length;

View File

@ -40,10 +40,12 @@ int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
/* check for accel */
if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
} else {
while (len) {
cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key);
if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) {
return err;
}
pt += cipher_descriptor[ecb->cipher].block_length;
ct += cipher_descriptor[ecb->cipher].block_length;
len -= cipher_descriptor[ecb->cipher].block_length;

View File

@ -43,7 +43,9 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
while (len-- > 0) {
if (ofb->padlen == ofb->blocklen) {
cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key);
if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
return err;
}
ofb->padlen = 0;
}
*ct++ = *pt++ ^ ofb->IV[ofb->padlen++];

View File

@ -41,8 +41,7 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
/* force next block */
ofb->padlen = 0;
cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
return CRYPT_OK;
return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
}
#endif

View File

@ -51,7 +51,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
/* get the length of the data */
if (in[x] & 0x80) {
/* long format get number of length bytes */
y = in[x++] & 127;
y = in[x++] & 0x7F;
/* invalid if 0 or > 2 */
if (y == 0 || y > 2) {
@ -65,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
}
} else {
/* short format */
dlen = in[x++] & 127;
dlen = in[x++] & 0x7F;
}
/* is the data len too long or too short? */

View File

@ -96,6 +96,7 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
case LTC_ASN1_NULL:
if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
*inlen = 2;
list[x].used = 1;
return CRYPT_OK;
}
break;

View 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$ */

View File

@ -101,6 +101,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
y += x;
break;
case LTC_ASN1_UTCTIME:
if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_SEQUENCE:
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;

View 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$ */

View 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$ */

View 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$ */

View File

@ -31,6 +31,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(ltc_mp.name != NULL);
/* init key */
if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {

View File

@ -33,6 +33,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
unsigned char *buf;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(ltc_mp.name != NULL);
/* check prng */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {

View 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$ */

File diff suppressed because it is too large Load Diff

View 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$ */

View 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
View 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
View 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
View 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
View 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
View 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$ */

View 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
View 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
View 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$ */

View File

@ -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
View 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$ */

View 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$ */

View File

@ -0,0 +1,45 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
/* 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
View 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
View 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

View 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$ */

View 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