blob: b9590335470dc9906322bd7061f93dfe5f795078 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// Wrapper functions for SRAM's encrypted read/write operations.
// This file is included in `mem_bkdr_util.sv` as a continuation of `mem_bkdr_util` class.
function logic [bus_params_pkg::BUS_AW-1:0] get_sram_encrypt_addr (
logic [bus_params_pkg::BUS_AW-1:0] addr,
logic [SRAM_BLOCK_WIDTH-1:0] nonce,
logic [31:0] extra_addr_bits = '0);
int full_addr_width = addr_width + extra_addr_bits;
logic [bus_params_pkg::BUS_AW-1:0] scr_addr;
logic scr_addr_arr [] = new[full_addr_width];
logic addr_arr [] = new[full_addr_width];
logic nonce_arr [] = new[SRAM_BLOCK_WIDTH];
nonce_arr = {<<{nonce}};
for (int i = 0; i < full_addr_width; i++) begin
addr_arr[i] = addr[addr_lsb + i];
end
// calculate scrambled address
scr_addr_arr = sram_scrambler_pkg::encrypt_sram_addr(addr_arr, full_addr_width, nonce_arr);
// convert to bus address output
for (int i = 0; i < addr_lsb; i++) begin
scr_addr[i] = addr[i];
end
for (int i = 0; i < full_addr_width; i++) begin
scr_addr[addr_lsb + i] = scr_addr_arr[i];
end
return scr_addr;
endfunction // get_sram_encrypt_addr
function logic [38:0] get_sram_encrypt32_intg_data (
logic [bus_params_pkg::BUS_AW-1:0] addr,
logic [31:0] data,
logic [SRAM_KEY_WIDTH-1:0] key,
logic [SRAM_BLOCK_WIDTH-1:0] nonce,
int extra_addr_bits=0);
logic [38:0] integ_data;
logic [38:0] scrambled_data;
int full_addr_width = addr_width + extra_addr_bits;
logic wdata_arr [] = new[39];
logic addr_arr [] = new[full_addr_width];
logic key_arr [] = new[SRAM_KEY_WIDTH];
logic nonce_arr [] = new[SRAM_BLOCK_WIDTH];
key_arr = {<<{key}};
nonce_arr = {<<{nonce}};
for (int i = 0; i < full_addr_width; i++) begin
addr_arr[i] = addr[addr_lsb + i];
end
// Calculate the integrity constant
integ_data = prim_secded_pkg::prim_secded_inv_39_32_enc(data);
// Calculate the scrambled data
wdata_arr = {<<{integ_data}};
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
wdata_arr, 39, 39, addr_arr, full_addr_width, key_arr, nonce_arr
);
scrambled_data = {<<{wdata_arr}};
return scrambled_data;
endfunction // get_sram_encrypt32_intg_data
virtual function logic [38:0] sram_encrypt_read32_integ(logic [bus_params_pkg::BUS_AW-1:0] addr,
logic [SRAM_KEY_WIDTH-1:0] key,
logic [SRAM_BLOCK_WIDTH-1:0] nonce);
logic [bus_params_pkg::BUS_AW-1:0] scr_addr;
logic [38:0] rdata = '0;
logic rdata_arr [] = new[39];
logic addr_arr [] = new[addr_width];
logic key_arr [] = new[SRAM_KEY_WIDTH];
logic nonce_arr [] = new[SRAM_BLOCK_WIDTH];
key_arr = {<<{key}};
nonce_arr = {<<{nonce}};
for (int i = 0; i < addr_width; i++) begin
addr_arr[i] = addr[addr_lsb + i];
end
// Calculate the scrambled address
scr_addr = get_sram_encrypt_addr(addr, nonce);
// Read memory and return the decrypted data
rdata = read39integ(scr_addr);
`uvm_info(`gfn, $sformatf("scr data: 0x%0x", rdata), UVM_HIGH)
rdata_arr = {<<{rdata}};
rdata_arr = sram_scrambler_pkg::decrypt_sram_data(
rdata_arr, 39, 39, addr_arr, addr_width, key_arr, nonce_arr
);
rdata = {<<{rdata_arr}};
// Only return the data payload without ECC bits.
return rdata[31:0];
endfunction
virtual function void sram_encrypt_write32_integ(logic [bus_params_pkg::BUS_AW-1:0] addr,
logic [31:0] data,
logic [SRAM_KEY_WIDTH-1:0] key,
logic [SRAM_BLOCK_WIDTH-1:0] nonce,
bit [38:0] flip_bits = 0);
logic [bus_params_pkg::BUS_AW-1:0] scr_addr;
logic [38:0] integ_data;
logic [38:0] scrambled_data;
logic wdata_arr [] = new[39];
logic addr_arr [] = new[addr_width];
logic key_arr [] = new[SRAM_KEY_WIDTH];
logic nonce_arr [] = new[SRAM_BLOCK_WIDTH];
key_arr = {<<{key}};
nonce_arr = {<<{nonce}};
for (int i = 0; i < addr_width; i++) begin
addr_arr[i] = addr[addr_lsb + i];
end
// Calculate the scrambled address
scr_addr = get_sram_encrypt_addr(addr, nonce);
// Calculate the integrity constant
integ_data = prim_secded_pkg::prim_secded_inv_39_32_enc(data);
// flip some bits to inject integrity fault
integ_data ^= flip_bits;
// Calculate the scrambled data
wdata_arr = {<<{integ_data}};
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
wdata_arr, 39, 39, addr_arr, addr_width, key_arr, nonce_arr
);
scrambled_data = {<<{wdata_arr}};
// Write the scrambled data to memory
write39integ(scr_addr, scrambled_data);
endfunction