added libtomcrypt-0.84

This commit is contained in:
Tom St Denis 2003-06-01 18:55:11 +00:00 committed by Steffen Jaeckel
parent 90a48a5bec
commit d6071c6267
41 changed files with 7688 additions and 6574 deletions

4
aes.c
View File

@ -327,6 +327,9 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
int rijndael_test(void) int rijndael_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int errno; int errno;
static const struct { static const struct {
int keylen; int keylen;
@ -377,6 +380,7 @@ int rijndael_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int rijndael_keysize(int *desired_keysize) int rijndael_keysize(int *desired_keysize)

55
ampi.c
View File

@ -1,55 +0,0 @@
/* Code submitted by Svante Seleborg, cleaned up by Tom St Denis */
#include "mycrypt.h"
#include <stdarg.h>
#ifdef MPI
mp_err mp_init_multi(mp_int *mp, ...)
{
mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
int n = 0; /* Number of ok inits */
mp_int* cur_arg = mp;
va_list args;
va_start(args, mp); /* init args to next argument from caller */
while (cur_arg != NULL) {
if (mp_init(cur_arg) != MP_OKAY) {
/* Oops - error! Back-track and mp_clear what we already
succeeded in init-ing, then return error.
*/
va_list clean_args;
cur_arg = mp;
va_start(clean_args, mp);
while (n--) {
mp_clear(cur_arg);
cur_arg = va_arg(clean_args, mp_int*);
}
va_end(clean_args);
res = MP_MEM;
break;
}
n++;
cur_arg = va_arg(args, mp_int*);
}
va_end(args);
return res; /* Assumed ok, if error flagged above. */
}
/*
Clear all arguments given, ended by a NULL marker.
*/
void mp_clear_multi(mp_int *mp, ...)
{
mp_int* next_mp = mp;
va_list args;
va_start(args, mp);
while (next_mp != NULL) {
mp_clear(next_mp);
next_mp = va_arg(args, mp_int*);
}
va_end(args);
}
#endif

View File

@ -436,6 +436,9 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
int blowfish_test(void) int blowfish_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err; int err;
symmetric_key key; symmetric_key key;
static const struct { static const struct {
@ -476,6 +479,7 @@ int blowfish_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int blowfish_keysize(int *desired_keysize) int blowfish_keysize(int *desired_keysize)

View File

@ -552,6 +552,9 @@ void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
int cast5_test(void) int cast5_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
int keylen; int keylen;
unsigned char key[16]; unsigned char key[16];
@ -590,6 +593,7 @@ int cast5_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int cast5_keysize(int *desired_keysize) int cast5_keysize(int *desired_keysize)

11
changes
View File

@ -1,3 +1,14 @@
Jun 1st, 2003
v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
-- Fixed another potential buffer problem. Not an overflow but could cause the
PK import routines to read past the end of the buffer.
-- Optimized the ECC mulmod more by removing a if condition that will always be false
-- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime
test from LibTomMath now
-- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h]
-- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now].
Mar 29th, 2003 Mar 29th, 2003
v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space
-- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL -- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL

View File

@ -24,6 +24,7 @@
"SMALL_CODE,Use small code where possible (slower code),y", "SMALL_CODE,Use small code where possible (slower code),y",
"NO_FILE,Avoid file I/O calls,n", "NO_FILE,Avoid file I/O calls,n",
"CLEAN_STACK,Clean the stack within functions,n", "CLEAN_STACK,Clean the stack within functions,n",
"LTC_TEST,Include Test Vector Routines,y",
"BLOWFISH,Include Blowfish block cipher,y", "BLOWFISH,Include Blowfish block cipher,y",
"RC2,Include RC2 block cipher,y", "RC2,Include RC2 block cipher,y",
@ -144,7 +145,7 @@ for (@settings) {
# output objects # output objects
print OUT "\ndefault: library\n\n"; print OUT "\ndefault: library\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o\n\n"; print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o\n\n";
# some depends # some depends
print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n"; print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n";

BIN
crypt.pdf

Binary file not shown.

View File

@ -48,7 +48,7 @@
\def\gap{\vspace{0.5ex}} \def\gap{\vspace{0.5ex}}
\makeindex \makeindex
\begin{document} \begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.83} \title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.84}
\author{Tom St Denis \\ \author{Tom St Denis \\
Algonquin College \\ Algonquin College \\
\\ \\
@ -64,8 +64,8 @@ Canada
\newpage \newpage
\tableofcontents \tableofcontents
\chapter{Introduction} \chapter{Introduction}
\section{What is the Libtomcrypt?} \section{What is the LibTomCrypt?}
Libtomcrypt is a portable ANSI C cryptographic library that supports symmetric ciphers, one-way hashes, LibTomCrypt is a portable ANSI C cryptographic library that supports symmetric ciphers, one-way hashes,
pseudo-random number generators, public key cryptography (via RSA,DH or ECC/DH) and a plethora of support pseudo-random number generators, public key cryptography (via RSA,DH or ECC/DH) and a plethora of support
routines. It is designed to compile out of the box with the GNU C Compiler (GCC) version 2.95.3 (and higher) routines. It is designed to compile out of the box with the GNU C Compiler (GCC) version 2.95.3 (and higher)
and with MSVC version 6 in win32. and with MSVC version 6 in win32.
@ -932,12 +932,12 @@ int hash_filehandle(int hash, FILE *in,
unsigned char *dst, unsigned long *outlen); unsigned char *dst, unsigned long *outlen);
\end{verbatim} \end{verbatim}
All three functions return {\bf CRYPT\_OK} on success, otherwise they return an error code. The ``hash'' parameter is The ``hash'' parameter is the location in the descriptor table of the hash (\textit{e.g. the return of find\_hash()}).
the location in the descriptor table of the hash. The ``*outlen'' variable is used to keep track of the output size. You The ``*outlen'' variable is used to keep track of the output size. You
must set it to the size of your output buffer before calling the functions. When they complete succesfully they store must set it to the size of your output buffer before calling the functions. When they complete succesfully they store
the length of the message digest back in it. The functions are otherwise straightforward. The ``hash\_filehandle'' the length of the message digest back in it. The functions are otherwise straightforward. The ``hash\_filehandle''
function assumes that ``in'' is an file handle opened in binary mode. It will not reset the file position after function assumes that ``in'' is an file handle opened in binary mode. It will hash to the end of file and not reset
hashing the content. the file position when finished.
To perform the above hash with md5 the following code could be used: To perform the above hash with md5 the following code could be used:
\begin{small} \begin{small}
@ -993,7 +993,7 @@ int unregister_hash(const struct _hash_descriptor *hash);
\end{verbatim} \end{verbatim}
\subsection{Notice} \subsection{Notice}
It is highly recommended that you not use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes. It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes.
These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators
(e.g. Yarrow). (e.g. Yarrow).
@ -1039,16 +1039,16 @@ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
unsigned char *dst, unsigned long *dstlen); unsigned char *dst, unsigned long *dstlen);
\end{verbatim} \end{verbatim}
This will produce an HMAC code for the array of octets in ``data'' of length ``len''. The index into the hash descriptor This will produce an HMAC code for the array of octets in ``data'' of length ``len''. The index into the hash descriptor
table must be provided in ``hash'' it uses the key from ``key'' with a key length of ``keylen''. table must be provided in ``hash''. It uses the key from ``key'' with a key length of ``keylen''.
The result is stored in the array of octets ``dst'' and the length in ``dstlen''. Similarly for files there is the The result is stored in the array of octets ``dst'' and the length in ``dstlen''. The value of ``dstlen'' must be set
following function: to the size of the destination buffer before calling this function. Similarly for files there is the following function:
\begin{verbatim} \begin{verbatim}
int hmac_file(int hash, const char *fname, const unsigned char *key, int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen, unsigned long keylen,
unsigned char *dst, unsigned long *dstlen); unsigned char *dst, unsigned long *dstlen);
\end{verbatim} \end{verbatim}
``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process. ``key'' ``hash'' is the index into the hash descriptor table of the hash you want to use. ``fname'' is the filename to process.
is the array of octets to use as the key. ``keylen'' is the length of the key. ``dst'' is the array of octets where the ``key'' is the array of octets to use as the key of length ``keylen''. ``dst'' is the array of octets where the
result should be stored. result should be stored.
To test if the HMAC code is working there is the following function: To test if the HMAC code is working there is the following function:
@ -1378,7 +1378,7 @@ int rsa_make_key(prng_state *prng,
Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired. Where ``wprng'' is the index into the PRNG descriptor array. ``size'' is the size in bytes of the RSA modulus desired.
``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big ``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537. I suggest you stick with 65537 since its big
enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at enough to prevent trivial math attacks and not super slow. ``key'' is where the key is placed. All keys must be at
least 128 bytes and no more than 512 bytes in size (that is from 1024 to 4096 bits). least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key. Make sure to call
``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically ``rsa\_free()'' (see below) when you are finished with the key. If ``rsa\_make\_key()'' fails it will automatically
@ -1408,22 +1408,21 @@ recipient who can RSA decrypt it and symmetrically decrypt the message.
int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
unsigned char *outkey, unsigned long *outlen, unsigned char *outkey, unsigned long *outlen,
prng_state *prng, int wprng, rsa_key *key); prng_state *prng, int wprng, rsa_key *key);
\end{verbatim}
This function is used to RSA encrypt a symmetric to share with another user. The symmetric key and its length are
passed as ``inkey'' and ``inlen'' respectively. The symmetric key is limited to a range of 8 to 32 bytes
(\textit{64 to 256 bits}). The RSA encrypted packet is stored in ``outkey'' and will be of length ``outlen'' bytes. The
value of ``outlen'' must be originally set to the size of the output buffer.
\begin{verbatim}
int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen, unsigned char *outkey, unsigned long *keylen,
rsa_key *key); rsa_key *key);
\end{verbatim} \end{verbatim}
The ``rsa\_encrypt\_key()'' function accepts a symmetric key (limited to 32 bytes) as input in ``inkey''. ``inlen'' This function will decrypt an RSA packet to retrieve the original symmetric key encrypted with rsa\_encrypt\_key().
is the size of the input key in bytes. The function will then ``rsa\_pad()'' the key and encrypt it using the RSA Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your message
algorithm. It will store the result in ``outkey'' along with the length in ``outlen''. then use these functions to RSA sign the hash.
The ``rsa\_decrypt\_key()'' function performs the opposite. The ``in'' variable is where the RSA packet of length
``inlen'' goes and it will store the original symmetric key in the ``outkey'' variable along with its length in
``keylen''.
Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your
message then use these functions to RSA sign the hash.
\begin{verbatim} \begin{verbatim}
int rsa_sign_hash(const unsigned char *in, unsigned long inlen, int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,

View File

@ -630,7 +630,7 @@ rsa_test (void)
/* time encryption */ /* time encryption */
t = XCLOCK (); t = XCLOCK ();
for (tt = 0; tt < 100; tt++) { for (tt = 0; tt < 20; tt++) {
y = sizeof (in); y = sizeof (in);
if ((errnum = if ((errnum =
rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) { rsa_exptmod (in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) {
@ -640,11 +640,11 @@ rsa_test (void)
} }
t = XCLOCK () - t; t = XCLOCK () - t;
printf ("Took %.0f ms to encrypt with a %ld-bit RSA key.\n", printf ("Took %.0f ms to encrypt with a %ld-bit RSA key.\n",
1000.0 * (((double) t / 100.0) / (double) XCLOCKS_PER_SEC), z); 1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z);
/* time decryption */ /* time decryption */
t = XCLOCK (); t = XCLOCK ();
for (tt = 0; tt < 100; tt++) { for (tt = 0; tt < 20; tt++) {
x = sizeof (out); x = sizeof (out);
if ((errnum = if ((errnum =
rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) { rsa_exptmod (out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
@ -654,7 +654,7 @@ rsa_test (void)
} }
t = XCLOCK () - t; t = XCLOCK () - t;
printf ("Took %.0f ms to decrypt with a %ld-bit RSA key.\n", printf ("Took %.0f ms to decrypt with a %ld-bit RSA key.\n",
1000.0 * (((double) t / 100.0) / (double) XCLOCKS_PER_SEC), z); 1000.0 * (((double) t / 20.0) / (double) XCLOCKS_PER_SEC), z);
rsa_free (&key); rsa_free (&key);
} }
} }
@ -1123,7 +1123,7 @@ ecc_tests (void)
for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) { for (ii = 0; ii < (int) (sizeof (sizes) / sizeof (sizes[0])); ii++) {
t1 = XCLOCK (); t1 = XCLOCK ();
for (tt = 0; tt < 25; tt++) { for (tt = 0; tt < 10; tt++) {
if ((errnum = if ((errnum =
ecc_make_key (&prng, find_prng ("yarrow"), sizes[ii], ecc_make_key (&prng, find_prng ("yarrow"), sizes[ii],
&usera)) != CRYPT_OK) { &usera)) != CRYPT_OK) {
@ -1134,7 +1134,7 @@ ecc_tests (void)
} }
t1 = XCLOCK () - t1; t1 = XCLOCK () - t1;
printf ("Make ECC-%d key took %f msec\n", sizes[ii] * 8, printf ("Make ECC-%d key took %f msec\n", sizes[ii] * 8,
1000.0 * (((double) t1 / 25.0) / (double) XCLOCKS_PER_SEC)); 1000.0 * (((double) t1 / 10.0) / (double) XCLOCKS_PER_SEC));
} }
} }
@ -1342,15 +1342,15 @@ register_all_algs (void)
register_cipher (&null_desc); register_cipher (&null_desc);
#ifdef SHA1
register_hash (&sha1_desc);
#endif
#ifdef SHA256 #ifdef SHA256
register_hash (&sha256_desc); register_hash (&sha256_desc);
#endif #endif
#ifdef TIGER #ifdef TIGER
register_hash (&tiger_desc); register_hash (&tiger_desc);
#endif #endif
#ifdef SHA1
register_hash (&sha1_desc);
#endif
#ifdef MD5 #ifdef MD5
register_hash (&md5_desc); register_hash (&md5_desc);
#endif #endif

8
des.c
View File

@ -519,6 +519,9 @@ void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
int des_test(void) int des_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err; int err;
static const struct des_test_case { static const struct des_test_case {
int num, mode; // mode 1 = encrypt int num, mode; // mode 1 = encrypt
@ -648,10 +651,14 @@ int des_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int des3_test(void) int des3_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char key[24], pt[8], ct[8], tmp[8]; unsigned char key[24], pt[8], ct[8], tmp[8];
symmetric_key skey; symmetric_key skey;
int x, err; int x, err;
@ -680,6 +687,7 @@ int des3_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int des_keysize(int *desired_keysize) int des_keysize(int *desired_keysize)

16
dh.c
View File

@ -376,22 +376,28 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
_ARGCHK(in != NULL); _ARGCHK(in != NULL);
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
/* make sure valid length */
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* check type byte */ /* check type byte */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) { if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
return err; return err;
} }
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* init */ /* init */
if (mp_init_multi(&key->x, &key->y, NULL) != MP_OKAY) { if (mp_init_multi(&key->x, &key->y, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
/* advance past packet header */
y = PACKET_SIZE; y = PACKET_SIZE;
/* key type, e.g. private, public */
key->type = (int)in[y++]; key->type = (int)in[y++];
/* key size in bytes */
s = (unsigned long)in[y++] * 8; s = (unsigned long)in[y++] * 8;
for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++); for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
@ -467,7 +473,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
res = CRYPT_BUFFER_OVERFLOW; res = CRYPT_BUFFER_OVERFLOW;
goto done; goto done;
} }
(void)mp_to_unsigned_bin(&tmp, out); if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) { goto error; }
*outlen = x; *outlen = x;
res = CRYPT_OK; res = CRYPT_OK;
goto done; goto done;

View File

@ -194,7 +194,24 @@ done:
return res; return res;
} }
/* perform an ElGamal Signature of a hash
*
* The math works as follows. x is the private key, M is the message to sign
1. pick a random k
2. compute a = g^k mod p
3. compute b = (M - xa)/k mod p
4. Send (a,b)
Now to verify with y=g^x mod p, a and b
1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k)
= g^(xa + (M - xa))
= g^M [all mod p]
2. Compare against g^M mod p [based on input hash].
3. If result of #2 == result of #1 then signature valid
*/
int dh_sign_hash(const unsigned char *in, unsigned long inlen, int dh_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, dh_key *key) prng_state *prng, int wprng, dh_key *key)

24
ecc.c
View File

@ -425,8 +425,9 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
buf <<= 1; buf <<= 1;
/* skip leading zero bits */ /* skip leading zero bits */
if (mode == 0 && i == 0) if (mode == 0 && i == 0) {
continue; continue;
}
/* if the bit is zero and mode == 1 then we double */ /* if the bit is zero and mode == 1 then we double */
if (mode == 1 && i == 0) { if (mode == 1 && i == 0) {
@ -453,13 +454,9 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; } if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
} }
/* then add, bitbuf will be 1..15 [1..2^WINSIZE] guaranteed */ /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
if (bitbuf == 1) {
if (add_point(R, tG, R, modulus, &mu) != CRYPT_OK) { goto error; }
} else {
if (add_point(R, M[bitbuf-8], R, modulus, &mu) != CRYPT_OK) { goto error; } if (add_point(R, M[bitbuf-8], R, modulus, &mu) != CRYPT_OK) { goto error; }
} }
}
/* empty window and reset */ /* empty window and reset */
bitcpy = bitbuf = 0; bitcpy = bitbuf = 0;
mode = 1; mode = 1;
@ -842,15 +839,16 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
_ARGCHK(in != NULL); _ARGCHK(in != NULL);
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
/* check length */
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* check type */ /* check type */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) { if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
return err; return err;
} }
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* init key */ /* init key */
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) { if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
@ -938,7 +936,7 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
} }
if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; } if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; }
if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { res = err; goto done1; } if ((res = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
x = (unsigned long)mp_unsigned_bin_size(&result->x); x = (unsigned long)mp_unsigned_bin_size(&result->x);
y = (unsigned long)mp_unsigned_bin_size(&result->y); y = (unsigned long)mp_unsigned_bin_size(&result->y);
@ -948,8 +946,8 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
goto done1; goto done1;
} }
*outlen = x+y; *outlen = x+y;
(void)mp_to_unsigned_bin(&result->x, out); if (mp_to_unsigned_bin(&result->x, out) != MP_OKAY) { goto error; }
(void)mp_to_unsigned_bin(&result->y, out+x); if (mp_to_unsigned_bin(&result->y, out+x) != MP_OKAY) { goto error; }
res = CRYPT_OK; res = CRYPT_OK;
goto done1; goto done1;

