Задания к лабам / 3 / 03-Lit / Шифрование AES / app1
.pdfПРИЛОЖЕНИЕ 1 «Фрагмент кода системы Visual AES на языке C++ полной реализации алгоритма шифрования»
AES.H
#ifndef AES_H #define AES_H
#define ENCRYPT 0 #define DECRYPT 1
#include "StdAfx.h" #include "Resource.h" #include "winaesDlg.h"
/* rotates x one bit to the left */
#define ROTL(x) (((x)>>7)|((x)<<1))
/* Rotates 32-bit word left by 1, 2 or 3 byte */
#define ROTL8(x) (((x)<<8)|((x)>>24))
#define ROTL16(x) (((x)<<16)|((x)>>16))
#define ROTL24(x) (((x)<<24)|((x)>>8))
/* Function prototypes */
int KeyExpansion(CWinaesDlg* dlg, int nb,int nk, BYTE* key); void Encrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result); void InvDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result); void EquDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result);
int blockEncrypt(CWinaesDlg* dlg, BYTE *input, int inputLen, BYTE* result, int cipher_mode);
int blockDecrypt(CWinaesDlg* dlg, BYTE *input, int inputLen, BYTE* result, int decrypt_mode, int cipher_mode);
#endif
AES.CPP
#include <stdio.h> #include <stdlib.h> #include "Rijndael.h" #include "service.h"
#define BPOLY |
(BYTE) 0x11b |
|
|
#define MPOLY |
(BYTE) 0x101 |
|
|
/* Fixed Data */ |
|
/* Inverse Coefficients */ |
|
BYTE |
Co[4]={0x3,0x1,0x1,0x2}; |
||
BYTE InvCo[4]={0xB,0xD,0x9,0xE}; |
/* Inverse Coefficients */ |
||
/* Parameter-dependent data */ |
|
||
int N, Nk, Nb, Nr; |
|
|
|
DWORD fkey[120]; |
// inverse key |
||
DWORD ikey[120]; |
|||
DWORD ekey[120]; |
// equivalent key |
BYTE subbytes[256];
BYTE invsubbytes[256];
BYTE shfts[3][4];
static char strTmp[260], Tmp[260]; static DWORD s[8];
void ResetShifts()
{
for (int i=0; i<3; i++)
for (int j=0; j<4; j++)
if (i==2 && j==3) shfts[i][j]=4; else shfts[i][j]=j;
}
62
void shiftrow(BYTE* row, int n, int direct)
{
BYTE t; int j;
if (n)
{
for (int i=0; i<n; i++)
{
switch (direct)
{
case ENCRYPT: t=row[0];
for (j=1; j<Nb; j++) row[j-1]=row[j]; row[Nb-1]=t;
break;
case DECRYPT: t=row[Nb-1];
for (j = Nb-1; j>0; j--) row[j]=row[j-1]; row[0]=t;
break;
}
}
}
}
void ShifRows(BYTE* s, int direct)
{
BYTE temp[8]; int i, j;
for (i=0;i<4;i++)
{
for (j=0;j<Nb;j++) temp[j]=s[j*4+i];
shiftrow( temp, shfts[Nb/2-2][i], direct);
for (j=0;j<Nb;j++) s[j*4+i]=temp[j];
}
}
static DWORD pack(BYTE *b)
{ /* pack bytes into a 32-bit Word */
return ((DWORD)b[3]<<24)|((DWORD)b[2]<<16)|((DWORD)b[1]<<8)|(DWORD)b[0];
}
static void unpack(DWORD a,BYTE *b) { /* unpack bytes from a word */
b[0]=(BYTE)a;
b[1]=(BYTE)(a>>8);
b[2]=(BYTE)(a>>16);
b[3]=(BYTE)(a>>24);
}
static BYTE xtime(BYTE a, BYTE mod)
{
return ( ( a & 0x80) ? a<<1^mod : a<<1);
};
static BYTE add(BYTE a, BYTE b) {return a^b;}
/* multiply two elements of GF(2^m)
* needed for MixColumn and InvMixColumn */ static BYTE bmul(BYTE a,BYTE b, BYTE mod)
{
BYTE t,s, u;
u=b; t=a; s=0;
while (u)
{
if(u & 1) s^=t; u>>=1; t=xtime(t, mod);
63
}
return(s);
}
static BYTE square(BYTE a, BYTE mod)
{
return (bmul(a,a, mod));
}
static BYTE product(DWORD x,DWORD y, BYTE mod) { /* dot product of two 4-byte arrays */
BYTE xb[4],yb[4]; unpack(x,xb); unpack(y,yb);
return bmul(xb[0],yb[0], mod)^bmul(xb[1],yb[1], mod)^bmul(xb[2],yb[2], mod)^bmul(xb[3],yb[3], mod);
}
static BYTE finv(const BYTE x, BYTE mod)
{
BYTE result = x;
for (int i=1; i<7; i++) result = bmul(square(result , mod), x, mod); return square(result, mod);
}
/*
static BYTE ByteSubOLD(BYTE x)
{
DWORD w;
return ((w = (DWORD)finv((BYTE) x), w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(BYTE)(w^(w>>8))));
}
static BYTE InvByteSubOLD(BYTE x)
{
DWORD w;
return (finv((w = (DWORD)(BYTE) x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(BYTE)(w^(w>>8)))) );
}
*/
BYTE SBinvModulo;
BYTE SBmulModulo;
BYTE SBmulConst1;
BYTE SBmulConst2;
BYTE SBaddConst1;
BYTE SBaddConst2;
static BYTE ByteSubOLD(BYTE x)
{
BYTE result=x;
result = finv( result , SBinvModulo);
result = bmul( SBmulConst1, result, SBmulModulo); result = add( result, SBaddConst1);
return result;
}
static BYTE InvByteSubOLD(BYTE x)
{
BYTE result=x;
result = bmul( SBmulConst2, result, SBmulModulo); result = add(result, SBaddConst2);
result = finv( result, SBinvModulo); return result;
}
void FillTables(int mode)
{
for (int i=0; i<256; i++)
{
if (mode & 1) subbytes[i]= ByteSubOLD(i);
if (mode & 2) invsubbytes[i]= InvByteSubOLD(i);
}
}
void ResetTables()
64
{
SBinvModulo = BPOLY;
SBmulModulo = MPOLY; SBmulConst1 = 0x1f; SBmulConst2 = 0x4a; SBaddConst1 = 0x63; SBaddConst2 = 0x05;
FillTables(3);
}
static BYTE ByteSub(BYTE x)
{
return (subbytes[x]);
}
static BYTE InvByteSub(BYTE x)
{
return (invsubbytes[x]);
}
static DWORD SubDWord(DWORD a)
{
BYTE b[4]; unpack(a,b); b[0]=ByteSub(b[0]); b[1]=ByteSub(b[1]); b[2]=ByteSub(b[2]); b[3]=ByteSub(b[3]); return pack(b);
}
static void AddRoundKey(DWORD* s, DWORD* key, int nround)
{
for (int i=0; i<Nb; i++) s[i]^=key[Nb*nround + i];
}
void SubBytes(BYTE* s, int direct)
{
int j;
switch (direct)
{
case ENCRYPT:
for (j=0; j<Nb*4 ;j++) s[j]=ByteSub((BYTE)s[j]);
break; case DECRYPT:
for (j=0; j<Nb*4 ;j++) s[j]=InvByteSub((BYTE)s[j]);
break;
}
}
void MixCol(DWORD* s, int lenght,int direct) { /* matrix Multiplication */
DWORD m; BYTE b[4];
switch (direct)
{
case ENCRYPT: m=pack(Co); break;
case DECRYPT: m=pack(InvCo); break;
}
for (int i=0; i<lenght; i++)
{
b[3]=product(m, s[i], BPOLY); m=ROTL24(m);
b[2]=product(m, s[i], BPOLY); m=ROTL24(m);
65
b[1]=product(m, s[i], BPOLY); m=ROTL24(m);
b[0]=product(m, s[i], BPOLY); m=ROTL24(m);
s[i]=pack(b);
}
return;
}
void RecalcKeys(BYTE* key)
{
DWORD temp, rcon=1; int i, j;
N=Nb*(Nr+1);
for (i=0;i<Nk;i++)
{
fkey[i]=pack(&key[i*4]);
}
for(i = Nk; i < N; i++)
{
temp = fkey[i - 1];
if (i % Nk == 0)
{
temp = SubDWord(ROTL24(temp)) ^ rcon; rcon=(DWORD)xtime((BYTE)rcon, BPOLY );
}
else if ( (Nk > 6) && (i % Nk == 4) ) temp= SubDWord(temp);
fkey[i] = fkey[i - Nk] ^ temp;
}
for (i=0; i<N;i+=Nb)
{
for (j=0; j<Nb;j++) (ikey[i+j]= fkey[N-Nb-i+j], ekey[i+j]= fkey[N-Nb-i+j]);
if (i>= Nb && i<N-Nb)MixCol(&ekey[i], Nb, DECRYPT);
}
}
int KeyExpansion(CWinaesDlg* dlg, int nb,int nk, BYTE* key)
{
Nb=nb; Nk=nk;
(Nb>=Nk) ? Nr=6+Nb : Nr=6+Nk;
if(dlg->m_bRecalcKey) RecalcKeys(key);
return (Nr);
};
BOOL b_MixColumns;
BOOL b_AddRoundKey;
BOOL b_ShiftRows;
BOOL b_SubBytes;
void Encrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result)
{
int i,j;
for (i=j=0;i<Nb;i++,j+=4) s[i]=pack((BYTE *)&buff[j]);
i=0;
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].input %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
66
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&fkey[i*Nb], Tmp, Nb*4); sprintf(strTmp, "enc[%02u].k_sch %s", i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, fkey, 0);
}
for (i=1;i<Nr;i++)
{
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
if (!b_SubBytes)
{
SubBytes((BYTE*)s, ENCRYPT);
if (dlg->m_SBox)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_ShiftRows)
{
ShifRows((BYTE*)s, ENCRYPT);
if (dlg->m_SRow)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_MixColumns)
{
MixCol(s, Nb, ENCRYPT);
if (dlg->m_M_Col)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].m_col %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&fkey[i*Nb], Tmp, Nb*4); sprintf(strTmp, "enc[%02u].k_sch %s", i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, fkey, i);
}
}
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
if (!b_SubBytes)
{
SubBytes((BYTE*)s, ENCRYPT);
67
if (dlg->m_SBox)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_ShiftRows)
{
ShifRows((BYTE*)s, ENCRYPT);
if (dlg->m_SRow)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&fkey[i*Nb], Tmp, Nb*4); sprintf(strTmp, "enc[%02u].k_sch %s", i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, fkey, Nr);
}
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"enc[%02u].final %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
for (i=j=0;i<Nb;i++,j+=4) unpack(s[i],(BYTE *)&result[j]);
return;
}
void InvDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result)
{
int i,j;
for (i=j=0;i<Nb;i++,j+=4) s[i]=pack((BYTE *)&buff[j]);
i=0;
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].input %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, ikey, 0);
}
for (i=1;i<Nr;i++)
{
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
68
}
if (!b_ShiftRows)
{
ShifRows((BYTE*)s, DECRYPT);
if (dlg->m_SRow)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_SubBytes)
{
SubBytes((BYTE*)s, DECRYPT);
if (dlg->m_SBox)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, ikey, i);
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_add %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_MixColumns)
{
MixCol(s, Nb, DECRYPT);
if (dlg->m_M_Col)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].m_col %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
}
if (!b_ShiftRows)
{
ShifRows((BYTE*)s, DECRYPT);
if (dlg->m_SRow)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_SubBytes)
{
SubBytes((BYTE*)s, DECRYPT);
if (dlg->m_SBox)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
69
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"inv[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, ikey, i);
}
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"inv[%02u].final %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
for (i=j=0;i<Nb;i++,j+=4) unpack(s[i],(BYTE *)&result[j]);
return;
}
void EquDecrypt(CWinaesDlg* dlg, BYTE* buff, BYTE* result)
{
int i=0,j;
for ( i = j = 0; i < Nb; i++, j+=4) s[i]=pack((BYTE *)&buff[j]);
i=0;
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].input %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, ekey, 0);
}
for (i=1;i<Nr;i++)
{
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].start %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
if (!b_SubBytes)
{
SubBytes((BYTE*)s, DECRYPT);
if (dlg->m_SBox)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_ShiftRows)
{
ShifRows((BYTE*)s, DECRYPT);
if (dlg->m_SRow)
{
70
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_MixColumns)
{
MixCol(s, Nb, DECRYPT);
if (dlg->m_M_Col)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].m_col %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, ekey, i);
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_add %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
}
if (!b_SubBytes)
{
SubBytes((BYTE*)s, DECRYPT);
if (dlg->m_SBox)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_box %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_ShiftRows)
{
ShifRows((BYTE*)s, DECRYPT);
if (dlg->m_SRow)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].s_row %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
}
if (!b_AddRoundKey)
{
if (dlg->m_KSch)
{
CharStr2HexStr((BYTE*)&ikey[i*Nb], Tmp, Nb*4); sprintf(strTmp,"equ[%02u].k_sch %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
AddRoundKey(s, ekey, i);
}
if (dlg->m_Start)
{
CharStr2HexStr((BYTE*)s, Tmp, Nb*4); sprintf(strTmp,"equ[%02u].final %s",i, Tmp); dlg->m_eDebug.AddString(strTmp);
}
71