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 // PolyMultx2Enc
PolyMultx3Enc
// 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