#include "ckutilities.h"
#include "falloc.h"
#include "feeTypes.h"
#include "feeDebug.h"
#include "feeFunctions.h"
#include "byteRep.h"
#include "platform.h"
#include "curveParams.h"
#include <stdlib.h>
#ifdef NeXT
#include <libc.h>
#include <stdio.h>
#include <signal.h>
#include <sgtty.h>
#endif // NeXT
typedef struct {
feeReturn frtn;
const char *frtnString;
} frtnItem;
static const frtnItem frtnStrings[] = {
#ifndef NDEBUG
{ FR_Success, "Success" },
{ FR_BadPubKey, "Bad Public Key" },
{ FR_BadPubKeyString, "Bad Public Key String" },
{ FR_IncompatibleKey, "Incompatible key format" },
{ FR_IllegalDepth, "Illegal Depth" },
{ FR_BadUsageName, "Bad Usage Name" },
{ FR_BadSignatureFormat, "Bad Signature Format" },
{ FR_InvalidSignature, "Invalid Signature" },
{ FR_IllegalArg, "Illegal Argument" },
{ FR_BadCipherText, "Bad Ciphertext Format" },
{ FR_Unimplemented, "Unimplemented Function" },
{ FR_BadCipherFile, "Bad CipherFile Format" },
{ FR_BadEnc64, "Bad enc64 Format" },
{ FR_WrongSignatureType, "Wrong Signature Type" },
{ FR_BadKeyBlob, "Bad Key Blob" },
{ FR_IllegalCurve, "Bad curve type" },
{ FR_Internal, "Internal Library Error" },
{ FR_Memory, "Out of Memory" },
{ FR_ShortPrivData, "Insufficient Seed Data" },
#endif
{ (feeReturn) 0, NULL },
};
void initCryptKit(void)
{
#if GIANTS_VIA_STACK
curveParamsInitGiants();
#endif
}
void terminateCryptKit()
{
#if GIANTS_VIA_STACK
freeGiantStacks();
#endif
}
giant giant_with_data(const unsigned char *d, int len) {
int numDigits = BYTES_TO_GIANT_DIGITS(len);
giant result;
result = newGiant(numDigits);
deserializeGiant(d, result, len);
return result;
}
unsigned char *mem_from_giant(giant g,
unsigned *memLen)
{
unsigned char *cp;
unsigned numDigits = (g->sign < 0) ? -g->sign : g->sign;
*memLen = numDigits * GIANT_BYTES_PER_DIGIT;
cp = (unsigned char*) fmalloc(*memLen);
serializeGiant(g, cp, *memLen);
return cp;
}
extern const char *feeReturnString(feeReturn frtn)
{
const frtnItem *fi = frtnStrings;
while(fi->frtnString) {
if(fi->frtn == frtn) {
return fi->frtnString;
}
fi++;
}
return "Unknown Status";
}
#if FEE_DEBUG
void printGiant(const giant x)
{
int i;
printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
for(i=0; i<abs(x->sign); i++) {
printf("%u:", x->n[i]);
}
printf("\n");
}
void printGiantHex(const giant x)
{
int i;
printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
for(i=0; i<abs(x->sign); i++) {
printf("%x:", x->n[i]);
}
printf("\n");
}
void printGiantExp(const giant x)
{
int i;
int size = abs(x->sign);
printf("sign=%d cap=%d n[]=", x->sign, x->capacity);
for(i=0; i<size; i++) {
printf("%u ", x->n[i]);
if(i > 0) {
printf("* w^%d ", i);
}
if(i<(size-1)) {
printf("+ ");
}
}
printf("\n");
}
void printKey(const key k)
{
printf(" twist %d\n", k->twist);
printf(" x: ");
printGiant(k->x);
}
void printCurveParams(const curveParams *p)
{
const char *pt;
const char *ct;
switch(p->primeType) {
case FPT_Mersenne:
pt = "FPT_Mersenne";
break;
case FPT_FEE:
pt = "FPT_FEE";
break;
case FPT_General:
pt = "FPT_General";
break;
default:
pt = "UNKNOWN!";
break;
}
switch(p->curveType) {
case FCT_Montgomery:
ct = "FCT_Montgomery";
break;
case FCT_Weierstrass:
ct = "FCT_Weierstrass";
break;
case FCT_General:
ct = "FCT_General";
break;
default:
ct = "UNKNOWN!";
break;
}
printf(" q %d k %d primeType %s curveType %s\n",
p->q, p->k, pt, ct);
printf(" minBytes %d maxDigits %d\n", p->minBytes, p->maxDigits);
printf(" a : ");
printGiant(p->a);
printf(" b : ");
printGiant(p->b);
printf(" c : ");
printGiant(p->c);
printf(" basePrime : ");
printGiant(p->basePrime);
printf(" x1Plus : ");
printGiant(p->x1Plus);
printf(" x1Minus : ");
printGiant(p->x1Minus);
printf(" cOrderPlus : ");
printGiant(p->cOrderPlus);
printf(" cOrderMinus : ");
printGiant(p->cOrderMinus);
printf(" x1OrderPlus : ");
printGiant(p->x1OrderPlus);
printf(" x1OrderMinus: ");
printGiant(p->x1OrderMinus);
}
#else
void printGiant(const giant x) {}
void printGiantHex(const giant x) {}
void printGiantExp(const giant x) {}
void printKey(const key k) {}
void printCurveParams(const curveParams *p) {}
#endif
#if defined(NeXT) && !defined(WIN32)
void getpassword(const char *prompt, char *pbuf)
{
struct sgttyb ttyb;
int flags;
register char *p;
register int c;
FILE *fi;
void (*sig)(int);
if ((fi = fdopen(open("/dev/tty", 2, 0), "r")) == NULL)
fi = stdin;
else
setbuf(fi, (char *)NULL);
sig = signal(SIGINT, SIG_IGN);
ioctl(fileno(fi), TIOCGETP, &ttyb);
flags = ttyb.sg_flags;
ttyb.sg_flags &= ~ECHO;
ioctl(fileno(fi), TIOCSETP, &ttyb);
fprintf(stderr, "%s", prompt); fflush(stderr);
for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
if (p < &pbuf[PHRASELEN-1])
*p++ = c;
}
*p = '\0';
fprintf(stderr, "\n"); fflush(stderr);
ttyb.sg_flags = flags;
ioctl(fileno(fi), TIOCSETP, &ttyb);
(void)signal(SIGINT, sig);
if (fi != stdin)
fclose(fi);
}
#endif // NeXT
void serializeGiant(giant g,
unsigned char *cp,
unsigned numBytes)
{
unsigned digitDex;
unsigned numDigits = BYTES_TO_GIANT_DIGITS(numBytes);
giantDigit digit;
unsigned char *ptr;
unsigned digitByte;
int size = abs(g->sign);
if(numBytes == 0) {
return;
}
if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) {
CKRaise("serializeGiant: CAPACITY EXCEEDED!\n");
}
for(digitDex=size; digitDex<numDigits; digitDex++) {
g->n[digitDex] = 0;
}
digitDex = 0;
ptr = &cp[numBytes - 1];
do {
digit = g->n[digitDex++];
for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
*ptr-- = (unsigned char)digit;
if(--numBytes == 0) {
break;
}
digit >>= 8;
}
} while(numBytes != 0);
}
void deserializeGiant(const unsigned char *cp,
giant g,
unsigned numBytes)
{
unsigned numDigits;
giantDigit digit;
int digitDex;
unsigned digitByte;
const unsigned char *ptr;
if(numBytes == 0) {
g->sign = 0;
return;
}
numDigits = (numBytes + GIANT_BYTES_PER_DIGIT - 1) /
GIANT_BYTES_PER_DIGIT;
if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) {
CKRaise("deserializeGiant: CAPACITY EXCEEDED!\n");
}
digitDex = 0;
ptr = &cp[numBytes - 1];
do {
digit = 0;
for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) {
digit |= (*ptr-- << (8 * digitByte));
if(--numBytes == 0) {
break;
}
}
g->n[digitDex++] = digit;
} while (numBytes != 0);
g->sign = numDigits;
gtrimSign(g);
}