sbox bei aes128... bin ich bloed?

ach shit... ich hab das "multiplicative inverse" vergessen...

0x8d->0x5d, ist 0x8d also das "multiplicative inverse" von 0x02? ... hmmm...

conclusio: die sbox laesst sich berechnen mit
Code:
#include <stdio.h>
#include <stdlib.h>

unsigned char xtime(unsigned char a,unsigned char b)
{
        int i;
        unsigned int res1=0;
        unsigned int res2=a;
        for (i=0;i<8;i++)
        {
                if (b&1) res1^=res2;
                b>>=1;
                res2<<=1;
                if (res2&0x100) res2^=0x11b;
        }
        return (res1&0xff);
}

int main(void)
{
        unsigned char sbox_enc[256];
        unsigned char sbox_dec[256];
        int i;
        int j;
        unsigned int res;

        sbox_enc[0]=0x00;
        for (i=1;i<256;i++)
        {
                for (j=1;j<256;j++) if (xtime(i,j)==0x01) sbox_enc[i]=j; // inverse
        }



        for (i=0;i<256;i++)
        {
                unsigned char s;
                unsigned char b=sbox_enc[i];
                unsigned char c=0x63;
                unsigned char x;

                s=0x8f;
                x=0;
                for (j=0;j<8;j++)
                {
                        x|=(((b^(b>>4)^(b>>5)^(b>>6)^(b>>7)^c)&0x1)<<j);
                        s=(s<<7)|(s>>1);
                        b=(b<<7)|(b>>1);
                        c>>=1;
                }
                sbox_enc[i]=x;
                sbox_dec[x]=i;
        }
        printf("enc\n");
        for (i=0;i<256;i++)
        {
                printf("%02x ",sbox_enc[i]);
                if ((i&15)==15) printf("\n");
        }

        printf("dec\n");
        for (i=0;i<256;i++)
        {
                printf("%02x ",sbox_dec[i]);
                if ((i&15)==15) printf("\n");
        }

}
 
Zuletzt bearbeitet:
und damit kann man sich dann so ein kleines tool schreiben was die texteingaben verschluesselt. :)

(ich habs mal auf einfachheit getrimmt, nicht auf sicherheit oder fehlerfreiheit...)
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


const unsigned char sbox_enc[256]={0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16};
const unsigned char sbox_dec[256]={0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d};

unsigned char xtime(unsigned char a,unsigned char b)
{
	int i;
	unsigned int res1=0;
	unsigned int res2=a;
	for (i=0;i<8;i++)
	{
		if (b&1) res1^=res2;
		b>>=1;
		res2<<=1;
		if (res2&0x100) res2^=0x11b;
	}
	return (res1&0xff);
}

void subBytes(unsigned char* ptr,const unsigned char* subst)
{
	int i;
	for (i=0;i<16;i++) ptr[i]=subst[ptr[i]];
}
void shiftRows(unsigned char* ptr)
{
	unsigned char c0,c1,c2,c3;

	c0=ptr[ 1];c1=ptr[ 5];c2=ptr[ 9];c3=ptr[13];
	ptr[ 1]=c1;ptr[ 5]=c2;ptr[ 9]=c3;ptr[13]=c0;

	c0=ptr[ 2];c1=ptr[ 6];c2=ptr[10];c3=ptr[14];
	ptr[ 2]=c2;ptr[ 6]=c3;ptr[10]=c0;ptr[14]=c1;

	c0=ptr[ 3];c1=ptr[ 7];c2=ptr[11];c3=ptr[15];
	ptr[ 3]=c3;ptr[ 7]=c0;ptr[11]=c1;ptr[15]=c2;


}
void mixColumns(unsigned char* ptr)
{
	unsigned char c0,c1,c2,c3;
	int i;
	for (i=0;i<4;i++)
	{
		c0=ptr[0+i*4];c1=ptr[1+i*4];c2=ptr[2+i*4];c3=ptr[3+i*4];
		ptr[0+i*4]=xtime(c0,0x02)^xtime(c1,0x03)^c2^c3;
		ptr[1+i*4]=c0^xtime(c1,0x02)^xtime(c2,0x03)^c3;
		ptr[2+i*4]=c0^c1^xtime(c2,0x02)^xtime(c3,0x03);
		ptr[3+i*4]=xtime(c0,0x03)^c1^c2^xtime(c3,0x02);
	}
}
void addRoundKey(unsigned char* ptr,unsigned char* key)
{
	int i;
	for (i=0;i<16;i++)  ptr[i]^=key[i];
}
void expandKey(unsigned char* key,int round)
{
	unsigned char temp[4];
	unsigned char rcon=0x01;
	int i;

	for (i=0;i<round;i++) rcon=xtime(rcon,0x02);

	temp[3]=sbox_enc[(key[12])];
	temp[0]=sbox_enc[(key[13])]^rcon;
	temp[1]=sbox_enc[(key[14])];
	temp[2]=sbox_enc[(key[15])];


	for (i=0;i<4;i++)
	{
		key[i+ 0]^=temp[i];
		key[i+ 4]^=key[i+0];
		key[i+ 8]^=key[i+4];
		key[i+12]^=key[i+8];
	}	

}
void aes128encrypt(unsigned char* block,unsigned char* key,int rounds)
{
	int i;
	addRoundKey(block,key);	// first round
	for (i=0;i<rounds-2;i++)
	{
		expandKey(key,i);
		subBytes(block,sbox_enc);
		shiftRows(block);
		mixColumns(block);
		addRoundKey(block,key);
	}
	expandKey(key,rounds-2);	// final round
	subBytes(block,sbox_enc);
	shiftRows(block);
	addRoundKey(block,key);
}

