added libtomcrypt-0.79

This commit is contained in:
Tom St Denis 2003-03-03 01:02:10 +00:00 committed by Steffen Jaeckel
parent 2ef59575df
commit d5fbe63b70
35 changed files with 1918 additions and 709 deletions

View File

@ -25,7 +25,7 @@ tomstdenis@yahoo.com.
6) Clay Culver 6) Clay Culver
Submitted a fix for "rsa.c" which cleaned up some code. Submitted a fix for "rsa.c" which cleaned up some code. Submited some other fixes too. :-)
7) Jason Klapste 7) Jason Klapste

View File

@ -91,7 +91,7 @@ int base64_decode(const unsigned char *in, unsigned long len,
if (c == 254) { c = 0; g--; } if (c == 254) { c = 0; g--; }
t = (t<<6)|c; t = (t<<6)|c;
if (++y == 4) { if (++y == 4) {
if (z + g > *outlen) goto error; if (z + g > *outlen) { return CRYPT_BUFFER_OVERFLOW; }
out[z++] = (unsigned char)((t>>16)&255); out[z++] = (unsigned char)((t>>16)&255);
if (g > 1) out[z++] = (unsigned char)((t>>8)&255); if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
if (g > 2) out[z++] = (unsigned char)(t&255); if (g > 2) out[z++] = (unsigned char)(t&255);
@ -103,8 +103,6 @@ int base64_decode(const unsigned char *in, unsigned long len,
} }
*outlen = z; *outlen = z;
return CRYPT_OK; return CRYPT_OK;
error:
return CRYPT_BUFFER_OVERFLOW;
} }
#endif #endif

25
changes
View File

@ -1,3 +1,28 @@
Dec 14th, 2002
v0.79 -- Change to PK code [binary and source]. I made it so you have to pass the buffer size to the *_decrypt_key and
*_verify_hash functions. This prevents malformed packets from performing buffer overflows. I've also trimmed
the packet header size [by 4 bytes].
-- Made the test program halt on the first error it occurs. Also made it trap more errors than before.
-- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website!
-- Included a perl script "config.pl" that will make "makefile.out" according to the users needs.
-- Added shell script to look for latest release
-- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles
-- updated the makefile to use BSD friendly archiving invokations
-- Changed the DH and ECC code to use base64 static key settings [e.g. the primes]. Dropped the code size by 3KB
and is ever-so-slightly faster than before.
-- added "mp_shrink" function to shrink the size of bignums. Specially useful for PK code :-)
-- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto
sized numbers]. Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of
heap todo the calculation. Both are #define'able controlled
-- Added XREALLOC macro to provide realloc() functionality.
-- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's
not being used.
-- Fixed potential bug in the ECC code. Only would occur on platforms where char is not eight bits [which isn't
often!]
-- Fixed up the ECC point multiplication, its about 15% faster now
-- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines
so they export as "unsigned" types saving 1 byte per bignum outputted. Not a lot but heck why not.
Nov 28th, 2002 Nov 28th, 2002
v0.78 -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB. v0.78 -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB.
-- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly. -- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly.

143
config.pl Normal file
View File

@ -0,0 +1,143 @@
#!/usr/bin/perl
#
# Generates a makefile based on user input
#
# Tom St Denis, tomstdenis@yahoo.com, http://tom.iahu.ca
@settings = (
"CC,Compiler,gcc",
"AR,Archiver,ar",
"LD,Linker,ld",
"CFLAGS,Optimizations,-Os",
"CFLAGS,Warnings,-Wall -Wsign-compare -W -Wno-unused -Werror",
"CFLAGS,Include Paths,-I./",
"CFLAGS,Other compiler options,",
"CFLAGS,XMALLOC,-DXMALLOC=malloc",
"CFLAGS,XCALLOC,-DXCALLOC=calloc",
"CFLAGS,XFREE,-DXFREE=free",
"CFLAGS,XCLOCK,-DXCLOCK=clock",
"CFLAGS,XCLOCKS_PER_SEC,-DXCLOCKS_PER_SEC=CLOCKS_PER_SEC",
);
@opts = (
"SMALL_CODE,Use small code where possible (slower code),y",
"NO_FILE,Avoid file I/O calls,n",
"CLEAN_STACK,Clean the stack within functions,n",
"BLOWFISH,Include Blowfish block cipher,y",
"RC2,Include RC2 block cipher,y",
"RC5,Include RC5 block cipher,y",
"RC6,Include RC6 block cipher,y",
"SERPENT,Include Serpent block cipher,y",
"SAFERP,Include Safer+ block cipher,y",
"SAFER,Include Safer-64 block ciphers,y",
"RIJNDAEL,Include Rijndael (AES) block cipher,y",
"XTEA,Include XTEA block cipher,y",
"TWOFISH,Include Twofish block cipher,y",
"TWOFISH_SMALL,Include Use a low ram variant of Twofish,n",
"TWOFISH_TABLES,Include Use precomputed tables to speed up the low-ram variant,n",
"DES,Include DES and 3DES block ciphers,y",
"CAST5,Include CAST5 (aka CAST-128) block cipher,y",
"NOEKEON,Include Noekeon block cipher,y",
"CFB,Include CFB block mode of operation,y",
"OFB,Include OFB block mode of operation,y",
"ECB,Include ECB block mode of operation,y",
"CBC,Include CBC block mode of operation,y",
"CTR,Include CTR block mode of operation,y",
"SHA512,Include SHA512 one-way hash,y",
"SHA384,Include SHA384 one-way hash (requires SHA512),y",
"SHA256,Include SHA256 one-way hash,y",
"TIGER,Include TIGER one-way hash,y",
"SHA1,Include SHA1 one-way hash,y",
"MD5,Include MD5 one-way hash,y",
"MD4,Include MD4 one-way hash,y",
"MD2,Include MD2 one-way hash,y",
"HMAC,Include Hash based Message Authentication Support,y",
"BASE64,Include Base64 encoding support,y",
"YARROW,Include Yarrow PRNG,y",
"SPRNG,Include Secure PRNG base on RNG code,y",
"RC4,Include RC4 PRNG,y",
"DEVRANDOM,Use /dev/random or /dev/urandom if available?,y",
"TRY_URANDOM_FIRST,Try /dev/urandom before /dev/random?,n",
"MRSA,Include RSA public key support,y",
"MDH,Include Diffie-Hellman (over Z/pZ) public key support,y",
"MECC,Include Eliptic Curve public key crypto support,y",
"MDSA,Include Digital Signature Algoritm (DSA) support\n(not required for signatures in the other three),y",
"KR,Include Keyring support (groups all three PK systems),y",
"DH768,768-bit DH key support,y",
"DH1024,1024-bit DH key support,y",
"DH1280,1280-bit DH key support,y",
"DH1536,1280-bit DH key support,y",
"DH1792,1792-bit DH key support,y",
"DH2048,2048-bit DH key support,y",
"DH2560,2560-bit DH key support,y",
"DH3072,3072-bit DH key support,y",
"DH4096,4096-bit DH key support,y",
"ECC160,160-bit ECC key support,y",
"ECC192,192-bit ECC key support,y",
"ECC224,224-bit ECC key support,y",
"ECC256,256-bit ECC key support,y",
"ECC384,384-bit ECC key support,y",
"ECC521,521-bit ECC key support,y",
"DSA1024,1024-bit (160-bit) DSA key support,y",
"DSA2048,2048-bit (256-bit) DSA key support,y",
"DSA4096,4096-bit (512-bit) DSA key support,y",
"GF,Include GF(2^w) math support (not used internally),n",
"MPI,Include MPI big integer math support (required by the public key code),y",
"MPI_FASTEXPT,Use the faster exponentiation code (uses some heap but is faster),y",
"MPI_FASTEXPT_LOWMEM,Use the low ram variant of the fast code\nRequires the fast code to enabled,n",
);
# scan for switches and make variables
for (@settings) {
@m = split(",", $_);
print "@m[1]: [@m[2]] ";
$r = <>; $r = @m[2] if ($r eq "\n");
chomp($r);
@vars{@m[0]} = @vars{@m[0]} . $r . " ";
}
# scan for build flags
for (@opts) {
@m = split(",", $_);
print "@m[1]: [@m[2]]";
$r = <>; @vars{'CFLAGS'} = @vars{'CFLAGS'} . "-D" . $m[0] . " " if (($r eq "y\n") || ($r eq "\n" && @m[2] eq "y"));
}
open(OUT,">makefile.out");
print OUT "#makefile generated with config.pl\n#\n#Tom St Denis (tomstdenis\@yahoo.com, http://tom.iahu.ca) \n\n";
# output unique vars first
for (@settings) {
@m = split(",", $_);
print OUT "@m[0] = @vars{@m[0]}\n" if (@vars{@m[0]} ne "" && @m[0] ne "CFLAGS");
print OUT "CFLAGS += @vars{@m[0]}\n" if (@vars{@m[0]} ne "" && @m[0] eq "CFLAGS");
@vars{@m[0]} = "";
}
# output objects
print OUT "\ndefault: library\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o dsa.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";
# some depends
print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n";
# targets
print OUT "library: \$(OBJECTS)\n\t \$(AR) rs libtomcrypt.a \$(OBJECTS)\n\n";
print OUT "clean:\n\trm -f \$(OBJECTS) libtomcrypt.a \n\n";
close OUT;
print "\n\nmakefile.out was written.\n";

59
crypt.c
View File

@ -1,7 +1,9 @@
#include "mycrypt.h" #include "mycrypt.h"
#include <signal.h> #include <signal.h>
struct _cipher_descriptor cipher_descriptor[32] = { #define TAB_SIZE 32
struct _cipher_descriptor cipher_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
@ -35,7 +37,7 @@ struct _cipher_descriptor cipher_descriptor[32] = {
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } };
struct _hash_descriptor hash_descriptor[32] = { struct _hash_descriptor hash_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
@ -69,7 +71,7 @@ struct _hash_descriptor hash_descriptor[32] = {
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } }; { NULL, 0, 0, 0, NULL, NULL, NULL, NULL } };
struct _prng_descriptor prng_descriptor[32] = { struct _prng_descriptor prng_descriptor[TAB_SIZE] = {
{ NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL },
@ -103,26 +105,27 @@ struct _prng_descriptor prng_descriptor[32] = {
{ NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL },
{ NULL, NULL, NULL, NULL, NULL } }; { NULL, NULL, NULL, NULL, NULL } };
#if (ARGTYPE == 0) && defined(SMALL_CODE) /* ch1-01-1 */
#if (ARGTYPE == 0)
void crypt_argchk(char *v, char *s, int d) void crypt_argchk(char *v, char *s, int d)
{ {
#ifdef SONY_PS2 #ifdef SONY_PS2
printf("_ARGCHK '%s' failure on line %d of file %s\n", v, d, s); printf("_ARGCHK '%s' failure on line %d of file %s\n",
v, d, s);
#else #else
fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n", v, d, s); fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n",
v, d, s);
#endif #endif
raise(SIGABRT); raise(SIGABRT);
} }
#endif #endif
/* ch1-01-1 */
int find_cipher(const char *name) int find_cipher(const char *name)
{ {
int x; int x;
_ARGCHK(name != NULL); _ARGCHK(name != NULL);
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) { if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) {
return x; return x;
} }
@ -134,7 +137,7 @@ int find_hash(const char *name)
{ {
int x; int x;
_ARGCHK(name != NULL); _ARGCHK(name != NULL);
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name != NULL && !strcmp(hash_descriptor[x].name, name)) { if (hash_descriptor[x].name != NULL && !strcmp(hash_descriptor[x].name, name)) {
return x; return x;
} }
@ -146,7 +149,7 @@ int find_prng(const char *name)
{ {
int x; int x;
_ARGCHK(name != NULL); _ARGCHK(name != NULL);
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if ((prng_descriptor[x].name != NULL) && !strcmp(prng_descriptor[x].name, name)) { if ((prng_descriptor[x].name != NULL) && !strcmp(prng_descriptor[x].name, name)) {
return x; return x;
} }
@ -157,7 +160,7 @@ int find_prng(const char *name)
int find_cipher_id(unsigned char ID) int find_cipher_id(unsigned char ID)
{ {
int x; int x;
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].ID == ID) { if (cipher_descriptor[x].ID == ID) {
return (cipher_descriptor[x].name == NULL) ? -1 : x; return (cipher_descriptor[x].name == NULL) ? -1 : x;
} }
@ -168,7 +171,7 @@ int find_cipher_id(unsigned char ID)
int find_hash_id(unsigned char ID) int find_hash_id(unsigned char ID)
{ {
int x; int x;
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].ID == ID) { if (hash_descriptor[x].ID == ID) {
return (hash_descriptor[x].name == NULL) ? -1 : x; return (hash_descriptor[x].name == NULL) ? -1 : x;
} }
@ -186,7 +189,7 @@ int find_cipher_any(const char *name, int blocklen, int keylen)
x = find_cipher(name); x = find_cipher(name);
if (x != -1) return x; if (x != -1) return x;
for (x = 0; cipher_descriptor[x].name != NULL; x++) { for (x = 0; cipher_descriptor[x].name != NULL && x < TAB_SIZE; x++) {
if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) { if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
return x; return x;
} }
@ -201,14 +204,14 @@ int register_cipher(const struct _cipher_descriptor *cipher)
_ARGCHK(cipher != NULL); _ARGCHK(cipher != NULL);
/* is it already registered? */ /* is it already registered? */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) { if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
return x; return x;
} }
} }
/* find a blank spot */ /* find a blank spot */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name == NULL) { if (cipher_descriptor[x].name == NULL) {
memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor)); memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor));
return x; return x;
@ -226,7 +229,7 @@ int unregister_cipher(const struct _cipher_descriptor *cipher)
_ARGCHK(cipher != NULL); _ARGCHK(cipher != NULL);
/* is it already registered? */ /* is it already registered? */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (!memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor))) { if (!memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor))) {
cipher_descriptor[x].name = NULL; cipher_descriptor[x].name = NULL;
cipher_descriptor[x].ID = 255; cipher_descriptor[x].ID = 255;
@ -243,14 +246,14 @@ int register_hash(const struct _hash_descriptor *hash)
_ARGCHK(hash != NULL); _ARGCHK(hash != NULL);
/* is it already registered? */ /* is it already registered? */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (!memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor))) { if (!memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor))) {
return x; return x;
} }
} }
/* find a blank spot */ /* find a blank spot */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name == NULL) { if (hash_descriptor[x].name == NULL) {
memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)); memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor));
return x; return x;
@ -268,7 +271,7 @@ int unregister_hash(const struct _hash_descriptor *hash)
_ARGCHK(hash != NULL); _ARGCHK(hash != NULL);
/* is it already registered? */ /* is it already registered? */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (!memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor))) { if (!memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor))) {
hash_descriptor[x].name = NULL; hash_descriptor[x].name = NULL;
return CRYPT_OK; return CRYPT_OK;
@ -284,14 +287,14 @@ int register_prng(const struct _prng_descriptor *prng)
_ARGCHK(prng != NULL); _ARGCHK(prng != NULL);
/* is it already registered? */ /* is it already registered? */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (!memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor))) { if (!memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor))) {
return x; return x;
} }
} }
/* find a blank spot */ /* find a blank spot */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (prng_descriptor[x].name == NULL) { if (prng_descriptor[x].name == NULL) {
memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)); memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor));
return x; return x;
@ -309,7 +312,7 @@ int unregister_prng(const struct _prng_descriptor *prng)
_ARGCHK(prng != NULL); _ARGCHK(prng != NULL);
/* is it already registered? */ /* is it already registered? */
for (x = 0; x < 32; x++) { for (x = 0; x < TAB_SIZE; x++) {
if (!memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor))) { if (!memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor))) {
prng_descriptor[x].name = NULL; prng_descriptor[x].name = NULL;
return CRYPT_OK; return CRYPT_OK;
@ -320,7 +323,7 @@ int unregister_prng(const struct _prng_descriptor *prng)
int cipher_is_valid(int idx) int cipher_is_valid(int idx)
{ {
if (idx < 0 || idx > 32 || cipher_descriptor[idx].name == NULL) { if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
return CRYPT_INVALID_CIPHER; return CRYPT_INVALID_CIPHER;
} }
return CRYPT_OK; return CRYPT_OK;
@ -328,7 +331,7 @@ int cipher_is_valid(int idx)
int hash_is_valid(int idx) int hash_is_valid(int idx)
{ {
if (idx < 0 || idx > 32 || hash_descriptor[idx].name == NULL) { if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
return CRYPT_INVALID_HASH; return CRYPT_INVALID_HASH;
} }
return CRYPT_OK; return CRYPT_OK;
@ -336,7 +339,7 @@ int hash_is_valid(int idx)
int prng_is_valid(int idx) int prng_is_valid(int idx)
{ {
if (idx < 0 || idx > 32 || prng_descriptor[idx].name == NULL) { if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
return CRYPT_INVALID_PRNG; return CRYPT_INVALID_PRNG;
} }
return CRYPT_OK; return CRYPT_OK;

BIN
crypt.pdf

Binary file not shown.

View File

@ -44,7 +44,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.78} \title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.79}
\author{Tom St Denis \\ \author{Tom St Denis \\
Algonquin College \\ Algonquin College \\
\\ \\
@ -192,6 +192,7 @@ I would like to give thanks to the following people (in no particular order) for
\item Wayne Scott \item Wayne Scott
\item Andrew Tyler \item Andrew Tyler
\item Sky Schulz \item Sky Schulz
\item Christopher Imes
\end{enumerate} \end{enumerate}
\chapter{The Application Programming Interface (API)} \chapter{The Application Programming Interface (API)}
@ -1367,15 +1368,18 @@ 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);
int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey, int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, rsa_key *key); unsigned char *outkey, unsigned long *keylen,
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'' The ``rsa\_encrypt\_key()'' function accepts a symmetric key (limited to 32 bytes) as input in ``inkey''. ``inlen''
is the size of the input key in bytes. The function will then ``rsa\_pad()'' the key and encrypt it using the RSA is the size of the input key in bytes. The function will then ``rsa\_pad()'' the key and encrypt it using the RSA
algorithm. It will store the result in ``outkey'' along with the length in ``outlen''. The ``rsa\_decrypt\_key()'' function algorithm. It will store the result in ``outkey'' along with the length in ``outlen''.
performs the opposite. The ``in'' variable is where the RSA packet goes and it will store the original symmetric key in
the ``outkey'' variable along with its length in ``keylen''. 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 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. message then use these functions to RSA sign the hash.
@ -1384,8 +1388,8 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
rsa_key *key); rsa_key *key);
int rsa_verify_hash(const unsigned char *sig, const unsigned char *hash, int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
int *stat, rsa_key *key); const unsigned char *hash, int *stat, rsa_key *key);
\end{verbatim} \end{verbatim}
For ``rsa\_sign\_hash'' the input is intended to be the hash of a message the user wants to sign. The output is the For ``rsa\_sign\_hash'' the input is intended to be the hash of a message the user wants to sign. The output is the
RSA signed packet which ``rsa\_verify\_hash'' can verify. For the verification function ``sig'' is the RSA signature RSA signed packet which ``rsa\_verify\_hash'' can verify. For the verification function ``sig'' is the RSA signature
@ -1633,12 +1637,13 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
prng_state *prng, int wprng, int hash, prng_state *prng, int wprng, int hash,
dh_key *key); dh_key *key);
int dh_decrypt_key(const unsigned char *in, unsigned char *outkey, int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, dh_key *key); unsigned char *outkey, unsigned long *keylen,
dh_key *key);
\end{verbatim} \end{verbatim}
Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key
and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the required and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the
data is placed in ``out'' by ``dh\_encrypt\_key()''. The hash must produce a message digest at least as large required data is placed in ``out'' by ``dh\_encrypt\_key()''. The hash must produce a message digest at least as large
as the symmetric key you are trying to share. as the symmetric key you are trying to share.
Similar to the RSA system you can sign and verify a hash of a message. Similar to the RSA system you can sign and verify a hash of a message.
@ -1647,9 +1652,9 @@ 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);
int dh_verify_hash(const unsigned char *sig, const unsigned char *hash, int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
unsigned long inlen, int *stat, const unsigned char *hash, unsigned long hashlen,
dh_key *key); int *stat, dh_key *key);
\end{verbatim} \end{verbatim}
The ``dh\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a DH packet in ``out''. The ``dh\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a DH packet in ``out''.
@ -1742,8 +1747,9 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
prng_state *prng, int wprng, int hash, prng_state *prng, int wprng, int hash,
ecc_key *key); ecc_key *key);
int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey, int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, ecc_key *key); unsigned char *outkey, unsigned long *keylen,
ecc_key *key);
\end{verbatim} \end{verbatim}
Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key Where ``inkey'' is an input symmetric key of no more than 32 bytes. Essentially these routines created a random public key
@ -1757,9 +1763,9 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, ecc_key *key); prng_state *prng, int wprng, ecc_key *key);
int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash, int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
unsigned long inlen, int *stat, const unsigned char *hash, unsigned long hashlen,
ecc_key *key); int *stat, ecc_key *key);
\end{verbatim} \end{verbatim}
The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''. The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.

View File

