Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
829a1a833This file is pinned to the selected release. Download the original to open it in your design tool.
//======================================================================
//
// tb_aes_decipher_block.v
// -----------------------
// Testbench for the AES decipher block module.
//
//
// Author: Joachim Strombergson
// Copyright (c) 2014, Secworks Sweden AB
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following
// conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//======================================================================
//------------------------------------------------------------------
// Simulator directives.
//------------------------------------------------------------------
`timescale 1ns/100ps
//------------------------------------------------------------------
// Test module.
//------------------------------------------------------------------
module tb_aes_decipher_block();
//----------------------------------------------------------------
// Internal constant and parameter definitions.
//----------------------------------------------------------------
parameter DEBUG = 1;
parameter DUMP_WAIT = 0;
parameter CLK_HALF_PERIOD = 1;
parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD;
parameter AES_128_BIT_KEY = 0;
parameter AES_256_BIT_KEY = 1;
parameter AES_DECIPHER = 1'b0;
parameter AES_ENCIPHER = 1'b1;
//----------------------------------------------------------------
// Register and Wire declarations.
//----------------------------------------------------------------
reg [31 : 0] cycle_ctr;
reg [31 : 0] error_ctr;
reg [31 : 0] tc_ctr;
reg tb_clk;
reg tb_reset_n;
reg tb_next;
reg tb_keylen;
wire tb_ready;
wire [3 : 0] tb_round;
wire [127 : 0] tb_round_key;
reg [127 : 0] tb_block;
wire [127 : 0] tb_new_block;
reg [127 : 0] key_mem [0 : 14];
//----------------------------------------------------------------
// Assignments.
//----------------------------------------------------------------
assign tb_round_key = key_mem[tb_round];
//----------------------------------------------------------------
// Device Under Test.
//----------------------------------------------------------------
aes_decipher_block dut(
.clk(tb_clk),
.reset_n(tb_reset_n),
.next(tb_next),
.keylen(tb_keylen),
.round(tb_round),
.round_key(tb_round_key),
.block(tb_block),
.new_block(tb_new_block),
.ready(tb_ready)
);
//----------------------------------------------------------------
// clk_gen
//
// Always running clock generator process.
//----------------------------------------------------------------
always
begin : clk_gen
#CLK_HALF_PERIOD;
tb_clk = !tb_clk;
end // clk_gen
//----------------------------------------------------------------
// sys_monitor()
//
// An always running process that creates a cycle counter and
// conditionally displays information about the DUT.
//----------------------------------------------------------------
always
begin : sys_monitor
cycle_ctr = cycle_ctr + 1;
#(CLK_PERIOD);
if (DEBUG)
begin
dump_dut_state();
end
end
//----------------------------------------------------------------
// dump_dut_state()
//
// Dump the state of the dump when needed.
//----------------------------------------------------------------
task dump_dut_state();
begin
$display("State of DUT");
$display("------------");
$display("Interfaces");
$display("ready = 0x%01x, next = 0x%01x, keylen = 0x%01x",
dut.ready, dut.next, dut.keylen);
$display("block = 0x%032x", dut.block);
$display("new_block = 0x%032x", dut.new_block);
$display("");
$display("Control states");
$display("round = 0x%01x", dut.round);
$display("dec_ctrl = 0x%01x, update_type = 0x%01x, sword_ctr = 0x%01x, round_ctr = 0x%01x",
dut.dec_ctrl_reg, dut.update_type, dut.sword_ctr_reg, dut.round_ctr_reg);
$display("");
$display("Internal data values");
$display("round_key = 0x%016x", dut.round_key);
$display("sboxw = 0x%08x, new_sboxw = 0x%08x", dut.tmp_sboxw, dut.new_sboxw);
$display("block_w0_reg = 0x%08x, block_w1_reg = 0x%08x, block_w2_reg = 0x%08x, block_w3_reg = 0x%08x",
dut.block_w0_reg, dut.block_w1_reg, dut.block_w2_reg, dut.block_w3_reg);
$display("");
$display("old_block = 0x%08x", dut.round_logic.old_block);
$display("inv_shiftrows_block = 0x%08x", dut.round_logic.inv_shiftrows_block);
$display("inv_mixcolumns_block = 0x%08x", dut.round_logic.inv_mixcolumns_block);
$display("addkey_block = 0x%08x", dut.round_logic.addkey_block);
$display("block_w0_new = 0x%08x, block_w1_new = 0x%08x, block_w2_new = 0x%08x, block_w3_new = 0x%08x",
dut.block_new[127 : 096], dut.block_new[095 : 064],
dut.block_new[063 : 032], dut.block_new[031 : 000]);
$display("");
end
endtask // dump_dut_state
//----------------------------------------------------------------
// reset_dut()
//
// Toggle reset to put the DUT into a well known state.
//----------------------------------------------------------------
task reset_dut();
begin
$display("*** Toggle reset.");
tb_reset_n = 0;
#(2 * CLK_PERIOD);
tb_reset_n = 1;
end
endtask // reset_dut
//----------------------------------------------------------------
// init_sim()
//
// Initialize all counters and testbed functionality as well
// as setting the DUT inputs to defined values.
//----------------------------------------------------------------
task init_sim();
begin
cycle_ctr = 0;
error_ctr = 0;
tc_ctr = 0;
tb_clk = 0;
tb_reset_n = 1;
tb_next = 0;
tb_keylen = 0;
tb_block = {4{32'h00000000}};
end
endtask // init_sim
//----------------------------------------------------------------
// display_test_result()
//
// Display the accumulated test results.
//----------------------------------------------------------------
task display_test_result();
begin
if (error_ctr == 0)
begin
$display("*** All %02d test cases completed successfully", tc_ctr);
end
else
begin
$display("*** %02d tests completed - %02d test cases did not complete successfully.",
tc_ctr, error_ctr);
end
end
endtask // display_test_result
//----------------------------------------------------------------
// wait_ready()
//
// Wait for the ready flag in the dut to be set.
//
// Note: It is the callers responsibility to call the function
// when the dut is actively processing and will in fact at some
// point set the flag.
//----------------------------------------------------------------
task wait_ready();
begin
while (!tb_ready)
begin
#(CLK_PERIOD);
if (DUMP_WAIT)
begin
dump_dut_state();
end
end
end
endtask // wait_ready
//----------------------------------------------------------------
// test_ecb_de()
//
// Perform ECB mode encryption test.
//----------------------------------------------------------------
task test_ecb_dec(
input key_length,
input [127 : 0] block,
input [127 : 0] expected);
begin
$display("*** TC %0d ECB mode test started.", tc_ctr);
// Init the cipher with the given key and length.
tb_keylen = key_length;
// Perform decipher operation on the block.
tb_block = block;
tb_next = 1;
#(2 * CLK_PERIOD);
tb_next = 0;
#(2 * CLK_PERIOD);
wait_ready();
if (tb_new_block == expected)
begin
$display("*** TC %0d successful.", tc_ctr);
$display("");
end
else
begin
$display("*** ERROR: TC %0d NOT successful.", tc_ctr);
$display("Expected: 0x%032x", expected);
$display("Got: 0x%032x", tb_new_block);
$display("");
error_ctr = error_ctr + 1;
end
tc_ctr = tc_ctr + 1;
end
endtask // ecb_mode_single_block_test
//----------------------------------------------------------------
// tb_aes_decipher_block
// The main test functionality.
//
// Test cases taken from NIST SP 800-38A:
// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
//----------------------------------------------------------------
initial
begin : tb_aes_decipher_block
reg [127 : 0] nist_plaintext0;
reg [127 : 0] nist_plaintext1;
reg [127 : 0] nist_plaintext2;
reg [127 : 0] nist_plaintext3;
reg [127 : 0] nist_ecb_128_dec_ciphertext0;
reg [127 : 0] nist_ecb_128_dec_ciphertext1;
reg [127 : 0] nist_ecb_128_dec_ciphertext2;
reg [127 : 0] nist_ecb_128_dec_ciphertext3;
reg [127 : 0] nist_ecb_256_dec_ciphertext0;
reg [127 : 0] nist_ecb_256_dec_ciphertext1;
reg [127 : 0] nist_ecb_256_dec_ciphertext2;
reg [127 : 0] nist_ecb_256_dec_ciphertext3;
nist_plaintext0 = 128'h6bc1bee22e409f96e93d7e117393172a;
nist_plaintext1 = 128'hae2d8a571e03ac9c9eb76fac45af8e51;
nist_plaintext2 = 128'h30c81c46a35ce411e5fbc1191a0a52ef;
nist_plaintext3 = 128'hf69f2445df4f9b17ad2b417be66c3710;
nist_ecb_128_dec_ciphertext0 = 128'h3ad77bb40d7a3660a89ecaf32466ef97;
nist_ecb_128_dec_ciphertext1 = 128'hf5d3d58503b9699de785895a96fdbaaf;
nist_ecb_128_dec_ciphertext2 = 128'h43b1cd7f598ece23881b00e3ed030688;
nist_ecb_128_dec_ciphertext3 = 128'h7b0c785e27e8ad3f8223207104725dd4;
nist_ecb_256_dec_ciphertext0 = 255'hf3eed1bdb5d2a03c064b5a7e3db181f8;
nist_ecb_256_dec_ciphertext1 = 255'h591ccb10d410ed26dc5ba74a31362870;
nist_ecb_256_dec_ciphertext2 = 255'hb6ed21b99ca6f4f9f153e7b1beafed1d;
nist_ecb_256_dec_ciphertext3 = 255'h23304b7a39f9f3ff067d8d8f9e24ecc7;
$display(" -= Testbench for aes decipher block started =-");
$display(" ============================================");
$display("");
init_sim();
dump_dut_state();
reset_dut();
dump_dut_state();
// NIST 128 bit ECB tests.
key_mem[00] = 128'h2b7e151628aed2a6abf7158809cf4f3c;
key_mem[01] = 128'ha0fafe1788542cb123a339392a6c7605;
key_mem[02] = 128'hf2c295f27a96b9435935807a7359f67f;
key_mem[03] = 128'h3d80477d4716fe3e1e237e446d7a883b;
key_mem[04] = 128'hef44a541a8525b7fb671253bdb0bad00;
key_mem[05] = 128'hd4d1c6f87c839d87caf2b8bc11f915bc;
key_mem[06] = 128'h6d88a37a110b3efddbf98641ca0093fd;
key_mem[07] = 128'h4e54f70e5f5fc9f384a64fb24ea6dc4f;
key_mem[08] = 128'head27321b58dbad2312bf5607f8d292f;
key_mem[09] = 128'hac7766f319fadc2128d12941575c006e;
key_mem[10] = 128'hd014f9a8c9ee2589e13f0cc8b6630ca6;
key_mem[11] = 128'h00000000000000000000000000000000;
key_mem[12] = 128'h00000000000000000000000000000000;
key_mem[13] = 128'h00000000000000000000000000000000;
key_mem[14] = 128'h00000000000000000000000000000000;
test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext0, nist_plaintext0);
test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext1, nist_plaintext1);
test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext2, nist_plaintext2);
test_ecb_dec(AES_128_BIT_KEY, nist_ecb_128_dec_ciphertext3, nist_plaintext3);
// NIST 256 bit ECB tests.
key_mem[00] = 128'h603deb1015ca71be2b73aef0857d7781;
key_mem[01] = 128'h1f352c073b6108d72d9810a30914dff4;
key_mem[02] = 128'h9ba354118e6925afa51a8b5f2067fcde;
key_mem[03] = 128'ha8b09c1a93d194cdbe49846eb75d5b9a;
key_mem[04] = 128'hd59aecb85bf3c917fee94248de8ebe96;
key_mem[05] = 128'hb5a9328a2678a647983122292f6c79b3;
key_mem[06] = 128'h812c81addadf48ba24360af2fab8b464;
key_mem[07] = 128'h98c5bfc9bebd198e268c3ba709e04214;
key_mem[08] = 128'h68007bacb2df331696e939e46c518d80;
key_mem[09] = 128'hc814e20476a9fb8a5025c02d59c58239;
key_mem[10] = 128'hde1369676ccc5a71fa2563959674ee15;
key_mem[11] = 128'h5886ca5d2e2f31d77e0af1fa27cf73c3;
key_mem[12] = 128'h749c47ab18501ddae2757e4f7401905a;
key_mem[13] = 128'hcafaaae3e4d59b349adf6acebd10190d;
key_mem[14] = 128'hfe4890d1e6188d0b046df344706c631e;
test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext0, nist_plaintext0);
test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext1, nist_plaintext1);
test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext2, nist_plaintext2);
test_ecb_dec(AES_256_BIT_KEY, nist_ecb_256_dec_ciphertext3, nist_plaintext3);
display_test_result();
$display("");
$display("*** AES decipher block module simulation done. ***");
$finish;
end // aes_core_test
endmodule // tb_aes_decipher_block
//======================================================================
// EOF tb_aes_decipher_block.v
//======================================================================