loca/Programming2013.02.15 17:29

AES(File ver.).zip

AES - 파일에서 불러오기

/*
Language : C
Coder : loca
Summary : AES Encrypt & Decrypt (FILE ver.)
Date : 2013.02.15
E-mail : loca@loca.kr
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void infoPrint(void);	// Print Help(info)
void statePrint(unsigned char state[0x04][0x04]);	// Print State
void SubBytes(unsigned char state[0x04][0x04], unsigned char S_BOX[0x10][0x10]);	// Sub Bytes
void ShiftRows(unsigned char state[0x04][0x04]);	// Shift Rows
void MixColumns(unsigned char state[0x04][0x04]);	// Mix Columns
void AddRoundKey(unsigned char state[0x04][0x04], unsigned char RoundKey[0x04][0x04]);	// Add RoundKey
void KeySchedule(unsigned char CipherKey[0x04][0x04], unsigned char S_BOX[0x10][0x10], int i);	// Key Schedule
void AESEncrypt(unsigned char state[0x04][0x04], unsigned char CipherKey[0x04][0x04], unsigned char S_BOX[0x10][0x10]);	// AES Encrypt Func

int main(int argc, char **argv){
	FILE * STATE_FILE;
	FILE * CIPHERYKEY_FILE;
	FILE * S_BOX_FILE;
	unsigned char state[0x04][0x04];
	unsigned char CipherKey[0x04][0x04];
	unsigned char S_BOX[0x10][0x10];
	int i, j;

	if(argc != 5){// 인자 갯수가 다를경우
		printf("인자 에러\n\n");
		infoPrint();
	}

	/* Encryption Start */
	if(strcmp(argv[1], "-e") == 0){// Encrypt
		printf("[Encrypt]\n");

		/* 파일 오픈 --start-- */
		if(((STATE_FILE = fopen(argv[2], "rb")) == NULL) ||
			((CIPHERYKEY_FILE = fopen(argv[3], "rb")) == NULL) ||
			((S_BOX_FILE = fopen(argv[4], "rb")) == NULL)){
				printf("File Open Error\n\n");
				infoPrint();
		}
		/* 파일 오픈 --end-- */

		/* 파일 사이즈 체크 --start-- */
		fseek(STATE_FILE, 0L, SEEK_END);
		fseek(CIPHERYKEY_FILE, 0L, SEEK_END);
		fseek(S_BOX_FILE, 0L, SEEK_END);

		if((ftell(STATE_FILE) != 16) ||
			((ftell(CIPHERYKEY_FILE) != 16)) ||
			((ftell(S_BOX_FILE) != 256))){
				printf("Size Error\n\n");
				infoPrint();
		}
		/* 파일 사이즈 체크 --end-- */

		fseek(STATE_FILE, 0L, SEEK_SET);
		fseek(CIPHERYKEY_FILE, 0L, SEEK_SET);
		fseek(S_BOX_FILE, 0L, SEEK_SET);

		/* 파일 내용 불러오기 --start-- */
		for(i=0; i<4; i++){
			for(j=0; j<4; j++){
				fread(&state[i][j], sizeof(char), 1, STATE_FILE);
				fread(&CipherKey[i][j], sizeof(char), 1, CIPHERYKEY_FILE);
			}
		}
		for(i=0; i<16; i++){
			for(j=0; j<16; j++){
				fread(&S_BOX[i][j], sizeof(char), 1, S_BOX_FILE);
			}
		}
		/* 파일 내용 불러오기 --end-- */

		AESEncrypt(state, CipherKey, S_BOX);	// Encryption Function
	}
	/* Encryption End */
	/* Decryption Start */
	else if(strcmp(argv[1], "-d") == 0){// Decrypt
		printf("[Decrypt]\n");
		printf("Not yet Decrypt\n");
		// Not yet

	}
	/* Decryption End */
	/* Type Error */
	else{
		printf("Type Error\n\n");
		infoPrint();
	}
	//	AESEncrypt(state, CipherKey, S_BOX);

	return 0;
}

void infoPrint(void){
	printf("[AES Encrypt & Decrypt by loca]\n");
	printf("Encrypt:\tAES.exe -e [PlainText] [CipherKey] [S-Box]\n");
	printf("Decrypt:\tAES.exe -d [CipherText] [CipherKey] [S-Box]\n");
	printf("Ex) AES.exe -e Text Key S-Box\n\n");
	printf("option:\n");
	printf("-e\t\tEncrypt\n");
	printf("-d\t\tDecrypt\n\n");
	printf("[PlainText]\tPlain Text File Name\t\t16byte\n");
	printf("[CipherText]\tCipher Text File Name\t\t16byte\n");
	printf("[CipherKey]\tCipher Key File Name\t\t16byte\n");
	printf("[S-Box]\t\tS-Box File Name\t\t\t256byte\n");
	exit(1);
}

