⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tst2fish.c

📁 嵌入环境下Blowfish加密算法的实现
💻 C
📖 第 1 页 / 共 4 页
字号:
		printf(";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n");
	}


/*
+*****************************************************************************
*
* Function Name:	AES_Sanity_Check
*
* Function:			Make sure things work to the interface spec and
*					that encryption and decryption are inverse functions
*
* Arguments:		None.
*
* Return:			None.
*
* Notes:			Will FatalError if any problems found
*
-****************************************************************************/
void AES_Sanity_Check(int testCnt)
	{
	static DWORD hexVal[] =
			{0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,
			 0x33221100,0x77665544,0xBBAA9988,0xFFEEDDCC};
	static char *modeNames[]={"(null)","MODE_ECB","MODE_CBC","MODE_CFB1"};

	int i,j,q,n,testNum,lim,saveDebug=debug;
	testData t;
	keyInstance k2;
	BYTE pt[128];
	BYTE ct[128];
	char ivString[BLOCK_SIZE/4];
	char *mName;
	BYTE mode;
#if ALIGN32
	BYTE alignDummy[3];	/* keep dword alignment on stack after BYTE mode */
#endif

	
	if (!quietVerify) printf("\nTwofish code sanity check...");
#if (MODE_CFB1 != MODE_ECB  + 2)
#error Need to change mode loop constants
#endif
	if (testCnt)
	for (mode=MODE_ECB;mode<=MODE_CFB1;mode++)
		{
		debug=(mode == saveDebug);
		mName=modeNames[mode];
		if (cipherInit(&t.ci,mode,hexString) != TRUE)
			FatalError("cipherInit error during sanity check %s",mName);
		if (t.ci.mode != mode)
			FatalError("Cipher mode not set properly during sanity check %s",mName);
		if (mode != MODE_ECB)
			for (i=0;i<BLOCK_SIZE/32;i++)
				if (t.ci.iv32[i] != hexVal[i])
					FatalError("Invalid IV parse during sanity check %s",mName);
		lim = (mode == MODE_CFB1) ? (testCnt+31)/32 : testCnt;
		for (t.keySize=KEY_BITS_0;t.keySize <= MAX_KEY_BITS;t.keySize+=STEP_KEY_BITS)
			{
			/* printf("Running %-9s sanity check on keySize = %3d.\n",mName,t.keySize); */
			if (!quietVerify) printf(".");	/* show some progress */
			ClearTestData(&t);
			debug=0;			/* don't show debug info in this makeKey call */
			if (makeKey(&t.ki,DIR_ENCRYPT,t.keySize,hexString) != TRUE)
				FatalError("Error parsing key during sanity check %s",mName);
			debug=(mode == saveDebug);
			for (i=0;i<t.keySize/32;i++)
				if (t.ki.key32[i]!=hexVal[i])
					FatalError("Invalid key parse during sanity check %s",mName);
			for (testNum=0;testNum<lim;testNum++)
				{						/* run a bunch of encode/decode tests */
				if ((testNum&0x1F)==0)	/* periodic re-key time? */
					{
					for (j=0;j<t.keySize/4;j++)
						t.ki.keyMaterial[j]=hexTab[Rand() & 0xF];
					if (testNum==0)
						ClearTestData(&t);	/* give "easy" test data the first time */
					if (makeKey(&t.ki,DIR_ENCRYPT,t.keySize,t.ki.keyMaterial) != TRUE)
						FatalError("Encrypt makeKey during sanity check %s",mName);
					debug=0;
					if (makeKey(&k2  ,DIR_DECRYPT,t.keySize,t.ki.keyMaterial) != TRUE)
						FatalError("Decrypt makeKey during sanity check %s",mName);
					debug=(mode == saveDebug);
					}
				if (mode != MODE_ECB)				/* set IV  if needed*/
					for (j=0;j<BLOCK_SIZE/4;j++)
						ivString[j]=hexTab[(testNum)? Rand() & 0xF : 0];
				if ((debug) || (testNum == 0))
					n = (BLOCK_SIZE/8);				/* do only one block if debugging */
				else
					n = (BLOCK_SIZE/8)*(1 + (Rand() % (sizeof(pt)/(BLOCK_SIZE/8))));

				for (j=0;j<n;j++)					/* set random plaintext */
					pt[j]=(testNum) ? (BYTE) Rand() : 0;
				if (mode == MODE_CBC)
					{	/* check that CBC works as advertised */
					cipherInit(&t.ci,mode,ivString);
					t.ci.mode=MODE_ECB;
					for (q=0;q<BLOCK_SIZE/8;q++)	/* copy over the iv */
						t.pt[q] = (BYTE) (t.ci.iv32[q/4] >> (8*(q&3)));	/* auto-Bswap! */
					for (j=0;j<n;j+=BLOCK_SIZE/8)
						{
						for (q=0;q<BLOCK_SIZE/8;q++)	/* xor in next block */
							t.pt[q] ^= pt[j+q];
						debug=0;
						if (BLOCK_SIZE != blockEncrypt(&t.ci,&t.ki,t.pt,BLOCK_SIZE,t.pt))
							FatalError("blockEncrypt return value during sanity check %s",mName);
						debug=(mode == saveDebug);
						}
					t.ci.mode=MODE_CBC;			/* restore mode */
					}
				/* encrypt */
				cipherInit(&t.ci,mode,ivString);
				if (n*8 != blockEncrypt(&t.ci,&t.ki,pt,n*8,ct))
					FatalError("blockEncrypt return value during sanity check %s",mName);
				if (mode == MODE_CBC)			/* validate CBC "hash" */
					for (q=0;q<BLOCK_SIZE/8;q++)
						if (t.pt[q] != ct[n-BLOCK_SIZE/8+q])
							FatalError("CBC doesn't work during sanity check %s",mName);
				/* decrypt */
				cipherInit(&t.ci,mode,ivString);
				if (n*8 != blockDecrypt(&t.ci,&t.ki,ct,n*8,ct))
					FatalError("blockDecrypt return value during sanity check %s",mName);
				/* compare */
				for (j=0;j<n;j++)
					if (pt[j] != ct[j])
						{
						char s[128];
						sprintf(s,"Sanity check: encrypt/decrypt miscompare (mode=%s,keySize=%d)",
								mName,t.keySize);
						FatalError(s,"");
						}
				if (debug)
					{
					if (testNum >= debug)
						exit(1);
					printf(";-------------------------------------------------\n");
					}
				}
			}
		}
	debug=saveDebug;
	if (!quietVerify) printf("  OK\n");
	}