void mixColumnsInv(unsigned char* ptr)
{
	unsigned char c0,c1,c2,c3;
	int i;
	for (i=0;i<4;i++)
	{
		c0=ptr[0+i*4];c1=ptr[1+i*4];c2=ptr[2+i*4];c3=ptr[3+i*4];
		ptr[0+i*4]=xtime(c0,0x0e)^xtime(c1,0x0b)^xtime(c2,0x0d)^xtime(c3,0x09);
		ptr[1+i*4]=xtime(c0,0x09)^xtime(c1,0x0e)^xtime(c2,0x0b)^xtime(c3,0x0d);
		ptr[2+i*4]=xtime(c0,0x0d)^xtime(c1,0x09)^xtime(c2,0x0e)^xtime(c3,0x0b);
		ptr[3+i*4]=xtime(c0,0x0b)^xtime(c1,0x0d)^xtime(c2,0x09)^xtime(c3,0x0e);
	}
}
void shiftRowsInv(unsigned char* ptr)
{
	unsigned char c0,c1,c2,c3;

	c0=ptr[ 1];c1=ptr[ 5];c2=ptr[ 9];c3=ptr[13];
	ptr[ 1]=c3;ptr[ 5]=c0;ptr[ 9]=c1;ptr[13]=c2;

	c0=ptr[ 2];c1=ptr[ 6];c2=ptr[10];c3=ptr[14];
	ptr[ 2]=c2;ptr[ 6]=c3;ptr[10]=c0;ptr[14]=c1;

	c0=ptr[ 3];c1=ptr[ 7];c2=ptr[11];c3=ptr[15];
	ptr[ 3]=c1;ptr[ 7]=c2;ptr[11]=c3;ptr[15]=c0;


}
void aes128decrypt(unsigned char* block,unsigned char* key,int rounds)
{
	int i,j;
	unsigned char keys[256][16];
	for (i=0;i<rounds-1 && i<256;i++)
	{
		memcpy(keys[i],key,16);
		expandKey(key,i);
	}
	memcpy(keys[i],key,16);
	rounds--;
	addRoundKey(block,keys[rounds]);
	shiftRowsInv(block);
	subBytes(block,sbox_dec);
	j=rounds-1;
	for (i=0;i<j;i++)
	{
		rounds--;
		addRoundKey(block,keys[rounds]);
		mixColumnsInv(block);	
		shiftRowsInv(block);
		subBytes(block,sbox_dec);
	}
	addRoundKey(block,keys[0]);	
	memset(keys,0,sizeof(keys));
}

