blob: ab7e3f22c4ec905a814ad5e257d56dfcf7d086d4 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class aes_message_item extends uvm_sequence_item;
`uvm_object_utils(aes_message_item)
`uvm_object_new
///////////////////////////////////////
// control Knobs //
///////////////////////////////////////
// min number of data bytes
int message_len_max = 16;
// Max number of data bytes
int message_len_min = 1;
// percentage of configuration errors
int config_error_pct = 20;
// errors enabled
bit [2:0] error_types = 3'b000;
// configuraiton errors enabled
bit config_err = 0;
// manual mode percentage
int manual_operation_pct = 10;
// maskout unused key bits
bit keymask = 0;
// use fixed key
bit fixed_key_en = 0;
//used fixed key length
bit fixed_keylen_en = 0;
// use fixed data (same data for each block in a message
bit fixed_data_en = 0;
// fixed operation
bit fixed_operation_en = 0;
// fixed IV
bit fixed_iv_en = 0;
// predefined values for fixed mode
bit [3:0] [31:0] fixed_data = 128'hDEADBEEFEEDDBBAABAADBEEFDEAFBEAD;
bit [7:0] [31:0] fixed_key [2] = '{256'h0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF, 256'h0};
bit [2:0] fixed_keylen = 3'b001;
bit fixed_operation = 1'b0;
bit [3:0] [31:0] fixed_iv = 128'h00000000000000000000000000000000;
// Mode distribution //
// chance of selection ecb_mode
// ecb_mode /(ecb_mode + cbc_mode + cfb_mode + ofb_mode + ctr_mode)
// with the defaults 10/50 = 1/5 (20%)
int ecb_weight = 10;
int cbc_weight = 10;
int cfb_weight = 10;
int ofb_weight = 10;
int ctr_weight = 10;
// KEYLEN weights
int key_128b_weight = 10;
int key_192b_weight = 10;
int key_256b_weight = 10;
///////////////////////////////////////
// Randomizable variables //
///////////////////////////////////////
// length of the message //
rand int message_length;
// mode - which type of ecnryption is used //
rand aes_mode_e aes_mode = AES_NONE;
// operation - encruption or decryption //
rand aes_op_e aes_operation;
// aes key length //
rand bit [2:0] aes_keylen;
// 256 bit key (8x32 bit) //
rand bit [7:0][31:0] aes_key [2];
// 256 bit initialization vector (8x32 bit) //
rand bit [3:0][31:0] aes_iv;
// configuration error //
rand bit has_config_error;
// [0] mode error [1] key_len error
rand bit [1:0] cfg_error_type;
// run AES in manual mode
rand bit manual_operation;
///////////////////////////////////////
// FIXED variables //
///////////////////////////////////////
bit [7:0] input_msg[];
bit [7:0] output_msg[];
bit [7:0] predicted_msg[];
///////////////////////////////////////
// Constraints //
///////////////////////////////////////
constraint c_data { message_length inside { [message_len_min:message_len_max] };}
constraint c_keylen {
solve has_config_error before aes_keylen;
solve cfg_error_type before aes_keylen;
if (!(has_config_error && cfg_error_type[1])) {
// key len 001: 128, 010: 192, 100: 256
aes_keylen inside { 3'b001, 3'b010, 3'b100 };
// mode distribution
aes_keylen dist { 3'b001 := key_128b_weight,
3'b010 := key_192b_weight,
3'b100 := key_256b_weight };
} else {
// force the selection to be something invalid
!(aes_keylen inside { 3'b001, 3'b010, 3'b100 });
}
if (fixed_keylen_en) {
aes_keylen == fixed_keylen
};
}
constraint c_key {
if (fixed_key_en) {
aes_key[0] == fixed_key[0],
aes_key[1] == fixed_key[1]
};
}
constraint c_iv {
if (fixed_iv_en) {
aes_iv == fixed_iv
};
}
constraint c_operation {
if (fixed_operation_en) {
aes_operation == fixed_operation
};
}
constraint c_mode {
solve has_config_error before aes_mode;
solve cfg_error_type before aes_mode;
if (!(has_config_error && cfg_error_type[0]) ) {
aes_mode dist { AES_ECB := ecb_weight,
AES_CBC := cbc_weight,
AES_CFB := cfb_weight,
AES_OFB := ofb_weight,
AES_CTR := ctr_weight };
} else {
// the mode will be randomized to a random
// non legal value later.
aes_mode == AES_NONE;
}
}
constraint c_has_config_error {
if (error_types[0])
{
has_config_error dist { 0 :/ (100 - config_error_pct),
1 :/ config_error_pct };
}
else { has_config_error == 0; }
}
constraint c_config_error_type {
solve has_config_error before cfg_error_type;
if (has_config_error) {
cfg_error_type inside { [1:3] };
} else {
cfg_error_type ==2'b00;
}
}
constraint c_manual_operation {
manual_operation dist { 0:/ (100 - manual_operation_pct),
1:/ manual_operation_pct };
};
function void add_data_item(aes_seq_item item);
for(int i=0; i < 4 ; i++ ) begin
// data_in.push_front (data_in[3:0])
input_msg = { input_msg , item.data_in[i][7:0], item.data_in[i][15:8], item.data_in[i][23:16]
,item.data_in[i][31:24]};
// data_in.push_front (data_in[3:0])
output_msg = { output_msg, item.data_out[i][7:0], item.data_out[i][15:8],
item.data_out[i][23:16],item.data_out[i][31:24] };
end
endfunction // add_data_item
function void add_start_msg_item(aes_seq_item item);
this.aes_mode = item.mode;
this.aes_operation = item.operation;
this.aes_key = item.key;
this.aes_iv = item.iv;
// check for valid keylen
if ( item.key_len inside { 3'b001, 3'b010, 3'b100 } ) begin
this.aes_keylen = item.key_len;
end else begin
this.aes_keylen = 3'b100; // force to 256b
`uvm_info(`gfn, $sformatf("\n\t ---| Illegal key len detected reverting to default 256"), UVM_MEDIUM)
end
add_data_item(item);
endfunction // add_start_msg_item
function void alloc_predicted_msg();
predicted_msg = new[input_msg.size()];
endfunction // alloc_predicted_msg
// convert to string //
virtual function string convert2string();
string str;
str = super.convert2string();
str = {str, $sformatf("\n\t ----| \t\t AES MESSAGE ITEM \t |----\t ")
};
str = {str, "\n\t ----| " };
str = {str, $sformatf("\n\t ----| Mode: \t \t \t %s \t ",
aes_mode.name() ) };
str = {str, $sformatf("\n\t ----| Operation: \t \t %s \t ",
aes_operation.name() ) };
str = {str, $sformatf("\n\t ----| has Configuration error: %s \t \t \t ",
(has_config_error==1) ? "TRUE" : "FALSE" ) };
str = {str, $sformatf("\n\t ----| Mode error en: \t %d \n\t ----| Key_len error en: \t %d \t \t ",
cfg_error_type[0], cfg_error_type[1]) };
str = {str, $sformatf("\n\t ----| Message Length: \t \t %d \t ",
message_length ) };
str = {str, $sformatf("\n\t ----| Key Length: \t \t %03b \t ",
aes_keylen) };
str = {str, $sformatf("\n\t ----| Key Share 0: \t \t ") };
for(int i=0; i <8; i++) begin
str = {str, $sformatf("%h ",aes_key[0][i])};
end
str = {str, $sformatf("\n\t ----| Key Share 1: \t \t ") };
for(int i=0; i <8; i++) begin
str = {str, $sformatf("%h ",aes_key[1][i])};
end
str = {str, $sformatf("\n\t ----| Key Mask: \t \t %0b |----\t ",
keymask) };
str = {str, $sformatf("\n\t ----| Initializaion vector: \t \t ") };
for(int i=0; i <4; i++) begin
str = {str, $sformatf("%h ",aes_iv[i])};
end
str = {str, $sformatf("\n\t ----| Manual Mode : %b \t \t ", manual_operation) };
str = {str, $sformatf("\n\t ----| errors types enabled: %b \t \t ", error_types) };
str = {str, $sformatf("\n\t ----| CFB Weight: %d \t \t ", cfb_weight) };
str = {str, $sformatf("\n\t ----| OFB Weight: %d \t \t ", ofb_weight) };
str = {str, $sformatf("\n\t ----| ECB Weight: %d \t \t ", ecb_weight) };
str = {str, $sformatf("\n\t ----| CBC Weight: %d \t \t ", cbc_weight) };
str = {str, $sformatf("\n\t ----| CTR Weight: %d \t \t ", ctr_weight) };
str = {str, $sformatf("\n\t ----| Key Len Distribution: \t \t " ) };
str = {str, $sformatf("\n\t ----| 128 Weight: %d \t \t ", key_128b_weight) };
str = {str, $sformatf("\n\t ----| 192 Weight: %d \t \t ", key_192b_weight) };
str = {str, $sformatf("\n\t ----| 256 Weight: %d \t \t ", key_256b_weight) };
str = {str, $sformatf("\n\t") };
return str;
endfunction // conver2string
virtual function void do_copy(uvm_object rhs);
aes_message_item rhs_;
`downcast(rhs_,rhs)
super.do_copy(rhs);
aes_operation = rhs_.aes_operation;
aes_key = rhs_.aes_key;
aes_keylen = rhs_.aes_keylen;
aes_mode = rhs_.aes_mode;
aes_iv = rhs_.aes_iv;
message_length = rhs_.message_length;
has_config_error = rhs_.has_config_error;
cfg_error_type = rhs_.cfg_error_type;
error_types = rhs_.error_types;
ecb_weight = rhs_.ecb_weight;
cbc_weight = rhs_.cbc_weight;
cfb_weight = rhs_.cfb_weight;
ofb_weight = rhs_.ofb_weight;
ctr_weight = rhs_.ctr_weight;
key_128b_weight = rhs_.key_128b_weight;
key_192b_weight = rhs_.key_192b_weight;
key_256b_weight = rhs_.key_256b_weight;
input_msg = rhs_.input_msg;
output_msg = rhs_.output_msg;
predicted_msg = rhs_.predicted_msg;
manual_operation = rhs_.manual_operation;
keymask = rhs_.keymask;
fixed_data_en = rhs_.fixed_data_en;
fixed_data = rhs_.fixed_data;
fixed_iv_en = rhs_.fixed_iv_en;
endfunction // copy
endclass