OpenCores
URL https://opencores.org/ocsvn/aes_beh_model/aes_beh_model/trunk

Subversion Repositories aes_beh_model

[/] [aes_beh_model/] [trunk/] [src/] [verilog/] [aes_beh_model.sv] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 schengopen
////////////////////////////////////////////////////////////////////////
2
////                                                                                                                            ////
3
//// This file is part of the AES SystemVerilog Behavioral                      ////
4
//// Model project                                                                                                      ////
5
//// http://www.opencores.org/cores/aes_beh_model/                                      ////
6
////                                                                                                                            ////
7
//// Description                                                                                                        ////
8
//// Implementation of AES SystemVerilog Behavioral                                     ////
9
//// Model according to AES Behavioral Model specification document.////
10
////                                                                                                                            ////
11
//// To Do:                                                                                                                     ////
12
//// -                                                                                                                          ////
13
////                                                                                                                            ////
14
//// Author(s):                                                                                                         ////
15
//// - scheng, schengopencores@opencores.org                                            ////
16
////                                                                                                                            ////
17
////////////////////////////////////////////////////////////////////////
18
////                                                                                                                            ////
19
//// Copyright (C) 2009 Authors and OPENCORES.ORG                                       ////
20
////                                                                                                                            ////
21
//// This source file may be used and distributed without                       ////
22
//// restriction provided that this copyright statement is not          ////
23
//// removed from the file and that any derivative work contains        ////
24
//// the original copyright notice and the associated disclaimer.       ////
25
////                                                                                                                            ////
26
//// This source file is free software; you can redistribute it         ////
27
//// and/or modify it under the terms of the GNU Lesser General         ////
28
//// Public License as published by the Free Software Foundation;       ////
29
//// either version 2.1 of the License, or (at your option) any         ////
30
//// later version.                                                                                                     ////
31
////                                                                                                                            ////
32
//// This source is distributed in the hope that it will be                     ////
33
//// useful, but WITHOUT ANY WARRANTY; without even the implied         ////
34
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR            ////
35
//// PURPOSE. See the GNU Lesser General Public License for more        ////
36
//// details.                                                                                                           ////
37
////                                                                                                                            ////
38
//// You should have received a copy of the GNU Lesser General          ////
39
//// Public License along with this source; if not, download it         ////
40
//// from http://www.opencores.org/lgpl.shtml                                           ////
41
////                                                                                                                            ////
42
////////////////////////////////////////////////////////////////////////
43
 
44 3 schengopen
// This is a SystemVerilog implementation of the AES encryption/decryption
45
// algorithm described in FIPS-197. The model is implemented as a SystemVerilog
46
// class which can be instantiated in a testbench to generate known good
47
// results for verification of AES IPs.
48 2 schengopen
//
49 3 schengopen
// You are encouraged to use the typdefs at the end of this file instead of the
50
// class below while declaring variables for the aes model in your testbench.
51 2 schengopen
//
52
// Refer to the specification document on how to use the model in your
53
// testbench.
54
 
55 3 schengopen
typedef enum {encrypt, decrypt} aes_func;
56
 
57
class aes_beh_model #(int Nk=4, int Nr=10, aes_func func=decrypt);
58 2 schengopen
        // Refer to section 5 fig.4 of FIPS-197 spec for definitions of Nk and Nr
59
        //
60
        // Key length   Nk              Nr
61
        //              128              4              10
62
        //              192              6              12
63
        //              256              8              14
64
 
65
        byte unsigned state[0:3][0:3];
66
        byte unsigned keysch[0:4*(Nr+1)-1][0:3];
67
        protected int unsigned curr_round;
68
        bit done;       // done=1 -> decryption done, valid plaintext available for read.
69
        bit loaded;     // Ciphertext loaded, ready to start decryption.
70
 
71
        function new(); // Constructor
72
                done = 0;
73
                loaded = 0;
74
        endfunction
75
 
76
        function int unsigned GetCurrRound;
77
                // Returns which round we are at in the decryption process. For AES decryption