/*
+*****************************************************************************
*
* Function Name:	AES_FileIO
*
* Function:			Output to file or verify file contents vs. string
*
* Arguments:		f		=	opened file
*					s		=	string to output/compare (NULL-->reset, return)
*					errOK	=	do not fatalError on miscompare
*
* Return:			Zero --> compare ok
*
* Notes:			On miscompare, FatalError (unless errOK)
*
-****************************************************************************/
int AES_FileIO(FILE *f,CONST char *s,int errOK)
	{
	int  i;
	static int  lineNum=0;
	static int  j=0;
	static char line[516]="";

	if (s == NULL)	/* starting new file */
		{
		line[0]=j=lineNum=0;
		return 0;
		}

	if (!verify)
		{
		fprintf(f,s);
		return 0;
		}
				
	/* here to verify the file against the string */
	for (i=0;s[i];i++)
		{
		while (line[j] == 0)
			{
			lineNum++;
			if (fgets(line,sizeof(line)-4,f) == NULL)
				{
				if ((s[i]=='\n') && (s[i+1]==0))
					{
					line[0]=j=0;	/* missing final eol is ok */
					return 0;
					}
				FatalError("Unexpected EOF looking for %s",s);
				}
			if (verbose) printf(line);
			j=0;
			}
		if (s[i] != line[j])
			{
			if ((s[i] == '\n') && ((i==0) || (s[i-1] == '\n'))) continue; /* blank line skip */
			if (line[j] == '\n') {j++; continue; }
			if (!errOK)
				{
				char tmp[1024];
				sprintf(tmp,"Miscompare at line #%d:\n%s\nlooking for\n\n%%s",lineNum,line);
				FatalError(tmp,s);
				}
			line[0]=j=0;	/* let caller re-synch if desired */
			return 1;		/* return error flag */
			}
		j++;
		}

	return 0;
	}



/*
+*****************************************************************************
*
* Function Name:	AES_PutFileHeader
*
* Function:			Output a text header for AES test file
*
* Arguments:		fileName	=	name of file to create
*					testName	=	name of the specific test
*
* Return:			Open FILE pointer
*
* Notes:			If unable to create, gives FatalError
*
-****************************************************************************/
FILE *AES_PutFileHeader(CONST char *fileName,CONST char *testName)
	{
	char s[512];
	FILE *f;

	sprintf(s,"%s%s",filePath,fileName);
	if (verify)
		{
		if (!quietVerify) printf("Verifying file %s",s);
		f=fopen(s,"rt");
		AES_FileIO(NULL,NULL,0);		/* reset file read state */
		}
	else
		{
		printf("Creating file %s.\n",s);
		f=fopen(s,"wt");
		}
	if (f == NULL) FatalError("Unable to open file '%s'",s);

	sprintf(s,
			"\n=========================\n"
			"\n"
			"FILENAME:  \"%s\"\n"
			"\n"
			"%s\n"
			"\n"
			"Algorithm Name:       TWOFISH\n"
			"Principal Submitter:  Bruce Schneier, Counterpane Systems\n"
			"\n"
			"==========\n"
			"\n",
			fileName,testName);

	if (AES_FileIO(f,s,1))		
		{						/* header mismatch */
		if (!verify)
			FatalError("Miscompare while not verifying??","");
		printf("  \tWARNING:  header mismatch!");
		fgets(s,sizeof(s)-4,f);
		do	{					/* skip rest of "bad" header */
			if (fgets(s,sizeof(s)-4,f) == NULL)
				break;			/* end of file? */
			}
		while ((s[0] != '=') || (s[1] != '='));
		fgets(s,sizeof(s)-4,f);	/* skip trailing blank line */
		}

	if (verify)
		if (!quietVerify) printf("\n");

	return f;
	}

