added libtomcrypt-0.79
This commit is contained in:
parent
2ef59575df
commit
d5fbe63b70
2
authors
2
authors
@ -25,7 +25,7 @@ tomstdenis@yahoo.com.
|
||||
|
||||
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
|
||||
|
||||
|
4
base64.c
4
base64.c
@ -91,7 +91,7 @@ int base64_decode(const unsigned char *in, unsigned long len,
|
||||
if (c == 254) { c = 0; g--; }
|
||||
t = (t<<6)|c;
|
||||
if (++y == 4) {
|
||||
if (z + g > *outlen) goto error;
|
||||
if (z + g > *outlen) { return CRYPT_BUFFER_OVERFLOW; }
|
||||
out[z++] = (unsigned char)((t>>16)&255);
|
||||
if (g > 1) out[z++] = (unsigned char)((t>>8)&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;
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
25
changes
25
changes
@ -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
|
||||
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.
|
||||
|
143
config.pl
Normal file
143
config.pl
Normal 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";
|
57
crypt.c
57
crypt.c
@ -1,7 +1,9 @@
|
||||
#include "mycrypt.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 },
|
||||
@ -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 } };
|
||||
|
||||
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 },
|
||||
@ -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 } };
|
||||
|
||||
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 },
|
||||
@ -103,26 +105,27 @@ struct _prng_descriptor prng_descriptor[32] = {
|
||||
{ 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)
|
||||
{
|
||||
#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
|
||||
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
|
||||
raise(SIGABRT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ch1-01-1 */
|
||||
|
||||
int find_cipher(const char *name)
|
||||
{
|
||||
int x;
|
||||
_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)) {
|
||||
return x;
|
||||
}
|
||||
@ -134,7 +137,7 @@ int find_hash(const char *name)
|
||||
{
|
||||
int x;
|
||||
_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)) {
|
||||
return x;
|
||||
}
|
||||
@ -146,7 +149,7 @@ int find_prng(const char *name)
|
||||
{
|
||||
int x;
|
||||
_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)) {
|
||||
return x;
|
||||
}
|
||||
@ -157,7 +160,7 @@ int find_prng(const char *name)
|
||||
int find_cipher_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 32; x++) {
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].ID == ID) {
|
||||
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 x;
|
||||
for (x = 0; x < 32; x++) {
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].ID == ID) {
|
||||
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);
|
||||
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) {
|
||||
return x;
|
||||
}
|
||||
@ -201,14 +204,14 @@ int register_cipher(const struct _cipher_descriptor *cipher)
|
||||
_ARGCHK(cipher != NULL);
|
||||
|
||||
/* 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) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < 32; x++) {
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name == NULL) {
|
||||
memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor));
|
||||
return x;
|
||||
@ -226,7 +229,7 @@ int unregister_cipher(const struct _cipher_descriptor *cipher)
|
||||
_ARGCHK(cipher != NULL);
|
||||
|
||||
/* 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))) {
|
||||
cipher_descriptor[x].name = NULL;
|
||||
cipher_descriptor[x].ID = 255;
|
||||
@ -243,14 +246,14 @@ int register_hash(const struct _hash_descriptor *hash)
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* 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))) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < 32; x++) {
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].name == NULL) {
|
||||
memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor));
|
||||
return x;
|
||||
@ -268,7 +271,7 @@ int unregister_hash(const struct _hash_descriptor *hash)
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* 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))) {
|
||||
hash_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
@ -284,14 +287,14 @@ int register_prng(const struct _prng_descriptor *prng)
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* 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))) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < 32; x++) {
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (prng_descriptor[x].name == NULL) {
|
||||
memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor));
|
||||
return x;
|
||||
@ -309,7 +312,7 @@ int unregister_prng(const struct _prng_descriptor *prng)
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* 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))) {
|
||||
prng_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
@ -320,7 +323,7 @@ int unregister_prng(const struct _prng_descriptor *prng)
|
||||
|
||||
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_OK;
|
||||
@ -328,7 +331,7 @@ int cipher_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_OK;
|
||||
@ -336,7 +339,7 @@ int hash_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_OK;
|
||||
|
46
crypt.tex
46
crypt.tex
@ -44,7 +44,7 @@
|
||||
\def\gap{\vspace{0.5ex}}
|
||||
\makeindex
|
||||
\begin{document}
|
||||
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.78}
|
||||
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.79}
|
||||
\author{Tom St Denis \\
|
||||
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 Andrew Tyler
|
||||
\item Sky Schulz
|
||||
\item Christopher Imes
|
||||
\end{enumerate}
|
||||
|
||||
\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,
|
||||
prng_state *prng, int wprng, rsa_key *key);
|
||||
|
||||
int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, rsa_key *key);
|
||||
int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
rsa_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
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
|
||||
algorithm. It will store the result in ``outkey'' along with the length in ``outlen''. The ``rsa\_decrypt\_key()'' function
|
||||
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''.
|
||||
algorithm. It will store the result in ``outkey'' along with the length in ``outlen''.
|
||||
|
||||
The ``rsa\_decrypt\_key()'' function performs the opposite. The ``in'' variable is where the RSA packet of length
|
||||
``inlen'' goes and it will store the original symmetric key in the ``outkey'' variable along with its length in
|
||||
``keylen''.
|
||||
|
||||
Similarly to sign or verify a hash of a message the following two messages are provided. The idea is to hash your
|
||||
message then use these functions to RSA sign the hash.
|
||||
@ -1384,8 +1388,8 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
rsa_key *key);
|
||||
|
||||
int rsa_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
int *stat, rsa_key *key);
|
||||
int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, int *stat, rsa_key *key);
|
||||
\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
|
||||
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,
|
||||
dh_key *key);
|
||||
|
||||
int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, dh_key *key);
|
||||
int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
dh_key *key);
|
||||
\end{verbatim}
|
||||
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
|
||||
data is placed in ``out'' by ``dh\_encrypt\_key()''. The hash must produce a message digest at least as large
|
||||
and find the hash of the shared secret. The message digest is than XOR'ed against the symmetric key. All of the
|
||||
required data is placed in ``out'' by ``dh\_encrypt\_key()''. The hash must produce a message digest at least as large
|
||||
as the symmetric key you are trying to share.
|
||||
|
||||
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,
|
||||
prng_state *prng, int wprng, dh_key *key);
|
||||
|
||||
int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key);
|
||||
int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dh_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
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,
|
||||
ecc_key *key);
|
||||
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, ecc_key *key);
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
ecc_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
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,
|
||||
prng_state *prng, int wprng, ecc_key *key);
|
||||
|
||||
int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key);
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, ecc_key *key);
|
||||
\end{verbatim}
|
||||
|
||||
The ``ecc\_sign\_hash'' function signs the message hash in ``in'' of length ``inlen'' and forms a ECC packet in ``out''.
|
||||
|
426
demos/test.c
426
demos/test.c
@ -63,23 +63,23 @@ void store_tests(void)
|
||||
STORE32L(L, &buf[0]);
|
||||
L = 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);
|
||||
STORE64L(LL, &buf[0]);
|
||||
LL = 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;
|
||||
STORE32H(L, &buf[0]);
|
||||
L = 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);
|
||||
STORE64H(LL, &buf[0]);
|
||||
LL = 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) {
|
||||
@ -103,11 +103,13 @@ void ecb_tests(void)
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
printf(" %12s: ",
|
||||
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));
|
||||
else
|
||||
exit(-1);
|
||||
} else {
|
||||
printf("passed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CBC
|
||||
@ -124,11 +126,15 @@ void cbc_tests(void)
|
||||
for (x = 0; x < 32; x++) blk[x] = IV[x] = x;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
cbc_encrypt(blk+8*x, ct+8*x, &cbc);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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));
|
||||
|
||||
@ -137,11 +143,16 @@ void cbc_tests(void)
|
||||
for (x = 0; x < 32; x++) IV[x] = x;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
cbc_decrypt(ct+8*x, blk+8*x, &cbc);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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 */
|
||||
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");
|
||||
for (x = 0; x < 16; x++) printf("%02x ", ct[x]);
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
} else {
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
ofb_encrypt(blk+8*x, ct+8*x, 8, &ofb);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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));
|
||||
|
||||
@ -191,15 +207,20 @@ void ofb_tests(void)
|
||||
for (x = 0; x < 32; x++) IV[x] = x;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
ofb_decrypt(ct+8*x, blk+8*x, 8, &ofb);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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 */
|
||||
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
|
||||
printf(" %s\n", y?"failed":"passed");
|
||||
if (y) exit(-1);
|
||||
}
|
||||
#else
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
cfb_encrypt(blk+8*x, ct+8*x, 8, &cfb);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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));
|
||||
|
||||
@ -231,15 +256,20 @@ void cfb_tests(void)
|
||||
for (x = 0; x < 32; x++) IV[x] = x;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
cfb_decrypt(ct+8*x, blk+8*x, 8, &cfb);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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 */
|
||||
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
|
||||
printf(" %s\n", y?"failed":"passed");
|
||||
if (y) exit(-1);
|
||||
}
|
||||
#else
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
ctr_encrypt(blk+8*x, ct+8*x, 8, &ctr);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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));
|
||||
|
||||
@ -272,15 +306,20 @@ void ctr_tests(void)
|
||||
for (x = 0; x < 32; x++) count[x] = x;
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < 4; x++)
|
||||
ctr_decrypt(ct+8*x, blk+8*x, 8, &ctr);
|
||||
for (x = 0; x < 4; x++) {
|
||||
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 */
|
||||
for (x = y = 0; x < 32; x++) if (blk[x] != x) y = 1;
|
||||
printf(" %s\n", y?"failed":"passed");
|
||||
if (y) exit(-1);
|
||||
|
||||
/* lets actually check the bytes */
|
||||
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 */
|
||||
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 */
|
||||
memset(in, 0, sizeof(in));
|
||||
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 */
|
||||
printf("rsa_pad: ");
|
||||
if (x != 16) { printf("Failed. Wrong size.\n"); return; }
|
||||
for (x = 0; x < 16; x++) if (in[x] != x) { printf("Failed. Expected %02lx and got %02x.\n", x, in[x]); 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]); exit(-1); }
|
||||
printf("passed.\n");
|
||||
}
|
||||
|
||||
@ -349,100 +389,40 @@ void rsa_test(void)
|
||||
|
||||
/* ---- SINGLE ENCRYPT ---- */
|
||||
/* 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);
|
||||
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 */
|
||||
zeromem(in, sizeof(in));
|
||||
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 */
|
||||
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");
|
||||
|
||||
#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 */
|
||||
for (x = 0; x < 16; x++) in[x] = x;
|
||||
y = sizeof(out);
|
||||
if ((errno = rsa_encrypt_key(in, 16, out, &y, &prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
zeromem(in, 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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("RSA en/de crypt key routines: ");
|
||||
if (x != 16) { printf("Failed (length)\n"); return; }
|
||||
for (x = 0; x < 16; x++) if (in[x] != x) { printf("Failed (contents)\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"); exit(-1); }
|
||||
printf("Passed\n");
|
||||
|
||||
/* test sign_hash functions */
|
||||
@ -450,24 +430,25 @@ void rsa_test(void)
|
||||
x = sizeof(in);
|
||||
if ((errno = rsa_sign_hash(in, 16, out, &x, &key)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("Verify hash: %s, ", stat?"passed":"failed");
|
||||
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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("%s\n", (!stat)?"passed":"failed");
|
||||
if (stat) exit(-1);
|
||||
rsa_free(&key);
|
||||
|
||||
/* make a RSA key */
|
||||
#ifdef SONY_PS2
|
||||
#ifdef SONY_PS2_NOPE
|
||||
limit = 1024;
|
||||
#else
|
||||
limit = 2048;
|
||||
@ -475,21 +456,21 @@ void rsa_test(void)
|
||||
|
||||
for (z = 1024; z <= limit; z += 512) {
|
||||
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;
|
||||
printf("Took %.0f ms to make a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z);
|
||||
|
||||
/* time encryption */
|
||||
y = sizeof(in);
|
||||
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;
|
||||
printf("Took %.0f ms to encrypt with a %ld-bit RSA key.\n", 1000.0 * ((double)t / (double)XCLOCKS_PER_SEC), z);
|
||||
|
||||
/* time decryption */
|
||||
x = sizeof(out);
|
||||
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;
|
||||
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);
|
||||
@ -516,19 +497,19 @@ void base64_test(void)
|
||||
x = 100;
|
||||
if (base64_encode(buf[0], 16, buf[1], &x) != CRYPT_OK) {
|
||||
printf(" error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf(" encoded 16 bytes to %ld bytes...[%s]\n", x, buf[1]);
|
||||
memset(buf[0], 0, 100);
|
||||
y = 100;
|
||||
if (base64_decode(buf[1], x, buf[0], &y) != CRYPT_OK) {
|
||||
printf(" error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf(" decoded %ld bytes to %ld bytes\n", x, y);
|
||||
for (x = 0; x < 16; x++) if (buf[0][x] != x) {
|
||||
printf(" **failed**\n");
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf(" passed\n");
|
||||
}
|
||||
@ -642,50 +623,50 @@ void dh_tests(void)
|
||||
/* make up two keys */
|
||||
if ((errno = dh_make_key(&prng, find_prng("yarrow"), 96, &usera)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
if ((errno = dh_make_key(&prng, find_prng("yarrow"), 96, &userb)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* make the shared secret */
|
||||
x = 4096;
|
||||
if ((errno = dh_shared_secret(&usera, &userb, buf[0], &x)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
y = 4096;
|
||||
if ((errno = dh_shared_secret(&userb, &usera, buf[1], &y)) != CRYPT_OK) {
|
||||
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 (memcmp(buf[0], buf[1], x)) { printf("DH Shared keys not same contents.\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"); exit(-1); }
|
||||
|
||||
/* now export userb */
|
||||
y = 4096;
|
||||
if ((errno = dh_export(buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
dh_free(&userb);
|
||||
|
||||
/* import and make the shared secret again */
|
||||
if ((errno = dh_import(buf[1], y, &userb)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
z = 4096;
|
||||
if ((errno = dh_shared_secret(&usera, &userb, buf[2], &z)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("DH routines: ");
|
||||
if (z != x) { printf("failed. Size don't match?\n"); return; }
|
||||
if (memcmp(buf[0], buf[2], x)) { printf("Failed. Content didn'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"); exit(-1); }
|
||||
printf("Passed\n");
|
||||
dh_free(&usera);
|
||||
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));
|
||||
dh_free(&usera);
|
||||
|
||||
#ifndef SONY_PS2
|
||||
#ifndef SONY_PS2_NOPE
|
||||
t1 = XCLOCK();
|
||||
dh_make_key(&prng, find_prng("yarrow"), 160, &usera);
|
||||
t1 = XCLOCK() - t1;
|
||||
@ -735,71 +716,23 @@ void dh_tests(void)
|
||||
dh_free(&usera);
|
||||
#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 */
|
||||
dh_make_key(&prng, find_prng("yarrow"), 96, &usera);
|
||||
for (x = 0; x < 16; x++) buf[0][x] = x;
|
||||
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) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
zeromem(buf[0], 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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("DH en/de crypt key routines: ");
|
||||
if (x != 16) { printf("Failed (length)\n"); return; }
|
||||
for (x = 0; x < 16; x++) if (buf[0][x] != x) { printf("Failed (contents)\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"); exit(-1); }
|
||||
printf("Passed (size %lu)\n", y);
|
||||
|
||||
/* test sign_hash */
|
||||
@ -807,16 +740,16 @@ void dh_tests(void)
|
||||
x = sizeof(buf[1]);
|
||||
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));
|
||||
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));
|
||||
return;
|
||||
exit(-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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("dh_sign/verify_hash: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2);
|
||||
dh_free(&usera);
|
||||
@ -868,7 +801,7 @@ void ecc_tests(void)
|
||||
ecc_key usera, userb;
|
||||
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);
|
||||
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 */
|
||||
if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &usera)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &userb)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* make the shared secret */
|
||||
x = 4096;
|
||||
if ((errno = ecc_shared_secret(&usera, &userb, buf[0], &x)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
y = 4096;
|
||||
if ((errno = ecc_shared_secret(&userb, &usera, buf[1], &y)) != CRYPT_OK) {
|
||||
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 */
|
||||
y = 4096;
|
||||
if ((errno = ecc_export(buf[1], &y, PK_PUBLIC, &userb)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
ecc_free(&userb);
|
||||
printf("ECC-192 export took %ld bytes\n", y);
|
||||
@ -912,142 +845,94 @@ void ecc_tests(void)
|
||||
/* import and make the shared secret again */
|
||||
if ((errno = ecc_import(buf[1], y, &userb)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
z = 4096;
|
||||
if ((errno = ecc_shared_secret(&usera, &userb, buf[2], &z)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("ecc routines: ");
|
||||
if (z != x) { printf("failed. Size don't match?\n"); return; }
|
||||
if (memcmp(buf[0], buf[2], x)) { printf("Failed. Content didn'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"); exit(-1); }
|
||||
printf("Passed\n");
|
||||
ecc_free(&usera);
|
||||
ecc_free(&userb);
|
||||
|
||||
/* time stuff */
|
||||
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;
|
||||
printf("Make ECC-160 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
|
||||
ecc_free(&usera);
|
||||
|
||||
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;
|
||||
printf("Make ECC-192 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
|
||||
ecc_free(&usera);
|
||||
|
||||
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;
|
||||
printf("Make ECC-224 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
|
||||
ecc_free(&usera);
|
||||
|
||||
#ifndef SONY_PS2
|
||||
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;
|
||||
printf("Make ECC-256 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
|
||||
ecc_free(&usera);
|
||||
|
||||
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;
|
||||
printf("Make ECC-384 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
|
||||
ecc_free(&usera);
|
||||
|
||||
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;
|
||||
printf("Make ECC-521 key took %f msec\n", 1000.0 * ((double)t1 / (double)XCLOCKS_PER_SEC));
|
||||
ecc_free(&usera);
|
||||
#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 */
|
||||
ecc_make_key(&prng, find_prng("yarrow"), 32, &usera);
|
||||
for (x = 0; x < 16; x++) buf[0][x] = x;
|
||||
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) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
zeromem(buf[0], 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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("ECC en/de crypt key routines: ");
|
||||
if (x != 16) { printf("Failed (length)\n"); return; }
|
||||
for (x = 0; x < 16; x++) if (buf[0][x] != x) { printf("Failed (contents)\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"); exit(-1); }
|
||||
printf("Passed (size: %lu)\n", y);
|
||||
/* test sign_hash */
|
||||
for (x = 0; x < 16; x++) buf[0][x] = x;
|
||||
x = sizeof(buf[1]);
|
||||
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));
|
||||
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));
|
||||
return;
|
||||
exit(-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));
|
||||
return;
|
||||
exit(-1);
|
||||
}
|
||||
printf("ecc_sign/verify_hash: %s (%d,%d)\n", ((stat==1)&&(stat2==0))?"passed":"failed", stat,stat2);
|
||||
ecc_free(&usera);
|
||||
@ -1185,15 +1070,16 @@ void register_all_algs(void)
|
||||
|
||||
register_cipher(&null_desc);
|
||||
|
||||
#ifdef SHA1
|
||||
register_hash(&sha1_desc);
|
||||
#endif
|
||||
#ifdef SHA256
|
||||
register_hash(&sha256_desc);
|
||||
#endif
|
||||
#ifdef TIGER
|
||||
register_hash(&tiger_desc);
|
||||
#endif
|
||||
#ifdef SHA1
|
||||
register_hash(&sha1_desc);
|
||||
#endif
|
||||
|
||||
#ifdef MD5
|
||||
register_hash(&md5_desc);
|
||||
#endif
|
||||
@ -1383,18 +1269,18 @@ void kr_test(void)
|
||||
|
||||
len = sizeof(buf2);
|
||||
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);
|
||||
}
|
||||
printf("kr_sign_hash: ");
|
||||
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);
|
||||
}
|
||||
printf("%s, ", stat?"passed":"failed");
|
||||
buf[15] ^= 1;
|
||||
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);
|
||||
}
|
||||
printf("%s\n", (!stat)?"passed":"failed");
|
||||
|
173
dh.c
173
dh.c
@ -12,10 +12,9 @@ static const struct {
|
||||
96,
|
||||
"DH-768",
|
||||
"2",
|
||||
"2893527720709661239493896562339544088620375736490408468011883030469939904368"
|
||||
"0860923364582982212457078989335831907131881773994018526277492109945959747917"
|
||||
"8279025394653904396221302707492255957231214118178743427870878320796645901947"
|
||||
"9487"
|
||||
"1tH+dRFGpEYyVLe4ydZcYyGDpeAxnChz0yk+pNCtkEXwUsOORyguBtx8spUD"
|
||||
"FAjEDS8PutUBTEu2q4USqu19dUbCLj9D2jY7y3871RnSccurMBsMm35ILcyQ"
|
||||
"rpN0MQKc/"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1024
|
||||
@ -23,11 +22,9 @@ static const struct {
|
||||
128,
|
||||
"DH-1024",
|
||||
"2",
|
||||
"3477431594398766260792527967974222231775354473882066076071816639030459075912"
|
||||
"0194047822362172211817327089848758298713770865641434468581617942085516098634"
|
||||
"0457973820182883508387588163122354089264395604796675278966117567294812714812"
|
||||
"7968205965648764507160662831267200108590414847865290564578963676831229604111"
|
||||
"36319"
|
||||
"Uypu+t9nfUnCj7xD+xokM+Cd6mASW4ofg1jpC2BpQasC5edtA1dJC+RjbOBZ"
|
||||
"z+5mvq5VYT8Wfjmlpjm9tQxHOYB0+3Myl7gbCQ5SRljWT2oBLukLNvgFjiU4"
|
||||
"wiWkmu41Ern/j6uxwKb740C+VIgDAdeUY4fA5hyfr3/+DWYb14/"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1280
|
||||
@ -35,12 +32,10 @@ static const struct {
|
||||
160,
|
||||
"DH-1280",
|
||||
"2",
|
||||
"2618298020488323341377089635550383393554460131909411928885489146533597039863"
|
||||
"5379029297773089246854323581071445272213255646852180580463169755159411503866"
|
||||
"4190218001872082125570169842848154404911652982668791288605239288293106162305"
|
||||
"7236093554796242806887062958692596037823904832542385180840218330924392268465"
|
||||
"0197244314233248991982159235832322194332167923655574170280697353556560854901"
|
||||
"280047"
|
||||
"520QV4Tsq4NwK9Mt5CGR9xk4slvaikgi/ax3OPky5GERKTsoqEXOlFyMzURP"
|
||||
"P8jYzCVz1izKd2zTDxbFfLxrJry0ceaQ5YZa5N4teByCPVlQh4v6iQl+944+"
|
||||
"/NDlKzvWpx7HG7k8cGKhva7aFF8bP/CvLpaQhrfXlOX+X9pcmML9QH63tUjq"
|
||||
"B80l8Yx9KN0dC3iNnsTV3DnqnEvFQkoqql"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1536
|
||||
@ -48,13 +43,11 @@ static const struct {
|
||||
192,
|
||||
"DH-1536",
|
||||
"3",
|
||||
"2992593690703251306835100868059076484222548092264611010748654597096560864537"
|
||||
"1704684310938824733433085888971827086341295918925237859522548192211945291282"
|
||||
"1170570153374563548621496076860061698150233114892317627457427359445435608693"
|
||||
"5625000902194809114890745455404045166957722404567939575618007347432055137282"
|
||||
"3291711752537781447636541738638119983678441628437171377508654097130147131310"
|
||||
"9209393805685590941710151477648542896503595482724205166251069428524927527085"
|
||||
"2602467"
|
||||
"1FTWXrPcY1w74oZ0ouIzSN8uZcRiOf6U11fx0ka6+7fqIAezPhd3Ab43QnDf"
|
||||
"KFg+or/fFRGEWAxF8WIE2jx8iTOu010yNEQyH14CK0RAyy2zY4gRs2MpnU5r"
|
||||
"/feWf60OkLtnPzN34+Xnlg5xf7Jl00wkHRCeJG17L3SklOidAPxWnE+Wm4BS"
|
||||
"SOzdQBgiZOjlhrYS1+TIU3NP5H7BrtKFcf+ZwBULibf29L7LkDOgQbie1+43"
|
||||
"lU+8SHAyBwAeGYMfZ"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1792
|
||||
@ -62,14 +55,11 @@ static const struct {
|
||||
224,
|
||||
"DH-1792",
|
||||
"2",
|
||||
"3210090394251532205679207425273650879078185529033544241951292722086520015900"
|
||||
"0402371844205168176419829949232601235193754977706171541009393172204470047690"
|
||||
"6659627844880912479392592056697278305733615369406596661203184035142652643118"
|
||||
"1379603333858737848321053048184938839622944591194935387992479717305577175500"
|
||||
"2554620614907177847128950276247571809502831255425929468853285490357704941968"
|
||||
"3407102520889651917659577334897408316217748346860775479727332331727022096550"
|
||||
"7718799868459391361770854814013613619048768630587629568449528005570971478547"
|
||||
"34960319"
|
||||
"IPo3wjvfS7vBYnFHwJHmesA51od9fnR8Aenezif4qLE2HX+YCv1tpvHA8yLH"
|
||||
"yYbKe9QfSHHtOgVjK8AYEyPirpXxlmdykGuj+dX7EiWMRGYc+v1kKkqmCn0o"
|
||||
"5tU416O/1HXTpQ2Hps0buchUD+HlCMrSgnIqRxK6Fjr0ZfiCS4XgAD6sLgi0"
|
||||
"BxKFMxDsVzpGMNwF5Lj2R/cJiTi0cNDDY3gn4lK/PRUsJtRKU+9sxy0q5Yof"
|
||||
"aG5VO8VcHkZJVwUKhDFHkZYWMHV808TGHXM2RQ9kRa2QvS2mXxMrDSCloQ/"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH2048
|
||||
@ -77,15 +67,12 @@ static const struct {
|
||||
256,
|
||||
"DH-2048",
|
||||
"2",
|
||||
"4726642895635639316469736509812041897640060270607231273592407174543853221823"
|
||||
"7979333351774907308168340693326687317443721193266215155735814510792148768576"
|
||||
"4984911991227443513994894535335532038333186916782632419417062569961974604240"
|
||||
"2901241901263467186228353234265630967717360250949841797609150915436003989316"
|
||||
"5037637034737020327399910409885798185771003505320583967737293415979917317338"
|
||||
"9858373857347474783642420203804168920566508414708692945275435973492502995396"
|
||||
"8243060517332102902655554683247304860032703684578197028928889831788842751736"
|
||||
"4945316709081173840186150794397479045034008257793436817683392375274635794835"
|
||||
"245695887"
|
||||
"5sR1VmdsQQzzjN0iridVVyveug6sAC3+/jTIHSgEoimPOREXQ05r2WJZJAF2"
|
||||
"CRu8kuusiPw2ivRli+fdLr63v1uZG5nQa28uLwNxZEsu4gu6TrGjepXeXm4Z"
|
||||
"CVOC1HMmi660fLZ2ruHLa4v2NWex2Zx91/y4ygPlZM+K//iy+Gft9Ma9Ayn0"
|
||||
"eYwofZeUL9vJSfutPVp2ZrIEUQDBKMvMm0SRSLiUjDtzXqrH+b/wuwIFG1K4"
|
||||
"var3ucsT45mDzD9qb3tBdksSPZbr6yrELV8h+qmjiBr15oHKEglS0XwSvCap"
|
||||
"abUn5XPPVoaKv13+tOnG9mGgzQ8JeClVXN63Q+GGEF"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH2560
|
||||
@ -93,17 +80,14 @@ static const struct {
|
||||
320,
|
||||
"DH-2560",
|
||||
"3",
|
||||
"4364638085059577685748948703943497396233464406019459611612544400721432981520"
|
||||
"4010567649104824811014627875285783993051576616744140702150122992472133564455"
|
||||
"7342265864606569000117714935185566842453630868849121480179691838399545644365"
|
||||
"5711067577313173717585579907818806913366955847993133136872874688941488237617"
|
||||
"8558298254958618375680644901754262226787427510387748147553499120184991222267"
|
||||
"0102069951687572917937634467778042874315463238062009202992087620963771759666"
|
||||
"4482665328580794026699200252242206134194410697184828373996126449788399252071"
|
||||
"0987084027819404215874884544513172913711709852902888677006373648742061314404"
|
||||
"5836803985635654192482395882603511950547826439092832800532152534003936926017"
|
||||
"6124466061356551464456206233957889787267447285030586700468858762515271223502"
|
||||
"75750995227"
|
||||
"G7UVKk+N6LfpGkdBP6XLB4QJ3wzee5YH/3o6tBDMwr4FS8YjCmeP6l4gu0hX"
|
||||
"dzY2Rive4TYOu4Akm4naZuv32d71/2lQeNcO23BNYOEPxtn9BU8uYfaHP9Mo"
|
||||
"M+m76oUCiI5uqpag5RH3BO34FyE4BiKkzjEXq9xxc8ERacG8Mo8DNiXu79p9"
|
||||
"Q/0wsRz+W/lIN4gYw3w4iLMooAGnDrhcj5cZb0HysHWYfqmFo+jTBP6Egi0g"
|
||||
"cmVO2qWQh2cZIQMfppaf1Ffq0XGIJpgDFyOHPl3NVxDabVK1tkVct+hathxJ"
|
||||
"UTdqZmR2VFwMASXjfgj4VFdvFCUxV8Xr8JcwXkwlMjOJbAl0LoCa4M7hpYvz"
|
||||
"G/0XviGCpv7qQaONKtsiQ6mHhMcyo9hBCRZXtNPkfPMZkPeV05akvaDs6Ek7"
|
||||
"DZ62oKR"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH3072
|
||||
@ -111,19 +95,15 @@ static const struct {
|
||||
384,
|
||||
"DH-3072",
|
||||
"2",
|
||||
"1142416747335183639807830604262436227795642944052113706188970261176634876069"
|
||||
"2206243140413411077394583180726863277012016602279290144126785129569474909173"
|
||||
"5847898223419867427192303319460727303195559844849117167970588759054009995043"
|
||||
"0587724584911968750902323279027363746682105257685923245298206183100977078603"
|
||||
"1785669030271542286603956118755585683996118896215213488875253101894663403069"
|
||||
"6777459483058938495054342017637452328957807119724320113448575216910178963168"
|
||||
"6140320644942133224365885545343578400651720289418164056243357539082138421096"
|
||||
"0117518650374602256601091379644034244332285065935413233557998331562749140202"
|
||||
"9658442193362989700115138825649355387042894469683222814519074873620465114612"
|
||||
"2132979989735099337056069750580968643878203623537213701573130477907243026098"
|
||||
"6460269894522159103008260495503005267165927542949439526272736586626709581721"
|
||||
"0321895327263896436255906801057848442461527026701693042037830722750891947548"
|
||||
"89511973916207"
|
||||
"1zsV6XgY57R/hu2RR4H/BjwRqmQL9h+Dc5rgoWOcqiTS8qpVTWafi1KFV77V"
|
||||
"rUcjcer1EDgCV0tpzlemtyrC2pHpw7hr3EEl2evfWOvg05FRI6mKc2UPNv2c"
|
||||
"2Bjww4LD/tdsLleX7AHHXCXFSSyd6C3qWq7BqABZriSpQeaEtXbWfeC6ytFe"
|
||||
"2i3VeQsLa40XQ21UxwhPAjamjSOfYzkW7xi0fwI1e+4OQiFcWOfOuvswoaEf"
|
||||
"MIICyAmVp67vjGo66dk81dMemyplipgXAWPdl7ppnDd6cEjyN4N90D7kQiNg"
|
||||
"lVmJlKLecldOUtdIqMnbJCbiN/t/3/AEFaokGO9om5ckc6M9gG5PG0T7Oh1N"
|
||||
"dSx/PstGdxwvs9DOwjyo5wl5C9QSLtUYJl2+GZYMj6WfsgCrb6jjRJJJQe2C"
|
||||
"y7wUcBILbRsP3lYT8s14zm4xFBrfMUoLN287j3wQ1TNUXjYSCi4ZLKT1XDai"
|
||||
"93345OiutLOqGGikFg6ypnymJK3yeHuul"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH4096
|
||||
@ -131,23 +111,18 @@ static const struct {
|
||||
512,
|
||||
"DH-4096",
|
||||
"3",
|
||||
"1214855636816562637502584060163403830270705000634713483015101384881871978446"
|
||||
"8012247985361554068958233050354675916325310675478909486951171720769542207270"
|
||||
"7568804875102242119871203284889005635784597424656074834791863005085393369779"
|
||||
"2254955890439720297560693579400297062396904306270145886830719309296352765295"
|
||||
"7121830407731464190228751653827780070401099576097395898755908857011261979060"
|
||||
"6362013395489321661267883850754077713843779770560245371955901763398648664952"
|
||||
"3611975865005712371194067612263330335590526176087004421363598470302731349138"
|
||||
"7732059014477046821815179040647356365184624522427916765417252923789255682968"
|
||||
"5801015185232631677751193503753101741391050692192245066693320227848902452126"
|
||||
"3798482237150056835746454842662048692127173834433089016107854491097456725016"
|
||||
"3277096631997382384421648431471327891537255132571679155551620949708535844479"
|
||||
"9312548860769600816980737473671129700747381225627224548940589847029717873802"
|
||||
"9484459690836250560495461579533254473316340608217876781986188705928270735695"
|
||||
"7528308255279638383554197625162460286802809880204019145518254873499903069763"
|
||||
"0409310938445143881325121105159739212749146489879740678917545306796007200859"
|
||||
"0614886532333015881171367104445044718144312416815712216611576221546455968770"
|
||||
"801413440778423979"
|
||||
"Id8ukxZdao3hS0NGTKAXdt3c8PpiyigIyBY8lwOHjM2cqkaZgwvr1pA6OowS"
|
||||
"32kJkeOqKB8gNTZZZVqOFkPXgvC4WveUgA5a7rhTj28pDidNROmMO70CCcSw"
|
||||
"aHI3GLFuEMz3JJyvQKGaGwpV3C9gS70dFWTxEfNRzdYEdvIic8/SXI79VgNP"
|
||||
"LGR68nzd4qxCgaLpVBnWsanRp7mfEj52S/7Kxjs14lrbAOMjCuHgN4F6THWh"
|
||||
"PNhG0VXfFFIwAMW2unrfpdo+gQHNclqCf2N1FALpABzvUesgs3wIP+QTMqms"
|
||||
"os/AkuulG7MusbeFl3SoCtaoW12CF038ZbqW+e+DKI1zObhtsLanvaiZm/N4"
|
||||
"BsJirW7avcWNQYm1oYjZ2bR/jYqfoJ0CLXLO/vqHb8J9a5VE9nz7cqMD3/MH"
|
||||
"k/g7BapsOtKuol6ipbUvxQPtf4KCwqQQ40JeqgS6amivI/aLu05S7bAxKOwE"
|
||||
"Yu8YxjN6lXm3co5Wy+BmNSuRlzKhxICyHEqMfKwUtm48XHzHuPaGQzHgkn6H"
|
||||
"3A+FQjQGLHewADYlbfdTF3sHYyc5k9h/9cYVkbmv7bQze53CJGr3T1hZYbN6"
|
||||
"+fuz0SPnfjiKu+bWD+8RYtZpLs2+f32huMz3OqoryGfULxC2aEjL2rdBn+ZR"
|
||||
"PT0+ZAUyLSAVHbsul++cawh"
|
||||
},
|
||||
#endif
|
||||
{
|
||||
@ -180,9 +155,8 @@ int dh_test(void)
|
||||
#if 0
|
||||
printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
|
||||
#endif
|
||||
/* see if g^((p-1)/2) == 1 mod p. */
|
||||
if (mp_read_radix(&g, sets[x].base, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&p, sets[x].prime, 10) != 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; }
|
||||
|
||||
/* ensure p is prime */
|
||||
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) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
if (mp_read_radix(&g, sets[x].base, 10) != MP_OKAY) { goto error2; }
|
||||
if (mp_read_radix(&p, sets[x].prime, 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[key->idx].prime, 64) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load the x value */
|
||||
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;
|
||||
|
||||
if (mp_shrink(&key->x) != MP_OKAY) { goto error; }
|
||||
if (mp_shrink(&key->y) != MP_OKAY) { goto error; }
|
||||
|
||||
/* free up ram */
|
||||
res = CRYPT_OK;
|
||||
goto done2;
|
||||
error2:
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
mp_clear_multi(&key->x, &key->y, NULL);
|
||||
done2:
|
||||
@ -304,10 +281,10 @@ void dh_free(dh_key *key)
|
||||
|
||||
#define OUTPUT_BIGNUM(num, buf2, y, z) \
|
||||
{ \
|
||||
z = mp_raw_size(num); \
|
||||
z = mp_unsigned_bin_size(num); \
|
||||
STORE32L(z, buf2+y); \
|
||||
y += 4; \
|
||||
mp_toraw(num, buf2+y); \
|
||||
mp_to_unsigned_bin(num, buf2+y); \
|
||||
y += z; \
|
||||
}
|
||||
|
||||
@ -329,11 +306,15 @@ void dh_free(dh_key *key)
|
||||
} \
|
||||
\
|
||||
/* 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; \
|
||||
goto error; \
|
||||
} \
|
||||
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 */
|
||||
packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY, y);
|
||||
packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY);
|
||||
|
||||
/* output it */
|
||||
*outlen = y;
|
||||
memcpy(out, buf2, y);
|
||||
|
||||
/* clear mem */
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf2, sizeof(buf2));
|
||||
#endif
|
||||
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) {
|
||||
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);
|
||||
@ -469,7 +458,7 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
|
||||
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; }
|
||||
|
||||
/* enough space for output? */
|
||||
|
68
dh_sys.c
68
dh_sys.c
@ -80,7 +80,7 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
}
|
||||
|
||||
/* 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
|
||||
/* clean up */
|
||||
@ -93,8 +93,9 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, dh_key *key)
|
||||
int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
dh_key *key)
|
||||
{
|
||||
unsigned char shared_secret[1536], skey[MAXBLOCKSIZE];
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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? */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -128,6 +136,14 @@ int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
|
||||
/* now check if the imported key will fit */
|
||||
if (inlen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= x;
|
||||
}
|
||||
|
||||
y += 4;
|
||||
if ((errno = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -149,6 +165,14 @@ int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
|
||||
/* load in the encrypted key */
|
||||
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) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
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; }
|
||||
|
||||
/* load g, p and p1 */
|
||||
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 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, 64) != 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 */
|
||||
|
||||
@ -256,7 +280,7 @@ int dh_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
memcpy(out, buf, y);
|
||||
@ -275,9 +299,9 @@ done:
|
||||
return res;
|
||||
}
|
||||
|
||||
int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key)
|
||||
int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dh_key *key)
|
||||
{
|
||||
mp_int a, b, p, g, m, tmp;
|
||||
unsigned char md[MAXBLOCKSIZE];
|
||||
@ -292,6 +316,13 @@ int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
/* default to invalid */
|
||||
*stat = 0;
|
||||
|
||||
/* check initial input length */
|
||||
if (siglen < PACKET_SIZE+4+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= PACKET_SIZE + 4 + 4;
|
||||
}
|
||||
|
||||
/* header ok? */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -302,7 +333,7 @@ int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
|
||||
/* hash the message */
|
||||
md[0] = 0;
|
||||
memcpy(md+1, hash, MIN(sizeof(md) - 1, inlen));
|
||||
memcpy(md+1, hash, MIN(sizeof(md) - 1, hashlen));
|
||||
|
||||
/* init all bignums */
|
||||
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 */
|
||||
LOAD32L(x, sig+y);
|
||||
if (siglen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= x;
|
||||
}
|
||||
|
||||
y += 4;
|
||||
if (mp_read_raw(&a, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
LOAD32L(x, sig+y);
|
||||
if (siglen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= x;
|
||||
}
|
||||
y += 4;
|
||||
if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* load p and g */
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&g, sets[key->idx].base, 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, 64) != MP_OKAY) { goto error; }
|
||||
|
||||
/* 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 */
|
||||
if (mp_exptmod(&g, &m, &p, &m) != MP_OKAY) { goto error; } /* m = g^m mod p */
|
||||
|
398
dsa.c
Normal file
398
dsa.c
Normal 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 */
|
||||
|
221
ecc.c
221
ecc.c
@ -18,15 +18,15 @@ static const struct {
|
||||
20,
|
||||
"ECC-160",
|
||||
/* prime */
|
||||
"1461501637330902918203684832716283019655932542983",
|
||||
"G00000000000000000000000007",
|
||||
/* B */
|
||||
"1C9E7C2E5891CBE097BD46",
|
||||
"1oUV2vOaSlWbxr6",
|
||||
/* order */
|
||||
"1461501637330902918203686297565868358251373258181",
|
||||
"G0000000000004sCQUtDxaqDUN5",
|
||||
/* Gx */
|
||||
"2DCF462904B478D868A7FF3F2BF1FCD9",
|
||||
"jpqOf1BHus6Yd/pyhyVpP",
|
||||
/* Gy */
|
||||
"DFFAF2EE3848FA75FB967CEC7B9A399E085ACED8",
|
||||
"D/wykuuIFfr+vPyx7kQEPu8MixO",
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC192
|
||||
@ -34,19 +34,19 @@ static const struct {
|
||||
24,
|
||||
"ECC-192",
|
||||
/* prime */
|
||||
"6277101735386680763835789423207666416083908700390324961279",
|
||||
"/////////////////////l//////////",
|
||||
|
||||
/* B */
|
||||
"64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
|
||||
"P2456UMSWESFf+chSYGmIVwutkp1Hhcn",
|
||||
|
||||
/* order */
|
||||
"6277101735386680763835789423176059013767194773182842284081",
|
||||
"////////////////cTxuDXHhoR6qqYWn",
|
||||
|
||||
/* Gx */
|
||||
"188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
|
||||
"68se3h0maFPylo3hGw680FJ/2ls2/n0I",
|
||||
|
||||
/* Gy */
|
||||
"07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
|
||||
"1nahbV/8sdXZ417jQoJDrNFvTw4UUKWH"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC224
|
||||
@ -55,19 +55,19 @@ static const struct {
|
||||
"ECC-224",
|
||||
|
||||
/* prime */
|
||||
"26959946667150639794667015087019630673637144422540572481103610249951",
|
||||
"400000000000000000000000000000000000BV",
|
||||
|
||||
/* B */
|
||||
"2051BA041508CED34B3",
|
||||
"21HkWGL2CxJIp",
|
||||
|
||||
/* order */
|
||||
"26959946667150639794667015087019637467111563745054605861463538557247",
|
||||
"4000000000000000000Kxnixk9t8MLzMiV264/",
|
||||
|
||||
/* Gx */
|
||||
"2DCF462904B478D868A7FF3F2BF1FCD9",
|
||||
"jpqOf1BHus6Yd/pyhyVpP",
|
||||
|
||||
/* Gy */
|
||||
"CF337F320BC44A15C3EDB8C4258BB958E57A0CAFA73EB46E9C4BA9AE",
|
||||
"3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC256
|
||||
@ -75,19 +75,19 @@ static const struct {
|
||||
32,
|
||||
"ECC-256",
|
||||
/* Prime */
|
||||
"115792089210356248762697446949407573530086143415290314195533631308867097853951",
|
||||
"F////y000010000000000000000////////////////",
|
||||
|
||||
/* B */
|
||||
"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
|
||||
"5h6DTYgEfFdi+kzLNQOXhnb7GQmp5EmzZlEF3udqc1B",
|
||||
|
||||
/* Order */
|
||||
"115792089210356248762697446949407573529996955224135760342422259061068512044369",
|
||||
"F////y00000//////////+yvlgjfnUUXFEvoiByOoLH",
|
||||
|
||||
/* Gx */
|
||||
"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
|
||||
"6iNqVBXB497+BpcvMEaGF9t0ts1BUipeFIXEKNOcCAM",
|
||||
|
||||
/* Gy */
|
||||
"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
|
||||
"4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC384
|
||||
@ -95,22 +95,23 @@ static const struct {
|
||||
48,
|
||||
"ECC-384",
|
||||
/* prime */
|
||||
"394020061963944792122790401001436138050797392704654466679482934042457217714968"
|
||||
"70329047266088258938001861606973112319",
|
||||
"//////////////////////////////////////////x/////00000000003/"
|
||||
"////",
|
||||
|
||||
/* B */
|
||||
"b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed1"
|
||||
"9d2a85c8edd3ec2aef",
|
||||
"ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ"
|
||||
"x2hl",
|
||||
|
||||
/* Order */
|
||||
"394020061963944792122790401001436138050797392704654466679469052796276593991132"
|
||||
"63569398956308152294913554433653942643",
|
||||
"////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC"
|
||||
"nIbp",
|
||||
|
||||
/* Gx and Gy */
|
||||
"aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf5529"
|
||||
"6c3a545e3872760ab7",
|
||||
"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e81"
|
||||
"9d7a431d7c90ea0e5f"
|
||||
"geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo"
|
||||
"TWgt",
|
||||
|
||||
"DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG"
|
||||
"wWvV"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC521
|
||||
@ -118,22 +119,23 @@ static const struct {
|
||||
65,
|
||||
"ECC-521",
|
||||
/* prime */
|
||||
"686479766013060971498190079908139321726943530014330540939446345918554318339765"
|
||||
"6052122559640661454554977296311391480858037121987999716643812574028291115057151",
|
||||
"V///////////////////////////////////////////////////////////"
|
||||
"///////////////////////////",
|
||||
|
||||
/* B */
|
||||
"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7"
|
||||
"e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
|
||||
"56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l"
|
||||
"JknlmSrSz+8FImqyUz57zHhK3y0",
|
||||
|
||||
/* Order */
|
||||
"686479766013060971498190079908139321726943530014330540939446345918554318339765"
|
||||
"5394245057746333217197532963996371363321113864768612440380340372808892707005449",
|
||||
"V//////////////////////////////////////////+b66XuE/BvPhVym1I"
|
||||
"FS9fT0xjScuYPn7hhjljnwHE6G9",
|
||||
|
||||
/* Gx and Gy */
|
||||
"c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe7"
|
||||
"5928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
|
||||
"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef"
|
||||
"42640c550b9013fad0761353c7086a272c24088be94769fd16650",
|
||||
"CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19"
|
||||
"wB/gDupIBF1XMf2c/b+VZ72vRrc",
|
||||
|
||||
"HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0"
|
||||
"J+j1s4rF726edB2G8Y+b7QVqMPG",
|
||||
},
|
||||
#endif
|
||||
{
|
||||
@ -329,59 +331,103 @@ done:
|
||||
/* 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)
|
||||
{
|
||||
ecc_point *tG;
|
||||
int i, j, z, first, res;
|
||||
ecc_point *tG, *M[14];
|
||||
int i, j, m, z, first, res;
|
||||
mp_digit d;
|
||||
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 */
|
||||
first = m = 0;
|
||||
for (z = i = 0; z < (int)USED(k); z++) {
|
||||
d = DIGIT(k, z);
|
||||
for (j = 0; j < (int)MP_DIGIT_BIT; j++) {
|
||||
first |= (d&1)<<(m++);
|
||||
if (m == 4) {
|
||||
bits[i++] = first;
|
||||
first = m = 0;
|
||||
}
|
||||
d >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#define DO1 bits[i++] = d&1; d >>= 1;
|
||||
#define DO2 DO1 DO1
|
||||
#define DO4 DO2 DO2
|
||||
|
||||
DO4; DO4; DO4; DO4
|
||||
|
||||
#undef DO4
|
||||
#undef DO2
|
||||
#undef DO1
|
||||
/* residue of multiplicand [if any] */
|
||||
if (m) {
|
||||
bits[i++] = first;
|
||||
}
|
||||
|
||||
/* make a copy of G incase R==G */
|
||||
tG = new_point();
|
||||
if (tG == NULL) {
|
||||
return CRYPT_MEM;
|
||||
if (tG == NULL) { goto error; }
|
||||
|
||||
/* 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 */
|
||||
if (mp_copy(&G->x, &tG->x) != 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 (bits[i] == 1) {
|
||||
if (mp_copy(&G->x, &R->x) != MP_OKAY) { goto error; }
|
||||
if (mp_copy(&G->y, &R->y) != MP_OKAY) { goto error; }
|
||||
first = 0;
|
||||
} else if (bits[i]>=2) {
|
||||
if (mp_copy(&M[bits[i]-2]->x, &R->x) != MP_OKAY) { goto error; }
|
||||
if (mp_copy(&M[bits[i]-2]->y, &R->y) != MP_OKAY) { goto error; }
|
||||
}
|
||||
|
||||
/* now do dbl+add through all the bits */
|
||||
for (j = i-1; j >= 0; j--) {
|
||||
if (first) {
|
||||
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 (bits[i] == 0) {
|
||||
/* nop */
|
||||
} else if (bits[i] == 1) {
|
||||
/* add base point */
|
||||
if (add_point(R, tG, R, modulus) != CRYPT_OK) { goto error; }
|
||||
}
|
||||
first = 1;
|
||||
} else {
|
||||
/* other case */
|
||||
if (add_point(R, M[bits[i]-2], R, modulus) != CRYPT_OK) { goto error; }
|
||||
}
|
||||
}
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
del_point(tG);
|
||||
for (i = 0; i < 14; i++) {
|
||||
del_point(M[i]);
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(bits, sizeof(bits));
|
||||
#endif
|
||||
@ -412,8 +458,11 @@ int ecc_test(void)
|
||||
}
|
||||
|
||||
for (i = 0; sets[i].size; i++) {
|
||||
if (mp_read_radix(&modulus, (unsigned char *)sets[i].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&order, (unsigned char *)sets[i].order, 10) != MP_OKAY) { goto error; }
|
||||
#if 0
|
||||
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? */
|
||||
if (is_prime(&modulus, &primality) != CRYPT_OK) { goto error; }
|
||||
@ -429,8 +478,8 @@ int ecc_test(void)
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (mp_read_radix(&G->x, (unsigned char *)sets[i].Gx, 16) != 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->x, (unsigned char *)sets[i].Gx, 64) != 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 */
|
||||
if (mp_add_d(&order, 1, &order) != MP_OKAY) { goto error; }
|
||||
@ -509,15 +558,20 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *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(&base->x, (unsigned char *)sets[x].Gx, 16) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&base->y, (unsigned char *)sets[x].Gy, 16) != 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[key->idx].Gx, 64) != 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; }
|
||||
|
||||
/* make the public key */
|
||||
if (ecc_mulmod(&key->k, base, &key->pubkey, &prime, x) != CRYPT_OK) { goto error; }
|
||||
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 */
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
@ -551,12 +605,12 @@ static int compress_y_point(ecc_point *pt, int idx, int *result)
|
||||
}
|
||||
|
||||
/* 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_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_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 */
|
||||
|
||||
/* 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 */
|
||||
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_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_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 */
|
||||
|
||||
/* now find square root */
|
||||
@ -625,10 +679,10 @@ done:
|
||||
|
||||
#define OUTPUT_BIGNUM(num, buf2, y, z) \
|
||||
{ \
|
||||
z = mp_raw_size(num); \
|
||||
z = mp_unsigned_bin_size(num); \
|
||||
STORE32L(z, buf2+y); \
|
||||
y += 4; \
|
||||
mp_toraw(num, buf2+y); \
|
||||
mp_to_unsigned_bin(num, buf2+y); \
|
||||
y += z; \
|
||||
}
|
||||
|
||||
@ -650,11 +704,15 @@ done:
|
||||
} \
|
||||
\
|
||||
/* 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; \
|
||||
goto error; \
|
||||
} \
|
||||
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)
|
||||
@ -696,7 +754,7 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
|
||||
}
|
||||
|
||||
/* 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);
|
||||
*outlen = y;
|
||||
@ -765,10 +823,15 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
|
||||
/* load private key */
|
||||
INPUT_BIGNUM(&key->k, in, x, y);
|
||||
}
|
||||
|
||||
/* eliminate private key if public */
|
||||
if (key->type == PK_PUBLIC) {
|
||||
mp_clear(&key->k);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
|
||||
done:
|
||||
return errno;
|
||||
}
|
||||
|
||||
@ -805,7 +868,7 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
|
||||
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; }
|
||||
|
||||
x = mp_raw_size(&result->x);
|
||||
|
56
ecc_sys.c
56
ecc_sys.c
@ -84,7 +84,7 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
}
|
||||
|
||||
/* 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
|
||||
/* clean up */
|
||||
@ -96,8 +96,9 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, ecc_key *key)
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char shared_secret[256], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, res, hashsize, keysize;
|
||||
@ -114,6 +115,13 @@ int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
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? */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -131,6 +139,11 @@ int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
if (inlen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= x;
|
||||
}
|
||||
y += 4;
|
||||
if ((errno = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -151,6 +164,11 @@ int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
}
|
||||
|
||||
LOAD32L(keysize, in+y);
|
||||
if (inlen < keysize) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= keysize;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
if (*keylen < keysize) {
|
||||
@ -223,7 +241,7 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
ecc_free(&pubkey);
|
||||
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; }
|
||||
|
||||
/* find b = (m - x)/k */
|
||||
@ -266,7 +284,7 @@ int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
*outlen = y;
|
||||
@ -286,9 +304,9 @@ done1:
|
||||
}
|
||||
|
||||
/* verify that mG = (bA + Y) */
|
||||
int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key)
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long inlen,
|
||||
int *stat, ecc_key *key)
|
||||
{
|
||||
ecc_point *mG;
|
||||
ecc_key pubkey;
|
||||
@ -305,6 +323,12 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
|
||||
if (siglen < PACKET_SIZE+4+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= PACKET_SIZE+4+4;
|
||||
}
|
||||
|
||||
/* is the message format correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -315,6 +339,11 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
|
||||
/* get size of public key */
|
||||
LOAD32L(x, sig+y);
|
||||
if (siglen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= x;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
/* load the public key */
|
||||
@ -325,6 +354,11 @@ int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
|
||||
/* load size of 'b' */
|
||||
LOAD32L(x, sig+y);
|
||||
if (siglen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= x;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
/* 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; }
|
||||
|
||||
/* 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 */
|
||||
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; }
|
||||
|
||||
/* get mG */
|
||||
if (mp_read_radix(&mG->x, (unsigned char *)sets[key->idx].Gx, 16) != 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->x, (unsigned char *)sets[key->idx].Gx, 64) != 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; }
|
||||
|
||||
/* compare mG to bA + Y */
|
||||
|
18
examples/ch1-01.c
Normal file
18
examples/ch1-01.c
Normal 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
25
examples/ch1-02.c
Normal 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
29
examples/ch1-03.c
Normal 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 */
|
||||
|
||||
|
||||
|
41
keyring.c
41
keyring.c
@ -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)
|
||||
{
|
||||
//_ARGCHK(buf != NULL && len == 0);
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len >= 8) {
|
||||
DO8 (buf);
|
||||
@ -587,25 +588,26 @@ int kr_encrypt_key(pk_key *pk, unsigned long ID,
|
||||
STORE32L(kr->ID,buf+4);
|
||||
|
||||
/* now encrypt it */
|
||||
len = sizeof(buf)-8;
|
||||
len = sizeof(buf)-12;
|
||||
switch (kr->system) {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
len += 8;
|
||||
STORE32L(len,buf+8);
|
||||
len += 12;
|
||||
|
||||
if (len > *outlen) {
|
||||
#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 buf[8192];
|
||||
unsigned long len, ID;
|
||||
unsigned long pklen, len, ID;
|
||||
pk_key *kr;
|
||||
int errno;
|
||||
|
||||
@ -653,20 +655,21 @@ int kr_decrypt_key(pk_key *pk, const unsigned char *in,
|
||||
}
|
||||
|
||||
/* now try and decrypt it */
|
||||
LOAD32L(pklen,in+8);
|
||||
len = sizeof(buf);
|
||||
switch (kr->system) {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
@ -720,26 +723,27 @@ int kr_sign_hash(pk_key *pk, unsigned long ID,
|
||||
STORE32L(kr->ID,buf+4);
|
||||
|
||||
/* now sign it */
|
||||
len = sizeof(buf)-12;
|
||||
len = sizeof(buf)-16;
|
||||
switch (kr->system) {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
STORE32L(inlen,buf+8);
|
||||
len += 12;
|
||||
STORE32L(len,buf+12);
|
||||
len += 16;
|
||||
|
||||
if (len > *outlen) {
|
||||
#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,
|
||||
unsigned long hashlen, int *stat)
|
||||
{
|
||||
unsigned long inlen, ID;
|
||||
unsigned long inlen, pklen, ID;
|
||||
pk_key *kr;
|
||||
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 */
|
||||
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 */
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
switch (kr->system) {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
146
makefile
146
makefile
@ -9,62 +9,77 @@
|
||||
# a build. This is easy to remedy though, for those that have problems.
|
||||
|
||||
# The version
|
||||
VERSION=0.78
|
||||
VERSION=0.79
|
||||
|
||||
#Compiler and Linker Names
|
||||
#ch1-01-1
|
||||
# Compiler and Linker Names
|
||||
CC=gcc
|
||||
LD=ld
|
||||
|
||||
#Archiver [makes .a files]
|
||||
# Archiver [makes .a files]
|
||||
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
|
||||
XCALLOC=calloc
|
||||
XREALLOC=realloc
|
||||
XFREE=free
|
||||
|
||||
#you can redefine the clock
|
||||
# you can redefine the clock
|
||||
XCLOCK=clock
|
||||
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 \
|
||||
-DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) -DXCLOCK=$(XCLOCK) \
|
||||
-DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) \
|
||||
-DXREALLOC=$(XREALLOC) -DXCLOCK=$(XCLOCK) \
|
||||
-DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
|
||||
|
||||
#optimize for SPEED (comment out SIZE/DEBUG line as well)
|
||||
# optimize for SPEED
|
||||
#CFLAGS += -O3 -funroll-loops
|
||||
|
||||
#optimize for SIZE (comment out SPEED/DEBUG line as well)
|
||||
# optimize for SIZE
|
||||
CFLAGS += -Os
|
||||
|
||||
#Use small code variants of functions when possible? (Slows it down!)
|
||||
CFLAGS += -DSMALL_CODE
|
||||
|
||||
#compile for DEBUGGING
|
||||
# compile for DEBUGGING
|
||||
#CFLAGS += -g3
|
||||
#ch1-01-3
|
||||
|
||||
#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
|
||||
#(comment out to have file support)
|
||||
#ch1-01-4
|
||||
# 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
|
||||
|
||||
#Support the UNIX /dev/random or /dev/urandom
|
||||
# Support the UNIX /dev/random or /dev/urandom
|
||||
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
|
||||
|
||||
# Clean the stack after sensitive functions. Not always required...
|
||||
# With this defined most of the ciphers and hashes will clean their stack area
|
||||
# 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.
|
||||
# Clean the stack after sensitive functions. Not
|
||||
# always required... With this defined most of
|
||||
# the ciphers and hashes will clean their stack area
|
||||
# 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
|
||||
#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 += -DRC2
|
||||
CFLAGS += -DRC5
|
||||
@ -78,6 +93,7 @@ CFLAGS += -DTWOFISH
|
||||
CFLAGS += -DDES
|
||||
CFLAGS += -DCAST5
|
||||
CFLAGS += -DNOEKEON
|
||||
#ch1-01-5
|
||||
|
||||
#You can also customize the Twofish code. All four combinations
|
||||
#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
|
||||
# faster keysetup though...
|
||||
|
||||
# Small Ram Variant of Twofish. For this you must have TWOFISH defined. This
|
||||
# variant requires about 4kb less memory but 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.
|
||||
#ch1-01-6
|
||||
# Small Ram Variant of Twofish. For this you must have TWOFISH
|
||||
# defined. This variant requires about 4kb less memory but
|
||||
# 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
|
||||
|
||||
# Tell Twofish to use precomputed tables. If you want to use the small table
|
||||
# variant of Twofish you may want to turn this on. Essentially it tells Twofish to use
|
||||
# precomputed S-boxes (Q0 and Q1) as well as precomputed GF multiplications [in the MDS].
|
||||
# This speeds up the cipher somewhat.
|
||||
# Tell Twofish to use precomputed tables. If you want to use
|
||||
# the small table variant of Twofish you may want to turn
|
||||
# this on. Essentially it tells Twofish to use precomputed
|
||||
# S-boxes (Q0 and Q1) as well as precomputed GF
|
||||
# multiplications [in the MDS]. This speeds up the cipher
|
||||
# somewhat.
|
||||
#CFLAGS += -DTWOFISH_TABLES
|
||||
#ch1-01-6
|
||||
|
||||
#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
|
||||
@ -110,13 +132,16 @@ CFLAGS += -DNOEKEON
|
||||
#security so its by default not turned on. USE AT YOUR RISK!
|
||||
#CFLAGS += -DFAST_PK
|
||||
|
||||
#ch1-01-7
|
||||
# Chaining modes
|
||||
CFLAGS += -DCFB
|
||||
CFLAGS += -DOFB
|
||||
CFLAGS += -DECB
|
||||
CFLAGS += -DCBC
|
||||
CFLAGS += -DCTR
|
||||
#ch1-01-7
|
||||
|
||||
#ch1-01-8
|
||||
#One-way hashes
|
||||
CFLAGS += -DSHA512
|
||||
CFLAGS += -DSHA384
|
||||
@ -126,29 +151,73 @@ CFLAGS += -DSHA1
|
||||
CFLAGS += -DMD5
|
||||
CFLAGS += -DMD4
|
||||
CFLAGS += -DMD2
|
||||
#ch1-01-8
|
||||
|
||||
# base64
|
||||
CFLAGS += -DBASE64
|
||||
|
||||
#ch1-01-9
|
||||
# prngs
|
||||
CFLAGS += -DYARROW
|
||||
CFLAGS += -DSPRNG
|
||||
CFLAGS += -DRC4
|
||||
#ch1-01-9
|
||||
|
||||
#ch1-01-10
|
||||
# PK code
|
||||
CFLAGS += -DMRSA
|
||||
CFLAGS += -DMDH
|
||||
CFLAGS += -DMECC
|
||||
#CFLAGS += -DMDSA
|
||||
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
|
||||
|
||||
# include large integer math routines? (required by the PK code)
|
||||
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
|
||||
CFLAGS += -DHMAC
|
||||
#ch1-01-11
|
||||
|
||||
#Output filenames for various targets.
|
||||
LIBNAME=libtomcrypt.a
|
||||
@ -163,7 +232,7 @@ LIBPATH=/usr/lib
|
||||
INCPATH=/usr/include
|
||||
|
||||
#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 \
|
||||
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 \
|
||||
@ -199,6 +268,7 @@ sha512.o: sha512.c sha384.c
|
||||
#This rule makes the libtomcrypt library.
|
||||
library: $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS)
|
||||
ranlib $(LIBNAME)
|
||||
|
||||
#This rule makes the test program included with libtomcrypt
|
||||
test: library $(TESTOBJECTS)
|
||||
@ -219,9 +289,11 @@ small: library $(SMALLOBJECTS)
|
||||
#This rule installs the library and the header files. This must be run
|
||||
#as root in order to have a high enough permission to write to the correct
|
||||
#directories and to set the owner and group to root.
|
||||
install: library
|
||||
install: library docs
|
||||
install -g root -o root $(LIBNAME) $(LIBPATH)
|
||||
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
|
||||
#documentation.
|
||||
|
23
makefile.out
Normal file
23
makefile.out
Normal 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
|
||||
|
48
makefile.ps2
48
makefile.ps2
@ -32,6 +32,7 @@ ARFLAGS=rs
|
||||
#here you can set the malloc/calloc/free functions you want
|
||||
XMALLOC=malloc
|
||||
XCALLOC=calloc
|
||||
XREALLOC=realloc
|
||||
XFREE=free
|
||||
|
||||
#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!
|
||||
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)
|
||||
|
||||
#optimize for SPEED (comment out SIZE line as well)
|
||||
@ -103,14 +105,6 @@ CFLAGS += -DNOEKEON
|
||||
# This speeds up the cipher somewhat.
|
||||
# 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
|
||||
#DH system to 256 bits. The group order remains unchanged so the best
|
||||
#attacks are still GNFS (for DH upto 2560-bits)
|
||||
@ -148,14 +142,48 @@ CFLAGS += -DRC4
|
||||
CFLAGS += -DMRSA
|
||||
CFLAGS += -DMDH
|
||||
CFLAGS += -DMECC
|
||||
#CFLAGS += -DDSA
|
||||
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)
|
||||
#CFLAGS += -DGF
|
||||
|
||||
# include large integer math routines? (required by the PK code)
|
||||
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
|
||||
CFLAGS += -DHMAC
|
||||
|
||||
@ -175,7 +203,7 @@ LIBPATH=/usr/lib
|
||||
INCPATH=/usr/include
|
||||
|
||||
#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 \
|
||||
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 \
|
||||
|
44
makefile.vc
44
makefile.vc
@ -8,13 +8,14 @@ AR=lib
|
||||
#here you can set the malloc/calloc/free functions you want
|
||||
XMALLOC=malloc
|
||||
XCALLOC=calloc
|
||||
XREALLOC=realloc
|
||||
XFREE=free
|
||||
|
||||
#you can redefine the clock
|
||||
XCLOCK=clock
|
||||
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)
|
||||
CFLAGS += /DSMALL_CODE
|
||||
@ -113,14 +114,49 @@ CFLAGS += /DRC4
|
||||
CFLAGS += /DMRSA
|
||||
CFLAGS += /DMDH
|
||||
CFLAGS += /DMECC
|
||||
#CFLAGS += /DDSA
|
||||
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)
|
||||
#CFLAGS += /DGF
|
||||
|
||||
# include large integer math routines? (required by the PK code)
|
||||
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
|
||||
CFLAGS += /DHMAC
|
||||
|
||||
@ -216,6 +252,8 @@ cast5.obj: cast5.c
|
||||
$(CC) $(CFLAGS) cast5.c
|
||||
noekeon.obj: noekeon.c
|
||||
$(CC) $(CFLAGS) noekeon.c
|
||||
dsa.obj: dsa.c
|
||||
$(CC) $(CFLAGS) dsa.c
|
||||
|
||||
demos/test.obj: demos/test.c
|
||||
$(CC) $(CFLAGS) demos/test.c
|
||||
@ -223,11 +261,11 @@ demos/test.obj: demos/test.c
|
||||
demos/hashsum.obj: 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 \
|
||||
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
|
||||
$(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 \
|
||||
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
|
||||
|
213
mpi.c
213
mpi.c
@ -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) */
|
||||
|
||||
#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)
|
||||
|
||||
@ -1731,6 +1882,8 @@ mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
|
||||
|
||||
} /* end mp_exptmod() */
|
||||
|
||||
#endif
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ 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++)
|
||||
dp[ix - p] = dp[ix];
|
||||
|
||||
|
||||
/* Fill the top digits with zeroes */
|
||||
|
||||
ix -= p;
|
||||
while(ix < USED(mp))
|
||||
dp[ix++] = 0;
|
||||
@ -2966,10 +3121,14 @@ void s_mp_mod_2d(mp_int *mp, mp_digit d)
|
||||
dp[ndig] &= dmask;
|
||||
|
||||
/* Flush all digits above the one with 2^d in it */
|
||||
|
||||
/*
|
||||
for(ix = ndig + 1; ix < USED(mp); ix++)
|
||||
dp[ix] = 0;
|
||||
|
||||
s_mp_clamp(mp);
|
||||
*/
|
||||
USED(mp) = ndig;
|
||||
|
||||
} /* end s_mp_mod_2d() */
|
||||
|
||||
@ -3431,6 +3590,56 @@ mp_err s_mp_mul(mp_int *a, mp_int *b)
|
||||
|
||||
} /* 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) */
|
||||
@ -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)));
|
||||
|
||||
/* q = q * m mod b^(k+1), quick (no division) */
|
||||
s_mp_mul(&q, m);
|
||||
s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1)));
|
||||
s_mp_mul_dig(&q, m, um + 1);
|
||||
// s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1)));
|
||||
|
||||
/* x = x - q */
|
||||
if((res = mp_sub(x, &q, x)) != MP_OKAY)
|
||||
|
5
mpi.h
5
mpi.h
@ -98,6 +98,8 @@ void mp_clear_array(mp_int mp[], int count);
|
||||
void mp_zero(mp_int *mp);
|
||||
void mp_set(mp_int *mp, mp_digit d);
|
||||
mp_err mp_set_int(mp_int *mp, long z);
|
||||
mp_err mp_shrink(mp_int *a);
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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)
|
||||
#endif
|
||||
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);
|
||||
#endif /* MP_MODARITH */
|
||||
|
||||
|
52
mycrypt.h
52
mycrypt.h
@ -13,46 +13,48 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* version */
|
||||
#define CRYPT 0x0078
|
||||
#define SCRYPT "0.78"
|
||||
#define CRYPT 0x0079
|
||||
#define SCRYPT "0.79"
|
||||
|
||||
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
|
||||
#define MAXBLOCKSIZE 128
|
||||
|
||||
/* ch1-01-1 */
|
||||
/* error codes [will be expanded in future releases] */
|
||||
enum {
|
||||
CRYPT_OK=0,
|
||||
CRYPT_ERROR,
|
||||
CRYPT_OK=0, /* Result OK */
|
||||
CRYPT_ERROR, /* Generic Error */
|
||||
|
||||
CRYPT_INVALID_KEYSIZE,
|
||||
CRYPT_INVALID_ROUNDS,
|
||||
CRYPT_FAIL_TESTVECTOR,
|
||||
CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
|
||||
CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
|
||||
CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
|
||||
|
||||
CRYPT_BUFFER_OVERFLOW,
|
||||
CRYPT_INVALID_PACKET,
|
||||
CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
|
||||
CRYPT_INVALID_PACKET, /* Invalid input packet given */
|
||||
|
||||
CRYPT_INVALID_PRNGSIZE,
|
||||
CRYPT_ERROR_READPRNG,
|
||||
CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
|
||||
CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
|
||||
|
||||
CRYPT_INVALID_CIPHER,
|
||||
CRYPT_INVALID_HASH,
|
||||
CRYPT_INVALID_PRNG,
|
||||
CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
|
||||
CRYPT_INVALID_HASH, /* Invalid hash specified */
|
||||
CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
|
||||
|
||||
CRYPT_MEM,
|
||||
CRYPT_MEM, /* Out of memory */
|
||||
|
||||
CRYPT_PK_TYPE_MISMATCH,
|
||||
CRYPT_PK_NOT_PRIVATE,
|
||||
CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
|
||||
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_SYSTEM,
|
||||
CRYPT_PK_DUP,
|
||||
CRYPT_PK_NOT_FOUND,
|
||||
CRYPT_PK_INVALID_SIZE,
|
||||
CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
|
||||
CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
|
||||
CRYPT_PK_DUP, /* Duplicate key already in key ring */
|
||||
CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
|
||||
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_macros.h>
|
||||
@ -63,10 +65,8 @@ enum {
|
||||
#include <mycrypt_gf.h>
|
||||
#include <mycrypt_misc.h>
|
||||
#include <mycrypt_kr.h>
|
||||
|
||||
#include <mycrypt_argchk.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,26 +1,14 @@
|
||||
/* Defines the _ARGCHK macro used within the library */
|
||||
|
||||
/* ch1-01-1 */
|
||||
/* ARGTYPE is defined in mycrypt_cfg.h */
|
||||
#if ARGTYPE == 0
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/* this is the default LibTomCrypt macro
|
||||
*
|
||||
* On embedded platforms you can change the fprintf() to be a routine that would display a message
|
||||
* 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
|
||||
/* this is the default LibTomCrypt macro */
|
||||
extern void crypt_argchk(char *v, char *s, int d);
|
||||
#define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
|
||||
|
||||
#elif ARGTYPE == 1
|
||||
|
||||
@ -32,4 +20,5 @@
|
||||
#define _ARGCHK(x)
|
||||
|
||||
#endif
|
||||
/* ch1-01-1 */
|
||||
|
||||
|
@ -9,14 +9,17 @@
|
||||
|
||||
/* you can change how memory allocation works ... */
|
||||
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 XFREE(void *p);
|
||||
|
||||
/* change the clock function too */
|
||||
extern clock_t XCLOCK(void);
|
||||
|
||||
/* ch1-01-1 */
|
||||
/* type of argument checking, 0=default, 1=fatal and 2=none */
|
||||
#define ARGTYPE 0
|
||||
/* ch1-01-1 */
|
||||
|
||||
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */
|
||||
/* detect x86-32 machines somewhat */
|
||||
@ -53,7 +56,7 @@ extern clock_t XCLOCK(void);
|
||||
|
||||
#ifdef YARROW
|
||||
#ifndef CTR
|
||||
#error YARROW Requires CTR mode
|
||||
#error YARROW requires CTR chaining mode to be defined!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -62,12 +65,13 @@ extern clock_t XCLOCK(void);
|
||||
#define PACKET
|
||||
|
||||
/* size of a packet header in bytes */
|
||||
#define PACKET_SIZE 8
|
||||
#define PACKET_SIZE 4
|
||||
|
||||
/* Section tags */
|
||||
#define PACKET_SECT_RSA 0
|
||||
#define PACKET_SECT_DH 1
|
||||
#define PACKET_SECT_ECC 2
|
||||
#define PACKET_SECT_DSA 4
|
||||
|
||||
/* Subsection Tags for the first three sections */
|
||||
#define PACKET_SUB_KEY 0
|
||||
@ -76,33 +80,6 @@ extern clock_t XCLOCK(void);
|
||||
#define PACKET_SUB_ENC_KEY 3
|
||||
#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
|
||||
#include "mpi.h"
|
||||
#else
|
||||
@ -115,6 +92,9 @@ extern clock_t XCLOCK(void);
|
||||
#ifdef MDH
|
||||
#error DH requires the big int library
|
||||
#endif
|
||||
#ifdef MDSA
|
||||
#error DSA requires the big int library
|
||||
#endif
|
||||
#endif /* MPI */
|
||||
|
||||
#endif /* MYCRYPT_CFG_H */
|
||||
|
@ -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 burn_stack(unsigned long len);
|
||||
|
||||
/* ch1-01-1*/
|
||||
extern const char *error_to_string(int errno);
|
||||
/* ch1-01-1*/
|
||||
|
||||
extern const char *crypt_build_settings;
|
||||
|
52
mycrypt_pk.h
52
mycrypt_pk.h
@ -17,7 +17,7 @@ extern void mp_clear_multi(mp_int* mp, ...);
|
||||
/* ---- 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);
|
||||
|
||||
#endif
|
||||
@ -56,15 +56,16 @@ extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, rsa_key *key);
|
||||
|
||||
extern int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, rsa_key *key);
|
||||
extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
rsa_key *key);
|
||||
|
||||
extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
rsa_key *key);
|
||||
|
||||
extern int rsa_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
int *stat, rsa_key *key);
|
||||
extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
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_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,
|
||||
dh_key *key);
|
||||
|
||||
extern int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, dh_key *key);
|
||||
extern int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
dh_key *key);
|
||||
|
||||
extern int dh_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, dh_key *key);
|
||||
|
||||
extern int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key);
|
||||
extern int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dh_key *key);
|
||||
|
||||
|
||||
#endif
|
||||
@ -140,15 +142,35 @@ extern int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key);
|
||||
|
||||
extern int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, ecc_key *key);
|
||||
extern int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
ecc_key *key);
|
||||
|
||||
extern int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key);
|
||||
|
||||
extern int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key);
|
||||
extern int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
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
|
||||
|
||||
|
4
packet.c
4
packet.c
@ -2,7 +2,7 @@
|
||||
|
||||
#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);
|
||||
|
||||
@ -14,8 +14,6 @@ void packet_store_header(unsigned char *dst, int section, int subsection, unsign
|
||||
dst[2] = section & 255;
|
||||
dst[3] = subsection & 255;
|
||||
|
||||
/* store length */
|
||||
STORE32L(length, &dst[4]);
|
||||
}
|
||||
|
||||
int packet_valid_header(unsigned char *src, int section, int subsection)
|
||||
|
2
prime.c
2
prime.c
@ -230,8 +230,6 @@ done:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
|
||||
{
|
||||
unsigned char buf[260];
|
||||
|
33
rsa.c
33
rsa.c
@ -74,6 +74,18 @@ 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(&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;
|
||||
key->type = PK_PRIVATE_OPTIMIZED;
|
||||
goto done;
|
||||
@ -293,10 +305,10 @@ int rsa_depad(const unsigned char *in, unsigned long inlen,
|
||||
|
||||
#define OUTPUT_BIGNUM(num, buf2, y, z) \
|
||||
{ \
|
||||
z = mp_raw_size(num); \
|
||||
z = mp_unsigned_bin_size(num); \
|
||||
STORE32L(z, buf2+y); \
|
||||
y += 4; \
|
||||
mp_toraw(num, buf2+y); \
|
||||
mp_to_unsigned_bin(num, buf2+y); \
|
||||
y += z; \
|
||||
}
|
||||
|
||||
@ -318,11 +330,16 @@ int rsa_depad(const unsigned char *in, unsigned long inlen,
|
||||
} \
|
||||
\
|
||||
/* 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; \
|
||||
goto error2; \
|
||||
} \
|
||||
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)
|
||||
@ -371,7 +388,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
memcpy(out, buf2, y);
|
||||
@ -432,6 +449,14 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
|
||||
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;
|
||||
error2:
|
||||
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
|
||||
|
40
rsa_sys.c
40
rsa_sys.c
@ -49,7 +49,7 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
|
||||
}
|
||||
|
||||
/* 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
|
||||
/* clean up */
|
||||
@ -60,8 +60,9 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, rsa_key *key)
|
||||
int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
rsa_key *key)
|
||||
{
|
||||
unsigned char sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096];
|
||||
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;
|
||||
}
|
||||
|
||||
if (inlen < PACKET_SIZE+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= PACKET_SIZE+4;
|
||||
}
|
||||
|
||||
/* check the header */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -84,7 +91,12 @@ int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
|
||||
/* grab length of the rsa key */
|
||||
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;
|
||||
|
||||
/* read it in */
|
||||
@ -94,8 +106,9 @@ int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
|
||||
/* decrypt it */
|
||||
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;
|
||||
}
|
||||
|
||||
/* depad it */
|
||||
z = sizeof(sym_key);
|
||||
@ -170,7 +183,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
}
|
||||
|
||||
/* 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
|
||||
/* clean up */
|
||||
@ -181,8 +194,8 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_verify_hash(const unsigned char *sig, const unsigned char *md,
|
||||
int *stat, rsa_key *key)
|
||||
int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *md, int *stat, rsa_key *key)
|
||||
{
|
||||
unsigned long rsa_size, x, y, z;
|
||||
unsigned char rsa_in[4096], rsa_out[4096];
|
||||
@ -196,6 +209,12 @@ int rsa_verify_hash(const unsigned char *sig, const unsigned char *md,
|
||||
/* always be incorrect by default */
|
||||
*stat = 0;
|
||||
|
||||
if (siglen < PACKET_SIZE+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= PACKET_SIZE+4;
|
||||
}
|
||||
|
||||
/* verify header */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
@ -204,6 +223,11 @@ int rsa_verify_hash(const unsigned char *sig, const unsigned char *md,
|
||||
/* get the len */
|
||||
y = PACKET_SIZE;
|
||||
LOAD32L(rsa_size, (sig+y));
|
||||
if (siglen < rsa_size) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= rsa_size;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
/* load the signature */
|
||||
|
3
sha1.c
3
sha1.c
@ -25,7 +25,7 @@ static void _sha1_compress(hash_state *md)
|
||||
static void sha1_compress(hash_state *md)
|
||||
#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);
|
||||
|
||||
@ -47,6 +47,7 @@ static void sha1_compress(hash_state *md)
|
||||
W[i] = ROL(j, 1);
|
||||
}
|
||||
|
||||
|
||||
/* compress */
|
||||
/* round one */
|
||||
for (i = 0; i < 20; i++) {
|
||||
|
@ -38,7 +38,7 @@ static const char *err_2_str[] =
|
||||
|
||||
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.";
|
||||
} else {
|
||||
return err_2_str[errno];
|
||||
|
131
update_libtomcrypt.sh
Normal file
131
update_libtomcrypt.sh
Normal 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
|
Loading…
Reference in New Issue
Block a user