You are on page 1of 17

ПРИЛОЖЕНИЕ 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 */
BYTE Co[4]={0x3,0x1,0x1,0x2}; /* Inverse Coefficients */
BYTE InvCo[4]={0xB,0xD,0x9,0xE}; /* Inverse Coefficients */

/* Parameter-dependent data */

int N, Nk, Nb, Nr;

DWORD fkey[120];
DWORD ikey[120]; // inverse key
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
for (i=j=0;i<Nb;i++,j+=4) unpack(s[i],(BYTE *)&result[j]);

return;
}

void gen_random(BYTE *pb, int size)


{
for (int i=0; i < size; i++) pb[i]^=rand();
}

/* This function will add one to the given number (as a byte string).
* has been reached.
*/
static void increase_counter( BYTE *x, int x_size)
{
int i, y;

for (i = x_size - 1; i >= 0; i--)


{
y = 0;
if ( x[i] == 0xff)
{
x[i] = 0;
y = 1;
}
else x[i]++;

if (y==0) break;
}

return;
}

BYTE cipher_IV[32];

static BYTE block[32];


static BYTE *iv;

BOOL CFB_Debug = false;


BOOL OFB_Debug = false;
BOOL CTR_Debug = false;
BOOL CBC_Debug = false;
BOOL ECB_Debug = false;

int CFB_bits = 1;
int OFB_bits = 1;