78
                // round counts down from Nr to 0.
79
                GetCurrRound = curr_round;
80
        endfunction
81
 
82
        task LoadCt(bit [0:127] ct);
83
        // Populate state array with ciphertext and set loaded flag
84 3 schengopen
                if (func == decrypt)
85
                begin
86
                        for (int j=0; j<=3; j++)
87
                                for (int k=0; k<=3; k++) state[k][j] = ct[(32*j+8*k)+:8];
88
                        loaded = 1;
89
                        done = 0;
90
                        curr_round = Nr;        // Inverse cipher round counts down from Nr
91
                end
92
                else
93
                        $display("#Info : aes_beh_model::LoadCt() cannot load ciphertext to encryptor.");
94 2 schengopen
        endtask
95
 
96 3 schengopen
        task LoadPt(bit [0:127] pt);
97
        // Populate state array with plaintext and set loaded flag
98
                if (func == encrypt)
99
                begin
100
                        for (int j=0; j<=3; j++)
101
                                for (int k=0; k<=3; k++) state[k][j] = pt[(32*j+8*k)+:8];
102
                        loaded = 1;
103
                        done = 0;
104
                        curr_round = 0; // Cipher round counts up from 0
105
                end
106
                else
107
                        $display("#Info : aes_beh_model::LoadPt() cannot load plaintext to decryptor.");
108
        endtask
109
 
110 2 schengopen
        function bit [0:127] GetState;
111
        // Returns current state as a 128-bit vector.
112
        // Once all rounds are completed, state contains the decrypted plaintext.
113
           for (int j=0; j<=3; j++)
114
               for (int k=0; k<=3; k++) GetState[(32*j+8*k)+:8] = state[k][j];
115
        endfunction
116
 
117
        function bit [0:127] GetCurrKsch;
118
        // Get key schedule of the current round.
119
        // Note that for decryption, round counts down from Nr.
120
                for (int j=0; j<=3; j++)
121
                        for (int k=0; k<=3; k++) GetCurrKsch[(32*j+8*k)+:8] = keysch[curr_round*4+j][k];
122
        endfunction
123
 
124
        function bit [0:127] LookupKsch(int unsigned r);
125
        // Lookup key schedule for any round.
126
                for (int j=0; j<=3; j++)
127
                        for (int k=0; k<=3; k++) LookupKsch[(32*j+8*k)+:8] = keysch[r*4+j][k];
128
        endfunction
129
 
130
        task KeyExpand(bit [0:4*8*Nk-1] key);
131
        // Load key to model and compute key_schedule
132
 
133
                int j=0;
134
                byte unsigned temp[0:3];