@ -63,23 +63,23 @@ void store_tests(void)
STORE32L(L, &buf[0]); STORE32L(L, &buf[0]);
L = 0; L = 0;
LOAD32L(L, &buf[0]); LOAD32L(L, &buf[0]);
if (L != 0x12345678UL) printf("LOAD/STORE32 Little don't work\n"); if (L != 0x12345678UL) { printf("LOAD/STORE32 Little don't work\n"); exit(-1); }
LL = CONST64(0x01020304050607); LL = CONST64(0x01020304050607);
STORE64L(LL, &buf[0]); STORE64L(LL, &buf[0]);
LL = 0; LL = 0;
LOAD64L(LL, &buf[0]) LOAD64L(LL, &buf[0])
if (LL != CONST64(0x01020304050607)) printf("LOAD/STORE64 Little don't work\n"); if (LL != CONST64(0x01020304050607)) { printf("LOAD/STORE64 Little don't work\n"); exit(-1); }
L = 0x12345678UL; L = 0x12345678UL;
STORE32H(L, &buf[0]); STORE32H(L, &buf[0]);
L = 0; L = 0;
LOAD32H(L, &buf[0]); LOAD32H(L, &buf[0]);
if (L != 0x12345678UL) printf("LOAD/STORE32 High don't work\n"); if (L != 0x12345678UL) { printf("LOAD/STORE32 High don't work\n"); exit(-1); }
LL = CONST64(0x01020304050607); LL = CONST64(0x01020304050607);
STORE64H(LL, &buf[0]); STORE64H(LL, &buf[0]);
LL = 0; LL = 0;
LOAD64H(LL, &buf[0]) LOAD64H(LL, &buf[0])
if (LL != CONST64(0x01020304050607)) printf("LOAD/STORE64 High don't work\n"); if (LL != CONST64(0x01020304050607)) { printf("LOAD/STORE64 High don't work\n"); exit(-1); }
} }
void cipher_tests(void) { void cipher_tests(void) {
@ -103,10 +103,12 @@ void ecb_tests(void)
for (x = 0; cipher_descriptor[x].name != NULL; x++) { for (x = 0; cipher_descriptor[x].name != NULL; x++) {
printf(" %12s: ", printf(" %12s: ",
cipher_descriptor[x].name); cipher_descriptor[x].name);
if ((errno = cipher_descriptor[x].test()) != CRYPT_OK) if ((errno = cipher_descriptor[x].test()) != CRYPT_OK) {
printf(" **failed** Reason: %s\n", error_to_string(errno)); printf(" **failed** Reason: %s\n", error_to_string(errno));
else exit(-1);
} else {
printf("passed\n"); printf("passed\n");
}
} }
} }
@ -124,11 +126,15 @@ void cbc_tests(void)
for (x = 0; x < 32; x++) blk[x] = IV[x] = x; for (x = 0; x < 32; x++) blk[x] = IV[x] = x;
/* now lets start a cbc session */ /* now lets start a cbc session */
if ((errno = cbc_start(find_cipher("blowfish"), IV, key, 16, 0, &cbc)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = cbc_start(find_cipher("blowfish"), IV, key, 16, 0, &cbc)) != CRYPT_OK) {
printf("CBC Setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets encode 32 bytes */ /* now lets encode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
cbc_encrypt(blk+8*x, ct+8*x, &cbc); if ((errno = cbc_encrypt(blk+8*x, ct+8*x, &cbc)) != CRYPT_OK) {
printf("CBC encrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
zeromem(blk, sizeof(blk)); zeromem(blk, sizeof(blk));
@ -137,11 +143,16 @@ void cbc_tests(void)
for (x = 0; x < 32; x++) IV[x] = x; for (x = 0; x < 32; x++) IV[x] = x;
/* now lets start a cbc session */ /* now lets start a cbc session */
if ((errno = cbc_start(find_cipher("blowfish"), IV, key, 16, 0, &cbc)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = cbc_start(find_cipher("blowfish"), IV, key, 16, 0, &cbc)) != CRYPT_OK) {
printf("CBC Setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets decode 32 bytes */ /* now lets decode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
cbc_decrypt(ct+8*x, blk+8*x, &cbc); if ((errno = cbc_decrypt(ct+8*x, blk+8*x, &cbc)) != CRYPT_OK) {
printf("CBC decrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
/* print output */ /* print output */
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1; for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
@ -157,6 +168,7 @@ void cbc_tests(void)
printf("CBC failed logical testing.\n"); printf("CBC failed logical testing.\n");
for (x = 0; x < 16; x++) printf("%02x ", ct[x]); for (x = 0; x < 16; x++) printf("%02x ", ct[x]);
printf("\n"); printf("\n");
exit(-1);
} else { } else {
printf("CBC passed logical testing.\n"); printf("CBC passed logical testing.\n");
} }
@ -178,11 +190,15 @@ void ofb_tests(void)
for (x = 0; x < 32; x++) blk[x] = IV[x] = x; for (x = 0; x < 32; x++) blk[x] = IV[x] = x;
/* now lets start a ofb session */ /* now lets start a ofb session */
if ((errno = ofb_start(find_cipher("blowfish"), IV, key, 16, 0, &ofb)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = ofb_start(find_cipher("cast5"), IV, key, 16, 0, &ofb)) != CRYPT_OK) {
printf("OFB Setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets encode 32 bytes */ /* now lets encode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
ofb_encrypt(blk+8*x, ct+8*x, 8, &ofb); if ((errno = ofb_encrypt(blk+8*x, ct+8*x, 8, &ofb)) != CRYPT_OK) {
printf("OFB encrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
zeromem(blk, sizeof(blk)); zeromem(blk, sizeof(blk));
@ -191,15 +207,20 @@ void ofb_tests(void)
for (x = 0; x < 32; x++) IV[x] = x; for (x = 0; x < 32; x++) IV[x] = x;
/* now lets start a ofb session */ /* now lets start a ofb session */
if ((errno = ofb_start(find_cipher("blowfish"), IV, key, 16, 0, &ofb)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = ofb_start(find_cipher("cast5"), IV, key, 16, 0, &ofb)) != CRYPT_OK) {
printf("OFB setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets decode 32 bytes */ /* now lets decode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
ofb_decrypt(ct+8*x, blk+8*x, 8, &ofb); if ((errno = ofb_decrypt(ct+8*x, blk+8*x, 8, &ofb)) != CRYPT_OK) {
printf("OFB decrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
/* print output */ /* print output */
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1; for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
printf(" %s\n", y?"failed":"passed"); printf(" %s\n", y?"failed":"passed");
if (y) exit(-1);
} }
#else #else
void ofb_tests(void) { printf("OFB not compiled in\n"); } void ofb_tests(void) { printf("OFB not compiled in\n"); }
@ -218,11 +239,15 @@ void cfb_tests(void)
for (x = 0; x < 32; x++) blk[x] = IV[x] = x; for (x = 0; x < 32; x++) blk[x] = IV[x] = x;
/* now lets start a cfb session */ /* now lets start a cfb session */
if ((errno = cfb_start(find_cipher("blowfish"), IV, key, 16, 0, &cfb)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = cfb_start(find_cipher("blowfish"), IV, key, 16, 0, &cfb)) != CRYPT_OK) {
printf("CFB setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets encode 32 bytes */ /* now lets encode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
cfb_encrypt(blk+8*x, ct+8*x, 8, &cfb); if ((errno = cfb_encrypt(blk+8*x, ct+8*x, 8, &cfb)) != CRYPT_OK) {
printf("CFB encrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
zeromem(blk, sizeof(blk)); zeromem(blk, sizeof(blk));
@ -231,15 +256,20 @@ void cfb_tests(void)
for (x = 0; x < 32; x++) IV[x] = x; for (x = 0; x < 32; x++) IV[x] = x;
/* now lets start a cfb session */ /* now lets start a cfb session */
if ((errno = cfb_start(find_cipher("blowfish"), IV, key, 16, 0, &cfb)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = cfb_start(find_cipher("blowfish"), IV, key, 16, 0, &cfb)) != CRYPT_OK) {
printf("CFB Setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets decode 32 bytes */ /* now lets decode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
cfb_decrypt(ct+8*x, blk+8*x, 8, &cfb); if ((errno = cfb_decrypt(ct+8*x, blk+8*x, 8, &cfb)) != CRYPT_OK) {
printf("CFB decrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
/* print output */ /* print output */
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1; for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
printf(" %s\n", y?"failed":"passed"); printf(" %s\n", y?"failed":"passed");
if (y) exit(-1);
} }
#else #else
void cfb_tests(void) { printf("CFB not compiled in\n"); } void cfb_tests(void) { printf("CFB not compiled in\n"); }
@ -259,11 +289,15 @@ void ctr_tests(void)
for (x = 0; x < 32; x++) blk[x] = count[x] = x; for (x = 0; x < 32; x++) blk[x] = count[x] = x;
/* now lets start a ctr session */ /* now lets start a ctr session */
if ((errno = ctr_start(find_cipher("aes"), count, key, 16, 0, &ctr)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = ctr_start(find_cipher("xtea"), count, key, 16, 0, &ctr)) != CRYPT_OK) {
printf("CTR Setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets encode 32 bytes */ /* now lets encode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
ctr_encrypt(blk+8*x, ct+8*x, 8, &ctr); if ((errno = ctr_encrypt(blk+8*x, ct+8*x, 8, &ctr)) != CRYPT_OK) {
printf("CTR encrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
zeromem(blk, sizeof(blk)); zeromem(blk, sizeof(blk));
@ -272,15 +306,20 @@ void ctr_tests(void)
for (x = 0; x < 32; x++) count[x] = x; for (x = 0; x < 32; x++) count[x] = x;
/* now lets start a cbc session */ /* now lets start a cbc session */
if ((errno = ctr_start(find_cipher("aes"), count, key, 16, 0, &ctr)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = ctr_start(find_cipher("xtea"), count, key, 16, 0, &ctr)) != CRYPT_OK) {
printf("CTR Setup: %s\n", error_to_string(errno)); exit(-1); }
/* now lets decode 32 bytes */ /* now lets decode 32 bytes */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++) {
ctr_decrypt(ct+8*x, blk+8*x, 8, &ctr); if ((errno = ctr_decrypt(ct+8*x, blk+8*x, 8, &ctr)) != CRYPT_OK) {
printf("CTR decrypt: %s\n", error_to_string(errno)); exit(-1);
}
}
/* print output */ /* print output */
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1; for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
printf(" %s\n", y?"failed":"passed"); printf(" %s\n", y?"failed":"passed");
if (y) exit(-1);
/* lets actually check the bytes */ /* lets actually check the bytes */
memset(count, 0, 8); count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */ memset(count, 0, 8); count[0] = 0xFF; /* IV = FF 00 00 00 00 00 00 00 */
@ -325,17 +364,18 @@ void pad_test(void)
/* pad the message so that random filler is placed before and after it */ /* pad the message so that random filler is placed before and after it */
y = 100; y = 100;
if ((errno = rsa_pad(in, 16, out, &y, find_prng("yarrow"), &prng)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_pad(in, 16, out, &y, find_prng("yarrow"), &prng)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); exit(-1); }
/* depad the message to get the original content */ /* depad the message to get the original content */
memset(in, 0, sizeof(in)); memset(in, 0, sizeof(in));
x = 100; x = 100;
if ((errno = rsa_depad(out, y, in, &x)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_depad(out, y, in, &x)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
/* check outcome */ /* check outcome */
printf("rsa_pad: "); printf("rsa_pad: ");
if (x != 16) { printf("Failed. Wrong size.\n"); return; } if (x != 16) { printf("Failed. Wrong size.\n"); exit(-1); }
for (x = 0; x < 16; x++) if (in[x] != x) { printf("Failed. Expected %02lx and got %02x.\n", x, in[x]); return; } for (x = 0; x < 16; x++) if (in[x] != x) { printf("Failed. Expected %02lx and got %02x.\n", x, in[x]); exit(-1); }
printf("passed.\n"); printf("passed.\n");
} }
@ -349,100 +389,40 @@ void rsa_test(void)
/* ---- SINGLE ENCRYPT ---- */ /* ---- SINGLE ENCRYPT ---- */
/* encrypt a short 8 byte string */ /* encrypt a short 8 byte string */
if ((errno = rsa_make_key(&prng, find_prng("yarrow"), 1024/8, 65537, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_make_key(&prng, find_prng("yarrow"), 1024/8, 65537, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); exit(-1); }
for (x = 0; x < 8; x++) in[x] = (unsigned char)(x+1); for (x = 0; x < 8; x++) in[x] = (unsigned char)(x+1);
y = sizeof(in); y = sizeof(in);
if ((errno = rsa_exptmod(in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_exptmod(in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); exit(-1); }
/* decrypt it */ /* decrypt it */
zeromem(in, sizeof(in)); zeromem(in, sizeof(in));
x = sizeof(out); x = sizeof(out);
if ((errno = rsa_exptmod(out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_exptmod(out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); exit(-1); }
/* compare */ /* compare */
printf("RSA : "); printf("RSA : ");
for (x = 0; x < 8; x++) if (in[x] != (x+1)) { printf("Failed. x==%02lx, in[%ld]==%02x\n", x, x, in[x]); } for (x = 0; x < 8; x++) if (in[x] != (x+1)) { printf("Failed. x==%02lx, in[%ld]==%02x\n", x, x, in[x]); exit(-1); }
printf("passed.\n"); printf("passed.\n");
#ifdef PK_PACKET
/* ---- BLOCK ENCRYPT ---- */
/* now lets test rsa_encrypt() */
for (x = 0; x < 8; x++) in[x] = (unsigned char)x;
x = sizeof(out);
if ((errno = rsa_encrypt(in, 8, out, &x, &prng, find_prng("yarrow"), find_cipher("aes"), &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
/* test rsa_decrypt() */
zeromem(in, sizeof(in));
y = sizeof(in);
if ((errno = rsa_decrypt(out, x, in, &y, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("rsa_encrypt()/rsa_decrypt(): ");
for (y = 0; y < 8; y++) if (in[y] != y) { printf("failed.\n"); return; }
printf("Passed.\n");
/* ---- SIGNATURES ---- */
x = sizeof(in);
if ((errno = rsa_sign("hello", 5, in, &x, find_hash("md5"), &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
if ((errno = rsa_verify(in, "hello", 5, &stat, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("RSA Signatures: %s, ", (stat==1)?"pass":"fail");
if ((errno = rsa_verify(in, "abcde", 5, &stat, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("%s\n", (stat==0)?"pass":"fail");
/* ---- EXPORT/IMPORT ---- */
x = sizeof(out);
if ((errno = rsa_export(out, &x, PK_PRIVATE_OPTIMIZED, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("RSA Export takes %lu bytes\n", x);
rsa_free(&key);
if ((errno = rsa_import(out, &key, x)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("RSA Import: ");
if ((errno = rsa_verify(in, "hello", 5, &stat, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("%s, ", (stat==1)?"pass":"fail");
if ((errno = rsa_verify(in, "abcde", 5, &stat, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("%s\n", (stat==0)?"pass":"fail");
#endif
/* test the rsa_encrypt_key functions */ /* test the rsa_encrypt_key functions */
for (x = 0; x < 16; x++) in[x] = x; for (x = 0; x < 16; x++) in[x] = x;
y = sizeof(out); y = sizeof(out);
if ((errno = rsa_encrypt_key(in, 16, out, &y, &prng, find_prng("yarrow"), &key)) != CRYPT_OK) { if ((errno = rsa_encrypt_key(in, 16, out, &y, &prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
zeromem(in, sizeof(in)); zeromem(in, sizeof(in));
x = sizeof(in); x = sizeof(in);
if ((errno = rsa_decrypt_key(out, in, &x, &key)) != CRYPT_OK) { if ((errno = rsa_decrypt_key(out, y, in, &x, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("RSA en/de crypt key routines: "); printf("RSA en/de crypt key routines: ");
if (x != 16) { printf("Failed (length)\n"); return; } if (x != 16) { printf("Failed (length)\n"); exit(-1); }
for (x = 0; x < 16; x++) if (in[x] != x) { printf("Failed (contents)\n"); return; } for (x = 0; x < 16; x++) if (in[x] != x) { printf("Failed (contents)\n"); exit(-1); }
printf("Passed\n"); printf("Passed\n");
/* test sign_hash functions */ /* test sign_hash functions */
@ -450,24 +430,25 @@ void rsa_test(void)
x = sizeof(in); x = sizeof(in);
if ((errno = rsa_sign_hash(in, 16, out, &x, &key)) != CRYPT_OK) { if ((errno = rsa_sign_hash(in, 16, out, &x, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("RSA signed hash: %lu bytes\n", x); printf("RSA signed hash: %lu bytes\n", x);
if ((errno = rsa_verify_hash(out, in, &stat, &key)) != CRYPT_OK) { if ((errno = rsa_verify_hash(out, x, in, &stat, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("Verify hash: %s, ", stat?"passed":"failed"); printf("Verify hash: %s, ", stat?"passed":"failed");
in[0] ^= 1; in[0] ^= 1;
if ((errno = rsa_verify_hash(out, in, &stat, &key)) != CRYPT_OK) { if ((errno = rsa_verify_hash(out, x, in, &stat, &key)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("%s\n", (!stat)?"passed":"failed"); printf("%s\n", (!stat)?"passed":"failed");
if (stat) exit(-1);
rsa_free(&key); rsa_free(&key);
/* make a RSA key */ /* make a RSA key */
#ifdef SONY_PS2 #ifdef SONY_PS2_NOPE
limit = 1024; limit = 1024;
#else #else
limit = 2048; limit = 2048;
@ -475,21 +456,21 @@ void rsa_test(void)
for (z = 1024; z <= limit; z += 512) { for (z = 1024; z <= limit; z += 512) {
t = XCLOCK(); t = XCLOCK();
if ((errno = rsa_make_key(&prng, find_prng("yarrow"), z/8, 65537, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_make_key(&prng, find_prng("yarrow"), z/8, 65537, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t = XCLOCK() - t; t = XCLOCK() - t;
printf("Took %.0f ms to make a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z); printf("Took %.0f ms to make a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z);
/* time encryption */ /* time encryption */
y = sizeof(in); y = sizeof(in);
t = XCLOCK(); t = XCLOCK();
if ((errno = rsa_exptmod(in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_exptmod(in, 8, out, &y, PK_PUBLIC, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t = XCLOCK() - t; t = XCLOCK() - t;
printf("Took %.0f ms to encrypt with a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z); printf("Took %.0f ms to encrypt with a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z);
/* time decryption */ /* time decryption */
x = sizeof(out); x = sizeof(out);
t = XCLOCK(); t = XCLOCK();
if ((errno = rsa_exptmod(out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); return; } if ((errno = rsa_exptmod(out, y, in, &x, PK_PRIVATE, &key)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t = XCLOCK() - t; t = XCLOCK() - t;
printf("Took %.0f ms to decrypt with a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z); printf("Took %.0f ms to decrypt with a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z);
rsa_free(&key); rsa_free(&key);
@ -516,19 +497,19 @@ void base64_test(void)
x = 100; x = 100;
if (base64_encode(buf[0], 16, buf[1], &x) != CRYPT_OK) { if (base64_encode(buf[0], 16, buf[1], &x) != CRYPT_OK) {
printf(" error: %s\n", error_to_string(errno)); printf(" error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf(" encoded 16 bytes to %ld bytes...[%s]\n", x, buf[1]); printf(" encoded 16 bytes to %ld bytes...[%s]\n", x, buf[1]);
memset(buf[0], 0, 100); memset(buf[0], 0, 100);
y = 100; y = 100;
if (base64_decode(buf[1], x, buf[0], &y) != CRYPT_OK) { if (base64_decode(buf[1], x, buf[0], &y) != CRYPT_OK) {
printf(" error: %s\n", error_to_string(errno)); printf(" error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf(" decoded %ld bytes to %ld bytes\n", x, y); printf(" decoded %ld bytes to %ld bytes\n", x, y);
for (x = 0; x < 16; x++) if (buf[0][x] != x) { for (x = 0; x < 16; x++) if (buf[0][x] != x) {
printf(" **failed**\n"); printf(" **failed**\n");
return; exit(-1);
} }
printf(" passed\n"); printf(" passed\n");
} }
@ -642,50 +623,50 @@ void dh_tests(void)
/* make up two keys */ /* make up two keys */
if ((errno = dh_make_key(&prng, find_prng("yarrow"), 96, &usera)) != CRYPT_OK) { if ((errno = dh_make_key(&prng, find_prng("yarrow"), 96, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
if ((errno = dh_make_key(&prng, find_prng("yarrow"), 96, &userb)) != CRYPT_OK) { if ((errno = dh_make_key(&prng, find_prng("yarrow"), 96, &userb)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
/* make the shared secret */ /* make the shared secret */
x = 4096; x = 4096;
if ((errno = dh_shared_secret(&usera, &userb, buf[0], &x)) != CRYPT_OK) { if ((errno = dh_shared_secret(&usera, &userb, buf[0], &x)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
y = 4096; y = 4096;
if ((errno = dh_shared_secret(&userb, &usera, buf[1], &y)) != CRYPT_OK) { if ((errno = dh_shared_secret(&userb, &usera, buf[1], &y)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
if (y != x) { printf("DH Shared keys are not same size.\n"); return; } if (y != x) { printf("DH Shared keys are not same size.\n"); exit(-1); }
if (memcmp(buf[0], buf[1], x)) { printf("DH Shared keys not same contents.\n"); return; } if (memcmp(buf[0], buf[1], x)) { printf("DH Shared keys not same contents.\n"); exit(-1); }
/* now export userb */ /* now export userb */
y = 4096; y = 4096;
if ((errno = dh_export(buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) { if ((errno = dh_export(buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
dh_free(&userb); dh_free(&userb);
/* import and make the shared secret again */ /* import and make the shared secret again */
if ((errno = dh_import(buf[1], y, &userb)) != CRYPT_OK) { if ((errno = dh_import(buf[1], y, &userb)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
z = 4096; z = 4096;
if ((errno = dh_shared_secret(&usera, &userb, buf[2], &z)) != CRYPT_OK) { if ((errno = dh_shared_secret(&usera, &userb, buf[2], &z)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("DH routines: "); printf("DH routines: ");
if (z != x) { printf("failed. Size don't match?\n"); return; } if (z != x) { printf("failed. Size don't match?\n"); exit(-1); }
if (memcmp(buf[0], buf[2], x)) { printf("Failed. Content didn't match.\n"); return; } if (memcmp(buf[0], buf[2], x)) { printf("Failed. Content didn't match.\n"); exit(-1); }
printf("Passed\n"); printf("Passed\n");
dh_free(&usera); dh_free(&usera);
dh_free(&userb); dh_free(&userb);
@ -703,7 +684,7 @@ void dh_tests(void)
printf("Make dh-1024 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make dh-1024 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
dh_free(&usera); dh_free(&usera);
#ifndef SONY_PS2 #ifndef SONY_PS2_NOPE
t1 = XCLOCK(); t1 = XCLOCK();
dh_make_key(&prng, find_prng("yarrow"), 160, &usera); dh_make_key(&prng, find_prng("yarrow"), 160, &usera);
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
@ -735,71 +716,23 @@ void dh_tests(void)
dh_free(&usera); dh_free(&usera);
#endif #endif
#ifdef PK_PACKET
/* try dh packet stuff */
for (x = 0; x < 16; x++) buf[0][x] = (unsigned char)x;
dh_make_key(&prng, find_prng("yarrow"), 24, &usera);
x = 4096;
if (dh_encrypt(buf[0], 16, buf[1], &x, &prng, find_prng("yarrow"), find_cipher("aes"),
find_hash("sha1"), &usera) != CRYPT_OK) {
printf("dh_encrypt says %s\n", error_to_string(errno));
return;
}
printf("dh encrypted 16 bytes into %ld bytes!\n", x);
y = 4096;
if ((errno = dh_decrypt(buf[1], x, buf[2], &y, &usera)) != CRYPT_OK) {
printf("dh_decrypt says %s\n", error_to_string(errno));
return;
}
printf("dh packet: ");
if (16 != y) { printf("Failed: Sizes different! 16 vs %ld\n", y); return; }
if (memcmp(buf[0], buf[2], 16)) { printf("Failed; Content mismatch.\n"); return; }
printf("Passed!\n");
dh_free(&usera);
/* try dh signatures */
dh_make_key(&prng, find_prng("yarrow"), 96, &usera);
x = 4096;
if ((errno = dh_sign("hello", 5, buf[0], &x, find_hash("sha1"), &prng, find_prng("yarrow"), &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("dh-768 Signature took %ld bytes\n", x);
if ((errno = dh_verify(buf[0], "hello", 5, &stat, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
if ((errno = dh_verify(buf[0], "hellp", 5, &stat2, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("dh Signatures: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2);
dh_free(&usera);
#endif
/* test encrypt_key */ /* test encrypt_key */
dh_make_key(&prng, find_prng("yarrow"), 96, &usera); dh_make_key(&prng, find_prng("yarrow"), 96, &usera);
for (x = 0; x < 16; x++) buf[0][x] = x; for (x = 0; x < 16; x++) buf[0][x] = x;
y = sizeof(buf[1]); y = sizeof(buf[1]);
if ((errno = dh_encrypt_key(buf[0], 16, buf[1], &y, &prng, find_prng("yarrow"), find_hash("md5"), &usera)) != CRYPT_OK) { if ((errno = dh_encrypt_key(buf[0], 16, buf[1], &y, &prng, find_prng("yarrow"), find_hash("md5"), &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
zeromem(buf[0], sizeof(buf[0])); zeromem(buf[0], sizeof(buf[0]));
x = sizeof(buf[0]); x = sizeof(buf[0]);
if ((errno = dh_decrypt_key(buf[1], buf[0], &x, &usera)) != CRYPT_OK) { if ((errno = dh_decrypt_key(buf[1], y, buf[0], &x, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("DH en/de crypt key routines: "); printf("DH en/de crypt key routines: ");
if (x != 16) { printf("Failed (length)\n"); return; } if (x != 16) { printf("Failed (length)\n"); exit(-1); }
for (x = 0; x < 16; x++) if (buf[0][x] != x) { printf("Failed (contents)\n"); return; } for (x = 0; x < 16; x++) if (buf[0][x] != x) { printf("Failed (contents)\n"); exit(-1); }
printf("Passed (size %lu)\n", y); printf("Passed (size %lu)\n", y);
/* test sign_hash */ /* test sign_hash */
@ -807,16 +740,16 @@ void dh_tests(void)
x = sizeof(buf[1]); x = sizeof(buf[1]);
if ((errno = dh_sign_hash(buf[0], 16, buf[1], &x, &prng, find_prng("yarrow"), &usera)) != CRYPT_OK) { if ((errno = dh_sign_hash(buf[0], 16, buf[1], &x, &prng, find_prng("yarrow"), &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
if (dh_verify_hash(buf[1], buf[0], 16, &stat, &usera)) { if (dh_verify_hash(buf[1], x, buf[0], 16, &stat, &usera)) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
buf[0][0] ^= 1; buf[0][0] ^= 1;
if (dh_verify_hash(buf[1], buf[0], 16, &stat2, &usera)) { if (dh_verify_hash(buf[1], x, buf[0], 16, &stat2, &usera)) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("dh_sign/verify_hash: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2); printf("dh_sign/verify_hash: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2);
dh_free(&usera); dh_free(&usera);
@ -868,7 +801,7 @@ void ecc_tests(void)
ecc_key usera, userb; ecc_key usera, userb;
clock_t t1; clock_t t1;
if ((errno = ecc_test()) != CRYPT_OK) printf("ecc Error: %s\n", error_to_string(errno)); if ((errno = ecc_test()) != CRYPT_OK) { printf("ecc Error: %s\n", error_to_string(errno)); exit(-1); }
ecc_sizes(&low, &high); ecc_sizes(&low, &high);
printf("ecc Keys from %d to %d supported.\n", low*8, high*8); printf("ecc Keys from %d to %d supported.\n", low*8, high*8);
@ -876,35 +809,35 @@ void ecc_tests(void)
/* make up two keys */ /* make up two keys */
if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &usera)) != CRYPT_OK) { if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &userb)) != CRYPT_OK) { if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &userb)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
/* make the shared secret */ /* make the shared secret */
x = 4096; x = 4096;
if ((errno = ecc_shared_secret(&usera, &userb, buf[0], &x)) != CRYPT_OK) { if ((errno = ecc_shared_secret(&usera, &userb, buf[0], &x)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
y = 4096; y = 4096;
if ((errno = ecc_shared_secret(&userb, &usera, buf[1], &y)) != CRYPT_OK) { if ((errno = ecc_shared_secret(&userb, &usera, buf[1], &y)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
if (y != x) { printf("ecc Shared keys are not same size.\n"); return; } if (y != x) { printf("ecc Shared keys are not same size.\n"); exit(-1); }
if (memcmp(buf[0], buf[1], x)) { printf("ecc Shared keys not same contents.\n"); return; } if (memcmp(buf[0], buf[1], x)) { printf("ecc Shared keys not same contents.\n"); exit(-1); }
/* now export userb */ /* now export userb */
y = 4096; y = 4096;
if ((errno = ecc_export(buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) { if ((errno = ecc_export(buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
ecc_free(&userb); ecc_free(&userb);
printf("ECC-192 export took %ld bytes\n", y); printf("ECC-192 export took %ld bytes\n", y);
@ -912,142 +845,94 @@ void ecc_tests(void)
/* import and make the shared secret again */ /* import and make the shared secret again */
if ((errno = ecc_import(buf[1], y, &userb)) != CRYPT_OK) { if ((errno = ecc_import(buf[1], y, &userb)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
z = 4096; z = 4096;
if ((errno = ecc_shared_secret(&usera, &userb, buf[2], &z)) != CRYPT_OK) { if ((errno = ecc_shared_secret(&usera, &userb, buf[2], &z)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("ecc routines: "); printf("ecc routines: ");
if (z != x) { printf("failed. Size don't match?\n"); return; } if (z != x) { printf("failed. Size don't match?\n"); exit(-1); }
if (memcmp(buf[0], buf[2], x)) { printf("Failed. Content didn't match.\n"); return; } if (memcmp(buf[0], buf[2], x)) { printf("Failed. Content didn't match.\n"); exit(-1); }
printf("Passed\n"); printf("Passed\n");
ecc_free(&usera); ecc_free(&usera);
ecc_free(&userb); ecc_free(&userb);
/* time stuff */ /* time stuff */
t1 = XCLOCK(); t1 = XCLOCK();
ecc_make_key(&prng, find_prng("yarrow"), 20, &usera); if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 20, &usera)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
printf("Make ECC-160 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make ECC-160 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
ecc_free(&usera); ecc_free(&usera);
t1 = XCLOCK(); t1 = XCLOCK();
ecc_make_key(&prng, find_prng("yarrow"), 24, &usera); if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &usera)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
printf("Make ECC-192 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make ECC-192 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
ecc_free(&usera); ecc_free(&usera);
t1 = XCLOCK(); t1 = XCLOCK();
ecc_make_key(&prng, find_prng("yarrow"), 28, &usera); if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 28, &usera)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
printf("Make ECC-224 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make ECC-224 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
ecc_free(&usera); ecc_free(&usera);
#ifndef SONY_PS2 #ifndef SONY_PS2
t1 = XCLOCK(); t1 = XCLOCK();
ecc_make_key(&prng, find_prng("yarrow"), 32, &usera); if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 32, &usera)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
printf("Make ECC-256 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make ECC-256 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
ecc_free(&usera); ecc_free(&usera);
t1 = XCLOCK(); t1 = XCLOCK();
ecc_make_key(&prng, find_prng("yarrow"), 48, &usera); if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 48, &usera)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
printf("Make ECC-384 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make ECC-384 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
ecc_free(&usera); ecc_free(&usera);
t1 = XCLOCK(); t1 = XCLOCK();
ecc_make_key(&prng, find_prng("yarrow"), 65, &usera); if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 65, &usera)) != CRYPT_OK) { printf("Error: %s\n", error_to_string(errno)); exit(-1); }
t1 = XCLOCK() - t1; t1 = XCLOCK() - t1;
printf("Make ECC-521 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC)); printf("Make ECC-521 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
ecc_free(&usera); ecc_free(&usera);
#endif #endif
#ifdef PK_PACKET
/* try ECC packet stuff */
for (x = 0; x < 16; x++) buf[0][x] = (unsigned char)x;
ecc_make_key(&prng, find_prng("yarrow"), 20, &usera);
x = 4096;
if (ecc_encrypt(buf[0], 16, buf[1], &x, &prng, find_prng("yarrow"), find_cipher("aes"),
find_hash("tiger"), &usera) != CRYPT_OK) {
printf("ecc_encrypt says %s\n", error_to_string(errno));
return;
}
printf("Ecc encrypted 16 bytes into %ld bytes!\n", x);
y = 4096;
if ((errno = ecc_decrypt(buf[1], x, buf[2], &y, &usera)) != CRYPT_OK) {
printf("ecc_decrypt says %s\n", error_to_string(errno));
return;
}
printf("ECC packet: ");
if (16 != y) { printf("Failed: Sizes different! 16 vs %ld\n", y); return; }
if (memcmp(buf[0], buf[2], 16)) { printf("Failed; Content mismatch.\n"); return; }
printf("Passed!\n");
ecc_free(&usera);
/* try ECC signatures */
ecc_make_key(&prng, find_prng("yarrow"), 20, &usera);
x = 4096;
if ((errno = ecc_sign("hello", 5, buf[0], &x, find_hash("sha1"), &prng, find_prng("yarrow"), &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("ECC-160 Signature took %ld bytes\n", x);
if ((errno = ecc_verify(buf[0], "hello", 5, &stat, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
if ((errno = ecc_verify(buf[0], "hellp", 5, &stat2, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return;
}
printf("ECC Signatures: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2);
ecc_free(&usera);
#endif
/* test encrypt_key */ /* test encrypt_key */
ecc_make_key(&prng, find_prng("yarrow"), 32, &usera); ecc_make_key(&prng, find_prng("yarrow"), 32, &usera);
for (x = 0; x < 16; x++) buf[0][x] = x; for (x = 0; x < 16; x++) buf[0][x] = x;
y = sizeof(buf[1]); y = sizeof(buf[1]);
if ((errno = ecc_encrypt_key(buf[0], 16, buf[1], &y, &prng, find_prng("yarrow"), find_hash("md5"), &usera)) != CRYPT_OK) { if ((errno = ecc_encrypt_key(buf[0], 16, buf[1], &y, &prng, find_prng("yarrow"), find_hash("md5"), &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
zeromem(buf[0], sizeof(buf[0])); zeromem(buf[0], sizeof(buf[0]));
x = sizeof(buf[0]); x = sizeof(buf[0]);
if ((errno = ecc_decrypt_key(buf[1],buf[0], &x, &usera)) != CRYPT_OK) { if ((errno = ecc_decrypt_key(buf[1], y, buf[0], &x, &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("ECC en/de crypt key routines: "); printf("ECC en/de crypt key routines: ");
if (x != 16) { printf("Failed (length)\n"); return; } if (x != 16) { printf("Failed (length)\n"); exit(-1); }
for (x = 0; x < 16; x++) if (buf[0][x] != x) { printf("Failed (contents)\n"); return; } for (x = 0; x < 16; x++) if (buf[0][x] != x) { printf("Failed (contents)\n"); exit(-1); }
printf("Passed (size: %lu)\n", y); printf("Passed (size: %lu)\n", y);
/* test sign_hash */ /* test sign_hash */
for (x = 0; x < 16; x++) buf[0][x] = x; for (x = 0; x < 16; x++) buf[0][x] = x;
x = sizeof(buf[1]); x = sizeof(buf[1]);
if ((errno = ecc_sign_hash(buf[0], 16, buf[1], &x, &prng, find_prng("yarrow"), &usera)) != CRYPT_OK) { if ((errno = ecc_sign_hash(buf[0], 16, buf[1], &x, &prng, find_prng("yarrow"), &usera)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
if (ecc_verify_hash(buf[1], buf[0], 16, &stat, &usera)) { if (ecc_verify_hash(buf[1], x, buf[0], 16, &stat, &usera)) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
buf[0][0] ^= 1; buf[0][0] ^= 1;
if (ecc_verify_hash(buf[1], buf[0], 16, &stat2, &usera)) { if (ecc_verify_hash(buf[1], x, buf[0], 16, &stat2, &usera)) {
printf("Error: %s\n", error_to_string(errno)); printf("Error: %s\n", error_to_string(errno));
return; exit(-1);
} }
printf("ecc_sign/verify_hash: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2); printf("ecc_sign/verify_hash: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2);
ecc_free(&usera); ecc_free(&usera);
@ -1185,15 +1070,16 @@ void 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,18 +1269,18 @@ void kr_test(void)
len = sizeof(buf2); len = sizeof(buf2);
if ((errno = kr_sign_hash(kr, _kr->ID, buf, 32, buf2, &len, &prng, find_prng("yarrow"))) != CRYPT_OK) { if ((errno = kr_sign_hash(kr, _kr->ID, buf, 32, buf2, &len, &prng, find_prng("yarrow"))) != CRYPT_OK) {
printf("kr_sign_hash failed, %i, %lu\n", i, len); printf("kr_sign_hash failed, %i, %s\n", i, error_to_string(errno));
exit(-1); exit(-1);
} }
printf("kr_sign_hash: "); printf("kr_sign_hash: ");
if ((errno = kr_verify_hash(kr, buf2, buf, 32, &stat)) != CRYPT_OK) { if ((errno = kr_verify_hash(kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
printf("kr_sign_hash failed, %i, %lu\n", i, len); printf("kr_sign_hash failed, %i, %s\n", i, error_to_string(errno));
exit(-1); exit(-1);
} }
printf("%s, ", stat?"passed":"failed"); printf("%s, ", stat?"passed":"failed");
buf[15] ^= 1; buf[15] ^= 1;
if ((errno = kr_verify_hash(kr, buf2, buf, 32, &stat)) != CRYPT_OK) { if ((errno = kr_verify_hash(kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
printf("kr_sign_hash failed, %i, %lu\n", i, len); printf("kr_sign_hash failed, %i, %s\n", i, error_to_string(errno));
exit(-1); exit(-1);
} }
printf("%s\n", (!stat)?"passed":"failed"); printf("%s\n", (!stat)?"passed":"failed");
@ -1542,7 +1428,7 @@ int main(void)
if ((errno = yarrow_ready(&prng)) != CRYPT_OK) { if ((errno = yarrow_ready(&prng)) != CRYPT_OK) {
printf("yarrow_ready: %s\n", error_to_string(errno)); printf("yarrow_ready: %s\n", error_to_string(errno));
} }
printf(crypt_build_settings); printf(crypt_build_settings);
test_errs(); test_errs();

175
dh.c
View File

@ -12,10 +12,9 @@ static const struct {
96, 96,
"DH-768", "DH-768",
"2", "2",
"2893527720709661239493896562339544088620375736490408468011883030469939904368" "1tH+dRFGpEYyVLe4ydZcYyGDpeAxnChz0yk+pNCtkEXwUsOORyguBtx8spUD"
"0860923364582982212457078989335831907131881773994018526277492109945959747917" "FAjEDS8PutUBTEu2q4USqu19dUbCLj9D2jY7y3871RnSccurMBsMm35ILcyQ"
"8279025394653904396221302707492255957231214118178743427870878320796645901947" "rpN0MQKc/"
"9487"
}, },
#endif #endif
#ifdef DH1024 #ifdef DH1024
@ -23,11 +22,9 @@ static const struct {
128, 128,
"DH-1024", "DH-1024",
"2", "2",
"3477431594398766260792527967974222231775354473882066076071816639030459075912" "Uypu+t9nfUnCj7xD+xokM+Cd6mASW4ofg1jpC2BpQasC5edtA1dJC+RjbOBZ"
"0194047822362172211817327089848758298713770865641434468581617942085516098634" "z+5mvq5VYT8Wfjmlpjm9tQxHOYB0+3Myl7gbCQ5SRljWT2oBLukLNvgFjiU4"
"0457973820182883508387588163122354089264395604796675278966117567294812714812" "wiWkmu41Ern/j6uxwKb740C+VIgDAdeUY4fA5hyfr3/+DWYb14/"
"7968205965648764507160662831267200108590414847865290564578963676831229604111"
"36319"
}, },
#endif #endif
#ifdef DH1280 #ifdef DH1280
@ -35,12 +32,10 @@ static const struct {
160, 160,
"DH-1280", "DH-1280",
"2", "2",
"2618298020488323341377089635550383393554460131909411928885489146533597039863" "520QV4Tsq4NwK9Mt5CGR9xk4slvaikgi/ax3OPky5GERKTsoqEXOlFyMzURP"
"5379029297773089246854323581071445272213255646852180580463169755159411503866" "P8jYzCVz1izKd2zTDxbFfLxrJry0ceaQ5YZa5N4teByCPVlQh4v6iQl+944+"
"4190218001872082125570169842848154404911652982668791288605239288293106162305" "/NDlKzvWpx7HG7k8cGKhva7aFF8bP/CvLpaQhrfXlOX+X9pcmML9QH63tUjq"
"7236093554796242806887062958692596037823904832542385180840218330924392268465" "B80l8Yx9KN0dC3iNnsTV3DnqnEvFQkoqql"
"0197244314233248991982159235832322194332167923655574170280697353556560854901"
"280047"
}, },
#endif #endif
#ifdef DH1536 #ifdef DH1536
@ -48,13 +43,11 @@ static const struct {
192, 192,
"DH-1536", "DH-1536",
"3", "3",
"2992593690703251306835100868059076484222548092264611010748654597096560864537" "1FTWXrPcY1w74oZ0ouIzSN8uZcRiOf6U11fx0ka6+7fqIAezPhd3Ab43QnDf"
"1704684310938824733433085888971827086341295918925237859522548192211945291282" "KFg+or/fFRGEWAxF8WIE2jx8iTOu010yNEQyH14CK0RAyy2zY4gRs2MpnU5r"
"1170570153374563548621496076860061698150233114892317627457427359445435608693" "/feWf60OkLtnPzN34+Xnlg5xf7Jl00wkHRCeJG17L3SklOidAPxWnE+Wm4BS"
"5625000902194809114890745455404045166957722404567939575618007347432055137282" "SOzdQBgiZOjlhrYS1+TIU3NP5H7BrtKFcf+ZwBULibf29L7LkDOgQbie1+43"
"3291711752537781447636541738638119983678441628437171377508654097130147131310" "lU+8SHAyBwAeGYMfZ"
"9209393805685590941710151477648542896503595482724205166251069428524927527085"
"2602467"
}, },
#endif #endif
#ifdef DH1792 #ifdef DH1792
@ -62,14 +55,11 @@ static const struct {
224, 224,
"DH-1792", "DH-1792",
"2", "2",
"3210090394251532205679207425273650879078185529033544241951292722086520015900" "IPo3wjvfS7vBYnFHwJHmesA51od9fnR8Aenezif4qLE2HX+YCv1tpvHA8yLH"
"0402371844205168176419829949232601235193754977706171541009393172204470047690" "yYbKe9QfSHHtOgVjK8AYEyPirpXxlmdykGuj+dX7EiWMRGYc+v1kKkqmCn0o"
"6659627844880912479392592056697278305733615369406596661203184035142652643118" "5tU416O/1HXTpQ2Hps0buchUD+HlCMrSgnIqRxK6Fjr0ZfiCS4XgAD6sLgi0"
"1379603333858737848321053048184938839622944591194935387992479717305577175500" "BxKFMxDsVzpGMNwF5Lj2R/cJiTi0cNDDY3gn4lK/PRUsJtRKU+9sxy0q5Yof"
"2554620614907177847128950276247571809502831255425929468853285490357704941968" "aG5VO8VcHkZJVwUKhDFHkZYWMHV808TGHXM2RQ9kRa2QvS2mXxMrDSCloQ/"
"3407102520889651917659577334897408316217748346860775479727332331727022096550"
"7718799868459391361770854814013613619048768630587629568449528005570971478547"
"34960319"
}, },
#endif #endif
#ifdef DH2048 #ifdef DH2048
@ -77,15 +67,12 @@ static const struct {
256, 256,
"DH-2048", "DH-2048",
"2", "2",
"4726642895635639316469736509812041897640060270607231273592407174543853221823" "5sR1VmdsQQzzjN0iridVVyveug6sAC3+/jTIHSgEoimPOREXQ05r2WJZJAF2"
"7979333351774907308168340693326687317443721193266215155735814510792148768576" "CRu8kuusiPw2ivRli+fdLr63v1uZG5nQa28uLwNxZEsu4gu6TrGjepXeXm4Z"
"4984911991227443513994894535335532038333186916782632419417062569961974604240" "CVOC1HMmi660fLZ2ruHLa4v2NWex2Zx91/y4ygPlZM+K//iy+Gft9Ma9Ayn0"
"2901241901263467186228353234265630967717360250949841797609150915436003989316" "eYwofZeUL9vJSfutPVp2ZrIEUQDBKMvMm0SRSLiUjDtzXqrH+b/wuwIFG1K4"
"5037637034737020327399910409885798185771003505320583967737293415979917317338" "var3ucsT45mDzD9qb3tBdksSPZbr6yrELV8h+qmjiBr15oHKEglS0XwSvCap"
"9858373857347474783642420203804168920566508414708692945275435973492502995396" "abUn5XPPVoaKv13+tOnG9mGgzQ8JeClVXN63Q+GGEF"
"8243060517332102902655554683247304860032703684578197028928889831788842751736"
"4945316709081173840186150794397479045034008257793436817683392375274635794835"
"245695887"
}, },
#endif #endif
#ifdef DH2560 #ifdef DH2560
@ -93,17 +80,14 @@ static const struct {
320, 320,
"DH-2560", "DH-2560",
"3", "3",
"4364638085059577685748948703943497396233464406019459611612544400721432981520" "G7UVKk+N6LfpGkdBP6XLB4QJ3wzee5YH/3o6tBDMwr4FS8YjCmeP6l4gu0hX"
"4010567649104824811014627875285783993051576616744140702150122992472133564455" "dzY2Rive4TYOu4Akm4naZuv32d71/2lQeNcO23BNYOEPxtn9BU8uYfaHP9Mo"
"7342265864606569000117714935185566842453630868849121480179691838399545644365" "M+m76oUCiI5uqpag5RH3BO34FyE4BiKkzjEXq9xxc8ERacG8Mo8DNiXu79p9"
"5711067577313173717585579907818806913366955847993133136872874688941488237617" "Q/0wsRz+W/lIN4gYw3w4iLMooAGnDrhcj5cZb0HysHWYfqmFo+jTBP6Egi0g"
"8558298254958618375680644901754262226787427510387748147553499120184991222267" "cmVO2qWQh2cZIQMfppaf1Ffq0XGIJpgDFyOHPl3NVxDabVK1tkVct+hathxJ"
"0102069951687572917937634467778042874315463238062009202992087620963771759666" "UTdqZmR2VFwMASXjfgj4VFdvFCUxV8Xr8JcwXkwlMjOJbAl0LoCa4M7hpYvz"
"4482665328580794026699200252242206134194410697184828373996126449788399252071" "G/0XviGCpv7qQaONKtsiQ6mHhMcyo9hBCRZXtNPkfPMZkPeV05akvaDs6Ek7"
"0987084027819404215874884544513172913711709852902888677006373648742061314404" "DZ62oKR"
"5836803985635654192482395882603511950547826439092832800532152534003936926017"
"6124466061356551464456206233957889787267447285030586700468858762515271223502"
"75750995227"
}, },
#endif #endif
#ifdef DH3072 #ifdef DH3072
@ -111,19 +95,15 @@ static const struct {
384, 384,
"DH-3072", "DH-3072",
"2", "2",
"1142416747335183639807830604262436227795642944052113706188970261176634876069" "1zsV6XgY57R/hu2RR4H/BjwRqmQL9h+Dc5rgoWOcqiTS8qpVTWafi1KFV77V"
"2206243140413411077394583180726863277012016602279290144126785129569474909173" "rUcjcer1EDgCV0tpzlemtyrC2pHpw7hr3EEl2evfWOvg05FRI6mKc2UPNv2c"
"5847898223419867427192303319460727303195559844849117167970588759054009995043" "2Bjww4LD/tdsLleX7AHHXCXFSSyd6C3qWq7BqABZriSpQeaEtXbWfeC6ytFe"
"0587724584911968750902323279027363746682105257685923245298206183100977078603" "2i3VeQsLa40XQ21UxwhPAjamjSOfYzkW7xi0fwI1e+4OQiFcWOfOuvswoaEf"
"1785669030271542286603956118755585683996118896215213488875253101894663403069" "MIICyAmVp67vjGo66dk81dMemyplipgXAWPdl7ppnDd6cEjyN4N90D7kQiNg"
"6777459483058938495054342017637452328957807119724320113448575216910178963168" "lVmJlKLecldOUtdIqMnbJCbiN/t/3/AEFaokGO9om5ckc6M9gG5PG0T7Oh1N"
"6140320644942133224365885545343578400651720289418164056243357539082138421096" "dSx/PstGdxwvs9DOwjyo5wl5C9QSLtUYJl2+GZYMj6WfsgCrb6jjRJJJQe2C"
"0117518650374602256601091379644034244332285065935413233557998331562749140202" "y7wUcBILbRsP3lYT8s14zm4xFBrfMUoLN287j3wQ1TNUXjYSCi4ZLKT1XDai"
"9658442193362989700115138825649355387042894469683222814519074873620465114612" "93345OiutLOqGGikFg6ypnymJK3yeHuul"
"2132979989735099337056069750580968643878203623537213701573130477907243026098"
"6460269894522159103008260495503005267165927542949439526272736586626709581721"
"0321895327263896436255906801057848442461527026701693042037830722750891947548"
"89511973916207"
}, },
#endif #endif
#ifdef DH4096 #ifdef DH4096
@ -131,23 +111,18 @@ static const struct {
512, 512,
"DH-4096", "DH-4096",
"3", "3",
"1214855636816562637502584060163403830270705000634713483015101384881871978446" "Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS"
"8012247985361554068958233050354675916325310675478909486951171720769542207270" "32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw"
"7568804875102242119871203284889005635784597424656074834791863005085393369779" "aHI3GLFuEMz3JJyvQKGaGwpV3C9gS70dFWTxEfNRzdYEdvIic8/SXI79VgNP"
"2254955890439720297560693579400297062396904306270145886830719309296352765295" "LGR68nzd4qxCgaLpVBnWsanRp7mfEj52S/7Kxjs14lrbAOMjCuHgN4F6THWh"
"7121830407731464190228751653827780070401099576097395898755908857011261979060" "PNhG0VXfFFIwAMW2unrfpdo+gQHNclqCf2N1FALpABzvUesgs3wIP+QTMqms"
"6362013395489321661267883850754077713843779770560245371955901763398648664952" "os/AkuulG7MusbeFl3SoCtaoW12CF038ZbqW+e+DKI1zObhtsLanvaiZm/N4"
"3611975865005712371194067612263330335590526176087004421363598470302731349138" "BsJirW7avcWNQYm1oYjZ2bR/jYqfoJ0CLXLO/vqHb8J9a5VE9nz7cqMD3/MH"
"7732059014477046821815179040647356365184624522427916765417252923789255682968" "k/g7BapsOtKuol6ipbUvxQPtf4KCwqQQ40JeqgS6amivI/aLu05S7bAxKOwE"
"5801015185232631677751193503753101741391050692192245066693320227848902452126" "Yu8YxjN6lXm3co5Wy+BmNSuRlzKhxICyHEqMfKwUtm48XHzHuPaGQzHgkn6H"
"3798482237150056835746454842662048692127173834433089016107854491097456725016" "3A+FQjQGLHewADYlbfdTF3sHYyc5k9h/9cYVkbmv7bQze53CJGr3T1hZYbN6"
"3277096631997382384421648431471327891537255132571679155551620949708535844479" "+fuz0SPnfjiKu+bWD+8RYtZpLs2+f32huMz3OqoryGfULxC2aEjL2rdBn+ZR"
"9312548860769600816980737473671129700747381225627224548940589847029717873802" "PT0+ZAUyLSAVHbsul++cawh"
"9484459690836250560495461579533254473316340608217876781986188705928270735695"
"7528308255279638383554197625162460286802809880204019145518254873499903069763"
"0409310938445143881325121105159739212749146489879740678917545306796007200859"
"0614886532333015881171367104445044718144312416815712216611576221546455968770"
"801413440778423979"
}, },
#endif #endif
{ {
@ -180,9 +155,8 @@ int dh_test(void)
#if 0 #if 0
printf("dh_test():testing size %d-bits\n", sets[x].size * 8); printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
#endif #endif
/* see if g^((p-1)/2) == 1 mod p. */ if (mp_read_radix(&g, sets[x].base, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&g, sets[x].base, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&p, sets[x].prime, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&p, sets[x].prime, 10) != MP_OKAY) { goto error; }
/* 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; }
@ -276,18 +250,21 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
if (mp_init_multi(&g, &p, &key->x, &key->y, NULL) != MP_OKAY) { if (mp_init_multi(&g, &p, &key->x, &key->y, NULL) != MP_OKAY) {
return CRYPT_MEM; return CRYPT_MEM;
} }
if (mp_read_radix(&g, sets[x].base, 10) != MP_OKAY) { goto error2; } if (mp_read_radix(&g, sets[key->idx].base, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&p, sets[x].prime, 10) != MP_OKAY) { goto error2; } if (mp_read_radix(&p, sets[key->idx].prime, 64) != MP_OKAY) { goto error; }
/* load the x value */ /* load the x value */
mp_read_raw(&key->x, buf, keysize+1); mp_read_raw(&key->x, buf, keysize+1);
if (mp_exptmod(&g, &key->x, &p, &key->y) != MP_OKAY) { goto error2; } 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->y) != MP_OKAY) { goto error; }
/* free up ram */ /* free up ram */
res = CRYPT_OK; res = CRYPT_OK;
goto done2; goto done2;
error2: error:
res = CRYPT_MEM; res = CRYPT_MEM;
mp_clear_multi(&key->x, &key->y, NULL); mp_clear_multi(&key->x, &key->y, NULL);
done2: done2:
@ -304,10 +281,10 @@ void dh_free(dh_key *key)
#define OUTPUT_BIGNUM(num, buf2, y, z) \ #define OUTPUT_BIGNUM(num, buf2, y, z) \
{ \ { \
z = mp_raw_size(num); \ z = mp_unsigned_bin_size(num); \
STORE32L(z, buf2+y); \ STORE32L(z, buf2+y); \
y += 4; \ y += 4; \
mp_toraw(num, buf2+y); \ mp_to_unsigned_bin(num, buf2+y); \
y += z; \ y += z; \
} }
@ -329,11 +306,15 @@ void dh_free(dh_key *key)
} \ } \
\ \
/* load it */ \ /* load it */ \
if (mp_read_raw(num, (unsigned char *)in+y, x) != MP_OKAY) {\ if (mp_read_unsigned_bin(num, (unsigned char *)in+y, x) != MP_OKAY) {\
errno = CRYPT_MEM; \ errno = CRYPT_MEM; \
goto error; \ goto error; \
} \ } \
y += x; \ y += x; \
if (mp_shrink(num) != MP_OKAY) { \
errno = CRYPT_MEM; \
goto error; \
} \
} }
@ -374,14 +355,16 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
} }
/* store header */ /* store header */
packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY, y); packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY);
/* output it */ /* output it */
*outlen = y; *outlen = y;
memcpy(out, buf2, y); memcpy(out, buf2, y);
/* clear mem */ /* clear mem */
#ifdef CLEAN_STACK
zeromem(buf2, sizeof(buf2)); zeromem(buf2, sizeof(buf2));
#endif
return CRYPT_OK; return CRYPT_OK;
} }
@ -436,6 +419,12 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
if (key->type == PK_PRIVATE) { if (key->type == PK_PRIVATE) {
INPUT_BIGNUM(&key->x, in, x, y); INPUT_BIGNUM(&key->x, in, x, y);
} }
/* eliminate private key if public */
if (key->type == PK_PUBLIC) {
mp_clear(&key->x);
}
return CRYPT_OK; return CRYPT_OK;
error: error:
mp_clear_multi(&key->y, &key->x, NULL); mp_clear_multi(&key->y, &key->x, NULL);
@ -469,7 +458,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
return CRYPT_MEM; return CRYPT_MEM;
} }
if (mp_read_radix(&p, sets[private_key->idx].prime, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&p, sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; }
if (mp_exptmod(&public_key->y, &private_key->x, &p, &tmp) != MP_OKAY) { goto error; } if (mp_exptmod(&public_key->y, &private_key->x, &p, &tmp) != MP_OKAY) { goto error; }
/* enough space for output? */ /* enough space for output? */

View File

@ -80,7 +80,7 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
} }
/* store header */ /* store header */
packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY, y); packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
/* clean up */ /* clean up */
@ -93,8 +93,9 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
return CRYPT_OK; return CRYPT_OK;
} }
int dh_decrypt_key(const unsigned char *in, unsigned char *outkey, int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, dh_key *key) unsigned char *outkey, unsigned long *keylen,
dh_key *key)
{ {
unsigned char shared_secret[1536], skey[MAXBLOCKSIZE]; unsigned char shared_secret[1536], skey[MAXBLOCKSIZE];
unsigned long x, y, z, res, hashsize, keysize; unsigned long x, y, z, res, hashsize, keysize;
@ -111,6 +112,13 @@ int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
return CRYPT_PK_NOT_PRIVATE; return CRYPT_PK_NOT_PRIVATE;
} }
/* check if initial header should fit */
if (inlen < PACKET_SIZE+1+4+4) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= PACKET_SIZE+1+4+4;
}
/* is header correct? */ /* is header correct? */
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
return errno; return errno;
@ -128,6 +136,14 @@ int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
/* get public key */ /* get public key */
LOAD32L(x, in+y); LOAD32L(x, in+y);
/* now check if the imported key will fit */
if (inlen < x) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= x;
}
y += 4; y += 4;
if ((errno = dh_import(in+y, x, &pubkey)) != CRYPT_OK) { if ((errno = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
return errno; return errno;
@ -149,6 +165,14 @@ int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
/* load in the encrypted key */ /* load in the encrypted key */
LOAD32L(keysize, in+y); LOAD32L(keysize, in+y);
/* will the outkey fit as part of the input */
if (inlen < keysize) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= keysize;
}
if (keysize > *keylen) { if (keysize > *keylen) {
res = CRYPT_BUFFER_OVERFLOW; res = CRYPT_BUFFER_OVERFLOW;
goto done; goto done;
@ -223,8 +247,8 @@ int dh_sign_hash(const unsigned char *in, unsigned long inlen,
if (mp_read_raw(&k, buf, sets[key->idx].size) != MP_OKAY) { goto error; } if (mp_read_raw(&k, buf, sets[key->idx].size) != MP_OKAY) { goto error; }
/* load g, p and p1 */ /* load g, p and p1 */
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&g, sets[key->idx].base, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&p, sets[key->idx].prime, 64) != MP_OKAY) { goto error; }
if (mp_sub_d(&p, 1, &p1) != MP_OKAY) { goto error; } if (mp_sub_d(&p, 1, &p1) != MP_OKAY) { goto error; }
if (mp_div_2(&p1, &p1) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */ if (mp_div_2(&p1, &p1) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */
@ -256,7 +280,7 @@ int dh_sign_hash(const unsigned char *in, unsigned long inlen,
} }
/* store header */ /* store header */
packet_store_header(buf, PACKET_SECT_DH, PACKET_SUB_SIGNED, y); packet_store_header(buf, PACKET_SECT_DH, PACKET_SUB_SIGNED);
/* store it */ /* store it */
memcpy(out, buf, y); memcpy(out, buf, y);
@ -275,9 +299,9 @@ done:
return res; return res;
} }
int dh_verify_hash(const unsigned char *sig, const unsigned char *hash, int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
unsigned long inlen, int *stat, const unsigned char *hash, unsigned long hashlen,
dh_key *key) int *stat, dh_key *key)
{ {
mp_int a, b, p, g, m, tmp; mp_int a, b, p, g, m, tmp;
unsigned char md[MAXBLOCKSIZE]; unsigned char md[MAXBLOCKSIZE];
@ -292,17 +316,24 @@ int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
/* default to invalid */ /* default to invalid */
*stat = 0; *stat = 0;
/* check initial input length */
if (siglen < PACKET_SIZE+4+4) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= PACKET_SIZE + 4 + 4;
}
/* header ok? */ /* header ok? */
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) { if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
return errno; return errno;
} }
/* get hash out of packet */ /* get hash out of packet */
y = PACKET_SIZE; y = PACKET_SIZE;
/* hash the message */ /* hash the message */
md[0] = 0; md[0] = 0;
memcpy(md+1, hash, MIN(sizeof(md) - 1, inlen)); memcpy(md+1, hash, MIN(sizeof(md) - 1, hashlen));
/* init all bignums */ /* init all bignums */
if (mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL) != MP_OKAY) { if (mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL) != MP_OKAY) {
@ -311,21 +342,32 @@ int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
/* load a and b */ /* load a and b */
LOAD32L(x, sig+y); LOAD32L(x, sig+y);
if (siglen < x) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= x;
}
y += 4; y += 4;
if (mp_read_raw(&a, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; } if (mp_read_raw(&a, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
y += x; y += x;
LOAD32L(x, sig+y); LOAD32L(x, sig+y);
if (siglen < x) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= x;
}
y += 4; y += 4;
if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; } if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
y += x; y += x;
/* load p and g */ /* load p and g */
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&p, sets[key->idx].prime, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&g, sets[key->idx].base, 64) != MP_OKAY) { goto error; }
/* load m */ /* load m */
if (mp_read_raw(&m, md, 1+MIN(sizeof(md)-1, inlen)) != MP_OKAY) { goto error; } if (mp_read_raw(&m, md, 1+MIN(sizeof(md)-1, hashlen)) != MP_OKAY) { goto error; }
/* find g^m mod p */ /* find g^m mod p */
if (mp_exptmod(&g, &m, &p, &m) != MP_OKAY) { goto error; } /* m = g^m mod p */ if (mp_exptmod(&g, &m, &p, &m) != MP_OKAY) { goto error; } /* m = g^m mod p */

398
dsa.c Normal file
View File

@ -0,0 +1,398 @@
/* Implementation of the Digital Signature Algorithm (DSA) by Tom St Denis */
#ifdef MDSA
#include <mycrypt.h>
static const struct {
int size, osize;
char *order,
*prime,
*base;
} sets[] = {
#ifdef DSA1024
{
1024, 160,
"PE6GbKzFwpeAAMtC3PUsqsRQMWl",
"PyhJv87GTec3fBvC8BQT4yQ8gSYB8rk6DfLRfeirnZsQaQBVwh8PZ7V1hKfD"
"SGGUgr1cAb3YrnZw97HvyaKmypY2dM19OxeNWNI4f6IyYwj/mcAiJpkjxMmZ"
"mYVrTbGxBG8OaKBD9vFd9/Jif8djJ18GnaRsdRoCBDec+W++x6D",
"3uYLnHhrVRR6hATv30lj/XX5AecEE2tJVgtWcHkbwKuR3WEqqvP8xBUG70Ve"
"p6kUchz/E/kZaGIJ0mrqme6bNDIxoNqtshyDfska/Zfm/QHuDZWljVGbPx68"
"eSBw1vzkRKFCmR8QgpT+R887JufEgQRRIQOuLK8c1ND61efJH2t"
},
#endif
#ifdef DSA2048
{
2048, 256,
"TZLgPgD7D46uoATLyNSgKsgh6LglcVDwlPFvT6dcOdN",
"EUlAFvO8lXjhXn/6BobNq4bo0st12+zwgpshNJgoUap/LFCQcGeVGt/s/ocD"
"M+4v+bU3dNKjFJEYzb+sxmy5dbzQsa15+Ud4v1UJ/7D4p0IyA+h9aeU9i/C9"
"tJQC824mQhmL5cxx7SbQPMD/2+P04hLyeDOir1L1vmvE1tWZg43Jbza2LTQJ"
"52wi/Sguai3vFZVMObEPBfbXzg9b8pH1i75Q1os9w0LtfJ4pYQJD3Xn66jYF"
"mpLVqK4yuMXOOq07bkM5Nx+jQvFpGuRiD5e4a2FB1NjXbCGMtRxu6eurPAIY"
"F5dw3QWXkZm74SFmLTi0GW+3pipDWiBSUu9pUpp6rr",
"79PG50FKgZgffOnFiUuuZLhWicqFZ6EwvWXQi7uBmvMQUoXNEBschAhRtLQE"
"ev5iHrR2g41rEEundwwFTbRdyq2txBS2bClkFjGlojPwayWvXLAaDltfkhws"
"TjS/gNKch4qD1nPu+Kd1RmjWp1B1JzBXnlcj/z5qMaF8oL4bk9qGGEmaeOLs"
"90vW0Z/7QWBC8h+65SohFBmydUWwXhs4rAa7NwHbPltnXdF6kZHpQOtT5h+4"
"hYA83eYzdeOl5rYrFDiyJ+nfOptgLiLIHB9L0wkOhFrb52+S7qKpgYe1+oof"
"K1/Rd4D8fL5qvGyXWz1dB8W2iqAXeXKlkWZrvHQdMM"
},
#endif
#ifdef DSA4096
{
4096, 512,
"4GO4hUY+2MqiwNBYFx/JqRejRKXXJfcaY7mIBYksn2Dwn6JQZp9Qpg3bbnOJ"
"kt5ZqH2dtEjbV9B/AXF51jOkW/",
"Jddrq1iN+f03IKVqcDSOz7IquBVxzb34Cwzmc7rHpIOW3DqW7IjMz47ETtWu"
"KvG3JxFdYaiv69lAE+X38DEqQSTE8Ba9jfNYs9PYeH4RfsT5op/u3r41anRW"
"jJTHMhnvwwQ0eQrZ+9d7LQePnQSUs3eXb8ZdNsh8/h30b3gIMk+08bZoJejF"
"6Y2vMtMQUHmmoM/+IlrMz7TZ4tu0jkYWBp1y74WLGemXkYvU6pqH8dTQX1MM"
"oG93eBKQ87jHbtBJ+L6EbcqO/jVa6lwUivEbBs9UtKf4lC0pe3SZqfFhrJde"
"2b5LfbPBLk2pNdC5MJCsIVz7TUL28SWYwx7Nx7ybxtKd76L8kgbLfoOYiJRx"
"WIFGRE40Q9/0zuqzz6D1WHKQE4wg5oy6WQeO3Q5BN1UC6O4EUSkD7mC3KmWA"
"MgxNDZYMA+BSCTirVL2eS90WCA4LkTsHhoLgafwZT5xanUKGY/cZix29sy21"
"J1Ut4cbPFjxg76OVu9obONitMLg+63dz3Ho8LMhXaKN43yl5Kc4PxeUCQWVU"
"gHXg8RSldQMOvhwohHFibiMUrRkkCs2//Ts6hVdS3cEFgfYhpnzeEiGBCuat"
"ZZYpaWKZlmrlcUYH7Rg9SyHH1h4DLrki5ySIjGxozT6JhIrMme8uQcN9YOiq"
"GwRhjR3AM1QiOUfolENTYCn",
"3VIJLic34uyamh2TbNHEjECeH289m938S2wvHYe/3xPNiCjVhBxl6RAgom+Q"
"3X7+r8EII4QQKXXdqR3Ad/nXzJkgMUJVvt5d5lIwwKM7+ffbLmhJWldO0Jkc"
"7oZQr7t81khBUG4wgPVZO8OwjB66v9npPCcBLNLO6DAWE82CM8YfPJzQt0tr"
"JSHwcgixvkFft25SdI0V9zg2H6sj2Q/yAYUEAPzyDfQVvLzqEN2tmIhturnR"
"wUW4WLy8PSls/tt5eWjdI++ofdGHNJmKaZjHgym52GhNQmWZYWzK/hcllWtC"
"U8vCw7GY3nE4uF74YuTYC6LGx7wXS5ivj531KTPe4EarZ4j+aVw9ZJhfy/h+"
"K0esj9ALQP9jSz3OMDKeYaJKjj/scC5NrPdSjeJf7EvlVf41ufZHNGrFVmVW"
"kqaEuNZr+SmC6/2buPEmL4UO94H1z4QItK+rHqNWEQP6ptST0lcFwHO4uESR"
"qp8scA2/Fh+G0TfJ/rg8wImqbWsgrUwGnmDmKtFLRiX4aMPIsyFIsJvPQECT"
"EIR6yd6QIRVGZbCRiVsCqMrHsn0KZWSeKdtW9TRt/yNu+VKcgRZFfU991Nab"
"OBxkAS1kw9kyj/HZYxPG4NrqL0j5bnb1VjqQZKEEQMSBAyMMfDuMyWhrmsxV"
"ffmF/sYGxFHCbacGeu06C3U"
},
#endif
{
0, 0,
NULL,
NULL,
NULL
}
};
int dsa_test(void)
{
mp_int q, p, g, t;
int errno, i, res, primality;
/* init memory */
if (mp_init_multi(&q, &p, &g, &t, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
res = CRYPT_MEM;
for (i = 0; i < sets[i].size; i++) {
#if 0
printf("Testing size: %d\n", sets[i].size);
#endif
/* read in order, prime, generator */
if (mp_read_radix(&q, sets[i].order, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&p, sets[i].prime, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&g, sets[i].base, 64) != MP_OKAY) { goto error; }
/* now see if the order and modulus are prime */
if ((errno = is_prime(&q, &primality)) != CRYPT_OK) {
res = errno;
goto error;
}
if (primality == 0) {
res = CRYPT_FAIL_TESTVECTOR;
goto error;
}
if ((errno = is_prime(&p, &primality)) != CRYPT_OK) {
res = errno;
goto error;
}
if (primality == 0) {
res = CRYPT_FAIL_TESTVECTOR;
goto error;
}
/* now see what g^q mod p is (should be 1) */
if (mp_exptmod(&g, &q, &p, &t) != MP_OKAY) { goto error; }
if (mp_cmp_d(&t, 1)) {
res = CRYPT_FAIL_TESTVECTOR;
goto error;
}
}
res = CRYPT_OK;
error:
mp_clear_multi(&t, &g, &p, &q, NULL);
return res;
}
int dsa_make_key(prng_state *prng, int wprng, int keysize, dsa_key *key)
{
mp_int g, p, q;
unsigned char buf[64];
int errno, idx, x;
_ARGCHK(prng != NULL);
_ARGCHK(key != NULL);
/* good prng? */
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
return errno;
}
/* find key size */
for (x = 0; (keysize > sets[x].size) && (sets[x].size); x++);
if (sets[x].size == 0) {
return CRYPT_INVALID_KEYSIZE;
}
key->idx = x;
keysize = sets[x].osize;
/* read prng */
if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) {
return CRYPT_ERROR_READPRNG;
}
/* init parameters */
if (mp_init_multi(&g, &p, &q, &key->x, &key->y, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
if (mp_read_radix(&q, sets[x].order, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&g, sets[x].base, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&p, sets[x].prime, 64) != MP_OKAY) { goto error; }
/* load exponent */
if (mp_read_unsigned_bin(&key->x, buf, keysize) != MP_OKAY) { goto error; }
if (mp_mod(&key->x, &q, &key->x) != MP_OKAY) { goto error; }
/* calc public key */
if (mp_exptmod(&g, &key->x, &p, &key->y) != MP_OKAY) { goto error; }
key->type = PK_PRIVATE;
/* shrink values */
if (mp_shrink(&key->x) != MP_OKAY) { goto error; }
if (mp_shrink(&key->y) != MP_OKAY) { goto error; }
/* free temps */
mp_clear_multi(&g, &q, &p, NULL);
#ifdef CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
error:
mp_clear_multi(&g, &q, &p, &key->x, &key->y, NULL);
return CRYPT_MEM;
}
void dsa_free(dsa_key *key)
{
_ARGCHK(key != NULL);
mp_clear_multi(&key->x, &key->y, NULL);
}
static int is_valid_idx(int n)
{
int x;
for (x = 0; sets[x].size; x++);
if ((n < 0) || (n >= x)) {
return 0;
}
return 1;
}
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key)
{
unsigned char buf[4096];
unsigned long x, y;
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(key != NULL);
if (is_valid_idx(key->idx) == 0) {
return CRYPT_PK_INVALID_TYPE;
}
if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
return CRYPT_PK_NOT_PRIVATE;
}
y = PACKET_SIZE;
buf[y++] = type;
buf[y++] = sets[key->idx].osize/8;
x = mp_unsigned_bin_size(&key->y);
STORE32L(x, &buf[y]);
y += 4;
mp_to_unsigned_bin(&key->y, &buf[y]);
y += x;
if (type == PK_PRIVATE) {
x = mp_unsigned_bin_size(&key->x);
STORE32L(x, &buf[y]);
y += 4;
mp_to_unsigned_bin(&key->x, &buf[y]);
y += x;
}
/* check for overflow */
if (*outlen < y) {
#ifdef CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_BUFFER_OVERFLOW;
}
/* store header */
packet_store_header(buf, PACKET_SECT_DSA, PACKET_SUB_KEY);
/* output it */
*outlen = y;
memcpy(out, buf, y);
/* clear mem */
#ifdef CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
#define INPUT_BIGNUM(num, in, x, y) \
{ \
/* load value */ \
if (y + 4 > inlen) { \
errno = CRYPT_INVALID_PACKET; \
goto error; \
} \
LOAD32L(x, in+y); \
y += 4; \
\
/* sanity check... */ \
if (x+y > inlen) { \
errno = CRYPT_INVALID_PACKET; \
goto error; \
} \
\
/* load it */ \
if (mp_read_unsigned_bin(num, (unsigned char *)in+y, x) != MP_OKAY) {\
errno = CRYPT_MEM; \
goto error; \
} \
y += x; \
if (mp_shrink(num) != MP_OKAY) { \
errno = CRYPT_MEM; \
goto error; \
} \
}
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
{
unsigned long x, y, s;
int errno;
_ARGCHK(in != NULL);
_ARGCHK(key != NULL);
/* check type byte */
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return errno;
}
if (2+PACKET_SIZE > inlen) {
return CRYPT_INVALID_PACKET;
}
/* init */
if (mp_init_multi(&key->x, &key->y, NULL) != MP_OKAY) {
return CRYPT_MEM;
}
y = PACKET_SIZE;
key->type = in[y++];
s = (long)in[y++] * 8;
for (x = 0; (s > (unsigned long)sets[x].osize) && (sets[x].osize); x++);
if (sets[x].osize == 0) {
errno = CRYPT_INVALID_KEYSIZE;
goto error;
}
key->idx = x;
/* type check both values */
if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
errno = CRYPT_PK_TYPE_MISMATCH;
goto error;
}
/* is the key idx valid? */
if (!is_valid_idx(key->idx)) {
errno = CRYPT_PK_TYPE_MISMATCH;
goto error;
}
/* load public value g^x mod p*/
INPUT_BIGNUM(&key->y, in, x, y);
if (key->type == PK_PRIVATE) {
INPUT_BIGNUM(&key->x, in, x, y);
}
/* eliminate private key if public */
if (key->type == PK_PUBLIC) {
mp_clear(&key->x);
}
return CRYPT_OK;
error:
mp_clear_multi(&key->y, &key->x, NULL);
return errno;
}
int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, dsa_key *key)
{
mp_int g, q, p, k, tmp;
unsigned char buf[4096];
int x, y, errno;
_ARGCHK(in != NULL);
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(prng != NULL);
_ARGCHK(key != NULL);
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
return errno;
}
if (is_valid_idx(key->idx) == 0) {
return CRYPT_PK_INVALID_TYPE;
}
return 0;
}
#endif /* MDSA */

245
ecc.c
View File

@ -18,15 +18,15 @@ static const struct {
20, 20,
"ECC-160", "ECC-160",
/* prime */ /* prime */
"1461501637330902918203684832716283019655932542983", "G00000000000000000000000007",
/* B */ /* B */
"1C9E7C2E5891CBE097BD46", "1oUV2vOaSlWbxr6",
/* order */ /* order */
"1461501637330902918203686297565868358251373258181", "G0000000000004sCQUtDxaqDUN5",
/* Gx */ /* Gx */
"2DCF462904B478D868A7FF3F2BF1FCD9", "jpqOf1BHus6Yd/pyhyVpP",
/* Gy */ /* Gy */
"DFFAF2EE3848FA75FB967CEC7B9A399E085ACED8", "D/wykuuIFfr+vPyx7kQEPu8MixO",
}, },
#endif #endif
#ifdef ECC192 #ifdef ECC192
@ -34,19 +34,19 @@ static const struct {
24, 24,
"ECC-192", "ECC-192",
/* prime */ /* prime */
"6277101735386680763835789423207666416083908700390324961279", "/////////////////////l//////////",
/* B */ /* B */
"64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", "P2456UMSWESFf+chSYGmIVwutkp1Hhcn",
/* order */ /* order */
"6277101735386680763835789423176059013767194773182842284081", "////////////////cTxuDXHhoR6qqYWn",
/* Gx */ /* Gx */
"188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "68se3h0maFPylo3hGw680FJ/2ls2/n0I",
/* Gy */ /* Gy */
"07192b95ffc8da78631011ed6b24cdd573f977a11e794811" "1nahbV/8sdXZ417jQoJDrNFvTw4UUKWH"
}, },
#endif #endif
#ifdef ECC224 #ifdef ECC224
@ -55,19 +55,19 @@ static const struct {
"ECC-224", "ECC-224",
/* prime */ /* prime */
"26959946667150639794667015087019630673637144422540572481103610249951", "400000000000000000000000000000000000BV",
/* B */ /* B */
"2051BA041508CED34B3", "21HkWGL2CxJIp",
/* order */ /* order */
"26959946667150639794667015087019637467111563745054605861463538557247", "4000000000000000000Kxnixk9t8MLzMiV264/",
/* Gx */ /* Gx */
"2DCF462904B478D868A7FF3F2BF1FCD9", "jpqOf1BHus6Yd/pyhyVpP",
/* Gy */ /* Gy */
"CF337F320BC44A15C3EDB8C4258BB958E57A0CAFA73EB46E9C4BA9AE", "3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
}, },
#endif #endif
#ifdef ECC256 #ifdef ECC256
@ -75,19 +75,19 @@ static const struct {
32, 32,
"ECC-256", "ECC-256",
/* Prime */ /* Prime */
"115792089210356248762697446949407573530086143415290314195533631308867097853951", "F////y000010000000000000000////////////////",
/* B */ /* B */
"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", "5h6DTYgEfFdi+kzLNQOXhnb7GQmp5EmzZlEF3udqc1B",
/* Order */ /* Order */
"115792089210356248762697446949407573529996955224135760342422259061068512044369", "F////y00000//////////+yvlgjfnUUXFEvoiByOoLH",
/* Gx */ /* Gx */
"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "6iNqVBXB497+BpcvMEaGF9t0ts1BUipeFIXEKNOcCAM",
/* Gy */ /* Gy */
"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" "4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r"
}, },
#endif #endif
#ifdef ECC384 #ifdef ECC384
@ -95,22 +95,23 @@ static const struct {
48, 48,
"ECC-384", "ECC-384",
/* prime */ /* prime */
"394020061963944792122790401001436138050797392704654466679482934042457217714968" "//////////////////////////////////////////x/////00000000003/"
"70329047266088258938001861606973112319", "////",
/* B */ /* B */
"b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed1" "ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ"
"9d2a85c8edd3ec2aef", "x2hl",
/* Order */ /* Order */
"394020061963944792122790401001436138050797392704654466679469052796276593991132" "////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC"
"63569398956308152294913554433653942643", "nIbp",
/* Gx and Gy */ /* Gx and Gy */
"aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf5529" "geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo"
"6c3a545e3872760ab7", "TWgt",
"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e81"
"9d7a431d7c90ea0e5f" "DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG"
"wWvV"
}, },
#endif #endif
#ifdef ECC521 #ifdef ECC521
@ -118,22 +119,23 @@ static const struct {
65, 65,
"ECC-521", "ECC-521",
/* prime */ /* prime */
"686479766013060971498190079908139321726943530014330540939446345918554318339765" "V///////////////////////////////////////////////////////////"
"6052122559640661454554977296311391480858037121987999716643812574028291115057151", "///////////////////////////",
/* B */ /* B */
"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7" "56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l"
"e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", "JknlmSrSz+8FImqyUz57zHhK3y0",
/* Order */ /* Order */
"686479766013060971498190079908139321726943530014330540939446345918554318339765" "V//////////////////////////////////////////+b66XuE/BvPhVym1I"
"5394245057746333217197532963996371363321113864768612440380340372808892707005449", "FS9fT0xjScuYPn7hhjljnwHE6G9",
/* Gx and Gy */ /* Gx and Gy */
"c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe7" "CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19"
"5928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "wB/gDupIBF1XMf2c/b+VZ72vRrc",
"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef"
"42640c550b9013fad0761353c7086a272c24088be94769fd16650", "HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0"
"J+j1s4rF726edB2G8Y+b7QVqMPG",
}, },
#endif #endif
{ {
@ -251,7 +253,7 @@ static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus)
/* s = (3Xp^2 + a) / (2Yp) */ /* s = (3Xp^2 + a) / (2Yp) */
if (mp_mul_2(&P->y, &tmp) != MP_OKAY) { goto error; } /* tmp = 2*y */ if (mp_mul_2(&P->y, &tmp) != MP_OKAY) { goto error; } /* tmp = 2*y */
if (mp_invmod(&tmp, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */ if (mp_invmod(&tmp, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
if (mp_sqr(&P->x, &s) != MP_OKAY) { goto error; } /* s = x^2 */ if (mp_sqr(&P->x, &s) != MP_OKAY) { goto error; } /* s = x^2 */
if (mp_mul_d(&s,(mp_digit)3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) */ if (mp_mul_d(&s,(mp_digit)3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) */
if (mp_sub_d(&s,(mp_digit)3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */ if (mp_sub_d(&s,(mp_digit)3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */
if (mp_mulmod(&s, &tmp, modulus, &s) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */ if (mp_mulmod(&s, &tmp, modulus, &s) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */
@ -329,59 +331,103 @@ done:
/* perform R = kG where k == integer and G == ecc_point */ /* perform R = kG where k == integer and G == ecc_point */
static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus, int idx) static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus, int idx)
{ {
ecc_point *tG; ecc_point *tG, *M[14];
int i, j, z, first, res; int i, j, m, z, first, res;
mp_digit d; mp_digit d;
unsigned char bits[768]; unsigned char bits[768];
/* init M tab */
for (i = 0; i < 14; i++) {
M[i] = new_point();
if (M[i] == NULL) {
for (j = 0; j < i; j++) {
del_point(M[j]);
}
return CRYPT_MEM;
}
}
/* get bits of k */ /* get bits of k */
first = m = 0;
for (z = i = 0; z < (int)USED(k); z++) { for (z = i = 0; z < (int)USED(k); z++) {
d = DIGIT(k, z); d = DIGIT(k, z);
for (j = 0; j < (int)MP_DIGIT_BIT; j++) {
#define DO1 bits[i++] = d&1; d >>= 1; first |= (d&1)<<(m++);
#define DO2 DO1 DO1 if (m == 4) {
#define DO4 DO2 DO2 bits[i++] = first;
first = m = 0;
DO4; DO4; DO4; DO4 }
d >>= 1;
#undef DO4 }
#undef DO2 }
#undef DO1
/* residue of multiplicand [if any] */
if (m) {
bits[i++] = first;
} }
/* 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) { if (tG == NULL) { goto error; }
return CRYPT_MEM;
}
/* skip leading digits which are zero */
--i; while (i && bits[i] == 0) { --i; }
if (i == 0) {
res = CRYPT_INVALID_ARG;
goto done;
}
/* now calc the M tab, note that there are only 14 spots, the normal M[0] is a no-op, and M[1] is the input
point (saves ram)
*/
/* M[0] now is 2*G */
if (dbl_point(G, M[0], modulus) != CRYPT_OK) { goto error; }
for (j = 1; j < 14; j++) {
if (add_point(M[j-1], G, M[j], modulus) != 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; }
/* set result to G, R = G */ /* set result M[bits[i]] */
if (mp_copy(&G->x, &R->x) != MP_OKAY) { goto error; } if (bits[i] == 1) {
if (mp_copy(&G->y, &R->y) != MP_OKAY) { goto error; } if (mp_copy(&G->x, &R->x) != MP_OKAY) { goto error; }
first = 0; if (mp_copy(&G->y, &R->y) != MP_OKAY) { goto error; }
} else if (bits[i]>=2) {
/* now do dbl+add through all the bits */ if (mp_copy(&M[bits[i]-2]->x, &R->x) != MP_OKAY) { goto error; }
for (j = i-1; j >= 0; j--) { if (mp_copy(&M[bits[i]-2]->y, &R->y) != MP_OKAY) { goto error; }
if (first) { }
if (dbl_point(R, R, modulus) != CRYPT_OK) { goto error; }
while (--i >= 0) {
/* double */
for (j = 0; j < 4; j++) {
if (dbl_point(R, R, modulus) != CRYPT_OK) { goto error; }
} }
if (bits[j] == 1) {
if (first) { /* now based on the value of bits[i] we do ops */
if (add_point(R, tG, R, modulus) != CRYPT_OK) { goto error; } if (bits[i] == 0) {
} /* nop */
first = 1; } else if (bits[i] == 1) {
/* add base point */
if (add_point(R, tG, R, modulus) != CRYPT_OK) { goto error; }
} else {
/* other case */
if (add_point(R, M[bits[i]-2], R, modulus) != CRYPT_OK) { goto error; }
} }
} }
res = CRYPT_OK; res = CRYPT_OK;
goto done; goto done;
error: error:
res = CRYPT_MEM; res = CRYPT_MEM;
done: done:
del_point(tG); del_point(tG);
for (i = 0; i < 14; i++) {
del_point(M[i]);
}
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
zeromem(bits, sizeof(bits)); zeromem(bits, sizeof(bits));
#endif #endif
@ -412,8 +458,11 @@ int ecc_test(void)
} }
for (i = 0; sets[i].size; i++) { for (i = 0; sets[i].size; i++) {
if (mp_read_radix(&modulus, (unsigned char *)sets[i].prime, 10) != MP_OKAY) { goto error; } #if 0
if (mp_read_radix(&order, (unsigned char *)sets[i].order, 10) != MP_OKAY) { goto error; } printf("Testing %d\n", sets[i].size);
#endif
if (mp_read_radix(&modulus, (unsigned char *)sets[i].prime, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&order, (unsigned char *)sets[i].order, 64) != MP_OKAY) { goto error; }
/* is prime actually prime? */ /* is prime actually prime? */
if (is_prime(&modulus, &primality) != CRYPT_OK) { goto error; } if (is_prime(&modulus, &primality) != CRYPT_OK) { goto error; }
@ -429,8 +478,8 @@ int ecc_test(void)
goto done1; goto done1;
} }
if (mp_read_radix(&G->x, (unsigned char *)sets[i].Gx, 16) != MP_OKAY) { goto error; } if (mp_read_radix(&G->x, (unsigned char *)sets[i].Gx, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&G->y, (unsigned char *)sets[i].Gy, 16) != MP_OKAY) { goto error; } if (mp_read_radix(&G->y, (unsigned char *)sets[i].Gy, 64) != MP_OKAY) { goto error; }
/* then we should have G == (order + 1)G */ /* then we should have G == (order + 1)G */
if (mp_add_d(&order, 1, &order) != MP_OKAY) { goto error; } if (mp_add_d(&order, 1, &order) != MP_OKAY) { goto error; }
@ -509,14 +558,19 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
} }
/* read in the specs for this key */ /* read in the specs for this key */
if (mp_read_radix(&prime, (unsigned char *)sets[x].prime, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&prime, (unsigned char *)sets[key->idx].prime, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&base->x, (unsigned char *)sets[x].Gx, 16) != MP_OKAY) { goto error; } if (mp_read_radix(&base->x, (unsigned char *)sets[key->idx].Gx, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&base->y, (unsigned char *)sets[x].Gy, 16) != MP_OKAY) { goto error; } if (mp_read_radix(&base->y, (unsigned char *)sets[key->idx].Gy, 64) != MP_OKAY) { goto error; }
if (mp_read_raw(&key->k, (unsigned char *)buf, keysize+1) != MP_OKAY) { goto error; } if (mp_read_raw(&key->k, (unsigned char *)buf, keysize+1) != MP_OKAY) { goto error; }
/* make the public key */ /* make the public key */
if (ecc_mulmod(&key->k, base, &key->pubkey, &prime, x) != CRYPT_OK) { goto error; } if (ecc_mulmod(&key->k, base, &key->pubkey, &prime, x) != CRYPT_OK) { goto error; }
key->type = PK_PRIVATE; key->type = PK_PRIVATE;
/* shrink key */
if (mp_shrink(&key->k) != MP_OKAY) { goto error; }
if (mp_shrink(&key->pubkey.x) != MP_OKAY) { goto error; }
if (mp_shrink(&key->pubkey.y) != MP_OKAY) { goto error; }
/* free up ram */ /* free up ram */
res = CRYPT_OK; res = CRYPT_OK;
@ -551,12 +605,12 @@ static int compress_y_point(ecc_point *pt, int idx, int *result)
} }
/* get x^3 - 3x + b */ /* get x^3 - 3x + b */
if (mp_read_radix(&p, (unsigned char *)sets[idx].B, 16) != MP_OKAY) { goto error; } /* p = B */ if (mp_read_radix(&p, (unsigned char *)sets[idx].B, 64) != MP_OKAY) { goto error; } /* p = B */
if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */ if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */
if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */ if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */
if (mp_read_radix(&p, (unsigned char *)sets[idx].prime, 10) != MP_OKAY) { goto error; } /* p = prime */ if (mp_read_radix(&p, (unsigned char *)sets[idx].prime, 64) != MP_OKAY) { goto error; } /* p = prime */
if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
/* now find square root */ /* now find square root */
@ -593,12 +647,12 @@ static int expand_y_point(ecc_point *pt, int idx, int result)
} }
/* get x^3 - 3x + b */ /* get x^3 - 3x + b */
if (mp_read_radix(&p, (unsigned char *)sets[idx].B, 16) != MP_OKAY) { goto error; } /* p = B */ if (mp_read_radix(&p, (unsigned char *)sets[idx].B, 64) != MP_OKAY) { goto error; } /* p = B */
if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */ if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */
if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */ if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */ if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */ if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */
if (mp_read_radix(&p, (unsigned char *)sets[idx].prime, 10) != MP_OKAY) { goto error; } /* p = prime */ if (mp_read_radix(&p, (unsigned char *)sets[idx].prime, 64) != MP_OKAY) { goto error; } /* p = prime */
if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */ if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
/* now find square root */ /* now find square root */
@ -625,10 +679,10 @@ done:
#define OUTPUT_BIGNUM(num, buf2, y, z) \ #define OUTPUT_BIGNUM(num, buf2, y, z) \
{ \ { \
z = mp_raw_size(num); \ z = mp_unsigned_bin_size(num); \
STORE32L(z, buf2+y); \ STORE32L(z, buf2+y); \
y += 4; \ y += 4; \
mp_toraw(num, buf2+y); \ mp_to_unsigned_bin(num, buf2+y); \
y += z; \ y += z; \
} }
@ -650,11 +704,15 @@ done:
} \ } \
\ \
/* load it */ \ /* load it */ \
if (mp_read_raw(num, (unsigned char *)in+y, x) != MP_OKAY) {\ if (mp_read_unsigned_bin(num, (unsigned char *)in+y, x) != MP_OKAY) {\
errno = CRYPT_MEM; \ errno = CRYPT_MEM; \
goto error; \ goto error; \
} \ } \
y += x; \ y += x; \
if (mp_shrink(num) != MP_OKAY) { \
errno = CRYPT_MEM; \
goto error; \
} \
} }
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
@ -696,7 +754,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
} }
/* store header */ /* store header */
packet_store_header(buf2, PACKET_SECT_ECC, PACKET_SUB_KEY, y); packet_store_header(buf2, PACKET_SECT_ECC, PACKET_SUB_KEY);
memcpy(out, buf2, y); memcpy(out, buf2, y);
*outlen = y; *outlen = y;
@ -765,10 +823,15 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
/* 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 */
if (key->type == PK_PUBLIC) {
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);
done:
return errno; return errno;
} }
@ -805,7 +868,7 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
return CRYPT_MEM; return CRYPT_MEM;
} }
if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 64) != MP_OKAY) { goto error; }
if ((errno = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime, private_key->idx)) != CRYPT_OK) { res = errno; goto done1; } if ((errno = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime, private_key->idx)) != CRYPT_OK) { res = errno; goto done1; }
x = mp_raw_size(&result->x); x = mp_raw_size(&result->x);

View File

@ -84,7 +84,7 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
} }
/* store header */ /* store header */
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY, y); packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
/* clean up */ /* clean up */
@ -96,8 +96,9 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
return CRYPT_OK; return CRYPT_OK;
} }
int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey, int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, ecc_key *key) unsigned char *outkey, unsigned long *keylen,
ecc_key *key)
{ {
unsigned char shared_secret[256], skey[MAXBLOCKSIZE]; unsigned char shared_secret[256], skey[MAXBLOCKSIZE];
unsigned long x, y, z, res, hashsize, keysize; unsigned long x, y, z, res, hashsize, keysize;
@ -113,6 +114,13 @@ int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
if (key->type != PK_PRIVATE) { if (key->type != PK_PRIVATE) {
return CRYPT_PK_NOT_PRIVATE; return CRYPT_PK_NOT_PRIVATE;
} }
/* correct length ? */
if (inlen < PACKET_SIZE+1+4+4) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= PACKET_SIZE+1+4+4;
}
/* is header correct? */ /* is header correct? */
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
@ -131,6 +139,11 @@ int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
/* get public key */ /* get public key */
LOAD32L(x, in+y); LOAD32L(x, in+y);
if (inlen < x) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= x;
}
y += 4; y += 4;
if ((errno = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) { if ((errno = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) {
return errno; return errno;
@ -151,6 +164,11 @@ int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
} }
LOAD32L(keysize, in+y); LOAD32L(keysize, in+y);
if (inlen < keysize) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= keysize;
}
y += 4; y += 4;
if (*keylen < keysize) { if (*keylen < keysize) {
@ -223,7 +241,7 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
ecc_free(&pubkey); ecc_free(&pubkey);
return CRYPT_MEM; return CRYPT_MEM;
} }
if (mp_read_radix(&p, (unsigned char *)sets[key->idx].order, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&p, (unsigned char *)sets[key->idx].order, 64) != MP_OKAY) { goto error; }
if (mp_read_raw(&b, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY) { goto error; } if (mp_read_raw(&b, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY) { goto error; }
/* find b = (m - x)/k */ /* find b = (m - x)/k */
@ -266,7 +284,7 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
} }
/* store header */ /* store header */
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED, y); packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED);
/* clear memory */ /* clear memory */
*outlen = y; *outlen = y;
@ -286,9 +304,9 @@ done1:
} }
/* verify that mG = (bA + Y) */ /* verify that mG = (bA + Y) */
int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash, int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
unsigned long inlen, int *stat, const unsigned char *hash, unsigned long inlen,
ecc_key *key) int *stat, ecc_key *key)
{ {
ecc_point *mG; ecc_point *mG;
ecc_key pubkey; ecc_key pubkey;
@ -305,6 +323,12 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
/* default to invalid signature */ /* default to invalid signature */
*stat = 0; *stat = 0;
if (siglen < PACKET_SIZE+4+4) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= PACKET_SIZE+4+4;
}
/* is the message format correct? */ /* is the message format correct? */
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) { if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) {
return errno; return errno;
@ -315,6 +339,11 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
/* get size of public key */ /* get size of public key */
LOAD32L(x, sig+y); LOAD32L(x, sig+y);
if (siglen < x) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= x;
}
y += 4; y += 4;
/* load the public key */ /* load the public key */
@ -325,6 +354,11 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
/* load size of 'b' */ /* load size of 'b' */
LOAD32L(x, sig+y); LOAD32L(x, sig+y);
if (siglen < x) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= x;
}
y += 4; y += 4;
/* init values */ /* init values */
@ -350,7 +384,7 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
if (mp_read_raw(&m, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY) { goto error; } if (mp_read_raw(&m, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY) { goto error; }
/* load prime */ /* load prime */
if (mp_read_radix(&p, (unsigned char *)sets[key->idx].prime, 10) != MP_OKAY) { goto error; } if (mp_read_radix(&p, (unsigned char *)sets[key->idx].prime, 64) != MP_OKAY) { goto error; }
/* get bA */ /* get bA */
if (ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p, key->idx) != CRYPT_OK) { goto error; } if (ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p, key->idx) != CRYPT_OK) { goto error; }
@ -359,8 +393,8 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
if (add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p) != CRYPT_OK) { goto error; } if (add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p) != CRYPT_OK) { goto error; }
/* get mG */ /* get mG */
if (mp_read_radix(&mG->x, (unsigned char *)sets[key->idx].Gx, 16) != MP_OKAY) { goto error; } if (mp_read_radix(&mG->x, (unsigned char *)sets[key->idx].Gx, 64) != MP_OKAY) { goto error; }
if (mp_read_radix(&mG->y, (unsigned char *)sets[key->idx].Gy, 16) != MP_OKAY) { goto error; } if (mp_read_radix(&mG->y, (unsigned char *)sets[key->idx].Gy, 64) != MP_OKAY) { goto error; }
if (ecc_mulmod(&m, mG, mG, &p, key->idx) != CRYPT_OK) { goto error; } if (ecc_mulmod(&m, mG, mG, &p, key->idx) != CRYPT_OK) { goto error; }
/* compare mG to bA + Y */ /* compare mG to bA + Y */

18
examples/ch1-01.c Normal file
View File

@ -0,0 +1,18 @@
/*
* Name : ch1-01.c
* Purpose : Demonstration of a basic libtomcrypt program
* Author : Tom St Denis
*
* History : v0.79 Initial release
*/
/* ch1-01-1 */
/* Include the default headers and libtomcrypt headers */
#include <mycrypt.h>
int main(void)
{
return 0;
}
/* ch1-01-1 */

25
examples/ch1-02.c Normal file
View File

@ -0,0 +1,25 @@
/*
* Name : ch1-02.c
* Purpose : Demonstration of error handling
* Author : Tom St Denis
*
* History : v0.79 Initial release
*/
/* ch1-01-1 */
#include <mycrypt.h>
int main(void)
{
int errno;
if ((errno = some_func(...)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return EXIT_FAILURE;
}
return 0;
}
/*ch1-01-1 */

29
examples/ch1-03.c Normal file
View File

@ -0,0 +1,29 @@
/*
* Name : ch1-03.c
* Purpose : Demonstration of variable length outputs
* Author : Tom St Denis
*
* History : v0.79 Initial release
*/
/* ch1-01-1 */
#include <mycrypt.h>
int main(void)
{
unsigned long length;
unsigned char buffer[512];
int errno;
length = sizeof(buffer);
if ((errno = some_func(..., buffer, &length)) != CRYPT_OK) {
printf("Error: %s\n", error_to_string(errno));
return EXIT_FAILURE;
}
printf("Size of output is %lu bytes\n", length);
return 0;
}
/* ch1-01-1 */

View File

@ -70,6 +70,7 @@ static const unsigned long crc_table[256] = {
static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len) static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len)
{ {
//_ARGCHK(buf != NULL && len == 0);
crc = crc ^ 0xffffffffL; crc = crc ^ 0xffffffffL;
while (len >= 8) { while (len >= 8) {
DO8 (buf); DO8 (buf);
@ -587,25 +588,26 @@ int kr_encrypt_key(pk_key *pk, unsigned long ID,
STORE32L(kr->ID,buf+4); STORE32L(kr->ID,buf+4);
/* now encrypt it */ /* now encrypt it */
len = sizeof(buf)-8; len = sizeof(buf)-12;
switch (kr->system) { switch (kr->system) {
case RSA_KEY: case RSA_KEY:
if ((errno = rsa_encrypt_key(in, inlen, buf+8, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) { if ((errno = rsa_encrypt_key(in, inlen, buf+12, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case DH_KEY: case DH_KEY:
if ((errno = dh_encrypt_key(in, inlen, buf+8, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) { if ((errno = dh_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case ECC_KEY: case ECC_KEY:
if ((errno = ecc_encrypt_key(in, inlen, buf+8, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) { if ((errno = ecc_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
} }
len += 8; STORE32L(len,buf+8);
len += 12;
if (len > *outlen) { if (len > *outlen) {
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
@ -626,7 +628,7 @@ int kr_decrypt_key(pk_key *pk, const unsigned char *in,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned char buf[8192]; unsigned char buf[8192];
unsigned long len, ID; unsigned long pklen, len, ID;
pk_key *kr; pk_key *kr;
int errno; int errno;
@ -653,20 +655,21 @@ int kr_decrypt_key(pk_key *pk, const unsigned char *in,
} }
/* now try and decrypt it */ /* now try and decrypt it */
LOAD32L(pklen,in+8);
len = sizeof(buf); len = sizeof(buf);
switch (kr->system) { switch (kr->system) {
case RSA_KEY: case RSA_KEY:
if ((errno = rsa_decrypt_key(in+8, buf, &len, &(kr->key.rsa))) != CRYPT_OK) { if ((errno = rsa_decrypt_key(in+12, pklen, buf, &len, &(kr->key.rsa))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case DH_KEY: case DH_KEY:
if ((errno = dh_decrypt_key(in+8, buf, &len, &(kr->key.dh))) != CRYPT_OK) { if ((errno = dh_decrypt_key(in+12, pklen, buf, &len, &(kr->key.dh))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case ECC_KEY: case ECC_KEY:
if ((errno = ecc_decrypt_key(in+8, buf, &len, &(kr->key.ecc))) != CRYPT_OK) { if ((errno = ecc_decrypt_key(in+12, pklen, buf, &len, &(kr->key.ecc))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
@ -720,26 +723,27 @@ int kr_sign_hash(pk_key *pk, unsigned long ID,
STORE32L(kr->ID,buf+4); STORE32L(kr->ID,buf+4);
/* now sign it */ /* now sign it */
len = sizeof(buf)-12; len = sizeof(buf)-16;
switch (kr->system) { switch (kr->system) {
case RSA_KEY: case RSA_KEY:
if ((errno = rsa_sign_hash(in, inlen, buf+12, &len, &(kr->key.rsa))) != CRYPT_OK) { if ((errno = rsa_sign_hash(in, inlen, buf+16, &len, &(kr->key.rsa))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case DH_KEY: case DH_KEY:
if ((errno = dh_sign_hash(in, inlen, buf+12, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) { if ((errno = dh_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case ECC_KEY: case ECC_KEY:
if ((errno = ecc_sign_hash(in, inlen, buf+12, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) { if ((errno = ecc_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
} }
STORE32L(inlen,buf+8); STORE32L(inlen,buf+8);
len += 12; STORE32L(len,buf+12);
len += 16;
if (len > *outlen) { if (len > *outlen) {
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
@ -759,7 +763,7 @@ int kr_sign_hash(pk_key *pk, unsigned long ID,
int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *hash, int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *hash,
unsigned long hashlen, int *stat) unsigned long hashlen, int *stat)
{ {
unsigned long inlen, ID; unsigned long inlen, pklen, ID;
pk_key *kr; pk_key *kr;
int errno; int errno;
@ -785,23 +789,24 @@ int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *has
/* now try and verify it */ /* now try and verify it */
LOAD32L(inlen,in+8); /* this is the length of the original inlen */ LOAD32L(inlen,in+8); /* this is the length of the original inlen */
LOAD32L(pklen,in+12); /* size of the PK packet */
if (inlen != hashlen) { /* size doesn't match means the signature is invalid */ if (inlen != hashlen) { /* size doesn't match means the signature is invalid */
return CRYPT_OK; return CRYPT_OK;
} }
switch (kr->system) { switch (kr->system) {
case RSA_KEY: case RSA_KEY:
if ((errno = rsa_verify_hash(in+12, hash, stat, &(kr->key.rsa))) != CRYPT_OK) { if ((errno = rsa_verify_hash(in+16, pklen, hash, stat, &(kr->key.rsa))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case DH_KEY: case DH_KEY:
if ((errno = dh_verify_hash(in+12, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) { if ((errno = dh_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;
case ECC_KEY: case ECC_KEY:
if ((errno = ecc_verify_hash(in+12, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) { if ((errno = ecc_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) {
return errno; return errno;
} }
break; break;

148
makefile
View File

@ -9,62 +9,77 @@
# 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.78 VERSION=0.79
#Compiler and Linker Names #ch1-01-1
# Compiler and Linker Names
CC=gcc CC=gcc
LD=ld LD=ld
#Archiver [makes .a files] # Archiver [makes .a files]
AR=ar AR=ar
ARFLAGS=rs ARFLAGS=r
#ch1-01-1
#here you can set the malloc/calloc/free functions you want #ch1-01-2
# here you can set the malloc/calloc/free functions you want
XMALLOC=malloc XMALLOC=malloc
XCALLOC=calloc XCALLOC=calloc
XREALLOC=realloc
XFREE=free XFREE=free
#you can redefine the clock # you can redefine the clock
XCLOCK=clock XCLOCK=clock
XCLOCKS_PER_SEC=CLOCKS_PER_SEC XCLOCKS_PER_SEC=CLOCKS_PER_SEC
#ch1-01-2
#Compilation flags. Note the += does not write over the user's CFLAGS! #ch1-01-3
# Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \
-DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) -DXCLOCK=$(XCLOCK) \ -DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) \
-DXREALLOC=$(XREALLOC) -DXCLOCK=$(XCLOCK) \
-DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC) -DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
#optimize for SPEED (comment out SIZE/DEBUG line as well) # optimize for SPEED
#CFLAGS += -O3 -funroll-loops #CFLAGS += -O3 -funroll-loops
#optimize for SIZE (comment out SPEED/DEBUG line as well) # optimize for SIZE
CFLAGS += -Os CFLAGS += -Os
#Use small code variants of functions when possible? (Slows it down!) # compile for DEBUGGING
CFLAGS += -DSMALL_CODE
#compile for DEBUGGING
#CFLAGS += -g3 #CFLAGS += -g3
#ch1-01-3
#These flags control how the library gets built. #These flags control how the library gets built.
#no file support, when defined the library will not have any functions that can read/write files #ch1-01-4
#(comment out to have file support) # Use small code variants of functions when possible?
CFLAGS += -DSMALL_CODE
# no file support, when defined the library will not
# have any functions that can read/write files
# (comment out to have file support)
#CFLAGS += -DNO_FILE #CFLAGS += -DNO_FILE
#Support the UNIX /dev/random or /dev/urandom # Support the UNIX /dev/random or /dev/urandom
CFLAGS += -DDEVRANDOM CFLAGS += -DDEVRANDOM
# Use /dev/urandom first on devices where /dev/random is too slow */ # Use /dev/urandom first on devices where
# /dev/random is too slow
#CFLAGS += -DTRY_URANDOM_FIRST #CFLAGS += -DTRY_URANDOM_FIRST
# Clean the stack after sensitive functions. Not always required... # Clean the stack after sensitive functions. Not
# With this defined most of the ciphers and hashes will clean their stack area # always required... With this defined most of
# after usage with a (sometimes) huge penalty in speed. Normally this is not # the ciphers and hashes will clean their stack area
# required if you simply lock your stack and wipe it when your program is done. # after usage with a (sometimes) huge penalty in speed.
# Normally this is not required if you simply lock your
# stack and wipe it when your program is done.
# #
#CFLAGS += -DCLEAN_STACK #CFLAGS += -DCLEAN_STACK
#ch1-01-4
# What algorithms to include? comment out and rebuild to remove em #ch1-01-5
# What algorithms to include? comment out and rebuild to remove them
CFLAGS += -DBLOWFISH CFLAGS += -DBLOWFISH
CFLAGS += -DRC2 CFLAGS += -DRC2
CFLAGS += -DRC5 CFLAGS += -DRC5
@ -78,6 +93,7 @@ CFLAGS += -DTWOFISH
CFLAGS += -DDES CFLAGS += -DDES
CFLAGS += -DCAST5 CFLAGS += -DCAST5
CFLAGS += -DNOEKEON CFLAGS += -DNOEKEON
#ch1-01-5
#You can also customize the Twofish code. All four combinations #You can also customize the Twofish code. All four combinations
#of the flags are possible but only three of them make sense. #of the flags are possible but only three of them make sense.
@ -90,17 +106,23 @@ CFLAGS += -DNOEKEON
#_TABLES defined: Very fast, not faster than if both were undefined. Code is ~1KB bigger #_TABLES defined: Very fast, not faster than if both were undefined. Code is ~1KB bigger
# faster keysetup though... # faster keysetup though...
# Small Ram Variant of Twofish. For this you must have TWOFISH defined. This #ch1-01-6
# variant requires about 4kb less memory but is considerably slower. It is ideal # Small Ram Variant of Twofish. For this you must have TWOFISH
# when high throughput is less important than conserving memory. By default it is # defined. This variant requires about 4kb less memory but
# not defined which means the larger ram (about 4.2Kb used) variant is built. # is considerably slower. It is ideal when high throughput is
# less important than conserving memory. By default it is not
# defined which means the larger ram (about 4.2Kb used) variant
# is built.
#CFLAGS += -DTWOFISH_SMALL #CFLAGS += -DTWOFISH_SMALL
# Tell Twofish to use precomputed tables. If you want to use the small table # Tell Twofish to use precomputed tables. If you want to use
# variant of Twofish you may want to turn this on. Essentially it tells Twofish to use # the small table variant of Twofish you may want to turn
# precomputed S-boxes (Q0 and Q1) as well as precomputed GF multiplications [in the MDS]. # this on. Essentially it tells Twofish to use precomputed
# This speeds up the cipher somewhat. # S-boxes (Q0 and Q1) as well as precomputed GF
# multiplications [in the MDS]. This speeds up the cipher
# somewhat.
#CFLAGS += -DTWOFISH_TABLES #CFLAGS += -DTWOFISH_TABLES
#ch1-01-6
#Use fast PK routines. Basically this limits the size of the private key in the #Use fast PK routines. Basically this limits the size of the private key in the
#DH system to 256 bits. The group order remains unchanged so the best #DH system to 256 bits. The group order remains unchanged so the best
@ -110,13 +132,16 @@ CFLAGS += -DNOEKEON
#security so its by default not turned on. USE AT YOUR RISK! #security so its by default not turned on. USE AT YOUR RISK!
#CFLAGS += -DFAST_PK #CFLAGS += -DFAST_PK
#ch1-01-7
# Chaining modes # Chaining modes
CFLAGS += -DCFB CFLAGS += -DCFB
CFLAGS += -DOFB CFLAGS += -DOFB
CFLAGS += -DECB CFLAGS += -DECB
CFLAGS += -DCBC CFLAGS += -DCBC
CFLAGS += -DCTR CFLAGS += -DCTR
#ch1-01-7
#ch1-01-8
#One-way hashes #One-way hashes
CFLAGS += -DSHA512 CFLAGS += -DSHA512
CFLAGS += -DSHA384 CFLAGS += -DSHA384
@ -126,29 +151,73 @@ CFLAGS += -DSHA1
CFLAGS += -DMD5 CFLAGS += -DMD5
CFLAGS += -DMD4 CFLAGS += -DMD4
CFLAGS += -DMD2 CFLAGS += -DMD2
#ch1-01-8
# base64 #ch1-01-9
CFLAGS += -DBASE64
# prngs # prngs
CFLAGS += -DYARROW CFLAGS += -DYARROW
CFLAGS += -DSPRNG CFLAGS += -DSPRNG
CFLAGS += -DRC4 CFLAGS += -DRC4
#ch1-01-9
#ch1-01-10
# PK code # PK code
CFLAGS += -DMRSA CFLAGS += -DMRSA
CFLAGS += -DMDH CFLAGS += -DMDH
CFLAGS += -DMECC CFLAGS += -DMECC
#CFLAGS += -DMDSA
CFLAGS += -DKR CFLAGS += -DKR
#ch1-01-10
# include GF math routines? (not currently used by anything internally) #ch1-01-12
# Control which built in DH or ECC key paramaters
# are to be allowed
CFLAGS += -DDH768
CFLAGS += -DDH1024
CFLAGS += -DDH1280
CFLAGS += -DDH1536
CFLAGS += -DDH1792
CFLAGS += -DDH2048
CFLAGS += -DDH2560
CFLAGS += -DDH3072
CFLAGS += -DDH4096
CFLAGS += -DECC160
CFLAGS += -DECC192
CFLAGS += -DECC224
CFLAGS += -DECC256
CFLAGS += -DECC384
CFLAGS += -DECC521
CFLAGS += -DDSA1024
CFLAGS += -DDSA2048
CFLAGS += -DDSA4096
#ch1-01-12
#ch1-01-11
# base64
CFLAGS += -DBASE64
# include GF math routines?
# (not currently used by anything internally)
#CFLAGS += -DGF #CFLAGS += -DGF
# include large integer math routines? (required by the PK code) # include large integer math routines? (required by the PK code)
CFLAGS += -DMPI CFLAGS += -DMPI
# use the fast exptmod operation (used in dsa/rsa/dh and is_prime)
# This uses slightly more heap than the old code [only during the function call]
# this is also fairly faster than the previous code
CFLAGS += -DMPI_FASTEXPT
# use a "low" mem variant of the fast exptmod. It is still always
# faster then the old exptmod but its savings drops off after
# 1024 to 2048-bits
#CFLAGS += -DMPI_FASTEXPT_LOWMEM
# include HMAC support # include HMAC support
CFLAGS += -DHMAC CFLAGS += -DHMAC
#ch1-01-11
#Output filenames for various targets. #Output filenames for various targets.
LIBNAME=libtomcrypt.a LIBNAME=libtomcrypt.a
@ -163,7 +232,7 @@ LIBPATH=/usr/lib
INCPATH=/usr/include INCPATH=/usr/include
#List of objects to compile. #List of objects to compile.
OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \ OBJECTS=keyring.o gf.o mem.o sprng.o dsa.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 \
@ -199,6 +268,7 @@ sha512.o: sha512.c sha384.c
#This rule makes the libtomcrypt library. #This rule makes the libtomcrypt library.
library: $(OBJECTS) library: $(OBJECTS)
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS) $(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS)
ranlib $(LIBNAME)
#This rule makes the test program included with libtomcrypt #This rule makes the test program included with libtomcrypt
test: library $(TESTOBJECTS) test: library $(TESTOBJECTS)
@ -219,9 +289,11 @@ small: library $(SMALLOBJECTS)
#This rule installs the library and the header files. This must be run #This rule installs the library and the header files. This must be run
#as root in order to have a high enough permission to write to the correct #as root in order to have a high enough permission to write to the correct
#directories and to set the owner and group to root. #directories and to set the owner and group to root.
install: library install: library docs
install -g root -o root $(LIBNAME) $(LIBPATH) install -g root -o root $(LIBNAME) $(LIBPATH)
install -g root -o root $(HEADERS) $(INCPATH) install -g root -o root $(HEADERS) $(INCPATH)
mkdir -p /usr/doc/libtomcrypt/pdf
cp crypt.pdf /usr/doc/libtomcrypt/pdf/
#This rule cleans the source tree of all compiled code, not including the pdf #This rule cleans the source tree of all compiled code, not including the pdf
#documentation. #documentation.
@ -241,7 +313,7 @@ docs: crypt.tex
makeindex crypt > /dev/null makeindex crypt > /dev/null
pdflatex crypt > /dev/null pdflatex crypt > /dev/null
rm -f $(LEFTOVERS) rm -f $(LEFTOVERS)
#zipup the project (take that!) #zipup the project (take that!)
zipup: clean docs zipup: clean docs
chdir .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ chdir .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \

23
makefile.out Normal file
View File

@ -0,0 +1,23 @@
#makefile generated with config.pl
#
#Tom St Denis (tomstdenis@yahoo.com, http://tom.iahu.ca)
CC = gcc
AR = ar
LD = ld
CFLAGS += -Os -Wall -Wsign-compare -W -Wno-unused -Werror -I./ -DXMALLOC=malloc -DXCALLOC=calloc -DXFREE=free -DXCLOCK=clock -DXCLOCKS_PER_SEC=CLOCKS_PER_SEC -DSMALL_CODE -DBLOWFISH -DRC2 -DRC5 -DRC6 -DSERPENT -DSAFERP -DSAFER -DRIJNDAEL -DXTEA -DTWOFISH -DDES -DCAST5 -DNOEKEON -DCFB -DOFB -DECB -DCBC -DCTR -DSHA512 -DSHA384 -DSHA256 -DTIGER -DSHA1 -DMD5 -DMD4 -DMD2 -DHMAC -DBASE64 -DYARROW -DSPRNG -DRC4 -DDEVRANDOM -DMRSA -DMDH -DMECC -DMDSA -DKR -DDH768 -DDH1024 -DDH1280 -DDH1536 -DDH1792 -DDH2048 -DDH2560 -DDH3072 -DDH4096 -DECC160 -DECC192 -DECC224 -DECC256 -DECC384 -DECC521 -DDSA1024 -DDSA2048 -DDSA4096 -DMPI -DMPI_FASTEXPT
default: library
OBJECTS = keyring.o gf.o mem.o sprng.o dsa.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
rsa.o: rsa_sys.c
dh.o: dh_sys.c
ecc.o: ecc_sys.c
library: $(OBJECTS)
$(AR) rs libtomcrypt.a $(OBJECTS)
clean:
rm -f $(OBJECTS) libtomcrypt.a

View File

@ -32,6 +32,7 @@ ARFLAGS=rs
#here you can set the malloc/calloc/free functions you want #here you can set the malloc/calloc/free functions you want
XMALLOC=malloc XMALLOC=malloc
XCALLOC=calloc XCALLOC=calloc
XREALLOC=realloc
XFREE=free XFREE=free
#you can redefine the clock #you can redefine the clock
@ -40,7 +41,8 @@ XCLOCKS_PER_SEC=576000
#Compilation flags. Note the += does not write over the user's CFLAGS! #Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \
-DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) -DXCLOCK=$(XCLOCK) \ -DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) \
-DXREALLOC=$(XREALLOC) -DXCLOCK=$(XCLOCK) \
-DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC) -DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
#optimize for SPEED (comment out SIZE line as well) #optimize for SPEED (comment out SIZE line as well)
@ -103,14 +105,6 @@ CFLAGS += -DNOEKEON
# This speeds up the cipher somewhat. # This speeds up the cipher somewhat.
# CFLAGS += -DTWOFISH_TABLES # CFLAGS += -DTWOFISH_TABLES
#Small code variant of the SAFER+ cipher, uses same RAM but less code space
#With this defined the cipher is slower. On my x86 with GCC 3.2 it required 50KB less space
CFLAGS += -DSAFERP_SMALL
#Small Rijndael [saves 13KB on an x86]
#With this defined the cipher is slower (by 50Mbit/sec on an Athon XP)
CFLAGS += -DRIJNDAEL_SMALL
#Use fast PK routines. Basically this limits the size of the private key in the #Use fast PK routines. Basically this limits the size of the private key in the
#DH system to 256 bits. The group order remains unchanged so the best #DH system to 256 bits. The group order remains unchanged so the best
#attacks are still GNFS (for DH upto 2560-bits) #attacks are still GNFS (for DH upto 2560-bits)
@ -148,14 +142,48 @@ CFLAGS += -DRC4
CFLAGS += -DMRSA CFLAGS += -DMRSA
CFLAGS += -DMDH CFLAGS += -DMDH
CFLAGS += -DMECC CFLAGS += -DMECC
#CFLAGS += -DDSA
CFLAGS += -DKR CFLAGS += -DKR
# Control which built in DH or ECC key paramaters
# are to be allowed
CFLAGS += -DDH768
CFLAGS += -DDH1024
CFLAGS += -DDH1280
CFLAGS += -DDH1536
CFLAGS += -DDH1792
CFLAGS += -DDH2048
CFLAGS += -DDH2560
CFLAGS += -DDH3072
CFLAGS += -DDH4096
CFLAGS += -DECC160
CFLAGS += -DECC192
CFLAGS += -DECC224
CFLAGS += -DECC256
CFLAGS += -DECC384
CFLAGS += -DECC521
CFLAGS += -DDSA1024
CFLAGS += -DDSA2048
CFLAGS += -DDSA4096
# include GF math routines? (not currently used by anything internally) # include GF math routines? (not currently used by anything internally)
#CFLAGS += -DGF #CFLAGS += -DGF
# include large integer math routines? (required by the PK code) # include large integer math routines? (required by the PK code)
CFLAGS += -DMPI CFLAGS += -DMPI
# use the fast exptmod operation (used in dsa/rsa/dh and is_prime)
# This uses slightly more heap than the old code [only during the function call]
# this is also fairly faster than the previous code
CFLAGS += -DMPI_FASTEXPT
# use a "low" mem variant of the fast exptmod. It is still always
# faster then the old exptmod but its savings drops off after
# 1024-bits
CFLAGS += -DMPI_FASTEXPT_LOWMEM
# include HMAC support # include HMAC support
CFLAGS += -DHMAC CFLAGS += -DHMAC
@ -175,7 +203,7 @@ LIBPATH=/usr/lib
INCPATH=/usr/include INCPATH=/usr/include
#List of objects to compile. #List of objects to compile.
OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \ OBJECTS=keyring.o gf.o mem.o sprng.o dsa.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 \

View File

@ -8,13 +8,14 @@ AR=lib
#here you can set the malloc/calloc/free functions you want #here you can set the malloc/calloc/free functions you want
XMALLOC=malloc XMALLOC=malloc
XCALLOC=calloc XCALLOC=calloc
XREALLOC=realloc
XFREE=free XFREE=free
#you can redefine the clock #you can redefine the clock
XCLOCK=clock XCLOCK=clock
XCLOCKS_PER_SEC=CLOCKS_PER_SEC XCLOCKS_PER_SEC=CLOCKS_PER_SEC
CFLAGS = /c /Ogisy1 /Gs /I. /W3 /DWIN32 /DXMALLOC=$(XMALLOC) /DXCALLOC=$(XCALLOC) /DXFREE=$(XFREE) /DXCLOCK=$(XCLOCK) /DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC) CFLAGS = /c /Ogisy1 /Gs /I. /W3 /DWIN32 /DXREALLOC=$(XREALLOC) /DXMALLOC=$(XMALLOC) /DXCALLOC=$(XCALLOC) /DXFREE=$(XFREE) /DXCLOCK=$(XCLOCK) /DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
#Small code (smaller variants of some block ciphers) #Small code (smaller variants of some block ciphers)
CFLAGS += /DSMALL_CODE CFLAGS += /DSMALL_CODE
@ -113,14 +114,49 @@ CFLAGS += /DRC4
CFLAGS += /DMRSA CFLAGS += /DMRSA
CFLAGS += /DMDH CFLAGS += /DMDH
CFLAGS += /DMECC CFLAGS += /DMECC
#CFLAGS += /DDSA
CFLAGS += /DKR CFLAGS += /DKR
# Control which built in DH or ECC key paramaters
# are to be allowed
CFLAGS += /DDH768
CFLAGS += /DDH1024
CFLAGS += /DDH1280
CFLAGS += /DDH1536
CFLAGS += /DDH1792
CFLAGS += /DDH2048
CFLAGS += /DDH2560
CFLAGS += /DDH3072
CFLAGS += /DDH4096
CFLAGS += /DECC160
CFLAGS += /DECC192
CFLAGS += /DECC224
CFLAGS += /DECC256
CFLAGS += /DECC384
CFLAGS += /DECC521
CFLAGS += /DDSA1024
CFLAGS += /DDSA2048
CFLAGS += /DDSA4096
# include GF math routines? (not currently used by anything internally) # include GF math routines? (not currently used by anything internally)
#CFLAGS += /DGF #CFLAGS += /DGF
# include large integer math routines? (required by the PK code) # include large integer math routines? (required by the PK code)
CFLAGS += /DMPI CFLAGS += /DMPI
# use the fast exptmod operation (used in dsa/rsa/dh and is_prime)
# This uses slightly more heap than the old code [only during the function call]
# this is also fairly faster than the previous code
CFLAGS += /DMPI_FASTEXPT
# use a "low" mem variant of the fast exptmod. It is still always
# faster then the old exptmod but its savings drops off after
# 1024-bits
#CFLAGS += /DMPI_FASTEXPT_LOWMEM
# include HMAC support # include HMAC support
CFLAGS += /DHMAC CFLAGS += /DHMAC
@ -216,6 +252,8 @@ cast5.obj: cast5.c
$(CC) $(CFLAGS) cast5.c $(CC) $(CFLAGS) cast5.c
noekeon.obj: noekeon.c noekeon.obj: noekeon.c
$(CC) $(CFLAGS) noekeon.c $(CC) $(CFLAGS) noekeon.c
dsa.obj: dsa.c
$(CC) $(CFLAGS) dsa.c
demos/test.obj: demos/test.c demos/test.obj: demos/test.c
$(CC) $(CFLAGS) demos/test.c $(CC) $(CFLAGS) demos/test.c
@ -223,11 +261,11 @@ demos/test.obj: demos/test.c
demos/hashsum.obj: demos/hashsum.c demos/hashsum.obj: demos/hashsum.c
$(CC) $(CFLAGS) demos/hashsum.c $(CC) $(CFLAGS) demos/hashsum.c
tomcrypt.lib: keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj bits.obj hmac.obj \ tomcrypt.lib: keyring.obj gf.obj mem.obj sprng.obj dsa.obj ecc.obj base64.obj dh.obj rsa.obj bits.obj hmac.obj \
yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj md2.obj md5.obj md4.obj sha256.obj sha512.obj xtea.obj \ yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj md2.obj md5.obj md4.obj sha256.obj sha512.obj xtea.obj \
aes.obj serpent.obj safer_tab.obj safer.obj safer+.obj cast5.obj noekeon.obj rc2.obj rc6.obj rc5.obj des.obj blowfish.obj crypt.obj ampi.obj \ aes.obj serpent.obj safer_tab.obj safer.obj safer+.obj cast5.obj noekeon.obj rc2.obj rc6.obj rc5.obj des.obj blowfish.obj crypt.obj ampi.obj \
strings.obj mpi.obj prime.obj twofish.obj packet.obj strings.obj mpi.obj prime.obj twofish.obj packet.obj
$(AR) /out:tomcrypt.lib keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj hmac.obj \ $(AR) /out:tomcrypt.lib keyring.obj gf.obj mem.obj sprng.obj dsa.obj ecc.obj base64.obj dh.obj rsa.obj hmac.obj \
bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj md2.obj md5.obj md4.obj sha256.obj \ bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj md2.obj md5.obj md4.obj sha256.obj \
strings.obj sha512.obj xtea.obj aes.obj serpent.obj safer_tab.obj safer.obj safer+.obj cast5.obj noekeon.obj rc2.obj rc6.obj rc5.obj des.obj \ strings.obj sha512.obj xtea.obj aes.obj serpent.obj safer_tab.obj safer.obj safer+.obj cast5.obj noekeon.obj rc2.obj rc6.obj rc5.obj des.obj \
blowfish.obj crypt.obj ampi.obj mpi.obj prime.obj twofish.obj packet.obj blowfish.obj crypt.obj ampi.obj mpi.obj prime.obj twofish.obj packet.obj

213
mpi.c
View File

@ -1635,8 +1635,159 @@ mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c)
/* }}} */ /* }}} */
/* shrinks the memory required to store a mp_int if possible */
mp_err mp_shrink(mp_int *a)
{
if (a->used != a->alloc) {
if ((a->dp = XREALLOC(a->dp, a->used * sizeof(mp_digit))) == NULL) {
return MP_MEM;
} else {
a->alloc = a->used;
return MP_OKAY;
}
} else {
return MP_OKAY;
}
}
/* {{{ mp_exptmod(a, b, m, c) */ /* {{{ mp_exptmod(a, b, m, c) */
#ifdef MPI_FASTEXPT
/* computes y == g^x mod p */
mp_err mp_exptmod(mp_int *G, mp_int *X, mp_int *P, mp_int *Y)
{
mp_int *M, tx, mu, res;
int QQQ, QQ, Q, x, *vals, err;
/* determine the value of Q */
x = (USED(X) - 1) * DIGIT_BIT;
Q = DIGIT(X, USED(X)-1);
while (Q) {
++x;
Q >>= 1;
}
if (x <= 8) { Q = 2; }
else if (x <= 64) { Q = 3; }
else if (x <= 256) { Q = 4; }
else if (x <= 950) { Q = 5; }
else if (x <= 2755) { Q = 6; }
else { Q = 7; }
#ifdef MPI_FASTEXPT_LOWMEM
if (Q > 5) {
Q = 5;
}
#endif
/* alloc room for table */
vals = XCALLOC(sizeof(int), USED(X)*((DIGIT_BIT/Q)+((DIGIT_BIT%Q)?1:0)));
if (vals == NULL) { err = MP_MEM; goto _ERR; }
M = XCALLOC(sizeof(mp_int), 1<<Q);
if (M == NULL) { err = MP_MEM; goto _VALS; }
/* init M table */
for (x = 0; x < (1<<Q); x++) {
if (mp_init(&M[x]) != MP_OKAY) {
for (Q = 0; Q < x; Q++) {
mp_clear(&M[x]);
}
err = MP_MEM;
goto __M;
}
}
/* init the barett reduction */
/* mu = b^2k / m */
if ((err = mp_init(&mu)) != MP_OKAY) {
goto _M;
}
if ((err = mp_init(&res)) != MP_OKAY) {
goto _MU;
}
mp_set(&mu, 1);
s_mp_lshd(&mu, 2 * USED(P));
if((err = mp_div(&mu, P, &mu, NULL)) != MP_OKAY){
goto _RES;
}
/* now init the M array with powers of the base */
mp_set(&M[0], 1);
if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) { goto _RES; }
/* shrink first two */
for (x = 0; x < 2; x++) {
if ((err = mp_shrink(&M[x])) != MP_OKAY) { goto _RES; }
}
for (x = 2; x < (1<<Q); x++) {
if (USED(&M[x]) == 1 && DIGIT(&M[x], 0) == 0) {
if ((err = mp_mul(&M[x-1], &M[1], &M[x])) != MP_OKAY) { goto _RES; }
if ((err = s_mp_reduce(&M[x], P, &mu)) != MP_OKAY) { goto _RES; }
if ((err = mp_shrink(&M[x])) != MP_OKAY) { goto _RES; }
QQQ = x;
QQ = x * 2;
while (QQ < (1<<Q)) {
if ((err = mp_sqr(&M[QQQ], &M[QQ])) != MP_OKAY) { goto _RES; }
if ((err = s_mp_reduce(&M[QQ], P, &mu)) != MP_OKAY) { goto _RES; }
if ((err = mp_shrink(&M[QQ])) != MP_OKAY) { goto _RES; }
QQQ = QQ;
QQ *= 2;
}
}
}
/* now grab the bits */
if ((err = mp_init_copy(&tx, X)) != MP_OKAY) {
goto _RES;
}
x = 0;
while (mp_cmp_d(&tx, 0)) {
vals[x++] = DIGIT(&tx, 0) & ((1<<Q)-1);
s_mp_div_2d(&tx, Q);
}
/* now set output equal to the first digit exponent */
if ((err = mp_copy(&M[vals[--x]], &res)) != MP_OKAY) { goto _TX; }
while (--x >= 0) {
for (QQ = 0; QQ < Q; QQ++) {
if ((err = s_mp_sqr(&res)) != MP_OKAY) { goto _TX; }
if ((err = s_mp_reduce(&res, P, &mu)) != MP_OKAY) { goto _TX; }
}
if (vals[x] != 0) {
if ((err = s_mp_mul(&res, &M[vals[x]])) != MP_OKAY) { goto _TX; }
if ((err = s_mp_reduce(&res, P, &mu)) != MP_OKAY) { goto _TX; }
}
}
s_mp_exch(&res, Y);
/* free ram */
_TX:
mp_clear(&tx);
_RES:
mp_clear(&res);
_MU:
mp_clear(&mu);
_M:
for (x = 0; x < (1<<Q); x++) {
mp_clear(&M[x]);
}
__M:
XFREE(M);
_VALS:
XFREE(vals);
_ERR:
return err;
}
#else
/* /*
mp_exptmod(a, b, m, c) mp_exptmod(a, b, m, c)
@ -1731,6 +1882,8 @@ mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
} /* end mp_exptmod() */ } /* end mp_exptmod() */
#endif
/* }}} */ /* }}} */
/* {{{ mp_exptmod_d(a, d, m, c) */ /* {{{ mp_exptmod_d(a, d, m, c) */
@ -2888,7 +3041,9 @@ void s_mp_rshd(mp_int *mp, mp_size p)
for(ix = p; ix < USED(mp); ix++) for(ix = p; ix < USED(mp); ix++)
dp[ix - p] = dp[ix]; dp[ix - p] = dp[ix];
/* Fill the top digits with zeroes */ /* Fill the top digits with zeroes */
ix -= p; ix -= p;
while(ix < USED(mp)) while(ix < USED(mp))
dp[ix++] = 0; dp[ix++] = 0;
@ -2966,10 +3121,14 @@ void s_mp_mod_2d(mp_int *mp, mp_digit d)
dp[ndig] &= dmask; dp[ndig] &= dmask;
/* Flush all digits above the one with 2^d in it */ /* Flush all digits above the one with 2^d in it */
/*
for(ix = ndig + 1; ix < USED(mp); ix++) for(ix = ndig + 1; ix < USED(mp); ix++)
dp[ix] = 0; dp[ix] = 0;
s_mp_clamp(mp); s_mp_clamp(mp);
*/
USED(mp) = ndig;
} /* end s_mp_mod_2d() */ } /* end s_mp_mod_2d() */
@ -3431,6 +3590,56 @@ mp_err s_mp_mul(mp_int *a, mp_int *b)
} /* end s_mp_mul() */ } /* end s_mp_mul() */
/* Compute a = |a| * |b| max of digs digits */
mp_err s_mp_mul_dig(mp_int *a, mp_int *b, int digs)
{
mp_word w, k = 0;
mp_int tmp;
mp_err res;
mp_size ix, jx, ua = USED(a), ub = USED(b);
mp_digit *pa, *pb, *pt, *pbt;
if((res = mp_init_size(&tmp, digs+1)) != MP_OKAY)
return res;
/* This has the effect of left-padding with zeroes... */
USED(&tmp) = digs+1;
/* We're going to need the base value each iteration */
pbt = DIGITS(&tmp);
/* Outer loop: Digits of b */
pb = DIGITS(b);
for(ix = 0; ix < ub; ++ix, ++pb) {
if(*pb == 0)
continue;
/* Inner product: Digits of a */
pa = DIGITS(a);
for(jx = 0; jx < ua; ++jx, ++pa) {
if ((int)(ix+jx) > digs) { break; }
pt = pbt + ix + jx;
w = *pb * *pa + k + *pt;
*pt = ACCUM(w);
k = CARRYOUT(w);
}
if ((int)(ix + jx) < digs) {
pbt[ix + jx] = k;
}
k = 0;
}
USED(&tmp) = digs;
s_mp_clamp(&tmp);
s_mp_exch(&tmp, a);
mp_clear(&tmp);
return MP_OKAY;
} /* end s_mp_mul() */
/* }}} */ /* }}} */
/* {{{ s_mp_kmul(a, b, out, len) */ /* {{{ s_mp_kmul(a, b, out, len) */
@ -3763,8 +3972,8 @@ mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu)
s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1))); s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1)));
/* q = q * m mod b^(k+1), quick (no division) */ /* q = q * m mod b^(k+1), quick (no division) */
s_mp_mul(&q, m); s_mp_mul_dig(&q, m, um + 1);
s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1))); // s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1)));
/* x = x - q */ /* x = x - q */
if((res = mp_sub(x, &q, x)) != MP_OKAY) if((res = mp_sub(x, &q, x)) != MP_OKAY)

5
mpi.h
View File

@ -98,6 +98,8 @@ void mp_clear_array(mp_int mp[], int count);
void mp_zero(mp_int *mp); void mp_zero(mp_int *mp);
void mp_set(mp_int *mp, mp_digit d); void mp_set(mp_int *mp, mp_digit d);
mp_err mp_set_int(mp_int *mp, long z); mp_err mp_set_int(mp_int *mp, long z);
mp_err mp_shrink(mp_int *a);
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
/* Single digit arithmetic */ /* Single digit arithmetic */
@ -149,6 +151,9 @@ mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c);
#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c) #define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
#endif #endif
mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu);
mp_err s_mp_lshd(mp_int *mp, mp_size p);
mp_err s_mp_mul_dig(mp_int *a, mp_int *b, int digs);
mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c); mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c);
#endif /* MP_MODARITH */ #endif /* MP_MODARITH */

View File

@ -13,46 +13,48 @@ extern "C" {
#endif #endif
/* version */ /* version */
#define CRYPT 0x0078 #define CRYPT 0x0079
#define SCRYPT "0.78" #define SCRYPT "0.79"
/* 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
/* ch1-01-1 */
/* error codes [will be expanded in future releases] */ /* error codes [will be expanded in future releases] */
enum { enum {
CRYPT_OK=0, CRYPT_OK=0, /* Result OK */
CRYPT_ERROR, CRYPT_ERROR, /* Generic Error */
CRYPT_INVALID_KEYSIZE, CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
CRYPT_INVALID_ROUNDS, CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
CRYPT_FAIL_TESTVECTOR, CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
CRYPT_BUFFER_OVERFLOW, CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
CRYPT_INVALID_PACKET, CRYPT_INVALID_PACKET, /* Invalid input packet given */
CRYPT_INVALID_PRNGSIZE, CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
CRYPT_ERROR_READPRNG, CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
CRYPT_INVALID_CIPHER, CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
CRYPT_INVALID_HASH, CRYPT_INVALID_HASH, /* Invalid hash specified */
CRYPT_INVALID_PRNG, CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
CRYPT_MEM, CRYPT_MEM, /* Out of memory */
CRYPT_PK_TYPE_MISMATCH, CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
CRYPT_PK_NOT_PRIVATE, CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
CRYPT_INVALID_ARG, CRYPT_INVALID_ARG, /* Generic invalid argument */
CRYPT_PK_INVALID_TYPE, CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
CRYPT_PK_INVALID_SYSTEM, CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
CRYPT_PK_DUP, CRYPT_PK_DUP, /* Duplicate key already in key ring */
CRYPT_PK_NOT_FOUND, CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
CRYPT_PK_INVALID_SIZE, CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
CRYPT_INVALID_PRIME_SIZE CRYPT_INVALID_PRIME_SIZE/* Invalid size of prime requested */
}; };
/* ch1-01-1 */
#include <mycrypt_cfg.h> #include <mycrypt_cfg.h>
#include <mycrypt_macros.h> #include <mycrypt_macros.h>
@ -63,10 +65,8 @@ enum {
#include <mycrypt_gf.h> #include <mycrypt_gf.h>
#include <mycrypt_misc.h> #include <mycrypt_misc.h>
#include <mycrypt_kr.h> #include <mycrypt_kr.h>
#include <mycrypt_argchk.h> #include <mycrypt_argchk.h>
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,26 +1,14 @@
/* Defines the _ARGCHK macro used within the library */ /* Defines the _ARGCHK macro used within the library */
/* ch1-01-1 */
/* ARGTYPE is defined in mycrypt_cfg.h */ /* ARGTYPE is defined in mycrypt_cfg.h */
#if ARGTYPE == 0 #if ARGTYPE == 0
#include <signal.h> #include <signal.h>
/* this is the default LibTomCrypt macro /* this is the default LibTomCrypt macro */
* extern void crypt_argchk(char *v, char *s, int d);
* On embedded platforms you can change the fprintf() to be a routine that would display a message #define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
* somehow
*/
#ifdef SMALL_CODE
extern void crypt_argchk(char *v, char *s, int d);
#define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
#else
#ifdef SONY_PS2
#define _ARGCHK(x) if (!(x)) { printf("_ARGCHK '%s' failure on line %d of file %s\n", #x, __LINE__, __FILE__); raise(SIGABRT); }
#else
#define _ARGCHK(x) if (!(x)) { fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n", #x, __LINE__, __FILE__); raise(SIGABRT); }
#endif
#endif
#elif ARGTYPE == 1 #elif ARGTYPE == 1
@ -32,4 +20,5 @@
#define _ARGCHK(x) #define _ARGCHK(x)
#endif #endif
/* ch1-01-1 */

View File

@ -9,18 +9,21 @@
/* you can change how memory allocation works ... */ /* you can change how memory allocation works ... */
extern void *XMALLOC(size_t n); extern void *XMALLOC(size_t n);
extern void *REALLOC(void *p, size_t n);
extern void *XCALLOC(size_t n, size_t s); extern void *XCALLOC(size_t n, size_t s);
extern void XFREE(void *p); extern void XFREE(void *p);
/* change the clock function too */ /* change the clock function too */
extern clock_t XCLOCK(void); extern clock_t XCLOCK(void);
/* ch1-01-1 */
/* type of argument checking, 0=default, 1=fatal and 2=none */ /* type of argument checking, 0=default, 1=fatal and 2=none */
#define ARGTYPE 0 #define ARGTYPE 0
/* ch1-01-1 */
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */ /* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */
/* detect x86-32 machines somewhat */ /* detect x86-32 machines somewhat */
#if (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__))) #if (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__)))
#define ENDIAN_LITTLE #define ENDIAN_LITTLE
#define ENDIAN_32BITWORD #define ENDIAN_32BITWORD
#endif #endif
@ -53,7 +56,7 @@ extern clock_t XCLOCK(void);
#ifdef YARROW #ifdef YARROW
#ifndef CTR #ifndef CTR
#error YARROW Requires CTR mode #error YARROW requires CTR chaining mode to be defined!
#endif #endif
#endif #endif
@ -62,12 +65,13 @@ extern clock_t XCLOCK(void);
#define PACKET #define PACKET
/* size of a packet header in bytes */ /* size of a packet header in bytes */
#define PACKET_SIZE 8 #define PACKET_SIZE 4
/* Section tags */ /* Section tags */
#define PACKET_SECT_RSA 0 #define PACKET_SECT_RSA 0
#define PACKET_SECT_DH 1 #define PACKET_SECT_DH 1
#define PACKET_SECT_ECC 2 #define PACKET_SECT_ECC 2
#define PACKET_SECT_DSA 4
/* Subsection Tags for the first three sections */ /* Subsection Tags for the first three sections */
#define PACKET_SUB_KEY 0 #define PACKET_SUB_KEY 0
@ -76,33 +80,6 @@ extern clock_t XCLOCK(void);
#define PACKET_SUB_ENC_KEY 3 #define PACKET_SUB_ENC_KEY 3
#endif #endif
/* Diffie-Hellman key settings you can omit ones you don't want to save space */
#ifdef MDH
#define DH768
#define DH1024
#define DH1280
#define DH1536
#define DH1792
#define DH2048
#define DH2560
#define DH3072
#define DH4096
#endif /* MDH */
/* ECC Key settings */
#ifdef MECC
#define ECC160
#define ECC192
#define ECC224
#define ECC256
#define ECC384
#define ECC521
#endif /* MECC */
#ifdef MPI #ifdef MPI
#include "mpi.h" #include "mpi.h"
#else #else
@ -115,6 +92,9 @@ extern clock_t XCLOCK(void);
#ifdef MDH #ifdef MDH
#error DH requires the big int library #error DH requires the big int library
#endif #endif
#ifdef MDSA
#error DSA requires the big int library
#endif
#endif /* MPI */ #endif /* MPI */
#endif /* MYCRYPT_CFG_H */ #endif /* MYCRYPT_CFG_H */

View File

@ -11,6 +11,8 @@ extern int base64_decode(const unsigned char *in, unsigned long len,
extern void zeromem(void *dst, unsigned long len); extern void zeromem(void *dst, unsigned long len);
extern void burn_stack(unsigned long len); extern void burn_stack(unsigned long len);
/* ch1-01-1*/
extern const char *error_to_string(int errno); extern const char *error_to_string(int errno);
/* ch1-01-1*/
extern const char *crypt_build_settings; extern const char *crypt_build_settings;

View File

@ -17,7 +17,7 @@ extern void mp_clear_multi(mp_int* mp, ...);
/* ---- PACKET ---- */ /* ---- PACKET ---- */
#ifdef PACKET #ifdef PACKET
extern void packet_store_header(unsigned char *dst, int section, int subsection, unsigned long length); extern void packet_store_header(unsigned char *dst, int section, int subsection);
extern int packet_valid_header(unsigned char *src, int section, int subsection); extern int packet_valid_header(unsigned char *src, int section, int subsection);
#endif #endif
@ -56,15 +56,16 @@ extern 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);
extern int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey, extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, rsa_key *key); unsigned char *outkey, unsigned long *keylen,
rsa_key *key);
extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen, extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
rsa_key *key); rsa_key *key);
extern int rsa_verify_hash(const unsigned char *sig, const unsigned char *hash, extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
int *stat, rsa_key *key); const unsigned char *hash, int *stat, rsa_key *key);
extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
extern int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); extern int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
@ -96,16 +97,17 @@ extern int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
prng_state *prng, int wprng, int hash, prng_state *prng, int wprng, int hash,
dh_key *key); dh_key *key);
extern int dh_decrypt_key(const unsigned char *in, unsigned char *outkey, extern int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, dh_key *key); unsigned char *outkey, unsigned long *keylen,
dh_key *key);
extern int dh_sign_hash(const unsigned char *in, unsigned long inlen, extern 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);
extern int dh_verify_hash(const unsigned char *sig, const unsigned char *hash, extern int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
unsigned long inlen, int *stat, const unsigned char *hash, unsigned long hashlen,
dh_key *key); int *stat, dh_key *key);
#endif #endif
@ -140,15 +142,35 @@ extern int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
prng_state *prng, int wprng, int hash, prng_state *prng, int wprng, int hash,
ecc_key *key); ecc_key *key);
extern int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey, extern int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, ecc_key *key); unsigned char *outkey, unsigned long *keylen,
ecc_key *key);
extern int ecc_sign_hash(const unsigned char *in, unsigned long inlen, extern int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, unsigned char *out, unsigned long *outlen,
prng_state *prng, int wprng, ecc_key *key); prng_state *prng, int wprng, ecc_key *key);
extern int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash, extern int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
unsigned long inlen, int *stat, const unsigned char *hash, unsigned long hashlen,
ecc_key *key); int *stat, ecc_key *key);
#endif
#ifdef MDSA
typedef struct {
int type, idx;
mp_int x, y;
} dsa_key;
extern int dsa_test(void);
extern int dsa_make_key(prng_state *prng, int wprng, int keysize, dsa_key *key);
extern void dsa_free(dsa_key *key);
extern int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key);
extern int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key);
#endif #endif

View File

@ -2,7 +2,7 @@
#ifdef PACKET #ifdef PACKET
void packet_store_header(unsigned char *dst, int section, int subsection, unsigned long length) void packet_store_header(unsigned char *dst, int section, int subsection)
{ {
_ARGCHK(dst != NULL); _ARGCHK(dst != NULL);
@ -14,8 +14,6 @@ void packet_store_header(unsigned char *dst, int section, int subsection, unsign
dst[2] = section & 255; dst[2] = section & 255;
dst[3] = subsection & 255; dst[3] = subsection & 255;
/* store length */
STORE32L(length, &dst[4]);
} }
int packet_valid_header(unsigned char *src, int section, int subsection) int packet_valid_header(unsigned char *src, int section, int subsection)

View File

@ -230,8 +230,6 @@ done:
return res; return res;
} }
int rand_prime(mp_int *N, long len, prng_state *prng, int wprng) int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
{ {
unsigned char buf[260]; unsigned char buf[260];

33
rsa.c
View File

@ -73,7 +73,19 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
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 */
if (mp_shrink(&key->e) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->d) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->N) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->dQ) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->dP) != MP_OKAY) { goto error2; }
if (mp_shrink(&key->qP) != 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->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;
@ -293,10 +305,10 @@ int rsa_depad(const unsigned char *in, unsigned long inlen,
#define OUTPUT_BIGNUM(num, buf2, y, z) \ #define OUTPUT_BIGNUM(num, buf2, y, z) \
{ \ { \
z = mp_raw_size(num); \ z = mp_unsigned_bin_size(num); \
STORE32L(z, buf2+y); \ STORE32L(z, buf2+y); \
y += 4; \ y += 4; \
mp_toraw(num, buf2+y); \ mp_to_unsigned_bin(num, buf2+y); \
y += z; \ y += z; \
} }
@ -318,11 +330,16 @@ int rsa_depad(const unsigned char *in, unsigned long inlen,
} \ } \
\ \
/* load it */ \ /* load it */ \
if (mp_read_raw(num, (unsigned char *)in+y, x) != MP_OKAY) {\ if (mp_read_unsigned_bin(num, (unsigned char *)in+y, x) != MP_OKAY) {\
errno = CRYPT_MEM; \ errno = CRYPT_MEM; \
goto error2; \ goto error2; \
} \ } \
y += x; \ y += x; \
\
if (mp_shrink(num) != MP_OKAY) { \
errno = CRYPT_MEM; \
goto error2; \
} \
} }
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
@ -371,7 +388,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
} }
/* store packet header */ /* store packet header */
packet_store_header(buf2, PACKET_SECT_RSA, PACKET_SUB_KEY, y); packet_store_header(buf2, PACKET_SECT_RSA, PACKET_SUB_KEY);
/* copy to the user buffer */ /* copy to the user buffer */
memcpy(out, buf2, y); memcpy(out, buf2, y);
@ -431,6 +448,14 @@ 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 */
if (key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
}
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear(&key->d);
}
return CRYPT_OK; return CRYPT_OK;
error2: error2:

View File

@ -49,7 +49,7 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
} }
/* store header */ /* store header */
packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY, y); packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
/* clean up */ /* clean up */
@ -60,8 +60,9 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
return CRYPT_OK; return CRYPT_OK;
} }
int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey, int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned long *keylen, rsa_key *key) unsigned char *outkey, unsigned long *keylen,
rsa_key *key)
{ {
unsigned char sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096]; unsigned char sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096];
unsigned long x, y, z, i, rsa_size; unsigned long x, y, z, i, rsa_size;
@ -77,6 +78,12 @@ int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
return CRYPT_PK_NOT_PRIVATE; return CRYPT_PK_NOT_PRIVATE;
} }
if (inlen < PACKET_SIZE+4) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= PACKET_SIZE+4;
}
/* check the header */ /* check the header */
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) { if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
return errno; return errno;
@ -84,7 +91,12 @@ int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
/* grab length of the rsa key */ /* grab length of the rsa key */
y = PACKET_SIZE; y = PACKET_SIZE;
LOAD32L(rsa_size, (in+y)) LOAD32L(rsa_size, (in+y));
if (inlen < rsa_size) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= rsa_size;
}
y += 4; y += 4;
/* read it in */ /* read it in */
@ -94,8 +106,9 @@ int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
/* decrypt it */ /* decrypt it */
x = sizeof(rsa_out); x = sizeof(rsa_out);
if ((errno = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) if ((errno = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) {
return errno; return errno;
}
/* depad it */ /* depad it */
z = sizeof(sym_key); z = sizeof(sym_key);
@ -170,7 +183,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
} }
/* store header */ /* store header */
packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED, y); packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED);
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
/* clean up */ /* clean up */
@ -181,8 +194,8 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
return CRYPT_OK; return CRYPT_OK;
} }
int rsa_verify_hash(const unsigned char *sig, const unsigned char *md, int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
int *stat, rsa_key *key) const unsigned char *md, int *stat, rsa_key *key)
{ {
unsigned long rsa_size, x, y, z; unsigned long rsa_size, x, y, z;
unsigned char rsa_in[4096], rsa_out[4096]; unsigned char rsa_in[4096], rsa_out[4096];
@ -195,6 +208,12 @@ int rsa_verify_hash(const unsigned char *sig, const unsigned char *md,
/* always be incorrect by default */ /* always be incorrect by default */
*stat = 0; *stat = 0;
if (siglen < PACKET_SIZE+4) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= PACKET_SIZE+4;
}
/* verify header */ /* verify header */
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) { if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
@ -204,6 +223,11 @@ int rsa_verify_hash(const unsigned char *sig, const unsigned char *md,
/* get the len */ /* get the len */
y = PACKET_SIZE; y = PACKET_SIZE;
LOAD32L(rsa_size, (sig+y)); LOAD32L(rsa_size, (sig+y));
if (siglen < rsa_size) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= rsa_size;
}
y += 4; y += 4;
/* load the signature */ /* load the signature */

3
sha1.c
View File

@ -25,7 +25,7 @@ static void _sha1_compress(hash_state *md)
static void sha1_compress(hash_state *md) static void sha1_compress(hash_state *md)
#endif #endif
{ {
unsigned long a,b,c,d,e,W[80],i,j; unsigned long a,b,c,d,e,W[80],i,j,j2,j3;
_ARGCHK(md != NULL); _ARGCHK(md != NULL);
@ -47,6 +47,7 @@ static void sha1_compress(hash_state *md)
W[i] = ROL(j, 1); W[i] = ROL(j, 1);
} }
/* compress */ /* compress */
/* round one */ /* round one */
for (i = 0; i < 20; i++) { for (i = 0; i < 20; i++) {

View File

@ -38,7 +38,7 @@ static const char *err_2_str[] =
const char *error_to_string(int errno) const char *error_to_string(int errno)
{ {
if (errno < 0 || errno > (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { if (errno < 0 || errno >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
return "Invalid error code."; return "Invalid error code.";
} else { } else {
return err_2_str[errno]; return err_2_str[errno];

131
update_libtomcrypt.sh Normal file
View File

@ -0,0 +1,131 @@
#!/bin/tcsh
# Get latest copy of libtomcrypt and install it using "tcsh"
#
# Tom St Denis
echo libtomcrypt update script, Tom St Denis
echo "http://libtomcrypt.iahu.ca\n"
if ($1 == "--help") then
echo "update_libtomcrypt.sh [makefile] [sig]-- Download and optionally build the libtomcrypt project.\n"
echo "\t[makefile] --\tYou can optionally specify which makefile you want to build with. If you specify "
echo "\t\t\t'nobuild' then the library is not built, just downloaded and unzipped. If you "
echo "\t\t\tleave it empty the default 'makefile' is used to build the library.\n"
echo "\t[sig] -- \tOptionally verify [via GPG] the signature of the package."
exit
endif
if ($1 == "" || $1 == "sig") then
set make = "makefile"
else
set make = $1;
endif
if ($1 == "sig" || $2 == "sig") then
set sig = "sig"
else
set sig = ""
endif
rm -f latest
echo Getting latest version number from website.
wget -q http://iahu.ca:8080/download/latest
if (-r latest) then
set a = `cat latest`
echo "Latest release is v$a.\n"
if (-d "libtomcrypt-$a" && (-r "libtomcrypt-$a/libtomcrypt.a" || $make == "nobuild")) then
echo Libtomcrypt v$a is already installed on your system.
else
echo "Downloading libtomcrypt v$a ..."
if (-r "crypt-$a.tar.bz2") then
rm -f crypt-$a.tar.bz2
endif
wget http://iahu.ca:8080/download/crypt-$a.tar.bz2
if (-r "crypt-$a.tar.bz2") then
if (-d "libtomcrypt-$a") then
echo "WARNING! Directory libtomcrypt-$a already exists. Cannot continue.\n"
exit
endif
if ($sig == "sig") then
if (!(-r public.asc)) then
echo "Downloading and installing code signing key...\n"
wget -q http://iahu.ca:8080/download/public.asc
if (-r public.asc) then
gpg --import public.asc
if ($? != 0) then
echo Could not import signing key required to verify the package.
exit
else
echo "\n********************************************************************************"
echo "A new key has been imported to your keyring. You should check that it is valid."
echo "********************************************************************************"
endif
else
echo "Could not download the key to import."
exit
endif
endif
echo Verifying signature...
wget -q http://iahu.ca:8080/download/crypt-$a.tar.bz2.asc
if (!(-r "crypt-$a.tar.bz2.asc")) then
echo Could not download signature to test.
exit
endif
gpg -q --verify crypt-$a.tar.bz2.asc
if ($? != 0) then
echo "\n\nSignature for crypt-$a.tar.bz2 is ****not**** valid.\n\n"
exit
else
echo "\n\nSignature for crypt-$a.tar.bz2 is valid.\n\n"
endif
endif
bzip2 -d -c crypt-$a.tar.bz2 | tar -x
if (-d "libtomcrypt-$a") then
if (-r "libtomcrypt-$a/$make") then
cd libtomcrypt-$a
make -f $make
if (-r "libtomcrypt.a") then
echo "\n\n*****************************************************************"
echo The library has been built and you can now install it either with
echo
echo "cd libtomcrypt-$a ; make install"
echo
echo Or by editing the makefile and changing the user you wish to install
echo it with, or simply copy "libtomcrypt.a" to your library directory and
echo copy "*.h" to your include directory
echo "*****************************************************************"
else
echo "\n\n*****************************************************************"
echo The library failed to build. Please note the errors and send them to tomstdenis@yahoo.com
echo "*****************************************************************"
endif
else if ($make == "nobuild") then
echo "\n\n*****************************************************************"
echo "The library was downloaded and unzipped into libtomcrypt-$a/"
echo "*****************************************************************"
else
echo "The makefile '$make' was not found in the archive.\n";
endif
else
echo "Could not unpack the libtomcrypt archive (corrupt?)."
endif
cd ..
else
echo "Could not download the libtomcrypt archive from server."
endif
endif
if (-r "libtomcrypt-$a/changes") then
perl <<!
open(IN,"<libtomcrypt-$a/changes") or die "Can't open libtomcrypt change log.";
print "\nChange log for v$a :\n";
\$a = <IN>; print \$a; \$a = <IN>;
while (<IN>) {
if (\$_ =~ m/^(v\d\.\d\d)/) { close(IN); exit(0); }
print "\$a"; \$a = \$_;
}
!
else
echo "Change log not found. Is the package really installed?"
endif
else
echo "Could not download latest file from server to check version."
endif