/*
+*****************************************************************************
*
* Function Name:	AES_PutTestResult
*
* Function:			Output a test result
*
* Arguments:		f		=	output file
*					name	=	name of field
*					p		=	pointer to bytes/dwords
*					cnt		=	# bytes to output
*					fmt32	=	nonzero --> p points to dwords, else bytes
* Return:			None.
*
* Notes:
*
-****************************************************************************/
void AES_PutBytes(FILE *f,CONST char *name,CONST void *p,int cnt,int fmt32)
	{
	char s[128];
	int i,j,a;
	if (p == NULL) return;

	a = (fmt32) ? ADDR_XOR : 0;	/* handle big/little endian on dword i/o */

	sprintf(s,"%s=",name);
	for (j=0;s[j];j++) ;
	for (i=0;i<cnt;i++)
		{
		s[j++]=hexTab[((BYTE *)p)[i ^ a] >> 4 ];
		s[j++]=hexTab[((BYTE *)p)[i ^ a] & 0xF];
		}
	s[j++]='\n';
	s[j  ]=0;	/* terminate the string */

	AES_FileIO(f,s,0);
	}


/*
+*****************************************************************************
*
* Function Name:	AES_printf
*
* Function:			Output a test result
*
* Arguments:		t		=	testData (includes output file)
*					fmt		=	format list (string of chars, see notes)
*
* Return:			None.
*
* Notes:
*	The fmt string specifies what is output. The following characters are
*	treated specially (S,K,P,C,v,V,I).  See the code in the switch statement
*	to see how they are handled.  All other characters (e.g., '\n') are
*	simply output to the file.
*
-****************************************************************************/
void AES_printf(testData *t,CONST char *fmt)
	{
	char s[40];

	for (s[1]=0;*fmt;fmt++)
		switch (*fmt)
			{
			case 'I': sprintf(s,"I=%d\n",t->I);				AES_FileIO(t->f,s,0);	break;
			case 'S': sprintf(s,"KEYSIZE=%d\n",t->keySize); AES_FileIO(t->f,s,0);	break;
			case 'P': AES_PutBytes(t->f,"PT" ,t->pt		 ,BLOCK_SIZE/8,0);	break;
			case 'C': AES_PutBytes(t->f,"CT" ,t->ct	     ,BLOCK_SIZE/8,0);	break;
			case 'v': AES_PutBytes(t->f,"IV" ,t->ci.IV   ,BLOCK_SIZE/8,0);	break;
			case 'V': AES_PutBytes(t->f,"IV" ,t->ci.iv32 ,BLOCK_SIZE/8,1);	break;
			case 'K': AES_PutBytes(t->f,"KEY",t->ki.key32,t->keySize/8,1);	break;
			default:  s[0]=*fmt; s[1]=0; AES_FileIO(t->f,s,0);				break;
			}
	}

/*
+*****************************************************************************
*
* Function Name:	AES_EndSection
*
* Function:			Insert a separator between sections
*
* Arguments:		t		=	ptr to testData, contains file
*
* Return:			None.
*
* Notes:
*
-****************************************************************************/
void AES_EndSection(testData *t)
	{
	AES_FileIO(t->f,"==========\n\n",0);
	}

/*
+*****************************************************************************
*
* Function Name:	AES_Close
*
* Function:			Close an AES text file
*
* Arguments:		t	=	testData ptr (contains f)
*
* Return:			None.
*
* Notes:
*
-****************************************************************************/
void AES_Close(testData *t)
	{
	fclose(t->f);
	}

/*
+*****************************************************************************
*
* Function Name:	DebugIO
*
* Function:			Output debug string
*
* Arguments:		s	=	string to output
*
* Return:			None.
*
* Notes:			
*
-****************************************************************************/
void DebugIO(CONST char *s)
	{
	if (debugTD)
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -