Skip to content

Commit

Permalink
Update lowrisc_ip to lowRISC/opentitan@4cf2479b8e
Browse files Browse the repository at this point in the history
Update code from upstream repository
https://github.com/lowRISC/opentitan to revision
4cf2479b8e6c9b68b9fe1adba202443d3dbe3ff3

* [prim_trivium] Allow dynamically disabling the lockup protection
  (Pirmin Vogel)
* [scrambling] Add reference to RFC issue (Michael Schaffner)
* [edn] Move prim_edn_req out of prim (Rupert Swarbrick)
* [reggen] Remove the devmode input (Michael Schaffner)
* [prim, rom_ctrl] Remove S&P layer from data scrambling (Michael
  Schaffner)
* [prim] Fix typo in Trivium/Bivium stream cipher primitives (Pirmin
  Vogel)
* [prim] Add scratch Verilator testbench for Trivium/Bivium primitives
  (Pirmin Vogel)
* [prim] Add Trivium/Bivium stream cipher primitives (Pirmin Vogel)
* [chip,dv] update makefile for real_key rom test (Jaedon Kim)
* [dvsim] cast self.seed to 'int' (Jaedon Kim)
* [dvsim] Change systemverilog seed to 32 bits (Hakim Filali)
* [dv] Specialize dv_spinwait_* documentation comments (Rupert
  Swarbrick)

Signed-off-by: Michael Schaffner <msf@opentitan.org>
  • Loading branch information
msfschaffner committed Jan 19, 2024
1 parent 123d46b commit 94a7446
Show file tree
Hide file tree
Showing 31 changed files with 1,249 additions and 364 deletions.
2 changes: 1 addition & 1 deletion vendor/lowrisc_ip.lock.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/lowRISC/opentitan
rev: e6a0e9a1363d33789283ea6ba3c4d94d41f2dee5
rev: 4cf2479b8e6c9b68b9fe1adba202443d3dbe3ff3
}
}
17 changes: 8 additions & 9 deletions vendor/lowrisc_ip/dv/sv/dv_utils/dv_macros.svh
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,13 @@
`define GET_PARITY(val, odd=0) (^val ^ odd)
`endif

