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

@ -14,21 +14,21 @@ int errnum;
int int
null_setup (const unsigned char *key, int keylen, int num_rounds, null_setup (const unsigned char *key, int keylen, int num_rounds,
symmetric_key * skey) symmetric_key * skey)
{ {
return CRYPT_OK; return CRYPT_OK;
} }
void void
null_ecb_encrypt (const unsigned char *pt, unsigned char *ct, null_ecb_encrypt (const unsigned char *pt, unsigned char *ct,
symmetric_key * key) symmetric_key * key)
{ {
memcpy (ct, pt, 8); memcpy (ct, pt, 8);
} }
void void
null_ecb_decrypt (const unsigned char *ct, unsigned char *pt, null_ecb_decrypt (const unsigned char *ct, unsigned char *pt,
symmetric_key * key) symmetric_key * key)
{ {
memcpy (pt, ct, 8); memcpy (pt, ct, 8);
} }
@ -156,7 +156,7 @@ cbc_tests (void)
/* now lets start a cbc session */ /* now lets start a cbc session */
if ((errnum = if ((errnum =
cbc_start (find_cipher ("blowfish"), IV, key, 16, 0, cbc_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cbc)) != CRYPT_OK) { &cbc)) != CRYPT_OK) {
printf ("CBC Setup: %s\n", error_to_string (errnum)); printf ("CBC Setup: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -179,7 +179,7 @@ cbc_tests (void)
/* now lets start a cbc session */ /* now lets start a cbc session */
if ((errnum = if ((errnum =
cbc_start (find_cipher ("blowfish"), IV, key, 16, 0, cbc_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cbc)) != CRYPT_OK) { &cbc)) != CRYPT_OK) {
printf ("CBC Setup: %s\n", error_to_string (errnum)); printf ("CBC Setup: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -201,12 +201,12 @@ cbc_tests (void)
/* lets actually check the bytes */ /* lets actually check the bytes */
memset (IV, 0, 8); memset (IV, 0, 8);
IV[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */ IV[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
memset (blk, 0, 32); memset (blk, 0, 32);
blk[8] = 0xFF; /* BLK = 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 */ blk[8] = 0xFF; /* BLK = 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 */
cbc_start (find_cipher ("memcpy()"), IV, key, 8, 0, &cbc); cbc_start (find_cipher ("memcpy()"), IV, key, 8, 0, &cbc);
cbc_encrypt (blk, ct, &cbc); /* expect: FF 00 00 00 00 00 00 00 */ cbc_encrypt (blk, ct, &cbc); /* expect: FF 00 00 00 00 00 00 00 */
cbc_encrypt (blk + 8, ct + 8, &cbc); /* expect: 00 00 00 00 00 00 00 00 */ cbc_encrypt (blk + 8, ct + 8, &cbc); /* expect: 00 00 00 00 00 00 00 00 */
if (memcmp (ct, test, 16)) { if (memcmp (ct, test, 16)) {
printf ("CBC failed logical testing.\n"); printf ("CBC failed logical testing.\n");
for (x = 0; x < 16; x++) for (x = 0; x < 16; x++)
@ -309,7 +309,7 @@ cfb_tests (void)
/* now lets start a cfb session */ /* now lets start a cfb session */
if ((errnum = if ((errnum =
cfb_start (find_cipher ("blowfish"), IV, key, 16, 0, cfb_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cfb)) != CRYPT_OK) { &cfb)) != CRYPT_OK) {
printf ("CFB setup: %s\n", error_to_string (errnum)); printf ("CFB setup: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -332,7 +332,7 @@ cfb_tests (void)
/* now lets start a cfb session */ /* now lets start a cfb session */
if ((errnum = if ((errnum =
cfb_start (find_cipher ("blowfish"), IV, key, 16, 0, cfb_start (find_cipher ("blowfish"), IV, key, 16, 0,
&cfb)) != CRYPT_OK) { &cfb)) != CRYPT_OK) {
printf ("CFB Setup: %s\n", error_to_string (errnum)); printf ("CFB Setup: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -380,7 +380,7 @@ ctr_tests (void)
/* now lets start a ctr session */ /* now lets start a ctr session */
if ((errnum = if ((errnum =
ctr_start (find_cipher ("xtea"), count, key, 16, 0, ctr_start (find_cipher ("xtea"), count, key, 16, 0,
&ctr)) != CRYPT_OK) { &ctr)) != CRYPT_OK) {
printf ("CTR Setup: %s\n", error_to_string (errnum)); printf ("CTR Setup: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -403,7 +403,7 @@ ctr_tests (void)
/* now lets start a cbc session */ /* now lets start a cbc session */
if ((errnum = if ((errnum =
ctr_start (find_cipher ("xtea"), count, key, 16, 0, ctr_start (find_cipher ("xtea"), count, key, 16, 0,
&ctr)) != CRYPT_OK) { &ctr)) != CRYPT_OK) {
printf ("CTR Setup: %s\n", error_to_string (errnum)); printf ("CTR Setup: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -426,12 +426,12 @@ ctr_tests (void)
/* lets actually check the bytes */ /* lets actually check the bytes */
memset (count, 0, 8); memset (count, 0, 8);
count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */ count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
memset (blk, 0, 32); memset (blk, 0, 32);
blk[9] = 2; /* BLK = 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 */ blk[9] = 2; /* BLK = 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 */
ctr_start (find_cipher ("memcpy()"), count, key, 8, 0, &ctr); ctr_start (find_cipher ("memcpy()"), count, key, 8, 0, &ctr);
ctr_encrypt (blk, ct, 8, &ctr); /* expect: FF 00 00 00 00 00 00 00 */ ctr_encrypt (blk, ct, 8, &ctr); /* expect: FF 00 00 00 00 00 00 00 */
ctr_encrypt (blk + 8, ct + 8, 8, &ctr); /* expect: 00 03 00 00 00 00 00 00 */ ctr_encrypt (blk + 8, ct + 8, 8, &ctr); /* expect: 00 03 00 00 00 00 00 00 */
if (memcmp (ct, test, 16)) { if (memcmp (ct, test, 16)) {
printf ("CTR failed logical testing.\n"); printf ("CTR failed logical testing.\n");
for (x = 0; x < 16; x++) for (x = 0; x < 16; x++)
@ -520,7 +520,7 @@ rsa_test (void)
/* encrypt a short 8 byte string */ /* encrypt a short 8 byte string */
if ((errnum = if ((errnum =
rsa_make_key (&prng, find_prng ("yarrow"), 1024 / 8, 65537, rsa_make_key (&prng, find_prng ("yarrow"), 1024 / 8, 65537,
&key)) != CRYPT_OK) { &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -555,7 +555,7 @@ rsa_test (void)
y = sizeof (out); y = sizeof (out);
if ((errnum = if ((errnum =
rsa_encrypt_key (in, 16, out, &y, &prng, find_prng ("yarrow"), rsa_encrypt_key (in, 16, out, &y, &prng, find_prng ("yarrow"),
&key)) != CRYPT_OK) { &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -614,47 +614,47 @@ rsa_test (void)
for (z = 1024; z <= limit; z += 512) { for (z = 1024; z <= limit; z += 512) {
t = XCLOCK (); t = XCLOCK ();
for (tt = 0; tt < 3; tt++) { for (tt = 0; tt < 3; tt++) {
if ((errnum = if ((errnum =
rsa_make_key (&prng, find_prng ("yarrow"), z / 8, 65537, rsa_make_key (&prng, find_prng ("yarrow"), z / 8, 65537,
&key)) != CRYPT_OK) { &key)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
if (tt < 2) if (tt < 2)
rsa_free (&key); rsa_free (&key);
} }
t = XCLOCK () - t; t = XCLOCK () - t;
printf ("Took %.0f ms to make a %ld-bit RSA key.\n", printf ("Took %.0f ms to make a %ld-bit RSA key.\n",
1000.0 * (((double) t / 3.0) / (double) XCLOCKS_PER_SEC), z); 1000.0 * (((double) t / 3.0) / (double) XCLOCKS_PER_SEC), z);
/* 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) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
} }
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) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
} }
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);
} }
} }
@ -765,9 +765,9 @@ time_hash (void)
} }
t1 = XCLOCK () - t1; t1 = XCLOCK () - t1;
printf ("%-20s: Hash at %5.2f Mbit/sec\n", hash_descriptor[x].name, printf ("%-20s: Hash at %5.2f Mbit/sec\n", hash_descriptor[x].name,
((8.0 * 4096.0) * ((8.0 * 4096.0) *
((double) y / ((double) t1 / (double) XCLOCKS_PER_SEC))) / ((double) y / ((double) t1 / (double) XCLOCKS_PER_SEC))) /
1000000.0); 1000000.0);
} }
} }
@ -783,7 +783,7 @@ time_ecb (void)
printf ("ECB Time Trials for the Symmetric Ciphers:\n"); printf ("ECB Time Trials for the Symmetric Ciphers:\n");
for (x = 0; cipher_descriptor[x].name != NULL; x++) { for (x = 0; cipher_descriptor[x].name != NULL; x++) {
cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0, cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0,
&skey); &skey);
#define DO1 func(pt,pt,&skey); #define DO1 func(pt,pt,&skey);
#define DO2 DO1 DO1 #define DO2 DO1 DO1
@ -816,9 +816,9 @@ time_ecb (void)
("%-20s: Encrypt at %5.2f Mbit/sec and Decrypt at %5.2f Mbit/sec\n", ("%-20s: Encrypt at %5.2f Mbit/sec and Decrypt at %5.2f Mbit/sec\n",
cipher_descriptor[x].name, cipher_descriptor[x].name,
((8.0 * (double) cipher_descriptor[x].block_length) * ((8.0 * (double) cipher_descriptor[x].block_length) *
((double) y1 / ((double) t1 / (double) XCLOCKS_PER_SEC))) / 1000000.0, ((double) y1 / ((double) t1 / (double) XCLOCKS_PER_SEC))) / 1000000.0,
((8.0 * (double) cipher_descriptor[x].block_length) * ((8.0 * (double) cipher_descriptor[x].block_length) *
((double) y2 / ((double) t2 / (double) XCLOCKS_PER_SEC))) / ((double) y2 / ((double) t2 / (double) XCLOCKS_PER_SEC))) /
1000000.0); 1000000.0);
#undef DO256 #undef DO256
@ -843,7 +843,7 @@ dh_tests (void)
dh_key usera, userb; dh_key usera, userb;
clock_t t1; clock_t t1;
/* if ((errnum = dh_test()) != CRYPT_OK) printf("DH Error: %s\n", error_to_string(errnum)); */ /* if ((errnum = dh_test()) != CRYPT_OK) printf("DH Error: %s\n", error_to_string(errnum)); */
dh_sizes (&low, &high); dh_sizes (&low, &high);
printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8); printf ("DH Keys from %d to %d supported.\n", low * 8, high * 8);
@ -921,12 +921,12 @@ dh_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 < 5; tt++) { for (tt = 0; tt < 5; tt++) {
dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera); dh_make_key (&prng, find_prng ("yarrow"), sizes[ii], &usera);
dh_free (&usera); dh_free (&usera);
} }
t1 = XCLOCK () - t1; t1 = XCLOCK () - t1;
printf ("Make dh-%d key took %f msec\n", sizes[ii] * 8, printf ("Make dh-%d key took %f msec\n", sizes[ii] * 8,
1000.0 * (((double) t1 / 5.0) / (double) XCLOCKS_PER_SEC)); 1000.0 * (((double) t1 / 5.0) / (double) XCLOCKS_PER_SEC));
} }
} }
@ -937,7 +937,7 @@ dh_tests (void)
y = sizeof (buf[1]); y = sizeof (buf[1]);
if ((errnum = if ((errnum =
dh_encrypt_key (buf[0], 16, buf[1], &y, &prng, find_prng ("yarrow"), dh_encrypt_key (buf[0], 16, buf[1], &y, &prng, find_prng ("yarrow"),
find_hash ("md5"), &usera)) != CRYPT_OK) { find_hash ("md5"), &usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -965,7 +965,7 @@ dh_tests (void)
x = sizeof (buf[1]); x = sizeof (buf[1]);
if ((errnum = if ((errnum =
dh_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"), dh_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"),
&usera)) != CRYPT_OK) { &usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -979,8 +979,8 @@ dh_tests (void)
exit (-1); exit (-1);
} }
printf ("dh_sign/verify_hash: %s (%d,%d), %lu\n", printf ("dh_sign/verify_hash: %s (%d,%d), %lu\n",
((stat == 1) ((stat == 1)
&& (stat2 == 0)) ? "passed" : "failed", stat, stat2, x); && (stat2 == 0)) ? "passed" : "failed", stat, stat2, x);
dh_free (&usera); dh_free (&usera);
} }
#else #else
@ -1013,7 +1013,7 @@ rng_tests (void)
x = rng_get_bytes (buf, sizeof (buf), &callback); x = rng_get_bytes (buf, sizeof (buf), &callback);
t1 = XCLOCK () - t1; t1 = XCLOCK () - t1;
printf (" %f bytes per second...", printf (" %f bytes per second...",
(double) x / ((double) t1 / (double) XCLOCKS_PER_SEC)); (double) x / ((double) t1 / (double) XCLOCKS_PER_SEC));
printf ("read %d bytes.\n ", x); printf ("read %d bytes.\n ", x);
for (y = 0; y < x; y++) for (y = 0; y < x; y++)
printf ("%02x ", buf[y]); printf ("%02x ", buf[y]);
@ -1022,7 +1022,7 @@ rng_tests (void)
#ifdef YARROW #ifdef YARROW
if ((errnum = if ((errnum =
rng_make_prng (128, find_prng ("yarrow"), &prng, rng_make_prng (128, find_prng ("yarrow"), &prng,
&callback)) != CRYPT_OK) { &callback)) != CRYPT_OK) {
printf (" starting yarrow error: %s\n", error_to_string (errnum)); printf (" starting yarrow error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1123,18 +1123,18 @@ 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) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
ecc_free (&usera); ecc_free (&usera);
} }
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));
} }
} }
@ -1145,7 +1145,7 @@ ecc_tests (void)
y = sizeof (buf[1]); y = sizeof (buf[1]);
if ((errnum = if ((errnum =
ecc_encrypt_key (buf[0], 32, buf[1], &y, &prng, find_prng ("yarrow"), ecc_encrypt_key (buf[0], 32, buf[1], &y, &prng, find_prng ("yarrow"),
find_hash ("sha256"), &usera)) != CRYPT_OK) { find_hash ("sha256"), &usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1172,7 +1172,7 @@ ecc_tests (void)
x = sizeof (buf[1]); x = sizeof (buf[1]);
if ((errnum = if ((errnum =
ecc_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"), ecc_sign_hash (buf[0], 16, buf[1], &x, &prng, find_prng ("yarrow"),
&usera)) != CRYPT_OK) { &usera)) != CRYPT_OK) {
printf ("Error: %s\n", error_to_string (errnum)); printf ("Error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1187,7 +1187,7 @@ ecc_tests (void)
exit (-1); exit (-1);
} }
printf ("ecc_sign/verify_hash: %s (%d,%d)\n", printf ("ecc_sign/verify_hash: %s (%d,%d)\n",
((stat == 1) && (stat2 == 0)) ? "passed" : "failed", stat, stat2); ((stat == 1) && (stat2 == 0)) ? "passed" : "failed", stat, stat2);
ecc_free (&usera); ecc_free (&usera);
} }
#else #else
@ -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
@ -1383,8 +1383,8 @@ kr_display (pk_key * kr)
while (kr->system != NON_KEY) { while (kr->system != NON_KEY) {
printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID, printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
sys[kr->system], type[kr->key_type], kr->name, kr->email, sys[kr->system], type[kr->key_type], kr->name, kr->email,
kr->description); kr->description);
kr = kr->next; kr = kr->next;
} }
printf ("\n"); printf ("\n");
@ -1402,7 +1402,7 @@ kr_test_makekeys (pk_key ** kr)
printf ("KR: Making DH key...\n"); printf ("KR: Making DH key...\n");
if ((errnum = if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey", kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey",
"dh@dh.dh", "dhkey one")) != CRYPT_OK) { "dh@dh.dh", "dhkey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum)); printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1411,7 +1411,7 @@ kr_test_makekeys (pk_key ** kr)
printf ("KR: Making ECC key...\n"); printf ("KR: Making ECC key...\n");
if ((errnum = if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey", kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey",
"ecc@ecc.ecc", "ecckey one")) != CRYPT_OK) { "ecc@ecc.ecc", "ecckey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum)); printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1420,7 +1420,7 @@ kr_test_makekeys (pk_key ** kr)
printf ("KR: Making RSA key...\n"); printf ("KR: Making RSA key...\n");
if ((errnum = if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey", kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey",
"rsa@rsa.rsa", "rsakey one")) != CRYPT_OK) { "rsa@rsa.rsa", "rsakey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum)); printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1533,12 +1533,12 @@ kr_test (void)
_kr = kr; _kr = kr;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
printf ("Testing a key with system %d, type %d:\t", _kr->system, printf ("Testing a key with system %d, type %d:\t", _kr->system,
_kr->key_type); _kr->key_type);
len = sizeof (buf2); len = sizeof (buf2);
if ((errnum = if ((errnum =
kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng, kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
find_prng ("yarrow"), find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) { find_hash ("md5"))) != CRYPT_OK) {
printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum)); printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1555,8 +1555,8 @@ kr_test (void)
len = sizeof (buf2); len = sizeof (buf2);
if ((errnum = if ((errnum =
kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng, kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
find_prng ("yarrow"))) != CRYPT_OK) { find_prng ("yarrow"))) != CRYPT_OK) {
printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum)); printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
exit (-1); exit (-1);
} }
@ -1576,8 +1576,8 @@ kr_test (void)
len = sizeof (buf); len = sizeof (buf);
if ((errnum = if ((errnum =
kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf, kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
&len)) != CRYPT_OK) { &len)) != CRYPT_OK) {
printf ("kr_fingerprint failed, %i, %lu\n", i, len); printf ("kr_fingerprint failed, %i, %lu\n", i, len);
exit (-1); exit (-1);
} }
@ -1585,7 +1585,7 @@ kr_test (void)
for (j = 0; j < 20; j++) { for (j = 0; j < 20; j++) {
printf ("%02x", buf[j]); printf ("%02x", buf[j]);
if (j < 19) if (j < 19)
printf (":"); printf (":");
} }
printf ("\n\n"); printf ("\n\n");
@ -1633,8 +1633,8 @@ kr_test (void)
len = sizeof (buf3); len = sizeof (buf3);
if ((errnum = if ((errnum =
kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng, kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng,
find_prng ("yarrow"), find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) { find_hash ("md5"))) != CRYPT_OK) {
printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum)); printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1); exit (-1);
} }

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)

48
dh.c
View File

@ -109,7 +109,7 @@ static const struct {
#ifdef DH4096 #ifdef DH4096
{ {
512, 512,
"DH-4096", "DH-4096",
"3", "3",
"Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS" "Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS"
"32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw" "32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw"
@ -125,7 +125,7 @@ static const struct {
"PT0+ZAUyLSAVHbsul++cawh" "PT0+ZAUyLSAVHbsul++cawh"
}, },
#endif #endif
{ {
0, 0,
NULL, NULL,
NULL, NULL,
@ -160,7 +160,7 @@ int dh_test(void)
/* ensure p is prime */ /* ensure p is prime */
if ((res = is_prime(&p, &primality)) != CRYPT_OK) { goto done; } if ((res = is_prime(&p, &primality)) != CRYPT_OK) { goto done; }
if (primality == 0) { if (primality == 0) {
res = CRYPT_FAIL_TESTVECTOR; res = CRYPT_FAIL_TESTVECTOR;
goto done; goto done;
} }
@ -213,7 +213,7 @@ int dh_get_size(dh_key *key)
return INT_MAX; /* large value that would cause dh_make_key() to fail */ return INT_MAX; /* large value that would cause dh_make_key() to fail */
} }
} }
int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key) int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
{ {
unsigned char buf[512]; unsigned char buf[512];
@ -232,7 +232,7 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
#ifdef FAST_PK #ifdef FAST_PK
keysize = MIN(sets[x].size, 32); keysize = MIN(sets[x].size, 32);
#else #else
keysize = sets[x].size; keysize = sets[x].size;
#endif #endif
@ -257,7 +257,7 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
if (mp_read_unsigned_bin(&key->x, buf, keysize) != MP_OKAY) { goto error; } if (mp_read_unsigned_bin(&key->x, buf, keysize) != MP_OKAY) { goto error; }
if (mp_exptmod(&g, &key->x, &p, &key->y) != MP_OKAY) { goto error; } if (mp_exptmod(&g, &key->x, &p, &key->y) != MP_OKAY) { goto error; }
key->type = PK_PRIVATE; key->type = PK_PRIVATE;
if (mp_shrink(&key->x) != MP_OKAY) { goto error; } if (mp_shrink(&key->x) != MP_OKAY) { goto error; }
if (mp_shrink(&key->y) != MP_OKAY) { goto error; } if (mp_shrink(&key->y) != MP_OKAY) { goto error; }
@ -341,11 +341,11 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
/* export y */ /* export y */
OUTPUT_BIGNUM(&key->y, buf2, y, z); OUTPUT_BIGNUM(&key->y, buf2, y, z);
if (type == PK_PRIVATE) { if (type == PK_PRIVATE) {
/* export x */ /* export x */
OUTPUT_BIGNUM(&key->x, buf2, y, z); OUTPUT_BIGNUM(&key->x, buf2, y, z);
} }
/* check for overflow */ /* check for overflow */
if (*outlen < y) { if (*outlen < y) {
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
@ -362,9 +362,9 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
memcpy(out, buf2, (size_t)y); memcpy(out, buf2, (size_t)y);
/* clear mem */ /* clear mem */
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
zeromem(buf2, sizeof(buf2)); zeromem(buf2, sizeof(buf2));
#endif #endif
return CRYPT_OK; return CRYPT_OK;
} }
@ -376,24 +376,30 @@ 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);
/* check type byte */ /* make sure valid length */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
if (2+PACKET_SIZE > inlen) { if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET; return CRYPT_INVALID_PACKET;
} }
/* check type byte */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* 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++);
if (sets[x].size == 0) { if (sets[x].size == 0) {
err = CRYPT_INVALID_KEYSIZE; err = CRYPT_INVALID_KEYSIZE;
@ -423,7 +429,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
/* eliminate private key if public */ /* eliminate private key if public */
if (key->type == PK_PUBLIC) { if (key->type == PK_PUBLIC) {
mp_clear(&key->x); mp_clear(&key->x);
} }
return CRYPT_OK; return CRYPT_OK;
error: error:
@ -431,7 +437,7 @@ error:
return err; return err;
} }
int dh_shared_secret(dh_key *private_key, dh_key *public_key, int dh_shared_secret(dh_key *private_key, dh_key *public_key,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
mp_int tmp, p; mp_int tmp, p;
@ -454,7 +460,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
} }
/* compute y^x mod p */ /* compute y^x mod p */
if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) { if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
@ -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)

166
ecc.c
View File

@ -30,7 +30,7 @@ static const struct {
}, },
#endif #endif
#ifdef ECC192 #ifdef ECC192
{ {
24, 24,
"ECC-192", "ECC-192",
/* prime */ /* prime */
@ -65,7 +65,7 @@ static const struct {
/* Gx */ /* Gx */
"jpqOf1BHus6Yd/pyhyVpP", "jpqOf1BHus6Yd/pyhyVpP",
/* Gy */ /* Gy */
"3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck", "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
}, },
@ -88,7 +88,7 @@ static const struct {
/* Gy */ /* Gy */
"4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r" "4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r"
}, },
#endif #endif
#ifdef ECC384 #ifdef ECC384
{ {
@ -97,11 +97,11 @@ static const struct {
/* prime */ /* prime */
"//////////////////////////////////////////x/////00000000003/" "//////////////////////////////////////////x/////00000000003/"
"////", "////",
/* B */ /* B */
"ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ" "ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ"
"x2hl", "x2hl",
/* Order */ /* Order */
"////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC" "////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC"
"nIbp", "nIbp",
@ -109,7 +109,7 @@ static const struct {
/* Gx and Gy */ /* Gx and Gy */
"geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo" "geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo"
"TWgt", "TWgt",
"DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG" "DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG"
"wWvV" "wWvV"
}, },
@ -118,22 +118,22 @@ static const struct {
{ {
65, 65,
"ECC-521", "ECC-521",
/* prime */ /* prime */
"V///////////////////////////////////////////////////////////" "V///////////////////////////////////////////////////////////"
"///////////////////////////", "///////////////////////////",
/* B */ /* B */
"56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l" "56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l"
"JknlmSrSz+8FImqyUz57zHhK3y0", "JknlmSrSz+8FImqyUz57zHhK3y0",
/* Order */ /* Order */
"V//////////////////////////////////////////+b66XuE/BvPhVym1I" "V//////////////////////////////////////////+b66XuE/BvPhVym1I"
"FS9fT0xjScuYPn7hhjljnwHE6G9", "FS9fT0xjScuYPn7hhjljnwHE6G9",
/* Gx and Gy */ /* Gx and Gy */
"CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19" "CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19"
"wB/gDupIBF1XMf2c/b+VZ72vRrc", "wB/gDupIBF1XMf2c/b+VZ72vRrc",
"HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0" "HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0"
"J+j1s4rF726edB2G8Y+b7QVqMPG", "J+j1s4rF726edB2G8Y+b7QVqMPG",
}, },
@ -189,7 +189,7 @@ void ecc_find_base(void)
mp_sqrmod(&tmp2, &p, &tmp2); mp_sqrmod(&tmp2, &p, &tmp2);
/* tmp2 should equal tmp1 */ /* tmp2 should equal tmp1 */
} while (mp_cmp(&tmp1, &tmp2)); } while (mp_cmp(&tmp1, &tmp2));
/* now output values in way that libtomcrypt wants */ /* now output values in way that libtomcrypt wants */
mp_todecimal(&p, buf); mp_todecimal(&p, buf);
@ -249,8 +249,8 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
{ {
mp_int s, tmp, tmpx; mp_int s, tmp, tmpx;
int res; int res;
if (mp_init_multi(&s, &tmp, &tmpx, NULL) != MP_OKAY) { if (mp_init_multi(&s, &tmp, &tmpx, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
@ -293,8 +293,8 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus,
{ {
mp_int s, tmp, tmpx; mp_int s, tmp, tmpx;
int res; int res;
if (mp_init(&tmp) != MP_OKAY) { if (mp_init(&tmp) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
@ -303,14 +303,14 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus,
mp_clear(&tmp); mp_clear(&tmp);
return CRYPT_MEM; return CRYPT_MEM;
} }
if (mp_cmp(&P->x, &Q->x) == MP_EQ) if (mp_cmp(&P->x, &Q->x) == MP_EQ)
if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) { if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) {
mp_clear(&tmp); mp_clear(&tmp);
return dbl_point(P, R, modulus, mu); return dbl_point(P, R, modulus, mu);
} }
if (mp_init_multi(&tmpx, &s, NULL) != MP_OKAY) { if (mp_init_multi(&tmpx, &s, NULL) != MP_OKAY) {
mp_clear(&tmp); mp_clear(&tmp);
return CRYPT_MEM; return CRYPT_MEM;
} }
@ -360,7 +360,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
mp_int mu; mp_int mu;
mp_digit buf; mp_digit buf;
int first, bitbuf, bitcpy, bitcnt, mode, digidx; int first, bitbuf, bitcpy, bitcnt, mode, digidx;
/* init barrett reduction */ /* init barrett reduction */
if (mp_init(&mu) != MP_OKAY) { if (mp_init(&mu) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
@ -369,7 +369,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
mp_clear(&mu); mp_clear(&mu);
return CRYPT_MEM; return CRYPT_MEM;
} }
/* alloc ram for window temps */ /* alloc ram for window temps */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
M[i] = new_point(); M[i] = new_point();
@ -381,7 +381,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
return CRYPT_MEM; return CRYPT_MEM;
} }
} }
/* make a copy of G incase R==G */ /* make a copy of G incase R==G */
tG = new_point(); tG = new_point();
if (tG == NULL) { goto error; } if (tG == NULL) { goto error; }
@ -391,12 +391,12 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
if (dbl_point(G, M[0], modulus, &mu) != CRYPT_OK) { goto error; } if (dbl_point(G, M[0], modulus, &mu) != CRYPT_OK) { goto error; }
if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; } if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; }
if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; } if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK) { goto error; }
/* now find (8+k)G for k=1..7 */ /* now find (8+k)G for k=1..7 */
for (j = 9; j < 16; j++) { for (j = 9; j < 16; j++) {
if (add_point(M[j-9], G, M[j-8], modulus, &mu) != CRYPT_OK) { goto error; } if (add_point(M[j-9], G, M[j-8], modulus, &mu) != CRYPT_OK) { goto error; }
} }
/* tG = G */ /* tG = G */
if (mp_copy(&G->x, &tG->x) != MP_OKAY) { goto error; } if (mp_copy(&G->x, &tG->x) != MP_OKAY) { goto error; }
if (mp_copy(&G->y, &tG->y) != MP_OKAY) { goto error; } if (mp_copy(&G->y, &tG->y) != MP_OKAY) { goto error; }
@ -408,13 +408,13 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
digidx = k->used - 1; digidx = k->used - 1;
bitcpy = bitbuf = 0; bitcpy = bitbuf = 0;
first = 1; first = 1;
/* perform ops */ /* perform ops */
for (;;) { for (;;) {
/* grab next digit as required */ /* grab next digit as required */
if (--bitcnt == 0) { if (--bitcnt == 0) {
if (digidx == -1) { if (digidx == -1) {
break; break;
} }
buf = k->dp[digidx--]; buf = k->dp[digidx--];
bitcnt = (int) DIGIT_BIT; bitcnt = (int) DIGIT_BIT;
@ -423,17 +423,18 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
/* grab the next msb from the multiplicand */ /* grab the next msb from the multiplicand */
i = (buf >> (DIGIT_BIT - 1)) & 1; i = (buf >> (DIGIT_BIT - 1)) & 1;
buf <<= 1; buf <<= 1;
/* skip leading zero bits */ /* skip leading zero bits */
if (mode == 0 && i == 0) if (mode == 0 && i == 0) {
continue;
/* if the bit is zero and mode == 1 then we double */
if (mode == 1 && i == 0) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
continue; continue;
} }
/* if the bit is zero and mode == 1 then we double */
if (mode == 1 && i == 0) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
continue;
}
/* else we add it to the window */ /* else we add it to the window */
bitbuf |= (i << (WINSIZE - ++bitcpy)); bitbuf |= (i << (WINSIZE - ++bitcpy));
mode = 2; mode = 2;
@ -442,39 +443,35 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
/* if this is the first window we do a simple copy */ /* if this is the first window we do a simple copy */
if (first == 1) { if (first == 1) {
/* R = kG [k = first window] */ /* R = kG [k = first window] */
if (mp_copy(&M[bitbuf-8]->x, &R->x) != MP_OKAY) { goto error; } if (mp_copy(&M[bitbuf-8]->x, &R->x) != MP_OKAY) { goto error; }
if (mp_copy(&M[bitbuf-8]->y, &R->y) != MP_OKAY) { goto error; } if (mp_copy(&M[bitbuf-8]->y, &R->y) != MP_OKAY) { goto error; }
first = 0; first = 0;
} else { } else {
/* normal window */ /* normal window */
/* ok window is filled so double as required and add */ /* ok window is filled so double as required and add */
/* double first */ /* double first */
for (j = 0; j < WINSIZE; j++) { for (j = 0; j < WINSIZE; j++) {
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, M[bitbuf-8], R, modulus, &mu) != CRYPT_OK) { goto error; }
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; }
}
} }
/* empty window and reset */ /* empty window and reset */
bitcpy = bitbuf = 0; bitcpy = bitbuf = 0;
mode = 1; mode = 1;
} }
} }
/* if bits remain then double/add */ /* if bits remain then double/add */
if (mode == 2 && bitcpy > 0) { if (mode == 2 && bitcpy > 0) {
/* double then add */ /* double then add */
for (j = 0; j < bitcpy; j++) { for (j = 0; j < bitcpy; j++) {
/* only double if we have had at least one add first */ /* only double if we have had at least one add first */
if (first == 0) { if (first == 0) {
if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; } if (dbl_point(R, R, modulus, &mu) != CRYPT_OK) { goto error; }
} }
bitbuf <<= 1; bitbuf <<= 1;
if ((bitbuf & (1 << WINSIZE)) != 0) { if ((bitbuf & (1 << WINSIZE)) != 0) {
if (first == 1){ if (first == 1){
@ -489,7 +486,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
} }
} }
} }
res = CRYPT_OK; res = CRYPT_OK;
goto done; goto done;
error: error:
res = CRYPT_MEM; res = CRYPT_MEM;
@ -510,18 +507,18 @@ int ecc_test(void)
ecc_point *G, *GG; ecc_point *G, *GG;
int i, res, primality; int i, res, primality;
if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) { if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
G = new_point(); G = new_point();
if (G == NULL) { if (G == NULL) {
mp_clear_multi(&modulus, &order, NULL); mp_clear_multi(&modulus, &order, NULL);
return CRYPT_MEM; return CRYPT_MEM;
} }
GG = new_point(); GG = new_point();
if (GG == NULL) { if (GG == NULL) {
mp_clear_multi(&modulus, &order, NULL); mp_clear_multi(&modulus, &order, NULL);
del_point(G); del_point(G);
return CRYPT_MEM; return CRYPT_MEM;
@ -540,7 +537,7 @@ int ecc_test(void)
res = CRYPT_FAIL_TESTVECTOR; res = CRYPT_FAIL_TESTVECTOR;
goto done1; goto done1;
} }
/* is order prime ? */ /* is order prime ? */
if (is_prime(&order, &primality) != CRYPT_OK) { goto error; } if (is_prime(&order, &primality) != CRYPT_OK) { goto error; }
if (primality == 0) { if (primality == 0) {
@ -579,11 +576,11 @@ void ecc_sizes(int *low, int *high)
*low = INT_MAX; *low = INT_MAX;
*high = 0; *high = 0;
for (i = 0; sets[i].size != 0; i++) { for (i = 0; sets[i].size != 0; i++) {
if (sets[i].size < *low) { if (sets[i].size < *low) {
*low = sets[i].size; *low = sets[i].size;
} }
if (sets[i].size > *high) { if (sets[i].size > *high) {
*high = sets[i].size; *high = sets[i].size;
} }
} }
} }
@ -606,7 +603,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++); for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
keysize = sets[x].size; keysize = sets[x].size;
if (sets[x].size == 0) { if (sets[x].size == 0) {
return CRYPT_INVALID_KEYSIZE; return CRYPT_INVALID_KEYSIZE;
} }
key->idx = x; key->idx = x;
@ -617,7 +614,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
} }
/* setup the key variables */ /* setup the key variables */
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) { if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
base = new_point(); base = new_point();
@ -635,7 +632,7 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
/* make the public key */ /* make the public key */
if (ecc_mulmod(&key->k, base, &key->pubkey, &prime) != CRYPT_OK) { goto error; } if (ecc_mulmod(&key->k, base, &key->pubkey, &prime) != CRYPT_OK) { goto error; }
key->type = PK_PRIVATE; key->type = PK_PRIVATE;
/* shrink key */ /* shrink key */
if (mp_shrink(&key->k) != MP_OKAY) { goto error; } if (mp_shrink(&key->k) != MP_OKAY) { goto error; }
if (mp_shrink(&key->pubkey.x) != MP_OKAY) { goto error; } if (mp_shrink(&key->pubkey.x) != MP_OKAY) { goto error; }
@ -689,12 +686,12 @@ static int compress_y_point(ecc_point *pt, int idx, int *result)
if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */ if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
/* if tmp equals the y point give a 0, otherwise 1 */ /* if tmp equals the y point give a 0, otherwise 1 */
if (mp_cmp(&tmp, &pt->y) == 0) { if (mp_cmp(&tmp, &pt->y) == 0) {
*result = 0; *result = 0;
} else { } else {
*result = 1; *result = 1;
} }
res = CRYPT_OK; res = CRYPT_OK;
goto done; goto done;
error: error:
@ -710,7 +707,7 @@ static int expand_y_point(ecc_point *pt, int idx, int result)
int res; int res;
_ARGCHK(pt != NULL); _ARGCHK(pt != NULL);
if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) { if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
@ -736,7 +733,7 @@ static int expand_y_point(ecc_point *pt, int idx, int result)
} else { } else {
if (mp_sub(&p, &tmp, &pt->y) != MP_OKAY) { goto error; } if (mp_sub(&p, &tmp, &pt->y) != MP_OKAY) { goto error; }
} }
res = CRYPT_OK; res = CRYPT_OK;
goto done; goto done;
error: error:
@ -795,8 +792,8 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
/* type valid? */ /* type valid? */
if (key->type != PK_PRIVATE && type == PK_PRIVATE) { if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
return CRYPT_PK_TYPE_MISMATCH; return CRYPT_PK_TYPE_MISMATCH;
} }
/* output type and magic byte */ /* output type and magic byte */
@ -818,7 +815,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
} }
/* check size */ /* check size */
if (*outlen < y) { if (*outlen < y) {
return CRYPT_BUFFER_OVERFLOW; return CRYPT_BUFFER_OVERFLOW;
} }
@ -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 type */ /* check length */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
if (2+PACKET_SIZE > inlen) { if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET; return CRYPT_INVALID_PACKET;
} }
/* check type */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* 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;
@ -859,9 +857,9 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
y = PACKET_SIZE; y = PACKET_SIZE;
key->type = (int)in[y++]; key->type = (int)in[y++];
s = (unsigned long)in[y++]; s = (unsigned long)in[y++];
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++);
if (sets[x].size == 0) { if (sets[x].size == 0) {
err = CRYPT_INVALID_KEYSIZE; err = CRYPT_INVALID_KEYSIZE;
goto error; goto error;
} }
@ -881,30 +879,30 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
/* load x coordinate */ /* load x coordinate */
INPUT_BIGNUM(&key->pubkey.x, in, x, y); INPUT_BIGNUM(&key->pubkey.x, in, x, y);
/* load y */ /* load y */
x = (unsigned long)in[y++]; x = (unsigned long)in[y++];
if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) { if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) {
goto error; goto error;
} }
if (key->type == PK_PRIVATE) { if (key->type == PK_PRIVATE) {
/* load private key */ /* load private key */
INPUT_BIGNUM(&key->k, in, x, y); INPUT_BIGNUM(&key->k, in, x, y);
} }
/* eliminate private key if public */ /* eliminate private key if public */
if (key->type == PK_PUBLIC) { if (key->type == PK_PUBLIC) {
mp_clear(&key->k); mp_clear(&key->k);
} }
return CRYPT_OK; return CRYPT_OK;
error: error:
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL); mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
return err; return err;
} }
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned long x, y; unsigned long x, y;
@ -928,17 +926,17 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
/* make new point */ /* make new point */
result = new_point(); result = new_point();
if (result == NULL) { if (result == NULL) {
return CRYPT_MEM; return CRYPT_MEM;
} }
if (mp_init(&prime) != MP_OKAY) { if (mp_init(&prime) != MP_OKAY) {
del_point(result); del_point(result);
return CRYPT_MEM; return CRYPT_MEM;
} }
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

