program t_aestab; (************************************************************************* DESCRIPTION : Calculate static AES tables REQUIREMENTS : TP5-7, D1-D7/D9-D10, FPC, VP EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : [1] http://csrc.nist.gov/fips/fips-197.pdf Version Date Author Modification ------- -------- ------- ------------------------------------------ 1.00 17.09.03 we Init version 1.01 18.09.03 we duplicate GF routines and rotword 1.10 05.10.03 we STD.INC, TP5-6 1.20 09.01.04 we Sbox is calculated, uses only mem_util 1.21 11.04.04 we D7, {$apptype console} if needed 1.22 27.17.04 we Te0..Te4, Td0..Td4 **************************************************************************) {$i STD.INC} {$ifdef APPCONS} {$apptype console} {$endif} uses {$ifdef WINCRT} wincrt, {$endif} mem_util; type bytearray = array[byte] of byte; longarray = array[byte] of longint; {encr} var SBox: bytearray; Te0,Te1,Te2,Te3,Te4: longarray; {decr} var InvSBox: bytearray; GLog, GPow: bytearray; Td0,Td1,Td2,Td3,Td4: longarray; {---------------------------------------------------------------------------} procedure CalcBaseTables; {-Calculate dynamic tables: power, log} var i, p: byte; begin {Power/Log tables} p := 1; for i:=0 to 254 do begin GPow[i] := p; GLog[p] := i; if p and $80 = 0 then p := (p shl 1) xor p else p := (p shl 1) xor p xor $1B; end; GPow[255] := 1; end; {---------------------------------------------------------------------------} function GMul(x,y: byte): byte; {-calculate x*y in GF(2^8)} var i: word; begin if (x=0) or (y=0) then GMul := 0 else begin i := word(GLog[x])+word(GLog[y]); if i>=255 then dec(i,255); GMul := GPow[i]; end; end; {---------------------------------------------------------------------------} function GM32(x,y: byte): longint; {-calculate x*y in GF(2^8) result as longint} begin GM32 := GMul(x,y); end; {---------------------------------------------------------------------------} procedure RotWord(var w: longint); {-rotate AES word} type TBA4 = packed array[0..3] of byte; var b: TBA4 absolute w; t: byte; begin t := b[0]; b[0] := b[1]; b[1] := b[2]; b[2] := b[3]; b[3] := t; end; {---------------------------------------------------------------------------} procedure CalcEncrTables; {-Calculate dynamic encr tables Te0..Te4, SBox} var i, p: byte; t: longint; function rot(b,n: byte): byte; begin rot := (b shr n) xor (b shl (8-n)); end; begin for i:=0 to 255 do begin end; for i:=0 to 255 do begin {SBox calculation, cf. [1] 5.1.1} if i=0 then p:=0 else p:=GPow[255-GLog[i]]; {p*i = 1} p := p xor rot(p,4) xor rot(p,5) xor rot(p,6) xor rot(p,7) xor $63; Sbox[i] := p; Te4[i] := $01010101*p; {Tex tables} t := GM32(2,p) or (longint(p) shl 8) or (longint(p) shl 16) or (GM32(3,p) shl 24); Te0[i] := t; RotWord(t); Te3[i] := t; RotWord(t); Te2[i] := t; RotWord(t); Te1[i] := t; end; end; {---------------------------------------------------------------------------} procedure CalcDecrTables; {-Calculate dynamic decr. tables: Td0..Td4, inverse SBox} var i, p: byte; t: longint; begin {InvSBox} for i:=0 to 255 do InvSBox[SBox[i]] := i; {Tdx tables} for i:=0 to 255 do begin p := InvSBox[i]; Td4[i] := $01010101*p; t := GM32(14,p) or (GM32(9,p) shl 8) or (GM32(13,p) shl 16) or (GM32(11,p) shl 24); Td0[i] := t; RotWord(t); Td3[i] := t; RotWord(t); Td2[i] := t; RotWord(t); Td1[i] := t; end; end; {---------------------------------------------------------------------------} procedure DumpByteTab(VName: string; var BA: bytearray); {-dump an array of bytes} var i: integer; begin writeln; writeln(VName, ': array[byte] of byte = ('); for i:= 0 to 255 do begin write(' $',HexByte(BA[i])); if i=255 then writeln(');') else if i and 15 = 15 then writeln(',') else write(','); end; end; {---------------------------------------------------------------------------} procedure DumpLongTab(VName: string; var LA: longarray); {-dump an array of longint} var i: integer; begin writeln; writeln(VName, ': array[byte] of longint = ('); for i:= 0 to 255 do begin write(' $',HexLong(LA[i])); if i=255 then writeln(');') else if i and 7 = 7 then writeln(',') else write(','); end; end; begin CalcBaseTables; CalcEncrTables; CalcDecrTables; DumpByteTab('GLog', GLog); DumpByteTab('GPow', GPow); DumpByteTab('SBox', SBox); DumpByteTab('InvSBox', InvSBox); DumpLongTab('Te0', Te0); DumpLongTab('Te1', Te1); DumpLongTab('Te2', Te2); DumpLongTab('Te3', Te3); DumpLongTab('Te4', Te4); DumpLongTab('Td0', Td0); DumpLongTab('Td1', Td1); DumpLongTab('Td2', Td2); DumpLongTab('Td3', Td3); DumpLongTab('Td4', Td4); end.