added libtomcrypt-1.07
This commit is contained in:
parent
72412f6dac
commit
4a1a5796de
2
Doxyfile
2
Doxyfile
@ -23,7 +23,7 @@ PROJECT_NAME = LibTomCrypt
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 1.06
|
||||
PROJECT_NUMBER = 1.07
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
37
TODO
37
TODO
@ -1,6 +1,43 @@
|
||||
For 1.07
|
||||
|
||||
|
||||
1. [3 hours] ASN.1 SET and T61String [punishment, add UTF8 to the list!]
|
||||
|
||||
4. [short] Make parameters in descriptors common, e.g. cipher.block_length => cipher.block_size, hash.blocksize => hash.block_size
|
||||
|
||||
DONE
|
||||
----
|
||||
|
||||
0. [important] Make ciphers enc/dec routines return int [for accel]. Make the ciphers themselves return CRYPT_OK [default] *AND* make
|
||||
all dependent code check the returns
|
||||
[x] gcm
|
||||
[x] ccm
|
||||
[x] yarrow
|
||||
[x] fortuna
|
||||
[x] eax
|
||||
[x] ocb
|
||||
[x] omac
|
||||
[x] pmac
|
||||
[x] pelican
|
||||
[x] ctr
|
||||
[x] cbc
|
||||
[x] ecb
|
||||
[x] cfb
|
||||
[x] ofb
|
||||
|
||||
2. [many] ASN.1 flexidecoder. Basically decode and construct a list of decoded ASN.1 types on the fly.
|
||||
This will allow easy decoding of things like X.509 as their orders can be "screwed up".
|
||||
The concept is simple, just read the ID byte and use a linked list. I'll do this after step #1.
|
||||
|
||||
3. [short] Make the cipher/hash accelerators return int [not void] to signal errors. Whoops
|
||||
|
||||
5. [short] Swap arguments of MGF1 around so hash_idx is first
|
||||
|
||||
6. [longish] Re-write parts of the ECC api, re-factor the code, convert to w-NAF, add FP support, add ecc point verifier
|
||||
|
||||
7. [shortish] Provide DH for the DSA code e.g. dsa_encrypt_key()
|
||||
|
||||
8. [worthit] Move the ECC code for point mul and what not as symbols that the TFM/LTM descriptors link in. Means a change to the hierarchy. This allows
|
||||
code that uses ECC plugins to simply ignore this code [e.g. save space]
|
||||
|
||||
9. [short] Document the flexi decoder and how it relates to the other DER routines
|
||||
|
49
changes
49
changes
@ -1,3 +1,44 @@
|
||||
November 18th, 2005
|
||||
v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly. That's because as of a few releases ago
|
||||
I added support to set the mode of the counter at init time
|
||||
-- Fixed some "testprof" make issues
|
||||
-- Added RSA keygen to the math descriptors
|
||||
-- Fixed install_test target ... oops
|
||||
-- made the "ranlib" program renamable useful for cross-compiling
|
||||
-- Made the cipher accelerators return error codes. :-)
|
||||
-- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets
|
||||
-- Added "Katja" public key crypto. It's based on the recent N = p^2q work by Katja. I added OAEP padding
|
||||
to it. Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly
|
||||
analyzed. It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also
|
||||
some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible.
|
||||
-- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya :-)
|
||||
-- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER
|
||||
-- Cleaned up the LIBTEST_S definitions in both GNU makefiles. A few minor touchups as well.
|
||||
-- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this.
|
||||
-- der_decode_choice() would fail to mark a NULL as "used" when decoding. Fixed
|
||||
-- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-)
|
||||
-- Added mp_neg() to the math descriptors.
|
||||
-- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent)
|
||||
-- Made the math descriptors buildable when RSA has been undefined
|
||||
-- ECC timing demo now capable of detecting which curves have been defined
|
||||
-- Refactored the ECC code so it's easier to maintain. (note: the form of this code hasn't really changed since I first added ECC ... :-/)
|
||||
-- Updated the documentation w.r.t. ECC and the accelerators to keep it current
|
||||
-- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error.
|
||||
-- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes)
|
||||
-- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters)
|
||||
-- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead!
|
||||
-- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used)
|
||||
-- ECC code now ALWAYS uses the accelerator interface. This allows people who use the accelerators to not have the stock
|
||||
ECC point add/dbl/mul code linked in. Yeah space savings! Rah Rah Rah.
|
||||
-- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at
|
||||
build time (e.g. LTC_PTHREAD == pthreads)
|
||||
-- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock)
|
||||
-- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-)
|
||||
-- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that]
|
||||
-- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD]
|
||||
-- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing
|
||||
their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask)
|
||||
|
||||
August 1st, 2005
|
||||
v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson]
|
||||
-- Added fourth ARGCHK type which outputs to stderr and continues. Useful if you trap sigsegv. [Valient Gough]
|
||||
@ -234,7 +275,7 @@ October 29th, 2004
|
||||
v0.99 -- Merged in the latest version of LTM which includes all of the recent bug fixes
|
||||
-- Deprecated LTMSSE and removed it (to be replaced with TFM later on)
|
||||
-- Stefan Arentz pointed out that mp_s_rmap should be extern
|
||||
-- Kristian Gjøsteen pointed out that there are typos in the
|
||||
-- Kristian Gj?steen pointed out that there are typos in the
|
||||
"test" makefile and minor issues in Yarrow and Sober [just cosmetics really]
|
||||
-- Matthew P. Cashdollar pointed out that "export" is a C++ keyword
|
||||
so changed the PRNG api to use "pexport" and "pimport"
|
||||
@ -613,7 +654,7 @@ v0.81 -- Merged in new makefile from Clay Culver and Mike Frysinger
|
||||
as much as possible. This sped the routine up quite a bit.
|
||||
-- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
|
||||
-- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
|
||||
(fix due to Mika Boström)
|
||||
(fix due to Mika Bostr?m)
|
||||
-- Merged in LibTomMath for kicks
|
||||
-- Changed the build process so that by default "mycrypt_custom.h" is included and provided
|
||||
The makefile doesn't include any build options anymore
|
||||
@ -1342,6 +1383,6 @@ v0.02 -- Changed RC5 to only allow 12 to 24 rounds
|
||||
v0.01 -- We will call this the first version.
|
||||
|
||||
/* $Source: /cvs/libtom/libtomcrypt/changes,v $ */
|
||||
/* $Revision: 1.123 $ */
|
||||
/* $Date: 2005/08/01 16:50:34 $ */
|
||||
/* $Revision: 1.151 $ */
|
||||
/* $Date: 2005/11/17 22:04:00 $ */
|
||||
|
||||
|
293
crypt.tex
293
crypt.tex
@ -47,7 +47,7 @@
|
||||
\def\gap{\vspace{0.5ex}}
|
||||
\makeindex
|
||||
\begin{document}
|
||||
\title{LibTomCrypt \\ Version 1.06}
|
||||
\title{LibTomCrypt \\ Version 1.07}
|
||||
\author{Tom St Denis \\
|
||||
\\
|
||||
tomstdenis@gmail.com \\
|
||||
@ -236,8 +236,7 @@ int main(void) {
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'', ``ctype.h'' and
|
||||
``ltc\_tommath.h'' (the bignum library routines).
|
||||
The header file ``tomcrypt.h'' also includes ``stdio.h'', ``string.h'', ``stdlib.h'', ``time.h'' and ``ctype.h''.
|
||||
|
||||
\section{Macros}
|
||||
|
||||
@ -363,16 +362,17 @@ done with a key you can simply discard it (e.g. they can be on the stack).
|
||||
To encrypt or decrypt a block in ECB mode there are these two function classes
|
||||
\index{Cipher Encrypt} \index{Cipher Decrypt}
|
||||
\begin{verbatim}
|
||||
void XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
|
||||
int XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct,
|
||||
symmetric_key *skey);
|
||||
|
||||
void XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
|
||||
int XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt,
|
||||
symmetric_key *skey);
|
||||
\end{verbatim}
|
||||
These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on
|
||||
which cipher you are using.} and store the result where you want it. It is possible that the input and output buffer are
|
||||
the same buffer. For the encrypt function ``pt''\footnote{pt stands for plaintext.} is the input and
|
||||
``ct''\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. To test a particular
|
||||
``ct''\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. They both
|
||||
return \textbf{CRYPT\_OK} on success. To test a particular
|
||||
cipher against test vectors\footnote{As published in their design papers.} call the self-test function
|
||||
|
||||
\subsection{Self--Testing}
|
||||
@ -496,39 +496,47 @@ struct _cipher_descriptor {
|
||||
block_length,
|
||||
default_rounds;
|
||||
int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int (*test)(void);
|
||||
void (*done)(symmetric_key *skey);
|
||||
int (*keysize)(int *keysize);
|
||||
|
||||
void (*accel_ecb_encrypt)(const unsigned char *pt,
|
||||
int (*accel_ecb_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct,
|
||||
unsigned long blocks, symmetric_key *skey);
|
||||
void (*accel_ecb_decrypt)(const unsigned char *ct,
|
||||
int (*accel_ecb_decrypt)(const unsigned char *ct,
|
||||
unsigned char *pt,
|
||||
unsigned long blocks, symmetric_key *skey);
|
||||
void (*accel_cbc_encrypt)(const unsigned char *pt,
|
||||
int (*accel_cbc_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct,
|
||||
unsigned long blocks, unsigned char *IV,
|
||||
symmetric_key *skey);
|
||||
void (*accel_cbc_decrypt)(const unsigned char *ct,
|
||||
int (*accel_cbc_decrypt)(const unsigned char *ct,
|
||||
unsigned char *pt,
|
||||
unsigned long blocks, unsigned char *IV,
|
||||
symmetric_key *skey);
|
||||
void (*accel_ctr_encrypt)(const unsigned char *pt,
|
||||
int (*accel_ctr_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct,
|
||||
unsigned long blocks, unsigned char *IV,
|
||||
int mode, symmetric_key *skey);
|
||||
void (*accel_ccm_memory)(
|
||||
int (*accel_ccm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
|
||||
int (*accel_gcm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *IV, unsigned long IVlen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{small}
|
||||
@ -1200,6 +1208,7 @@ function that performs the protocol.
|
||||
\begin{verbatim}
|
||||
int ccm_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
@ -1209,9 +1218,15 @@ int ccm_memory(int cipher,
|
||||
\end{verbatim}
|
||||
|
||||
This performs the ``CCM'' operation on the data. The ``cipher'' variable indicates which cipher in the descriptor table to use. It must have a
|
||||
16--byte block size for CCM. The key is ``key'' with a length of ``keylen'' octets. The nonce or salt is ``nonce'' of
|
||||
length ``noncelen'' octets. The header is meta--data you want to send with the message but not have encrypted, it is stored in ``header''
|
||||
of length ``headerlen'' octets. The header can be zero octets long (if $headerlen = 0$ then you can pass ``header'' as \textbf{NULL}).
|
||||
16--byte block size for CCM.
|
||||
|
||||
The key can be specified in one of two fashions. First it can be passed as an array of octets in ``key'' of length ``keylen''. Alternatively,
|
||||
it can be passed in as a previously scheduled key in ``uskey''. The latter fashion saves time when the same key is used for multiple packets. If
|
||||
``uskey'' is not \textbf{NULL} then ``key'' may be \textbf{NULL} (and vice-versa).
|
||||
|
||||
The nonce or salt is ``nonce'' of length ``noncelen'' octets. The header is meta--data you want to send with the message but not have
|
||||
encrypted, it is stored in ``header'' of length ``headerlen'' octets. The header can be zero octets long (if $headerlen = 0$ then
|
||||
you can pass ``header'' as \textbf{NULL}).
|
||||
|
||||
The plaintext is stored in ``pt'' and the ciphertext in ``ct''. The length of both are expected to be equal and is passed in as ``ptlen''. It is
|
||||
allowable that $pt = ct$. The ``direction'' variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or
|
||||
@ -2902,28 +2917,39 @@ int ecc_shared_secret(ecc_key *private_key,
|
||||
The ``private\_key'' is your own key and ``public\_key'' is the key the other user sent you. Note that this function stores only the
|
||||
$x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH.
|
||||
|
||||
\section{ECC Packet}
|
||||
\section{ECC Diffie-Hellman Encryption}
|
||||
Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key
|
||||
algorithms.
|
||||
|
||||
\index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()}
|
||||
\index{ecc\_encrypt\_key()}
|
||||
\begin{verbatim}
|
||||
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
Where ``in'' is an input symmetric key of no more than 64 bytes. This function creates a random public key
|
||||
and computes the hash of the shared secret. The message digest is then XOR'ed against the symmetric key. All of the required
|
||||
data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large
|
||||
as the symmetric key you are trying to share.
|
||||
|
||||
The data is encrypted to the public ECC ``key'' such that only the holder of the private key can decrypt the payload. If you want
|
||||
to have multiple recipients you will have to call this function for each public ECC key you want to encrypt to.
|
||||
|
||||
|
||||
\index{ecc\_decrypt\_key()}
|
||||
\begin{verbatim}
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
ecc_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
Where ``in'' is an input symmetric key of no more than 64 bytes. Essentially these routines created a random public key
|
||||
and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the required
|
||||
data is placed in ``out'' by ``ecc\_encrypt\_key()''. The hash chosen must produce a message digest at least as large
|
||||
as the symmetric key you are trying to share.
|
||||
This function will decrypt an encrypted payload. The ``key'' provided must be the private key corresponding to the public key
|
||||
used during encryption. If the wrong key is provided the function won't specifically return an error code. It is important
|
||||
to use some form of challenge response in that case (e.g. compute a MAC of a known string).
|
||||
|
||||
\subsection{Encrypt Packet Format}
|
||||
\subsection{Encrypt Encryption Format}
|
||||
|
||||
The packet format for the encrypted keys is the following ASN.1 SEQUENCE:
|
||||
|
||||
@ -2935,30 +2961,40 @@ ECCEncrypt ::= SEQUENCE {
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
\section{ECC DSA Signatures}
|
||||
|
||||
There are also functions to sign and verify the hash of a message.
|
||||
\index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()}
|
||||
\index{ecc\_sign\_hash()}
|
||||
\begin{verbatim}
|
||||
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
This function will EC--DSA sign the message digest stored in the buffer ``in'' of length inlen octets. The signature
|
||||
will be stored in the ``out'' buffer of length ``outlen''. The function requires a properly seeded PRNG and
|
||||
the ECC ``key'' provided must be a private key.
|
||||
|
||||
\index{ecc\_verify\_hash()}
|
||||
\begin{verbatim}
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, ecc_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.
|
||||
The ``ecc\_verify\_hash'' function verifies the ECC signature in ``sig'' against the hash in ``hash''. It sets ``stat''
|
||||
to non-zero if the signature passes or zero if it fails.
|
||||
This function will verify the EC-DSA signature in ``sig'' of length ``siglen'' against the message digest ``hash''.
|
||||
It will store a non--zero value in ``stat'' if the signature is valid. Note that the function will not return
|
||||
an error if the signature is invalid. It will if the actual signature payload is an invalid format. They ECC ``key''
|
||||
must be the public (or private) ECC key corresponding to the key that performed the signature.
|
||||
|
||||
\subsection{Signature Format}
|
||||
The signature code is an implementation of X9.62 EC-DSA and the output is comformant for GF(p) curves.
|
||||
The signature code is an implementation of X9.62 EC--DSA and the output is comformant for GF(p) curves.
|
||||
|
||||
\section{ECC Keysizes}
|
||||
With ECC if you try and sign a hash that is bigger than your ECC key you can run into problems. The math will still work
|
||||
and in effect the signature will still work. With ECC keys the strength of the signature is limited by the size of
|
||||
the hash or the size of they key, whichever is smaller. For example, if you sign with SHA256 and an ECC-192 key in effect
|
||||
you have 192-bits of security.
|
||||
you have 96-bits of security.
|
||||
|
||||
The library will not warn you if you make this mistake so it is important to check yourself before using the
|
||||
signatures.
|
||||
@ -3077,6 +3113,7 @@ This will test ``key'' and store the result in ``stat''. If the result is $stat
|
||||
and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned).
|
||||
|
||||
\section{Signatures}
|
||||
\subsection{Signature Generation}
|
||||
To generate a DSA signature call the following function
|
||||
|
||||
\index{dsa\_sign\_hash()}
|
||||
@ -3090,6 +3127,7 @@ Which will sign the data in ``in'' of length ``inlen'' bytes. The signature is
|
||||
of the signature in ``outlen''. If the signature is longer than the size you initially specify in ``outlen'' nothing
|
||||
is stored and the function returns an error code. The DSA ``key'' must be of the \textbf{PK\_PRIVATE} persuasion.
|
||||
|
||||
\subsection{Signature Verification}
|
||||
To verify a hash created with that function use the following function
|
||||
|
||||
\index{dsa\_verify\_hash()}
|
||||
@ -3101,6 +3139,35 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
Which will verify the data in ``hash'' of length ``inlen'' against the signature stored in ``sig'' of length ``siglen''.
|
||||
It will set ``stat'' to $1$ if the signature is valid, otherwise it sets ``stat'' to $0$.
|
||||
|
||||
\section{DSA Encrypt and Decrypt}
|
||||
As of version 1.07 the DSA keys can be used to encrypt and decrypt small payloads. It works similar to the ECC encryption where
|
||||
a shared key is computed and the hash of the shared key xor'ed against the plaintext forms the ciphertext.
|
||||
|
||||
\subsection{DSA Encryption}
|
||||
This function will encrypt a small payload with a recipients public DSA key.
|
||||
|
||||
\index{dsa\_encrypt\_key()}
|
||||
\begin{verbatim}
|
||||
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dsa_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
This will encrypt the payload in ``in'' of length ``inlen'' and store the ciphertext in the output buffer ``out''. The
|
||||
length of the ciphertext ``outlen'' must be originally set to the length of the output buffer. The DSA ``key'' can be
|
||||
a public key.
|
||||
|
||||
\subsection{DSA Decryption}
|
||||
|
||||
\index{dsa\_decrypt\_key()}
|
||||
\begin{verbatim}
|
||||
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
dsa_key *key);
|
||||
\end{verbatim}
|
||||
This will decrypt the ciphertext ``in'' of length ``inlen'' and store the original payload in ``out'' of length ``outlen''. The DSA ``key'' must be a private key.
|
||||
|
||||
\section{Import and Export}
|
||||
|
||||
To export a DSA key so that it can be transported use the following function
|
||||
@ -3141,9 +3208,12 @@ typedef struct {
|
||||
void *data;
|
||||
unsigned long size;
|
||||
int used;
|
||||
struct ltc_asn1_list_ *prev, *next,
|
||||
*child, *parent;
|
||||
} ltc_asn1_list;
|
||||
\end{verbatim}
|
||||
|
||||
\index{LTC\_SET\_ASN1 macro}
|
||||
The ``type'' field is one of the following ASN.1 field definitions. The ``data'' pointer is a void pointer to the data to be encoded (or the destination) and the
|
||||
``size'' field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type). The ``used'' field is primarily for the CHOICE decoder
|
||||
and reflects if the particular member of a list was the decoded data type. To help build the lists in an orderly fashion the macro
|
||||
@ -3468,6 +3538,45 @@ This will decode the input in the ``in'' field of length ``inlen''. It uses the
|
||||
The ``inlen'' field will be updated with the length of the decoded data type as well as the respective entry in the ``list'' field will have the ``used'' flag
|
||||
set to non--zero to reflect it was the data type decoded.
|
||||
|
||||
\subsection{ASN.1 Flexi Decoder}
|
||||
The ASN.1 ``flexi'' decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing
|
||||
the structure of the data. Where der\_decode\_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely
|
||||
free form.
|
||||
|
||||
The flexi decoder uses the same ``ltc\_asn1\_list'' but instead of being stored in an array it uses the linked list pointers ``prev'', ``next'', ``parent''
|
||||
and ``child''. The list works as a ``doubly-linked list'' structure where decoded items at the same level are sibblings (using next and prev) and items
|
||||
encoded in a SEQUENCE are stored as a child element.
|
||||
|
||||
When a SEQUENCE has been encountered a SEQUENCE item is added as a sibbling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child pointer points to a new list
|
||||
of items contained within the sequence\footnote{The same will be true for the SET data type when I eventually support it.}.
|
||||
|
||||
\index{der\_decode\_sequence\_flexi()}
|
||||
\begin{verbatim}
|
||||
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_asn1_list **out);
|
||||
\end{verbatim}
|
||||
|
||||
This will decode items in the ``in'' buffer of max input length ``inlen'' and store the newly created pointer to the list in ``out''. This function allocates
|
||||
all required memory for the decoding. It stores the number of octets read back into ``inlen''.
|
||||
|
||||
The function will terminate when either it hits an invalid ASN.1 type octet or it reads ``inlen'' octets. An early terminate is a soft error and returns
|
||||
normally. The decoded list ``out'' will point to the very first element of the list (e.g. both parent and prev pointers will be \textbf{NULL}).
|
||||
|
||||
An invalid decoding will terminate the process and free the allocated memory automatically.
|
||||
|
||||
\textbf{Note} that the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly. You will have to first
|
||||
have to convert the list by first storing all of the sibblings in an array then storing all the children as sub-lists of a sequence using the ``.data''
|
||||
pointer. Currently no function in LibTomCrypt provides this ability.
|
||||
|
||||
To free the list use the following function.
|
||||
|
||||
\index{der\_sequence\_free()}
|
||||
\begin{verbatim}
|
||||
void der_sequence_free(ltc_asn1_list *in);
|
||||
\end{verbatim}
|
||||
|
||||
This will free all of the memory allocated by der\_decode\_sequence\_flexi().
|
||||
|
||||
\section{Password Based Cryptography}
|
||||
\subsection{PKCS \#5}
|
||||
\index{PKCS \#5}
|
||||
@ -3729,6 +3838,26 @@ libraries. One for LibTomMath and one for TomsFastMath.
|
||||
All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process. Most of the
|
||||
settings can be overwritten from the command line which makes custom installation a breeze.
|
||||
|
||||
\index{MAKE}
|
||||
\index{CC}
|
||||
\index{AR}
|
||||
\subsection{MAKE, CC and AR}
|
||||
The MAKE, CC and AR flags can all be overwritten. They default to ``make'', ``\$CC'' and ``\$AR'' respectively.
|
||||
|
||||
Changing MAKE allows you to change what program will be invoked to handle sub--directories. E.g.
|
||||
|
||||
\begin{verbatim}
|
||||
MAKE=gmake gmake install
|
||||
\end{verbatim}
|
||||
|
||||
Will build and install the libraries with the ``gmake'' tool. Similarly
|
||||
|
||||
\begin{verbatim}
|
||||
CC=arm-gcc AR=arm-ar make
|
||||
\end{verbatim}
|
||||
|
||||
Will build the library using ``arm--gcc'' as the compiler and ``arm--ar'' as the archiver.
|
||||
|
||||
\subsection{IGNORE\_SPEED}
|
||||
\index{IGNORE\_SPEED}
|
||||
When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new
|
||||
@ -3758,7 +3887,8 @@ directory which defaults to ``/usr/lib''. \textbf{INCPATH} is the prefix for th
|
||||
All four can be used to create custom install locations depending on the nature of the OS and file system in use.
|
||||
|
||||
\begin{verbatim}
|
||||
make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include DATAPATH=/home/tom/project/docs install
|
||||
make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include \
|
||||
DATAPATH=/home/tom/project/docs install
|
||||
\end{verbatim}
|
||||
|
||||
This will build the library and install it to the directories under ``/home/tom/project/''. e.g.
|
||||
@ -3848,13 +3978,11 @@ LibTomCrypt can also be built as a shared library through the ``makefile.shared'
|
||||
that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time.
|
||||
|
||||
\begin{verbatim}
|
||||
CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared
|
||||
CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install
|
||||
\end{verbatim}
|
||||
|
||||
This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well).
|
||||
Note that unlike the static build there is no ``install'' target. The default action of this make script is to install the library.
|
||||
|
||||
The shared build process requires libtool to be installed.
|
||||
This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well). The
|
||||
shared build process requires libtool to be installed.
|
||||
|
||||
\section{tomcrypt\_cfg.h}
|
||||
The file ``tomcrypt\_cfg.h'' is what lets you control various high level macros which control the behaviour
|
||||
@ -4025,26 +4153,31 @@ struct ltc_cipher_descriptor {
|
||||
@param skey [out] The destination of the scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int (*setup)(const unsigned char *key, int keylen,
|
||||
int num_rounds, symmetric_key *skey);
|
||||
int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
/** Encrypt a block
|
||||
@param pt The plaintext
|
||||
@param ct [out] The ciphertext
|
||||
@param skey The scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*ecb_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct, symmetric_key *skey);
|
||||
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
/** Decrypt a block
|
||||
@param ct The ciphertext
|
||||
@param pt [out] The plaintext
|
||||
@param skey The scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*ecb_decrypt)(const unsigned char *ct,
|
||||
unsigned char *pt, symmetric_key *skey);
|
||||
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
/** Test the block cipher
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
|
||||
*/
|
||||
int (*test)(void);
|
||||
|
||||
/** Terminate the context
|
||||
@param skey The scheduled key
|
||||
*/
|
||||
void (*done)(symmetric_key *skey);
|
||||
|
||||
/** Determine a key size
|
||||
@param keysize [in/out] The size of the key desired and the suggested size
|
||||
@return CRYPT_OK if successful
|
||||
@ -4057,20 +4190,20 @@ struct ltc_cipher_descriptor {
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ecb_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct, unsigned long blocks,
|
||||
symmetric_key *skey);
|
||||
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct,
|
||||
unsigned long blocks, symmetric_key *skey);
|
||||
|
||||
/** Accelerated ECB decryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ecb_decrypt)(const unsigned char *ct,
|
||||
unsigned char *pt, unsigned long blocks,
|
||||
symmetric_key *skey);
|
||||
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt,
|
||||
unsigned long blocks, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CBC encryption
|
||||
@param pt Plaintext
|
||||
@ -4078,10 +4211,11 @@ struct ltc_cipher_descriptor {
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_cbc_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct, unsigned long blocks,
|
||||
unsigned char *IV, symmetric_key *skey);
|
||||
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct,
|
||||
unsigned long blocks, unsigned char *IV,
|
||||
symmetric_key *skey);
|
||||
|
||||
/** Accelerated CBC decryption
|
||||
@param pt Plaintext
|
||||
@ -4089,10 +4223,11 @@ struct ltc_cipher_descriptor {
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_cbc_decrypt)(const unsigned char *ct,
|
||||
unsigned char *pt, unsigned long blocks,
|
||||
unsigned char *IV, symmetric_key *skey);
|
||||
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt,
|
||||
unsigned long blocks, unsigned char *IV,
|
||||
symmetric_key *skey);
|
||||
|
||||
/** Accelerated CTR encryption
|
||||
@param pt Plaintext
|
||||
@ -4101,14 +4236,16 @@ struct ltc_cipher_descriptor {
|
||||
@param IV The initial value (input/output)
|
||||
@param mode little or big endian counter (mode=0 or mode=1)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ctr_encrypt)(const unsigned char *pt,
|
||||
unsigned char *ct, unsigned long blocks,
|
||||
unsigned char *IV, int mode, symmetric_key *skey);
|
||||
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct,
|
||||
unsigned long blocks, unsigned char *IV,
|
||||
int mode, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CCM packet (one-shot)
|
||||
@param key The secret key to use
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param uskey A previously scheduled key [optional can be NULL]
|
||||
@param nonce The session nonce [use once]
|
||||
@param noncelen The length of the nonce
|
||||
@param header The header for the session
|
||||
@ -4121,8 +4258,9 @@ struct ltc_cipher_descriptor {
|
||||
@param direction Encrypt or Decrypt direction (0 or 1)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ccm_memory)(
|
||||
int (*accel_ccm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
@ -4143,8 +4281,9 @@ struct ltc_cipher_descriptor {
|
||||
@param tag [out] The MAC tag
|
||||
@param taglen [in/out] The MAC tag length
|
||||
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
void (*accel_gcm_memory)(
|
||||
int (*accel_gcm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *IV, unsigned long IVlen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
@ -4152,7 +4291,6 @@ struct ltc_cipher_descriptor {
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen,
|
||||
int direction);
|
||||
|
||||
};
|
||||
\end{verbatim}
|
||||
\end{small}
|
||||
@ -4231,8 +4369,22 @@ buffer provided) before encrypting it to create the pad.
|
||||
The accelerator will only be used to encrypt whole blocks. Partial blocks are always handled in software.
|
||||
|
||||
\subsubsection{Accelerated CCM}
|
||||
This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not
|
||||
be called prior to this. This function must handle scheduling the key provided on its own.
|
||||
This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. You can optimize the work flow somewhat
|
||||
by allowing the caller to call the setup() function first to schedule the key if your accelerator cannot do the key schedule on the fly (for instance). This
|
||||
function MUST support both key passing methods.
|
||||
|
||||
\begin{center}
|
||||
\begin{small}
|
||||
\begin{tabular}{|r|r|l|}
|
||||
\hline \textbf{key} & \textbf{uskey} & \textbf{Source of key} \\
|
||||
\hline NULL & NULL & Error, not supported \\
|
||||
\hline non-NULL & NULL & Use key, do a key schedule \\
|
||||
\hline NULL & non-NULL & Use uskey, key schedule not required \\
|
||||
\hline non-NULL & non-NULL & Use uskey, key schedule not required \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{small}
|
||||
\end{center}
|
||||
|
||||
\subsubsection{Accelerated GCM}
|
||||
This function is meant for accelerated GCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not
|
||||
@ -4560,7 +4712,6 @@ typedef struct {
|
||||
*/
|
||||
int (*add)(void *a, void *b, void *c);
|
||||
|
||||
|
||||
/** add two integers
|
||||
@param a The first source integer
|
||||
@param b The second source integer (single digit of upto bits_per_digit in length)
|
||||
@ -4748,6 +4899,16 @@ typedef struct {
|
||||
|
||||
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
|
||||
|
||||
/** RSA Key Generation
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param size The size of the modulus (key size) desired (octets)
|
||||
@param e The "e" value (public key). e==65537 is a good choice
|
||||
@param key [out] Destination of a newly created private key pair
|
||||
@return CRYPT_OK if successful, upon error all allocated ram is freed
|
||||
*/
|
||||
int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
|
||||
|
||||
/** RSA exponentiation
|
||||
@param in The octet array representing the base
|
||||
@param inlen The length of the input
|
||||
@ -4851,5 +5012,5 @@ Since the function is given the entire RSA key (for private keys only) CRT is po
|
||||
\end{document}
|
||||
|
||||
% $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $
|
||||
% $Revision: 1.45 $
|
||||
% $Date: 2005/08/01 16:59:29 $
|
||||
% $Revision: 1.55 $
|
||||
% $Date: 2005/11/18 01:45:03 $
|
||||
|
@ -170,7 +170,7 @@ int main(int argc, char *argv[])
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_start error: %s\n",error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
@ -212,7 +212,7 @@ int main(int argc, char *argv[])
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_start error: %s\n",error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ int main(void)
|
||||
printf("\nrsa_test......"); fflush(stdout); x = rsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
|
||||
printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
|
||||
printf("\ndsa_test......"); fflush(stdout); x = dsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
|
||||
printf("\nkatja_test...."); fflush(stdout); x = katja_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE);
|
||||
printf("\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ reg_algs();
|
||||
extern ltc_math_descriptor EXT_MATH_LIB;
|
||||
ltc_mp = EXT_MATH_LIB;
|
||||
#endif
|
||||
|
||||
time_keysched();
|
||||
time_cipher();
|
||||
time_cipher2();
|
||||
@ -27,6 +26,9 @@ time_mult();
|
||||
time_sqr();
|
||||
time_rsa();
|
||||
time_ecc();
|
||||
#ifdef USE_LTM
|
||||
time_katja();
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ void ccm_gen(void)
|
||||
plaintext[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(tag);
|
||||
if ((err = ccm_memory(x, key, kl, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
|
||||
if ((err = ccm_memory(x, key, kl, NULL, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) {
|
||||
printf("Error CCM'ing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -682,7 +682,7 @@ void ecc_gen(void)
|
||||
mp_set(G->z, 1);
|
||||
|
||||
while (mp_cmp(k, order) == LTC_MP_LT) {
|
||||
ltc_ecc_mulmod(k, G, R, modulus, 1);
|
||||
ltc_mp.ecc_ptmul(k, G, R, modulus, 1);
|
||||
mp_tohex(k, str); fprintf(out, "%s, ", str);
|
||||
mp_tohex(R->x, str); fprintf(out, "%s, ", str);
|
||||
mp_tohex(R->y, str); fprintf(out, "%s\n", str);
|
||||
|
BIN
doc/crypt.pdf
BIN
doc/crypt.pdf
Binary file not shown.
80
makefile
80
makefile
@ -4,7 +4,7 @@
|
||||
# Modified by Clay Culver
|
||||
|
||||
# The version
|
||||
VERSION=1.06
|
||||
VERSION=1.07
|
||||
|
||||
# Compiler and Linker Names
|
||||
#CC=gcc
|
||||
@ -14,12 +14,23 @@ VERSION=1.06
|
||||
#AR=ar
|
||||
#ARFLAGS=r
|
||||
|
||||
ifndef MAKE
|
||||
MAKE=make
|
||||
endif
|
||||
|
||||
# ranlib tools
|
||||
ifndef RANLIB
|
||||
RANLIB=ranlib
|
||||
endif
|
||||
|
||||
# Compilation flags. Note the += does not write over the user's CFLAGS!
|
||||
CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter -DLTC_SOURCE
|
||||
|
||||
# additional warnings (newer GCC 3.4 and higher)
|
||||
#CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
|
||||
# -Wmissing-declarations -Wpointer-arith
|
||||
ifdef GCC_34
|
||||
CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Wmissing-declarations -Wpointer-arith
|
||||
endif
|
||||
|
||||
ifndef IGNORE_SPEED
|
||||
|
||||
@ -47,8 +58,8 @@ ifndef LIBNAME
|
||||
endif
|
||||
ifndef LIBTEST
|
||||
LIBTEST=libtomcrypt_prof.a
|
||||
LIBTEST_S=$(LIBTEST)
|
||||
endif
|
||||
LIBTEST_S=$(LIBTEST)
|
||||
|
||||
HASH=hashsum
|
||||
CRYPT=encrypt
|
||||
@ -154,22 +165,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
|
||||
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_length_printable_string.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
|
||||
src/pk/asn1/der/sequence/der_length_sequence.o \
|
||||
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
|
||||
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
|
||||
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
|
||||
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
|
||||
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
|
||||
src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \
|
||||
src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
|
||||
src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \
|
||||
src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
|
||||
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
|
||||
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
|
||||
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
|
||||
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
|
||||
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
|
||||
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
|
||||
src/prngs/sprng.o src/prngs/yarrow.o
|
||||
src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
|
||||
src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
|
||||
src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
|
||||
src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
|
||||
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
|
||||
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
|
||||
src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
|
||||
src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
|
||||
src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
|
||||
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
|
||||
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
|
||||
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
|
||||
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
|
||||
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
|
||||
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
|
||||
|
||||
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
|
||||
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
|
||||
@ -203,8 +223,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
|
||||
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
|
||||
src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
|
||||
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
|
||||
src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
|
||||
src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
|
||||
src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
|
||||
src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
|
||||
|
||||
@ -212,11 +230,11 @@ src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
|
||||
library: $(LIBNAME)
|
||||
|
||||
testprof/$(LIBTEST):
|
||||
cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) make
|
||||
cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE)
|
||||
|
||||
$(LIBNAME): $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJECTS)
|
||||
ranlib $(LIBNAME)
|
||||
$(RANLIB) $@
|
||||
|
||||
#This rule makes the hash program included with libtomcrypt
|
||||
hashsum: library $(HASHOBJECTS)
|
||||
@ -242,28 +260,33 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
|
||||
test: library testprof/$(LIBTEST) $(TESTS)
|
||||
$(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST)
|
||||
|
||||
|
||||
#This rule installs the library and the header files. This must be run
|
||||
#as root in order to have a high enough permission to write to the correct
|
||||
#directories and to set the owner and group to root.
|
||||
ifndef NODOCS
|
||||
install: library docs
|
||||
else
|
||||
install: library
|
||||
endif
|
||||
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
|
||||
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
|
||||
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH)
|
||||
install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
|
||||
install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
|
||||
ifndef NODOCS
|
||||
install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH)
|
||||
endif
|
||||
|
||||
install_test: $(LIBTEST)
|
||||
install_test: testprof/$(LIBTEST)
|
||||
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
|
||||
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
|
||||
install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH)
|
||||
install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH)
|
||||
|
||||
profile:
|
||||
CFLAGS="$(CFLAGS) -fprofile-generate" make timing EXTRALIBS=-lgcov
|
||||
CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
|
||||
./timing
|
||||
rm -f timing `find . -type f | grep [.][ao] | xargs`
|
||||
CFLAGS="$(CFLAGS) -fprofile-use" make timing EXTRALIBS=-lgcov
|
||||
CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov"
|
||||
|
||||
|
||||
#This rule cleans the source tree of all compiled code, not including the pdf
|
||||
@ -291,7 +314,7 @@ clean:
|
||||
#build the doxy files (requires Doxygen, tetex and patience)
|
||||
doxy:
|
||||
doxygen
|
||||
cd doc/doxygen/latex ; make ; mv -f refman.pdf ../../.
|
||||
cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../.
|
||||
echo The huge doxygen PDF should be available as doc/refman.pdf
|
||||
|
||||
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
|
||||
@ -333,6 +356,5 @@ zipup: no_oops docs
|
||||
|
||||
|
||||
# $Source: /cvs/libtom/libtomcrypt/makefile,v $
|
||||
# $Revision: 1.86 $
|
||||
# $Date: 2005/07/30 04:54:20 $
|
||||
|
||||
# $Revision: 1.103 $
|
||||
# $Date: 2005/11/18 01:46:22 $
|
||||
|
39
makefile.icc
39
makefile.icc
@ -152,22 +152,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
|
||||
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_length_printable_string.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
|
||||
src/pk/asn1/der/sequence/der_length_sequence.o \
|
||||
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
|
||||
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
|
||||
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
|
||||
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
|
||||
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
|
||||
src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \
|
||||
src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
|
||||
src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \
|
||||
src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
|
||||
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
|
||||
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
|
||||
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
|
||||
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
|
||||
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
|
||||
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
|
||||
src/prngs/sprng.o src/prngs/yarrow.o
|
||||
src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
|
||||
src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
|
||||
src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
|
||||
src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
|
||||
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
|
||||
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
|
||||
src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
|
||||
src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
|
||||
src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
|
||||
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
|
||||
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
|
||||
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
|
||||
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
|
||||
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
|
||||
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
|
||||
|
||||
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
|
||||
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
|
||||
@ -207,8 +216,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
|
||||
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
|
||||
src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
|
||||
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
|
||||
src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
|
||||
src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
|
||||
src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
|
||||
src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
|
||||
|
||||
@ -254,5 +261,5 @@ install: library
|
||||
install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
|
||||
|
||||
# $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $
|
||||
# $Revision: 1.39 $
|
||||
# $Date: 2005/07/30 23:38:39 $
|
||||
# $Revision: 1.44 $
|
||||
# $Date: 2005/11/18 01:46:22 $
|
||||
|
@ -1,7 +1,7 @@
|
||||
#MSVC Makefile [tested with MSVC 6.00 with SP5]
|
||||
#
|
||||
#Tom St Denis
|
||||
CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@
|
||||
CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF)
|
||||
|
||||
OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \
|
||||
src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/khazad.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
|
||||
@ -67,22 +67,31 @@ src/pk/asn1/der/octet/der_length_octet_string.obj \
|
||||
src/pk/asn1/der/printable_string/der_decode_printable_string.obj \
|
||||
src/pk/asn1/der/printable_string/der_encode_printable_string.obj \
|
||||
src/pk/asn1/der/printable_string/der_length_printable_string.obj \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence.obj src/pk/asn1/der/sequence/der_encode_sequence_multi.obj \
|
||||
src/pk/asn1/der/sequence/der_length_sequence.obj \
|
||||
src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.obj src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_multi.obj src/pk/asn1/der/sequence/der_encode_sequence.obj \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \
|
||||
src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \
|
||||
src/pk/asn1/der/short_integer/der_encode_short_integer.obj \
|
||||
src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \
|
||||
src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \
|
||||
src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj \
|
||||
src/pk/dsa/dsa_decrypt_key.obj src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj \
|
||||
src/pk/dsa/dsa_import.obj src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_shared_secret.obj \
|
||||
src/pk/dsa/dsa_sign_hash.obj src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc.obj \
|
||||
src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj src/pk/pkcs1/pkcs_1_oaep_decode.obj \
|
||||
src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj src/pk/pkcs1/pkcs_1_pss_decode.obj \
|
||||
src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \
|
||||
src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \
|
||||
src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \
|
||||
src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \
|
||||
src/prngs/sprng.obj src/prngs/yarrow.obj
|
||||
src/pk/ecc/ecc_decrypt_key.obj src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_free.obj \
|
||||
src/pk/ecc/ecc_get_size.obj src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.obj \
|
||||
src/pk/ecc/ecc_shared_secret.obj src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj \
|
||||
src/pk/ecc/ecc_verify_hash.obj src/pk/ecc/ltc_ecc_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj \
|
||||
src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \
|
||||
src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \
|
||||
src/pk/katja/katja_decrypt_key.obj src/pk/katja/katja_encrypt_key.obj src/pk/katja/katja_export.obj \
|
||||
src/pk/katja/katja_exptmod.obj src/pk/katja/katja_free.obj src/pk/katja/katja_import.obj \
|
||||
src/pk/katja/katja_make_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \
|
||||
src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \
|
||||
src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/rsa/rsa_decrypt_key.obj \
|
||||
src/pk/rsa/rsa_encrypt_key.obj src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj \
|
||||
src/pk/rsa/rsa_import.obj src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj \
|
||||
src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj src/prngs/rc4.obj src/prngs/rng_get_bytes.obj \
|
||||
src/prngs/rng_make_prng.obj src/prngs/sober128.obj src/prngs/sprng.obj src/prngs/yarrow.obj
|
||||
|
||||
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
|
||||
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
|
||||
@ -115,5 +124,6 @@ timing: demos/timing.c library
|
||||
cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS)
|
||||
|
||||
# $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $
|
||||
# $Revision: 1.17 $
|
||||
# $Date: 2005/07/30 23:42:57 $
|
||||
# $Revision: 1.24 $
|
||||
# $Date: 2005/11/18 01:46:22 $
|
||||
|
||||
|
@ -6,11 +6,16 @@
|
||||
# Tom St Denis
|
||||
|
||||
# The version
|
||||
VERSION=0:106
|
||||
VERSION=0:107
|
||||
|
||||
# Compiler and Linker Names
|
||||
CC=libtool --mode=compile gcc
|
||||
|
||||
# ranlib tools
|
||||
ifndef RANLIB
|
||||
RANLIB=ranlib
|
||||
endif
|
||||
|
||||
# Compilation flags. Note the += does not write over the user's CFLAGS!
|
||||
CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE
|
||||
|
||||
@ -39,8 +44,10 @@ endif
|
||||
#CFLAGS += -DLTC_NO_ROLC
|
||||
|
||||
#Output filenames for various targets.
|
||||
ifndef LIBTEST
|
||||
ifndef LIBTEST_S
|
||||
LIBTEST_S=libtomcrypt_prof.a
|
||||
endif
|
||||
ifndef LIBTEST
|
||||
LIBTEST=libtomcrypt_prof.la
|
||||
endif
|
||||
ifndef LIBNAME
|
||||
@ -152,22 +159,31 @@ src/pk/asn1/der/octet/der_length_octet_string.o \
|
||||
src/pk/asn1/der/printable_string/der_decode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_encode_printable_string.o \
|
||||
src/pk/asn1/der/printable_string/der_length_printable_string.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence.o src/pk/asn1/der/sequence/der_encode_sequence_multi.o \
|
||||
src/pk/asn1/der/sequence/der_length_sequence.o \
|
||||
src/pk/asn1/der/short_integer/der_decode_short_integer.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence.o src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
|
||||
src/pk/asn1/der/sequence/der_decode_sequence_multi.o src/pk/asn1/der/sequence/der_encode_sequence.o \
|
||||
src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
|
||||
src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
|
||||
src/pk/asn1/der/short_integer/der_encode_short_integer.o \
|
||||
src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
|
||||
src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
|
||||
src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o \
|
||||
src/pk/dsa/dsa_decrypt_key.o src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o \
|
||||
src/pk/dsa/dsa_import.o src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o \
|
||||
src/pk/dsa/dsa_sign_hash.o src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
|
||||
src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o src/pk/pkcs1/pkcs_1_oaep_decode.o \
|
||||
src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o src/pk/pkcs1/pkcs_1_pss_decode.o \
|
||||
src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
|
||||
src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
|
||||
src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
|
||||
src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
|
||||
src/prngs/sprng.o src/prngs/yarrow.o
|
||||
src/pk/ecc/ecc_decrypt_key.o src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o \
|
||||
src/pk/ecc/ecc_get_size.o src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o \
|
||||
src/pk/ecc/ecc_shared_secret.o src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o \
|
||||
src/pk/ecc/ecc_verify_hash.o src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o \
|
||||
src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
|
||||
src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
|
||||
src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
|
||||
src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
|
||||
src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
|
||||
src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
|
||||
src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/rsa/rsa_decrypt_key.o \
|
||||
src/pk/rsa/rsa_encrypt_key.o src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o \
|
||||
src/pk/rsa/rsa_import.o src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o \
|
||||
src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o src/prngs/rc4.o src/prngs/rng_get_bytes.o \
|
||||
src/prngs/rng_make_prng.o src/prngs/sober128.o src/prngs/sprng.o src/prngs/yarrow.o
|
||||
|
||||
HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
|
||||
src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
|
||||
@ -194,8 +210,6 @@ src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
|
||||
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
|
||||
src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c
|
||||
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
|
||||
src/pk/ecc/ecc.o: src/pk/ecc/ecc.c src/pk/ecc/ecc_sys.c
|
||||
src/pk/dh/dh.o: src/pk/dh/dh.c src/pk/dh/dh_sys.c
|
||||
src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c
|
||||
src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c
|
||||
|
||||
@ -205,10 +219,13 @@ library: $(LIBNAME)
|
||||
testprof/$(LIBTEST):
|
||||
cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared
|
||||
|
||||
$(LIBNAME): $(OBJECTS)
|
||||
objs: $(OBJECTS)
|
||||
|
||||
$(LIBNAME): $(OBJECTS) testprof/$(LIBTEST)
|
||||
libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION)
|
||||
libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]o" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME_S)
|
||||
ranlib $(LIBNAME_S)
|
||||
|
||||
install: $(LIBNAME)
|
||||
cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared install
|
||||
libtool --silent --mode=install install -c libtomcrypt.la $(LIBPATH)/libtomcrypt.la
|
||||
install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
|
||||
install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
|
||||
@ -233,5 +250,6 @@ timing: library testprof/$(LIBTEST) $(TIMINGS)
|
||||
gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS)
|
||||
|
||||
# $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $
|
||||
# $Revision: 1.25 $
|
||||
# $Date: 2005/07/30 04:54:20 $
|
||||
# $Revision: 1.36 $
|
||||
# $Date: 2005/11/18 01:46:22 $
|
||||
|
||||
|
@ -281,11 +281,12 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s
|
||||
@param pt The input plaintext (16 bytes)
|
||||
@param ct The output ciphertext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
|
||||
@ -440,13 +441,16 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
(Te4_0[byte(t2, 0)]) ^
|
||||
rk[3];
|
||||
STORE32H(s3, ct+12);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_rijndael_ecb_encrypt(pt, ct, skey);
|
||||
int err = _rijndael_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -457,11 +461,12 @@ void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
@param ct The input ciphertext (16 bytes)
|
||||
@param pt The output plaintext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
|
||||
@ -615,14 +620,17 @@ void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
(Td4[byte(t0, 0)] & 0x000000ff) ^
|
||||
rk[3];
|
||||
STORE32H(s3, pt+12);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_rijndael_ecb_decrypt(ct, pt, skey);
|
||||
int err = _rijndael_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1134,13 +1134,15 @@ static void anubis_crypt(const unsigned char *plaintext, unsigned char *cipherte
|
||||
@param pt The input plaintext (16 bytes)
|
||||
@param ct The output ciphertext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(skey != NULL);
|
||||
anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1148,13 +1150,15 @@ void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
|
||||
@param ct The input ciphertext (16 bytes)
|
||||
@param pt The output plaintext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(skey != NULL);
|
||||
anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -385,11 +385,12 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 L, R;
|
||||
@ -428,13 +429,16 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
|
||||
/* store */
|
||||
STORE32H(R, &ct[0]);
|
||||
STORE32H(L, &ct[4]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_blowfish_ecb_encrypt(pt, ct, skey);
|
||||
int err = _blowfish_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -443,11 +447,12 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 L, R;
|
||||
@ -486,13 +491,15 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
|
||||
/* store */
|
||||
STORE32H(L, &pt[0]);
|
||||
STORE32H(R, &pt[4]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_blowfish_ecb_decrypt(ct, pt, skey);
|
||||
int err = _blowfish_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -536,9 +536,9 @@ INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
|
||||
@param skey The key as scheduled
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 R, L;
|
||||
@ -569,14 +569,16 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
|
||||
}
|
||||
STORE32H(R,&ct[0]);
|
||||
STORE32H(L,&ct[4]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_cast5_ecb_encrypt(pt,ct,skey);
|
||||
int err =_cast5_ecb_encrypt(pt,ct,skey);
|
||||
burn_stack(sizeof(ulong32)*3);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -587,9 +589,9 @@ void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
|
||||
@param skey The key as scheduled
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 R, L;
|
||||
@ -620,13 +622,16 @@ void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
|
||||
L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
|
||||
STORE32H(L,&pt[0]);
|
||||
STORE32H(R,&pt[4]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_cast5_ecb_decrypt(ct,pt,skey);
|
||||
int err = _cast5_ecb_decrypt(ct,pt,skey);
|
||||
burn_stack(sizeof(ulong32)*3);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1582,8 +1582,9 @@ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
ulong32 work[2];
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
@ -1594,6 +1595,7 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
|
||||
desfunc(work, skey->des.ek);
|
||||
STORE32H(work[0],ct+0);
|
||||
STORE32H(work[1],ct+4);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1601,8 +1603,9 @@ void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
ulong32 work[2];
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
@ -1613,6 +1616,7 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
|
||||
desfunc(work, skey->des.dk);
|
||||
STORE32H(work[0],pt+0);
|
||||
STORE32H(work[1],pt+4);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1620,8 +1624,9 @@ void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
ulong32 work[2];
|
||||
|
||||
@ -1635,6 +1640,7 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
|
||||
desfunc(work, skey->des3.ek[2]);
|
||||
STORE32H(work[0],ct+0);
|
||||
STORE32H(work[1],ct+4);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1642,8 +1648,9 @@ void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
ulong32 work[2];
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
@ -1656,6 +1663,7 @@ void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
|
||||
desfunc(work, skey->des3.dk[2]);
|
||||
STORE32H(work[0],pt+0);
|
||||
STORE32H(work[1],pt+4);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -741,13 +741,15 @@ static void khazad_crypt(const unsigned char *plaintext, unsigned char *cipherte
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(skey != NULL);
|
||||
khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -755,13 +757,15 @@ void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(skey != NULL);
|
||||
khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,11 +107,12 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
|
||||
@param pt The input plaintext (16 bytes)
|
||||
@param ct The output ciphertext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d,temp;
|
||||
@ -142,13 +143,16 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
|
||||
|
||||
STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
|
||||
STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_noekeon_ecb_encrypt(pt, ct, skey);
|
||||
int err = _noekeon_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -157,11 +161,12 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
|
||||
@param ct The input ciphertext (16 bytes)
|
||||
@param pt The output plaintext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d, temp;
|
||||
@ -192,13 +197,15 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
|
||||
a ^= RC[0];
|
||||
STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
|
||||
STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_noekeon_ecb_decrypt(ct, pt, skey);
|
||||
int err = _noekeon_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -125,13 +125,14 @@ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rc2_ecb_encrypt( const unsigned char *pt,
|
||||
static int _rc2_ecb_encrypt( const unsigned char *pt,
|
||||
unsigned char *ct,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void rc2_ecb_encrypt( const unsigned char *pt,
|
||||
int rc2_ecb_encrypt( const unsigned char *pt,
|
||||
unsigned char *ct,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
@ -179,15 +180,18 @@ void rc2_ecb_encrypt( const unsigned char *pt,
|
||||
ct[5] = (unsigned char)(x54 >> 8);
|
||||
ct[6] = (unsigned char)x76;
|
||||
ct[7] = (unsigned char)(x76 >> 8);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void rc2_ecb_encrypt( const unsigned char *pt,
|
||||
int rc2_ecb_encrypt( const unsigned char *pt,
|
||||
unsigned char *ct,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_rc2_ecb_encrypt(pt, ct, skey);
|
||||
int err = _rc2_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -199,13 +203,14 @@ void rc2_ecb_encrypt( const unsigned char *pt,
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rc2_ecb_decrypt( const unsigned char *ct,
|
||||
static int _rc2_ecb_decrypt( const unsigned char *ct,
|
||||
unsigned char *pt,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void rc2_ecb_decrypt( const unsigned char *ct,
|
||||
int rc2_ecb_decrypt( const unsigned char *ct,
|
||||
unsigned char *pt,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
@ -254,15 +259,18 @@ void rc2_ecb_decrypt( const unsigned char *ct,
|
||||
pt[5] = (unsigned char)(x54 >> 8);
|
||||
pt[6] = (unsigned char)x76;
|
||||
pt[7] = (unsigned char)(x76 >> 8);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void rc2_ecb_decrypt( const unsigned char *ct,
|
||||
int rc2_ecb_decrypt( const unsigned char *ct,
|
||||
unsigned char *pt,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_rc2_ecb_decrypt(ct, pt, skey);
|
||||
int err = _rc2_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -123,11 +123,12 @@ int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 A, B, *K;
|
||||
@ -159,13 +160,16 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
|
||||
}
|
||||
STORE32L(A, &ct[0]);
|
||||
STORE32L(B, &ct[4]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_rc5_ecb_encrypt(pt, ct, skey);
|
||||
int err = _rc5_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -174,11 +178,12 @@ void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 A, B, *K;
|
||||
@ -211,13 +216,16 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
|
||||
B -= skey->rc5.K[1];
|
||||
STORE32L(A, &pt[0]);
|
||||
STORE32L(B, &pt[4]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_rc5_ecb_decrypt(ct, pt, skey);
|
||||
int err = _rc5_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -120,9 +120,9 @@ int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_ke
|
||||
@param skey The key as scheduled
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d,t,u, *K;
|
||||
@ -155,13 +155,15 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
|
||||
a += skey->rc6.K[42];
|
||||
c += skey->rc6.K[43];
|
||||
STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_rc6_ecb_encrypt(pt, ct, skey);
|
||||
int err = _rc6_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(ulong32) * 6 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -172,9 +174,9 @@ void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *
|
||||
@param skey The key as scheduled
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d,t,u, *K;
|
||||
@ -208,13 +210,16 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
|
||||
b -= skey->rc6.K[0];
|
||||
d -= skey->rc6.K[1];
|
||||
STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_rc6_ecb_decrypt(ct, pt, skey);
|
||||
int err = _rc6_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(ulong32) * 6 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -246,11 +246,11 @@ int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symme
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _safer_ecb_encrypt(const unsigned char *block_in,
|
||||
static int _safer_ecb_encrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void safer_ecb_encrypt(const unsigned char *block_in,
|
||||
int safer_ecb_encrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
@ -285,24 +285,26 @@ void safer_ecb_encrypt(const unsigned char *block_in,
|
||||
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
|
||||
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
|
||||
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void safer_ecb_encrypt(const unsigned char *block_in,
|
||||
int safer_ecb_encrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_safer_ecb_encrypt(block_in, block_out, skey);
|
||||
int err = _safer_ecb_encrypt(block_in, block_out, skey);
|
||||
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _safer_ecb_decrypt(const unsigned char *block_in,
|
||||
static int _safer_ecb_decrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void safer_ecb_decrypt(const unsigned char *block_in,
|
||||
int safer_ecb_decrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
@ -338,15 +340,17 @@ void safer_ecb_decrypt(const unsigned char *block_in,
|
||||
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
|
||||
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
|
||||
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void safer_ecb_decrypt(const unsigned char *block_in,
|
||||
int safer_ecb_decrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_safer_ecb_decrypt(block_in, block_out, skey);
|
||||
int err = _safer_ecb_decrypt(block_in, block_out, skey);
|
||||
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -329,8 +329,9 @@ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric
|
||||
@param pt The input plaintext (16 bytes)
|
||||
@param ct The output ciphertext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
unsigned char b[16];
|
||||
int x;
|
||||
@ -384,6 +385,7 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(b, sizeof(b));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -391,8 +393,9 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
|
||||
@param ct The input ciphertext (16 bytes)
|
||||
@param pt The output plaintext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
unsigned char b[16];
|
||||
int x;
|
||||
@ -446,6 +449,7 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(b, sizeof(b));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,11 +138,12 @@ static unsigned ig_func(unsigned w, int *kp, unsigned char *key)
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
unsigned w1,w2,w3,w4,tmp,tmp1;
|
||||
@ -183,13 +184,16 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
|
||||
ct[2] = (w2>>8)&255; ct[3] = w2&255;
|
||||
ct[4] = (w3>>8)&255; ct[5] = w3&255;
|
||||
ct[6] = (w4>>8)&255; ct[7] = w4&255;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_skipjack_ecb_encrypt(pt, ct, skey);
|
||||
int err = _skipjack_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -198,11 +202,12 @@ void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
unsigned w1,w2,w3,w4,tmp;
|
||||
@ -247,13 +252,16 @@ void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
|
||||
pt[2] = (w2>>8)&255; pt[3] = w2&255;
|
||||
pt[4] = (w3>>8)&255; pt[5] = w3&255;
|
||||
pt[6] = (w4>>8)&255; pt[7] = w4&255;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_skipjack_ecb_decrypt(ct, pt, skey);
|
||||
int err = _skipjack_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -465,11 +465,12 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
|
||||
@param pt The input plaintext (16 bytes)
|
||||
@param ct The output ciphertext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#else
|
||||
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
|
||||
@ -519,13 +520,16 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
|
||||
/* store output */
|
||||
STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
|
||||
STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
_twofish_ecb_encrypt(pt, ct, skey);
|
||||
int err = _twofish_ecb_encrypt(pt, ct, skey);
|
||||
burn_stack(sizeof(ulong32) * 10 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -534,11 +538,12 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
|
||||
@param ct The input ciphertext (16 bytes)
|
||||
@param pt The output plaintext (16 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#else
|
||||
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
|
||||
@ -591,13 +596,15 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
|
||||
/* store */
|
||||
STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
|
||||
STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
_twofish_ecb_decrypt(ct, pt, skey);
|
||||
int err =_twofish_ecb_decrypt(ct, pt, skey);
|
||||
burn_stack(sizeof(ulong32) * 10 + sizeof(int));
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -71,8 +71,9 @@ int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_k
|
||||
@param pt The input plaintext (8 bytes)
|
||||
@param ct The output ciphertext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
unsigned long y, z;
|
||||
int r;
|
||||
@ -98,6 +99,7 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
|
||||
}
|
||||
STORE32L(y, &ct[0]);
|
||||
STORE32L(z, &ct[4]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,8 +107,9 @@ void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key
|
||||
@param ct The input ciphertext (8 bytes)
|
||||
@param pt The output plaintext (8 bytes)
|
||||
@param skey The key as scheduled
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
unsigned long y, z;
|
||||
int r;
|
||||
@ -132,6 +135,7 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
|
||||
}
|
||||
STORE32L(y, &pt[0]);
|
||||
STORE32L(z, &pt[4]);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,7 @@
|
||||
@param cipher The index of the cipher desired
|
||||
@param key The secret key to use
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param uskey A previously scheduled key [optional can be NULL]
|
||||
@param nonce The session nonce [use once]
|
||||
@param noncelen The length of the nonce
|
||||
@param header The header for the session
|
||||
@ -36,6 +37,7 @@
|
||||
*/
|
||||
int ccm_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
@ -48,7 +50,9 @@ int ccm_memory(int cipher,
|
||||
int err;
|
||||
unsigned long len, L, x, y, z, CTRlen;
|
||||
|
||||
if (uskey == NULL) {
|
||||
LTC_ARGCHK(key != NULL);
|
||||
}
|
||||
LTC_ARGCHK(nonce != NULL);
|
||||
if (headerlen > 0) {
|
||||
LTC_ARGCHK(header != NULL);
|
||||
@ -85,15 +89,15 @@ int ccm_memory(int cipher,
|
||||
|
||||
/* is there an accelerator? */
|
||||
if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
|
||||
cipher_descriptor[cipher].accel_ccm_memory(
|
||||
return cipher_descriptor[cipher].accel_ccm_memory(
|
||||
key, keylen,
|
||||
uskey,
|
||||
nonce, noncelen,
|
||||
header, headerlen,
|
||||
pt, ptlen,
|
||||
ct,
|
||||
tag, taglen,
|
||||
direction);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* let's get the L value */
|
||||
@ -114,6 +118,7 @@ int ccm_memory(int cipher,
|
||||
}
|
||||
|
||||
/* allocate mem for the symmetric key */
|
||||
if (uskey == NULL) {
|
||||
skey = XMALLOC(sizeof(*skey));
|
||||
if (skey == NULL) {
|
||||
return CRYPT_MEM;
|
||||
@ -124,6 +129,9 @@ int ccm_memory(int cipher,
|
||||
XFREE(skey);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
skey = uskey;
|
||||
}
|
||||
|
||||
/* form B_0 == flags | Nonce N | l(m) */
|
||||
x = 0;
|
||||
@ -154,7 +162,9 @@ int ccm_memory(int cipher,
|
||||
}
|
||||
|
||||
/* encrypt PAD */
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* handle header */
|
||||
if (headerlen > 0) {
|
||||
@ -177,7 +187,9 @@ int ccm_memory(int cipher,
|
||||
for (y = 0; y < headerlen; y++) {
|
||||
if (x == 16) {
|
||||
/* full block so let's encrypt it */
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
PAD[x++] ^= header[y];
|
||||
@ -185,7 +197,9 @@ int ccm_memory(int cipher,
|
||||
|
||||
/* remainder? */
|
||||
if (x != 0) {
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,14 +233,18 @@ int ccm_memory(int cipher,
|
||||
ctr[z] = (ctr[z] + 1) & 255;
|
||||
if (ctr[z]) break;
|
||||
}
|
||||
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* xor the PT against the pad first */
|
||||
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
|
||||
*((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
|
||||
*((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
|
||||
}
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (; y < (ptlen & ~15); y += 16) {
|
||||
@ -235,14 +253,18 @@ int ccm_memory(int cipher,
|
||||
ctr[z] = (ctr[z] + 1) & 255;
|
||||
if (ctr[z]) break;
|
||||
}
|
||||
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* xor the PT against the pad last */
|
||||
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
|
||||
*((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z]));
|
||||
*((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z]));
|
||||
}
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -255,7 +277,9 @@ int ccm_memory(int cipher,
|
||||
ctr[z] = (ctr[z] + 1) & 255;
|
||||
if (ctr[z]) break;
|
||||
}
|
||||
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
CTRlen = 0;
|
||||
}
|
||||
|
||||
@ -269,21 +293,30 @@ int ccm_memory(int cipher,
|
||||
}
|
||||
|
||||
if (x == 16) {
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
PAD[x++] ^= b;
|
||||
}
|
||||
|
||||
if (x != 0) {
|
||||
cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* setup CTR for the TAG */
|
||||
ctr[14] = ctr[15] = 0x00;
|
||||
cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (skey != uskey) {
|
||||
cipher_descriptor[cipher].done(skey);
|
||||
}
|
||||
|
||||
/* store the TAG */
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
@ -296,10 +329,12 @@ int ccm_memory(int cipher,
|
||||
zeromem(PAD, sizeof(PAD));
|
||||
zeromem(CTRPAD, sizeof(CTRPAD));
|
||||
#endif
|
||||
|
||||
error:
|
||||
if (skey != uskey) {
|
||||
XFREE(skey);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -116,6 +116,7 @@ int ccm_test(void)
|
||||
unsigned long taglen, x;
|
||||
unsigned char buf[64], buf2[64], tag2[16], tag[16];
|
||||
int err, idx;
|
||||
symmetric_key skey;
|
||||
|
||||
idx = find_cipher("aes");
|
||||
if (idx == -1) {
|
||||
@ -127,8 +128,13 @@ int ccm_test(void)
|
||||
|
||||
for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
taglen = tests[x].taglen;
|
||||
if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = ccm_memory(idx,
|
||||
tests[x].key, 16,
|
||||
&skey,
|
||||
tests[x].nonce, tests[x].noncelen,
|
||||
tests[x].header, tests[x].headerlen,
|
||||
(unsigned char*)tests[x].pt, tests[x].ptlen,
|
||||
@ -146,6 +152,7 @@ int ccm_test(void)
|
||||
|
||||
if ((err = ccm_memory(idx,
|
||||
tests[x].key, 16,
|
||||
NULL,
|
||||
tests[x].nonce, tests[x].noncelen,
|
||||
tests[x].header, tests[x].headerlen,
|
||||
buf2, tests[x].ptlen,
|
||||
@ -160,8 +167,7 @@ int ccm_test(void)
|
||||
if (memcmp(tag2, tests[x].tag, tests[x].taglen)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
|
||||
cipher_descriptor[idx].done(&skey);
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
|
@ -62,7 +62,9 @@ int gcm_done(gcm_state *gcm,
|
||||
gcm_mult_h(gcm, gcm->X);
|
||||
|
||||
/* encrypt original counter */
|
||||
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K);
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < 16 && x < *taglen; x++) {
|
||||
tag[x] = gcm->buf[x] ^ gcm->X[x];
|
||||
}
|
||||
|
@ -98,7 +98,9 @@ int gcm_init(gcm_state *gcm, int cipher,
|
||||
|
||||
/* H = E(0) */
|
||||
zeromem(B, 16);
|
||||
cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* setup state */
|
||||
zeromem(gcm->buf, sizeof(gcm->buf));
|
||||
|
@ -51,6 +51,7 @@ int gcm_memory( int cipher,
|
||||
}
|
||||
|
||||
if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
|
||||
return
|
||||
cipher_descriptor[cipher].accel_gcm_memory
|
||||
(key, keylen,
|
||||
IV, IVlen,
|
||||
@ -59,7 +60,6 @@ int gcm_memory( int cipher,
|
||||
ct,
|
||||
tag, taglen,
|
||||
direction);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,7 +62,9 @@ int gcm_process(gcm_state *gcm,
|
||||
if (++gcm->Y[y]) { break; }
|
||||
}
|
||||
/* encrypt the counter */
|
||||
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
gcm->buflen = 0;
|
||||
gcm->mode = GCM_MODE_TEXT;
|
||||
@ -89,7 +91,9 @@ int gcm_process(gcm_state *gcm,
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y]) { break; }
|
||||
}
|
||||
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < (ptlen & ~15); x += 16) {
|
||||
@ -105,7 +109,9 @@ int gcm_process(gcm_state *gcm,
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y]) { break; }
|
||||
}
|
||||
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,7 +127,9 @@ int gcm_process(gcm_state *gcm,
|
||||
for (y = 15; y >= 12; y--) {
|
||||
if (++gcm->Y[y]) { break; }
|
||||
}
|
||||
cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K);
|
||||
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
gcm->buflen = 0;
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,9 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
tmp[x] = ct[x] ^ Z[x];
|
||||
}
|
||||
cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key);
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
pt[x] ^= Z[x];
|
||||
}
|
||||
|
@ -51,7 +51,9 @@ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
tmp[x] = pt[x] ^ Z[x];
|
||||
}
|
||||
cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key);
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ct[x] ^= Z[x];
|
||||
}
|
||||
|
@ -76,13 +76,17 @@ int ocb_init(ocb_state *ocb, int cipher,
|
||||
|
||||
/* find L = E[0] */
|
||||
zeromem(ocb->L, ocb->block_len);
|
||||
cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find R = E[N xor L] */
|
||||
for (x = 0; x < ocb->block_len; x++) {
|
||||
ocb->R[x] = ocb->L[x] ^ nonce[x];
|
||||
}
|
||||
cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find Ls[i] = L << i for i == 0..31 */
|
||||
XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);
|
||||
|
@ -84,7 +84,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
}
|
||||
|
||||
/* Y[m] = E(X[m])) */
|
||||
cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key);
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (mode == 1) {
|
||||
/* decrypt mode, so let's xor it first */
|
||||
@ -113,7 +115,9 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
}
|
||||
|
||||
/* encrypt checksum, er... tag!! */
|
||||
cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key);
|
||||
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
cipher_descriptor[ocb->cipher].done(&ocb->key);
|
||||
|
||||
/* now store it */
|
||||
@ -128,12 +132,12 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
zeromem(Z, MAXBLOCKSIZE);
|
||||
zeromem(ocb, sizeof(*ocb));
|
||||
#endif
|
||||
|
||||
error:
|
||||
XFREE(X);
|
||||
XFREE(Y);
|
||||
XFREE(Z);
|
||||
|
||||
return CRYPT_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,8 +16,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* version */
|
||||
#define CRYPT 0x0106
|
||||
#define SCRYPT "1.06"
|
||||
#define CRYPT 0x0107
|
||||
#define SCRYPT "1.07"
|
||||
|
||||
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
|
||||
#define MAXBLOCKSIZE 128
|
||||
|
@ -54,6 +54,14 @@ int XMEMCMP(const void *s1, const void *s2, size_t n);
|
||||
#define LTC_FAST_TYPE unsigned long
|
||||
#endif
|
||||
|
||||
/* detect PPC32 */
|
||||
#if defined(LTC_PPC32)
|
||||
#define ENDIAN_BIG
|
||||
#define ENDIAN_32BITWORD
|
||||
#define LTC_FAST
|
||||
#define LTC_FAST_TYPE unsigned long
|
||||
#endif
|
||||
|
||||
/* detect sparc and sparc64 */
|
||||
#if defined(__sparc__)
|
||||
#define ENDIAN_BIG
|
||||
|
@ -263,14 +263,16 @@ extern struct ltc_cipher_descriptor {
|
||||
@param pt The plaintext
|
||||
@param ct [out] The ciphertext
|
||||
@param skey The scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
/** Decrypt a block
|
||||
@param ct The ciphertext
|
||||
@param pt [out] The plaintext
|
||||
@param skey The scheduled key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
/** Test the block cipher
|
||||
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
|
||||
*/
|
||||
@ -293,16 +295,18 @@ extern struct ltc_cipher_descriptor {
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
|
||||
int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey);
|
||||
|
||||
/** Accelerated ECB decryption
|
||||
@param pt Plaintext
|
||||
@param ct Ciphertext
|
||||
@param blocks The number of complete blocks to process
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
|
||||
int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CBC encryption
|
||||
@param pt Plaintext
|
||||
@ -310,8 +314,9 @@ extern struct ltc_cipher_descriptor {
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
|
||||
int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CBC decryption
|
||||
@param pt Plaintext
|
||||
@ -319,8 +324,9 @@ extern struct ltc_cipher_descriptor {
|
||||
@param blocks The number of complete blocks to process
|
||||
@param IV The initial value (input/output)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
|
||||
int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CTR encryption
|
||||
@param pt Plaintext
|
||||
@ -329,12 +335,14 @@ extern struct ltc_cipher_descriptor {
|
||||
@param IV The initial value (input/output)
|
||||
@param mode little or big endian counter (mode=0 or mode=1)
|
||||
@param skey The scheduled key context
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
|
||||
int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey);
|
||||
|
||||
/** Accelerated CCM packet (one-shot)
|
||||
@param key The secret key to use
|
||||
@param keylen The length of the secret key (octets)
|
||||
@param uskey A previously scheduled key [optional can be NULL]
|
||||
@param nonce The session nonce [use once]
|
||||
@param noncelen The length of the nonce
|
||||
@param header The header for the session
|
||||
@ -347,8 +355,9 @@ extern struct ltc_cipher_descriptor {
|
||||
@param direction Encrypt or Decrypt direction (0 or 1)
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
void (*accel_ccm_memory)(
|
||||
int (*accel_ccm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
@ -369,8 +378,9 @@ extern struct ltc_cipher_descriptor {
|
||||
@param tag [out] The MAC tag
|
||||
@param taglen [in/out] The MAC tag length
|
||||
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
void (*accel_gcm_memory)(
|
||||
int (*accel_gcm_memory)(
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *IV, unsigned long IVlen,
|
||||
const unsigned char *adata, unsigned long adatalen,
|
||||
@ -382,8 +392,8 @@ extern struct ltc_cipher_descriptor {
|
||||
|
||||
#ifdef BLOWFISH
|
||||
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int blowfish_test(void);
|
||||
void blowfish_done(symmetric_key *skey);
|
||||
int blowfish_keysize(int *keysize);
|
||||
@ -392,8 +402,8 @@ extern const struct ltc_cipher_descriptor blowfish_desc;
|
||||
|
||||
#ifdef RC5
|
||||
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc5_test(void);
|
||||
void rc5_done(symmetric_key *skey);
|
||||
int rc5_keysize(int *keysize);
|
||||
@ -402,8 +412,8 @@ extern const struct ltc_cipher_descriptor rc5_desc;
|
||||
|
||||
#ifdef RC6
|
||||
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc6_test(void);
|
||||
void rc6_done(symmetric_key *skey);
|
||||
int rc6_keysize(int *keysize);
|
||||
@ -412,8 +422,8 @@ extern const struct ltc_cipher_descriptor rc6_desc;
|
||||
|
||||
#ifdef RC2
|
||||
int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rc2_test(void);
|
||||
void rc2_done(symmetric_key *skey);
|
||||
int rc2_keysize(int *keysize);
|
||||
@ -422,8 +432,8 @@ extern const struct ltc_cipher_descriptor rc2_desc;
|
||||
|
||||
#ifdef SAFERP
|
||||
int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int saferp_test(void);
|
||||
void saferp_done(symmetric_key *skey);
|
||||
int saferp_keysize(int *keysize);
|
||||
@ -435,8 +445,8 @@ int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmet
|
||||
int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
int safer_k64_test(void);
|
||||
int safer_sk64_test(void);
|
||||
int safer_sk128_test(void);
|
||||
@ -461,13 +471,13 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer
|
||||
#define aes_enc_keysize rijndael_enc_keysize
|
||||
|
||||
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int rijndael_test(void);
|
||||
void rijndael_done(symmetric_key *skey);
|
||||
int rijndael_keysize(int *keysize);
|
||||
int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void rijndael_enc_done(symmetric_key *skey);
|
||||
int rijndael_enc_keysize(int *keysize);
|
||||
extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
|
||||
@ -476,8 +486,8 @@ extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
|
||||
|
||||
#ifdef XTEA
|
||||
int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int xtea_test(void);
|
||||
void xtea_done(symmetric_key *skey);
|
||||
int xtea_keysize(int *keysize);
|
||||
@ -486,8 +496,8 @@ extern const struct ltc_cipher_descriptor xtea_desc;
|
||||
|
||||
#ifdef TWOFISH
|
||||
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int twofish_test(void);
|
||||
void twofish_done(symmetric_key *skey);
|
||||
int twofish_keysize(int *keysize);
|
||||
@ -496,14 +506,14 @@ extern const struct ltc_cipher_descriptor twofish_desc;
|
||||
|
||||
#ifdef DES
|
||||
int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int des_test(void);
|
||||
void des_done(symmetric_key *skey);
|
||||
int des_keysize(int *keysize);
|
||||
int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int des3_test(void);
|
||||
void des3_done(symmetric_key *skey);
|
||||
int des3_keysize(int *keysize);
|
||||
@ -512,8 +522,8 @@ extern const struct ltc_cipher_descriptor des_desc, des3_desc;
|
||||
|
||||
#ifdef CAST5
|
||||
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int cast5_test(void);
|
||||
void cast5_done(symmetric_key *skey);
|
||||
int cast5_keysize(int *keysize);
|
||||
@ -522,8 +532,8 @@ extern const struct ltc_cipher_descriptor cast5_desc;
|
||||
|
||||
#ifdef NOEKEON
|
||||
int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int noekeon_test(void);
|
||||
void noekeon_done(symmetric_key *skey);
|
||||
int noekeon_keysize(int *keysize);
|
||||
@ -532,8 +542,8 @@ extern const struct ltc_cipher_descriptor noekeon_desc;
|
||||
|
||||
#ifdef SKIPJACK
|
||||
int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int skipjack_test(void);
|
||||
void skipjack_done(symmetric_key *skey);
|
||||
int skipjack_keysize(int *keysize);
|
||||
@ -542,8 +552,8 @@ extern const struct ltc_cipher_descriptor skipjack_desc;
|
||||
|
||||
#ifdef KHAZAD
|
||||
int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int khazad_test(void);
|
||||
void khazad_done(symmetric_key *skey);
|
||||
int khazad_keysize(int *keysize);
|
||||
@ -552,8 +562,8 @@ extern const struct ltc_cipher_descriptor khazad_desc;
|
||||
|
||||
#ifdef ANUBIS
|
||||
int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
void anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
void anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
|
||||
int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
|
||||
int anubis_test(void);
|
||||
void anubis_done(symmetric_key *skey);
|
||||
int anubis_keysize(int *keysize);
|
||||
|
@ -186,6 +186,9 @@
|
||||
/* Include RSA support */
|
||||
#define MRSA
|
||||
|
||||
/* Include Katja (an Rabin variant like RSA) */
|
||||
// #define MKAT
|
||||
|
||||
/* Digital Signature Algorithm */
|
||||
#define MDSA
|
||||
/* Max diff between group and modulus size in bytes */
|
||||
@ -200,11 +203,13 @@
|
||||
/* #define LTC_ECC_TIMING_RESISTANT */
|
||||
|
||||
/* Supported ECC Key Sizes */
|
||||
#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,6 +245,8 @@
|
||||
|
||||
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
|
||||
#define LTC_MUTEX_TYPE(x) pthread_mutex_t x;
|
||||
#define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL);
|
||||
#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
|
||||
#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
|
||||
|
||||
@ -248,6 +255,8 @@
|
||||
/* default no functions */
|
||||
#define LTC_MUTEX_GLOBAL(x)
|
||||
#define LTC_MUTEX_PROTO(x)
|
||||
#define LTC_MUTEX_TYPE(x)
|
||||
#define LTC_MUTEX_INIT(x)
|
||||
#define LTC_MUTEX_LOCK(x)
|
||||
#define LTC_MUTEX_UNLOCK(x)
|
||||
|
||||
|
@ -200,6 +200,7 @@ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
|
||||
int ccm_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
symmetric_key *uskey,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
unsigned char *pt, unsigned long ptlen,
|
||||
|
@ -285,6 +285,50 @@ static inline unsigned RORc(unsigned word, const int i)
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined(LTC_PPC32)
|
||||
|
||||
static inline unsigned ROL(unsigned word, int i)
|
||||
{
|
||||
asm ("rotlw %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"r" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned ROR(unsigned word, int i)
|
||||
{
|
||||
asm ("rotlw %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"r" (32-i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#ifndef LTC_NO_ROLC
|
||||
|
||||
static inline unsigned ROLc(unsigned word, const int i)
|
||||
{
|
||||
asm ("rotlwi %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"I" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
static inline unsigned RORc(unsigned word, const int i)
|
||||
{
|
||||
asm ("rotrwi %0,%0,%2"
|
||||
:"=r" (word)
|
||||
:"0" (word),"I" (i));
|
||||
return word;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ROLc ROL
|
||||
#define RORc ROR
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* rotates the hard way */
|
||||
|
@ -11,6 +11,10 @@
|
||||
typedef void ecc_point;
|
||||
#endif
|
||||
|
||||
#ifndef MRSA
|
||||
typedef void rsa_key;
|
||||
#endif
|
||||
|
||||
/** math descriptor */
|
||||
typedef struct {
|
||||
/** Name of the math provider */
|
||||
@ -42,6 +46,13 @@ typedef struct {
|
||||
|
||||
/* ---- data movement ---- */
|
||||
|
||||
/** negate
|
||||
@param src The number to negate
|
||||
@param dst The destination
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int (*neg)(void *src, void *dst);
|
||||
|
||||
/** copy
|
||||
@param src The number to copy from
|
||||
@param dst The number to write to
|
||||
@ -339,11 +350,22 @@ typedef struct {
|
||||
|
||||
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
|
||||
|
||||
/** RSA Key Generation
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param size The size of the modulus (key size) desired (octets)
|
||||
@param e The "e" value (public key). e==65537 is a good choice
|
||||
@param key [out] Destination of a newly created private key pair
|
||||
@return CRYPT_OK if successful, upon error all allocated ram is freed
|
||||
*/
|
||||
int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key);
|
||||
|
||||
|
||||
/** RSA exponentiation
|
||||
@param in The octet array representing the base
|
||||
@param inlen The length of the input
|
||||
@param out The destination (to be stored in an octet array format)
|
||||
@param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus
|
||||
@param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus)
|
||||
@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
|
||||
@param key The RSA key to use
|
||||
@return CRYPT_OK on success
|
||||
@ -375,7 +397,9 @@ extern const ltc_math_descriptor tfm_desc;
|
||||
#define mp_init_multi ltc_init_multi
|
||||
#define mp_clear(a) ltc_mp.deinit(a)
|
||||
#define mp_clear_multi ltc_deinit_multi
|
||||
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
|
||||
|
||||
#define mp_neg(a, b) ltc_mp.neg(a, b)
|
||||
#define mp_copy(a, b) ltc_mp.copy(a, b)
|
||||
|
||||
#define mp_set(a, b) ltc_mp.set_int(a, b)
|
||||
|
@ -73,9 +73,70 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- Katja ---- */
|
||||
#ifdef MKAT
|
||||
|
||||
/* Min and Max KAT key sizes (in bits) */
|
||||
#define MIN_KAT_SIZE 1024
|
||||
#define MAX_KAT_SIZE 4096
|
||||
|
||||
/** Katja PKCS style key */
|
||||
typedef struct KAT_key {
|
||||
/** Type of key, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
/** The private exponent */
|
||||
void *d;
|
||||
/** The modulus */
|
||||
void *N;
|
||||
/** The p factor of N */
|
||||
void *p;
|
||||
/** The q factor of N */
|
||||
void *q;
|
||||
/** The 1/q mod p CRT param */
|
||||
void *qP;
|
||||
/** The d mod (p - 1) CRT param */
|
||||
void *dP;
|
||||
/** The d mod (q - 1) CRT param */
|
||||
void *dQ;
|
||||
/** The pq param */
|
||||
void *pq;
|
||||
} katja_key;
|
||||
|
||||
int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key);
|
||||
|
||||
int katja_exptmod(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int which,
|
||||
katja_key *key);
|
||||
|
||||
void katja_free(katja_key *key);
|
||||
|
||||
/* These use PKCS #1 v2.0 padding */
|
||||
int katja_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
prng_state *prng, int prng_idx, int hash_idx, katja_key *key);
|
||||
|
||||
int katja_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const unsigned char *lparam, unsigned long lparamlen,
|
||||
int hash_idx, int *stat,
|
||||
katja_key *key);
|
||||
|
||||
/* PKCS #1 import/export */
|
||||
int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key);
|
||||
int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- ECC Routines ---- */
|
||||
#ifdef MECC
|
||||
|
||||
/* size of our temp buffers for exported keys */
|
||||
#define ECC_BUF_SIZE 256
|
||||
|
||||
/* max private key size */
|
||||
#define ECC_MAXSIZE 66
|
||||
|
||||
/** Structure defines a NIST GF(p) curve */
|
||||
typedef struct {
|
||||
/** The size of the curve in octets */
|
||||
@ -104,8 +165,10 @@ typedef struct {
|
||||
typedef struct {
|
||||
/** The x co-ordinate */
|
||||
void *x;
|
||||
|
||||
/** The y co-ordinate */
|
||||
void *y;
|
||||
|
||||
/** The z co-ordinate */
|
||||
void *z;
|
||||
} ecc_point;
|
||||
@ -114,10 +177,13 @@ typedef struct {
|
||||
typedef struct {
|
||||
/** Type of key, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
|
||||
/** Index into the ltc_ecc_sets[] for the parameters of this curve */
|
||||
int idx;
|
||||
|
||||
/** The public key */
|
||||
ecc_point pubkey;
|
||||
|
||||
/** The private key */
|
||||
void *k;
|
||||
} ecc_key;
|
||||
@ -158,14 +224,19 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
/* low level functions */
|
||||
ecc_point *ltc_ecc_new_point(void);
|
||||
void ltc_ecc_del_point(ecc_point *p);
|
||||
int ltc_ecc_is_valid_idx(int n);
|
||||
|
||||
|
||||
/* point ops (mp == montgomery digit) */
|
||||
/* R = 2P */
|
||||
int ltc_ecc_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
|
||||
int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
|
||||
|
||||
/* R = P + Q */
|
||||
int ltc_ecc_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
|
||||
int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
|
||||
|
||||
/* R = kG */
|
||||
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
|
||||
|
||||
/* map P to affine from projective */
|
||||
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
|
||||
|
||||
@ -177,16 +248,22 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp);
|
||||
typedef struct {
|
||||
/** The key type, PK_PRIVATE or PK_PUBLIC */
|
||||
int type;
|
||||
|
||||
/** The order of the sub-group used in octets */
|
||||
int qord;
|
||||
|
||||
/** The generator */
|
||||
void *g;
|
||||
|
||||
/** The prime used to generate the sub-group */
|
||||
void *q;
|
||||
|
||||
/** The large prime that generats the field the contains the sub-group */
|
||||
void *p;
|
||||
|
||||
/** The private key */
|
||||
void *x;
|
||||
|
||||
/** The public key */
|
||||
void *y;
|
||||
} dsa_key;
|
||||
@ -194,7 +271,6 @@ typedef struct {
|
||||
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key);
|
||||
void dsa_free(dsa_key *key);
|
||||
|
||||
|
||||
int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
|
||||
void *r, void *s,
|
||||
prng_state *prng, int wprng, dsa_key *key);
|
||||
@ -211,12 +287,24 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dsa_key *key);
|
||||
|
||||
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dsa_key *key);
|
||||
|
||||
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
dsa_key *key);
|
||||
|
||||
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
|
||||
|
||||
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
|
||||
|
||||
int dsa_verify_key(dsa_key *key, int *stat);
|
||||
|
||||
|
||||
|
||||
int dsa_shared_secret(void *private_key, void *base,
|
||||
dsa_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
#ifdef LTC_DER
|
||||
@ -239,7 +327,7 @@ enum {
|
||||
};
|
||||
|
||||
/** A LTC ASN.1 list type */
|
||||
typedef struct {
|
||||
typedef struct ltc_asn1_list_ {
|
||||
/** The LTC ASN.1 enumerated type identifier */
|
||||
int type;
|
||||
/** The data to encode or place for decoding */
|
||||
@ -248,6 +336,8 @@ typedef struct {
|
||||
unsigned long size;
|
||||
/** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
|
||||
int used;
|
||||
/** prev/next entry in the list */
|
||||
struct ltc_asn1_list_ *prev, *next, *child, *parent;
|
||||
} ltc_asn1_list;
|
||||
|
||||
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
|
||||
@ -270,10 +360,16 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
|
||||
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned long *outlen);
|
||||
|
||||
/* VA list handy helpers */
|
||||
/* VA list handy helpers with triplets of <type, size, data> */
|
||||
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
|
||||
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
|
||||
|
||||
/* handle unknown list decoder */
|
||||
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
|
||||
void der_free_sequence_flexi(ltc_asn1_list *list);
|
||||
|
||||
void der_sequence_free(ltc_asn1_list *in);
|
||||
|
||||
/* INTEGER */
|
||||
int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen);
|
||||
int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num);
|
||||
|
@ -3,8 +3,8 @@
|
||||
/* ===> PKCS #1 -- RSA Cryptography <=== */
|
||||
#ifdef PKCS_1
|
||||
|
||||
int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
|
||||
int hash_idx,
|
||||
int pkcs_1_mgf1( int hash_idx,
|
||||
const unsigned char *seed, unsigned long seedlen,
|
||||
unsigned char *mask, unsigned long masklen);
|
||||
|
||||
int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out);
|
||||
|
@ -4,6 +4,7 @@ struct yarrow_prng {
|
||||
int cipher, hash;
|
||||
unsigned char pool[MAXBLOCKSIZE];
|
||||
symmetric_CTR ctr;
|
||||
LTC_MUTEX_TYPE(prng_lock)
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -28,6 +29,7 @@ struct fortuna_prng {
|
||||
wd;
|
||||
|
||||
ulong64 reset_cnt; /* number of times we have reset */
|
||||
LTC_MUTEX_TYPE(prng_lock)
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -61,7 +61,9 @@ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen)
|
||||
}
|
||||
|
||||
/* encrypt it */
|
||||
cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key);
|
||||
if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cipher_descriptor[omac->cipher_idx].done(&omac->key);
|
||||
|
||||
/* output it */
|
||||
|
@ -63,7 +63,9 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l
|
||||
|
||||
/* first calc L which is Ek(0) */
|
||||
zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
|
||||
cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* now do the mults, whoopy! */
|
||||
for (x = 0; x < 2; x++) {
|
||||
|
@ -49,7 +49,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
|
||||
*((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y]));
|
||||
}
|
||||
in += 16;
|
||||
cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key);
|
||||
if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
inlen -= x;
|
||||
}
|
||||
@ -61,7 +63,9 @@ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen)
|
||||
for (x = 0; x < (unsigned long)omac->blklen; x++) {
|
||||
omac->block[x] ^= omac->prev[x];
|
||||
}
|
||||
cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key);
|
||||
if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
omac->buflen = 0;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,9 @@ int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen)
|
||||
}
|
||||
|
||||
/* encrypt it */
|
||||
cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key);
|
||||
if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cipher_descriptor[state->cipher_idx].done(&state->key);
|
||||
|
||||
/* store it */
|
||||
|
@ -87,7 +87,9 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l
|
||||
|
||||
/* find L = E[0] */
|
||||
zeromem(L, pmac->block_len);
|
||||
cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key);
|
||||
if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* find Ls[i] = L << i for i == 0..31 */
|
||||
XMEMCPY(pmac->Ls[0], L, pmac->block_len);
|
||||
@ -127,14 +129,15 @@ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned l
|
||||
zeromem(pmac->block, sizeof(pmac->block));
|
||||
zeromem(pmac->Li, sizeof(pmac->Li));
|
||||
zeromem(pmac->checksum, sizeof(pmac->checksum));
|
||||
|
||||
err = CRYPT_OK;
|
||||
error:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(L, pmac->block_len);
|
||||
#endif
|
||||
|
||||
XFREE(L);
|
||||
|
||||
return CRYPT_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -50,7 +50,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y]));
|
||||
}
|
||||
cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key);
|
||||
if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
|
||||
*((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y]));
|
||||
}
|
||||
@ -67,7 +69,9 @@ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen)
|
||||
for (x = 0; x < (unsigned long)pmac->block_len; x++) {
|
||||
Z[x] = pmac->Li[x] ^ pmac->block[x];
|
||||
}
|
||||
cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key);
|
||||
if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (x = 0; x < (unsigned long)pmac->block_len; x++) {
|
||||
pmac->checksum[x] ^= Z[x];
|
||||
}
|
||||
|
@ -65,6 +65,13 @@ static void deinit(void *a)
|
||||
XFREE(a);
|
||||
}
|
||||
|
||||
static int neg(void *a, void *b)
|
||||
{
|
||||
LTC_ARGCHK(a != NULL);
|
||||
LTC_ARGCHK(b != NULL);
|
||||
return mpi_to_ltc_error(mp_neg(a, b));
|
||||
}
|
||||
|
||||
static int copy(void *a, void *b)
|
||||
{
|
||||
LTC_ARGCHK(a != NULL);
|
||||
@ -379,6 +386,7 @@ const ltc_math_descriptor ltm_desc = {
|
||||
&init_copy,
|
||||
&deinit,
|
||||
|
||||
&neg,
|
||||
©,
|
||||
|
||||
&set_int,
|
||||
@ -420,10 +428,11 @@ const ltc_math_descriptor ltm_desc = {
|
||||
&exptmod,
|
||||
&isprime,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
<c_ecc_mulmod,
|
||||
<c_ecc_projective_add_point,
|
||||
<c_ecc_map,
|
||||
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@ int ltc_init_multi(void **a, ...)
|
||||
va_end(clean_list);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
++np;
|
||||
cur = va_arg(args, void**);
|
||||
}
|
||||
va_end(args);
|
||||
|
@ -59,6 +59,14 @@ static void deinit(void *a)
|
||||
XFREE(a);
|
||||
}
|
||||
|
||||
static int neg(void *a, void *b)
|
||||
{
|
||||
LTC_ARGCHK(a != NULL);
|
||||
LTC_ARGCHK(b != NULL);
|
||||
fp_neg(((fp_int*)a), ((fp_int*)b));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static int copy(void *a, void *b)
|
||||
{
|
||||
LTC_ARGCHK(a != NULL);
|
||||
@ -390,6 +398,7 @@ const ltc_math_descriptor tfm_desc = {
|
||||
&init_copy,
|
||||
&deinit,
|
||||
|
||||
&neg,
|
||||
©,
|
||||
|
||||
&set_int,
|
||||
@ -431,10 +440,11 @@ const ltc_math_descriptor tfm_desc = {
|
||||
&exptmod,
|
||||
&isprime,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
<c_ecc_mulmod,
|
||||
<c_ecc_projective_add_point,
|
||||
<c_ecc_map,
|
||||
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -229,15 +229,18 @@ const char *crypt_build_settings =
|
||||
#if defined(MDSA)
|
||||
" DSA\n"
|
||||
#endif
|
||||
#if defined(MKAT)
|
||||
" Katja\n"
|
||||
#endif
|
||||
|
||||
"\nCompiler:\n"
|
||||
#if defined(WIN32)
|
||||
" WIN32 platform detected.\n"
|
||||
#endif
|
||||
#if defined(LBL_CYGWIN__)
|
||||
#if defined(__CYGWIN__)
|
||||
" CYGWIN Detected.\n"
|
||||
#endif
|
||||
#if defined(LBL_DJGPP__)
|
||||
#if defined(__DJGPP__)
|
||||
" DJGPP Detected.\n"
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
@ -249,9 +252,12 @@ const char *crypt_build_settings =
|
||||
#if defined(INTEL_CC)
|
||||
" Intel C Compiler detected.\n"
|
||||
#endif
|
||||
#if defined(LBL_x86_64__)
|
||||
#if defined(__x86_64__)
|
||||
" x86-64 detected.\n"
|
||||
#endif
|
||||
#if defined(LTC_PPC32)
|
||||
" LTC_PPC32 defined \n"
|
||||
#endif
|
||||
|
||||
"\nVarious others: "
|
||||
#if defined(BASE64)
|
||||
|
@ -59,11 +59,13 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
|
||||
#endif
|
||||
|
||||
if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
|
||||
cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
|
||||
return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
|
||||
} else {
|
||||
while (len) {
|
||||
/* decrypt */
|
||||
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
|
||||
if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* xor IV against plaintext */
|
||||
#if defined(LTC_FAST)
|
||||
|
@ -53,7 +53,7 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
#endif
|
||||
|
||||
if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
|
||||
cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
|
||||
return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
|
||||
} else {
|
||||
while (len) {
|
||||
/* xor IV against plaintext */
|
||||
@ -68,7 +68,9 @@ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
#endif
|
||||
|
||||
/* encrypt */
|
||||
cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key);
|
||||
if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* store IV [ciphertext] for a future block */
|
||||
#if defined(LTC_FAST)
|
||||
|
@ -45,7 +45,9 @@ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
|
||||
|
||||
while (len-- > 0) {
|
||||
if (cfb->padlen == cfb->blocklen) {
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
|
||||
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cfb->padlen = 0;
|
||||
}
|
||||
cfb->pad[cfb->padlen] = *ct;
|
||||
|
@ -45,7 +45,9 @@ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
|
||||
while (len-- > 0) {
|
||||
if (cfb->padlen == cfb->blocklen) {
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
|
||||
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cfb->padlen = 0;
|
||||
}
|
||||
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
|
||||
|
@ -40,9 +40,7 @@ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
|
||||
|
||||
/* force next block */
|
||||
cfb->padlen = 0;
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
|
||||
|
||||
return CRYPT_OK;
|
||||
return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -54,10 +54,8 @@ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
}
|
||||
|
||||
/* encrypt the IV */
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -52,7 +52,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
|
||||
/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
|
||||
if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
|
||||
cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key);
|
||||
if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
len %= ctr->blocklen;
|
||||
}
|
||||
|
||||
@ -79,7 +81,9 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
}
|
||||
|
||||
/* encrypt it */
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ctr->padlen = 0;
|
||||
}
|
||||
#ifdef LTC_FAST
|
||||
|
@ -45,9 +45,7 @@ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
|
||||
|
||||
/* force next block */
|
||||
ctr->padlen = 0;
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
|
||||
|
||||
return CRYPT_OK;
|
||||
return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -59,8 +59,7 @@ int ctr_start( int cipher,
|
||||
for (x = 0; x < ctr->blocklen; x++) {
|
||||
ctr->ctr[x] = IV[x];
|
||||
}
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
return CRYPT_OK;
|
||||
return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -40,10 +40,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, s
|
||||
|
||||
/* check for accel */
|
||||
if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
|
||||
cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
|
||||
return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
|
||||
} else {
|
||||
while (len) {
|
||||
cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
|
||||
if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
pt += cipher_descriptor[ecb->cipher].block_length;
|
||||
ct += cipher_descriptor[ecb->cipher].block_length;
|
||||
len -= cipher_descriptor[ecb->cipher].block_length;
|
||||
|
@ -40,10 +40,12 @@ int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
|
||||
/* check for accel */
|
||||
if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
|
||||
cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
|
||||
return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
|
||||
} else {
|
||||
while (len) {
|
||||
cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key);
|
||||
if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
pt += cipher_descriptor[ecb->cipher].block_length;
|
||||
ct += cipher_descriptor[ecb->cipher].block_length;
|
||||
len -= cipher_descriptor[ecb->cipher].block_length;
|
||||
|
@ -43,7 +43,9 @@ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
|
||||
|
||||
while (len-- > 0) {
|
||||
if (ofb->padlen == ofb->blocklen) {
|
||||
cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key);
|
||||
if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ofb->padlen = 0;
|
||||
}
|
||||
*ct++ = *pt++ ^ ofb->IV[ofb->padlen++];
|
||||
|
@ -41,8 +41,7 @@ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
|
||||
|
||||
/* force next block */
|
||||
ofb->padlen = 0;
|
||||
cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
|
||||
return CRYPT_OK;
|
||||
return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -51,7 +51,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
/* get the length of the data */
|
||||
if (in[x] & 0x80) {
|
||||
/* long format get number of length bytes */
|
||||
y = in[x++] & 127;
|
||||
y = in[x++] & 0x7F;
|
||||
|
||||
/* invalid if 0 or > 2 */
|
||||
if (y == 0 || y > 2) {
|
||||
@ -65,7 +65,7 @@ int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
}
|
||||
} else {
|
||||
/* short format */
|
||||
dlen = in[x++] & 127;
|
||||
dlen = in[x++] & 0x7F;
|
||||
}
|
||||
|
||||
/* is the data len too long or too short? */
|
||||
|
@ -96,6 +96,7 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
||||
case LTC_ASN1_NULL:
|
||||
if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
|
||||
*inlen = 2;
|
||||
list[x].used = 1;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
break;
|
||||
|
352
src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
Normal file
352
src/pk/asn1/der/sequence/der_decode_sequence_flexi.c
Normal file
@ -0,0 +1,352 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file der_decode_sequence_flexi.c
|
||||
ASN.1 DER, decode a SEQUENCE with a flexi parser, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
static unsigned long fetch_length(const unsigned char *in, unsigned long inlen)
|
||||
{
|
||||
unsigned long x, y, z;
|
||||
|
||||
y = 0;
|
||||
|
||||
/* skip type and read len */
|
||||
if (inlen < 2) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
++in; ++y;
|
||||
|
||||
/* read len */
|
||||
x = *in++; ++y;
|
||||
|
||||
/* <128 means literal */
|
||||
if (x < 128) {
|
||||
return x+y;
|
||||
}
|
||||
x &= 0x7F; /* the lower 7 bits are the length of the length */
|
||||
inlen -= 2;
|
||||
|
||||
/* len means len of len! */
|
||||
if (x == 0 || x > 4 || x > inlen) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
y += x;
|
||||
z = 0;
|
||||
while (x--) {
|
||||
z = (z<<8) | ((unsigned long)*in);
|
||||
++in;
|
||||
}
|
||||
return z+y;
|
||||
}
|
||||
|
||||
/**
|
||||
ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
|
||||
@param in The input buffer
|
||||
@param inlen [in/out] The length of the input buffer and on output the amount of decoded data
|
||||
@param out [out] A pointer to the linked list
|
||||
@return CRYPT_OK on success.
|
||||
*/
|
||||
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
|
||||
{
|
||||
ltc_asn1_list *l;
|
||||
unsigned long err, type, len, totlen, x, y;
|
||||
void *realloc_tmp;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
l = NULL;
|
||||
totlen = 0;
|
||||
|
||||
/* scan the input and and get lengths and what not */
|
||||
while (*inlen) {
|
||||
/* read the type byte */
|
||||
type = *in;
|
||||
|
||||
/* fetch length */
|
||||
len = fetch_length(in, *inlen);
|
||||
if (len > *inlen) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* alloc new link */
|
||||
if (l == NULL) {
|
||||
l = XCALLOC(1, sizeof(*l));
|
||||
if (l == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
l->next = XCALLOC(1, sizeof(*l));
|
||||
if (l->next == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
l->next->prev = l;
|
||||
l = l->next;
|
||||
}
|
||||
|
||||
/* now switch on type */
|
||||
switch (type) {
|
||||
case 0x02: /* INTEGER */
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_INTEGER;
|
||||
l->size = 1;
|
||||
if ((err = mp_init(&l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* decode field */
|
||||
if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* calc length of object */
|
||||
if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03: /* BIT */
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_BIT_STRING;
|
||||
l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04: /* OCTET */
|
||||
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_OCTET_STRING;
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x05: /* NULL */
|
||||
|
||||
/* valid NULL is 0x05 0x00 */
|
||||
if (in[0] != 0x05 || in[1] != 0x00) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* simple to store ;-) */
|
||||
l->type = LTC_ASN1_NULL;
|
||||
l->data = NULL;
|
||||
l->size = 0;
|
||||
len = 2;
|
||||
|
||||
break;
|
||||
|
||||
case 0x06: /* OID */
|
||||
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_OBJECT_IDENTIFIER;
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* resize it to save a bunch of mem */
|
||||
if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
|
||||
/* out of heap but this is not an error */
|
||||
break;
|
||||
}
|
||||
l->data = realloc_tmp;
|
||||
break;
|
||||
|
||||
|
||||
case 0x13: /* PRINTABLE */
|
||||
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_PRINTABLE_STRING;
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x16: /* IA5 */
|
||||
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_IA5_STRING;
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x17: /* UTC TIME */
|
||||
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_UTCTIME;
|
||||
l->size = 1;
|
||||
|
||||
if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
len = *inlen;
|
||||
if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x30: /* SEQUENCE */
|
||||
|
||||
/* init field */
|
||||
l->type = LTC_ASN1_SEQUENCE;
|
||||
|
||||
/* we have to decode the SEQUENCE header and get it's length */
|
||||
|
||||
/* move past type */
|
||||
++in; --(*inlen);
|
||||
|
||||
/* read length byte */
|
||||
x = *in++; --(*inlen);
|
||||
|
||||
/* smallest SEQUENCE header */
|
||||
y = 2;
|
||||
|
||||
/* now if it's > 127 the next bytes are the length of the length */
|
||||
if (x > 128) {
|
||||
x &= 0x7F;
|
||||
in += x;
|
||||
*inlen -= x;
|
||||
|
||||
/* update sequence header len */
|
||||
y += x;
|
||||
}
|
||||
|
||||
/* Sequence elements go as child */
|
||||
len = *inlen;
|
||||
if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* len update */
|
||||
totlen += y;
|
||||
|
||||
/* link them up y0 */
|
||||
l->child->parent = l;
|
||||
|
||||
break;
|
||||
default:
|
||||
/* invalid byte ... this is a soft error */
|
||||
/* remove link */
|
||||
l = l->prev;
|
||||
XFREE(l->next);
|
||||
l->next = NULL;
|
||||
goto outside;
|
||||
}
|
||||
|
||||
/* advance pointers */
|
||||
totlen += len;
|
||||
in += len;
|
||||
*inlen -= len;
|
||||
}
|
||||
|
||||
outside:
|
||||
|
||||
/* rewind l please */
|
||||
while (l->prev != NULL || l->parent != NULL) {
|
||||
if (l->parent != NULL) {
|
||||
l = l->parent;
|
||||
} else {
|
||||
l = l->prev;
|
||||
}
|
||||
}
|
||||
|
||||
/* return */
|
||||
*out = l;
|
||||
*inlen = totlen;
|
||||
return CRYPT_OK;
|
||||
|
||||
error:
|
||||
/* free list */
|
||||
der_sequence_free(l);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
@ -101,6 +101,13 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTCTIME:
|
||||
if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
y += x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
|
63
src/pk/asn1/der/sequence/der_sequence_free.c
Normal file
63
src/pk/asn1/der/sequence/der_sequence_free.c
Normal file
@ -0,0 +1,63 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file der_sequence_free.c
|
||||
ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Free memory allocated by der_decode_sequence_flexi()
|
||||
@param in The list to free
|
||||
*/
|
||||
void der_sequence_free(ltc_asn1_list *in)
|
||||
{
|
||||
ltc_asn1_list *l;
|
||||
|
||||
/* walk to the start of the chain */
|
||||
while (in->prev != NULL || in->parent != NULL) {
|
||||
if (in->parent != NULL) {
|
||||
in = in->parent;
|
||||
} else {
|
||||
in = in->prev;
|
||||
}
|
||||
}
|
||||
|
||||
/* now walk the list and free stuff */
|
||||
while (in != NULL) {
|
||||
/* is there a child? */
|
||||
if (in->child) {
|
||||
/* disconnect */
|
||||
in->child->parent = NULL;
|
||||
der_sequence_free(in->child);
|
||||
}
|
||||
|
||||
switch (in->type) {
|
||||
case LTC_ASN1_SEQUENCE: break;
|
||||
case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
|
||||
default : if (in->data != NULL) { XFREE(in->data); }
|
||||
}
|
||||
|
||||
/* move to next and free current */
|
||||
l = in->next;
|
||||
free(in);
|
||||
in = l;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
138
src/pk/dsa/dsa_decrypt_key.c
Normal file
138
src/pk/dsa/dsa_decrypt_key.c
Normal file
@ -0,0 +1,138 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file dsa_decrypt_key.c
|
||||
DSA Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Decrypt an DSA encrypted key
|
||||
@param in The ciphertext
|
||||
@param inlen The length of the ciphertext (octets)
|
||||
@param out [out] The plaintext
|
||||
@param outlen [in/out] The max size and resulting size of the plaintext
|
||||
@param key The corresponding private DSA key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
dsa_key *key)
|
||||
{
|
||||
unsigned char *skey, *expt;
|
||||
void *g_pub;
|
||||
unsigned long x, y, hashOID[32];
|
||||
int hash, err;
|
||||
ltc_asn1_list decode[3];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* decode to find out hash */
|
||||
LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
|
||||
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
hash = find_hash_oid(hashOID, decode[0].size);
|
||||
if (hash_is_valid(hash) != CRYPT_OK) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* we now have the hash! */
|
||||
|
||||
if ((err = mp_init(&g_pub)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* allocate memory */
|
||||
expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (expt == NULL || skey == NULL) {
|
||||
if (expt != NULL) {
|
||||
XFREE(expt);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
mp_clear(g_pub);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL);
|
||||
LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
|
||||
|
||||
/* read the structure in now */
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make shared key */
|
||||
x = mp_unsigned_bin_size(key->p) + 1;
|
||||
if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE);
|
||||
if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* ensure the hash of the shared secret is at least as big as the encrypt itself */
|
||||
if (decode[2].size > y) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* avoid buffer overflow */
|
||||
if (*outlen < decode[2].size) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Decrypt the key */
|
||||
for (x = 0; x < decode[2].size; x++) {
|
||||
out[x] = expt[x] ^ skey[x];
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(expt, mp_unsigned_bin_size(key->p) + 1);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(expt);
|
||||
XFREE(skey);
|
||||
|
||||
mp_clear(g_pub);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
136
src/pk/dsa/dsa_encrypt_key.c
Normal file
136
src/pk/dsa/dsa_encrypt_key.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file dsa_encrypt_key.c
|
||||
DSA Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MDSA
|
||||
|
||||
/**
|
||||
Encrypt a symmetric key with DSA
|
||||
@param in The symmetric key you want to encrypt
|
||||
@param inlen The length of the key to encrypt (octets)
|
||||
@param out [out] The destination for the ciphertext
|
||||
@param outlen [in/out] The max size and resulting size of the ciphertext
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param hash The index of the hash you want to use
|
||||
@param key The DSA key you want to encrypt to
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dsa_key *key)
|
||||
{
|
||||
unsigned char *expt, *skey;
|
||||
void *g_pub, *g_priv;
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (inlen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (expt == NULL || skey == NULL) {
|
||||
if (expt != NULL) {
|
||||
XFREE(expt);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
mp_clear_multi(g_pub, g_priv, NULL);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* make a random x, g^x pair */
|
||||
x = mp_unsigned_bin_size(key->q);
|
||||
if (prng_descriptor[wprng].read(expt, x, prng) != x) {
|
||||
err = CRYPT_ERROR_READPRNG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* load x */
|
||||
if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* compute y */
|
||||
if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
x = mp_unsigned_bin_size(key->p) + 1;
|
||||
if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
y = MAXBLOCKSIZE;
|
||||
if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Encrypt key */
|
||||
for (x = 0; x < inlen; x++) {
|
||||
skey[x] ^= in[x];
|
||||
}
|
||||
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
|
||||
LTC_ASN1_INTEGER, 1UL, g_pub,
|
||||
LTC_ASN1_OCTET_STRING, inlen, skey,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(expt, mp_unsigned_bin_size(key->p) + 1);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(skey);
|
||||
XFREE(expt);
|
||||
|
||||
mp_clear_multi(g_pub, g_priv, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
@ -31,6 +31,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* init key */
|
||||
if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
|
||||
|
@ -33,6 +33,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
|
||||
unsigned char *buf;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* check prng */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
|
71
src/pk/dsa/dsa_shared_secret.c
Normal file
71
src/pk/dsa/dsa_shared_secret.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file dsa_shared_secret.c
|
||||
DSA Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MDSA
|
||||
|
||||
/**
|
||||
Create a DSA shared secret between two keys
|
||||
@param private_key The private DSA key (the exponent)
|
||||
@param base The base of the exponentiation (allows this to be used for both encrypt and decrypt)
|
||||
@param public_key The public key
|
||||
@param out [out] Destination of the shared secret
|
||||
@param outlen [in/out] The max size and resulting size of the shared secret
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_shared_secret(void *private_key, void *base,
|
||||
dsa_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x;
|
||||
void *res;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(private_key != NULL);
|
||||
LTC_ARGCHK(public_key != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* make new point */
|
||||
if ((err = mp_init(&res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) {
|
||||
mp_clear(res);
|
||||
return err;
|
||||
}
|
||||
|
||||
x = (unsigned long)mp_unsigned_bin_size(res);
|
||||
if (*outlen < x) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
zeromem(out, x);
|
||||
if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; }
|
||||
|
||||
err = CRYPT_OK;
|
||||
*outlen = x;
|
||||
done:
|
||||
mp_clear(res);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
1065
src/pk/ecc/ecc.c
1065
src/pk/ecc/ecc.c
File diff suppressed because it is too large
Load Diff
149
src/pk/ecc/ecc_decrypt_key.c
Normal file
149
src/pk/ecc/ecc_decrypt_key.c
Normal file
@ -0,0 +1,149 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_decrypt_key.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Decrypt an ECC encrypted key
|
||||
@param in The ciphertext
|
||||
@param inlen The length of the ciphertext (octets)
|
||||
@param out [out] The plaintext
|
||||
@param outlen [in/out] The max size and resulting size of the plaintext
|
||||
@param key The corresponding private ECC key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char *ecc_shared, *skey, *pub_expt;
|
||||
unsigned long x, y, hashOID[32];
|
||||
int hash, err;
|
||||
ecc_key pubkey;
|
||||
ltc_asn1_list decode[3];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* decode to find out hash */
|
||||
LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
|
||||
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
hash = find_hash_oid(hashOID, decode[0].size);
|
||||
if (hash_is_valid(hash) != CRYPT_OK) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* we now have the hash! */
|
||||
|
||||
/* allocate memory */
|
||||
pub_expt = XMALLOC(ECC_BUF_SIZE);
|
||||
ecc_shared = XMALLOC(ECC_BUF_SIZE);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
|
||||
if (pub_expt != NULL) {
|
||||
XFREE(pub_expt);
|
||||
}
|
||||
if (ecc_shared != NULL) {
|
||||
XFREE(ecc_shared);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE);
|
||||
LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
|
||||
|
||||
/* read the structure in now */
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* import ECC key from packet */
|
||||
if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make shared key */
|
||||
x = ECC_BUF_SIZE;
|
||||
if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
|
||||
y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE);
|
||||
if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* ensure the hash of the shared secret is at least as big as the encrypt itself */
|
||||
if (decode[2].size > y) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* avoid buffer overflow */
|
||||
if (*outlen < decode[2].size) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Decrypt the key */
|
||||
for (x = 0; x < decode[2].size; x++) {
|
||||
out[x] = skey[x] ^ ecc_shared[x];
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(pub_expt, ECC_BUF_SIZE);
|
||||
zeromem(ecc_shared, ECC_BUF_SIZE);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(pub_expt);
|
||||
XFREE(ecc_shared);
|
||||
XFREE(skey);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
136
src/pk/ecc/ecc_encrypt_key.c
Normal file
136
src/pk/ecc/ecc_encrypt_key.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_encrypt_key.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Encrypt a symmetric key with ECC
|
||||
@param in The symmetric key you want to encrypt
|
||||
@param inlen The length of the key to encrypt (octets)
|
||||
@param out [out] The destination for the ciphertext
|
||||
@param outlen [in/out] The max size and resulting size of the ciphertext
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param hash The index of the hash you want to use
|
||||
@param key The ECC key you want to encrypt to
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char *pub_expt, *ecc_shared, *skey;
|
||||
ecc_key pubkey;
|
||||
unsigned long x, y, pubkeysize;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (inlen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pub_expt = XMALLOC(ECC_BUF_SIZE);
|
||||
ecc_shared = XMALLOC(ECC_BUF_SIZE);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
|
||||
if (pub_expt != NULL) {
|
||||
XFREE(pub_expt);
|
||||
}
|
||||
if (ecc_shared != NULL) {
|
||||
XFREE(ecc_shared);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
pubkeysize = ECC_BUF_SIZE;
|
||||
if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
x = ECC_BUF_SIZE;
|
||||
if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
y = MAXBLOCKSIZE;
|
||||
if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Encrypt key */
|
||||
for (x = 0; x < inlen; x++) {
|
||||
skey[x] ^= in[x];
|
||||
}
|
||||
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
|
||||
LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt,
|
||||
LTC_ASN1_OCTET_STRING, inlen, skey,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, ECC_BUF_SIZE);
|
||||
zeromem(ecc_shared, ECC_BUF_SIZE);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(skey);
|
||||
XFREE(ecc_shared);
|
||||
XFREE(pub_expt);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
82
src/pk/ecc/ecc_export.c
Normal file
82
src/pk/ecc/ecc_export.c
Normal file
@ -0,0 +1,82 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_export.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Export an ECC key as a binary packet
|
||||
@param out [out] Destination for the key
|
||||
@param outlen [in/out] Max size and resulting size of the exported key
|
||||
@param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
|
||||
@param key The key to export
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
|
||||
{
|
||||
int err;
|
||||
unsigned char flags[1];
|
||||
unsigned long key_size;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* type valid? */
|
||||
if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
if (ltc_ecc_is_valid_idx(key->idx) == 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* we store the NIST byte size */
|
||||
key_size = ltc_ecc_sets[key->idx].size;
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
flags[0] = 1;
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
|
||||
LTC_ASN1_INTEGER, 1UL, key->k,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
} else {
|
||||
flags[0] = 0;
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
40
src/pk/ecc/ecc_free.c
Normal file
40
src/pk/ecc/ecc_free.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_free.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Free an ECC key from memory
|
||||
@param key The key you wish to free
|
||||
*/
|
||||
void ecc_free(ecc_key *key)
|
||||
{
|
||||
LTC_ARGCHK(key != NULL);
|
||||
mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
44
src/pk/ecc/ecc_get_size.c
Normal file
44
src/pk/ecc/ecc_get_size.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_get_size.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Get the size of an ECC key
|
||||
@param key The key to get the size of
|
||||
@return The size (octets) of the key or INT_MAX on error
|
||||
*/
|
||||
int ecc_get_size(ecc_key *key)
|
||||
{
|
||||
LTC_ARGCHK(key != NULL);
|
||||
if (ltc_ecc_is_valid_idx(key->idx))
|
||||
return ltc_ecc_sets[key->idx].size;
|
||||
else
|
||||
return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
155
src/pk/ecc/ecc_import.c
Normal file
155
src/pk/ecc/ecc_import.c
Normal file
@ -0,0 +1,155 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_import.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
static int is_point(ecc_key *key)
|
||||
{
|
||||
void *prime, *b, *t1, *t2;
|
||||
int err;
|
||||
|
||||
if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* load prime and b */
|
||||
if ((err = mp_read_radix(prime, ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_read_radix(b, ltc_ecc_sets[key->idx].B, 64)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* compute y^2 */
|
||||
if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* compute x^3 */
|
||||
if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* compute y^2 - x^3 */
|
||||
if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* compute y^2 - x^3 + 3x */
|
||||
if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
|
||||
while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
|
||||
if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
|
||||
}
|
||||
while (mp_cmp(t1, prime) != LTC_MP_LT) {
|
||||
if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
|
||||
}
|
||||
|
||||
/* compare to b */
|
||||
if (mp_cmp(t1, b) != LTC_MP_EQ) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
mp_clear_multi(prime, b, t1, t2, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Import an ECC key from a binary packet
|
||||
@param in The packet to import
|
||||
@param inlen The length of the packet
|
||||
@param key [out] The destination of the import
|
||||
@return CRYPT_OK if successful, upon error all allocated memory will be freed
|
||||
*/
|
||||
int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
|
||||
{
|
||||
unsigned long key_size;
|
||||
unsigned char flags[1];
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* init key */
|
||||
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* find out what type of key it is */
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, &flags,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (flags[0] == 1) {
|
||||
/* private key */
|
||||
key->type = PK_PRIVATE;
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
|
||||
LTC_ASN1_INTEGER, 1UL, key->k,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
/* public key */
|
||||
key->type = PK_PUBLIC;
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &key_size,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.x,
|
||||
LTC_ASN1_INTEGER, 1UL, key->pubkey.y,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* find the idx */
|
||||
for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx);
|
||||
if (ltc_ecc_sets[key->idx].size == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* set z */
|
||||
mp_set(key->pubkey.z, 1);
|
||||
|
||||
/* is it a point on the curve? */
|
||||
if ((err = is_point(key)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* we're good */
|
||||
return CRYPT_OK;
|
||||
done:
|
||||
mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
112
src/pk/ecc/ecc_make_key.c
Normal file
112
src/pk/ecc/ecc_make_key.c
Normal file
@ -0,0 +1,112 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_make_key.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Make a new ECC key
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param keysize The keysize for the new key (in octets from 20 to 65 bytes)
|
||||
@param key [out] Destination of the newly created key
|
||||
@return CRYPT_OK if successful, upon error all allocated memory will be freed
|
||||
*/
|
||||
int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
|
||||
{
|
||||
int x, err;
|
||||
ecc_point *base;
|
||||
void *prime;
|
||||
unsigned char *buf;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* good prng? */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find key size */
|
||||
for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++);
|
||||
keysize = ltc_ecc_sets[x].size;
|
||||
|
||||
if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
key->idx = x;
|
||||
|
||||
/* allocate ram */
|
||||
base = NULL;
|
||||
buf = XMALLOC(ECC_MAXSIZE);
|
||||
if (buf == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* make up random string */
|
||||
if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
|
||||
err = CRYPT_ERROR_READPRNG;
|
||||
goto LBL_ERR2;
|
||||
}
|
||||
|
||||
/* setup the key variables */
|
||||
if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, NULL)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
base = ltc_ecc_new_point();
|
||||
if (base == NULL) {
|
||||
mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, NULL);
|
||||
err = CRYPT_MEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* read in the specs for this key */
|
||||
if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_read_radix(base->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_read_radix(base->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK) { goto done; }
|
||||
mp_set(base->z, 1);
|
||||
if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* make the public key */
|
||||
if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto done; }
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
/* free up ram */
|
||||
err = CRYPT_OK;
|
||||
done:
|
||||
ltc_ecc_del_point(base);
|
||||
mp_clear(prime);
|
||||
LBL_ERR2:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(buf, ECC_MAXSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
94
src/pk/ecc/ecc_shared_secret.c
Normal file
94
src/pk/ecc/ecc_shared_secret.c
Normal file
@ -0,0 +1,94 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_shared_secret.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Create an ECC shared secret between two keys
|
||||
@param private_key The private ECC key
|
||||
@param public_key The public key
|
||||
@param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63)
|
||||
@param outlen [in/out] The max size and resulting size of the shared secret
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x;
|
||||
ecc_point *result;
|
||||
void *prime;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(private_key != NULL);
|
||||
LTC_ARGCHK(public_key != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* type valid? */
|
||||
if (private_key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if (ltc_ecc_is_valid_idx(private_key->idx) == 0) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (private_key->idx != public_key->idx) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* make new point */
|
||||
result = ltc_ecc_new_point();
|
||||
if (result == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = mp_init(&prime)) != CRYPT_OK) {
|
||||
ltc_ecc_del_point(result);
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = mp_read_radix(prime, (char *)ltc_ecc_sets[private_key->idx].prime, 64)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; }
|
||||
|
||||
x = (unsigned long)mp_unsigned_bin_size(prime);
|
||||
if (*outlen < x) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
zeromem(out, x);
|
||||
if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; }
|
||||
|
||||
err = CRYPT_OK;
|
||||
*outlen = x;
|
||||
done:
|
||||
mp_clear(prime);
|
||||
ltc_ecc_del_point(result);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
118
src/pk/ecc/ecc_sign_hash.c
Normal file
118
src/pk/ecc/ecc_sign_hash.c
Normal file
@ -0,0 +1,118 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_sign_hash.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Sign a message digest
|
||||
@param in The message digest to sign
|
||||
@param inlen The length of the digest
|
||||
@param out [out] The destination for the signature
|
||||
@param outlen [in/out] The max size and resulting size of the signature
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param key A private ECC key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key)
|
||||
{
|
||||
ecc_key pubkey;
|
||||
void *r, *s, *e, *p;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* is this a private key? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is the IDX valid ? */
|
||||
if (ltc_ecc_is_valid_idx(key->idx) != 1) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* get the hash and load it as a bignum into 'e' */
|
||||
/* init the bignums */
|
||||
if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* make up a key and export the public copy */
|
||||
for (;;) {
|
||||
if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find r = x1 mod n */
|
||||
if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; }
|
||||
|
||||
if (mp_iszero(r)) {
|
||||
ecc_free(&pubkey);
|
||||
} else {
|
||||
/* find s = (e + xr)/k */
|
||||
if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */
|
||||
if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */
|
||||
if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
|
||||
if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
|
||||
if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */
|
||||
|
||||
if (mp_iszero(s)) {
|
||||
ecc_free(&pubkey);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* store as SEQUENCE { r, s -- integer } */
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_INTEGER, 1UL, r,
|
||||
LTC_ASN1_INTEGER, 1UL, s,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
goto LBL_ERR;
|
||||
error:
|
||||
LBL_ERR:
|
||||
mp_clear_multi(r, s, p, e, NULL);
|
||||
ecc_free(&pubkey);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
48
src/pk/ecc/ecc_sizes.c
Normal file
48
src/pk/ecc/ecc_sizes.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_sizes.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
void ecc_sizes(int *low, int *high)
|
||||
{
|
||||
int i;
|
||||
LTC_ARGCHK(low != NULL);
|
||||
LTC_ARGCHK(high != NULL);
|
||||
|
||||
*low = INT_MAX;
|
||||
*high = 0;
|
||||
for (i = 0; ltc_ecc_sets[i].size != 0; i++) {
|
||||
if (ltc_ecc_sets[i].size < *low) {
|
||||
*low = ltc_ecc_sets[i].size;
|
||||
}
|
||||
if (ltc_ecc_sets[i].size > *high) {
|
||||
*high = ltc_ecc_sets[i].size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
@ -1,472 +0,0 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/**
|
||||
@file ecc_sys.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
/**
|
||||
Encrypt a symmetric key with ECC
|
||||
@param in The symmetric key you want to encrypt
|
||||
@param inlen The length of the key to encrypt (octets)
|
||||
@param out [out] The destination for the ciphertext
|
||||
@param outlen [in/out] The max size and resulting size of the ciphertext
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param hash The index of the hash you want to use
|
||||
@param key The ECC key you want to encrypt to
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char *pub_expt, *ecc_shared, *skey;
|
||||
ecc_key pubkey;
|
||||
unsigned long x, y, pubkeysize;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (inlen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pub_expt = XMALLOC(ECC_BUF_SIZE);
|
||||
ecc_shared = XMALLOC(ECC_BUF_SIZE);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
|
||||
if (pub_expt != NULL) {
|
||||
XFREE(pub_expt);
|
||||
}
|
||||
if (ecc_shared != NULL) {
|
||||
XFREE(ecc_shared);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
pubkeysize = ECC_BUF_SIZE;
|
||||
if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
x = ECC_BUF_SIZE;
|
||||
if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
y = MAXBLOCKSIZE;
|
||||
if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Encrypt key */
|
||||
for (x = 0; x < inlen; x++) {
|
||||
skey[x] ^= in[x];
|
||||
}
|
||||
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
|
||||
LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt,
|
||||
LTC_ASN1_OCTET_STRING, inlen, skey,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, ECC_BUF_SIZE);
|
||||
zeromem(ecc_shared, ECC_BUF_SIZE);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(skey);
|
||||
XFREE(ecc_shared);
|
||||
XFREE(pub_expt);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Decrypt an ECC encrypted key
|
||||
@param in The ciphertext
|
||||
@param inlen The length of the ciphertext (octets)
|
||||
@param out [out] The plaintext
|
||||
@param outlen [in/out] The max size and resulting size of the plaintext
|
||||
@param key The corresponding private ECC key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char *ecc_shared, *skey, *pub_expt;
|
||||
unsigned long x, y, hashOID[32];
|
||||
int hash, err;
|
||||
ecc_key pubkey;
|
||||
ltc_asn1_list decode[3];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* decode to find out hash */
|
||||
LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
|
||||
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
for (hash = 0; hash_descriptor[hash].name != NULL &&
|
||||
(hash_descriptor[hash].OIDlen != decode[0].size ||
|
||||
memcmp(hash_descriptor[hash].OID, hashOID, sizeof(unsigned long)*decode[0].size)); hash++);
|
||||
|
||||
if (hash_descriptor[hash].name == NULL) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* we now have the hash! */
|
||||
|
||||
/* allocate memory */
|
||||
pub_expt = XMALLOC(ECC_BUF_SIZE);
|
||||
ecc_shared = XMALLOC(ECC_BUF_SIZE);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) {
|
||||
if (pub_expt != NULL) {
|
||||
XFREE(pub_expt);
|
||||
}
|
||||
if (ecc_shared != NULL) {
|
||||
XFREE(ecc_shared);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE);
|
||||
LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
|
||||
|
||||
/* read the structure in now */
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* import ECC key from packet */
|
||||
if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make shared key */
|
||||
x = ECC_BUF_SIZE;
|
||||
if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
|
||||
y = MAXBLOCKSIZE;
|
||||
if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* ensure the hash of the shared secret is at least as big as the encrypt itself */
|
||||
if (decode[2].size > y) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* avoid buffer overflow */
|
||||
if (*outlen < decode[2].size) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Decrypt the key */
|
||||
for (x = 0; x < decode[2].size; x++) {
|
||||
out[x] = skey[x] ^ ecc_shared[x];
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(pub_expt, ECC_BUF_SIZE);
|
||||
zeromem(ecc_shared, ECC_BUF_SIZE);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(pub_expt);
|
||||
XFREE(ecc_shared);
|
||||
XFREE(skey);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Sign a message digest
|
||||
@param in The message digest to sign
|
||||
@param inlen The length of the digest
|
||||
@param out [out] The destination for the signature
|
||||
@param outlen [in/out] The max size and resulting size of the signature
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param key A private ECC key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key)
|
||||
{
|
||||
ecc_key pubkey;
|
||||
void *r, *s, *e, *p;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* is this a private key? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is the IDX valid ? */
|
||||
if (is_valid_idx(key->idx) != 1) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* get the hash and load it as a bignum into 'e' */
|
||||
/* init the bignums */
|
||||
if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* make up a key and export the public copy */
|
||||
for (;;) {
|
||||
if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find r = x1 mod n */
|
||||
if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; }
|
||||
|
||||
if (mp_iszero(r)) {
|
||||
ecc_free(&pubkey);
|
||||
} else {
|
||||
/* find s = (e + xr)/k */
|
||||
if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */
|
||||
if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */
|
||||
if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
|
||||
if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */
|
||||
if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */
|
||||
|
||||
if (mp_iszero(s)) {
|
||||
ecc_free(&pubkey);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* store as SEQUENCE { r, s -- integer } */
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_INTEGER, 1UL, r,
|
||||
LTC_ASN1_INTEGER, 1UL, s,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
goto LBL_ERR;
|
||||
error:
|
||||
LBL_ERR:
|
||||
mp_clear_multi(r, s, p, e, NULL);
|
||||
ecc_free(&pubkey);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* verify
|
||||
*
|
||||
* w = s^-1 mod n
|
||||
* u1 = xw
|
||||
* u2 = rw
|
||||
* X = u1*G + u2*Q
|
||||
* v = X_x1 mod n
|
||||
* accept if v == r
|
||||
*/
|
||||
|
||||
/**
|
||||
Verify an ECC signature
|
||||
@param sig The signature to verify
|
||||
@param siglen The length of the signature (octets)
|
||||
@param hash The hash (message digest) that was signed
|
||||
@param hashlen The length of the hash (octets)
|
||||
@param stat Result of signature, 1==valid, 0==invalid
|
||||
@param key The corresponding public ECC key
|
||||
@return CRYPT_OK if successful (even if the signature is not valid)
|
||||
*/
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, ecc_key *key)
|
||||
{
|
||||
ecc_point *mG, *mQ;
|
||||
void *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
|
||||
void *mp;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(sig != NULL);
|
||||
LTC_ARGCHK(hash != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
mp = NULL;
|
||||
|
||||
/* is the IDX valid ? */
|
||||
if (is_valid_idx(key->idx) != 1) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
/* allocate ints */
|
||||
if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* allocate points */
|
||||
mG = ltc_ecc_new_point();
|
||||
mQ = ltc_ecc_new_point();
|
||||
if (mQ == NULL || mG == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* parse header */
|
||||
if ((err = der_decode_sequence_multi(sig, siglen,
|
||||
LTC_ASN1_INTEGER, 1UL, r,
|
||||
LTC_ASN1_INTEGER, 1UL, s,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* get the order */
|
||||
if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* get the modulus */
|
||||
if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* check for zero */
|
||||
if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* read hash */
|
||||
if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* w = s^-1 mod n */
|
||||
if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* u1 = ew */
|
||||
if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* u2 = rw */
|
||||
if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* find mG = u1*G */
|
||||
if ((err = mp_read_radix(mG->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK) { goto error; }
|
||||
mp_set(mG->z, 1);
|
||||
if ((err = ltc_ecc_mulmod(u1, mG, mG, m, 0)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* find mQ = u2*Q */
|
||||
if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_ecc_mulmod(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* find the montgomery mp */
|
||||
if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; }
|
||||
/* add them */
|
||||
if (ltc_mp.ecc_ptadd != NULL) {
|
||||
if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto done; }
|
||||
} else {
|
||||
if ((err = ltc_ecc_add_point(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* reduce */
|
||||
if (ltc_mp.ecc_map != NULL) {
|
||||
if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto done; }
|
||||
} else {
|
||||
if ((err = ltc_ecc_map(mG, m, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* v = X_x1 mod n */
|
||||
if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* does v == r */
|
||||
if (mp_cmp(v, r) == LTC_MP_EQ) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clear up and return */
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
done:
|
||||
ltc_ecc_del_point(mG);
|
||||
ltc_ecc_del_point(mQ);
|
||||
mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
|
||||
if (mp != NULL) {
|
||||
mp_montgomery_free(mp);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
96
src/pk/ecc/ecc_test.c
Normal file
96
src/pk/ecc/ecc_test.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_test.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Perform on the ECC system
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ecc_test(void)
|
||||
{
|
||||
void *modulus, *order;
|
||||
ecc_point *G, *GG;
|
||||
int i, err, primality;
|
||||
|
||||
if ((err = mp_init_multi(&modulus, &order, NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
G = ltc_ecc_new_point();
|
||||
GG = ltc_ecc_new_point();
|
||||
if (G == NULL || GG == NULL) {
|
||||
mp_clear_multi(modulus, order, NULL);
|
||||
ltc_ecc_del_point(G);
|
||||
ltc_ecc_del_point(GG);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
for (i = 0; ltc_ecc_sets[i].size; i++) {
|
||||
#if 0
|
||||
printf("Testing %d\n", ltc_ecc_sets[i].size);
|
||||
#endif
|
||||
if ((err = mp_read_radix(modulus, (char *)ltc_ecc_sets[i].prime, 64)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_read_radix(order, (char *)ltc_ecc_sets[i].order, 64)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* is prime actually prime? */
|
||||
if ((err = mp_prime_is_prime(modulus, 8, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* is order prime ? */
|
||||
if ((err = mp_prime_is_prime(order, 8, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((err = mp_read_radix(G->x, (char *)ltc_ecc_sets[i].Gx, 64)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_read_radix(G->y, (char *)ltc_ecc_sets[i].Gy, 64)) != CRYPT_OK) { goto done; }
|
||||
mp_set(G->z, 1);
|
||||
|
||||
/* then we should have G == (order + 1)G */
|
||||
if ((err = mp_add_d(order, 1, order)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_mp.ecc_ptmul(order, G, GG, modulus, 1)) != CRYPT_OK) { goto done; }
|
||||
if (mp_cmp(G->x, GG->x) != LTC_MP_EQ || mp_cmp(G->y, GG->y) != LTC_MP_EQ) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
done:
|
||||
ltc_ecc_del_point(GG);
|
||||
ltc_ecc_del_point(G);
|
||||
mp_clear_multi(order, modulus, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
160
src/pk/ecc/ecc_verify_hash.c
Normal file
160
src/pk/ecc/ecc_verify_hash.c
Normal file
@ -0,0 +1,160 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ecc_verify_hash.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/* verify
|
||||
*
|
||||
* w = s^-1 mod n
|
||||
* u1 = xw
|
||||
* u2 = rw
|
||||
* X = u1*G + u2*Q
|
||||
* v = X_x1 mod n
|
||||
* accept if v == r
|
||||
*/
|
||||
|
||||
/**
|
||||
Verify an ECC signature
|
||||
@param sig The signature to verify
|
||||
@param siglen The length of the signature (octets)
|
||||
@param hash The hash (message digest) that was signed
|
||||
@param hashlen The length of the hash (octets)
|
||||
@param stat Result of signature, 1==valid, 0==invalid
|
||||
@param key The corresponding public ECC key
|
||||
@return CRYPT_OK if successful (even if the signature is not valid)
|
||||
*/
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, ecc_key *key)
|
||||
{
|
||||
ecc_point *mG, *mQ;
|
||||
void *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
|
||||
void *mp;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(sig != NULL);
|
||||
LTC_ARGCHK(hash != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
mp = NULL;
|
||||
|
||||
/* is the IDX valid ? */
|
||||
if (ltc_ecc_is_valid_idx(key->idx) != 1) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
/* allocate ints */
|
||||
if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* allocate points */
|
||||
mG = ltc_ecc_new_point();
|
||||
mQ = ltc_ecc_new_point();
|
||||
if (mQ == NULL || mG == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* parse header */
|
||||
if ((err = der_decode_sequence_multi(sig, siglen,
|
||||
LTC_ASN1_INTEGER, 1UL, r,
|
||||
LTC_ASN1_INTEGER, 1UL, s,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* get the order */
|
||||
if ((err = mp_read_radix(p, (char *)ltc_ecc_sets[key->idx].order, 64)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* get the modulus */
|
||||
if ((err = mp_read_radix(m, (char *)ltc_ecc_sets[key->idx].prime, 64)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* check for zero */
|
||||
if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* read hash */
|
||||
if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* w = s^-1 mod n */
|
||||
if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* u1 = ew */
|
||||
if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* u2 = rw */
|
||||
if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* find mG = u1*G */
|
||||
if ((err = mp_read_radix(mG->x, (char *)ltc_ecc_sets[key->idx].Gx, 64)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_read_radix(mG->y, (char *)ltc_ecc_sets[key->idx].Gy, 64)) != CRYPT_OK) { goto error; }
|
||||
mp_set(mG->z, 1);
|
||||
if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* find mQ = u2*Q */
|
||||
if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; }
|
||||
if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* find the montgomery mp */
|
||||
if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; }
|
||||
/* add them */
|
||||
if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* reduce */
|
||||
if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* v = X_x1 mod n */
|
||||
if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* does v == r */
|
||||
if (mp_cmp(v, r) == LTC_MP_EQ) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clear up and return */
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
done:
|
||||
ltc_ecc_del_point(mG);
|
||||
ltc_ecc_del_point(mQ);
|
||||
mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
|
||||
if (mp != NULL) {
|
||||
mp_montgomery_free(mp);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
45
src/pk/ecc/ltc_ecc_is_valid_idx.c
Normal file
45
src/pk/ecc/ltc_ecc_is_valid_idx.c
Normal file
@ -0,0 +1,45 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ltc_ecc_is_valid_idx.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/** Returns whether an ECC idx is valid or not
|
||||
@param n The idx number to check
|
||||
@return 1 if valid, 0 if not
|
||||
*/
|
||||
int ltc_ecc_is_valid_idx(int n)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; ltc_ecc_sets[x].size != 0; x++);
|
||||
if ((n < 0) || (n >= x)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
77
src/pk/ecc/ltc_ecc_map.c
Normal file
77
src/pk/ecc/ltc_ecc_map.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ltc_ecc_map.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Map a projective jacbobian point back to affine space
|
||||
@param P [in/out] The point to map
|
||||
@param modulus The modulus of the field the ECC curve is in
|
||||
@param mp The "b" value from montgomery_setup()
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
|
||||
{
|
||||
void *t1, *t2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(P != NULL);
|
||||
LTC_ARGCHK(modulus != NULL);
|
||||
LTC_ARGCHK(mp != NULL);
|
||||
|
||||
if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* first map z back to normal */
|
||||
if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* get 1/z */
|
||||
if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* get 1/z^2 and 1/z^3 */
|
||||
if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* multiply against x/y */
|
||||
if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
mp_set(P->z, 1);
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
done:
|
||||
mp_clear_multi(t1, t2, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
213
src/pk/ecc/ltc_ecc_mulmod.c
Normal file
213
src/pk/ecc/ltc_ecc_mulmod.c
Normal file
@ -0,0 +1,213 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ltc_ecc_mulmod.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
#ifndef LTC_ECC_TIMING_RESISTANT
|
||||
|
||||
/* size of sliding window, don't change this! */
|
||||
#define WINSIZE 4
|
||||
|
||||
/**
|
||||
Perform a point multiplication
|
||||
@param k The scalar to multiply by
|
||||
@param G The base point
|
||||
@param R [out] Destination for kG
|
||||
@param modulus The modulus of the field the ECC curve is in
|
||||
@param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
|
||||
{
|
||||
ecc_point *tG, *M[8];
|
||||
int i, j, err;
|
||||
void *mu, *mp;
|
||||
unsigned long buf;
|
||||
int first, bitbuf, bitcpy, bitcnt, mode, digidx;
|
||||
|
||||
LTC_ARGCHK(k != NULL);
|
||||
LTC_ARGCHK(G != NULL);
|
||||
LTC_ARGCHK(R != NULL);
|
||||
LTC_ARGCHK(modulus != NULL);
|
||||
|
||||
/* init montgomery reduction */
|
||||
if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = mp_init(&mu)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
|
||||
mp_montgomery_free(mp);
|
||||
mp_clear(mu);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* alloc ram for window temps */
|
||||
for (i = 0; i < 8; i++) {
|
||||
M[i] = ltc_ecc_new_point();
|
||||
if (M[i] == NULL) {
|
||||
for (j = 0; j < i; j++) {
|
||||
ltc_ecc_del_point(M[j]);
|
||||
}
|
||||
mp_montgomery_free(mp);
|
||||
mp_clear(mu);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* make a copy of G incase R==G */
|
||||
tG = ltc_ecc_new_point();
|
||||
if (tG == NULL) { err = CRYPT_MEM; goto done; }
|
||||
|
||||
/* tG = G and convert to montgomery */
|
||||
if (mp_cmp_d(mu, 1) == LTC_MP_EQ) {
|
||||
if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; }
|
||||
} else {
|
||||
if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
mp_clear(mu);
|
||||
|
||||
/* calc the M tab, which holds kG for k==8..15 */
|
||||
/* M[0] == 8G */
|
||||
if ((err = ltc_ecc_projective_dbl_point(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_ecc_projective_dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_ecc_projective_dbl_point(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* now find (8+k)G for k=1..7 */
|
||||
for (j = 9; j < 16; j++) {
|
||||
if ((err = ltc_ecc_projective_add_point(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* setup sliding window */
|
||||
mode = 0;
|
||||
bitcnt = 1;
|
||||
buf = 0;
|
||||
digidx = mp_get_digit_count(k) - 1;
|
||||
bitcpy = bitbuf = 0;
|
||||
first = 1;
|
||||
|
||||
/* perform ops */
|
||||
for (;;) {
|
||||
/* grab next digit as required */
|
||||
if (--bitcnt == 0) {
|
||||
if (digidx == -1) {
|
||||
break;
|
||||
}
|
||||
buf = mp_get_digit(k, digidx);
|
||||
bitcnt = (int) MP_DIGIT_BIT;
|
||||
--digidx;
|
||||
}
|
||||
|
||||
/* grab the next msb from the ltiplicand */
|
||||
i = (buf >> (MP_DIGIT_BIT - 1)) & 1;
|
||||
buf <<= 1;
|
||||
|
||||
/* skip leading zero bits */
|
||||
if (mode == 0 && i == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if the bit is zero and mode == 1 then we double */
|
||||
if (mode == 1 && i == 0) {
|
||||
if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
continue;
|
||||
}
|
||||
|
||||
/* else we add it to the window */
|
||||
bitbuf |= (i << (WINSIZE - ++bitcpy));
|
||||
mode = 2;
|
||||
|
||||
if (bitcpy == WINSIZE) {
|
||||
/* if this is the first window we do a simple copy */
|
||||
if (first == 1) {
|
||||
/* R = kG [k = first window] */
|
||||
if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; }
|
||||
first = 0;
|
||||
} else {
|
||||
/* normal window */
|
||||
/* ok window is filled so double as required and add */
|
||||
/* double first */
|
||||
for (j = 0; j < WINSIZE; j++) {
|
||||
if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
|
||||
if ((err = ltc_ecc_projective_add_point(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
/* empty window and reset */
|
||||
bitcpy = bitbuf = 0;
|
||||
mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if bits remain then double/add */
|
||||
if (mode == 2 && bitcpy > 0) {
|
||||
/* double then add */
|
||||
for (j = 0; j < bitcpy; j++) {
|
||||
/* only double if we have had at least one add first */
|
||||
if (first == 0) {
|
||||
if ((err = ltc_ecc_projective_dbl_point(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
bitbuf <<= 1;
|
||||
if ((bitbuf & (1 << WINSIZE)) != 0) {
|
||||
if (first == 1){
|
||||
/* first add, so copy */
|
||||
if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; }
|
||||
first = 0;
|
||||
} else {
|
||||
/* then add */
|
||||
if ((err = ltc_ecc_projective_add_point(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* map R back from projective space */
|
||||
if (map) {
|
||||
err = ltc_ecc_map(R, modulus, mp);
|
||||
} else {
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
done:
|
||||
mp_montgomery_free(mp);
|
||||
ltc_ecc_del_point(tG);
|
||||
for (i = 0; i < 8; i++) {
|
||||
ltc_ecc_del_point(M[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef WINSIZE
|
||||
|
||||
#endif
|
162
src/pk/ecc/ltc_ecc_mulmod_timing.c
Normal file
162
src/pk/ecc/ltc_ecc_mulmod_timing.c
Normal file
@ -0,0 +1,162 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ltc_ecc_mulmod_timing.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
#ifdef LTC_ECC_TIMING_RESISTANT
|
||||
|
||||
/**
|
||||
Perform a point multiplication (timing resistant)
|
||||
@param k The scalar to multiply by
|
||||
@param G The base point
|
||||
@param R [out] Destination for kG
|
||||
@param modulus The modulus of the field the ECC curve is in
|
||||
@param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
|
||||
{
|
||||
ecc_point *tG, *M[3];
|
||||
int i, j, err;
|
||||
void *mu, *mp;
|
||||
unsigned long buf;
|
||||
int first, bitbuf, bitcpy, bitcnt, mode, digidx;
|
||||
|
||||
LTC_ARGCHK(k != NULL);
|
||||
LTC_ARGCHK(G != NULL);
|
||||
LTC_ARGCHK(R != NULL);
|
||||
LTC_ARGCHK(modulus != NULL);
|
||||
|
||||
/* init montgomery reduction */
|
||||
if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = mp_init(&mu)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
|
||||
mp_montgomery_free(mp);
|
||||
mp_clear(mu);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* alloc ram for window temps */
|
||||
for (i = 0; i < 3; i++) {
|
||||
M[i] = ltc_ecc_new_point();
|
||||
if (M[i] == NULL) {
|
||||
for (j = 0; j < i; j++) {
|
||||
ltc_ecc_del_point(M[j]);
|
||||
}
|
||||
mp_montgomery_free(mp);
|
||||
mp_clear(mu);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* make a copy of G incase R==G */
|
||||
tG = ltc_ecc_new_point();
|
||||
if (tG == NULL) { err = CRYPT_MEM; goto done; }
|
||||
|
||||
/* tG = G and convert to montgomery */
|
||||
if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; }
|
||||
mp_clear(mu);
|
||||
|
||||
/* calc the M tab, which holds kG for k==8..15 */
|
||||
/* M[0] == G */
|
||||
if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; }
|
||||
/* M[1] == 2G */
|
||||
if ((err = ltc_ecc_projective_dbl_point(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* setup sliding window */
|
||||
mode = 0;
|
||||
bitcnt = 1;
|
||||
buf = 0;
|
||||
digidx = mp_get_digit_count(k) - 1;
|
||||
bitcpy = bitbuf = 0;
|
||||
first = 1;
|
||||
|
||||
/* perform ops */
|
||||
for (;;) {
|
||||
/* grab next digit as required */
|
||||
if (--bitcnt == 0) {
|
||||
if (digidx == -1) {
|
||||
break;
|
||||
}
|
||||
buf = mp_get_digit(k, digidx);
|
||||
bitcnt = (int) MP_DIGIT_BIT;
|
||||
--digidx;
|
||||
}
|
||||
|
||||
/* grab the next msb from the ltiplicand */
|
||||
i = (buf >> (MP_DIGIT_BIT - 1)) & 1;
|
||||
buf <<= 1;
|
||||
|
||||
if (mode == 0 && i == 0) {
|
||||
/* dummy operations */
|
||||
if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_ecc_projective_dbl_point(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode == 0 && i == 1) {
|
||||
mode = 1;
|
||||
/* dummy operations */
|
||||
if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_ecc_projective_dbl_point(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((err = ltc_ecc_projective_add_point(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
if ((err = ltc_ecc_projective_dbl_point(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* copy result out */
|
||||
if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; }
|
||||
if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* map R back from projective space */
|
||||
if (map) {
|
||||
err = ltc_ecc_map(R, modulus, mp);
|
||||
} else {
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
done:
|
||||
mp_montgomery_free(mp);
|
||||
ltc_ecc_del_point(tG);
|
||||
for (i = 0; i < 3; i++) {
|
||||
ltc_ecc_del_point(M[i]);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
60
src/pk/ecc/ltc_ecc_points.c
Normal file
60
src/pk/ecc/ltc_ecc_points.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
|
||||
*
|
||||
* LibTomCrypt is a library that provides various cryptographic
|
||||
* algorithms in a highly modular and flexible manner.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file ltc_ecc_points.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/**
|
||||
Allocate a new ECC point
|
||||
@return A newly allocated point or NULL on error
|
||||
*/
|
||||
ecc_point *ltc_ecc_new_point(void)
|
||||
{
|
||||
ecc_point *p;
|
||||
p = XMALLOC(sizeof(*p));
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) {
|
||||
XFREE(p);
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Free an ECC point from memory
|
||||
@param p The point to free
|
||||
*/
|
||||
void ltc_ecc_del_point(ecc_point *p)
|
||||
{
|
||||
/* prevents free'ing null arguments */
|
||||
if (p != NULL) {
|
||||
mp_clear_multi(p->x, p->y, p->z, NULL);
|
||||
XFREE(p);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user