13200
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

@ -1,14 +1,16 @@
/* This header is meant to be included before mycrypt.h in projects where /* This header is meant to be included before mycrypt.h in projects where
* you don't want to throw all the defines in a makefile. * you don't want to throw all the defines in a makefile.
*/ */
#ifndef MYCRYPT_CUSTOM_H_ #ifndef MYCRYPT_CUSTOM_H_
#define MYCRYPT_CUSTOM_H_ #define MYCRYPT_CUSTOM_H_
#ifdef CRYPT #ifdef CRYPT
#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,13 +196,14 @@ int noekeon_test(void)
} }
return CRYPT_OK; return CRYPT_OK;
#endif
} }
int noekeon_keysize(int *desired_keysize) int noekeon_keysize(int *desired_keysize)
{ {
_ARGCHK(desired_keysize != NULL); _ARGCHK(desired_keysize != NULL);
if (*desired_keysize < 16) { if (*desired_keysize < 16) {
return CRYPT_INVALID_KEYSIZE; return CRYPT_INVALID_KEYSIZE;
} else { } else {
*desired_keysize = 16; *desired_keysize = 16;
return CRYPT_OK; return CRYPT_OK;

147
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)

87
rsa.c
View File

@ -5,7 +5,7 @@
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
{ {
mp_int p, q, tmp1, tmp2, tmp3; mp_int p, q, tmp1, tmp2, tmp3;
int res, err; int res, err;
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
@ -16,7 +16,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if ((e < 3) || ((e & 1) == 0)) { if ((e < 3) || ((e & 1) == 0)) {
return CRYPT_INVALID_ARG; return CRYPT_INVALID_ARG;
} }
if ((err = prng_is_valid(wprng)) != CRYPT_OK) { if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err; return err;
} }
@ -34,7 +34,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = p-1 */ if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = p-1 */
if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(p-1, e) */ if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(p-1, e) */
} while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides p-1 */ } while (mp_cmp_d(&tmp2, 1) != 0); /* while e divides p-1 */
/* make prime "q" */ /* make prime "q" */
do { do {
if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; } if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
@ -48,7 +48,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = lcm(p-1, q-1) */ if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = lcm(p-1, q-1) */
/* make key */ /* make key */
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, 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->qP, &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
goto error; goto error;
} }
@ -64,16 +64,16 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */ if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */
if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */ if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */
if (mp_invmod(&q, &p, &key->qP) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */ if (mp_invmod(&q, &p, &key->qP) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */
if (mp_mulmod(&key->qP, &q, &key->N, &key->qP)) { goto error2; } /* qP = q * (1/q mod p) mod N */ if (mp_mulmod(&key->qP, &q, &key->N, &key->qP)) { goto error2; } /* qP = q * (1/q mod p) mod N */
if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */ if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */
if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) { goto error2; } /* pQ = p * (1/p mod q) mod N */ if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) { goto error2; } /* pQ = p * (1/p mod q) mod N */
if (mp_copy(&p, &key->p) != MP_OKAY) { goto error2; } if (mp_copy(&p, &key->p) != MP_OKAY) { goto error2; }
if (mp_copy(&q, &key->q) != MP_OKAY) { goto error2; } if (mp_copy(&q, &key->q) != MP_OKAY) { goto error2; }
/* shrink ram required */ /* shrink ram required */
if (mp_shrink(&key->e) != MP_OKAY) { goto error2; } if (mp_shrink(&key->e) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->d) != MP_OKAY) { goto error2; } if (mp_shrink(&key->d) != MP_OKAY) { goto error2; }
@ -84,12 +84,12 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
if (mp_shrink(&key->pQ) != MP_OKAY) { goto error2; } if (mp_shrink(&key->pQ) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->p) != MP_OKAY) { goto error2; } if (mp_shrink(&key->p) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->q) != MP_OKAY) { goto error2; } if (mp_shrink(&key->q) != MP_OKAY) { goto error2; }
res = CRYPT_OK; res = CRYPT_OK;
key->type = PK_PRIVATE_OPTIMIZED; key->type = PK_PRIVATE_OPTIMIZED;
goto done; goto done;
error2: error2:
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
&key->qP, &key->pQ, &key->p, &key->q, NULL); &key->qP, &key->pQ, &key->p, &key->q, NULL);
error: error:
res = CRYPT_MEM; res = CRYPT_MEM;
@ -101,7 +101,7 @@ done:
void rsa_free(rsa_key *key) void rsa_free(rsa_key *key)
{ {
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
&key->qP, &key->pQ, &key->p, &key->q, NULL); &key->qP, &key->pQ, &key->p, &key->q, NULL);
} }
@ -125,7 +125,7 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
/* init and copy into tmp */ /* init and copy into tmp */
if (mp_init_multi(&tmp, &tmpa, &tmpb, NULL) != MP_OKAY) { goto error; } if (mp_init_multi(&tmp, &tmpa, &tmpb, NULL) != MP_OKAY) { goto error; }
if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen) != MP_OKAY) { goto error; } if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen) != MP_OKAY) { goto error; }
/* sanity check on the input */ /* sanity check on the input */
if (mp_cmp(&key->N, &tmp) == MP_LT) { if (mp_cmp(&key->N, &tmp) == MP_LT) {
res = CRYPT_PK_INVALID_SIZE; res = CRYPT_PK_INVALID_SIZE;
@ -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;
@ -170,7 +170,7 @@ done:
return res; return res;
} }
int rsa_signpad(const unsigned char *in, unsigned long inlen, int rsa_signpad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned long x, y; unsigned long x, y;
@ -184,10 +184,10 @@ 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;
} }
for (y = x = 0; x < inlen; x++) for (y = x = 0; x < inlen; x++)
out[y++] = (unsigned char)0xFF; out[y++] = (unsigned char)0xFF;
for (x = 0; x < inlen; x++) for (x = 0; x < inlen; x++)
@ -198,8 +198,8 @@ int rsa_signpad(const unsigned char *in, unsigned long inlen,
return CRYPT_OK; return CRYPT_OK;
} }
int rsa_pad(const unsigned char *in, unsigned long inlen, int rsa_pad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
int wprng, prng_state *prng) int wprng, prng_state *prng)
{ {
unsigned char buf[1536]; unsigned char buf[1536];
@ -211,17 +211,17 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
_ARGCHK(outlen != NULL); _ARGCHK(outlen != NULL);
/* is output big enough? */ /* is output big enough? */
if (*outlen < (3 * inlen)) { if (*outlen < (3 * inlen)) {
return CRYPT_BUFFER_OVERFLOW; return CRYPT_BUFFER_OVERFLOW;
} }
/* get random padding required */ /* get random padding required */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) { if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err; return err;
} }
/* check inlen */ /* check inlen */
if ((inlen <= 0) || inlen > 512) { if (inlen > 512) {
return CRYPT_PK_INVALID_SIZE; return CRYPT_PK_INVALID_SIZE;
} }
@ -229,14 +229,14 @@ 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
* *
* Where R1/R2 are random and exactly equal to the length of M minus one byte. * Where R1/R2 are random and exactly equal to the length of M minus one byte.
*/ */
for (x = 0; x < inlen-1; x++) { for (x = 0; x < inlen-1; x++) {
out[x+1] = buf[x]; out[x+1] = buf[x];
} }
for (x = 0; x < inlen; x++) { for (x = 0; x < inlen; x++) {
@ -258,7 +258,7 @@ int rsa_pad(const unsigned char *in, unsigned long inlen,
return CRYPT_OK; return CRYPT_OK;
} }
int rsa_signdepad(const unsigned char *in, unsigned long inlen, int rsa_signdepad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned long x; unsigned long x;
@ -267,7 +267,7 @@ int rsa_signdepad(const unsigned char *in, unsigned long inlen,
_ARGCHK(out != NULL); _ARGCHK(out != NULL);
_ARGCHK(outlen != NULL); _ARGCHK(outlen != NULL);
if (*outlen < inlen/3) { if (*outlen < inlen/3) {
return CRYPT_BUFFER_OVERFLOW; return CRYPT_BUFFER_OVERFLOW;
} }
@ -277,13 +277,13 @@ int rsa_signdepad(const unsigned char *in, unsigned long inlen,
return CRYPT_INVALID_PACKET; return CRYPT_INVALID_PACKET;
} }
} }
for (x = 0; x < inlen/3; x++) for (x = 0; x < inlen/3; x++)
out[x] = in[x+(inlen/3)]; out[x] = in[x+(inlen/3)];
*outlen = inlen/3; *outlen = inlen/3;
return CRYPT_OK; return CRYPT_OK;
} }
int rsa_depad(const unsigned char *in, unsigned long inlen, int rsa_depad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned long x; unsigned long x;
@ -292,10 +292,10 @@ int rsa_depad(const unsigned char *in, unsigned long inlen,
_ARGCHK(out != NULL); _ARGCHK(out != NULL);
_ARGCHK(outlen != NULL); _ARGCHK(outlen != NULL);
if (*outlen < inlen/3) { if (*outlen < inlen/3) {
return CRYPT_BUFFER_OVERFLOW; return CRYPT_BUFFER_OVERFLOW;
} }
for (x = 0; x < inlen/3; x++) for (x = 0; x < inlen/3; x++)
out[x] = in[x+(inlen/3)]; out[x] = in[x+(inlen/3)];
*outlen = inlen/3; *outlen = inlen/3;
return CRYPT_OK; return CRYPT_OK;
@ -350,8 +350,8 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
/* type valid? */ /* type valid? */
if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) && if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
(type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) { (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
return CRYPT_PK_INVALID_TYPE; return CRYPT_PK_INVALID_TYPE;
} }
@ -363,7 +363,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
/* output modulus */ /* output modulus */
OUTPUT_BIGNUM(&key->N, buf2, y, z); OUTPUT_BIGNUM(&key->N, buf2, y, z);
/* output public key */ /* output public key */
OUTPUT_BIGNUM(&key->e, buf2, y, z); OUTPUT_BIGNUM(&key->e, buf2, y, z);
@ -381,7 +381,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
} }
/* check size */ /* check size */
if (*outlen < y) { if (*outlen < y) {
return CRYPT_BUFFER_OVERFLOW; return CRYPT_BUFFER_OVERFLOW;
} }
@ -407,17 +407,18 @@ 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);
/* test packet header */ /* check length */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
if (inlen < 1+PACKET_SIZE) { if (inlen < 1+PACKET_SIZE) {
return CRYPT_INVALID_PACKET; return CRYPT_INVALID_PACKET;
} }
/* test packet header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* 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) {
return CRYPT_MEM; return CRYPT_MEM;
} }
@ -446,7 +447,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
INPUT_BIGNUM(&key->p, in, x, y); INPUT_BIGNUM(&key->p, in, x, y);
INPUT_BIGNUM(&key->q, in, x, y); INPUT_BIGNUM(&key->q, in, x, y);
} }
/* free up ram not required */ /* free up ram not required */
if (key->type != PK_PRIVATE_OPTIMIZED) { if (key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL); mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
@ -457,7 +458,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
return CRYPT_OK; return CRYPT_OK;
error2: error2:
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
&key->pQ, &key->qP, &key->p, &key->q, NULL); &key->pQ, &key->qP, &key->p, &key->q, NULL);
return err; return err;
} }

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)