// Wait a task or statement with exit condition
// Kill the thread when either the wait statement is completed or exit condition occurs
// input WAIT_ need to be a statement. Here are some examples
// `DV_SPINWAIT(wait(...);, "Wait for ...")
// `DV_SPINWAIT(
// while (1) begin
// ...
// end)
// Wait for a statement but stop early if the EXIT statement completes.
//
// Example usage:
//
// `DV_SPINWAIT_EXIT(do_something_time_consuming();,
// wait(stop_now_flag);,
// "The stop flag was set when we were working")
`ifndef DV_SPINWAIT_EXIT
`define DV_SPINWAIT_EXIT(WAIT_, EXIT_, MSG_ = "exit condition occurred!", ID_ =`gfn) \
begin \
Expand Down Expand Up @@ -398,7 +397,7 @@
end
`endif

// wait a task or statement with timer watchdog
// Wait for a statement, but exit early after a timeout
`ifndef DV_SPINWAIT
`define DV_SPINWAIT(WAIT_, MSG_ = "timeout occurred!", TIMEOUT_NS_ = default_spinwait_timeout_ns, ID_ =`gfn) \
`DV_SPINWAIT_EXIT(WAIT_, `DV_WAIT_TIMEOUT(TIMEOUT_NS_, ID_, MSG_);, "", ID_)
Expand Down
1 change: 0 additions & 1 deletion vendor/lowrisc_ip/dv/sv/dv_utils/dv_utils_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ package dv_utils_pkg;

// typedef parameterized pins_if for ease of implementation for interrupts and alerts
typedef virtual pins_if #(NUM_MAX_INTERRUPTS) intr_vif;
typedef virtual pins_if #(1) devmode_vif;

// interface direction / mode - Host or Device
typedef enum bit {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ virtual function bit [38:0] rom_encrypt_read32(bit [bus_params_pkg::BUS_AW-1:0]
zero_key[i] = '0;
end

data_arr = sram_scrambler_pkg::sp_decrypt(data_arr, 39, zero_key);
for (int i = 0; i < 39; i++) begin
data[i] = data_arr[i] ^ keystream[i];
end
Expand Down
119 changes: 64 additions & 55 deletions vendor/lowrisc_ip/dv/sv/mem_bkdr_util/sram_scrambler_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ package sram_scrambler_pkg;
// SRAM data encryption is more involved, we need to run 2 rounds of PRINCE on the nonce and key
// and then XOR the result with the data.
//
// After that, the XORed data neeeds to them be passed through the S&P network one byte at a time.
// Optionally, the XORed data can be passed through the S&P network.
function automatic state_t encrypt_sram_data(logic data[], int data_width, int sp_width,
logic addr[], int addr_width,
logic key[], logic nonce[]);
logic key[], logic nonce[], bit use_sp_layer = 0);
logic keystream[] = new[SRAM_BLOCK_WIDTH];
logic data_enc[] = new[data_width];
logic byte_to_enc[] = new[8];
Expand All @@ -262,31 +262,33 @@ package sram_scrambler_pkg;
data_enc[i] = data[i] ^ keystream[i % ks_width];
end

if (data_width == sp_width) begin
// pass the entire word through the subst/perm network at once (the next cases would give the
// same results too, but this should be a bit more efficient)
data_enc = sp_encrypt(data_enc, data_width, zero_key);
end else if (sp_width == 8) begin
// pass each byte of the encoded result through the subst/perm network (special case of the
// general code below)
for (int i = 0; i < data_width / 8; i++) begin
byte_to_enc = data_enc[i*8 +: 8];
enc_byte = sp_encrypt(byte_to_enc, 8, zero_key);
data_enc[i*8 +: 8] = enc_byte;
end
end else begin
// divide the word into sp_width chunks to pass it through the subst/perm network
for (int chunk_lsb = 0; chunk_lsb < data_width; chunk_lsb += sp_width) begin
int bits_remaining = data_width - chunk_lsb;
int chunk_width = (bits_remaining < sp_width) ? bits_remaining : sp_width;
logic chunk[] = new[chunk_width];

for (int j = 0; j < chunk_width; j++) begin
chunk[j] = data_enc[chunk_lsb + j];
if (use_sp_layer) begin
if (data_width == sp_width) begin
// pass the entire word through the subst/perm network at once (the next cases would give the
// same results too, but this should be a bit more efficient)
data_enc = sp_encrypt(data_enc, data_width, zero_key);
end else if (sp_width == 8) begin
// pass each byte of the encoded result through the subst/perm network (special case of the
// general code below)
for (int i = 0; i < data_width / 8; i++) begin
byte_to_enc = data_enc[i*8 +: 8];
enc_byte = sp_encrypt(byte_to_enc, 8, zero_key);
data_enc[i*8 +: 8] = enc_byte;
end
chunk = sp_encrypt(chunk, chunk_width, zero_key);
for (int j = 0; j < chunk_width; j++) begin
data_enc[chunk_lsb + j] = chunk[j];
end else begin
// divide the word into sp_width chunks to pass it through the subst/perm network
for (int chunk_lsb = 0; chunk_lsb < data_width; chunk_lsb += sp_width) begin
int bits_remaining = data_width - chunk_lsb;
int chunk_width = (bits_remaining < sp_width) ? bits_remaining : sp_width;
logic chunk[] = new[chunk_width];

for (int j = 0; j < chunk_width; j++) begin
chunk[j] = data_enc[chunk_lsb + j];
end
chunk = sp_encrypt(chunk, chunk_width, zero_key);
for (int j = 0; j < chunk_width; j++) begin
data_enc[chunk_lsb + j] = chunk[j];
end
end
end
end
Expand All @@ -296,7 +298,7 @@ package sram_scrambler_pkg;

function automatic state_t decrypt_sram_data(logic data[], int data_width, int sp_width,
logic addr[], int addr_width,
logic key[], logic nonce[]);
logic key[], logic nonce[], bit use_sp_layer = 0);
logic keystream[] = new[SRAM_BLOCK_WIDTH];
logic data_dec[] = new[data_width];
logic byte_to_dec[] = new[8];
Expand All @@ -312,38 +314,45 @@ package sram_scrambler_pkg;
// Generate the keystream
keystream = gen_keystream(addr, addr_width, key, nonce);

if (data_width == sp_width) begin
// pass the entire word through the subst/perm network at once (the next cases would give the
// same results too, but this should be a bit more efficient)
data_dec = sp_decrypt(data, data_width, zero_key);
end else if (sp_width == 8) begin
// pass each byte of the data through the subst/perm network (special case of the general code
// below)
for (int i = 0; i < data_width / 8; i++) begin
byte_to_dec = data[i*8 +: 8];
dec_byte = sp_decrypt(byte_to_dec, 8, zero_key);
data_dec[i*8 +: 8] = dec_byte;
end
end else begin
// divide the word into sp_width chunks to pass it through the subst/perm network
for (int chunk_lsb = 0; chunk_lsb < data_width; chunk_lsb += sp_width) begin
int bits_remaining = data_width - chunk_lsb;
int chunk_width = (bits_remaining < sp_width) ? bits_remaining : sp_width;
logic chunk[] = new[chunk_width];

for (int j = 0; j < chunk_width; j++) begin
chunk[j] = data[chunk_lsb + j];
if (use_sp_layer) begin
if (data_width == sp_width) begin
// pass the entire word through the subst/perm network at once (the next cases would give the
// same results too, but this should be a bit more efficient)
data_dec = sp_decrypt(data, data_width, zero_key);
end else if (sp_width == 8) begin
// pass each byte of the data through the subst/perm network (special case of the general code
// below)
for (int i = 0; i < data_width / 8; i++) begin
byte_to_dec = data[i*8 +: 8];
dec_byte = sp_decrypt(byte_to_dec, 8, zero_key);
data_dec[i*8 +: 8] = dec_byte;
end
chunk = sp_decrypt(chunk, chunk_width, zero_key);
for (int j = 0; j < chunk_width; j++) begin
data_dec[chunk_lsb + j] = chunk[j];
end else begin
// divide the word into sp_width chunks to pass it through the subst/perm network
for (int chunk_lsb = 0; chunk_lsb < data_width; chunk_lsb += sp_width) begin
int bits_remaining = data_width - chunk_lsb;
int chunk_width = (bits_remaining < sp_width) ? bits_remaining : sp_width;
logic chunk[] = new[chunk_width];

for (int j = 0; j < chunk_width; j++) begin
chunk[j] = data[chunk_lsb + j];
end
chunk = sp_decrypt(chunk, chunk_width, zero_key);
for (int j = 0; j < chunk_width; j++) begin
data_dec[chunk_lsb + j] = chunk[j];
end
end
end
end

// XOR result data with the keystream
for (int i = 0; i < data_width; i++) begin
data_dec[i] = data_dec[i] ^ keystream[i % ks_width];
// XOR result data with the keystream
for (int i = 0; i < data_width; i++) begin
data_dec[i] = data_dec[i] ^ keystream[i % ks_width];
end
end else begin
// XOR result data with the keystream
for (int i = 0; i < data_width; i++) begin
data_dec[i] = data[i] ^ keystream[i % ks_width];
end
end

return data_dec;
Expand Down
37 changes: 19 additions & 18 deletions vendor/lowrisc_ip/dv/tools/dvsim/sim.mk
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ pre_build:
mkdir -p ${build_dir}
ifneq (${pre_build_cmds},)
# pre_build_cmds are likely changing the in-tree sources. We hence use FLOCK
# utility to prevent multiple builds that may be running in parallel from
# stepping on each other. TODO: Enforce the list of pre_build_cmds is
# identical across all build modes.
# utility to prevent multiple builds that may be running in parallel from
# stepping on each other. TODO: Enforce the list of pre_build_cmds is
# identical across all build modes.
${LOCK_ROOT_DIR} "cd ${build_dir} && ${pre_build_cmds}"
endif

Expand Down Expand Up @@ -124,6 +124,7 @@ ifneq (${sw_images},)
--output=label_kind | cut -f1 -d' '); \
if [[ $${kind} == "opentitan_test" \
|| $${bazel_label} == "//sw/device/lib/testing/test_rom:test_rom_sim_dv" \
|| $${bazel_label} == "//sw/device/silicon_creator/rom:rom_with_real_keys_sim_dv" \
|| $${bazel_label} == "//sw/device/silicon_creator/rom:rom_with_fake_keys_sim_dv" ]]; then \
for artifact in $$($${bazel_cmd} cquery $${bazel_airgapped_opts} \
$${bazel_label} \
Expand Down Expand Up @@ -229,18 +230,18 @@ cov_analyze:
${cov_analyze_cmd} ${cov_analyze_opts}

.PHONY: build \
pre_build \
gen_sv_flist \
do_build \
post_build \
build_result \
run \
pre_run \
sw_build \
simulate \
post_run \
run_result \
debug_waves \
cov_merge \
cov_analyze \
cov_report
pre_build \
gen_sv_flist \
do_build \
post_build \
build_result \
run \
pre_run \
sw_build \
simulate \
post_run \
run_result \
debug_waves \
cov_merge \
cov_analyze \
cov_report
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
- address and size aren't aligned, e.g. `a_address = 0x01`, `a_size != 0`
- size is greater than 2
- OpenTitan defined error cases
- access unmapped address, expect `d_error = 1` when `devmode_i == 1`
- access unmapped address, expect `d_error = 1`
- write a CSR with unaligned address, e.g. `a_address[1:0] != 0`
- write a CSR less than its width, e.g. when CSR is 2 bytes wide, only write 1 byte
- write a memory with `a_mask != '1` when it doesn't support partial accesses
Expand Down
4 changes: 2 additions & 2 deletions vendor/lowrisc_ip/dv/tools/dvsim/vcs.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@

run_opts: ["-licqueue",
"-ucli -do {run_script}",
"+ntb_random_seed={seed}",
"+ntb_random_seed={svseed}",
// Disable the display of the SystemVerilog assert and cover statement summary
// at the end of simulation. This summary is list of assertions that started but
// did not finish because the simulation terminated, or assertions that did not
Expand All @@ -134,7 +134,7 @@

// Individual test specific coverage data - this will be deleted if the test fails
// so that coverage from failiing tests is not included in the final report.
cov_db_test_dir_name: "{run_dir_name}.{seed}"
cov_db_test_dir_name: "{run_dir_name}.{svseed}"
cov_db_test_dir: "{cov_db_dir}/snps/coverage/db/testdata/{cov_db_test_dir_name}"

// Merging coverage.
Expand Down
4 changes: 1 addition & 3 deletions vendor/lowrisc_ip/dv/tools/dvsim/verilator.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@
// "--x-initial unique",
]

run_opts: [// Set random seed.
// "+verilator+seed+{seed}",
]
run_opts: []

// Supported wave dumping formats (in order of preference).
supported_wave_formats: ["fst"]
Expand Down
4 changes: 2 additions & 2 deletions vendor/lowrisc_ip/dv/tools/dvsim/xcelium.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"-64bit -xmlibdirname {build_db_dir}",
// Use the same snapshot name set during the build step.
"-r {tb}",
"+SVSEED={seed}",
"+SVSEED={svseed}",
"{uvm_testname_plusarg}",
"{uvm_testseq_plusarg}",
// Ignore "IEEE 1800-2009 SystemVerilog simulation semantics" warning
Expand Down Expand Up @@ -129,7 +129,7 @@

// Individual test specific coverage data - this will be deleted if the test fails
// so that coverage from failiing tests is not included in the final report.
cov_db_test_dir_name: "{run_dir_name}.{seed}"
cov_db_test_dir_name: "{run_dir_name}.{svseed}"
cov_db_test_dir: "{cov_db_dir}/{cov_db_test_dir_name}"

// Merging coverage.
Expand Down
10 changes: 6 additions & 4 deletions vendor/lowrisc_ip/dv/verilator/cpp/scrambled_ecc32_mem_area.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ void ScrambledEcc32MemArea::WriteBuffer(uint8_t buf[SV_MEM_WIDTH_BYTES],
std::vector<uint8_t> ScrambledEcc32MemArea::ReadUnscrambled(
const uint8_t buf[SV_MEM_WIDTH_BYTES], uint32_t src_word) const {
std::vector<uint8_t> scrambled_data(buf, buf + GetPhysWidthByte());
return scramble_decrypt_data(
scrambled_data, GetPhysWidth(), 39, AddrIntToBytes(src_word, addr_width_),
addr_width_, GetScrambleNonce(), GetScrambleKey(), repeat_keystream_);
return scramble_decrypt_data(scrambled_data, GetPhysWidth(), 39,
AddrIntToBytes(src_word, addr_width_),
addr_width_, GetScrambleNonce(),
GetScrambleKey(), repeat_keystream_, false);
}

void ScrambledEcc32MemArea::ReadBuffer(std::vector<uint8_t> &data,
Expand Down Expand Up @@ -196,7 +197,8 @@ void ScrambledEcc32MemArea::ScrambleBuffer(uint8_t buf[SV_MEM_WIDTH_BYTES],
// Scramble data with integrity
scramble_buf = scramble_encrypt_data(
scramble_buf, GetPhysWidth(), 39, AddrIntToBytes(dst_word, addr_width_),
addr_width_, GetScrambleNonce(), GetScrambleKey(), repeat_keystream_);
addr_width_, GetScrambleNonce(), GetScrambleKey(), repeat_keystream_,
false);

// Copy scrambled data to write buffer
std::copy(scramble_buf.begin(), scramble_buf.end(), &buf[0]);
Expand Down
30 changes: 17 additions & 13 deletions vendor/lowrisc_ip/ip/prim/dv/prim_ram_scr/cpp/scramble_model.cc
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ std::vector<uint8_t> scramble_encrypt_data(
const std::vector<uint8_t> &data_in, uint32_t data_width,
uint32_t subst_perm_width, const std::vector<uint8_t> &addr,
uint32_t addr_width, const std::vector<uint8_t> &nonce,
const std::vector<uint8_t> &key, bool repeat_keystream) {
const std::vector<uint8_t> &key, bool repeat_keystream, bool use_sp_layer) {
assert(data_in.size() == ((data_width + 7) / 8));
assert(addr.size() == ((addr_width + 7) / 8));

Expand All @@ -335,28 +335,32 @@ std::vector<uint8_t> scramble_encrypt_data(

auto data_enc = xor_vectors(data_in, keystream);

return scramble_subst_perm_full_width(data_enc, data_width, subst_perm_width,
true);
if (use_sp_layer) {
return scramble_subst_perm_full_width(data_enc, data_width,
subst_perm_width, true);
} else {
return data_enc;
}
}

std::vector<uint8_t> scramble_decrypt_data(
const std::vector<uint8_t> &data_in, uint32_t data_width,
uint32_t subst_perm_width, const std::vector<uint8_t> &addr,
uint32_t addr_width, const std::vector<uint8_t> &nonce,
const std::vector<uint8_t> &key, bool repeat_keystream) {
const std::vector<uint8_t> &key, bool repeat_keystream, bool use_sp_layer) {
assert(data_in.size() == ((data_width + 7) / 8));
assert(addr.size() == ((addr_width + 7) / 8));

// Data is decrypted by reversing substitution/permutation layer then XORing
// with keystream
auto data_sp_out = scramble_subst_perm_full_width(data_in, data_width,
subst_perm_width, false);

auto keystream =
scramble_gen_keystream(addr, addr_width, nonce, key, data_width,
kNumPrinceHalfRounds, repeat_keystream);

auto data_dec = xor_vectors(data_sp_out, keystream);

return data_dec;
if (use_sp_layer) {
// Data is decrypted by reversing substitution/permutation layer then XORing
// with keystream
auto data_sp_out = scramble_subst_perm_full_width(data_in, data_width,
subst_perm_width, false);
return xor_vectors(data_sp_out, keystream);
} else {
return xor_vectors(data_in, keystream);
}
}
Loading

0 comments on commit 94a7446

Please sign in to comment.