int blockEncrypt(CWinaesDlg* dlg, BYTE *input, int inputLen, BYTE* result, int cipher_mode)
{
int i, j, k, l, numBlocks;

numBlocks = inputLen/(Nb<<2);

switch (cipher_mode)
{
case MODE_ECB:

for (i = 1; i <= numBlocks ; i++)


{
if (ECB_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= ECB AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);
}

Encrypt(dlg, input, result);

if (ECB_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

72
input += Nb<<2;
result += Nb<<2;
}
break;

case MODE_CBC:
iv = cipher_IV;

for (i = 1; i <= numBlocks; i++)


{
if (CBC_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= CBC AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

for (j=0; j < Nb; j++) ((DWORD*)block)[j] = ((DWORD*)input)[j] ^


((DWORD*)iv)[j];

Encrypt(dlg, block, result);

iv = result;

if (CBC_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

input += Nb<<2;
result += Nb<<2;
}
break;

case MODE_CFB1:

iv = (BYTE*) malloc(Nb<<2);
memcpy(iv, cipher_IV, Nb<<2);

for (i = 1; i <= numBlocks ; i++)


{
memcpy(result, input, Nb<<2);

if (CFB_Debug)
{
sprintf(strTmp,"= CFB AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

for (k = 0; k < (Nb<<5); k+=CFB_bits)


{
Encrypt(dlg, iv, block);

for (l = k; (l < (k + CFB_bits)) && (l < Nb<<5); l++)


{
result[l >> 3] ^= (block[0] & 0x80U) >> (l & 7);

for (j = 0; j < (Nb<<2) - 1; j++)


{
iv[j] = (iv[j] << 1) | (iv[j + 1] >> 7);
block[j] = (block[j] << 1) | (block[j + 1] >>
7);
}

73
iv[(Nb<<2)-1] = (iv[(Nb<<2)-1] << 1) | ((result[l >>
3] >> (7 - (l & 7))) & 1);
}
}
if (CFB_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

result += Nb<<2;
input += Nb<<2;
}

free(iv);
break;

case MODE_OFB:

iv = (BYTE*) malloc(Nb<<2);
memcpy(iv, cipher_IV, Nb<<2);

for (i = 1; i <= numBlocks ; i++)


{
memcpy(result, input, Nb<<2);

if (OFB_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= OFB AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

for (k = 0; k < (Nb<<5); k+= OFB_bits)


{
Encrypt(dlg, iv, block);

for (l = k; (l < (k + OFB_bits)) && (l < Nb<<5); l++)


{
result[l >> 3] ^= (block[0] & 0x80U) >> (l & 7);

for (j = 0; j < (Nb<<2) - 1; j++)


{
iv[j] = (iv[j] << 1) | (iv[j + 1] >> 7);
block[j] = (block[j] << 1) | (block[j + 1] >>
7);
}

iv[(Nb<<2)-1] = (iv[(Nb<<2)-1] << 1) | ((block[0] &


0x80U) >> 7 );
}
}
if (OFB_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

result += Nb<<2;
input += Nb<<2;
}
free(iv);
break;

74
case MODE_CTR:

iv = (BYTE*) malloc(Nb<<2);
memcpy(iv, cipher_IV, Nb<<2);

for (i = 1; i <= numBlocks; i++)


{
if (CTR_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= CTR AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

Encrypt(dlg, iv, result);

for (j=0; j < Nb; j++) ((DWORD*)result)[j] ^= ((DWORD*)input)[j];

increase_counter( iv, Nb<<2);

if (CTR_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

input += Nb<<2;
result += Nb<<2;
}

free(iv);
break;

default:
return BAD_CIPHER_STATE;
}

return 128*numBlocks;

int blockDecrypt(CWinaesDlg* dlg, BYTE *input, int inputLen, BYTE* result, int decrypt_mode, int
cipher_mode)
{
int i, j, k, l, numBlocks;

numBlocks = inputLen/(Nb<<2);

switch (cipher_mode)
{
case MODE_ECB:
for (i = 1; i <= numBlocks; i++) {

switch (decrypt_mode)
{
case DIR_DECRYPTINV:
if (ECB_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= ECB AES Nb=%u Nk=%u, block
%04u inverse decrypt ===============", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);
}
InvDecrypt(dlg, input, result);
break;

case DIR_DECRYPTEQU:
if (ECB_Debug)

75
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= ECB AES Nb=%u Nk=%u, block
%04u equivalent decrypt ============", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);
}
EquDecrypt(dlg, input, result);
break;
}
if (ECB_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

input += Nb<<2;
result += Nb<<2;
}
break;

case MODE_CBC:
iv = cipher_IV;
for (i = numBlocks; i > 0; i--) {

switch (decrypt_mode)
{
case DIR_DECRYPTINV:
if (CBC_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= CBC AES Nb=%u Nk=%u, block
%04u inverse decrypt ===============", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

InvDecrypt(dlg, input, block);


break;

case DIR_DECRYPTEQU:
if (ECB_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= CBC AES Nb=%u Nk=%u, block
%04u equivalent decrypt ============", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

EquDecrypt(dlg, input, block);


break;
}

for (j=0; j < Nb; j++) ((DWORD*)block)[j] ^= ((DWORD*)iv)[j];

memcpy(result, block, Nb<<2);

if (CBC_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}
input += Nb<<2;
result += Nb<<2;

76
}
break;

case MODE_CFB1:

iv = (BYTE*) malloc(Nb<<2);
memcpy(iv, cipher_IV, Nb<<2);

for (i = 1; i <= numBlocks; i++)


{
memcpy(result, input, Nb<<2);

if (CFB_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= CFB AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}
for (k = 0; k < (Nb<<5); k+=CFB_bits)
{
Encrypt(dlg, iv, block);

for (l = k; (l < (k + CFB_bits)) && (l < (Nb<<5)); l++)


{
result[l >> 3] ^= (block[0] & 0x80U) >> (l & 7);

for (j = 0; j < (Nb<<2)-1; j++)


{
iv[j] = (iv[j] << 1) | (iv[j + 1] >> 7);
block[j] = (block[j] << 1) | (block[j + 1] >>
7);
}
iv[(Nb<<2)-1] = (iv[(Nb<<2)-1] << 1) | ((input[l >>
3] >> (7 - (l & 7))) & 1);
}
}
if (CFB_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}
result += Nb<<2;
input += Nb<<2;
}
free(iv);
break;

case MODE_OFB:

iv = (BYTE*) malloc(Nb<<2);
memcpy(iv, cipher_IV, Nb<<2);

for (i = 1; i <= numBlocks; i++)


{
memcpy(result, input, Nb<<2);

if (OFB_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= OFB AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

for (k = 0; k < (Nb<<5); k+=OFB_bits)


{

77
Encrypt(dlg, iv, block);

for (l = k; (l < (k + OFB_bits)) && (l < (Nb<<5)); l++)


{
result[l >> 3] ^= (block[0] & 0x80U) >> (l & 7);

for (j = 0; j < (Nb<<2)-1; j++)


{
iv[j] = (iv[j] << 1) | (iv[j + 1] >> 7);
block[j] = (block[j] << 1) | (block[j + 1] >>
7);
}

iv[(Nb<<2)-1] = (iv[(Nb<<2)-1] << 1) | ((block[0] &


0x80U) >> 7 );
}
}
if (OFB_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

result += Nb<<2;
input += Nb<<2;
}
free(iv);
break;

case MODE_CTR:

iv = (BYTE*) malloc(Nb<<2);
memcpy(iv, cipher_IV, Nb<<2);

for (i = 1; i <= numBlocks; i++)


{
if (CTR_Debug)
{
//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);
sprintf(strTmp,"= CTR AES Nb=%u Nk=%u, block %04u encrypt
=======================", Nb, Nk, i);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4);


sprintf(strTmp," IV[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}

Encrypt(dlg, iv, result);

for (j=0; j < Nb; j++) ((DWORD*)result)[j] ^= ((DWORD*)input)[j];

increase_counter( iv, Nb<<2);

if (CTR_Debug)
{
CharStr2HexStr((BYTE*)input, Tmp, Nb*4);
sprintf(strTmp," in[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4);


sprintf(strTmp,"out[%04u]=%s", i, Tmp);
dlg->m_eDebug.AddString(strTmp);
}
input += Nb<<2;
result += Nb<<2;
}
free(iv);
break;
default:
return BAD_CIPHER_STATE;
}

return 128*numBlocks;
}

78

You might also like