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

📄 rijndael-api-fst.c

📁 非常经典的加密算法
💻 C
字号:
/* rijndael-api-fst.c   v2.0   August '99 * Optimised ANSI C code * authors: v1.0: Antoon Bosselaers *          v2.0: Vincent Rijmen */#include <stdlib.h>#include <string.h>#include "rijndael-alg-fst.h"#include "rijndael-api-fst.h"int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial){	word8 k[MAXKC][4];	int i, j, t;		if (key == NULL) {		return BAD_KEY_INSTANCE;	}	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {		key->direction = direction;	} else {		return BAD_KEY_DIR;	}	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 		key->keyLen = keyLen;	} else {		return BAD_KEY_MAT;	}	if ( keyMaterial ) {		strncpy(key->keyMaterial, keyMaterial, keyLen/4);	}	ROUNDS = keyLen/32 + 6;	/* initialize key schedule: */ 	for(i = 0; i < key->keyLen/8; i++) {		t = key->keyMaterial[2*i];		if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;		else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; 		else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; 		else return BAD_KEY_MAT;				t = key->keyMaterial[2*i+1];		if ((t >= '0') && (t <= '9')) j ^= (t - '0');		else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); 		else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); 		else return BAD_KEY_MAT;				k[i / 4][i % 4] = (word8) j; 	}	rijndaelKeySched (k, key->keyLen, key->keySched);	if (direction == DIR_DECRYPT)		rijndaelKeyEnctoDec (key->keyLen, key->keySched);	return TRUE;}int cipherInit(cipherInstance *cipher, BYTE mode, char *IV){	int i, j, t;		if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {		cipher->mode = mode;	} else {		return BAD_CIPHER_MODE;	}		if (IV != NULL) { 		for(i = 0; i < 16; i++) {			t = IV[2*i];			if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;			else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4; 			else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4; 			else return BAD_CIPHER_INSTANCE;					t = IV[2*i+1];			if ((t >= '0') && (t <= '9')) j ^= (t - '0');			else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10); 			else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10); 			else return BAD_CIPHER_INSTANCE;						cipher->IV[i] = (word8) j;		} 	}	return TRUE;}int blockEncrypt(cipherInstance *cipher,	keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){	int i, k, numBlocks;	word8 block[16], iv[4][4];	if (cipher == NULL ||		key == NULL ||		key->direction == DIR_DECRYPT) {		return BAD_CIPHER_STATE;	}		numBlocks = inputLen/128;		switch (cipher->mode) {	case MODE_ECB: 		for (i = numBlocks; i > 0; i--) {						rijndaelEncrypt (input, outBuffer, key->keySched);						input += 16;			outBuffer += 16;		}		break;			case MODE_CBC:#if STRICT_ALIGN 		memcpy(block,cipher->IV,16); #else		*((word32*)block) =  *((word32*)(cipher->IV));		*((word32*)(block+4)) =  *((word32*)(cipher->IV+4));		*((word32*)(block+8)) =  *((word32*)(cipher->IV+8));		*((word32*)(block+12)) =  *((word32*)(cipher->IV+12));#endif				for (i = numBlocks; i > 0; i--) {			*((word32*)block) ^= *((word32*)(input));			*((word32*)(block+4)) ^= *((word32*)(input+4));			*((word32*)(block+8)) ^= *((word32*)(input+8));			*((word32*)(block+12)) ^= *((word32*)(input+12));			rijndaelEncrypt (block, outBuffer, key->keySched);						input += 16;			outBuffer += 16;		}		break;		case MODE_CFB1:#if STRICT_ALIGN 		memcpy(iv,cipher->IV,16); #else		*((word32*)iv[0]) = *((word32*)(cipher->IV));		*((word32*)iv[1]) = *((word32*)(cipher->IV+4));		*((word32*)iv[2]) = *((word32*)(cipher->IV+8));		*((word32*)iv[3]) = *((word32*)(cipher->IV+12));#endif		for (i = numBlocks; i > 0; i--) {			for (k = 0; k < 128; k++) {				*((word32*)block) = *((word32*)iv[0]);				*((word32*)(block+4)) = *((word32*)iv[1]);				*((word32*)(block+8)) = *((word32*)iv[2]);				*((word32*)(block+12)) = *((word32*)iv[3]);				rijndaelEncrypt (block, block, key->keySched);				outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);				iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);				iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);				iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);				iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);				iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);				iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);				iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);				iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);				iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);				iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);				iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);				iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);				iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);				iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);				iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);				iv[3][3] = (iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1;			}		}		break;		default:		return BAD_CIPHER_STATE;	}		return numBlocks*128;}int blockDecrypt(cipherInstance *cipher,	keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer){	int i, k, numBlocks;	word8 block[16], iv[4][4];	if (cipher == NULL ||		key == NULL ||		cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT) {		return BAD_CIPHER_STATE;	}		numBlocks = inputLen/128;		switch (cipher->mode) {	case MODE_ECB: 		for (i = numBlocks; i > 0; i--) { 			rijndaelDecrypt (input, outBuffer, key->keySched);			input += 16;			outBuffer += 16;		}		break;			case MODE_CBC:		/* first block */ 		rijndaelDecrypt (input, block, key->keySched);#if STRICT_ALIGN		memcpy(outBuffer,cipher->IV,16);   		*((word32*)(outBuffer)) ^= *((word32*)block);  		*((word32*)(outBuffer+4)) ^= *((word32*)(block+4));  		*((word32*)(outBuffer+8)) ^= *((word32*)(block+8));  		*((word32*)(outBuffer+12)) ^= *((word32*)(block+12));#else  		*((word32*)(outBuffer)) = *((word32*)block) ^ *((word32*)(cipher->IV));  		*((word32*)(outBuffer+4)) = *((word32*)(block+4)) ^ *((word32*)(cipher->IV+4));  		*((word32*)(outBuffer+8)) = *((word32*)(block+8)) ^ *((word32*)(cipher->IV+8));  		*((word32*)(outBuffer+12)) = *((word32*)(block+12)) ^ *((word32*)(cipher->IV+12));#endif				/* next blocks */		for (i = numBlocks-1; i > 0; i--) { 					rijndaelDecrypt (input, block, key->keySched);						*((word32*)(outBuffer+16)) = *((word32*)block) ^					*((word32*)(input-16));			*((word32*)(outBuffer+20)) = *((word32*)(block+4)) ^					*((word32*)(input-12));			*((word32*)(outBuffer+24)) = *((word32*)(block+8)) ^					*((word32*)(input-8));			*((word32*)(outBuffer+28)) = *((word32*)(block+12)) ^					*((word32*)(input-4));						input += 16;			outBuffer += 16;		}		break;		case MODE_CFB1:#if STRICT_ALIGN 		memcpy(iv,cipher->IV,16); #else		*((word32*)iv[0]) = *((word32*)(cipher->IV));		*((word32*)iv[1]) = *((word32*)(cipher->IV+4));		*((word32*)iv[2]) = *((word32*)(cipher->IV+8));		*((word32*)iv[3]) = *((word32*)(cipher->IV+12));#endif		for (i = numBlocks; i > 0; i--) {			for (k = 0; k < 128; k++) {				*((word32*)block) = *((word32*)iv[0]);				*((word32*)(block+4)) = *((word32*)iv[1]);				*((word32*)(block+8)) = *((word32*)iv[2]);				*((word32*)(block+12)) = *((word32*)iv[3]);				rijndaelEncrypt (block, block, key->keySched);				iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);				iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);				iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);				iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);				iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);				iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);				iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);				iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);				iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);				iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);				iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);				iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);				iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);				iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);				iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);				iv[3][3] = (iv[3][3] << 1) | (input[k/8] >> (7-(k&7))) & 1;				outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);			}		}		break;	default:		return BAD_CIPHER_STATE;	}		return numBlocks*128;}/** *	cipherUpdateRounds: * *	Encrypts/Decrypts exactly one full block a specified number of rounds. *	Only used in the Intermediate Value Known Answer Test.	 * *	Returns: *		TRUE - on success *		BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) */int cipherUpdateRounds(cipherInstance *cipher,	keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds){	int j;	word8 block[4][4];	if (cipher == NULL ||		key == NULL) {		return BAD_CIPHER_STATE;	}	for (j = 3; j >= 0; j--) {		/* parse input stream into rectangular array */  		*((word32*)block[j]) = *((word32*)(input+4*j));	}	switch (key->direction) {	case DIR_ENCRYPT:		rijndaelEncryptRound (block, key->keySched, rounds);	break;			case DIR_DECRYPT:		rijndaelDecryptRound (block, key->keySched, rounds);	break;			default: return BAD_KEY_DIR;	} 	for (j = 3; j >= 0; j--) {		/* parse rectangular array into output ciphertext bytes */		*((word32*)(outBuffer+4*j)) = *((word32*)block[j]);	}		return TRUE;}

⌨️ 快捷键说明

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