View File

@ -299,7 +299,19 @@ done1:
return res; return res;
} }
/* verify that mG = (bA + Y) */ /* verify that mG = (bA + Y)
*
* The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the
* public key Y = xG can verify it.
*
* b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it]
* A = kG therefore bA == ((m-x)/k)kG == (m-x)G
*
* Adding Y = xG to the bA gives us (m-x)G + xG == mG
*
* The user given only xG, kG and b cannot determine k or x which means they can't find the private key.
*
*/
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, unsigned long inlen, const unsigned char *hash, unsigned long inlen,
int *stat, ecc_key *key) int *stat, ecc_key *key)

6
hmac.c
View File

@ -37,7 +37,7 @@ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned lon
return err; return err;
} }
if(key == NULL || keylen == 0) { if (keylen == 0) {
return CRYPT_INVALID_KEYSIZE; return CRYPT_INVALID_KEYSIZE;
} }
@ -231,6 +231,9 @@ Category: Informational R. Glenn
int hmac_test(void) int hmac_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
unsigned char digest[MAXBLOCKSIZE]; unsigned char digest[MAXBLOCKSIZE];
int i; int i;
@ -497,6 +500,7 @@ Key First"
} else { } else {
return CRYPT_OK; return CRYPT_OK;
} }
#endif
} }
#endif #endif

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems. # a build. This is easy to remedy though, for those that have problems.
# The version # The version
VERSION=0.83 VERSION=0.84
#ch1-01-1 #ch1-01-1
# Compiler and Linker Names # Compiler and Linker Names
@ -31,7 +31,7 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -Werror
# optimize for SIZE # optimize for SIZE
CFLAGS += -Os CFLAGS += -Os
# compile for DEBUGGING # compile for DEBUGING
#CFLAGS += -g3 #CFLAGS += -g3
#ch1-01-3 #ch1-01-3
@ -57,7 +57,7 @@ OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \ bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o \ md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o \
safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \ safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
TESTOBJECTS=demos/test.o TESTOBJECTS=demos/test.o
HASHOBJECTS=demos/hashsum.o HASHOBJECTS=demos/hashsum.o
@ -71,7 +71,7 @@ LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
#Header files used by libtomcrypt. #Header files used by libtomcrypt.
HEADERS=mpi.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \ HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \ mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \
mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h
@ -129,8 +129,7 @@ clean:
#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to #nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
#delete it if we are rebuilding it. #delete it if we are rebuilding it.
docs: crypt.tex docs: crypt.tex
rm -f crypt.pdf rm -f crypt.pdf $(LEFTOVERS)
rm -f $(LEFTOVERS)
latex crypt > /dev/null latex crypt > /dev/null
makeindex crypt > /dev/null makeindex crypt > /dev/null
pdflatex crypt > /dev/null pdflatex crypt > /dev/null

View File

@ -2,7 +2,7 @@
# #
#Tom St Denis #Tom St Denis
CFLAGS = /I. /Ogiyb2t /Gs /DWIN32 /W3 CFLAGS = /I. /Ogiyb1s /Gs /DWIN32 /W3
default: library default: library
@ -11,7 +11,7 @@ OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \
bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \ bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \
md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj serpent.obj des.obj \ md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj serpent.obj des.obj \
safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \ safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \
blowfish.obj crypt.obj ampi.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj
library: $(OBJECTS) library: $(OBJECTS)
lib /out:tomcrypt.lib $(OBJECTS) lib /out:tomcrypt.lib $(OBJECTS)

4
md2.c
View File

@ -136,6 +136,9 @@ void md2_done(hash_state * md, unsigned char *hash)
int md2_test(void) int md2_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char md[16]; unsigned char md[16];
@ -184,6 +187,7 @@ int md2_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

4
md4.c
View File

@ -221,6 +221,9 @@ void md4_done(hash_state * md, unsigned char *hash)
int md4_test(void) int md4_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct md4_test_case { static const struct md4_test_case {
char *input; char *input;
unsigned char digest[16]; unsigned char digest[16];
@ -261,6 +264,7 @@ int md4_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

4
md5.c
View File

@ -208,6 +208,9 @@ void md5_done(hash_state * md, unsigned char *hash)
int md5_test(void) int md5_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char hash[16]; unsigned char hash[16];
@ -249,6 +252,7 @@ int md5_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

3558
mpi.c

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -9,6 +9,8 @@
#error mycrypt_custom.h should be included before mycrypt.h #error mycrypt_custom.h should be included before mycrypt.h
#endif #endif
#define LTC_TEST
#define XMALLOC malloc #define XMALLOC malloc
#define XREALLOC realloc #define XREALLOC realloc
#define XCALLOC calloc #define XCALLOC calloc

View File

@ -169,6 +169,9 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int noekeon_test(void) int noekeon_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char static const unsigned char
key[] = key[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
@ -193,6 +196,7 @@ int noekeon_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int noekeon_keysize(int *desired_keysize) int noekeon_keysize(int *desired_keysize)

145
prime.c
View File

@ -2,144 +2,17 @@
#ifdef MPI #ifdef MPI
#define UPPER_LIMIT (sizeof(prime_tab) / sizeof(prime_tab[0])) #define UPPER_LIMIT PRIME_SIZE
static const mp_digit prime_tab[] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 };
/* figures out if a number is prime (MR test) */ /* figures out if a number is prime (MR test) */
#ifdef CLEAN_STACK
static int _is_prime(mp_int *N, int *result)
#else
int is_prime(mp_int *N, int *result)
#endif
{
long x, s, j;
int res;
mp_int n1, a, y, r;
mp_digit d;
_ARGCHK(N != NULL);
_ARGCHK(result != NULL);
/* default to answer of no */
*result = 0;
/* divisible by any of the first primes? */
for (x = 0; x < (long)UPPER_LIMIT; x++) {
/* is N equal to a small prime? */
if (mp_cmp_d(N, prime_tab[x]) == 0) {
*result = 1;
return CRYPT_OK;
}
/* is N mod prime_tab[x] == 0, then its divisible by it */
if (mp_mod_d(N, prime_tab[x], &d) != MP_OKAY) {
return CRYPT_MEM;
}
if (d == 0) {
return CRYPT_OK;
}
}
/* init variables */
if (mp_init_multi(&r, &n1, &a, &y, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
/* n1 = N - 1 */
if (mp_sub_d(N, 1, &n1) != MP_OKAY) { goto error; }
/* r = N - 1 */
if (mp_copy(&n1, &r) != MP_OKAY) { goto error; }
/* find s such that N-1 = (2^s)r */
s = 0;
while (mp_iseven(&r) != 0) {
++s;
if (mp_div_2(&r, &r) != MP_OKAY) {
goto error;
}
}
for (x = 0; x < 8; x++) {
/* choose a */
mp_set(&a, prime_tab[x]);
/* compute y = a^r mod n */
if (mp_exptmod(&a, &r, N, &y) != MP_OKAY) { goto error; }
/* (y != 1) AND (y != N-1) */
if ((mp_cmp_d(&y, 1) != 0) && (mp_cmp(&y, &n1) != 0)) {
/* while j <= s-1 and y != n-1 */
for (j = 1; (j <= (s-1)) && (mp_cmp(&y, &n1) != 0); j++) {
/* y = y^2 mod N */
if (mp_sqrmod(&y, N, &y) != MP_OKAY) { goto error; }
/* if y == 1 return false */
if (mp_cmp_d(&y, 1) == 0) { goto ok; }
}
/* if y != n-1 return false */
if (mp_cmp(&y, &n1) != 0) { goto ok; }
}
}
*result = 1;
ok:
res = CRYPT_OK;
goto done;
error:
res = CRYPT_MEM;
done:
mp_clear_multi(&a, &y, &n1, &r, NULL);
return res;
}
#ifdef CLEAN_STACK
int is_prime(mp_int *N, int *result) int is_prime(mp_int *N, int *result)
{ {
int x; int err;
x = _is_prime(N, result); if ((err = mp_prime_is_prime(N, 8, result)) != MP_OKAY) {
burn_stack(sizeof(long) * 3 + sizeof(int) + sizeof(mp_int) * 4 + sizeof(mp_digit)); return CRYPT_MEM;
return x; }
return CRYPT_OK;
} }
#endif
static int next_prime(mp_int *N, mp_digit step) static int next_prime(mp_int *N, mp_digit step)
{ {
@ -152,7 +25,7 @@ static int next_prime(mp_int *N, mp_digit step)
/* first find the residues */ /* first find the residues */
for (x = 0; x < (long)UPPER_LIMIT; x++) { for (x = 0; x < (long)UPPER_LIMIT; x++) {
if (mp_mod_d(N, prime_tab[x], &residues[x]) != MP_OKAY) { if (mp_mod_d(N, __prime_tab[x], &residues[x]) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
} }
@ -168,7 +41,7 @@ loop:
dist = step; dist = step;
for (x = 0; (dist < (MP_DIGIT_MAX-step-1)) && (x < (long)UPPER_LIMIT); x++) { for (x = 0; (dist < (MP_DIGIT_MAX-step-1)) && (x < (long)UPPER_LIMIT); x++) {
j = (long)residues[x] + (long)dist + total_dist; j = (long)residues[x] + (long)dist + total_dist;
if (j % (long)prime_tab[x] == 0) { if (j % (long)__prime_tab[x] == 0) {
dist += step; x = -1; dist += step; x = -1;
} }
} }
@ -195,7 +68,7 @@ loop:
} }
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
/* choose a */ /* choose a */
mp_set(&a, prime_tab[x]); mp_set(&a, __prime_tab[x]);
/* compute y = a^r mod n */ /* compute y = a^r mod n */
if (mp_exptmod(&a, &r, N, &y) != MP_OKAY) { goto error; } if (mp_exptmod(&a, &r, N, &y) != MP_OKAY) { goto error; }

4
rc2.c
View File

@ -239,6 +239,9 @@ void rc2_ecb_decrypt( const unsigned char *cipher,
int rc2_test(void) int rc2_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
int keylen; int keylen;
unsigned char key[16], pt[8], ct[8]; unsigned char key[16], pt[8], ct[8];
@ -276,6 +279,7 @@ int rc2_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int rc2_keysize(int *keysize) int rc2_keysize(int *keysize)

4
rc5.c
View File

@ -152,6 +152,9 @@ void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
int rc5_test(void) int rc5_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
unsigned char key[16], pt[8], ct[8]; unsigned char key[16], pt[8], ct[8];
} tests[] = { } tests[] = {
@ -194,6 +197,7 @@ int rc5_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int rc5_keysize(int *desired_keysize) int rc5_keysize(int *desired_keysize)

4
rc6.c
View File

@ -156,6 +156,9 @@ void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *
int rc6_test(void) int rc6_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
int keylen; int keylen;
unsigned char key[32], pt[16], ct[16]; unsigned char key[32], pt[16], ct[16];
@ -214,6 +217,7 @@ int rc6_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int rc6_keysize(int *desired_keysize) int rc6_keysize(int *desired_keysize)

17
rsa.c
View File

@ -158,7 +158,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
*outlen = x; *outlen = x;
/* convert it */ /* convert it */
(void)mp_to_unsigned_bin(&tmp, out); if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) { goto error; }
/* clean up and return */ /* clean up and return */
res = CRYPT_OK; res = CRYPT_OK;
@ -184,7 +184,7 @@ int rsa_signpad(const unsigned char *in, unsigned long inlen,
} }
/* check inlen */ /* check inlen */
if ((inlen <= 0) || inlen > 512) { if (inlen > 512) {
return CRYPT_PK_INVALID_SIZE; return CRYPT_PK_INVALID_SIZE;
} }
@ -221,7 +221,7 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
} }
/* check inlen */ /* check inlen */
if ((inlen <= 0) || inlen > 512) { if (inlen > 512) {
return CRYPT_PK_INVALID_SIZE; return CRYPT_PK_INVALID_SIZE;
} }
@ -229,7 +229,7 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
return CRYPT_ERROR_READPRNG; return CRYPT_ERROR_READPRNG;
} }
/* pad it like a sandwitch (sp?) /* pad it like a sandwhich
* *
* Looks like 0xFF R1 M R2 0xFF * Looks like 0xFF R1 M R2 0xFF
* *
@ -407,15 +407,16 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
_ARGCHK(in != NULL); _ARGCHK(in != NULL);
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
/* check length */
if (inlen < 1+PACKET_SIZE) {
return CRYPT_INVALID_PACKET;
}
/* test packet header */ /* test packet header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) { if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err; return err;
} }
if (inlen < 1+PACKET_SIZE) {
return CRYPT_INVALID_PACKET;
}
/* init key */ /* init key */
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
&key->pQ, &key->p, &key->q, NULL) != MP_OKAY) { &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {

View File

@ -69,7 +69,7 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen, unsigned char *outkey, unsigned long *keylen,
rsa_key *key) rsa_key *key)
{ {
unsigned char sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096]; unsigned char sym_key[MAXBLOCKSIZE], rsa_out[4096];
unsigned long x, y, z, i, rsa_size; unsigned long x, y, z, i, rsa_size;
int err; int err;
@ -129,7 +129,6 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
/* clean up */ /* clean up */
zeromem(sym_key, sizeof(sym_key)); zeromem(sym_key, sizeof(sym_key));
zeromem(rsa_in, sizeof(rsa_in));
zeromem(rsa_out, sizeof(rsa_out)); zeromem(rsa_out, sizeof(rsa_out));
#endif #endif
*keylen = z; *keylen = z;
@ -150,7 +149,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
/* reject nonsense sizes */ /* reject nonsense sizes */
if (inlen < 16) { if (inlen > MAXBLOCKSIZE || inlen < 16) {
return CRYPT_INVALID_ARG; return CRYPT_INVALID_ARG;
} }

View File

@ -407,6 +407,9 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
int saferp_test(void) int saferp_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
int keylen; int keylen;
unsigned char key[32], pt[16], ct[16]; unsigned char key[32], pt[16], ct[16];
@ -459,6 +462,7 @@ int saferp_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int saferp_keysize(int *desired_keysize) int saferp_keysize(int *desired_keysize)

14
safer.c
View File

@ -344,6 +344,9 @@ int safer_128_keysize(int *keysize)
int safer_k64_test(void) int safer_k64_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 },
k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 };
@ -364,11 +367,15 @@ int safer_k64_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int safer_sk64_test(void) int safer_sk64_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 };
@ -390,10 +397,14 @@ int safer_sk64_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int safer_sk128_test(void) int safer_sk128_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8,
0, 0, 0, 0, 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0, 0, 0 },
@ -413,9 +424,8 @@ int safer_sk128_test(void)
if (memcmp(buf[0], sk128_ct, 8) != 0 || memcmp(buf[1], sk128_pt, 8) != 0) { if (memcmp(buf[0], sk128_ct, 8) != 0 || memcmp(buf[1], sk128_pt, 8) != 0) {
return CRYPT_FAIL_TESTVECTOR; return CRYPT_FAIL_TESTVECTOR;
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

View File

@ -588,6 +588,9 @@ void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int serpent_test(void) int serpent_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
int keylen; int keylen;
unsigned char key[32], pt[16], ct[16]; unsigned char key[32], pt[16], ct[16];
@ -680,6 +683,7 @@ int serpent_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int serpent_keysize(int *desired_keysize) int serpent_keysize(int *desired_keysize)

4
sha1.c
View File

@ -184,6 +184,9 @@ void sha1_done(hash_state * md, unsigned char *hash)
int sha1_test(void) int sha1_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char hash[20]; unsigned char hash[20];
@ -213,6 +216,7 @@ int sha1_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

View File

@ -180,6 +180,9 @@ void sha256_done(hash_state * md, unsigned char *hash)
int sha256_test(void) int sha256_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char hash[32]; unsigned char hash[32];
@ -211,6 +214,7 @@ int sha256_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

View File

@ -51,6 +51,9 @@ void sha384_done(hash_state * md, unsigned char *hash)
int sha384_test(void) int sha384_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char hash[48]; unsigned char hash[48];
@ -86,6 +89,7 @@ int sha384_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }

View File

@ -209,6 +209,9 @@ void sha512_done(hash_state * md, unsigned char *hash)
int sha512_test(void) int sha512_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char hash[64]; unsigned char hash[64];
@ -248,6 +251,7 @@ int sha512_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#ifdef SHA384 #ifdef SHA384

View File

@ -687,6 +687,9 @@ void tiger_done(hash_state * md, unsigned char *hash)
int tiger_test(void) int tiger_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
char *msg; char *msg;
unsigned char hash[24]; unsigned char hash[24];
@ -731,6 +734,7 @@ int tiger_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
#endif #endif

105
tommath.h
View File

@ -12,8 +12,6 @@
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <mycrypt.h>
#ifndef BN_H_ #ifndef BN_H_
#define BN_H_ #define BN_H_
@ -36,7 +34,7 @@ extern "C" {
#else #else
/* C on the other hand dosen't care */ /* C on the other hand doesn't care */
#define OPT_CAST #define OPT_CAST
#endif #endif
@ -47,7 +45,7 @@ extern "C" {
* A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
* *
* At the very least a mp_digit must be able to hold 7 bits * At the very least a mp_digit must be able to hold 7 bits
* [any size beyond that is ok provided it overflow the data type] * [any size beyond that is ok provided it doesn't overflow the data type]
*/ */
#ifdef MP_8BIT #ifdef MP_8BIT
typedef unsigned char mp_digit; typedef unsigned char mp_digit;
@ -55,9 +53,23 @@ extern "C" {
#elif defined(MP_16BIT) #elif defined(MP_16BIT)
typedef unsigned short mp_digit; typedef unsigned short mp_digit;
typedef unsigned long mp_word; typedef unsigned long mp_word;
#else #elif defined(MP_64BIT)
/* for GCC only on supported platforms */
#ifndef CRYPT #ifndef CRYPT
#ifdef _MSC_VER typedef unsigned long long ulong64;
typedef signed long long long64;
#endif
typedef ulong64 mp_digit;
typedef unsigned long mp_word __attribute__ ((mode(TI)));
#define DIGIT_BIT 60
#else
/* this is the default case, 28-bit digits */
/* this is to make porting into LibTomCrypt easier :-) */
#ifndef CRYPT
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64; typedef unsigned __int64 ulong64;
typedef signed __int64 long64; typedef signed __int64 long64;
#else #else
@ -66,17 +78,22 @@ extern "C" {
#endif #endif
#endif #endif
/* default case */
typedef unsigned long mp_digit; typedef unsigned long mp_digit;
typedef ulong64 mp_word; typedef ulong64 mp_word;
#ifdef MP_31BIT
#define DIGIT_BIT 31
#else
#define DIGIT_BIT 28 #define DIGIT_BIT 28
#endif #endif
#endif
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
#ifndef DIGIT_BIT #ifndef DIGIT_BIT
#define DIGIT_BIT ((CHAR_BIT * sizeof(mp_digit) - 1)) /* bits per digit */ #define DIGIT_BIT ((CHAR_BIT * sizeof(mp_digit) - 1)) /* bits per digit */
#endif #endif
#define MP_DIGIT_BIT DIGIT_BIT #define MP_DIGIT_BIT DIGIT_BIT
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK #define MP_DIGIT_MAX MP_MASK
@ -99,9 +116,17 @@ typedef int mp_err;
/* you'll have to tune these... */ /* you'll have to tune these... */
extern int KARATSUBA_MUL_CUTOFF, extern int KARATSUBA_MUL_CUTOFF,
KARATSUBA_SQR_CUTOFF, KARATSUBA_SQR_CUTOFF,
MONTGOMERY_EXPT_CUTOFF; TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
#define MP_PREC 64 /* default digits of precision */ /* various build options */
#define MP_PREC 64 /* default digits of precision (must be power of two) */
/* define this to use lower memory usage routines (exptmods mostly) */
/* #define MP_LOW_MEM */
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
typedef struct { typedef struct {
int used, alloc, sign; int used, alloc, sign;
@ -120,6 +145,12 @@ int mp_init(mp_int *a);
/* free a bignum */ /* free a bignum */
void mp_clear(mp_int *a); void mp_clear(mp_int *a);
/* init a null terminated series of arguments */
int mp_init_multi(mp_int *mp, ...);
/* clear a null terminated series of arguments */
void mp_clear_multi(mp_int *mp, ...);
/* exchange two ints */ /* exchange two ints */
void mp_exch(mp_int *a, mp_int *b); void mp_exch(mp_int *a, mp_int *b);
@ -145,7 +176,7 @@ void mp_zero(mp_int *a);
void mp_set(mp_int *a, mp_digit b); void mp_set(mp_int *a, mp_digit b);
/* set a 32-bit const */ /* set a 32-bit const */
int mp_set_int(mp_int *a, unsigned long b); int mp_set_int(mp_int *a, unsigned int b);
/* copy, b = a */ /* copy, b = a */
int mp_copy(mp_int *a, mp_int *b); int mp_copy(mp_int *a, mp_int *b);
@ -164,22 +195,22 @@ void mp_rshd(mp_int *a, int b);
/* left shift by "b" digits */ /* left shift by "b" digits */
int mp_lshd(mp_int *a, int b); int mp_lshd(mp_int *a, int b);
/* c = a / 2^b */ /* c = a / 2**b */
int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d); int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
/* b = a/2 */ /* b = a/2 */
int mp_div_2(mp_int *a, mp_int *b); int mp_div_2(mp_int *a, mp_int *b);
/* c = a * 2^b */ /* c = a * 2**b */
int mp_mul_2d(mp_int *a, int b, mp_int *c); int mp_mul_2d(mp_int *a, int b, mp_int *c);
/* b = a*2 */ /* b = a*2 */
int mp_mul_2(mp_int *a, mp_int *b); int mp_mul_2(mp_int *a, mp_int *b);
/* c = a mod 2^d */ /* c = a mod 2**d */
int mp_mod_2d(mp_int *a, int b, mp_int *c); int mp_mod_2d(mp_int *a, int b, mp_int *c);
/* computes a = 2^b */ /* computes a = 2**b */
int mp_2expt(mp_int *a, int b); int mp_2expt(mp_int *a, int b);
/* makes a pseudo-random int of a given size */ /* makes a pseudo-random int of a given size */
@ -218,7 +249,7 @@ int mp_sub(mp_int *a, mp_int *b, mp_int *c);
/* c = a * b */ /* c = a * b */
int mp_mul(mp_int *a, mp_int *b, mp_int *c); int mp_mul(mp_int *a, mp_int *b, mp_int *c);
/* b = a^2 */ /* b = a*a */
int mp_sqr(mp_int *a, mp_int *b); int mp_sqr(mp_int *a, mp_int *b);
/* a/b => cb + d == a */ /* a/b => cb + d == a */
@ -244,7 +275,10 @@ int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
/* a/b => cb + d == a */ /* a/b => cb + d == a */
int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d); int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
/* c = a^b */ /* a/3 => 3c + d == a */
int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
/* c = a**b */
int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
/* c = a mod b, 0 <= c < b */ /* c = a mod b, 0 <= c < b */
@ -273,7 +307,7 @@ int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
/* c = [a, b] or (a*b)/(a, b) */ /* c = [a, b] or (a*b)/(a, b) */
int mp_lcm(mp_int *a, mp_int *b, mp_int *c); int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
/* finds one of the b'th root of a, such that |c|^b <= |a| /* finds one of the b'th root of a, such that |c|**b <= |a|
* *
* returns error if a < 0 and b is even * returns error if a < 0 and b is even
*/ */
@ -290,7 +324,7 @@ int mp_reduce_setup(mp_int *a, mp_int *b);
/* Barrett Reduction, computes a (mod b) with a precomputed value c /* Barrett Reduction, computes a (mod b) with a precomputed value c
* *
* Assumes that 0 < a <= b^2, note if 0 > a > -(b^2) then you can merely * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
* compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code]. * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
*/ */
int mp_reduce(mp_int *a, mp_int *b, mp_int *c); int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
@ -298,12 +332,12 @@ int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
/* setups the montgomery reduction */ /* setups the montgomery reduction */
int mp_montgomery_setup(mp_int *a, mp_digit *mp); int mp_montgomery_setup(mp_int *a, mp_digit *mp);
/* computes a = B^n mod b without division or multiplication useful for /* computes a = B**n mod b without division or multiplication useful for
* normalizing numbers in a Montgomery system. * normalizing numbers in a Montgomery system.
*/ */
int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
/* computes xR^-1 == x (mod N) via Montgomery Reduction */ /* computes x/R == x (mod N) via Montgomery Reduction */
int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
/* returns 1 if a is a valid DR modulus */ /* returns 1 if a is a valid DR modulus */
@ -315,16 +349,31 @@ void mp_dr_setup(mp_int *a, mp_digit *d);
/* reduces a modulo b using the Diminished Radix method */ /* reduces a modulo b using the Diminished Radix method */
int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp); int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
/* d = a^b (mod c) */ /* returns true if a can be reduced with mp_reduce_2k */
int mp_reduce_is_2k(mp_int *a);
/* determines k value for 2k reduction */
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k);
/* d = a**b (mod c) */
int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d); int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
/* ---> Primes <--- */ /* ---> Primes <--- */
#define PRIME_SIZE 256 /* number of primes */
/* table of first 256 primes */ /* number of primes */
#ifdef MP_8BIT
#define PRIME_SIZE 31
#else
#define PRIME_SIZE 256
#endif
/* table of first PRIME_SIZE primes */
extern const mp_digit __prime_tab[]; extern const mp_digit __prime_tab[];
/* result=1 if a is divisible by one of the first 256 primes */ /* result=1 if a is divisible by one of the first PRIME_SIZE primes */
int mp_prime_is_divisible(mp_int *a, int *result); int mp_prime_is_divisible(mp_int *a, int *result);
/* performs one Fermat test of "a" using base "b". /* performs one Fermat test of "a" using base "b".
@ -340,7 +389,7 @@ int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
/* performs t rounds of Miller-Rabin on "a" using the first /* performs t rounds of Miller-Rabin on "a" using the first
* t prime bases. Also performs an initial sieve of trial * t prime bases. Also performs an initial sieve of trial
* division. Determines if "a" is prime with probability * division. Determines if "a" is prime with probability
* of error no more than (1/4)^t. * of error no more than (1/4)**t.
* *
* Sets result to 1 if probably prime, 0 otherwise * Sets result to 1 if probably prime, 0 otherwise
*/ */
@ -367,6 +416,9 @@ int mp_read_radix(mp_int *a, char *str, int radix);
int mp_toradix(mp_int *a, char *str, int radix); int mp_toradix(mp_int *a, char *str, int radix);
int mp_radix_size(mp_int *a, int radix); int mp_radix_size(mp_int *a, int radix);
int mp_fread(mp_int *a, int radix, FILE *stream);
int mp_fwrite(mp_int *a, int radix, FILE *stream);
#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) #define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
#define mp_raw_size(mp) mp_signed_bin_size(mp) #define mp_raw_size(mp) mp_signed_bin_size(mp)
#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) #define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
@ -390,10 +442,13 @@ int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
int fast_s_mp_sqr(mp_int *a, mp_int *b); int fast_s_mp_sqr(mp_int *a, mp_int *b);
int s_mp_sqr(mp_int *a, mp_int *b); int s_mp_sqr(mp_int *a, mp_int *b);
int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c); int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
int mp_karatsuba_sqr(mp_int *a, mp_int *b); int mp_karatsuba_sqr(mp_int *a, mp_int *b);
int mp_toom_sqr(mp_int *a, mp_int *b);
int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c); int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp); int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode); int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
void bn_reverse(unsigned char *s, int len); void bn_reverse(unsigned char *s, int len);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -633,6 +633,9 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
int twofish_test(void) int twofish_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct { static const struct {
int keylen; int keylen;
unsigned char key[32], pt[16], ct[16]; unsigned char key[32], pt[16], ct[16];
@ -682,6 +685,7 @@ int twofish_test(void)
} }
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int twofish_keysize(int *desired_keysize) int twofish_keysize(int *desired_keysize)

4
xtea.c
View File

@ -107,6 +107,9 @@ void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key
int xtea_test(void) int xtea_test(void)
{ {
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char key[16] = static const unsigned char key[16] =
{ 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a, { 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a,
0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d }; 0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d };
@ -129,6 +132,7 @@ int xtea_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int xtea_keysize(int *desired_keysize) int xtea_keysize(int *desired_keysize)