Skip to content

Commit f2f40ef

Browse files
committed
[test] Add rom fi
Add the rom fi host and test scripts. Signed-off-by: Siemen Dhooghe <sdhooghe@google.com>
1 parent fcebf8b commit f2f40ef

4 files changed

Lines changed: 250 additions & 1 deletion

File tree

communication/fi_rom_commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def _ujson_rom_fi_cmd(self) -> None:
1818
time.sleep(0.01)
1919
self.target.write(json.dumps("RomFi").encode("ascii"))
2020

21-
def rom_read(self) -> None:
21+
def handle_rom_read(self) -> None:
2222
""" Reads Rom digest.
2323
"""
2424
# RomFi command.

test/penetrationtests/fi/BUILD

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ py_binary(
163163
}),
164164
)
165165

166+
py_binary(
167+
name = "fi_rom_test",
168+
srcs = ["test_scripts/fi_rom_test.py"],
169+
testonly = True,
170+
deps = [
171+
":fi_rom_functions",
172+
"//communication:dut",
173+
"//communication:chip",
174+
"//communication:fi_rom_commands",
175+
"//test/penetrationtests/util:utils",
176+
"@rules_python//python/runfiles",
177+
],
178+
data = [
179+
"@lowrisc_opentitan//sw/host/opentitantool",
180+
] +
181+
select({
182+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/config:env_silicon_owner_gb_rom_ext": [
183+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_silicon_owner_gb_rom_ext",
184+
],
185+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/config:env_fpga_cw310_rom_with_fake_keys": [
186+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_fpga_cw310_rom_with_fake_keys",
187+
],
188+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/config:env_fpga_cw310_sival_rom_ext": [
189+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_fpga_cw310_sival_rom_ext",
190+
],
191+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/config:env_fpga_cw310_test_rom": [
192+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_fpga_cw310_test_rom",
193+
],
194+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/config:env_silicon_owner_a2_rom_ext": [
195+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_silicon_owner_a2_rom_ext",
196+
],
197+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/config:env_silicon_owner_sival_rom_ext": [
198+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_silicon_owner_sival_rom_ext",
199+
],
200+
"//conditions:default": [
201+
"@lowrisc_opentitan//sw/device/tests/penetrationtests/firmware:pen_test_fi_silicon_owner_gb_rom_ext",
202+
],
203+
}),
204+
)
205+
166206
py_library(
167207
name = "fi_ibex_functions",
168208
srcs = ["host_scripts/fi_ibex_functions.py"],
@@ -201,4 +241,14 @@ py_library(
201241
"//communication:chip",
202242
"//communication:fi_otp_commands",
203243
],
244+
)
245+
246+
py_library(
247+
name = "fi_rom_functions",
248+
srcs = ["host_scripts/fi_rom_functions.py"],
249+
deps = [
250+
"//communication:dut",
251+
"//communication:chip",
252+
"//communication:fi_rom_commands",
253+
],
204254
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from communication.fi_rom_commands import OTFIRom
2+
from communication.chip import *
3+
from communication.dut import DUT
4+
import time
5+
6+
def char_rom_read(opentitantool, iterations):
7+
target = DUT()
8+
reset_target(opentitantool)
9+
# Clear the output from the reset
10+
target.dump_all()
11+
12+
romfi = OTFIRom(target)
13+
# Initialize our chip and catch its output
14+
device_id, sensors, alerts, owner_page, boot_log, boot_measurements, version = romfi.init()
15+
for _ in range(iterations):
16+
romfi.handle_rom_read()
17+
response = target.read_response()
18+
return response
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
from test.penetrationtests.fi.host_scripts.fi_rom_functions import *
2+
from communication.fi_rom_commands import OTFIRom
3+
from python.runfiles import Runfiles
4+
from communication.chip import *
5+
from test.penetrationtests.util.utils import *
6+
import os
7+
import json
8+
9+
ignored_keys_set = set([])
10+
11+
def reset_test(opentitantool, target):
12+
reset_target(opentitantool)
13+
while True:
14+
read_line = str(target.readline().decode().strip())
15+
if len(read_line) > 0:
16+
if "firmware_fi.c" in read_line:
17+
return True
18+
else:
19+
return False
20+
21+
22+
def init_test(opentitantool, target):
23+
romfi = OTFIRom(target)
24+
device_id, sensors, alerts, owner_page, boot_log, boot_measurements, version = romfi.init()
25+
device_id_json = json.loads(device_id)
26+
sensors_json = json.loads(sensors)
27+
alerts_json = json.loads(alerts)
28+
owner_page_json = json.loads(owner_page)
29+
boot_log_json = json.loads(boot_log)
30+
boot_measurements_json = json.loads(boot_measurements)
31+
32+
expected_device_id_keys = {
33+
"device_id",
34+
"rom_digest",
35+
"icache_en",
36+
"dummy_instr_en",
37+
"clock_jitter_locked",
38+
"clock_jitter_en",
39+
"sram_main_readback_locked",
40+
"sram_main_readback_en",
41+
"sram_ret_readback_locked",
42+
"sram_ret_readback_en"
43+
}
44+
actual_device_id_keys = set(device_id_json.keys())
45+
46+
if not actual_device_id_keys == expected_device_id_keys:
47+
print("device_id keys do not match the expected set.")
48+
print(f"Expected: {expected_device_id_keys}")
49+
print(f"Actual: {actual_device_id_keys}")
50+
return False
51+
52+
expected_sensors_keys = {
53+
"sensor_ctrl_en",
54+
"sensor_ctrl_fatal"
55+
}
56+
actual_sensors_keys = set(sensors_json.keys())
57+
58+
if not expected_sensors_keys == actual_sensors_keys:
59+
print("sensor keys do not match the expected set.")
60+
print(f"Expected: {expected_sensors_keys}")
61+
print(f"Actual: {actual_sensors_keys}")
62+
return False
63+
64+
expected_alerts_keys = {
65+
"alert_classes",
66+
"enabled_alerts",
67+
"enabled_classes",
68+
"accumulation_thresholds",
69+
"duration_cycles",
70+
"escalation_signals_en",
71+
"escalation_signals_map"
72+
}
73+
actual_alerts_keys = set(alerts_json.keys())
74+
if not expected_alerts_keys == actual_alerts_keys:
75+
print("alert keys do not match the expected set.")
76+
print(f"Expected: {expected_alerts_keys}")
77+
print(f"Actual: {actual_alerts_keys}")
78+
return False
79+
80+
expected_owner_page_keys = {
81+
"config_version",
82+
"sram_exec_mode",
83+
"ownership_key_alg",
84+
"update_mode",
85+
"min_security_version_bl0",
86+
"lock_constraint"
87+
}
88+
actual_owner_page_keys = set(owner_page_json.keys())
89+
if not expected_owner_page_keys == actual_owner_page_keys:
90+
print("owner_page keys do not match the expected set.")
91+
print(f"Expected: {expected_owner_page_keys}")
92+
print(f"Actual: {actual_owner_page_keys}")
93+
return False
94+
95+
expected_boot_log_keys = {
96+
"digest",
97+
"identifier",
98+
"scm_revision_low",
99+
"scm_revision_high",
100+
"rom_ext_slot",
101+
"rom_ext_major",
102+
"rom_ext_minor",
103+
"rom_ext_size",
104+
"bl0_slot",
105+
"ownership_state",
106+
"ownership_transfers",
107+
"rom_ext_min_sec_ver",
108+
"bl0_min_sec_ver",
109+
"primary_bl0_slot",
110+
"retention_ram_initialized"
111+
}
112+
actual_boot_log_keys = set(boot_log_json.keys())
113+
if not expected_boot_log_keys == actual_boot_log_keys:
114+
print("boot_log keys do not match the expected set.")
115+
print(f"Expected: {expected_boot_log_keys}")
116+
print(f"Actual: {actual_boot_log_keys}")
117+
return False
118+
119+
expected_boot_measurements_keys = {
120+
"bl0",
121+
"rom_ext"
122+
}
123+
actual_boot_measurements_keys = set(boot_measurements_json.keys())
124+
if not expected_boot_measurements_keys == actual_boot_measurements_keys:
125+
print("boot_measurements keys do not match the expected set.")
126+
print(f"Expected: {expected_boot_measurements_keys}")
127+
print(f"Actual: {actual_boot_measurements_keys}")
128+
return False
129+
130+
if "PENTEST" not in version:
131+
print("Did not receive a PENTEST version.")
132+
print(f"Actual: {version}")
133+
return False
134+
135+
return True
136+
137+
def char_rom_read_test(opentitantool_path, iterations):
138+
actual_result = char_rom_read(opentitantool_path, iterations)
139+
try:
140+
actual_result_json = json.loads(actual_result)
141+
except:
142+
print("char_rom_read gave an unexpected result")
143+
print(f"Actual: {actual_result}")
144+
return False
145+
expected_result_json = json.loads('{"digest":[0,0,0,0,0,0,0,0],"err_status":0,"alerts":[0,0,0],"ast_alerts":[0,0]}')
146+
if not compare_json_data(actual_result_json, expected_result_json, ignored_keys_set):
147+
print("char_rom_read failed")
148+
print(f"Expected: {expected_result_json}")
149+
print(f"Actual: {actual_result_json}")
150+
print("")
151+
return False
152+
return True
153+
154+
def main():
155+
r = Runfiles.Create()
156+
opentitantool_path = r.Rlocation("lowrisc_opentitan/sw/host/opentitantool/opentitantool")
157+
158+
firmware_target_name = os.environ.get("SELECTED_FIRMWARE_TARGET", "pen_test_fi_silicon_owner_gb_rom_ext")
159+
firmware_path = r.Rlocation(f"lowrisc_opentitan/sw/device/tests/penetrationtests/firmware/{firmware_target_name}.img")
160+
161+
target = DUT()
162+
163+
flash_target(opentitantool_path, firmware_path)
164+
target.dump_all()
165+
166+
if not reset_test(opentitantool_path, target):
167+
print("Reset test failure")
168+
return False
169+
170+
if not init_test(opentitantool_path, target):
171+
print("Init test failure")
172+
return False
173+
174+
iterations = 10
175+
char_rom_read_test(opentitantool_path, iterations)
176+
177+
print("Testing finished")
178+
return True
179+
180+
if __name__ == "__main__":
181+
main()

0 commit comments

Comments
 (0)