16
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;
#endif
return CRYPT_OK;
} }
#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

@ -34,8 +34,8 @@ static const unsigned long K[64] = {
/* Various logical functions */ /* Various logical functions */
#define Ch(x,y,z) ((x & y) | (~x & z)) #define Ch(x,y,z) ((x & y) | (~x & z))
#define Maj(x,y,z) (((x | y) & z) | (x & y)) #define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR((x),(n)) #define S(x, n) ROR((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
@ -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

141
tommath.h
View File

@ -1,19 +1,17 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis /* LibTomMath, multiple-precision integer library -- Tom St Denis
* *
* LibTomMath is library that provides for multiple-precision * LibTomMath is library that provides for multiple-precision
* integer arithmetic as well as number theoretic functionality. * integer arithmetic as well as number theoretic functionality.
* *
* The library is designed directly after the MPI library by * The library is designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with * Michael Fromberger but has been written from scratch with
* additional optimizations in place. * additional optimizations in place.
* *
* The library is free for all purposes without any express * The library is free for all purposes without any express
* guarantee it works. * guarantee it works.
* *
* 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,18 +34,18 @@ 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
/* some default configurations. /* some default configurations.
* *
* A "mp_digit" must be able to hold DIGIT_BIT + 1 bits * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
* 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,31 +53,50 @@ 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
typedef unsigned long long ulong64; typedef unsigned long long ulong64;
typedef signed long long long64; typedef signed long long long64;
#endif #endif
#endif #endif
/* default case */
typedef unsigned long mp_digit; typedef unsigned long mp_digit;
typedef ulong64 mp_word; typedef ulong64 mp_word;
#define DIGIT_BIT 28
#endif
#ifdef MP_31BIT
#define DIGIT_BIT 31
#else
#define DIGIT_BIT 28
#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
/* equalities */ /* equalities */
#define MP_LT -1 /* less than */ #define MP_LT -1 /* less than */
@ -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,32 +349,47 @@ 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".
* Sets result to 0 if composite or 1 if probable prime * Sets result to 0 if composite or 1 if probable prime
*/ */
int mp_prime_fermat(mp_int *a, mp_int *b, int *result); int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
/* performs one Miller-Rabin test of "a" using base "b". /* performs one Miller-Rabin test of "a" using base "b".
* Sets result to 0 if composite or 1 if probable prime * Sets result to 0 if composite or 1 if probable prime
*/ */
int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); 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)