#import "Crypt.h"
#include "ckconfig.h"
#if !CRYPTKIT_HIGH_LEVEL_SIG
#error Can not build this program against a lib with !CRYPTKIT_HIGH_LEVEL_SIG.
#endif
#import <sys/param.h>
#import <libc.h>
static unsigned char *passwdPool;
static unsigned char *dataPool;
#define MAX_DATA_SIZE ((1024 * 1024) + 100)
#define LOOPS_DEF 1
#define MIN_EXP 2
#define MAX_EXP 4
#define PWD_LENGTH 15
#define DEPTH_DEFAULT FEE_DEPTH_DEFAULT
#define INCR_DEFAULT 1
static void usage(char **argv)
{
printf("usage: %s [options]\n", argv[0]);
printf(" Options:\n");
printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
printf(" n=minExp (default=%d)\n", MIN_EXP);
printf(" x=maxExp (default=max=%d)\n", MAX_EXP);
printf(" p=passwdLength (default=%d)\n", PWD_LENGTH);
printf(" D=depth (default=%d)\n", DEPTH_DEFAULT);
printf(" i=increment (default=%d)\n", INCR_DEFAULT);
#if CRYPTKIT_ECDSA_ENABLE
printf(" e (ElGamal only, no ECDSA)\n");
#endif
printf(" s=seed\n");
printf(" v(erbose)\n");
printf(" q(uiet)\n");
printf(" h(elp)\n");
exit(1);
}
static int genRand(int min, int max)
{
if(max == min)
return(max);
else
return(min + (random() % (max-min+1)));
}
static unsigned char *genPasswd(unsigned passwdLength)
{
unsigned *ip = (unsigned *)passwdPool;
unsigned intCount = passwdLength / 4;
int i;
unsigned char *cp;
unsigned residue = passwdLength & 0x3;
for (i=0; i<intCount; i++) {
*ip++ = random();
}
cp = (unsigned char *)ip;
for(i=0; i<residue; i++) {
*cp = (unsigned char)random();
}
return passwdPool;
}
typedef enum {
DT_Random,
DT_Zero,
DT_ASCII
} dataType;
#define MIN_OFFSET 0
#define MAX_OFFSET 99
#define MIN_ASCII ' '
#define MAX_ASCII '~'
static unsigned char *genData(unsigned minExp,
unsigned maxExp,
dataType type,
unsigned *length) {
int exp;
int offset;
int size;
unsigned *ip;
unsigned intCount;
unsigned residue;
char *cp;
int i;
char ac;
exp = genRand(minExp, maxExp);
offset = genRand(MIN_OFFSET, MAX_OFFSET);
size = 1;
while(exp--) { size *= 10;
}
size += offset;
switch(type) {
case DT_Zero:
bzero(dataPool, size);
break;
case DT_ASCII:
ac = MIN_ASCII;
cp = dataPool;
for(i=0; i<size; i++) {
*cp++ = ac++;
if(ac > MAX_ASCII) {
ac = MIN_ASCII;
}
}
break;
case DT_Random:
intCount = size >> 2;
ip = (unsigned *)dataPool;
for(i=0; i<intCount; i++) {
*ip++ = random();
}
residue = size & 0x3;
cp = (unsigned char *)ip;
for(i=0; i<residue; i++) {
*cp++ = (unsigned char)random();
}
break;
}
*length = size;
return dataPool;
}
static int sigError()
{
char resp[100];
printf("Attach via debugger for more info.\n");
printf("a to abort, c to continue: ");
gets(resp);
return (resp[0] != 'c');
}
#define LOG_FREQ 200
int doTest(unsigned char *ptext,
unsigned ptextLen,
unsigned char *passwd,
unsigned passwdLen,
int verbose,
int quiet,
unsigned depth,
unsigned incr,
int doECDSA,
int doECDSAVfy) {
feePubKey *pubKey;
unsigned char *sig;
unsigned sigLen;
unsigned byte;
unsigned char origData;
unsigned char bits;
feeReturn frtn;
pubKey = feePubKeyAlloc();
frtn = feePubKeyInitFromPrivDataDepth(pubKey,
passwd,
passwdLen,
depth,
1);
if(frtn) {
printf("feePubKeyInitFromPrivData returned %s\n",
feeReturnString(frtn));
return sigError();
}
#if CRYPTKIT_ECDSA_ENABLE
if(doECDSA) {
frtn = feePubKeyCreateECDSASignature(pubKey,
ptext,
ptextLen,
&sig,
&sigLen);
if(frtn) {
printf("feePubKeyCreateECDSASignature returned %s\n",
feeReturnString(frtn));
return sigError();
}
if(doECDSAVfy) {
frtn = feePubKeyVerifyECDSASignature(pubKey,
ptext,
ptextLen,
sig,
sigLen);
}
else {
frtn = feePubKeyVerifySignature(pubKey,
ptext,
ptextLen,
sig,
sigLen);
}
}
else {
#else
{
#endif
frtn = feePubKeyCreateSignature(pubKey,
ptext,
ptextLen,
&sig,
&sigLen);
if(frtn) {
printf("feePubKeyCreateSignature returned %s\n",
feeReturnString(frtn));
return sigError();
}
frtn = feePubKeyVerifySignature(pubKey,
ptext,
ptextLen,
sig,
sigLen);
}
if(frtn) {
printf("**Unexpected BAD signature\n");
return sigError();
}
for(byte=0; byte<ptextLen; byte += incr) {
if(!quiet && (verbose || ((byte % LOG_FREQ) == 0))) {
printf("....byte %d\n", byte);
}
origData = ptext[byte];
do {
bits = random() & 0xff;
} while(bits == 0);
ptext[byte] ^= bits;
#if CRYPTKIT_ECDSA_ENABLE
if(doECDSA && doECDSAVfy) {
frtn = feePubKeyVerifyECDSASignature(pubKey,
ptext,
ptextLen,
sig,
sigLen);
}
else {
#else
{
#endif
frtn = feePubKeyVerifySignature(pubKey,
ptext,
ptextLen,
sig,
sigLen);
}
if(frtn == FR_Success) {
printf("**Unexpected GOOD signature\n");
return sigError();
}
ptext[byte] = origData;
}
feePubKeyFree(pubKey);
return 0;
}
int main(int argc, char **argv)
{
int arg;
char *argp;
int loop;
unsigned char *ptext;
unsigned ptextLen;
unsigned char *passwd;
int doECDSA;
int doECDSAVfy;
unsigned passwdLen = PWD_LENGTH;
unsigned loops = LOOPS_DEF;
int seedSpec = 0;
unsigned seed;
int verbose = 0;
unsigned minExp = MIN_EXP;
unsigned maxExp = MAX_EXP;
int quiet = 0;
unsigned depth = DEPTH_DEFAULT;
unsigned incr = INCR_DEFAULT;
#if CRYPTKIT_ECDSA_ENABLE
int elGamalOnly = 0;
#else
int elGamalOnly = 1;
#endif
for(arg=1; arg<argc; arg++) {
argp = argv[arg];
switch(argp[0]) {
case 'l':
loops = atoi(&argp[2]);
break;
case 'n':
minExp = atoi(&argp[2]);
break;
case 'x':
maxExp = atoi(&argp[2]);
if(maxExp > MAX_EXP) {
usage(argv);
}
break;
case 'D':
depth = atoi(&argp[2]);
break;
case 'i':
incr = atoi(&argp[2]);
break;
case 's':
seed = atoi(&argp[2]);
seedSpec = 1;
break;
case 'p':
passwdLen = atoi(&argp[2]);
if(passwdLen == 0) {
usage(argv);
}
break;
case 'e':
elGamalOnly = 1;
break;
case 'v':
verbose = 1;
break;
case 'q':
quiet = 1;
break;
case 'h':
default:
usage(argv);
}
}
if(seedSpec == 0) {
time((long *)(&seed));
}
srandom(seed);
passwdPool = malloc(passwdLen);
dataPool = malloc(MAX_DATA_SIZE);
printf("Starting %s test: loops %d seed %d elGamalOnly %d depth %d\n",
argv[0], loops, seed, elGamalOnly, depth);
#if 0
{
char s[20];
printf("attach, then CR to continue: ");
gets(s);
}
#endif 0
for(loop=1; ; loop++) {
ptext = genData(minExp, maxExp, DT_Random, &ptextLen);
passwd = genPasswd(passwdLen);
if(elGamalOnly) {
doECDSA = 0;
doECDSAVfy = 0;
}
else {
if(loop & 1) {
doECDSA = 1;
if(loop & 2) {
doECDSAVfy = 1;
}
else {
doECDSAVfy = 0;
}
}
else {
doECDSA = 0;
doECDSAVfy = 0;
}
}
if(!quiet) {
printf("..loop %d text size %d ECDSA %d ECDSAVfy %d\n",
loop, ptextLen, doECDSA, doECDSAVfy);
}
if(doTest(ptext, ptextLen, passwd, passwdLen,
verbose, quiet, depth, incr,
doECDSA, doECDSAVfy)) {
exit(1);
}
if(loops && (loop == loops)) {
break;
}
}
if(!quiet) {
printf("%s test complete\n", argv[0]);
}
return 0;
}