135
                byte unsigned Rcon[1:11] = {8'h01,8'h02,8'h04,8'h08,8'h10,8'h20,8'h40,8'h80,8'h1b,8'h36,8'h6c};
136
                byte unsigned kt[0:4*Nk-1];     // Array holding the key
137
 
138
                // Populate kt array
139
                for (int i=0; i<=4*Nk-1; i++) kt[i] = key[i*8+:8];
140
 
141
                while (j < Nk)
142
                begin
143
                        keysch[j][0] = kt[4*j];
144
                        keysch[j][1] = kt[4*j+1];
145
                        keysch[j][2] = kt[4*j+2];
146
                        keysch[j][3] = kt[4*j+3];
147
                        j++;
148
                end
149
 
150
                // Now j = Nk
151
                while (j < 4*(Nr+1))
152
                begin
153
                        temp[0] = keysch[j-1][0];
154
                        temp[1] = keysch[j-1][1];
155
                        temp[2] = keysch[j-1][2];
156
                        temp[3] = keysch[j-1][3];
157
 
158
                        if ((j % Nk) == 0) // When j is a multiple of key length
159
                        begin
160
                                RotWord(temp);
161
                                SubWord(temp);
162
                                temp[0] ^= Rcon[j/Nk];
163
                        end
164
                        else if ((Nk > 6) && ((j % Nk) == 4)) // Only Nk=8 (AES256) will hit this case
165
                                SubWord(temp);
166
 
167
                        keysch[j][0] = keysch[j-Nk][0] ^ temp[0];
168
                        keysch[j][1] = keysch[j-Nk][1] ^ temp[1];
169
                        keysch[j][2] = keysch[j-Nk][2] ^ temp[2];
170
                        keysch[j][3] = keysch[j-Nk][3] ^ temp[3];
171
 
172
                        j++;
173
                end
174
 
175
        endtask
176
 
177
        protected task RotWord(inout byte unsigned x[0:3]);
178
                byte unsigned tmp;
179
 
180
                tmp = x[0];
181
                x[0] = x[1];
182
                x[1] = x[2];
183
                x[2] = x[3];
184
                x[3] = tmp;
185
        endtask
186
 
187
        protected function byte unsigned inv_sbox_transform(byte unsigned x);
188
    // Inverse Sbox transform matrix
189
    const byte unsigned inv_sbox[0:255] = {
190
    //        0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f
191
        //          ===============================================================================================
192
        /*0*/   8'h52,8'h09,8'h6a,8'hd5,8'h30,8'h36,8'ha5,8'h38,8'hbf,8'h40,8'ha3,8'h9e,8'h81,8'hf3,8'hd7,8'hfb,
193
        /*1*/   8'h7c,8'he3,8'h39,8'h82,8'h9b,8'h2f,8'hff,8'h87,8'h34,8'h8e,8'h43,8'h44,8'hc4,8'hde,8'he9,8'hcb,
194
        /*2*/   8'h54,8'h7b,8'h94,8'h32,8'ha6,8'hc2,8'h23,8'h3d,8'hee,8'h4c,8'h95,8'h0b,8'h42,8'hfa,8'hc3,8'h4e,
195
        /*3*/   8'h08,8'h2e,8'ha1,8'h66,8'h28,8'hd9,8'h24,8'hb2,8'h76,8'h5b,8'ha2,8'h49,8'h6d,8'h8b,8'hd1,8'h25,
196
        /*4*/   8'h72,8'hf8,8'hf6,8'h64,8'h86,8'h68,8'h98,8'h16,8'hd4,8'ha4,8'h5c,8'hcc,8'h5d,8'h65,8'hb6,8'h92,
197
        /*5*/   8'h6c,8'h70,8'h48,8'h50,8'hfd,8'hed,8'hb9,8'hda,8'h5e,8'h15,8'h46,8'h57,8'ha7,8'h8d,8'h9d,8'h84,
198
        /*6*/   8'h90,8'hd8,8'hab,8'h00,8'h8c,8'hbc,8'hd3,8'h0a,8'hf7,8'he4,8'h58,8'h05,8'hb8,8'hb3,8'h45,8'h06,
199
        /*7*/   8'hd0,8'h2c,8'h1e,8'h8f,8'hca,8'h3f,8'h0f,8'h02,8'hc1,8'haf,8'hbd,8'h03,8'h01,8'h13,8'h8a,8'h6b,
200
        /*8*/   8'h3a,8'h91,8'h11,8'h41,8'h4f,8'h67,8'hdc,8'hea,8'h97,8'hf2,8'hcf,8'hce,8'hf0,8'hb4,8'he6,8'h73,
201
        /*9*/   8'h96,8'hac,8'h74,8'h22,8'he7,8'had,8'h35,8'h85,8'he2,8'hf9,8'h37,8'he8,8'h1c,8'h75,8'hdf,8'h6e,
202
        /*a*/   8'h47,8'hf1,8'h1a,8'h71,8'h1d,8'h29,8'hc5,8'h89,8'h6f,8'hb7,8'h62,8'h0e,8'haa,8'h18,8'hbe,8'h1b,
203
        /*b*/   8'hfc,8'h56,8'h3e,8'h4b,8'hc6,8'hd2,8'h79,8'h20,8'h9a,8'hdb,8'hc0,8'hfe,8'h78,8'hcd,8'h5a,8'hf4,
204
        /*c*/   8'h1f,8'hdd,8'ha8,8'h33,8'h88,8'h07,8'hc7,8'h31,8'hb1,8'h12,8'h10,8'h59,8'h27,8'h80,8'hec,8'h5f,
205
        /*d*/   8'h60,8'h51,8'h7f,8'ha9,8'h19,8'hb5,8'h4a,8'h0d,8'h2d,8'he5,8'h7a,8'h9f,8'h93,8'hc9,8'h9c,8'hef,
206
        /*e*/   8'ha0,8'he0,8'h3b,8'h4d,8'hae,8'h2a,8'hf5,8'hb0,8'hc8,8'heb,8'hbb,8'h3c,8'h83,8'h53,8'h99,8'h61,
207
        /*f*/   8'h17,8'h2b,8'h04,8'h7e,8'hba,8'h77,8'hd6,8'h26,8'he1,8'h69,8'h14,8'h63,8'h55,8'h21,8'h0c,8'h7d
208
        };
209
                inv_sbox_transform = inv_sbox[x];
210
        endfunction
211
 
212
        protected function byte unsigned sbox_transform(byte unsigned x);
213
        // Sbox transform matrix
214
        const byte unsigned sbox[0:255] = {
215
    //        0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f
216
        //          ===============================================================================================
217
        /*0*/   8'h63,8'h7c,8'h77,8'h7b,8'hf2,8'h6b,8'h6f,8'hc5,8'h30,8'h01,8'h67,8'h2b,8'hfe,8'hd7,8'hab,8'h76,
218
    /*1*/       8'hca,8'h82,8'hc9,8'h7d,8'hfa,8'h59,8'h47,8'hf0,8'had,8'hd4,8'ha2,8'haf,8'h9c,8'ha4,8'h72,8'hc0,
219
    /*2*/       8'hb7,8'hfd,8'h93,8'h26,8'h36,8'h3f,8'hf7,8'hcc,8'h34,8'ha5,8'he5,8'hf1,8'h71,8'hd8,8'h31,8'h15,
220
        /*3*/   8'h04,8'hc7,8'h23,8'hc3,8'h18,8'h96,8'h05,8'h9a,8'h07,8'h12,8'h80,8'he2,8'heb,8'h27,8'hb2,8'h75,
221
    /*4*/       8'h09,8'h83,8'h2c,8'h1a,8'h1b,8'h6e,8'h5a,8'ha0,8'h52,8'h3b,8'hd6,8'hb3,8'h29,8'he3,8'h2f,8'h84,
222
    /*5*/       8'h53,8'hd1,8'h00,8'hed,8'h20,8'hfc,8'hb1,8'h5b,8'h6a,8'hcb,8'hbe,8'h39,8'h4a,8'h4c,8'h58,8'hcf,
223
    /*6*/       8'hd0,8'hef,8'haa,8'hfb,8'h43,8'h4d,8'h33,8'h85,8'h45,8'hf9,8'h02,8'h7f,8'h50,8'h3c,8'h9f,8'ha8,
224
    /*7*/       8'h51,8'ha3,8'h40,8'h8f,8'h92,8'h9d,8'h38,8'hf5,8'hbc,8'hb6,8'hda,8'h21,8'h10,8'hff,8'hf3,8'hd2,
225
    /*8*/       8'hcd,8'h0c,8'h13,8'hec,8'h5f,8'h97,8'h44,8'h17,8'hc4,8'ha7,8'h7e,8'h3d,8'h64,8'h5d,8'h19,8'h73,
226
    /*9*/       8'h60,8'h81,8'h4f,8'hdc,8'h22,8'h2a,8'h90,8'h88,8'h46,8'hee,8'hb8,8'h14,8'hde,8'h5e,8'h0b,8'hdb,
227
    /*a*/       8'he0,8'h32,8'h3a,8'h0a,8'h49,8'h06,8'h24,8'h5c,8'hc2,8'hd3,8'hac,8'h62,8'h91,8'h95,8'he4,8'h79,
228
    /*b*/       8'he7,8'hc8,8'h37,8'h6d,8'h8d,8'hd5,8'h4e,8'ha9,8'h6c,8'h56,8'hf4,8'hea,8'h65,8'h7a,8'hae,8'h08,
229
    /*c*/       8'hba,8'h78,8'h25,8'h2e,8'h1c,8'ha6,8'hb4,8'hc6,8'he8,8'hdd,8'h74,8'h1f,8'h4b,8'hbd,8'h8b,8'h8a,
230
    /*d*/       8'h70,8'h3e,8'hb5,8'h66,8'h48,8'h03,8'hf6,8'h0e,8'h61,8'h35,8'h57,8'hb9,8'h86,8'hc1,8'h1d,8'h9e,
231
    /*e*/       8'he1,8'hf8,8'h98,8'h11,8'h69,8'hd9,8'h8e,8'h94,8'h9b,8'h1e,8'h87,8'he9,8'hce,8'h55,8'h28,8'hdf,
232
    /*f*/       8'h8c,8'ha1,8'h89,8'h0d,8'hbf,8'he6,8'h42,8'h68,8'h41,8'h99,8'h2d,8'h0f,8'hb0,8'h54,8'hbb,8'h16
233
        };
234
                sbox_transform = sbox[x];
235
        endfunction
236
 
237
        protected task SubBytes;
238
                for (int j=0; j<=3; j++)
239
                        for (int k=0; k<=3; k++) state[j][k] = sbox_transform(state[j][k]);
240
        endtask
241
 
242
        protected task InvSubBytes;
243
                for (int j=0; j<=3; j++)
244
                        for (int k=0; k<=3; k++) state[j][k] = inv_sbox_transform(state[j][k]);
245
        endtask
246
 
247
        protected task SubWord(inout byte unsigned x[0:3]);
248
                x[0] = sbox_transform(x[0]);
249
                x[1] = sbox_transform(x[1]);
250
                x[2] = sbox_transform(x[2]);
251
                x[3] = sbox_transform(x[3]);
252
        endtask
253
 
254
        protected task InvShiftRows;
255
                byte unsigned tmp_state[1:3][0:3];      // Row 0 of state is not shifted
256
 
257
                for (int j=1; j<=3; j++)
258
                        for (int k=0; k<=3; k++) tmp_state[j][k] = state[j][(k+4-j)%4];
259
 
260
                for (int j=1; j<=3; j++)
261
                        for (int k=0; k<=3; k++) state[j][k] = tmp_state[j][k];
262
        endtask
263
 
264 3 schengopen
        protected task ShiftRows;
265
                byte unsigned tmp_state[1:3][0:3];      // Row 0 of state is not shifted
266
 
267
                for (int j=1; j<=3; j++)
268
                        for (int k=0; k<=3; k++) tmp_state[j][k] = state[j][(k+j)%4];
269
 
270
                for (int j=1; j<=3; j++)
271
                        for (int k=0; k<=3; k++) state[j][k] = tmp_state[j][k];
272
        endtask
273
 
274 2 schengopen
        protected function byte unsigned xtime(byte unsigned x);
275
        // Multiplication by 2 over GF(256)
276
        // Refer to FIPS-197 spec section 4.2.1 on definition of GF(256) multiplication
277
                xtime = (x[7])? (x<<1) ^ 8'h1b : x<<1;
278
        endfunction
279
 
280 3 schengopen
        protected function byte unsigned GFmul2(byte unsigned x);
281
        // Same as xtime(). For improved readibility only.
282
                GFmul2 = xtime(x);
283
        endfunction
284
 
285
        protected function byte unsigned GFmul3(byte unsigned x);
286
        // Multiply by 3 over GF(256)
287
        // 3*x = 2*x + x
288
        // Addition over GF(256) is xor
289
                GFmul3 = xtime(x) ^ x;
290
        endfunction
291
 
292 2 schengopen
        protected function byte unsigned GFmul4(byte unsigned x);
293
        // Multiply by 4 over GF(256)
294
        // 4*x = 2*(2*x)
295
                GFmul4 = xtime(xtime(x));
296
        endfunction
297
 
298
        protected function byte unsigned GFmul8(byte unsigned x);
299
        // Multiply by 8 over GF(256)
300
        // 8*x = 2*(4*x)
301
                GFmul8 = xtime(GFmul4(x));
302
        endfunction
303
 
304
        protected function byte unsigned GFmul9(byte unsigned x);
305
        // Multiply by 9 over GF(256)
306
        // 9*x = 8*x + x
307
        // Addition over GF(256) is xor
308
                GFmul9 = GFmul8(x) ^ x;
309
        endfunction
310
 
311
        protected function byte unsigned GFmulb(byte unsigned x);
312
        // Multiply by 0xb over GF(256)
313
        // b*x = 8*x + 2*x +x
314
                GFmulb = GFmul8(x) ^ xtime(x) ^ x;
315
        endfunction
316
 
317
        protected function byte unsigned GFmuld(byte unsigned x);
318
        // Multiply by 0xd over GF(256)
319
        // d*x = 8*x + 4*x + x
320
                GFmuld = GFmul8(x) ^ GFmul4(x) ^ x;
321
        endfunction
322
 
323
        protected function byte unsigned GFmule(byte unsigned x);
324
        // Multiply by 0xe over GF(256)
325
        // e*x = 8*x + 4*x +2*x
326
                GFmule = GFmul8(x) ^ GFmul4(x) ^ xtime(x);
327
        endfunction
328
 
329 3 schengopen
        protected task MixColumns;
330
                byte unsigned tmp_col[0:3];
331
 
332
                for (int j=0; j<=3; j++)
333
                begin
334
                        tmp_col[0] = GFmul2(state[0][j]) ^ GFmul3(state[1][j]) ^ state[2][j] ^ state[3][j];
335
                        tmp_col[1] = state[0][j] ^ GFmul2(state[1][j]) ^ GFmul3(state[2][j]) ^ state[3][j];
336
                        tmp_col[2] = state[0][j] ^ state[1][j] ^ GFmul2(state[2][j]) ^ GFmul3(state[3][j]);
337
                        tmp_col[3] = GFmul3(state[0][j]) ^ state[1][j] ^ state[2][j] ^ GFmul2(state[3][j]);
338
 
339
                        state[0][j] = tmp_col[0];
340
                        state[1][j] = tmp_col[1];
341
                        state[2][j] = tmp_col[2];
342
                        state[3][j] = tmp_col[3];
343
                end
344
        endtask
345
 
346 2 schengopen
        protected task InvMixColumns;
347
                byte unsigned tmp_col[0:3];
348
 
349
                for (int j=0; j<=3; j++)
350
                begin
351
                        tmp_col[0] = GFmule(state[0][j]) ^ GFmulb(state[1][j]) ^ GFmuld(state[2][j]) ^ GFmul9(state[3][j]);
352
                        tmp_col[1] = GFmul9(state[0][j]) ^ GFmule(state[1][j]) ^ GFmulb(state[2][j]) ^ GFmuld(state[3][j]);
353
                        tmp_col[2] = GFmuld(state[0][j]) ^ GFmul9(state[1][j]) ^ GFmule(state[2][j]) ^ GFmulb(state[3][j]);
354
                        tmp_col[3] = GFmulb(state[0][j]) ^ GFmuld(state[1][j]) ^ GFmul9(state[2][j]) ^ GFmule(state[3][j]);
355
 
356
                        state[0][j] = tmp_col[0];
357
                        state[1][j] = tmp_col[1];
358
                        state[2][j] = tmp_col[2];
359
                        state[3][j] = tmp_col[3];
360
                end
361
        endtask
362 3 schengopen
 
363 2 schengopen
        protected task AddRoundKey;
364
                for (int j=0; j<=3; j++)
365
                        for (int k=0; k<=3; k++) state[k][j] ^= keysch[curr_round*4+j][k];
366
        endtask
367
 
368
        task run(int mode);
369 3 schengopen
        // Run cipher / inverse cipher rounds as defined in section 5.1 / 5.3 of FIPS-197 spec.
370
        // Model functions as cipher / inverse cipher depending on the value of the parameter func.
371
        //
372
        // Two run modes are supported
373 2 schengopen
        // mode=0 -> Run from current round to completion
374
        // mode=1 -> Run 1 round only
375 3 schengopen
        //
376
        // For encryption both the LoadPt() and KeyExpand() must be called first before calling run().
377
        // For dncryption both the LoadPt() and KeyExpand() must be called first before calling run().
378
        // This is to ensure the cipher / inverse cipher doesn't work on garbage.
379 2 schengopen
 
380 3 schengopen
                // Only continue if model is loaded and there are unfinished round(s)
381 2 schengopen
                if (loaded & ~done)
382 3 schengopen
                begin
383
                        if (func == decrypt) // Model configured as decryptor
384 2 schengopen
                        do
385
                        begin
386
                                unique if (curr_round == Nr)
387
                                begin
388
                                        `ifdef INTERNAL_DEBUG
389
                                        $display("round[%2d].istart\t%h",Nr-curr_round,GetState);
390
                                        $display("round[%2d].ik_sch\t%h",Nr-curr_round,GetCurrKsch);
391
                                        `endif
392
 
393
                                        done = 0;
394
                                        AddRoundKey;
395
                                        curr_round--;
396
                                end
397
                                else if ((curr_round <= Nr-1) && (curr_round >= 1))
398
                                begin
399
                                        `ifdef INTERNAL_DEBUG
400
                                        $display("round[%2d].istart\t%h",Nr-curr_round,GetState);
401
                                        `endif
402
 
403
                                        InvShiftRows;
404
                                        `ifdef INTERNAL_DEBUG
405
                                        $display("round[%2d].is_row\t%h",Nr-curr_round,GetState);
406
                                        `endif
407
 
408
                                        InvSubBytes;
409
                                        `ifdef INTERNAL_DEBUG
410
                                        $display("round[%2d].is_box\t%h",Nr-curr_round,GetState);
411
                                        $display("round[%2d].ik_sch\t%h",Nr-curr_round,GetCurrKsch);
412
                                        `endif
413
 
414
                                        AddRoundKey;
415
                                        `ifdef INTERNAL_DEBUG
416
                                        $display("round[%2d].ik_add\t%h",Nr-curr_round,GetState);
417
                                        `endif
418
 
419
                                        InvMixColumns;
420
                                        curr_round--;
421
                                end
422
                                else if (curr_round == 0)
423
                                begin
424
                                        `ifdef INTERNAL_DEBUG
425
                                        $display("round[%2d].istart\t%h",Nr-curr_round,GetState);
426
                                        `endif
427
 
428
                                        InvShiftRows;
429
                                        `ifdef INTERNAL_DEBUG
430
                                        $display("round[%2d].is_row\t%h",Nr-curr_round,GetState);
431
                                        `endif
432
 
433
                                        InvSubBytes;
434
                                        `ifdef INTERNAL_DEBUG
435
                                        $display("round[%2d].is_box\t%h",Nr-curr_round,GetState);
436
                                        $display("round[%2d].ik_sch\t%h",Nr-curr_round,GetCurrKsch);
437
                                        `endif
438
 
439
                                        AddRoundKey;
440
                                        `ifdef INTERNAL_DEBUG
441
                                        $display("round[%2d].ioutput\t%h",Nr-curr_round,GetState);
442
                                        `endif
443
 
444
                                        done = 1;       // Last round completed
445
                                        loaded = 0;
446
                                end
447
 
448
                                if (mode == 1) break;
449
                        end
450
                        while (done == 0);
451
 
452 3 schengopen
                        else
453
                        // Model configured as encryptor
454
                        do
455
                        begin
456
                                unique if (curr_round == 0)
457
                                begin
458
                                        `ifdef INTERNAL_DEBUG
459
                                        $display("round[%2d].input\t%h",curr_round,GetState);
460
                                        $display("round[%2d].k_sch\t%h",curr_round,GetCurrKsch);
461
                                        `endif
462
 
463
                                        done = 0;
464
                                        AddRoundKey;
465
                                        curr_round++;
466
                                end
467
                                else if ((curr_round <= Nr-1) && (curr_round >= 1))
468
                                begin
469
                                        `ifdef INTERNAL_DEBUG
470
                                        $display("round[%2d].start\t%h",curr_round,GetState);
471
                                        `endif
472
 
473
                                        SubBytes;
474
                                        `ifdef INTERNAL_DEBUG
475
                                        $display("round[%2d].s_box\t%h",curr_round,GetState);
476
                                        `endif
477
 
478
                                        ShiftRows;
479
                                        `ifdef INTERNAL_DEBUG
480
                                        $display("round[%2d].s_row\t%h",curr_round,GetState);
481
                                        `endif
482
 
483
                                        MixColumns;
484
                                        `ifdef INTERNAL_DEBUG
485
                                        $display("round[%2d].m_col\t%h",curr_round,GetState);
486
                                        `endif
487
 
488
                                        AddRoundKey;
489
                                        `ifdef INTERNAL_DEBUG
490
                                        $display("round[%2d].k_sch\t%h",curr_round,GetCurrKsch);
491
                                        `endif
492
 
493
                                        curr_round++;
494
                                end
495
                                else if (curr_round == Nr)
496
                                begin
497
                                        `ifdef INTERNAL_DEBUG
498
                                        $display("round[%2d].start\t%h",curr_round,GetState);
499
                                        `endif
500
 
501
                                        SubBytes;
502
                                        `ifdef INTERNAL_DEBUG
503
                                        $display("round[%2d].s_box\t%h",curr_round,GetState);
504
                                        `endif
505
 
506
                                        ShiftRows;
507
                                        `ifdef INTERNAL_DEBUG
508
                                        $display("round[%2d].s_row\t%h",curr_round,GetState);
509
                                        `endif
510
 
511
                                        AddRoundKey;
512
                                        `ifdef INTERNAL_DEBUG
513
                                        $display("round[%2d].k_sch\t%h",curr_round,GetCurrKsch);
514
                                        $display("round[%2d].output\t%h",curr_round,GetState);
515
                                        `endif
516
 
517
                                        done = 1;       // Last round completed
518
                                        loaded = 0;
519
                                end
520
 
521
                                if (mode == 1) break;
522
                        end
523
                        while (done == 0);
524
 
525
                end
526 2 schengopen
                // Either ciphertext is not loaded or decryption has already completed
527 3 schengopen
                else $display("#Info : aes_beh_model::run() has nothing to do");
528 2 schengopen
        endtask
529
endclass        // aes_decrypt_model
530
 
531
// The following types should be used for declaration of aes class objects in your source code.
532
// e.g. ....
533
//              aes256_decrypt_t my_aes_decryptor;
534
//              bit [0:127] pt;
535
//              ....
536
//              my_aes_decryptor = new;
537
//              my_aes_decryptor.KeyExpand(256'h.......);
538
//              my_aes_decryptor.LoadCt(128'h.........);
539
//              my_aes_descryptor.run(0);
540
//              pt = my_aes_descryptor.GetState();
541
 
542 3 schengopen
typedef aes_beh_model #(.Nk(8),.Nr(14),.func(decrypt)) aes256_decrypt_t;
543
typedef aes_beh_model #(.Nk(6),.Nr(12),.func(decrypt)) aes192_decrypt_t;
544
typedef aes_beh_model #(.Nk(4),.Nr(10),.func(decrypt)) aes128_decrypt_t;
545
 
546
typedef aes_beh_model #(.Nk(8),.Nr(14),.func(encrypt)) aes256_encrypt_t;
547
typedef aes_beh_model #(.Nk(6),.Nr(12),.func(encrypt)) aes192_encrypt_t;
548
typedef aes_beh_model #(.Nk(4),.Nr(10),.func(encrypt)) aes128_encrypt_t;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.