📄 tst2fish.c
字号:
*
* Function Name: AES_Test_CBC_D_MCT
*
* Function: Run ECB Monte Carlo test for CBC decryption
*
* Arguments: fname = file name to produce
*
* Return: None.
*
* Notes:
*
-****************************************************************************/
void AES_Test_CBC_D_MCT(CONST char *fname)
{
int i,j,q;
testData t;
BYTE ptPrev[BLOCK_SIZE/8];
BYTE IV[BLOCK_SIZE/8];
#define CV t.ci.IV /* use t.ci.IV as CV */
t.f=AES_PutFileHeader(fname,
"Cipher Block Chaining (CBC) Mode - DECRYPTION\nMonte Carlo Test");
if (cipherInit(&t.ci,MODE_ECB,NULL) != TRUE)
FatalError("cipherInit error during %s test",fname);
for (t.keySize=KEY_BITS_0,q=0;t.keySize <= MAX_KEY_BITS;t.keySize+=STEP_KEY_BITS,q+=2)
{
AES_printf(&t,"S\n"); /* output key size */
if (!quietVerify) printf(" keyLen = %3d. ",t.keySize);
ClearTestData(&t); /* start with all zeroes */
memset(IV,0,sizeof(IV));
if (makeKey(&t.ki,DIR_DECRYPT,t.keySize,t.ki.keyMaterial) != TRUE)
FatalError("Error parsing key during %s test",fname);
BlockCopy(CV,IV);
for (t.I=0;t.I<mctOuter;t.I++)
{
AES_printf(&t,"IKvC");
if (!quietVerify) printf("%3d\b\b\b",t.I);
for (j=0;j<mctInner;j++)
{
BlockCopy(ptPrev,t.pt);
if (blockDecrypt(&t.ci,&t.ki,t.ct,BLOCK_SIZE,t.pt) != BLOCK_SIZE)
FatalError("blockDecrypt return during %s test",fname);
for (i=0;i<BLOCK_SIZE/8;i++)
t.pt[i] ^= CV[i]; /* PT = OB ^ CV */
BlockCopy(CV,t.ct); /* CV = CT */
BlockCopy(t.ct,t.pt); /* CT = PT */
}
AES_printf(&t,"P\n");
for (i=0;i<t.keySize/32;i++)
t.ki.key32[i] ^=
Bswap((i>=q) ? ((DWORD *)t.pt )[i-q] :
((DWORD *)ptPrev)[BLOCK_SIZE/32-q+i]);
if (reKey(&t.ki) != TRUE)
FatalError("reKey return during %s test",fname);
}
AES_EndSection(&t);
}
if (!quietVerify) printf(" \n");
AES_Close(&t);
}
/*
+*****************************************************************************
*
* Function Name: ShowParams
*
* Function: Print out the settings of settable parameters
*
* Arguments: None.
*
* Return: None.
*
* Notes:
*
-****************************************************************************/
void ShowParams(void)
{
int saveDebug=debug;
testData t;
debug=0; /* turn off debug output */
memset(t.ki.keyMaterial,'0',sizeof(t.ki.keyMaterial));
printf("(keyLen,numRounds): ");
for (t.keySize=KEY_BITS_0;t.keySize<=MAX_KEY_BITS;t.keySize+=STEP_KEY_BITS)
{
if (makeKey(&t.ki,DIR_ENCRYPT,t.keySize,t.ki.keyMaterial) != TRUE)
FatalError("Error parsing key during ShowParam","");
printf(" (%d,%d)",t.keySize,t.ki.numRounds);
}
printf("\n");
debug=saveDebug;
}
/*
+*****************************************************************************
*
* Function Name: ParseArgFile
*
* Function: Parse commands from argument file
*
* Arguments: fName = name of file to read
* argList = list of ptrs to fill in
* maxArgCnt = size of argList
*
* Return: None.
*
* Notes: '/' and ';' are comment to end of line characters in the file
* This function is used to allow a "custom" set of switches to
* be automatically read from a file at startup.
*
-****************************************************************************/
int ParseArgFile(CONST char *fName,char *argList[],int maxArgCnt)
{
static char buf[1024];
static int bufCnt=0; /* current # chars in buf */
int i,j,k,argCnt;
char line[256];
FILE *f=fopen(fName,"rt");
if (f == NULL) return 0;
if (debug) printf("Reading args from file %s: ",fName);
for (argCnt=0;argCnt<maxArgCnt;)
{ /* read in arg file one line at a time */
memset(line,0,sizeof(line));
if (fgets(line,sizeof(line)-4,f) == NULL)
break;
for (i=0;line[i];i++) /* ignore comments to end of line */
if ((line[i]=='/') || (line[i]==';'))
{ line[i]=line[i+1]=0; break; }
for (i=0;line[i];) /* parse out tokens */
{
for (j=i;line[j];j++) /* skip leading whitespace */
if (line[j] > ' ') break;
if (line[j]==0) break;
for (k=j;line[k];k++)
if (line[k] <= ' ') break;
/* now j..k-1 defines a token */
if (k-j+1 > (int)(sizeof(buf) - bufCnt))
FatalError("Arg file too large: %s",line);
if (argCnt >= maxArgCnt)
break;
memcpy(buf+bufCnt,line+j,k-j);
buf[bufCnt+k-j]=0; /* terminate the token */
if (debug) printf(" %s",buf+bufCnt);
argList[argCnt++]=buf+bufCnt;
bufCnt+=k-j+1;
i=k; /* skip to next token */
}
}
fclose(f);
if (debug) printf("\n");
return argCnt;
}
/*
+*****************************************************************************
*
* Function Name: GiveHelp
*
* Function: Print out list of command line switches
*
* Arguments: None.
*
* Return: None.
*
* Notes:
*
-****************************************************************************/
void GiveHelp(void)
{
printf("Syntax: TST2FISH [options]\n"
"Purpose: Generate/validate AES Twofish code and files\n"
"Options: -lNN ==> set sanity check loop to NN\n"
" -m ==> do full MCT generation\n"
" -pPath ==> set file path\n"
" -s ==> set initial random seed based on time\n"
" -sNN ==> set initial random seed to NN\n"
" -tNN ==> time performance using NN iterations\n"
" -v ==> validate files, don't generate them\n",
MAX_ROUNDS
);
exit(1);
}
#ifdef TEST_EXTERN
void Test_Extern(void);
#endif
void ShowHex(FILE *f,CONST void *p,int bCnt,CONST char *name)
{
int i;
fprintf(f," ;%s:",name);
for (i=0;i<bCnt;i++)
{
if ((i % 8) == 0)
fprintf(f,"\n\t.byte\t");
else
fprintf(f,",");
fprintf(f,"0%02Xh",((BYTE *)p)[i]);
}
fprintf(f,"\n");
}
/* output a formatted 6805 test vector include file */
void Debug6805(void)
{
int i,j;
testData t;
FILE *f;
ClearTestData(&t);
t.keySize=128;
f=stdout;
cipherInit(&t.ci,MODE_ECB,NULL);
makeKey(&t.ki,DIR_ENCRYPT,t.keySize,t.ki.keyMaterial);
for (i=0;i<4;i++) /* make sure it all fits in 256 bytes */
{
reKey(&t.ki);
blockEncrypt(&t.ci,&t.ki,t.pt,BLOCK_SIZE,t.ct);
fprintf(f,"; Twofish vector #%d\n",i+1);
ShowHex(f,&t.keySize,1,"Key Size");
ShowHex(f,t.ki.key32,16,"Key");
ShowHex(f,t.pt,BLOCK_SIZE/8,"Plaintext");
ShowHex(f,t.ct,BLOCK_SIZE/8,"Ciphertext");
for (j=0;j<16;j++)
((BYTE *)t.ki.key32)[j] = t.pt[j] ^ t.ct[j];
memcpy(t.pt,t.ct,sizeof(t.pt));
fprintf(f,";-------------------------------------------------------\n");
}
fprintf(f,"\n\t.byte 0\t;end of list\n");
fclose(f);
}
/*
+*****************************************************************************
* Main AES test function
-****************************************************************************/
int main(int argc,char *argv[])
{
#define MAX_ARGS 40
int i,j,k,argCnt,testCnt=32;
int doTableTest=1;
int doIntermediate=0;
DWORD randSeed=0x12345678;
char *argList[MAX_ARGS];
char *moduleName=moduleDescription;
i=1; /* make sure LittleEndian is defined correctly */
if (b0(i) != 1)
FatalError("LittleEndian defined incorrectly","");
if ((ALIGN32) && (k == 2))
FatalError("Cannot enable ALIGN32 in 16-bit mode\n","");
#if ((MCT_INNER != 10000) || (MCT_OUTER != 400))
#error MCT loop counts incorrect!
#endif
argCnt=ParseArgFile("TST2FISH.CFG",argList,MAX_ARGS); /* read parameter file */
for (i=1;(i<argc) && (argCnt<MAX_ARGS);i++) /* append command line */
argList[argCnt++]=argv[i];
for (i=0;i<argCnt;i++) /* parse command line arguments */
{
if (argList[i][0] == '-')
switch (toupper(argList[i][1]))
{
case 'D':
if (argList[i][2])
debug=atoi(argList[i]+2);
else
debug=1;
break;
case 'F':
switch (toupper(argList[i][2]))
{
case 'L': FMT_LOG = 1;
testCnt = 0; break;
case 'B': CLKS_BYTE = ~CLKS_BYTE; break;
case 'M': CLK_MHZ = atoi(argList[i]+3); break;
}
break;
case '?':
case 'H':
GiveHelp();
break;
case 'A':
if (argList[i][2])
useAsm=atoi(argList[i]+2);
else
useAsm=7; /* enable everything in ASM */
break;
case 'I':
doIntermediate=1;
break;
case 'L':
testCnt = atoi(argList[i]+2);
break;
case 'M': /* do FULL MCT generation */
mctInner = MCT_INNER;
mctOuter = MCT_OUTER;
break;
case 'P':
for (j=0;j<sizeof(filePath)-4;j++)
if ((filePath[j]=argList[i][j+2]) == 0)
break;
filePath[j]=filePath[j+1]=0;
#ifdef _M_IX86 /* DOS/Win specific filePath stuff */
if ((j) && (filePath[j-1] != ':') && (filePath[j-1] != '\\'))
filePath[j]='\\'; /* append backslash to filePath */
#endif
break;
case 'S':
if (argList[i][2])
randSeed = atol(argList[i]+2);
else
randSeed=(DWORD) time(NULL); /* randomize */
break;
case 'T':
if (argList[i][2])
timeIterCnt = atoi(argList[i]+2);
else
timeIterCnt = 32;
break;
case 'V':
verify=1; /* don't generate files. Read&verify them */
if (argList[i][2]=='+')
verbose=1;
if (argList[i][2]=='-')
doTableTest=0;
if (toupper(argList[i][2])=='Q')
quietVerify=1;
break;
case '6':
Debug6805();
exit(1);
break;
}
else
GiveHelp();
}
#ifdef USE_ASM
if (useAsm & 7) moduleName="Assembler ";
#endif
printf("%s%d.%s: %s%s [%ld bytes,%s].\n",CompilerName,8*sizeof(int),
#ifdef USE_ASM
(get_cpu_type() == 5) ? "Pentium" : "Pro/II",
#else
(sizeof(int) == 2) ? "x86" : "CPU???",
#endif
moduleName,modeString,TwofishCodeSize(),
#if LittleEndian
"little-endian"
#else
"big-endian"
#endif
);
SetRand(randSeed); /* init pseudorandom generator for testing */
if (testCnt)
AES_Sanity_Check(testCnt); /* test API compliance, self-consistency */
if ((timeIterCnt) && (!verify))
{
TimeOps(timeIterCnt);
exit(0);
}
#ifdef TEST_EXTERN
Test_Extern();
exit(0);
#endif
if (doIntermediate)
{
AES_Test_Intermediate("ecb_ival.txt"); /* intermediate value test */
return 0;
}
AES_Test_VK("ecb_vk.txt"); /* Variable key KAT */
AES_Test_VT("ecb_vt.txt"); /* Variable text KAT */
AES_Test_Intermediate("ecb_ival.txt"); /* intermediate value test */
if (!quietVerify)
printf("%s MCT Generation : %d,%d.\n",
((MCT_INNER == mctInner) && (MCT_OUTER == mctOuter)) ? "Full" : " *** Partial",
mctOuter,mctInner);
AES_Test_CBC_E_MCT("cbc_e_m.txt"); /* Monte Carlo test for CBC encryption */
AES_Test_CBC_D_MCT("cbc_d_m.txt"); /* Monte Carlo test for CBC decryption */
AES_Test_ECB_E_MCT("ecb_e_m.txt"); /* Monte Carlo test for ECB encryption */
AES_Test_ECB_D_MCT("ecb_d_m.txt"); /* Monte Carlo test for ECB decryption */
if (doTableTest)
AES_Test_TBL("ecb_tbl.txt"); /* Table test */
else
if (!quietVerify) printf("WARNING: Skipping ecb_tbl.txt verification\n");
if (verify)
printf("*** All files verified OK ***\n");
if (timeIterCnt)
TimeOps(timeIterCnt);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -