9a0042c61e
git-svn-id: svn://opensvn.adaptivecomputing.com/maui/trunk@2 3f5042e3-fb1d-0410-be18-d6ca2573e517
2013 lines
38 KiB
C
2013 lines
38 KiB
C
/* HEADER */
|
|
|
|
#include "moab.h"
|
|
#include "moab-proto.h"
|
|
|
|
extern mlog_t mlog;
|
|
|
|
extern msched_t MSched;
|
|
extern m64_t M64;
|
|
|
|
extern const char *MCSAlgoType[];
|
|
extern const char *MBool[];
|
|
|
|
|
|
/* DES config */
|
|
|
|
#define MAX_MDESCKSUM_ITERATION 4
|
|
|
|
unsigned short __MSecDoCRC(unsigned short,unsigned char);
|
|
int __MSecPSDES(unsigned int *,unsigned int *);
|
|
|
|
/* END DES config */
|
|
|
|
|
|
|
|
/* HMAC config */
|
|
|
|
#ifndef SHA_DIGESTSIZE
|
|
# define SHA_DIGESTSIZE 20
|
|
#endif
|
|
|
|
#ifndef SHA_BLOCKSIZE
|
|
# define SHA_BLOCKSIZE 64
|
|
#endif
|
|
|
|
typedef struct {
|
|
MUINT4 state[5];
|
|
MUINT4 count[2];
|
|
unsigned char buffer[64];
|
|
} SHA1_CTX;
|
|
|
|
typedef union
|
|
{
|
|
unsigned char c[64];
|
|
MUINT4 l[16];
|
|
} CHAR64LONG16;
|
|
|
|
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
|
|
|
/* blk0() and blk() perform the initial expand. */
|
|
/* I got the idea of expanding during the round function from SSLeay */
|
|
|
|
#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
|
|
# if defined(__BYTE_ORDER)
|
|
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
# define SHA1_LITTLE_ENDIAN 1
|
|
# endif
|
|
# if __BYTE_ORDER == __BIG_ENDIAN
|
|
# define SHA1_BIG_ENDIAN 1
|
|
# endif
|
|
# endif
|
|
|
|
# if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
|
|
# if defined(__AIX43) || defined(__AIX51) || defined(__HPUX) || defined(__IRIX) || defined(__SOLARIS)
|
|
# define SHA1_BIG_ENDIAN
|
|
# else
|
|
# define SHA1_LITTLE_ENDIAN
|
|
# endif
|
|
# endif
|
|
#endif /* !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) */
|
|
|
|
|
|
#if defined(SHA1_LITTLE_ENDIAN) && defined(SHA1_BIG_ENDIAN)
|
|
#error "So, which is it: big endian or little endian?"
|
|
#endif
|
|
|
|
#if defined(SHA1_LITTLE_ENDIAN)
|
|
# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|
|
|(rol(block->l[i],8)&0x00FF00FF))
|
|
# define SHA1_ENDIAN_KNOWN
|
|
#else
|
|
# define blk0(i) block->l[i]
|
|
# define SHA1_ENDIAN_KNOWN
|
|
#endif
|
|
|
|
#if !defined(SHA1_ENDIAN_KNOWN)
|
|
#error "ENDIANness of system not defined."
|
|
#endif
|
|
|
|
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
|
^block->l[(i+2)&15]^block->l[i&15],1))
|
|
|
|
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
|
|
|
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
|
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
|
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
|
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
|
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
|
|
|
|
|
int MSecHMACGetDigest(unsigned char *,int,unsigned char *,int,char *,int,char *,mbool_t,mbool_t);
|
|
|
|
static void __MSecSHA1Transform(MUINT4 S[5],unsigned char B[64]);
|
|
void __MSecSHA1Init(SHA1_CTX *);
|
|
void __MSecSHA1Update(SHA1_CTX *,unsigned char *,MUINT4);
|
|
void __MSecSHA1Final(unsigned char D[20],SHA1_CTX *);
|
|
void __MSecHMACTruncate (char *,char *,int);
|
|
|
|
/* END HMAC config */
|
|
|
|
|
|
/* MD5 config */
|
|
|
|
#ifdef __MMD5
|
|
#include <openssl/md5.h>
|
|
|
|
#ifdef MD5_DIGEST_LENGTH
|
|
#define MMD5_DIGESTSIZE MD5_DIGEST_LENGTH
|
|
#else /* MD5_DIGEST_LENGTH */
|
|
#define MMD5_DIGESTSIZE 0
|
|
#endif /* MD5_DIGEST_LENGTH */
|
|
#else /* __MMD5 */
|
|
#define MMD5_DIGESTSIZE 0
|
|
#endif /* __MMD5 */
|
|
|
|
int MSecMD5GetDigest(char *,int,char *,int,char *,int);
|
|
|
|
/* END MD5 config */
|
|
|
|
|
|
|
|
#ifndef __M32COMPAT
|
|
|
|
int M64Init(
|
|
|
|
m64_t *M) /* I (modified) */
|
|
|
|
{
|
|
if (sizeof(int) == 4)
|
|
{
|
|
/* 32 bit operation */
|
|
|
|
M->Is64 = FALSE;
|
|
|
|
M->INTBC = M32INTBITS;
|
|
M->INTLBC = M32INTLBITS;
|
|
M->MIntSize = M32INTSIZE;
|
|
M->IntShift = M32INTSHIFT;
|
|
}
|
|
else
|
|
{
|
|
/* 64 bit operation */
|
|
|
|
M->Is64 = TRUE;
|
|
|
|
M->INTBC = M64INTBITS;
|
|
M->INTLBC = M64INTLBITS;
|
|
M->MIntSize = M64INTSIZE;
|
|
M->IntShift = M64INTSHIFT;
|
|
}
|
|
|
|
MDB(5,fSTRUCT) MLog("INFO: 64Bit enabled: %s UINT4[%d] UINT8[%d]\n",
|
|
MBool[M->Is64],
|
|
sizeof(MUINT4),
|
|
sizeof(MUINT8));
|
|
|
|
return(SUCCESS);
|
|
} /* END M64Init() */
|
|
|
|
#endif /* !__M32COMPAT */
|
|
|
|
|
|
|
|
int MSecGetChecksum(
|
|
|
|
char *Buf, /* I */
|
|
int BufSize, /* I */
|
|
char *Checksum, /* O */
|
|
char *Digest, /* O (optional) */
|
|
enum MChecksumAlgoEnum Algo, /* I */
|
|
char *CSKeyString) /* I */
|
|
|
|
{
|
|
#ifndef __MPROD
|
|
const char *FName = "MSecGetChecksum";
|
|
|
|
MDB(5,fSTRUCT) MLog("%s(Buf,%d,Checksum,%s,CSKey)\n",
|
|
FName,
|
|
BufSize,
|
|
MCSAlgoType[Algo]);
|
|
#endif /* !__MPROD */
|
|
|
|
if ((Buf == NULL) || (Checksum == NULL) || (CSKeyString == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
switch(Algo)
|
|
{
|
|
case mcsaHMAC:
|
|
|
|
{
|
|
MSecHMACGetDigest(
|
|
(unsigned char *)CSKeyString,
|
|
strlen(CSKeyString),
|
|
(unsigned char *)Buf,
|
|
strlen(Buf),
|
|
Checksum,
|
|
SHA_DIGESTSIZE,
|
|
NULL,
|
|
FALSE,
|
|
FALSE);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaHMAC64:
|
|
|
|
{
|
|
MSecHMACGetDigest(
|
|
(unsigned char *)CSKeyString,
|
|
strlen(CSKeyString),
|
|
(unsigned char *)Buf,
|
|
strlen(Buf),
|
|
Checksum,
|
|
SHA_DIGESTSIZE,
|
|
Digest,
|
|
TRUE,
|
|
TRUE);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaMD5:
|
|
|
|
{
|
|
MSecMD5GetDigest(
|
|
CSKeyString,
|
|
strlen(CSKeyString),
|
|
Buf,
|
|
strlen(Buf),
|
|
Checksum,
|
|
MMD5_DIGESTSIZE);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaRemote:
|
|
|
|
{
|
|
char CmdLine[MMAX_LINE];
|
|
|
|
sprintf(CmdLine,"mauth \"%s\"",
|
|
Buf);
|
|
|
|
#ifndef __M32COMPAT
|
|
if (MUReadPipe(CmdLine,NULL,Checksum,MMAX_LINE) == FAILURE)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
#endif /* __M32COMPAT */
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaDES:
|
|
default:
|
|
|
|
{
|
|
unsigned int crc;
|
|
unsigned int lword;
|
|
unsigned int rword;
|
|
|
|
int index;
|
|
|
|
unsigned int SKey;
|
|
|
|
SKey = (unsigned int)strtoul(CSKeyString,NULL,0);
|
|
|
|
crc = 0;
|
|
|
|
for (index = 0;index < BufSize;index++)
|
|
{
|
|
crc = (unsigned int)__MSecDoCRC((unsigned short)crc,Buf[index]);
|
|
}
|
|
|
|
lword = crc;
|
|
rword = SKey;
|
|
|
|
__MSecPSDES(&lword,&rword);
|
|
|
|
Checksum[0] = '\0';
|
|
|
|
sprintf(Checksum,"%08x%08x",
|
|
(int)lword,
|
|
(int)rword);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
} /* END switch(Algo) */
|
|
|
|
/* NOTE: enable logging only for unit testing. MUST DISABLE FOR PRODUCTION */
|
|
|
|
/*
|
|
MDB(8,fSTRUCT) MLog("INFO: checksum '%s' calculated for %d byte buffer '%s' using seed %x\n",
|
|
Checksum,
|
|
BufSize,
|
|
Buf,
|
|
SKey);
|
|
*/
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecGetChecksum() */
|
|
|
|
|
|
|
|
|
|
int MSecGetChecksum2(
|
|
|
|
char *Buf1, /* I */
|
|
int BufSize1, /* I */
|
|
char *Buf2, /* I */
|
|
int BufSize2, /* I */
|
|
char *Checksum, /* O */
|
|
char *Digest, /* O (optional) */
|
|
enum MChecksumAlgoEnum Algo, /* I */
|
|
char *CSKeyString) /* I */
|
|
|
|
{
|
|
#ifndef __MPROD
|
|
const char *FName = "MSecGetChecksum2";
|
|
|
|
MDB(5,fSTRUCT) MLog("%s(Buf1,%d,Buf2,%d,Checksum,%s,CSKey)\n",
|
|
FName,
|
|
BufSize1,
|
|
BufSize2,
|
|
MCSAlgoType[Algo]);
|
|
#endif /* !__MPROD */
|
|
|
|
if ((Buf1 == NULL) || (Buf2 == NULL) || (Checksum == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
switch(Algo)
|
|
{
|
|
case mcsaHMAC:
|
|
|
|
{
|
|
char *ptr;
|
|
|
|
/* NOTE: merge header and data */
|
|
|
|
ptr = (char *)malloc(BufSize1 + BufSize2);
|
|
|
|
strcpy(ptr,Buf1);
|
|
strcpy(ptr + BufSize1,Buf2);
|
|
|
|
MSecHMACGetDigest(
|
|
(unsigned char *)CSKeyString,
|
|
strlen(CSKeyString),
|
|
(unsigned char *)ptr,
|
|
BufSize1 + BufSize2,
|
|
Checksum,
|
|
SHA_DIGESTSIZE,
|
|
NULL,
|
|
FALSE,
|
|
FALSE);
|
|
|
|
free(ptr);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaHMAC64:
|
|
|
|
{
|
|
char *ptr;
|
|
|
|
/* NOTE: merge header and data */
|
|
|
|
ptr = (char *)malloc(BufSize1 + BufSize2);
|
|
|
|
strcpy(ptr,Buf1);
|
|
strcpy(ptr + BufSize1,Buf2);
|
|
|
|
MSecHMACGetDigest(
|
|
(unsigned char *)CSKeyString,
|
|
strlen(CSKeyString),
|
|
(unsigned char *)ptr,
|
|
strlen(ptr),
|
|
Checksum,
|
|
SHA_DIGESTSIZE,
|
|
Digest,
|
|
TRUE,
|
|
TRUE);
|
|
|
|
free(ptr);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaMD5:
|
|
|
|
{
|
|
char *ptr;
|
|
|
|
/* NOTE: merge header and data */
|
|
|
|
ptr = (char *)malloc(BufSize1 + BufSize2);
|
|
|
|
strcpy(ptr,Buf1);
|
|
strcpy(ptr + BufSize1,Buf2);
|
|
|
|
MSecMD5GetDigest(
|
|
CSKeyString,
|
|
strlen(CSKeyString),
|
|
ptr,
|
|
BufSize1 + BufSize2,
|
|
Checksum,
|
|
MMD5_DIGESTSIZE);
|
|
|
|
free(ptr);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
|
|
case mcsaDES:
|
|
default:
|
|
|
|
{
|
|
unsigned int crc;
|
|
unsigned int lword;
|
|
unsigned int rword;
|
|
|
|
unsigned int Seed;
|
|
|
|
int index;
|
|
|
|
Seed = (unsigned int)strtoul(CSKeyString,NULL,0);
|
|
|
|
crc = 0;
|
|
|
|
for (index = 0;index < BufSize1;index++)
|
|
{
|
|
crc = (unsigned int)__MSecDoCRC((unsigned short)crc,Buf1[index]);
|
|
} /* END for (index) */
|
|
|
|
for (index = 0;index < BufSize2;index++)
|
|
{
|
|
crc = (unsigned int)__MSecDoCRC((unsigned short)crc,Buf2[index]);
|
|
} /* END for (index) */
|
|
|
|
lword = crc;
|
|
rword = Seed;
|
|
|
|
__MSecPSDES(&lword,&rword);
|
|
|
|
sprintf(Checksum,"%08x%08x",
|
|
(int)lword,
|
|
(int)rword);
|
|
} /* END BLOCK */
|
|
|
|
break;
|
|
} /* END switch(Algo) */
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecGetChecksum2() */
|
|
|
|
|
|
|
|
|
|
int MSecHMACGetDigest(
|
|
|
|
unsigned char *CSKeyString, /* I */
|
|
int CSKeyLen, /* I */
|
|
unsigned char *DataString, /* I */
|
|
int DataLen, /* I */
|
|
char *CSString, /* O */
|
|
int MaxCSStringLen, /* I */
|
|
char *DigestString, /* O (optional) */
|
|
mbool_t TwoPass, /* I */
|
|
mbool_t Use64BitEncoding) /* I */
|
|
|
|
{
|
|
SHA1_CTX ictx;
|
|
SHA1_CTX octx;
|
|
|
|
unsigned char isha[SHA_DIGESTSIZE];
|
|
unsigned char osha[SHA_DIGESTSIZE];
|
|
unsigned char key[SHA_DIGESTSIZE];
|
|
unsigned char buf[SHA_BLOCKSIZE];
|
|
unsigned char osha2[SHA_DIGESTSIZE];
|
|
|
|
int index;
|
|
|
|
char tmpBuf[SHA_DIGESTSIZE << 1];
|
|
|
|
unsigned char *DPtr;
|
|
|
|
int DLen;
|
|
|
|
#ifndef __MPROD
|
|
const char *FName = "MSecHMACGetDigest";
|
|
|
|
MDB(6,fSTRUCT) MLog("%s(%s,%d,%s,%d,CSString,%d,DigestString,%s,%s)\n",
|
|
FName,
|
|
(CSKeyString != NULL) ? (char *)CSKeyString : "NULL",
|
|
CSKeyLen,
|
|
(DataString != NULL) ? (char *)DataString : "NULL",
|
|
DataLen,
|
|
MaxCSStringLen,
|
|
MBool[TwoPass],
|
|
MBool[Use64BitEncoding]);
|
|
#endif /* !__MPROD */
|
|
|
|
/* create hash */
|
|
|
|
if (TwoPass == TRUE)
|
|
{
|
|
SHA1_CTX tctx;
|
|
|
|
__MSecSHA1Init(&tctx);
|
|
__MSecSHA1Update(&tctx,DataString,DataLen);
|
|
__MSecSHA1Final(osha2,&tctx);
|
|
|
|
if (DigestString != NULL)
|
|
{
|
|
/* encode digest */
|
|
|
|
if (Use64BitEncoding == TRUE)
|
|
{
|
|
MSecBufTo64BitEncoding(
|
|
(char *)osha2,
|
|
SHA_DIGESTSIZE,
|
|
DigestString);
|
|
}
|
|
else
|
|
{
|
|
MSecBufToHexEncoding(
|
|
(char *)osha2,
|
|
SHA_DIGESTSIZE,
|
|
DigestString);
|
|
}
|
|
} /* END if (DigestValue != NULL) */
|
|
|
|
DPtr = osha2;
|
|
DLen = SHA_DIGESTSIZE;
|
|
} /* END if (CSKeyString == NULL) */
|
|
else
|
|
{
|
|
DPtr = DataString;
|
|
DLen = DataLen;
|
|
}
|
|
|
|
if (CSKeyLen > SHA_BLOCKSIZE)
|
|
{
|
|
SHA1_CTX tctx;
|
|
|
|
__MSecSHA1Init(&tctx);
|
|
__MSecSHA1Update(&tctx,CSKeyString,CSKeyLen);
|
|
__MSecSHA1Final(key,&tctx);
|
|
|
|
CSKeyString = key;
|
|
CSKeyLen = SHA_DIGESTSIZE;
|
|
}
|
|
|
|
/**** inner digest ****/
|
|
|
|
__MSecSHA1Init(&ictx) ;
|
|
|
|
/* pad the key for inner digest */
|
|
|
|
for (index = 0;index < CSKeyLen;index++)
|
|
{
|
|
buf[index] = CSKeyString[index] ^ 0x36;
|
|
}
|
|
|
|
for (index = CSKeyLen;index < SHA_BLOCKSIZE;index++)
|
|
{
|
|
buf[index] = 0x36;
|
|
}
|
|
|
|
__MSecSHA1Update(&ictx,buf,SHA_BLOCKSIZE);
|
|
|
|
__MSecSHA1Update(&ictx,DPtr,DLen);
|
|
|
|
__MSecSHA1Final(isha,&ictx);
|
|
|
|
/**** outer digest ****/
|
|
|
|
__MSecSHA1Init(&octx) ;
|
|
|
|
/* pad the key for outer digest */
|
|
|
|
for (index = 0;index < CSKeyLen;index++)
|
|
{
|
|
buf[index] = CSKeyString[index] ^ 0x5C;
|
|
}
|
|
|
|
for (index = CSKeyLen;index < SHA_BLOCKSIZE;index++)
|
|
{
|
|
buf[index] = 0x5C;
|
|
}
|
|
|
|
__MSecSHA1Update(&octx,buf,SHA_BLOCKSIZE);
|
|
__MSecSHA1Update(&octx,isha,SHA_DIGESTSIZE);
|
|
|
|
__MSecSHA1Final(osha,&octx);
|
|
|
|
/* truncate and encode digest */
|
|
|
|
__MSecHMACTruncate(
|
|
(char *)osha,
|
|
tmpBuf,
|
|
MIN(SHA_DIGESTSIZE,MaxCSStringLen));
|
|
|
|
if (Use64BitEncoding == TRUE)
|
|
{
|
|
MSecBufTo64BitEncoding(
|
|
tmpBuf,
|
|
MIN(SHA_DIGESTSIZE,MaxCSStringLen),
|
|
CSString);
|
|
}
|
|
else
|
|
{
|
|
MSecBufToHexEncoding(
|
|
tmpBuf,
|
|
MIN(SHA_DIGESTSIZE,MaxCSStringLen),
|
|
CSString);
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecHMACGetDigest() */
|
|
|
|
|
|
|
|
|
|
void __MSecHMACTruncate(
|
|
|
|
char *d1, /* data to be truncated */
|
|
char *d2, /* truncated data */
|
|
int len) /* length in bytes to keep */
|
|
|
|
{
|
|
int i;
|
|
|
|
#ifndef __MPROD
|
|
const char *FName = "__MSecHMACTruncate";
|
|
|
|
MDB(9,fSTRUCT) MLog("%s(d1,d2,%d)\n",
|
|
FName,
|
|
len);
|
|
#endif /* !__MPROD */
|
|
|
|
for (i = 0;i < len;i++)
|
|
{
|
|
d2[i] = d1[i];
|
|
} /* END for (i) */
|
|
|
|
return;
|
|
} /* END __MSecHMACTruncate() */
|
|
|
|
|
|
|
|
|
|
|
|
static void __MSecSHA1Transform(
|
|
|
|
MUINT4 state[5], /* I */
|
|
unsigned char buffer[64]) /* I */
|
|
|
|
{
|
|
/* hash a single 512-bit block. This is the core of the algorithm. */
|
|
|
|
MUINT4 a,b,c,d,e;
|
|
|
|
unsigned char workspace[64];
|
|
|
|
CHAR64LONG16 *block = (CHAR64LONG16*)workspace;
|
|
|
|
#ifndef __BMPROD
|
|
const char *FName = "__MSecSHA1Transform";
|
|
|
|
MDB(9,fSTRUCT) MLog("%s(context)\n",
|
|
FName);
|
|
#endif /* !__BMPROD */
|
|
|
|
memcpy(block,buffer,64);
|
|
|
|
/* copy context->state[] to working vars */
|
|
|
|
a = state[0];
|
|
b = state[1];
|
|
c = state[2];
|
|
d = state[3];
|
|
e = state[4];
|
|
|
|
/* 4 rounds of 20 operations each. Loop unrolled. */
|
|
|
|
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
|
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
|
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
|
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
|
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
|
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
|
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
|
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
|
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
|
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
|
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
|
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
|
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
|
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
|
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
|
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
|
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
|
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
|
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
|
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
|
|
|
/* add the working vars back into context.state[] */
|
|
|
|
state[0] += a;
|
|
state[1] += b;
|
|
state[2] += c;
|
|
state[3] += d;
|
|
state[4] += e;
|
|
|
|
/* clear variables */
|
|
|
|
a = b = c = d = e = 0;
|
|
|
|
memset(block,0,64);
|
|
|
|
return;
|
|
} /* END __MSecSHA1Transform() */
|
|
|
|
|
|
|
|
|
|
void __MSecSHA1Init(
|
|
|
|
SHA1_CTX* context) /* O */
|
|
|
|
{
|
|
#ifndef __MPROD
|
|
const char *FName = "__MSecSHA1Init";
|
|
|
|
MDB(9,fSTRUCT) MLog("%s(context)\n",
|
|
FName);
|
|
#endif /* !__MPROD */
|
|
|
|
/* initialize new context */
|
|
|
|
/* SHA1 initialization constants */
|
|
|
|
context->state[0] = 0x67452301;
|
|
context->state[1] = 0xEFCDAB89;
|
|
context->state[2] = 0x98BADCFE;
|
|
context->state[3] = 0x10325476;
|
|
context->state[4] = 0xC3D2E1F0;
|
|
context->count[0] = context->count[1] = 0;
|
|
|
|
return;
|
|
} /* END __MSecSHA1Init() */
|
|
|
|
|
|
|
|
|
|
|
|
void __MSecSHA1Update(
|
|
|
|
SHA1_CTX *Context,
|
|
unsigned char *Data,
|
|
MUINT4 DataLen)
|
|
|
|
{
|
|
MUINT4 i,j;
|
|
|
|
#ifndef __MPROD
|
|
const char *FName = "__MSecSHA1Update";
|
|
|
|
MDB(10,fSTRUCT) MLog("%s(Context,Data,DataLen)\n",
|
|
FName);
|
|
#endif /* !__MPROD */
|
|
|
|
j = (Context->count[0] >> 3) & 63;
|
|
|
|
if ((Context->count[0] += DataLen << 3) < (DataLen << 3))
|
|
Context->count[1]++;
|
|
|
|
Context->count[1] += (DataLen >> 29);
|
|
|
|
if ((j + DataLen) > 63)
|
|
{
|
|
i = 64 - j;
|
|
|
|
memcpy(&Context->buffer[j],Data,i);
|
|
|
|
__MSecSHA1Transform(Context->state,Context->buffer);
|
|
|
|
for (;i + 63 < DataLen;i += 64)
|
|
{
|
|
__MSecSHA1Transform(Context->state, &Data[i]);
|
|
} /* END for() */
|
|
|
|
j = 0;
|
|
}
|
|
else
|
|
{
|
|
i = 0;
|
|
}
|
|
|
|
memcpy(&Context->buffer[j],&Data[i],DataLen - i);
|
|
|
|
return;
|
|
} /* END __MSecSHA1Update() */
|
|
|
|
|
|
|
|
|
|
|
|
void __MSecSHA1Final(
|
|
|
|
unsigned char digest[20],
|
|
SHA1_CTX *context)
|
|
|
|
{
|
|
/* add padding and return the message digest. */
|
|
|
|
MUINT4 i;
|
|
unsigned char finalcount[8];
|
|
|
|
#ifndef __MPROD
|
|
const char *FName = "__MSecSHA1Final";
|
|
|
|
MDB(9,fSTRUCT) MLog("%s(digest,context)\n",
|
|
FName);
|
|
#endif /* !__MPROD */
|
|
|
|
for (i = 0;i < 8;i++)
|
|
{
|
|
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
|
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
|
} /* END for (i) */
|
|
|
|
__MSecSHA1Update(context,(unsigned char *)"\200",1);
|
|
|
|
while ((context->count[0] & 504) != 448)
|
|
{
|
|
__MSecSHA1Update(context, (unsigned char *)"\0", 1);
|
|
}
|
|
|
|
__MSecSHA1Update(context,finalcount,8);
|
|
|
|
for (i = 0;i < 20;i++)
|
|
{
|
|
digest[i] = (unsigned char)
|
|
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
|
} /* END for (i) */
|
|
|
|
/* reset variables */
|
|
|
|
i = 0;
|
|
|
|
memset(context->buffer,0,64);
|
|
memset(context->state,0,20);
|
|
memset(context->count,0,8);
|
|
memset(finalcount,0,8);
|
|
|
|
return;
|
|
} /* END __MSecSHA1Final() */
|
|
|
|
|
|
|
|
|
|
int MSecMD5GetDigest(
|
|
|
|
char *CSKeyString, /* I */
|
|
int CSKeyLen, /* I */
|
|
char *DataString, /* I */
|
|
int DataLen, /* I */
|
|
char *CSString, /* O */
|
|
int MaxCSStringLen) /* O */
|
|
|
|
{
|
|
int index;
|
|
int len;
|
|
|
|
char tmpBuf[MMAX_BUFFER];
|
|
|
|
char MD5Sum[MMD5_DIGESTSIZE + 2];
|
|
|
|
char *ptr = NULL;
|
|
|
|
#ifndef __MPROD
|
|
const char *FName = "MSecMD5GetDigest";
|
|
|
|
MDB(2,fSTRUCT) MLog("%s(CSKeyString,CSKeyLen,DString,DLen,CSString,MaxCSLen)\n",
|
|
FName);
|
|
#endif /* !__MPROD */
|
|
|
|
if ((CSKeyString == NULL) ||
|
|
(DataString == NULL) ||
|
|
(CSString == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
/* NOTE: MD5(SrcBuf,strlen(SrcBuf),tmpLine); */
|
|
|
|
CSString[0] = '\0';
|
|
|
|
len = strlen(CSKeyString) + 1 + strlen(DataString);
|
|
|
|
sprintf(tmpBuf,"%s%s",
|
|
DataString,
|
|
CSKeyString);
|
|
|
|
#ifdef __MMD5
|
|
ptr = MD5(
|
|
(unsigned char *)tmpBuf,
|
|
(unsigned long)strlen(tmpBuf),
|
|
MD5Sum);
|
|
#endif /* __MMD5 */
|
|
|
|
if (ptr == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
for (index = 0;index < MMD5_DIGESTSIZE;index++)
|
|
{
|
|
sprintf(CSString,"%s%02x",
|
|
CSString,
|
|
(unsigned char)MD5Sum[index]);
|
|
} /* END for (index) */
|
|
|
|
strcat(CSString,"\n");
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecMD5GetDigest() */
|
|
|
|
|
|
|
|
|
|
int __MSecPSDES(
|
|
|
|
unsigned int *lword,
|
|
unsigned int *irword)
|
|
|
|
{
|
|
int index;
|
|
|
|
unsigned int ia;
|
|
unsigned int ib;
|
|
unsigned int iswap;
|
|
unsigned int itmph;
|
|
unsigned int itmpl;
|
|
|
|
static unsigned int c1[MAX_MDESCKSUM_ITERATION] = {
|
|
(unsigned int)0xcba4e531,
|
|
(unsigned int)0x537158eb,
|
|
(unsigned int)0x145cdc3c,
|
|
(unsigned int)0x0d3fdeb2 };
|
|
|
|
static unsigned int c2[MAX_MDESCKSUM_ITERATION] = {
|
|
(unsigned int)0x12be4590,
|
|
(unsigned int)0xab54ce58,
|
|
(unsigned int)0x6954c7a6,
|
|
(unsigned int)0x15a2ca46 };
|
|
|
|
itmph = 0;
|
|
itmpl = 0;
|
|
|
|
for (index = 0;index < MAX_MDESCKSUM_ITERATION;index++)
|
|
{
|
|
iswap = *irword;
|
|
|
|
ia = iswap ^ c1[index];
|
|
|
|
itmpl = ia & 0xffff;
|
|
itmph = ia >> 16;
|
|
|
|
ib = (itmpl * itmpl) + ~(itmph * itmph);
|
|
ia = (ib >> 16) | ((ib & 0xffff) << 16);
|
|
|
|
*irword = (*lword) ^ ((ia ^ c2[index]) + (itmpl * itmph));
|
|
|
|
*lword = iswap;
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END __MSecPSDES() */
|
|
|
|
|
|
|
|
|
|
unsigned short __MSecDoCRC(
|
|
|
|
unsigned short crc,
|
|
unsigned char val)
|
|
|
|
{
|
|
int index;
|
|
|
|
unsigned int ans;
|
|
|
|
ans = (crc ^ val << 8);
|
|
|
|
for (index = 0;index < 8;index++)
|
|
{
|
|
if (ans & 0x8000)
|
|
ans = (ans << 1) ^ 4129;
|
|
else
|
|
ans <<= 1;
|
|
} /* END for (index) */
|
|
|
|
return((unsigned short)ans);
|
|
} /* END __MSecDoCRC() */
|
|
|
|
|
|
|
|
|
|
int MSecTestChecksum(
|
|
|
|
char *TLine) /* I */
|
|
|
|
{
|
|
char *CSKey;
|
|
char *Msg;
|
|
char *AType;
|
|
|
|
char *TokPtr;
|
|
|
|
char CSBuf[MMAX_LINE];
|
|
char Digest[MMAX_LINE];
|
|
|
|
int rc;
|
|
|
|
enum MChecksumAlgoEnum AIndex;
|
|
|
|
if (TLine == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
/* FORMAT: <KEY>,<ALGO>,<MSG> */
|
|
|
|
CSKey = MUStrTok(TLine,",",&TokPtr);
|
|
AType = MUStrTok(NULL,",",&TokPtr);
|
|
Msg = MUStrTok(NULL,"\n",&TokPtr);
|
|
|
|
AIndex = (enum MChecksumAlgoEnum)MUGetIndex(AType,MCSAlgoType,FALSE,0);
|
|
|
|
Digest[0] = '\0';
|
|
|
|
rc = MSecGetChecksum(
|
|
Msg,
|
|
strlen(Msg),
|
|
CSBuf,
|
|
Digest,
|
|
AIndex,
|
|
CSKey);
|
|
|
|
fprintf(stderr,"CS: '%s'/'%s'\n",
|
|
CSBuf,
|
|
Digest);
|
|
|
|
exit(rc);
|
|
|
|
/*NOTREACHED*/
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecTestChecksum() */
|
|
|
|
|
|
|
|
|
|
int MSecBufToHexEncoding(
|
|
|
|
char *IBuf, /* I */
|
|
int IBufLen, /* I */
|
|
char *OBuf) /* O */
|
|
|
|
{
|
|
int index;
|
|
|
|
if ((IBuf == NULL) || (OBuf == NULL))
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
OBuf[0] = '\0';
|
|
|
|
for (index = 0;index < IBufLen;index++)
|
|
{
|
|
sprintf(OBuf,"%s%02x",
|
|
OBuf,
|
|
(unsigned char)IBuf[index]);
|
|
} /* END for (index) */
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecBufToHexEncoding() */
|
|
|
|
|
|
|
|
|
|
static char CList[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
|
|
static char CDList[256] = {
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,62, 00,00,00,63,
|
|
52,53,54,55, 56,57,58,59, 60,61,00,00, 00,00,00,00,
|
|
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
|
|
15,16,17,18, 19,20,21,22, 23,24,25,00, 00,00,00,00,
|
|
00,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
|
41,42,43,44, 45,46,47,48, 49,50,51,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00,
|
|
00,00,00,00, 00,00,00,00, 00,00,00,00, 00,00,00,00, };
|
|
|
|
|
|
int MSecBufTo64BitEncoding(
|
|
|
|
char *IBuf, /* I */
|
|
int IBufLen, /* I */
|
|
char *OBuf) /* O */
|
|
|
|
{
|
|
int index;
|
|
int cindex;
|
|
|
|
int block;
|
|
int slack;
|
|
int end;
|
|
|
|
char tmpBuf[5];
|
|
|
|
short val;
|
|
|
|
if ((IBuf == NULL) || (OBuf == NULL))
|
|
{
|
|
return(SUCCESS);
|
|
}
|
|
|
|
tmpBuf[4] = '\0';
|
|
|
|
OBuf[0] = '\0';
|
|
|
|
for (index = 0;index < IBufLen;index += 3)
|
|
{
|
|
block = 0;
|
|
slack = IBufLen - index - 1;
|
|
end = MIN(2,slack);
|
|
|
|
for (cindex = 0;cindex <= end;cindex++)
|
|
{
|
|
block +=
|
|
((unsigned char)IBuf[index + cindex] << (8 * (2 - cindex)));
|
|
} /* END for (cindex) */
|
|
|
|
for (cindex = 0;cindex < 4;cindex++)
|
|
{
|
|
val = (block >> (6 * (3 - cindex))) & 0x003f;
|
|
|
|
tmpBuf[cindex] = CList[val];
|
|
} /* END for (cindex) */
|
|
|
|
if (slack < 2)
|
|
{
|
|
tmpBuf[3] = '=';
|
|
|
|
if (slack < 1)
|
|
tmpBuf[2] = '=';
|
|
}
|
|
|
|
strcat(OBuf,tmpBuf);
|
|
} /* END for (index) */
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecBufTo64BitEncoding() */
|
|
|
|
|
|
|
|
|
|
|
|
int MSecCompBufTo64BitEncoding(
|
|
|
|
char *IBuf,
|
|
int IBufLen,
|
|
char *OBuf) /* size = X */
|
|
|
|
{
|
|
int IIndex = 0;
|
|
int OIndex = 0;
|
|
|
|
if ((OBuf == NULL) || (IBuf == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
do
|
|
{
|
|
OBuf[OIndex++] = CList[(IBuf[IIndex] >> 2) & 0x3f];
|
|
|
|
OBuf[OIndex++] = CList[((IBuf[IIndex] << 4) & 0x30) | ((IBuf[IIndex + 1] >> 4) & 0x0f)];
|
|
|
|
if (IIndex + 1 < IBufLen)
|
|
OBuf[OIndex++] = CList[((IBuf[IIndex + 1] << 2) & 0x3c) | ((IBuf[IIndex + 2] >> 6) & 0x03)];
|
|
else
|
|
OBuf[OIndex++] = '=';
|
|
|
|
if (IIndex + 2 < IBufLen)
|
|
OBuf[OIndex++] = CList[((IBuf[IIndex + 2]) & 0x3f)];
|
|
else
|
|
OBuf[OIndex++] = '=';
|
|
|
|
IIndex += 3;
|
|
} while (IIndex < IBufLen);
|
|
|
|
OBuf[OIndex++] = '\0';
|
|
|
|
return(SUCCESS);
|
|
} /* MSecCompBufTo64BitEncoding() */
|
|
|
|
|
|
|
|
|
|
int MSecComp64BitToBufDecoding(
|
|
|
|
char *IBuf,
|
|
int IBufLen,
|
|
char *OBuf,
|
|
int *OBufLen)
|
|
|
|
{
|
|
int IIndex = 0;
|
|
int OIndex = 0;
|
|
|
|
if ((OBuf == NULL) || (IBuf == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
do
|
|
{
|
|
OBuf[OIndex++] = ((CDList[(int)IBuf[IIndex]] << 2 ) & 0xfc ) | ((CDList[(int)IBuf[IIndex+1]] >> 4 ) & 0x03 );
|
|
|
|
OBuf[OIndex++] = ((CDList[(int)IBuf[IIndex+1]] << 4 ) & 0xf0 ) | ((CDList[(int)IBuf[IIndex+2]] >> 2 ) & 0x0f );
|
|
|
|
OBuf[OIndex++] = ((CDList[(int)IBuf[IIndex+2]] << 6 ) & 0xc0 ) | ((CDList[(int)IBuf[IIndex+3]]));
|
|
|
|
IIndex += 4;
|
|
} while (IIndex < IBufLen);
|
|
|
|
if (OBufLen != NULL)
|
|
*OBufLen = OIndex;
|
|
|
|
return(SUCCESS);
|
|
} /* MSecComp64BitToBufDecoding() */
|
|
|
|
|
|
|
|
|
|
#define N 16
|
|
#define noErr 0
|
|
#define DATAERROR -1
|
|
#define KEYBYTES 8
|
|
#define subkeyfilename "Blowfish.dat"
|
|
|
|
unsigned long P[N + 2];
|
|
unsigned long S[4][256];
|
|
FILE* SubkeyFile;
|
|
|
|
short __MSecBlowfishOpenSubkeyFile(void) /* read only */
|
|
|
|
{
|
|
short error;
|
|
|
|
error = noErr;
|
|
|
|
if ((SubkeyFile = fopen(subkeyfilename,"rb")) == NULL)
|
|
{
|
|
error = DATAERROR;
|
|
}
|
|
|
|
return(error);
|
|
} /* END __MSecBlowfishOpenSubkeyFile() */
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long __MSecBlowfishF(
|
|
|
|
mulong x) /* I */
|
|
|
|
{
|
|
unsigned short a;
|
|
unsigned short b;
|
|
unsigned short c;
|
|
unsigned short d;
|
|
unsigned long y;
|
|
|
|
d = x & 0x00FF;
|
|
x >>= 8;
|
|
|
|
c = x & 0x00FF;
|
|
x >>= 8;
|
|
|
|
b = x & 0x00FF;
|
|
x >>= 8;
|
|
|
|
a = x & 0x00FF;
|
|
|
|
/* y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d]; */
|
|
|
|
y = S[0][a] + S[1][b];
|
|
y ^= S[2][c];
|
|
y += S[3][d];
|
|
|
|
return(y);
|
|
} /* END __MSecBlowfishF() */
|
|
|
|
|
|
|
|
|
|
void MSecBlowfishEncipher(
|
|
|
|
mulong *xl, /* I (modified) */
|
|
mulong *xr) /* I (modified) */
|
|
|
|
{
|
|
unsigned long Xl;
|
|
unsigned long Xr;
|
|
unsigned long temp;
|
|
short i;
|
|
|
|
Xl = *xl;
|
|
Xr = *xr;
|
|
|
|
for (i = 0;i < N;++i)
|
|
{
|
|
Xl = Xl ^ P[i];
|
|
Xr = __MSecBlowfishF(Xl) ^ Xr;
|
|
|
|
temp = Xl;
|
|
Xl = Xr;
|
|
Xr = temp;
|
|
} /* END for (i) */
|
|
|
|
temp = Xl;
|
|
Xl = Xr;
|
|
Xr = temp;
|
|
|
|
Xr = Xr ^ P[N];
|
|
Xl = Xl ^ P[N + 1];
|
|
|
|
*xl = Xl;
|
|
*xr = Xr;
|
|
|
|
return;
|
|
} /* END MSecBlowfishEncipher() */
|
|
|
|
|
|
|
|
|
|
void MSecBlowfishDecipher(
|
|
|
|
mulong *xl, /* I (modified) */
|
|
mulong *xr) /* I (modified) */
|
|
|
|
{
|
|
unsigned long Xl;
|
|
unsigned long Xr;
|
|
unsigned long temp;
|
|
short i;
|
|
|
|
Xl = *xl;
|
|
Xr = *xr;
|
|
|
|
for (i = N + 1; i > 1; --i)
|
|
{
|
|
Xl = Xl ^ P[i];
|
|
Xr = __MSecBlowfishF(Xl) ^ Xr;
|
|
|
|
/* Exchange Xl and Xr */
|
|
|
|
temp = Xl;
|
|
Xl = Xr;
|
|
Xr = temp;
|
|
} /* END for (i) */
|
|
|
|
/* Exchange Xl and Xr */
|
|
|
|
temp = Xl;
|
|
Xl = Xr;
|
|
Xr = temp;
|
|
|
|
Xr = Xr ^ P[1];
|
|
Xl = Xl ^ P[0];
|
|
|
|
*xl = Xl;
|
|
*xr = Xr;
|
|
|
|
return;
|
|
} /* END MSecBlowfishDecipher() */
|
|
|
|
|
|
|
|
|
|
short MSecBlowfishInitialize(
|
|
|
|
char *Key, /* I */
|
|
short KeyBytes) /* I */
|
|
|
|
{
|
|
short i;
|
|
short j;
|
|
short k;
|
|
short error;
|
|
short numread;
|
|
unsigned long data;
|
|
unsigned long datal;
|
|
unsigned long datar;
|
|
|
|
/* First, open the file containing the array initialization data */
|
|
|
|
error = __MSecBlowfishOpenSubkeyFile();
|
|
|
|
if (error == noErr)
|
|
{
|
|
for (i = 0;i < N + 2;++i)
|
|
{
|
|
numread = fread(&data,4,1,SubkeyFile);
|
|
|
|
#ifdef little_endian /* Eg: Intel We want to process things in byte */
|
|
/* order, not as rearranged in a longword */
|
|
data = ((data & 0xFF000000) >> 24) |
|
|
((data & 0x00FF0000) >> 8) |
|
|
((data & 0x0000FF00) << 8) |
|
|
((data & 0x000000FF) << 24);
|
|
#endif
|
|
|
|
if (numread != 1)
|
|
{
|
|
return(DATAERROR);
|
|
}
|
|
else
|
|
{
|
|
P[i] = data;
|
|
}
|
|
} /* END for (i) */
|
|
|
|
for (i = 0;i < 4;++i)
|
|
{
|
|
for (j = 0;j < 256;++j)
|
|
{
|
|
numread = fread(&data,4,1,SubkeyFile);
|
|
|
|
#ifdef little_endian /* Eg: Intel We want to process things in byte */
|
|
/* order, not as rearranged in a longword */
|
|
data = ((data & 0xFF000000) >> 24) |
|
|
((data & 0x00FF0000) >> 8) |
|
|
((data & 0x0000FF00) << 8) |
|
|
((data & 0x000000FF) << 24);
|
|
#endif
|
|
|
|
if (numread != 1)
|
|
{
|
|
return(DATAERROR);
|
|
}
|
|
else
|
|
{
|
|
S[i][j] = data;
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(SubkeyFile);
|
|
|
|
j = 0;
|
|
|
|
for (i = 0;i < N + 2;++i)
|
|
{
|
|
data = 0x00000000;
|
|
|
|
for (k = 0;k < 4;++k)
|
|
{
|
|
data = (data << 8) | Key[j];
|
|
|
|
j = j + 1;
|
|
|
|
if (j >= KeyBytes)
|
|
{
|
|
j = 0;
|
|
}
|
|
}
|
|
|
|
P[i] = P[i] ^ data;
|
|
} /* END for (i) */
|
|
|
|
datal = 0x00000000;
|
|
datar = 0x00000000;
|
|
|
|
for (i = 0;i < N + 2;i += 2)
|
|
{
|
|
MSecBlowfishEncipher(&datal,&datar);
|
|
|
|
P[i] = datal;
|
|
P[i + 1] = datar;
|
|
}
|
|
|
|
for (i = 0;i < 4;++i)
|
|
{
|
|
for (j = 0;j < 256;j += 2)
|
|
{
|
|
MSecBlowfishEncipher(&datal,&datar);
|
|
|
|
S[i][j] = datal;
|
|
S[i][j + 1] = datar;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("Unable to open subkey initialization file : %d\n",
|
|
error);
|
|
}
|
|
|
|
return(error);
|
|
} /* END MSecBlowfishInitialize() */
|
|
|
|
|
|
|
|
|
|
|
|
#define FLAG_Copied 0x80
|
|
#define FLAG_Compress 0x40
|
|
|
|
int MSecCompressionGetMatch(
|
|
|
|
unsigned char *Source,
|
|
unsigned int X,
|
|
unsigned int SourceSize,
|
|
int *Hash,
|
|
unsigned int *Size,
|
|
int *Pos) /* O */
|
|
|
|
{
|
|
unsigned int HashValue = (40543L*((((Source[X] << 4) ^ Source[X+1]) << 4) ^ Source[X+2]) >> 4) & 0xfff;
|
|
|
|
*Pos = Hash[HashValue];
|
|
|
|
Hash[HashValue] = X;
|
|
|
|
if ((*Pos != -1) && ((X - *Pos) < 4096))
|
|
{
|
|
for (*Size = 0;
|
|
((*Size < 18) &&
|
|
(Source[X + *Size] == Source[*Pos + *Size]) &&
|
|
((X + *Size) < SourceSize));
|
|
(*Size)++);
|
|
|
|
return(*Size >= 3);
|
|
}
|
|
|
|
return(FALSE);
|
|
} /* END MSecCompressionGetMatch() */
|
|
|
|
|
|
|
|
|
|
|
|
int MSecCompress(
|
|
|
|
unsigned char *SrcString, /* I */
|
|
unsigned int SrcSize, /* I */
|
|
unsigned char *DstString, /* O (optional,if NULL, populate SrcString) */
|
|
char *EKey) /* I (optional - enables encryption when present) */
|
|
|
|
{
|
|
static char *LocalDstString = NULL;
|
|
static int LocalDstSize = 0;
|
|
|
|
char *Dest;
|
|
|
|
int Hash[4096];
|
|
|
|
int NewLength;
|
|
|
|
unsigned int Key;
|
|
unsigned int Size;
|
|
unsigned int Pos;
|
|
unsigned int Command;
|
|
unsigned int X = 0;
|
|
unsigned int Y = 9;
|
|
unsigned int Z = 3;
|
|
|
|
unsigned char Bit = 0;
|
|
|
|
#ifndef __MPROD
|
|
const char *FName = "MSecCompress";
|
|
|
|
MDB(2,fSTRUCT) MLog("%s(SrcString,%d,DstString,%s)\n",
|
|
FName,
|
|
SrcSize,
|
|
(EKey != NULL) ? "EKey" : "NULL");
|
|
#endif /* !__MPROD */
|
|
|
|
NewLength = (int)(ceil(SrcSize / 3.0) * 4) + 1;
|
|
|
|
MDB(7,fSTRUCT) MLog("INFO: compressing data (Original Size - %d)\n",
|
|
SrcSize);
|
|
|
|
NewLength = (int)(ceil(SrcSize / 3.0) * 4) + 1;
|
|
|
|
if (DstString == NULL)
|
|
{
|
|
/* use static local buffer */
|
|
|
|
if (LocalDstString == NULL)
|
|
{
|
|
LocalDstString = (char *)malloc(NewLength);
|
|
|
|
LocalDstSize = NewLength;
|
|
}
|
|
else if (LocalDstSize < NewLength)
|
|
{
|
|
LocalDstString = (char *)realloc(LocalDstString,NewLength);
|
|
|
|
LocalDstSize = NewLength;
|
|
}
|
|
|
|
Dest = LocalDstString;
|
|
}
|
|
else
|
|
{
|
|
Dest = (char *)DstString;
|
|
}
|
|
|
|
for (Key = 0;Key < 4096;Key++)
|
|
Hash[Key] = -1;
|
|
|
|
Dest[0] = FLAG_Compress;
|
|
|
|
/* Y = 9, initialize Dest up Y */
|
|
|
|
Dest[1] = '\0';
|
|
Dest[2] = '\0';
|
|
Dest[3] = '\0';
|
|
Dest[4] = '\0';
|
|
Dest[5] = '\0';
|
|
Dest[6] = '\0';
|
|
Dest[7] = '\0';
|
|
Dest[8] = '\0';
|
|
Dest[9] = '\0';
|
|
|
|
for (;(X < SrcSize) && (Y <= SrcSize);)
|
|
{
|
|
if (Bit > 15)
|
|
{
|
|
Dest[Z++] = (Command >> 8) & 0x00ff;
|
|
Dest[Z] = Command & 0x00ff;
|
|
Z = Y;
|
|
Bit = 0;
|
|
Y += 2;
|
|
}
|
|
|
|
for (Size = 1;
|
|
(SrcString[X] == SrcString[X + Size]) && (Size < 0x0fff) && (X + Size < SrcSize);
|
|
Size++);
|
|
|
|
if (Size >= 16)
|
|
{
|
|
Dest[Y++] = 0;
|
|
Dest[Y++] = ((Size - 16) >> 8) & 0x00ff;
|
|
Dest[Y++] = (Size - 16) & 0x00ff;
|
|
Dest[Y++] = SrcString[X];
|
|
X += Size;
|
|
Command = (Command << 1) + 1;
|
|
}
|
|
else if (MSecCompressionGetMatch(SrcString,X,SrcSize,Hash,&Size,(int *)&Pos))
|
|
{
|
|
Key = ((X-Pos) << 4) + (Size - 3);
|
|
Dest[Y++] = (Key >> 8) & 0x00ff;
|
|
Dest[Y++] = Key & 0x00ff;
|
|
X += Size;
|
|
Command = (Command << 1) + 1;
|
|
}
|
|
else
|
|
{
|
|
Dest[Y++] = SrcString[X++];
|
|
Command = (Command << 1);
|
|
}
|
|
|
|
Bit++;
|
|
} /* END for (X) */
|
|
|
|
if (Dest == LocalDstString)
|
|
{
|
|
/* pad end of data */
|
|
|
|
Dest[Y] = '\0';
|
|
Dest[Y + 1] = '\0';
|
|
}
|
|
|
|
Command <<= (16 - Bit);
|
|
|
|
Dest[Z++] = (Command >> 8) & 0x00ff;
|
|
Dest[Z] = Command & 0x00ff;
|
|
|
|
if (Y > SrcSize)
|
|
{
|
|
for (Y = 0;Y < SrcSize;Dest[Y + 1] = SrcString[Y++]);
|
|
|
|
Dest[0] = FLAG_Copied;
|
|
|
|
return(SrcSize + 1);
|
|
}
|
|
|
|
if (EKey != NULL)
|
|
{
|
|
MSecEncryption(Dest,EKey,Y);
|
|
}
|
|
|
|
MSecCompBufTo64BitEncoding(
|
|
Dest,
|
|
Y,
|
|
(DstString == NULL) ? (char *)SrcString : (char *)DstString);
|
|
|
|
MDB(7,fSTRUCT) MLog("INFO: compressed data size - %d\n",
|
|
(DstString == NULL) ? strlen((char *)SrcString) : strlen((char *)DstString));
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecCompress() */
|
|
|
|
|
|
|
|
|
|
|
|
int MSecDecompress(
|
|
|
|
unsigned char *SrcString, /* I */
|
|
unsigned int SrcSize, /* I */
|
|
unsigned char *SDstBuf, /* I (optional) */
|
|
unsigned int SDstSize, /* I (required if DstBuf set) */
|
|
unsigned char **DDstBuf, /* O (optional) */
|
|
char *EKey) /* I (optional - encryption enabled when present) */
|
|
|
|
{
|
|
static unsigned char *tmpBuf = NULL;
|
|
static unsigned char *OutBuf = NULL;
|
|
|
|
static int OutBufSize = 0;
|
|
|
|
unsigned int DstSize;
|
|
|
|
unsigned int NewLength;
|
|
|
|
unsigned int X = 9;
|
|
unsigned int Y = 0;
|
|
unsigned int Pos;
|
|
unsigned int Size;
|
|
unsigned int K;
|
|
int Command;
|
|
|
|
unsigned char *DstString;
|
|
|
|
unsigned char Bit = 16;
|
|
|
|
if ((SrcString == NULL) || (SrcSize <= 0))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
if ((SDstBuf != NULL) && (SDstSize > 0))
|
|
{
|
|
DstString = SDstBuf;
|
|
DstSize = SDstSize;
|
|
}
|
|
else if (DDstBuf != NULL)
|
|
{
|
|
if ((OutBuf == NULL) &&
|
|
((OutBuf = (unsigned char *)malloc(MMAX_BUFFER)) == NULL))
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
else
|
|
{
|
|
OutBufSize = MMAX_BUFFER;
|
|
}
|
|
|
|
*DDstBuf = NULL;
|
|
|
|
DstString = OutBuf;
|
|
DstSize = OutBufSize;
|
|
}
|
|
else
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
DstString[0] = '\0';
|
|
|
|
NewLength = SrcSize;
|
|
|
|
if (tmpBuf == NULL)
|
|
{
|
|
if ((tmpBuf = (unsigned char *)malloc(NewLength)) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (sizeof(tmpBuf) < NewLength)
|
|
{
|
|
if ((tmpBuf = (unsigned char *)realloc(tmpBuf,NewLength)) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
}
|
|
|
|
tmpBuf[0] = '\0';
|
|
|
|
MSecComp64BitToBufDecoding((char *)SrcString,(int)SrcSize,(char *)tmpBuf,(int *)&SrcSize);
|
|
|
|
if (EKey != NULL)
|
|
MSecEncryption((char *)tmpBuf,EKey,SrcSize);
|
|
|
|
Command = (tmpBuf[3] << 8) + tmpBuf[4];
|
|
|
|
/*
|
|
if (tmpBuf[0] == FLAG_Copied)
|
|
{
|
|
for (Y = 1; Y < SrcSize; DstString[Y-1] = tmpBuf[Y++]);
|
|
|
|
return(SrcSize-1);
|
|
}
|
|
*/
|
|
|
|
for (;X < SrcSize;)
|
|
{
|
|
if (Bit == 0)
|
|
{
|
|
Command = (tmpBuf[X++] << 8);
|
|
|
|
Command += tmpBuf[X++];
|
|
Bit = 16;
|
|
}
|
|
|
|
if (Command & 0x8000)
|
|
{
|
|
Pos = (tmpBuf[X++] << 4);
|
|
Pos += (tmpBuf[X] >> 4);
|
|
|
|
if (Pos)
|
|
{
|
|
Size = (tmpBuf[X++] & 0x0f) + 3;
|
|
|
|
if ((Y + Size) > DstSize)
|
|
{
|
|
/* bounds check */
|
|
|
|
if (DDstBuf != NULL)
|
|
{
|
|
DstSize <<= 1;
|
|
|
|
if ((OutBuf = (unsigned char *)realloc(OutBuf,DstSize)) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
DstString = OutBuf;
|
|
}
|
|
else
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
for (K = 0; K < Size;K++)
|
|
{
|
|
DstString[Y + K] = DstString[Y - Pos + K];
|
|
}
|
|
|
|
Y += Size;
|
|
}
|
|
else
|
|
{
|
|
Size = (tmpBuf[X++] << 8);
|
|
Size += tmpBuf[X++] + 16;
|
|
|
|
if ((Y + Size) > DstSize)
|
|
{
|
|
/* bounds check */
|
|
|
|
if (DDstBuf != NULL)
|
|
{
|
|
DstSize <<= 1;
|
|
|
|
if ((OutBuf = (unsigned char *)realloc(OutBuf,DstSize)) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
DstString = OutBuf;
|
|
}
|
|
else
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
for (K = 0;K < Size;DstString[Y + K++] = tmpBuf[X]);
|
|
|
|
X++;
|
|
Y += Size;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Y >= DstSize)
|
|
{
|
|
/* bounds check */
|
|
|
|
if (DDstBuf != NULL)
|
|
{
|
|
DstSize <<= 1;
|
|
|
|
if ((OutBuf = (unsigned char *)realloc(OutBuf,DstSize)) == NULL)
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
|
|
DstString = OutBuf;
|
|
}
|
|
else
|
|
{
|
|
return(FAILURE);
|
|
}
|
|
}
|
|
|
|
DstString[Y++] = tmpBuf[X++];
|
|
} /* END else () */
|
|
|
|
Command <<= 1;
|
|
Bit--;
|
|
} /* END for() */
|
|
|
|
/* terminate buffer */
|
|
|
|
if (Y < DstSize)
|
|
OutBuf[Y] = '\0';
|
|
|
|
if (DDstBuf != NULL)
|
|
{
|
|
*DDstBuf = OutBuf;
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecDecompress() */
|
|
|
|
|
|
|
|
|
|
int MSecEncryption(
|
|
|
|
char *SrcString,
|
|
char *Key,
|
|
int SrcSize)
|
|
|
|
{
|
|
int r;
|
|
char *cp_val;
|
|
char *cp_key;
|
|
char result;
|
|
|
|
r = 0;
|
|
|
|
if((SrcString != NULL) && (Key != NULL))
|
|
{
|
|
cp_val = SrcString;
|
|
cp_key = Key;
|
|
|
|
while(r < SrcSize)
|
|
{
|
|
result = *cp_val ^ *cp_key;
|
|
*cp_val = result;
|
|
cp_val++;
|
|
cp_key++;
|
|
if(*cp_key == '\0') cp_key = Key;
|
|
r++;
|
|
}
|
|
}
|
|
|
|
return(SUCCESS);
|
|
} /* END MSecEncryption() */
|
|
|
|
/* END MSec.c */
|
|
|