AES CORE Unpipelined
module AES_Enc_core(
output [32*‘Nb-1:0] oCiphertext, // outputs ciphered text Nb=4
output oValid, // data at output is valid
output oKeysValid, //???????? bu neyin ready sinyali?
input iClk, iReset,
input [32*‘Nb-1:0] iPlaintext, // input data to be encrypted
input [32*‘Nk-1:0] iKey, // input cipther key
input iReady, // valid data to encrypt (text'in ready signali)
input iNewKey// signals new key is input (key'in ready sinyali)
);
// registered inputs
wire [32*‘Nk-1:0] wKeyReg; //key'in modullere bağlantısı, key'i taşıyor
wire wNewKeyReg, wReadyReg; //wNewKeyReg hiç kullanılmamış,
// wReadyReg moduller arasında textin ready sinyalini taşıyor
wire [127:0] wPlaintextReg, wBlockOutInit; //wPlaintextReg şifrelenecek teksti bloklar arasında taşıyor
// wBlockOutInit moduller arası ????? taşıyor
wire [127:0] wRoundKeyInit, wRoundKey; // wRoundKeyInit initial key
// wRoundKey round keys
// register inputs
InputRegsEnc InputRegs( .iClk(iClk),
.iReset(iReset),
.iKey(iKey),
.iNewKey(iNewKey),
.iPlaintext(iPlaintext),
.oKeysValid(oKeysValid),
.iReady(iReady),
.oKey(wKeyReg),
.oPlaintext(wPlaintextReg),
.oReady(wReadyReg)
);
// initial addition of round key
AddRoundKeyEnc InitialKey( .iClk(iClk),
.iReset(iReset),
.iBlockIn(wPlaintextReg),
.iRoundKey(wRoundKeyInit),
.oBlockOut(wBlockOutInit),
.iReady(wReadyReg),
.oValid(wValidInit)//wValid init tanımlanmalı
);
// Number of rounds is a function of key size (10, 12, or 14)
// Key expansion block
KeyExpansionEnc KeyExpansion( .iClk(iClk),
.iReset(iReset),
.iNkKeys(wKeyReg),
.iReady(wReadyReg),
.oRoundKey(wRoundKey)
);
RoundsIterEnc RoundsIter( .iClk(iClk),
.iReset(iReset),
.iBlockIn(wBlockOutInit),
.oBlockOut(oCiphertext),
.iReady(wValidInit),
.oValid(oValid),
.iRoundKey(wRoundKey)
);
‘ifdef Nk4
assign wRoundKeyInit = wKeyReg[128-1:0];
‘endif
‘ifdef Nk6
assign wRoundKeyInit = wKeyReg[192-1:192-128];
‘endif
‘ifdef Nk8
assign wRoundKeyInit = wKeyReg[256-1:256-128];
‘endif
endmodule
AES CORE Semi-pipelined
module AES_core( output [32*‘Nb-1:0] oCiphertext, // output cipthertext output oValid, // data at output is valid // signals that new key has been completely processed output oKeysValid, input iClk, iReset, input [32*‘Nb-1:0] iPlaintext, // input data to be encrypted input [32*‘Nk-1:0] iKey, // input cipther key input iReady, // valid data to encrypt input iNewKey // signals new key is input ); wire [32*‘Nb-1:0] wRoundKey1, wRoundKey2, wRoundKey3, wRoundKey4, wRoundKey5, wRoundKey6, wRoundKey7, wRoundKey8, wRoundKey9, wRoundKeyFinal, wRoundKeyInit; wire [32*‘Nb-1:0] wBlockOut1, wBlockOut2, wBlockOut3, wBlockOut4, wBlockOut5, wBlockOut6, wBlockOut7, wBlockOut8, wBlockOut9, wBlockOutInit; wire wValid1, wValid2, wValid3, wValid4, wValid5, wValid6, wValid7, wValid8, wValid9, wValidFinal, wValidInit; wire [32*‘Nk-1:0] wNkKeysInit; wire [3:0] wKeyIterInit; wire [3:0] wKeyIterModNkInit; wire [3:0] wKeyIterDivNkInit; wire wNewKeyInit; wire [128*(‘Nr+1)-1:0] wKeys; // complete set of round keys // registered inputs wire [32*‘Nk-1:0] wKeyReg; wire wNewKeyReg, wReadyReg; wire [127:0] wPlaintextReg; // register inputs InputRegs InputRegs(.iClk(iClk), .iReset(iReset), .iKey(iKey), .iNewKey(iNewKey), .iPlaintext(iPlaintext), .iReady(iReady), .oKey(wKeyReg), .oNewKey(wNewKeyReg), .oPlaintext(wPlaintextReg), .oReady(wReadyReg) ); // initial key expansion KeyExpInit KeyExpInit( .iClk(iClk), .iReset(iReset), .iNkKeys(wKeyReg), .iNewKey(wNewKeyReg), .oKeyIter(wKeyIterInit), .oNewKey(wNewKeyInit), .oKeyIterModNk(wKeyIterModNkInit), .oNkKeys(wNkKeysInit), .oKeyIterDivNk(wKeyIterDivNkInit) ); // initial addition of round key AddRoundKey InitialKey( .iClk(iClk), .iReset(iReset), .iBlockIn(wPlaintextReg), .iRoundKey(wRoundKeyInit), .oBlockOut(wBlockOutInit), .iReady(wReadyReg), .oValid(wValidInit) ); // Number of rounds is a function of key size (10, 12, or 14) // Key expansion block KeyExpansion KeyExpansion( .iClk(iClk), .iReset(iReset), .iKeyIter(wKeyIterInit), .iKeyIterModNk(wKeyIterModNkInit), .iNkKeys(wNkKeysInit), .iKeyIterDivNk(wKeyIterDivNkInit), .iNewKey(wNewKeyInit), .oKeys(wKeys), .oKeysValid(oKeysValid) ); // round transformation blocks Round R1( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockOutInit), .iRoundKey(wRoundKey1), .oBlockOut(wBlockOut1), .iReady(wValidInit), .oValid(wValid1) ); Round R9( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockOut8), .iRoundKey(wRoundKey9), .oBlockOut(wBlockOut9), .iReady(wValid8), .oValid(wValid9) ); // 10 rounds total // Initial key addition assign wRoundKeyFinal = wKeys[128*(‘Nr-7)-1:128*(‘Nr-8)]; // round key assignments assign wRoundKey9 = wKeys[128*(‘Nr-6)-1: 128*(‘Nr-7)]; assign wRoundKey8 = wKeys[128*(‘Nr-5)-1: 128*(‘Nr-6)]; assign wRoundKey7 = wKeys[128*(‘Nr-4)-1: 128*(‘Nr-5)]; assign wRoundKey6 = wKeys[128*(‘Nr-3)-1: 128*(‘Nr-4)]; assign wRoundKey5 = wKeys[128*(‘Nr-2)-1: 128*(‘Nr-3)]; assign wRoundKey4 = wKeys[128*(‘Nr-1)-1: 128*(‘Nr-2)]; assign wRoundKey3 = wKeys[128*‘Nr-1: 128*(‘Nr-1)]; assign wRoundKey2 = wKeys[128*(‘Nr+1)-1: 128*‘Nr]; assign wRoundKey1 = wNkKeysInit[128-1:0]; assign wRoundKeyInit = iKey[128-1:0]; FinalRound FinalRound( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockOut9), .iRoundKey(wRoundKeyFinal), .oBlockOut(oCiphertext), .iReady(wValid9), .oValid(oValid) ); endmodule
AES CORE Fully-pipelined
module AES_core( output [32*‘Nb-1:0] oCiphertext, // output cipthertext output oValid, // data at output is valid input iClk, iReset, input [32*‘Nb-1:0] iPlaintext, // input data to be encrypted input [32*‘Nk-1:0] iKey, // input cipther key input iReady // valid data to encrypt ); wire [32*‘Nb-1:0] wRoundKey1, wRoundKey2, wRoundKey3, wRoundKey4, wRoundKey5, wRoundKey6, wRoundKey7, wRoundKey8, wRoundKey9, wRoundKeyFinal,wRoundKeyInit; wire [32*‘Nb-1:0] wBlockOut1, wBlockOut2, wBlockOut3, wBlockOut4, wBlockOut5, wBlockOut6, wBlockOut7, wBlockOut8, wBlockOut9, wBlockOutInit; wire [32*‘Nk-1:0] wNkKeys1, wNkKeys2, wNkKeys3, wNkKeys4, wNkKeys5, wNkKeys6, wNkKeys7, wNkKeys8, wNkKeys9, wNkKeysFinal, wNkKeysInit; wire [3:0] wKeyIter1, wKeyIter2, wKeyIter3, wKeyIter4, wKeyIter5, wKeyIter6, wKeyIter7, wKeyIter8, wKeyIter9, wKeyIterFinal, wKeyIterInit; wire [3:0] wKeyIterModNk1, wKeyIterModNk2, wKeyIterModNk3, wKeyIterModNk4, wKeyIterModNk5, wKeyIterModNk6, wKeyIterModNk7, wKeyIterModNk8, wKeyIterModNk9, wKeyIterModNkFinal, wKeyIterModNkInit; wire [3:0] wKeyIterDivNk1, wKeyIterDivNk2, wKeyIterDivNk3, wKeyIterDivNk4, wKeyIterDivNk5, wKeyIterDivNk6, wKeyIterDivNk7, wKeyIterDivNk8, wKeyIterDivNk9, wKeyIterDivNkFinal, wKeyIterDivNkInit; wire wValid1, wValid2, wValid3, wValid4, wValid5, wValid6, wValid7, wValid8, wValid9, wValidFinal, wValidInit; // registered inputs wire [32*‘Nk-1:0] wKeyReg; wire wReadyReg; wire [127:0] wPlaintextReg; // Initial key addition assign wRoundKeyInit = wKeyReg[32*‘Nk-1:32*‘Nk-128]; // round key assignments assign wRoundKey1 = wNkKeysInit[32*‘Nb-1:0]; assign wRoundKey2 = wNkKeys1[32*‘Nb-1:0]; assign wRoundKey3 = wNkKeys2[32*‘Nb-1:0]; assign wRoundKey4 = wNkKeys3[32*‘Nb-1:0]; assign wRoundKey5 = wNkKeys4[32*‘Nb-1:0]; assign wRoundKey6 = wNkKeys5[32*‘Nb-1:0]; assign wRoundKey7 = wNkKeys6[32*‘Nb-1:0]; assign wRoundKey8 = wNkKeys7[32*‘Nb-1:0]; assign wRoundKey9 = wNkKeys8[32*‘Nb-1:0]; // register inputs InputRegs InputRegs(.iClk(iClk), .iReset(iReset), .iKey(iKey), .iPlaintext(iPlaintext), .iReady(iReady), .oKey(wKeyReg), .oPlaintext(wPlaintextReg), .oReady(wReadyReg) ); // initial key expansion KeyExpInit KeyExpInit( .iClk(iClk), .iReset(iReset), .iNkKeys(wKeyReg), .oKeyIter(wKeyIterInit), .oKeyIterModNk(wKeyIterModNkInit), .oNkKeys(wNkKeysInit), .oKeyIterDivNk(wKeyIterDivNkInit) ); // initial addition of round key AddRoundKey InitialKey( .iClk(iClk), .iReset(iReset), .iBlockIn(wPlaintextReg), .iRoundKey(wRoundKeyInit), .oBlockOut(wBlockOutInit), .iReady(wReadyReg), .oValid(wValidInit) ); // Number of rounds is a function of key size (10, 12, or 14) // Key expansion blocks KeyExpBlock KeyExpBlock1( .iClk(iClk), .iReset(iReset), .iKeyIter(wKeyIterInit), .iKeyIterModNk(wKeyIterModNkInit), .iNkKeys(wNkKeysInit), .iKeyIterDivNk(wKeyIterDivNkInit), .oKeyIter(wKeyIter1), .oKeyIterModNk(wKeyIterModNk1), .oNkKeys(wNkKeys1), .oKeyIterDivNk(wKeyIterDivNk1) ); KeyExpBlock KeyExpBlock8( .iClk(iClk), .iReset(iReset), .iKeyIter(wKeyIter7), .iKeyIterModNk(wKeyIterModNk7), .iNkKeys(wNkKeys7), .iKeyIterDivNk(wKeyIterDivNk7), .oKeyIter(wKeyIter8), .oKeyIterModNk(wKeyIterModNk8), .oNkKeys(wNkKeys8), .oKeyIterDivNk(wKeyIterDivNk8) ); // round transformation blocks Round R1( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockOutInit), .iRoundKey(wRoundKey1), .oBlockOut(wBlockOut1), .iReady(wValidInit), .oValid(wValid1) ); //... Round R9( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockOut8), .iRoundKey(wRoundKey9), .oBlockOut(wBlockOut9), .iReady(wValid8), .oValid(wValid9) ); // 10 rounds total assign wRoundKeyFinal = wNkKeys9[32*‘Nb-1:0]; KeyExpBlock KeyExpBlock9( .iClk(iClk), .iReset(iReset), .iKeyIter(wKeyIter8), .iKeyIterModNk(wKeyIterModNk8), .iNkKeys(wNkKeys8), .iKeyIterDivNk(wKeyIterDivNk8), .oKeyIter(wKeyIter9), .oKeyIterModNk(wKeyIterModNk9), .oNkKeys(wNkKeys9), .oKeyIterDivNk(wKeyIterDivNk9) ); FinalRound FinalRound( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockOut9), .iRoundKey(wRoundKeyFinal), .oBlockOut(oCiphertext), .iReady(wValid9), .oValid(oValid) ); endmodule
InputRegsEnc
// Registers all inputs module InputRegsEnc( output reg [32 *‘Nk - 1:0] oKey, output reg oReady, oKeysValid, output reg [127:0] oPlaintext, input iClk, iReset, input [32 *‘Nk - 1:0] iKey, input iNewKey, iReady, input [127:0] iPlaintext ); reg [32 *‘Nk - 1:0] KeyReg; reg NewKeyReg, ReadyStaged; reg [127:0] PlaintextStaged; always @(posedge iClk or negedge iReset) if (!iReset) begin oKey <= 0; oReady <= 0; oPlaintext <= 0; NewKeyReg <= 0; KeyReg <= 0; oKeysValid <= 0; ReadyStaged <= 0; PlaintextStaged <= 0; end else begin NewKeyReg <= iNewKey; KeyReg <= iKey; if (NewKeyReg) begin oKeysValid <= 1; oKey <= KeyReg; end else oKeysValid <= 0; ReadyStaged <= iReady; PlaintextStaged <= iPlaintext; oReady <= ReadyStaged; oPlaintext <= PlaintextStaged; end endmodule
ADDRoundKey
// This block performs the AddRoundKey transformation on the iBlockIn data // and places it on oBlockOut module AddRoundKeyEnc( output reg [32 *‘Nb - 1:0] oBlockOut, output reg oValid, input iClk, iReset, iReady, // Data input to be transformed input [32 *‘Nb - 1:0] iBlockIn, iRoundKey ); reg [32 *‘Nb - 1:0] BlockOutStaged; reg ValidStaged; always @(posedge iClk or negedge iReset) if (!iReset) begin oBlockOut <= 0; oValid <= 0; BlockOutStaged <= 0; ValidStaged <= 0; end else begin BlockOutStaged <= iBlockIn ^ iRoundKey; ValidStaged <= iReady; oBlockOut <= BlockOutStaged; oValid <= ValidStaged; end endmodule
KeyExpansionEnc
module KeyExpansionEnc( output [128-1:0] oRoundKey, input iClk, iReset, // The last Nk keys generated in initial key expansion input [32*‘Nk-1:0] iNkKeys, input iReady// signals a new key is input ); wire [3:0] KeyIterIn, KeyIterOut; wire [3:0] KeyIterDivNkIn, KeyIterDivNkOut; wire [3:0] KeyIterModNkIn, KeyIterModNkOut; wire [32*‘Nk-1:0] NkKeysOut, NkKeysIn; wire wReady; assign wReady = iReady; assign KeyIterIn = wReady ? ‘Nk : KeyIterOut; assign oRoundKey = NkKeysOut[32*‘Nk-1:32*‘Nk-128]; assign KeyIterModNkIn = wReady ? 4’h0 : KeyIterModNkOut; assign KeyIterDivNkIn = wReady ? 4’h1 : KeyIterDivNkOut; assign NkKeysIn = wReady ? iNkKeys : NkKeysOut; KeyExp1Enc KeyExp1( .iClk(iClk), .iReset(iReset), .iKeyIter(KeyIterIn), .iKeyIterModNk(KeyIterModNkIn), .iNkKeys(NkKeysIn), .iKeyIterDivNk(KeyIterDivNkIn), .oKeyIter(KeyIterOut), .oKeyIterModNk(KeyIterModNkOut), .oNkKeys(NkKeysOut), .oKeyIterDivNk(KeyIterDivNkOut) ); endmodule
KeyExp1Enc
module KeyExp1Enc(
// updated values to be passed to next iteration
output [3:0] oKeyIter, oKeyIterModNk,oKeyIterDivNk,
output [32*‘Nk-1:0] oNkKeys,
input iClk, iReset,
// represents total # of iterations and value mod Nk
input [3:0] iKeyIter, iKeyIterModNk, iKeyIterDivNk,
// The last Nk keys generated in key expansion
input [32*‘Nk-1:0] iNkKeys
);
// updated values to be passed to next iteration
reg [3:0] oKeyIter, oKeyIterModNk, oKeyIterDivNk;
reg [32*‘Nk-1:0] OldKeys;
reg [31:0] InterKey; // intermediate key value
wire [32*‘Nk-1:0] oNkKeys;
wire [31:0] PrevKey, RotWord, SubWord, NewKeyWord;
wire [31:0] KeyWordNk;
wire [31:0] Rcon;
assign PrevKey = iNkKeys[31:0]; // last word in key array
assign KeyWordNk = OldKeys[32*‘Nk-1:32*‘Nk-32];
// 1 byte cyclic permutation
assign RotWord = {PrevKey[23:0], PrevKey[31:24]};
// new key calculated in this round
assign NewKeyWord = KeyWordNk ^ InterKey;
// calculate new key set
assign oNkKeys = {OldKeys[32*‘Nk-33:0], NewKeyWord};
// calculate Rcon over GF(2^8)
assign Rcon = iKeyIterDivNk == 8’h1 ? 32’h01000000:
iKeyIterDivNk == 8’h2 ? 32’h02000000:
iKeyIterDivNk == 8’h3 ? 32’h04000000:
iKeyIterDivNk == 8’h4 ? 32’h08000000:
iKeyIterDivNk == 8’h5 ? 32’h10000000:
iKeyIterDivNk == 8’h6 ? 32’h20000000:
iKeyIterDivNk == 8’h7 ? 32’h40000000:
iKeyIterDivNk == 8’h8 ? 32’h80000000:
iKeyIterDivNk == 8’h9 ? 32’h1b000000:
32’h36000000;
SboxEnc SboxEnc0(.iPreMap(RotWord[31:24]),.oPostMap(SubWord[31:24]));
SboxEnc SboxEnc1(.iPreMap(RotWord[23:16]),.oPostMap(SubWord[23:16]));
SboxEnc SboxEnc2(.iPreMap(RotWord[15:8]), .oPostMap(SubWord[15:8]));
SboxEnc SboxEnc3(.iPreMap(RotWord[7:0]), .oPostMap(SubWord[7:0]));
‘ifdef Nk8
wire [31:0] SubWordNk8;
// Substitution only when Nk = 8
SboxEnc SboxEncNk8_0(.iPreMap(PrevKey[31:24]),.oPostMap(SubWordNk8[31:24]));
SboxEnc SboxEncNk8_1(.iPreMap(PrevKey[23:16]),.oPostMap(SubWordNk8[23:16]));
SboxEnc SboxEncNk8_2(.iPreMap(PrevKey[15:8]), .oPostMap(SubWordNk8[15:8]));
SboxEnc SboxEncNk8_3(.iPreMap(PrevKey[7:0]), .oPostMap(SubWordNk8[7:0]));
‘endif
always @(posedge iClk)
if(!iReset)
begin
oKeyIter <= 0;
oKeyIterModNk <= 0;
InterKey <= 0;
oKeyIterDivNk <= 0;
OldKeys <= 0;
end
else
begin
oKeyIter <= iKeyIter + 1;
OldKeys <= iNkKeys;
// update "Key iteration mod Nk" for next iteration
if(iKeyIterModNk + 1 == ‘Nk)
begin
oKeyIterModNk <= 0;
oKeyIterDivNk <= iKeyIterDivNk+1;
end
else
begin
oKeyIterModNk <= iKeyIterModNk + 1;
oKeyIterDivNk <= iKeyIterDivNk;
end
if(iKeyIterModNk == 0)
InterKey <= SubWord ^ Rcon;
‘ifdef Nk8
// an option only for Nk = 8
else if(iKeyIterModNk == 4)
InterKey <= SubWordNk8;
‘endif
else
InterKey <= PrevKey;
end
endmodule
RoundsIterEnc
// This module iterates the intermediate data through the round block module RoundsIterEnc( output reg [32*‘Nb-1:0] oBlockOut, output reg oValid, input iClk, iReset, input [32*‘Nb-1:0] iBlockIn, input iReady, input [127:0] iRoundKey ); reg [3:0] round;// keeps track of current round reg ValidReg; reg [127:0] BlockOutReg; wire [127:0] wBlockIn, wBlockOut; wire wReady, wValid; assign wBlockIn = iReady ? iBlockIn: wBlockOut; // ready is asserted when we have a new input or when the // previous round has completed and we are not done assign wReady = iReady || (wValid && (round !=‘Nr)); RoundEnc Riter( .iClk(iClk), .iReset(iReset), .iBlockIn(wBlockIn), .iRoundKey(iRoundKey), .oBlockOut(wBlockOut), .iReady(wReady), .oValid(wValid), .iRound(round) ); always @(posedge iClk or negedge iReset) if(!iReset) begin round <= 0; oValid <= 0; oBlockOut <= 0; ValidReg <= 0; BlockOutReg <= 0; end else begin oValid <= ValidReg; oBlockOut <= BlockOutReg; if(iReady) begin round <= 1; ValidReg <= 0; end else if(wValid && (round != 0)) begin // rounds continue and data has completed another round if(round == ‘Nr) begin // data has completed last round round <= 0; ValidReg <= 1; BlockOutReg <= wBlockOut; end else begin // data will continue through rounds round <= round + 1; ValidReg <= 0; end end else ValidReg <= 0; end endmodule
RoundEnc
module RoundEnc( output [32*‘Nb-1:0] oBlockOut, output oValid, input iClk, iReset, input [32*‘Nb-1:0] iBlockIn, iRoundKey, input iReady, input [3:0] iRound ); wire [32*‘Nb-1:0] wSubOut, wShiftOut, wMixOut; wire wValidSub, wValidShift, wValidMix; SubBytesEnc sub(.iClk(iClk), .iReset(iReset), .iBlockIn(iBlockIn), .oBlockOut(wSubOut), .iReady(iReady), .oValid(wValidSub) ); ShiftRowsEnc shift( .iBlockIn(wSubOut), .oBlockOut(wShiftOut), .iReady(wValidSub), .oValid(wValidShift) ); MixColumnsEnc mixcolumn(.iClk(iClk), .iReset(iReset), .iBlockIn(wShiftOut), .oBlockOut(wMixOut), .iReady(wValidShift), .oValid(wValidMix), .iRound(iRound) ); AddRoundKeyEnc addroundkey( .iClk(iClk), .iReset(iReset), .iBlockIn(wMixOut), .iRoundKey(iRoundKey), .oBlockOut(oBlockOut), .iReady(wValidMix), .oValid(oValid) ); endmodule
Subbytes
// This block performs the SboxEnc transformationon the iBlockIn data // and places it on oBlockOut module SubBytesEnc( output reg [32 *‘Nb - 1:0] oBlockOut, output reg oValid, input iClk, iReset, iReady, input [32 *‘Nb - 1:0] iBlockIn); // Data input to be transformed wire [32 *‘Nb - 1:0] wPostMap; SboxEnc SboxEnc1(.oPostMap(wPostMap[7:0]), .iPreMap(iBlockIn[7:0])); SboxEnc SboxEnc2(.oPostMap(wPostMap[15:8]), .iPreMap(iBlockIn[15:8])); SboxEnc SboxEnc3(.oPostMap(wPostMap[23:16]), .iPreMap(iBlockIn[23:16])); SboxEnc SboxEnc4(.oPostMap(wPostMap[31:24]), .iPreMap(iBlockIn[31:24])); SboxEnc SboxEnc5(.oPostMap(wPostMap[39:32]), .iPreMap(iBlockIn[39:32])); SboxEnc SboxEnc6(.oPostMap(wPostMap[47:40]), .iPreMap(iBlockIn[47:40])); SboxEnc SboxEnc7(.oPostMap(wPostMap[55:48]), .iPreMap(iBlockIn[55:48])); SboxEnc SboxEnc8( .oPostMap(wPostMap[63:56]), .iPreMap(iBlockIn[63:56])); SboxEnc SboxEnc9( .oPostMap(wPostMap[71:64]), .iPreMap(iBlockIn[71:64])); SboxEnc SboxEnc10(.oPostMap(wPostMap[79:72]), .iPreMap(iBlockIn[79:72])); SboxEnc SboxEnc11(.oPostMap(wPostMap[87:80]), .iPreMap(iBlockIn[87:80])); SboxEnc SboxEnc12(.oPostMap(wPostMap[95:88]), .iPreMap(iBlockIn[95:88])); SboxEnc SboxEnc13(.oPostMap(wPostMap[103:96]), .iPreMap(iBlockIn[103:96])); SboxEnc SboxEnc14(.oPostMap(wPostMap[111:104]), .iPreMap(iBlockIn[111:104])); SboxEnc SboxEnc15(.oPostMap(wPostMap[119:112]), .iPreMap(iBlockIn[119:112])); SboxEnc SboxEnc16(.oPostMap(wPostMap[127:120]), .iPreMap(iBlockIn[127:120])); always @(posedge iClk or negedge iReset) if (!iReset) begin oBlockOut <= 0; oValid <= 0; end else begin oBlockOut <= wPostMap; oValid <= iReady; end endmodule // SubBytesEnc
ShiftRows
module ShiftRowsEnc( output [32 *‘Nb - 1:0] oBlockOut, output oValid, input [32 *‘Nb - 1:0] iBlockIn, // Data input to be transformed input iReady ); assign oValid = iReady; assign oBlockOut[7:0] = iBlockIn[39:32]; assign oBlockOut[15:8] = iBlockIn[79:72]; assign oBlockOut[23:16] = iBlockIn[119:112]; assign oBlockOut[31:24] = iBlockIn[31:24]; assign oBlockOut[39:32] = iBlockIn[71:64]; assign oBlockOut[47:40] = iBlockIn[111:104]; assign oBlockOut[55:48] = iBlockIn[23:16]; assign oBlockOut[63:56] = iBlockIn[63:56]; assign oBlockOut[71:64] = iBlockIn[103:96]; assign oBlockOut[79:72] = iBlockIn[15:8]; assign oBlockOut[87:80] = iBlockIn[55:48]; assign oBlockOut[95:88] = iBlockIn[95:88]; assign oBlockOut[103:96] = iBlockIn[7:0]; assign oBlockOut[111:104] = iBlockIn[47:40]; assign oBlockOut[119:112] = iBlockIn[87:80]; assign oBlockOut[127:120] = iBlockIn[127:120]; endmodule // ShiftRowsEnc
MixColumn
module MixColumnsEnc(
output reg [32 * ‘Nb - 1:0] oBlockOut,
output reg oValid,
input iClk, iReset,
input [32 *‘Nb - 1:0] iBlockIn, // Data input to be transformed
input iReady,
input [3:0] iRound);
reg [32 *‘Nb - 1:0] BlockInHold; // registered output
wire [32 *‘Nb - 1:0] wPostMap;
MapColumnEnc MapColumnEnc0 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[127:120], iBlockIn[119:112],iBlockIn[111:104],iBlockIn[103:96]}),
.oColumnOut({wPostMap[127:120],wPostMap[119:112],wPostMap[111:104],wPostMap[103:96]})
);
MapColumnEnc MapColumnEnc1 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[95:88],iBlockIn[87:80],iBlockIn[79:72],iBlockIn[71:64]}),
.oColumnOut({wPostMap[95:88],wPostMap[87:80],wPostMap[79:72],wPostMap[71:64]})
);
MapColumnEnc MapColumnEnc2 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[63:56],iBlockIn[55:48],iBlockIn[47:40],iBlockIn[39:32]}),
.oColumnOut({wPostMap[63:56],wPostMap[55:48],wPostMap[47:40],wPostMap[39:32]})
);
MapColumnEnc MapColumnEnc3 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[31:24],iBlockIn[23:16],iBlockIn[15:8],iBlockIn[7:0]}),
.oColumnOut({wPostMap[31:24],wPostMap[23:16],wPostMap[15:8],wPostMap[7:0]})
);
always @*
if (iRound != ‘Nr )
oBlockOut = wPostMap;
else
oBlockOut = BlockInHold;
always @(posedge iClk or negedge iReset)
if (!iReset)
begin
oValid = 0;
BlockInHold = 0;
end
else
begin
BlockInHold = iBlockIn;
oValid = iReady;
end
endmodule
MapColumn
// Provides necessary parameters to the
AES implementation
// number of data words (always 32*4 = 128)
‘define Nb 4
// 128 bit key mode
‘define Nk4
// 192 bit key mode
//‘define Nk6
// 256 bit key mode
//‘define Nk8
‘ifdef Nk4
‘define Nk 4
‘define Nr 10
‘endif
‘ifdef Nk6
‘define Nk 6
‘define Nr 12
‘endif
‘ifdef Nk8
‘define Nk 8
‘define Nr 14
‘endif
// Performs the column mapping for MixColumns
module MapColumnEnc(
output reg [31:0] oColumnOut,
input iClk, iReset,
input [31:0] iColumnIn);
// intermediate Poly mult results
wire [7:0] S0x2, S1x2, S2x2, S3x2;
wire [7:0] S0x3, S1x3, S2x3, S3x3;
// Mapped cells in column
wire [7:0] S0PostMap, S1PostMap,
S2PostMap, S3PostMap;
// Modules that will perform poly mults over GF(2^8)
PolyMultx2Enc PolyMultS0x2(.iPolyIn(iColumnIn[31:24]),.oPolyOut(S0x2));
PolyMultx2Enc PolyMultS1x2(.iPolyIn(iColumnIn[23:16]),.oPolyOut(S1x2));
PolyMultx2Enc PolyMultS2x2(.iPolyIn(iColumnIn[15:8]), .oPolyOut(S2x2));
PolyMultx2Enc PolyMultS3x2(.iPolyIn(iColumnIn[7:0]), .oPolyOut(S3x2));
PolyMultx3Enc PolyMultS0x3(.iPolyIn(iColumnIn[31:24]),.oPolyOut(S0x3));
PolyMultx3Enc PolyMultS1x3(.iPolyIn(iColumnIn[23:16]),.oPolyOut(S1x3));
PolyMultx3Enc PolyMultS2x3(.iPolyIn(iColumnIn[15:8]), .oPolyOut(S2x3));
PolyMultx3Enc PolyMultS3x3(.iPolyIn(iColumnIn[7:0]), .oPolyOut(S3x3));
// Sum terms over GF(2)
assign S0PostMap = S0x2 ^ S1x3 ^ iColumnIn[15:8] ^ iColumnIn[7:0];
assign S1PostMap = iColumnIn[31:24] ^ S1x2 ^ S2x3 ^ iColumnIn[7:0];
assign S2PostMap = iColumnIn[31:24] ^ iColumnIn[23:16] ^ S2x2 ^ S3x3;
assign S3PostMap = S0x3 ^ iColumnIn[23:16] ^ iColumnIn[15:8] ^ S3x2;
always @(posedge iClk or negedge iReset) begin
if (!iReset)
oColumnOut <= 0;
else // output is combination of post mapped cells
oColumnOut <= {S0PostMap, S1PostMap, S2PostMap,S3PostMap};
end
endmodule
MixColumnsEnc
module MixColumnsEnc(
output reg [32 * ‘Nb - 1:0] oBlockOut,
output reg oValid,
input iClk, iReset,
input [32 *‘Nb - 1:0] iBlockIn, // Data input to be transformed
input iReady,
input [3:0] iRound);
reg [32 *‘Nb - 1:0] BlockInHold; // registered output
wire [32 *‘Nb - 1:0] wPostMap;
MapColumnEnc MapColumnEnc0 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[127:120], iBlockIn[119:112],iBlockIn[111:104],iBlockIn[103:96]}),
.oColumnOut({wPostMap[127:120],wPostMap[119:112],wPostMap[111:104],wPostMap[103:96]})
);
MapColumnEnc MapColumnEnc1 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[95:88],iBlockIn[87:80],iBlockIn[79:72],iBlockIn[71:64]}),
.oColumnOut({wPostMap[95:88],wPostMap[87:80],wPostMap[79:72],wPostMap[71:64]})
);
MapColumnEnc MapColumnEnc2 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[63:56],iBlockIn[55:48],iBlockIn[47:40],iBlockIn[39:32]}),
.oColumnOut({wPostMap[63:56],wPostMap[55:48],wPostMap[47:40],wPostMap[39:32]})
);
MapColumnEnc MapColumnEnc3 (.iClk(iClk),
.iReset(iReset),
.iColumnIn({iBlockIn[31:24],iBlockIn[23:16],iBlockIn[15:8],iBlockIn[7:0]}),
.oColumnOut({wPostMap[31:24],wPostMap[23:16],wPostMap[15:8],wPostMap[7:0]})
);
always @*
if (iRound != ‘Nr )
oBlockOut = wPostMap;
else
oBlockOut = BlockInHold;
always @(posedge iClk or negedge iReset)
if (!iReset)
begin
oValid = 0;
BlockInHold = 0;
end
else
begin
BlockInHold = iBlockIn;
oValid = iReady;
end
endmodule
PolyMultx2Enc
// Multiplies input poly by {02} over GF(2^8) and reduces
// mod m(x) = x^8 + x^4 + x^3 + x + 1
module PolyMultx2Enc(
output [7:0] oPolyOut,
input [7:0] iPolyIn
);
wire [8:0] PolyPreShift, PolyPostShift, PolyReduced;
assign PolyPreShift = {1’b0, iPolyIn};
assign PolyPostShift = PolyPreShift << 1;
assign PolyReduced = PolyPostShift[8] ? (PolyPostShift ^ (9’b100011011)): PolyPostShift;
assign oPolyOut = PolyReduced[7:0];
endmodule // PolyMultx2EncPolyMultx3Enc
// Multiplies input poly by {03} over GF(2^8) and reduces
// mod m(x) = x^8 + x^4 + x^3 + x + 1
module PolyMultx3Enc (
output [7:0] oPolyOut,
input [7:0] iPolyIn
);
wire [8:0] PolyPreShift, PolyPostShift, PolyReduced;
assign PolyPreShift = {1’b0, iPolyIn};
assign PolyPostShift = (PolyPreShift << 1) ^ PolyPreShift;
assign PolyReduced = PolyPostShift[8] ? (PolyPostShift ^ (9’b100011011)): PolyPostShift;
assign oPolyOut = PolyReduced[7:0];
endmodule // PolyMultx3Enc