void statePrint(unsigned char state[0x04][0x04]){
	int i, j;

	for(i=0; i<4; i++){
		for(j=0; j<4; j++){
			printf("%#04x ", state[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}

void SubBytes(unsigned char state[0x04][0x04], unsigned char S_BOX[0x10][0x10]){
	int i, j, x, y;

	for(i=0; i<4; i++){
		for(j=0; j<4; j++){
			x = state[i][j] >> 4;
			y = state[i][j] & 0x0f;
			state[i][j] = S_BOX[x][y];
		}
	}
}

void ShiftRows(unsigned char state[0x04][0x04]){
	int i, j, k, tmp;

	for(i=0; i<4; i++){
		for(j=4-i; j<4; j++){
			tmp = state[i][0];
			for(k=0; k<4-1; k++){
				state[i][k] = state[i][k+1];
			}
			state[i][3] = tmp;
		}
	}
}

void MixColumns(unsigned char state[0x04][0x04]){
	unsigned char a[0x04], b[0x04], h;
	int i, j;

	for(i=0; i<4; i++){
		for(j=0; j<4; j++){
			a[j] = state[j][i];
			h = (unsigned char)((signed char)state[j][i] >> 7);
			b[j] = state[j][i] << 1;
			b[j] ^= 0x1b & h;
		}
		state[0][i] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1];
		state[1][i] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2];
		state[2][i] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3];
		state[3][i] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0];
	}
}

void AddRoundKey(unsigned char state[0x04][0x04], unsigned char RoundKey[0x04][0x04]){
	int i, j;

	for(i=0; i<4; i++){
		for(j=0; j<4; j++){
			state[i][j] ^= RoundKey[i][j];
		}
	}
}

void KeySchedule(unsigned char CipherKey[0x04][0x04], unsigned char S_BOX[0x10][0x10], int i){
	unsigned char Rcon[0x04][0x0a]={
		{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36},
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
	};
	unsigned char tmp[0x04][0x04];
	unsigned char tmp2[0x04];
	int j, k, x, y;

	for(j=0; j<3; j++){// RotWord
		tmp2[j] = CipherKey[j+1][3];
	}
	tmp2[3] = CipherKey[0][3];

	for(j=0; j<4; j++){// SubBytes
		x = tmp2[j] >> 4;
		y = tmp2[j] - (x << 4);
		tmp2[j] = S_BOX[x][y];
	}

	for(j=0; j<4; j++){
		tmp[j][0] = CipherKey[j][0] ^ tmp2[j] ^ Rcon[j][i];
	}
	for(j=0; j<4; j++){
		for(k=1; k<4; k++){
			tmp[j][k] = CipherKey[j][k] ^ tmp[j][k-1];
		}
	}
	for(i=0; i<4; i++){
		for(j=0; j<4; j++){
			CipherKey[i][j] = tmp[i][j];
		}
	}
}

void AESEncrypt(unsigned char state[0x04][0x04], unsigned char CipherKey[0x04][0x04], unsigned char S_BOX[0x10][0x10]){
	int i;

	printf("PlanText\n");
	statePrint(state);

	AddRoundKey(state, CipherKey);

	for(i=0; i<9; i++){
		SubBytes(state, S_BOX);
		ShiftRows(state);
		MixColumns(state);
		KeySchedule(CipherKey, S_BOX, i);
		AddRoundKey(state, CipherKey);
	}

	SubBytes(state, S_BOX);
	ShiftRows(state);
	KeySchedule(CipherKey, S_BOX, i);
	AddRoundKey(state, CipherKey);

	printf("CipherText\n");
	statePrint(state);
}

이 게시물은 http://www.cs.bc.edu/~straubin/cs381-05/blockciphers/rijndael_ingles2004.swf 을 보며 작성된 글입니다.

AES(File ver.).zip

'loca > Programming' 카테고리의 다른 글

[C언어] AES - 파일에서 불러오기  (2) 2013.02.15
[C언어] AES - Encrypt  (0) 2013.02.15
[C언어] AES - Key Schedule  (0) 2013.02.14
[C언어] AES - Encryption process  (0) 2013.02.14
[C언어] AES - AddRoundKey  (0) 2013.02.14
[C언어] AES - MixColumns  (0) 2013.02.14
[C언어] AES - ShiftRows  (0) 2013.02.10
[C언어] AES - SubBytes  (0) 2013.02.10
[VS] Visual Studio 색상 변경  (0) 2011.11.13
Posted by L0C4
TAG ,