int main(int argc,char** argv)
{
	unsigned char key[16];
	unsigned char block;
	int rounds=11;
	int i;
	unsigned char lc;
	unsigned char gotkey=0;
	unsigned char enc0dec1=0;
	unsigned char buf[1024];
	unsigned int len;

	fprintf(stderr,"*** aes128toy\n");
	fprintf(stderr,"*** (This is just a toy)\n");

	lc=0;
	for (i=1;i<argc;i++)
	{
		if (lc=='k') 
		{
			int l;
			int j;
			l=strlen(argv[i]);
			if (l==32)
			{
				unsigned char c1;
				unsigned char c2;
				gotkey=1;
				for (j=0;j<16;j++)
				{
					unsigned char x;
					c1=argv[i][j*2];
					c2=argv[i][j*2+1];

					if (c1>='0' && c1<='9') x=c1-'0';
					else if (c1>='a' && c1<='f') x=c1-'a'+10;
					else if (c1>='A' && c1<='F') x=c1-'A'+10;
					else gotkey=0;

					x<<=4;
					if (c2>='0' && c2<='9') x|=c2-'0';
					else if (c2>='a' && c2<='f') x|=c2-'a'+10;
					else if (c2>='A' && c2<='F') x|=c2-'A'+10;
					else gotkey=0;

					key[j]=x;
				}
			} 
		}
		if (lc=='r')
		{
			rounds=atoi(argv[i]);
		}

		if (strncmp("-k",argv[i],2)==0) lc='k';
		else if (strncmp("-K",argv[i],2)==0) lc='k';
		else if (strncmp("-r",argv[i],2)==0) lc='r';
		else if (strncmp("-R",argv[i],2)==0) lc='R';
		else if (strncmp("-e",argv[i],2)==0) enc0dec1=0;
		else if (strncmp("-E",argv[i],2)==0) enc0dec1=0;
		else if (strncmp("-d",argv[i],2)==0) enc0dec1=1;
		else if (strncmp("-D",argv[i],2)==0) enc0dec1=1;
		else lc=0;
	}

	if (!gotkey) fprintf(stderr,"sorry. illegal key.\n");
	if (rounds<11 || rounds>255) fprintf(stderr,"sorry. please choose a number between 11 and 256 for the rounds.\n");
	if (rounds<11 || rounds>255 || !gotkey) 
	{
		fprintf(stderr,"  %s -k KEY -r ROUNDS -e: encrypt\n",argv[0]);
		fprintf(stderr,"  %s -k KEY -r ROUNDS -d: decrypt\n",argv[0]);
		fprintf(stderr,"\n");
		fprintf(stderr,"  KEY is supposed to be a hexadecimal value 128bit long.\n");
		fprintf(stderr,"  for example 2b7e151628aed2a6abf7158809cf4f3c\n");
		fprintf(stderr,"\n");
		fprintf(stderr,"  ROUNDS is a number between 11 and 255.\n");

		return 0;
	}

	if (!enc0dec1)
	{
		fprintf(stderr,"starting encryption with %i rounds\n",rounds);
		fprintf(stderr,"please type in your secret message\n");
		while (!feof(stdin))
		{
			fgets(buf,sizeof(buf),stdin);
			len=strlen(buf);
			len=((len+15)/16)*16;

			for (i=0;i<len;i+=16)
			{
				aes128encrypt(&buf[i],key,rounds);
			}
			printf("[");
			for (i=0;i<len;i++)
			{
				printf("%02x",((unsigned int)buf[i])&0xff);
			}
			printf("]\n");
		}
	} else {
		int nibble=0;
		int j=0;
		unsigned char x;
		fprintf(stderr,"starting decryption with %i rounds\n",rounds);
		fprintf(stderr,"please type in the ciphertext\n");
		while (!feof(stdin))
		{
			fgets(buf,sizeof(buf),stdin);
			len=strlen(buf);
			j=0;
			for (i=0;i<len;i++)
			{
				unsigned char c=buf[i];
				if (c>='0' && c<='9') {x<<=4;x|=(c-'0');nibble++;}
				else if (c>='a' && c<='f') {x<<=4;x|=(c-'a'+10);nibble++;}
				else if (c>='A' && c<='F') {x<<=4;x|=(c-'A'+10);nibble++;}

				if (nibble==2) 
				{
					nibble=0;
					buf[j++]=x;
				}
			}
			if (j&0xf) fprintf(stderr,"sorry, that was not a multiple of 128bit\n");
			len=j;
			for (i=0;i<len;i+=16)
			{
				aes128decrypt(&buf[i],key,rounds);
			}
			for (i=0;i<len;i++)
			{
				x=buf[i];
				if (x>=' ' && x<127) printf("%c",x); else printf(".");
			}
			printf("\n");
		}
	}

	return 1;
}
 
Zuletzt bearbeitet:
Zurück
Oben